X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FFunctionLoweringInfo.cpp;h=b0d8103093192d60175702ef965a547f62982d7e;hb=a03aa8f8e72231673a35b6df5c42690630e2d186;hp=bb40326ba2d16308178755602ff925599b33feaa;hpb=9dea1d0d01f611d15fe4963d2241bc10546a243f;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index bb40326ba2d..b0d81030931 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -80,28 +80,6 @@ static ISD::NodeType getPreferredExtendForValue(const Value *V) { return ExtendKind; } -namespace { -struct WinEHNumbering { - WinEHNumbering(WinEHFuncInfo &FuncInfo) : FuncInfo(FuncInfo), NextState(0) {} - - WinEHFuncInfo &FuncInfo; - int NextState; - - SmallVector HandlerStack; - SmallPtrSet VisitedHandlers; - - int currentEHNumber() const { - return HandlerStack.empty() ? -1 : HandlerStack.back()->getEHState(); - } - - void createUnwindMapEntry(int ToState, ActionHandler *AH); - void createTryBlockMapEntry(int TryLow, int TryHigh, - ArrayRef Handlers); - void processCallSite(ArrayRef Actions, ImmutableCallSite CS); - void calculateStateNumbers(const Function &F); -}; -} - void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, SelectionDAG *DAG) { Fn = &fn; @@ -112,7 +90,8 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // Check whether the function can return without sret-demotion. SmallVector Outs; - GetReturnInfo(Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI); + GetReturnInfo(Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI, + mf.getDataLayout()); CanLowerReturn = TLI->CanLowerReturn(Fn->getCallingConv(), *MF, Fn->isVarArg(), Outs, Fn->getContext()); @@ -128,9 +107,9 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, if (AI->isStaticAlloca()) { const ConstantInt *CUI = cast(AI->getArraySize()); Type *Ty = AI->getAllocatedType(); - uint64_t TySize = TLI->getDataLayout()->getTypeAllocSize(Ty); + uint64_t TySize = MF->getDataLayout().getTypeAllocSize(Ty); unsigned Align = - std::max((unsigned)TLI->getDataLayout()->getPrefTypeAlignment(Ty), + std::max((unsigned)MF->getDataLayout().getPrefTypeAlignment(Ty), AI->getAlignment()); TySize *= CUI->getZExtValue(); // Get total allocated size. @@ -140,10 +119,10 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, MF->getFrameInfo()->CreateStackObject(TySize, Align, false, AI); } else { - unsigned Align = std::max( - (unsigned)TLI->getDataLayout()->getPrefTypeAlignment( - AI->getAllocatedType()), - AI->getAlignment()); + unsigned Align = + std::max((unsigned)MF->getDataLayout().getPrefTypeAlignment( + AI->getAllocatedType()), + AI->getAlignment()); unsigned StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlignment(); if (Align <= StackAlign) @@ -160,7 +139,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); std::vector Ops = - TLI->ParseConstraints(TRI, CS); + TLI->ParseConstraints(Fn->getParent()->getDataLayout(), TRI, CS); for (size_t I = 0, E = Ops.size(); I != E; ++I) { TargetLowering::AsmOperandInfo &Op = Ops[I]; if (Op.Type == InlineAsm::isClobber) { @@ -170,7 +149,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, TLI->getRegForInlineAsmConstraint(TRI, Op.ConstraintCode, Op.ConstraintVT); if (PhysReg.first == SP) - MF->getFrameInfo()->setHasInlineAsmWithSPAdjust(true); + MF->getFrameInfo()->setHasOpaqueSPAdjustment(true); } } } @@ -202,8 +181,9 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // during the initial isel pass through the IR so that it is done // in a predictable order. if (const DbgDeclareInst *DI = dyn_cast(I)) { - DIVariable DIVar = DI->getVariable(); - if (MMI.hasDebugInfo() && DIVar && DI->getDebugLoc()) { + assert(DI->getVariable() && "Missing variable"); + assert(DI->getDebugLoc() && "Missing location"); + if (MMI.hasDebugInfo()) { // Don't handle byval struct arguments or VLAs, for example. // Non-byval arguments are handled here (they refer to the stack // temporary alloca at this point). @@ -232,6 +212,23 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // also creates the initial PHI MachineInstrs, though none of the input // operands are populated. for (BB = Fn->begin(); BB != EB; ++BB) { + // Don't create MachineBasicBlocks for imaginary EH pad blocks. These blocks + // are really data, and no instructions can live here. + if (BB->isEHPad()) { + const Instruction *I = BB->getFirstNonPHI(); + // FIXME: Don't mark SEH functions without __finally blocks as having + // funclets. + if (!isa(I)) + MMI.setHasEHFunclets(true); + if (isa(I) || isa(I)) { + assert(&*BB->begin() == I && + "WinEHPrepare failed to remove PHIs from imaginary BBs"); + continue; + } + if (isa(I) || isa(I)) + assert(&*BB->begin() == I && "WinEHPrepare failed to demote PHIs"); + } + MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB); MBBMap[BB] = MBB; MF->push_back(MBB); @@ -257,7 +254,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, assert(PHIReg && "PHI node does not have an assigned virtual register!"); SmallVector ValueVTs; - ComputeValueVTs(*TLI, PN->getType(), ValueVTs); + ComputeValueVTs(*TLI, MF->getDataLayout(), PN->getType(), ValueVTs); for (unsigned vti = 0, vte = ValueVTs.size(); vti != vte; ++vti) { EVT VT = ValueVTs[vti]; unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); @@ -270,230 +267,75 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, } // Mark landing pad blocks. - const LandingPadInst *LP = nullptr; + SmallVector LPads; for (BB = Fn->begin(); BB != EB; ++BB) { - if (const auto *Invoke = dyn_cast(BB->getTerminator())) - MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad(); - if (BB->isLandingPad()) - LP = BB->getLandingPadInst(); - } - - // Calculate EH numbers for MSVC C++ EH and save SEH handlers if necessary. - EHPersonality Personality = EHPersonality::Unknown; - if (LP) - Personality = classifyEHPersonality(LP->getPersonalityFn()); - if (Personality == EHPersonality::MSVC_Win64SEH) { - addSEHHandlersForLPads(); - } else if (Personality == EHPersonality::MSVC_CXX) { - const Function *WinEHParentFn = MMI.getWinEHParent(&fn); - WinEHFuncInfo &FI = MMI.getWinEHFuncInfo(WinEHParentFn); - if (FI.LandingPadStateMap.empty()) { - WinEHNumbering Num(FI); - Num.calculateStateNumbers(*WinEHParentFn); - // Pop everything on the handler stack. - Num.processCallSite(None, ImmutableCallSite()); - } + const Instruction *FNP = BB->getFirstNonPHI(); + if (BB->isEHPad() && MBBMap.count(BB)) + MBBMap[BB]->setIsEHPad(); + if (const auto *LPI = dyn_cast(FNP)) + LPads.push_back(LPI); } -} - -void FunctionLoweringInfo::addSEHHandlersForLPads() { - MachineModuleInfo &MMI = MF->getMMI(); - // Iterate over all landing pads with llvm.eh.actions calls. - for (const BasicBlock &BB : *Fn) { - const LandingPadInst *LP = BB.getLandingPadInst(); - if (!LP) - continue; - const IntrinsicInst *ActionsCall = - dyn_cast(LP->getNextNode()); - if (!ActionsCall || - ActionsCall->getIntrinsicID() != Intrinsic::eh_actions) - continue; + // If this personality uses funclets, we need to do a bit more work. + if (!Fn->hasPersonalityFn()) + return; + EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn()); + if (!isFuncletEHPersonality(Personality)) + return; - // Parse the llvm.eh.actions call we found. - MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()]; - SmallVector Actions; - parseEHActions(ActionsCall, Actions); - - // Iterate EH actions from most to least precedence, which means - // iterating in reverse. - for (auto I = Actions.rbegin(), E = Actions.rend(); I != E; ++I) { - ActionHandler *Action = *I; - if (auto *CH = dyn_cast(Action)) { - const auto *Filter = - dyn_cast(CH->getSelector()->stripPointerCasts()); - assert((Filter || CH->getSelector()->isNullValue()) && - "expected function or catch-all"); - const auto *RecoverBA = - cast(CH->getHandlerBlockOrFunc()); - MMI.addSEHCatchHandler(LPadMBB, Filter, RecoverBA); + // Calculate state numbers if we haven't already. + WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn); + if (Personality == EHPersonality::MSVC_CXX) + calculateWinCXXEHStateNumbers(&fn, EHInfo); + else if (isAsynchronousEHPersonality(Personality)) + calculateSEHStateNumbers(&fn, EHInfo); + else if (Personality == EHPersonality::CoreCLR) + calculateClrEHStateNumbers(&fn, EHInfo); + + calculateCatchReturnSuccessorColors(&fn, EHInfo); + + // Map all BB references in the WinEH data to MBBs. + for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { + for (WinEHHandlerType &H : TBME.HandlerArray) { + if (H.CatchObjRecoverIdx == -2 && H.CatchObj.Alloca) { + assert(StaticAllocaMap.count(H.CatchObj.Alloca)); + H.CatchObj.FrameIndex = StaticAllocaMap[H.CatchObj.Alloca]; } else { - assert(isa(Action)); - const auto *Fini = cast(Action->getHandlerBlockOrFunc()); - MMI.addSEHCleanupHandler(LPadMBB, Fini); + H.CatchObj.FrameIndex = INT_MAX; } + if (H.Handler) + H.Handler = MBBMap[H.Handler.get()]; } - DeleteContainerPointers(Actions); - } -} - -void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) { - WinEHUnwindMapEntry UME; - UME.ToState = ToState; - if (auto *CH = dyn_cast_or_null(AH)) - UME.Cleanup = cast(CH->getHandlerBlockOrFunc()); - else - UME.Cleanup = nullptr; - FuncInfo.UnwindMap.push_back(UME); -} - -void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh, - ArrayRef Handlers) { - WinEHTryBlockMapEntry TBME; - TBME.TryLow = TryLow; - TBME.TryHigh = TryHigh; - assert(TBME.TryLow <= TBME.TryHigh); - for (CatchHandler *CH : Handlers) { - WinEHHandlerType HT; - if (CH->getSelector()->isNullValue()) { - HT.Adjectives = 0x40; - HT.TypeDescriptor = nullptr; - } else { - auto *GV = cast(CH->getSelector()->stripPointerCasts()); - // Selectors are always pointers to GlobalVariables with 'struct' type. - // The struct has two fields, adjectives and a type descriptor. - auto *CS = cast(GV->getInitializer()); - HT.Adjectives = - cast(CS->getAggregateElement(0U))->getZExtValue(); - HT.TypeDescriptor = - cast(CS->getAggregateElement(1)->stripPointerCasts()); - } - HT.Handler = cast(CH->getHandlerBlockOrFunc()); - HT.CatchObjRecoverIdx = CH->getExceptionVarIndex(); - TBME.HandlerArray.push_back(HT); } - FuncInfo.TryBlockMap.push_back(TBME); -} - -static void print_name(const Value *V) { -#ifndef NDEBUG - if (!V) { - DEBUG(dbgs() << "null"); - return; - } - - if (const auto *F = dyn_cast(V)) - DEBUG(dbgs() << F->getName()); - else - DEBUG(V->dump()); -#endif -} - -void WinEHNumbering::processCallSite(ArrayRef Actions, - ImmutableCallSite CS) { - int FirstMismatch = 0; - for (int E = std::min(HandlerStack.size(), Actions.size()); FirstMismatch < E; - ++FirstMismatch) { - if (HandlerStack[FirstMismatch]->getHandlerBlockOrFunc() != - Actions[FirstMismatch]->getHandlerBlockOrFunc()) - break; - delete Actions[FirstMismatch]; - } - - bool EnteringScope = (int)Actions.size() > FirstMismatch; - - // Don't recurse while we are looping over the handler stack. Instead, defer - // the numbering of the catch handlers until we are done popping. - SmallVector PoppedCatches; - for (int I = HandlerStack.size() - 1; I >= FirstMismatch; --I) { - if (auto *CH = dyn_cast(HandlerStack.back())) { - PoppedCatches.push_back(CH); - } else { - // Delete cleanup handlers - delete HandlerStack.back(); - } - HandlerStack.pop_back(); - } - - // We need to create a new state number if we are exiting a try scope and we - // will not push any more actions. - int TryHigh = NextState - 1; - if (!EnteringScope && !PoppedCatches.empty()) { - createUnwindMapEntry(currentEHNumber(), nullptr); - ++NextState; + for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap) + if (UME.Cleanup) + UME.Cleanup = MBBMap[UME.Cleanup.get()]; + for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) { + const BasicBlock *BB = UME.Handler.get(); + UME.Handler = MBBMap[BB]; } - - int LastTryLowIdx = 0; - for (int I = 0, E = PoppedCatches.size(); I != E; ++I) { - CatchHandler *CH = PoppedCatches[I]; - if (I + 1 == E || CH->getEHState() != PoppedCatches[I + 1]->getEHState()) { - int TryLow = CH->getEHState(); - auto Handlers = - makeArrayRef(&PoppedCatches[LastTryLowIdx], I - LastTryLowIdx + 1); - createTryBlockMapEntry(TryLow, TryHigh, Handlers); - LastTryLowIdx = I + 1; - } + for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) { + const BasicBlock *BB = CME.Handler.get(); + CME.Handler = MBBMap[BB]; } - for (CatchHandler *CH : PoppedCatches) { - if (auto *F = dyn_cast(CH->getHandlerBlockOrFunc())) - calculateStateNumbers(*F); - delete CH; + // If there's an explicit EH registration node on the stack, record its + // frame index. + if (EHInfo.EHRegNode && EHInfo.EHRegNode->getParent()->getParent() == Fn) { + assert(StaticAllocaMap.count(EHInfo.EHRegNode)); + EHInfo.EHRegNodeFrameIndex = StaticAllocaMap[EHInfo.EHRegNode]; } - bool LastActionWasCatch = false; - for (size_t I = FirstMismatch; I != Actions.size(); ++I) { - // We can reuse eh states when pushing two catches for the same invoke. - bool CurrActionIsCatch = isa(Actions[I]); - // FIXME: Reenable this optimization! - if (CurrActionIsCatch && LastActionWasCatch && false) { - Actions[I]->setEHState(currentEHNumber()); - } else { - createUnwindMapEntry(currentEHNumber(), Actions[I]); - Actions[I]->setEHState(NextState); - NextState++; - DEBUG(dbgs() << "Creating unwind map entry for: ("); - print_name(Actions[I]->getHandlerBlockOrFunc()); - DEBUG(dbgs() << ", " << currentEHNumber() << ")\n"); + // Copy the state numbers to LandingPadInfo for the current function, which + // could be a handler or the parent. This should happen for 32-bit SEH and + // C++ EH. + if (Personality == EHPersonality::MSVC_CXX || + Personality == EHPersonality::MSVC_X86SEH) { + for (const LandingPadInst *LP : LPads) { + MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()]; + MMI.addWinEHState(LPadMBB, EHInfo.EHPadStateMap[LP]); } - HandlerStack.push_back(Actions[I]); - LastActionWasCatch = CurrActionIsCatch; } - - DEBUG(dbgs() << "In EHState " << currentEHNumber() << " for CallSite: "); - print_name(CS ? CS.getCalledValue() : nullptr); - DEBUG(dbgs() << '\n'); -} - -void WinEHNumbering::calculateStateNumbers(const Function &F) { - auto I = VisitedHandlers.insert(&F); - if (!I.second) - return; // We've already visited this handler, don't renumber it. - - DEBUG(dbgs() << "Calculating state numbers for: " << F.getName() << '\n'); - SmallVector ActionList; - for (const BasicBlock &BB : F) { - for (const Instruction &I : BB) { - const auto *CI = dyn_cast(&I); - if (!CI || CI->doesNotThrow()) - continue; - processCallSite(None, CI); - } - const auto *II = dyn_cast(BB.getTerminator()); - if (!II) - continue; - const LandingPadInst *LPI = II->getLandingPadInst(); - auto *ActionsCall = dyn_cast(LPI->getNextNode()); - if (!ActionsCall) - continue; - assert(ActionsCall->getIntrinsicID() == Intrinsic::eh_actions); - parseEHActions(ActionsCall, ActionList); - processCallSite(ActionList, II); - ActionList.clear(); - FuncInfo.LandingPadStateMap[LPI] = currentEHNumber(); - } - - FuncInfo.CatchHandlerMaxState[&F] = NextState - 1; } /// clear - Clear out all the function-specific state. This returns this @@ -516,6 +358,7 @@ void FunctionLoweringInfo::clear() { ByValArgFrameIndexMap.clear(); RegFixups.clear(); StatepointStackSlots.clear(); + StatepointRelocatedValues.clear(); PreferredExtendType.clear(); } @@ -536,7 +379,7 @@ unsigned FunctionLoweringInfo::CreateRegs(Type *Ty) { const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); SmallVector ValueVTs; - ComputeValueVTs(*TLI, Ty, ValueVTs); + ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); unsigned FirstReg = 0; for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { @@ -583,7 +426,7 @@ void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) { return; SmallVector ValueVTs; - ComputeValueVTs(*TLI, Ty, ValueVTs); + ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); assert(ValueVTs.size() == 1 && "PHIs with non-vector integer types should have a single VT."); EVT IntVT = ValueVTs[0]; @@ -689,6 +532,17 @@ int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) { return 0; } +unsigned FunctionLoweringInfo::getCatchPadExceptionPointerVReg( + const Value *CPI, const TargetRegisterClass *RC) { + MachineRegisterInfo &MRI = MF->getRegInfo(); + auto I = CatchPadExceptionPointers.insert({CPI, 0}); + unsigned &VReg = I.first->second; + if (I.second) + VReg = MRI.createVirtualRegister(RC); + assert(VReg && "null vreg in exception pointer table!"); + return VReg; +} + /// ComputeUsesVAFloatArgument - Determine if any floating-point values are /// being passed to this variadic function, and set the MachineModuleInfo's /// usesVAFloatArgument flag if so. This flag is used to emit an undefined @@ -716,8 +570,9 @@ void llvm::ComputeUsesVAFloatArgument(const CallInst &I, /// landingpad instruction and add them to the specified machine module info. void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI, MachineBasicBlock *MBB) { - MMI.addPersonality(MBB, - cast(I.getPersonalityFn()->stripPointerCasts())); + if (const auto *PF = dyn_cast( + I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts())) + MMI.addPersonality(PF); if (I.isCleanup()) MMI.addCleanup(MBB);