X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAGBuilder.cpp;h=a48de572113750efe9a1c2804b4f92236064b2df;hp=6fba18d60b281d67f1bdbd9610deba2a4448814a;hb=39b3d70179e9ee0d8770aa08bc2400b5fdcc9aa1;hpb=69d051c87d28550b8721143a4d3135b4fa593af0 diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 6fba18d60b2..a48de572113 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -80,7 +80,7 @@ LimitFPPrecision("limit-float-precision", cl::init(0)); static cl::opt -EnableFMFInDAG("enable-fmf-dag", cl::init(false), cl::Hidden, +EnableFMFInDAG("enable-fmf-dag", cl::init(true), cl::Hidden, cl::desc("Enable fast-math-flags for DAG nodes")); // Limit the width of DAG chains. This is important in general to prevent @@ -1165,9 +1165,8 @@ void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) { void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) { // Update machine-CFG edge. - MachineBasicBlock *PadMBB = FuncInfo.MBB; MachineBasicBlock *TargetMBB = FuncInfo.MBBMap[I.getSuccessor()]; - PadMBB->addSuccessor(TargetMBB); + FuncInfo.MBB->addSuccessor(TargetMBB); // Create the terminator node. SDValue Ret = DAG.getNode(ISD::CATCHRET, getCurSDLoc(), MVT::Other, @@ -1180,11 +1179,65 @@ void SelectionDAGBuilder::visitCatchEndPad(const CatchEndPadInst &I) { } void SelectionDAGBuilder::visitCleanupPad(const CleanupPadInst &CPI) { - report_fatal_error("visitCleanupPad not yet implemented!"); + // Don't emit any special code for the cleanuppad instruction. It just marks + // the start of a funclet. + FuncInfo.MBB->setIsEHFuncletEntry(); + FuncInfo.MBB->setIsCleanupFuncletEntry(); +} + +/// When an invoke or a cleanupret unwinds to the next EH pad, there are +/// many places it could ultimately go. In the IR, we have a single unwind +/// 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) { + bool IsMSVCCXX = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()) == + EHPersonality::MSVC_CXX; + while (EHPadBB) { + const Instruction *Pad = EHPadBB->getFirstNonPHI(); + if (isa(Pad)) { + // Stop on landingpads. They are not funclets. + UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + break; + } else if (isa(Pad) || isa(Pad)) { + // Stop on cleanup pads. Cleanups are always funclet entries for all known + // personalities. + UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + UnwindDests.back()->setIsEHFuncletEntry(); + break; + } else if (const auto *CPI = dyn_cast(Pad)) { + // Add the catchpad handler to the possible destinations. + UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]); + // In MSVC C++, catchblocks are funclets and need prologues. + if (IsMSVCCXX) + 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(); + } + } } void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) { - report_fatal_error("visitCleanupRet not yet implemented!"); + // 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); + } + + // Create the terminator node. + SDValue Ret = + DAG.getNode(ISD::CLEANUPRET, getCurSDLoc(), MVT::Other, getControlRoot()); + DAG.setRoot(Ret); } void SelectionDAGBuilder::visitCleanupEndPad(const CleanupEndPadInst &I) { @@ -2020,37 +2073,8 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { CopyToExportRegsIfNeeded(&I); } - // Stop when we hit a pad that generates real code or we unwind to caller. - // Catchpads are conditional branches that add real MBB destinations and - // continue the loop. EH "end" pads are not real BBs and simply continue. SmallVector UnwindDests; - bool IsMSVCCXX = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()) == - EHPersonality::MSVC_CXX; - while (EHPadBB) { - const Instruction *Pad = EHPadBB->getFirstNonPHI(); - if (isa(Pad)) { - // Stop on landingpads. They are not funclets. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); - break; - } else if (isa(Pad) || isa(Pad)) { - // Stop on cleanup pads. Cleanups are always funclet entries for all known - // personalities. - UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); - UnwindDests.back()->setIsEHFuncletEntry(); - break; - } else if (const auto *CPI = dyn_cast(Pad)) { - // Add the catchpad handler to the possible destinations. - UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]); - // In MSVC C++, catchblocks are funclets and need prologues. - if (IsMSVCCXX) - 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(); - } - } + findUnwindDestinations(FuncInfo, EHPadBB, UnwindDests); // Update successor info. // FIXME: The weights for catchpads will be wrong. @@ -2181,10 +2205,7 @@ void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) { getValue(I.getAddress()))); } -void SelectionDAGBuilder::visitUnreachable(const UnreachableInst &I) { - if (DAG.getTarget().Options.TrapUnreachable) - DAG.setRoot(DAG.getNode(ISD::TRAP, getCurSDLoc(), MVT::Other, DAG.getRoot())); -} +void SelectionDAGBuilder::visitUnreachable(const UnreachableInst &I) {} void SelectionDAGBuilder::visitFSub(const User &I) { // -0.0 - X --> fneg @@ -2324,6 +2345,10 @@ void SelectionDAGBuilder::visitFCmp(const User &I) { SDValue Op1 = getValue(I.getOperand(0)); SDValue Op2 = getValue(I.getOperand(1)); ISD::CondCode Condition = getFCmpCondCode(predicate); + + // FIXME: Fcmp instructions have fast-math-flags in IR, so we should use them. + // FIXME: We should propagate the fast-math-flags to the DAG node itself for + // further optimization, but currently FMF is only applicable to binary nodes. if (TM.Options.NoNaNsFPMath) Condition = getFCmpCodeWithoutNaN(Condition); EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(), @@ -3606,6 +3631,8 @@ getF32Constant(SelectionDAG &DAG, unsigned Flt, SDLoc dl) { static SDValue getLimitedPrecisionExp2(SDValue t0, SDLoc dl, SelectionDAG &DAG) { + // TODO: What fast-math-flags should be set on the floating-point nodes? + // IntegerPartOfX = ((int32_t)(t0); SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, t0); @@ -3704,6 +3731,8 @@ static SDValue expandExp(SDLoc dl, SDValue Op, SelectionDAG &DAG, // // #define LOG2OFe 1.4426950f // t0 = Op * LOG2OFe + + // TODO: What fast-math-flags should be set here? SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op, getF32Constant(DAG, 0x3fb8aa3b, dl)); return getLimitedPrecisionExp2(t0, dl, DAG); @@ -3717,6 +3746,9 @@ static SDValue expandExp(SDLoc dl, SDValue Op, SelectionDAG &DAG, /// limited-precision mode. static SDValue expandLog(SDLoc dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI) { + + // TODO: What fast-math-flags should be set on the floating-point nodes? + if (Op.getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { SDValue Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op); @@ -3813,6 +3845,9 @@ static SDValue expandLog(SDLoc dl, SDValue Op, SelectionDAG &DAG, /// limited-precision mode. static SDValue expandLog2(SDLoc dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI) { + + // TODO: What fast-math-flags should be set on the floating-point nodes? + if (Op.getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { SDValue Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op); @@ -3908,6 +3943,9 @@ static SDValue expandLog2(SDLoc dl, SDValue Op, SelectionDAG &DAG, /// limited-precision mode. static SDValue expandLog10(SDLoc dl, SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI) { + + // TODO: What fast-math-flags should be set on the floating-point nodes? + if (Op.getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { SDValue Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op); @@ -4017,6 +4055,7 @@ static SDValue expandPow(SDLoc dl, SDValue LHS, SDValue RHS, } } + // TODO: What fast-math-flags should be set on the FMUL node? if (IsExp10) { // Put the exponent in the right bit position for later addition to the // final result: @@ -4060,6 +4099,8 @@ static SDValue ExpandPowI(SDLoc DL, SDValue LHS, SDValue RHS, // the benefit of being both really simple and much better than a libcall. SDValue Res; // Logically starts equal to 1.0 SDValue CurSquare = LHS; + // TODO: Intrinsics should have fast-math-flags that propagate to these + // nodes. while (Val) { if (Val & 1) { if (Res.getNode()) @@ -4350,15 +4391,9 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { N); return nullptr; } - } else if (AI) + } else { SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(), true, 0, dl, SDNodeOrder); - else { - // Can't do anything with other non-AI cases yet. - DEBUG(dbgs() << "Dropping debug info for " << DI << "\n"); - DEBUG(dbgs() << "non-AllocaInst issue for Address: \n\t"); - DEBUG(Address->dump()); - return nullptr; } DAG.AddDbgValue(SDV, N.getNode(), isParameter); } else { @@ -4713,6 +4748,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { getValue(I.getArgOperand(1)), getValue(I.getArgOperand(2)))); } else { + // TODO: Intrinsic calls should have fast-math-flags. SDValue Mul = DAG.getNode(ISD::FMUL, sdl, getValue(I.getArgOperand(0)).getValueType(), getValue(I.getArgOperand(0)), @@ -5218,7 +5254,13 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI, DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getRoot(), EndLabel)); // Inform MachineModuleInfo of range. - MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel); + if (MMI.hasEHFunclets()) { + WinEHFuncInfo &EHInfo = + MMI.getWinEHFuncInfo(DAG.getMachineFunction().getFunction()); + EHInfo.addIPToStateRange(EHPadBB, BeginLabel, EndLabel); + } else { + MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel); + } } return Result; @@ -6089,7 +6131,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { SDISelAsmOperandInfo &Input = ConstraintOperands[OpInfo.MatchingInput]; if (OpInfo.ConstraintVT != Input.ConstraintVT) { - const TargetRegisterInfo *TRI = DAG.getSubtarget().getRegisterInfo(); + const TargetRegisterInfo *TRI = DAG.getSubtarget().getRegisterInfo(); std::pair MatchRC = TLI.getRegForInlineAsmConstraint(TRI, OpInfo.ConstraintCode, OpInfo.ConstraintVT); @@ -8102,13 +8144,13 @@ void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond, uint32_t JumpWeight = I->Weight; uint32_t FallthroughWeight = UnhandledWeights; - // If Fallthrough is a target of the jump table, we evenly distribute - // the weight on the edge to Fallthrough to successors of CurMBB. - // Also update the weight on the edge from JumpMBB to Fallthrough. + // If the default statement is a target of the jump table, we evenly + // distribute the default weight to successors of CurMBB. Also update + // the weight on the edge from JumpMBB to Fallthrough. for (MachineBasicBlock::succ_iterator SI = JumpMBB->succ_begin(), SE = JumpMBB->succ_end(); SI != SE; ++SI) { - if (*SI == Fallthrough) { + if (*SI == DefaultMBB) { JumpWeight += DefaultWeight / 2; FallthroughWeight -= DefaultWeight / 2; JumpMBB->setSuccWeight(SI, DefaultWeight / 2);