X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FFunctionLoweringInfo.cpp;h=7da68deaaa34cdeb0e3fd0954882cdd7daf784e3;hp=fc5ca3ec58635304248f410e6c963d1d90edf574;hb=68754da26da6a2068b645573270564db6a5d0de5;hpb=39789f81ab330a5582919b2edb592d2a63f6c663 diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index fc5ca3ec586..7da68deaaa3 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); } } } @@ -233,6 +212,20 @@ 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(); + if (!isa(I)) + MMI.setHasEHFunclets(true); + if (isa(I) || isa(I) || + isa(I)) { + assert(&*BB->begin() == I && + "WinEHPrepare failed to remove PHIs from imaginary BBs"); + continue; + } + } + MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB); MBBMap[BB] = MBB; MF->push_back(MBB); @@ -258,7 +251,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); @@ -273,37 +266,72 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, // Mark landing pad blocks. 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()) - LPads.push_back(BB->getLandingPadInst()); + 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); } // If this is an MSVC EH personality, we need to do a bit more work. - EHPersonality Personality = EHPersonality::Unknown; - if (!LPads.empty()) - Personality = classifyEHPersonality(LPads.back()->getPersonalityFn()); + if (!Fn->hasPersonalityFn()) + return; + EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn()); if (!isMSVCEHPersonality(Personality)) return; - WinEHFuncInfo *EHInfo = nullptr; - if (Personality == EHPersonality::MSVC_Win64SEH) { + if (Personality == EHPersonality::MSVC_Win64SEH || + Personality == EHPersonality::MSVC_X86SEH) { addSEHHandlersForLPads(LPads); - } else if (Personality == EHPersonality::MSVC_CXX) { - const Function *WinEHParentFn = MMI.getWinEHParent(&fn); - EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn); - if (EHInfo->LandingPadStateMap.empty()) { - WinEHNumbering Num(*EHInfo); - Num.calculateStateNumbers(*WinEHParentFn); - // Pop everything on the handler stack. - Num.processCallSite(None, ImmutableCallSite()); + } + + // Calculate state numbers if we haven't already. + WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn); + const Function *WinEHParentFn = MMI.getWinEHParent(&fn); + if (Personality == EHPersonality::MSVC_CXX) + calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo); + else if (isAsynchronousEHPersonality(Personality)) + calculateSEHStateNumbers(WinEHParentFn, EHInfo); + + calculateCatchReturnSuccessorColors(WinEHParentFn, 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 { + H.CatchObj.FrameIndex = INT_MAX; + } + if (const auto *BB = dyn_cast(H.Handler.get())) + H.Handler = MBBMap[BB]; } + } + for (WinEHUnwindMapEntry &UME : EHInfo.UnwindMap) + if (UME.Cleanup) + if (const auto *BB = dyn_cast(UME.Cleanup.get())) + UME.Cleanup = MBBMap[BB]; + for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) { + const BasicBlock *BB = UME.Handler.get(); + UME.Handler = MBBMap[BB]; + } - // Copy the state numbers to LandingPadInfo for the current function, which - // could be a handler or the parent. + // 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]; + } + + // 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->LandingPadStateMap[LP]); + MMI.addWinEHState(LPadMBB, EHInfo.EHPadStateMap[LP]); } } } @@ -322,13 +350,13 @@ void FunctionLoweringInfo::addSEHHandlersForLPads( // Parse the llvm.eh.actions call we found. MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()]; - SmallVector Actions; + SmallVector, 4> 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; + ActionHandler *Action = I->get(); if (auto *CH = dyn_cast(Action)) { const auto *Filter = dyn_cast(CH->getSelector()->stripPointerCasts()); @@ -343,167 +371,7 @@ void FunctionLoweringInfo::addSEHHandlersForLPads( MMI.addSEHCleanupHandler(LPadMBB, Fini); } } - 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; - } - - 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 (CatchHandler *CH : PoppedCatches) { - if (auto *F = dyn_cast(CH->getHandlerBlockOrFunc())) - calculateStateNumbers(*F); - delete CH; - } - - 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"); - } - 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 @@ -526,6 +394,7 @@ void FunctionLoweringInfo::clear() { ByValArgFrameIndexMap.clear(); RegFixups.clear(); StatepointStackSlots.clear(); + StatepointRelocatedValues.clear(); PreferredExtendType.clear(); } @@ -546,7 +415,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) { @@ -593,7 +462,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]; @@ -726,8 +595,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);