X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAGBuilder.cpp;h=3d483464f6515b70ec1e3e674a4e845581f752e1;hb=ca7a19a85f82e15bd6756b0715963be0b9988d8a;hp=9e315194c9878097a0e93d2597c42377e01425dc;hpb=95b25773a76b1fa20a8ff76cfbd630ccbc76cfb2;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 9e315194c98..3d483464f65 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -64,6 +64,7 @@ #include "llvm/Target/TargetSelectionDAGInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" #include +#include using namespace llvm; #define DEBUG_TYPE "isel" @@ -1243,50 +1244,66 @@ void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) { /// destination, but in the machine CFG, we enumerate all the possible blocks. /// This function skips over imaginary basic blocks that hold catchpad, /// terminatepad, or catchendpad instructions, and finds all the "real" machine -/// basic block destinations. -static void -findUnwindDestinations(FunctionLoweringInfo &FuncInfo, - const BasicBlock *EHPadBB, - SmallVectorImpl &UnwindDests) { +/// basic block destinations. As those destinations may not be successors of +/// EHPadBB, here we also calculate the edge weight to those destinations. The +/// passed-in Weight is the edge weight to EHPadBB. +static void findUnwindDestinations( + FunctionLoweringInfo &FuncInfo, const BasicBlock *EHPadBB, uint32_t Weight, + SmallVectorImpl> &UnwindDests) { EHPersonality Personality = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()); bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX; bool IsCoreCLR = Personality == EHPersonality::CoreCLR; + while (EHPadBB) { const Instruction *Pad = EHPadBB->getFirstNonPHI(); + BasicBlock *NewEHPadBB = nullptr; if (isa(Pad)) { // Stop on landingpads. They are not funclets. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight); break; } else if (isa(Pad)) { // Stop on cleanup pads. Cleanups are always funclet entries for all known // personalities. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); - UnwindDests.back()->setIsEHFuncletEntry(); + UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight); + UnwindDests.back().first->setIsEHFuncletEntry(); break; } else if (const auto *CPI = dyn_cast(Pad)) { // Add the catchpad handler to the possible destinations. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + UnwindDests.emplace_back(FuncInfo.MBBMap[EHPadBB], Weight); // In MSVC C++, catchblocks are funclets and need prologues. if (IsMSVCCXX || IsCoreCLR) - UnwindDests.back()->setIsEHFuncletEntry(); - EHPadBB = CPI->getUnwindDest(); - } else if (const auto *CEPI = dyn_cast(Pad)) { - EHPadBB = CEPI->getUnwindDest(); - } else if (const auto *CEPI = dyn_cast(Pad)) { - EHPadBB = CEPI->getUnwindDest(); + UnwindDests.back().first->setIsEHFuncletEntry(); + NewEHPadBB = CPI->getUnwindDest(); + } else if (const auto *CEPI = dyn_cast(Pad)) + NewEHPadBB = CEPI->getUnwindDest(); + else if (const auto *CEPI = dyn_cast(Pad)) + NewEHPadBB = CEPI->getUnwindDest(); + else + continue; + + BranchProbabilityInfo *BPI = FuncInfo.BPI; + if (BPI && NewEHPadBB) { + // When BPI is available, the calculated weight cannot be zero as zero + // will be turned to a default weight in MachineBlockFrequencyInfo. + Weight = std::max( + BPI->getEdgeProbability(EHPadBB, NewEHPadBB).scale(Weight), 1); } + EHPadBB = NewEHPadBB; } } void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) { // Update successor info. - // FIXME: The weights for catchpads will be wrong. - SmallVector UnwindDests; - findUnwindDestinations(FuncInfo, I.getUnwindDest(), UnwindDests); - for (MachineBasicBlock *UnwindDest : UnwindDests) { - UnwindDest->setIsEHPad(); - addSuccessorWithWeight(FuncInfo.MBB, UnwindDest); + SmallVector, 1> UnwindDests; + auto UnwindDest = I.getUnwindDest(); + BranchProbabilityInfo *BPI = FuncInfo.BPI; + uint32_t UnwindDestWeight = + BPI ? BPI->getEdgeWeight(FuncInfo.MBB->getBasicBlock(), UnwindDest) : 0; + findUnwindDestinations(FuncInfo, UnwindDest, UnwindDestWeight, UnwindDests); + for (auto &UnwindDest : UnwindDests) { + UnwindDest.first->setIsEHPad(); + addSuccessorWithWeight(FuncInfo.MBB, UnwindDest.first, UnwindDest.second); } // Create the terminator node. @@ -2128,15 +2145,17 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { CopyToExportRegsIfNeeded(&I); } - SmallVector UnwindDests; - findUnwindDestinations(FuncInfo, EHPadBB, UnwindDests); + SmallVector, 1> UnwindDests; + BranchProbabilityInfo *BPI = FuncInfo.BPI; + uint32_t EHPadBBWeight = + BPI ? BPI->getEdgeWeight(InvokeMBB->getBasicBlock(), EHPadBB) : 0; + findUnwindDestinations(FuncInfo, EHPadBB, EHPadBBWeight, UnwindDests); // Update successor info. - // FIXME: The weights for catchpads will be wrong. addSuccessorWithWeight(InvokeMBB, Return); - for (MachineBasicBlock *UnwindDest : UnwindDests) { - UnwindDest->setIsEHPad(); - addSuccessorWithWeight(InvokeMBB, UnwindDest); + for (auto &UnwindDest : UnwindDests) { + UnwindDest.first->setIsEHPad(); + addSuccessorWithWeight(InvokeMBB, UnwindDest.first, UnwindDest.second); } // Drop into normal successor. @@ -4185,22 +4204,20 @@ static SDValue ExpandPowI(SDLoc DL, SDValue LHS, SDValue RHS, return DAG.getNode(ISD::FPOWI, DL, LHS.getValueType(), LHS, RHS); } -// getTruncatedArgReg - Find underlying register used for an truncated -// argument. -static unsigned getTruncatedArgReg(const SDValue &N) { - if (N.getOpcode() != ISD::TRUNCATE) +// getUnderlyingArgReg - Find underlying register used for a truncated or +// bitcasted argument. +static unsigned getUnderlyingArgReg(const SDValue &N) { + switch (N.getOpcode()) { + case ISD::CopyFromReg: + return cast(N.getOperand(1))->getReg(); + case ISD::BITCAST: + case ISD::AssertZext: + case ISD::AssertSext: + case ISD::TRUNCATE: + return getUnderlyingArgReg(N.getOperand(0)); + default: return 0; - - const SDValue &Ext = N.getOperand(0); - if (Ext.getOpcode() == ISD::AssertZext || - Ext.getOpcode() == ISD::AssertSext) { - const SDValue &CFR = Ext.getOperand(0); - if (CFR.getOpcode() == ISD::CopyFromReg) - return cast(CFR.getOperand(1))->getReg(); - if (CFR.getOpcode() == ISD::TRUNCATE) - return getTruncatedArgReg(CFR); } - return 0; } /// EmitFuncArgumentDbgValue - If the DbgValueInst is a dbg_value of a function @@ -4228,11 +4245,7 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue( Op = MachineOperand::CreateFI(FI); if (!Op && N.getNode()) { - unsigned Reg; - if (N.getOpcode() == ISD::CopyFromReg) - Reg = cast(N.getOperand(1))->getReg(); - else - Reg = getTruncatedArgReg(N); + unsigned Reg = getUnderlyingArgReg(N); if (Reg && TargetRegisterInfo::isVirtualRegister(Reg)) { MachineRegisterInfo &RegInfo = MF.getRegInfo(); unsigned PR = RegInfo.getLiveInPhysReg(Reg); @@ -5152,9 +5165,6 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { } case Intrinsic::clear_cache: return TLI.getClearCacheBuiltinName(); - case Intrinsic::eh_actions: - setValue(&I, DAG.getUNDEF(TLI.getPointerTy(DAG.getDataLayout()))); - return nullptr; case Intrinsic::donothing: // ignore return nullptr; @@ -5238,22 +5248,6 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { return nullptr; } - case Intrinsic::eh_begincatch: - case Intrinsic::eh_endcatch: - llvm_unreachable("begin/end catch intrinsics not lowered in codegen"); - case Intrinsic::eh_exceptioncode_old: { - unsigned Reg = TLI.getExceptionPointerRegister(); - assert(Reg && "cannot get exception code on this platform"); - MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout()); - const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT); - assert(FuncInfo.MBB->isEHPad() && "eh.exceptioncode in non-lpad"); - unsigned VReg = FuncInfo.MBB->addLiveIn(Reg, PtrRC); - SDValue N = - DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT); - N = DAG.getZExtOrTrunc(N, getCurSDLoc(), MVT::i32); - setValue(&I, N); - return nullptr; - } case Intrinsic::eh_exceptionpointer: case Intrinsic::eh_exceptioncode: {