aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp')
-rw-r--r--contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp196
1 files changed, 99 insertions, 97 deletions
diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index cc306cbf5ae4..b62bd2bd63ee 100644
--- a/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/contrib/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -87,6 +87,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
TLI = MF->getSubtarget().getTargetLowering();
RegInfo = &MF->getRegInfo();
MachineModuleInfo &MMI = MF->getMMI();
+ const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
// Check whether the function can return without sret-demotion.
SmallVector<ISD::OutputArg, 4> Outs;
@@ -103,28 +104,29 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
if (const AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
- // Static allocas can be folded into the initial stack frame adjustment.
- if (AI->isStaticAlloca()) {
+ Type *Ty = AI->getAllocatedType();
+ unsigned Align =
+ std::max((unsigned)MF->getDataLayout().getPrefTypeAlignment(Ty),
+ AI->getAlignment());
+ unsigned StackAlign = TFI->getStackAlignment();
+
+ // Static allocas can be folded into the initial stack frame
+ // adjustment. For targets that don't realign the stack, don't
+ // do this if there is an extra alignment requirement.
+ if (AI->isStaticAlloca() &&
+ (TFI->isStackRealignable() || (Align <= StackAlign))) {
const ConstantInt *CUI = cast<ConstantInt>(AI->getArraySize());
- Type *Ty = AI->getAllocatedType();
uint64_t TySize = MF->getDataLayout().getTypeAllocSize(Ty);
- unsigned Align =
- std::max((unsigned)MF->getDataLayout().getPrefTypeAlignment(Ty),
- AI->getAlignment());
TySize *= CUI->getZExtValue(); // Get total allocated size.
if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.
StaticAllocaMap[AI] =
MF->getFrameInfo()->CreateStackObject(TySize, Align, false, AI);
-
} else {
- unsigned Align =
- std::max((unsigned)MF->getDataLayout().getPrefTypeAlignment(
- AI->getAllocatedType()),
- AI->getAlignment());
- unsigned StackAlign =
- MF->getSubtarget().getFrameLowering()->getStackAlignment();
+ // FIXME: Overaligned static allocas should be grouped into
+ // a single dynamic allocation instead of using a separate
+ // stack allocation for each one.
if (Align <= StackAlign)
Align = 0;
// Inform the Frame Information that we have variable-sized objects.
@@ -134,7 +136,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
// Look for inline asm that clobbers the SP register.
if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
- ImmutableCallSite CS(I);
+ ImmutableCallSite CS(&*I);
if (isa<InlineAsm>(CS.getCalledValue())) {
unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
@@ -163,7 +165,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
MF->getFrameInfo()->setHasVAStart(true);
}
- // If we have a musttail call in a variadic funciton, we need to ensure we
+ // If we have a musttail call in a variadic function, we need to ensure we
// forward implicit register parameters.
if (const auto *CI = dyn_cast<CallInst>(I)) {
if (CI->isMustTailCall() && Fn->isVarArg())
@@ -172,10 +174,9 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
// Mark values used outside their block as exported, by allocating
// a virtual register for them.
- if (isUsedOutsideOfDefiningBlock(I))
- if (!isa<AllocaInst>(I) ||
- !StaticAllocaMap.count(cast<AllocaInst>(I)))
- InitializeRegForValue(I);
+ if (isUsedOutsideOfDefiningBlock(&*I))
+ if (!isa<AllocaInst>(I) || !StaticAllocaMap.count(cast<AllocaInst>(I)))
+ InitializeRegForValue(&*I);
// Collect llvm.dbg.declare information. This is done now instead of
// during the initial isel pass through the IR so that it is done
@@ -205,15 +206,36 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
}
// Decide the preferred extend type for a value.
- PreferredExtendType[I] = getPreferredExtendForValue(I);
+ PreferredExtendType[&*I] = getPreferredExtendForValue(&*I);
}
// Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This
// also creates the initial PHI MachineInstrs, though none of the input
// operands are populated.
for (BB = Fn->begin(); BB != EB; ++BB) {
- MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB);
- MBBMap[BB] = MBB;
+ // 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 this is a non-landingpad EH pad, mark this function as using
+ // funclets.
+ // FIXME: SEH catchpads do not create funclets, so we could avoid setting
+ // this in such cases in order to improve frame layout.
+ if (!isa<LandingPadInst>(I)) {
+ MMI.setHasEHFunclets(true);
+ MF->getFrameInfo()->setHasOpaqueSPAdjustment(true);
+ }
+ if (isa<CatchSwitchInst>(I)) {
+ assert(&*BB->begin() == I &&
+ "WinEHPrepare failed to remove PHIs from imaginary BBs");
+ continue;
+ }
+ if (isa<FuncletPadInst>(I))
+ assert(&*BB->begin() == I && "WinEHPrepare failed to demote PHIs");
+ }
+
+ MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(&*BB);
+ MBBMap[&*BB] = MBB;
MF->push_back(MBB);
// Transfer the address-taken flag. This is necessary because there could
@@ -252,94 +274,64 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
// Mark landing pad blocks.
SmallVector<const LandingPadInst *, 4> LPads;
for (BB = Fn->begin(); BB != EB; ++BB) {
- if (const auto *Invoke = dyn_cast<InvokeInst>(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<LandingPadInst>(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 (Fn->hasPersonalityFn())
- Personality = classifyEHPersonality(Fn->getPersonalityFn());
- if (!isMSVCEHPersonality(Personality))
+ // 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;
- if (Personality == EHPersonality::MSVC_Win64SEH ||
- Personality == EHPersonality::MSVC_X86SEH) {
- addSEHHandlersForLPads(LPads);
- }
-
- WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
- if (Personality == EHPersonality::MSVC_CXX) {
- const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
- calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
- }
-
- // 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]);
- }
- }
-}
-
-void FunctionLoweringInfo::addSEHHandlersForLPads(
- ArrayRef<const LandingPadInst *> LPads) {
- MachineModuleInfo &MMI = MF->getMMI();
-
- // Iterate over all landing pads with llvm.eh.actions calls.
- for (const LandingPadInst *LP : LPads) {
- const IntrinsicInst *ActionsCall =
- dyn_cast<IntrinsicInst>(LP->getNextNode());
- if (!ActionsCall ||
- ActionsCall->getIntrinsicID() != Intrinsic::eh_actions)
- continue;
-
- // Parse the llvm.eh.actions call we found.
- MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
- SmallVector<std::unique_ptr<ActionHandler>, 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->get();
- if (auto *CH = dyn_cast<CatchHandler>(Action)) {
- const auto *Filter =
- dyn_cast<Function>(CH->getSelector()->stripPointerCasts());
- assert((Filter || CH->getSelector()->isNullValue()) &&
- "expected function or catch-all");
- const auto *RecoverBA =
- cast<BlockAddress>(CH->getHandlerBlockOrFunc());
- MMI.addSEHCatchHandler(LPadMBB, Filter, RecoverBA);
+ // Calculate state numbers if we haven't already.
+ WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo();
+ 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.CatchObj.Alloca) {
+ assert(StaticAllocaMap.count(H.CatchObj.Alloca));
+ H.CatchObj.FrameIndex = StaticAllocaMap[H.CatchObj.Alloca];
} else {
- assert(isa<CleanupHandler>(Action));
- const auto *Fini = cast<Function>(Action->getHandlerBlockOrFunc());
- MMI.addSEHCleanupHandler(LPadMBB, Fini);
+ H.CatchObj.FrameIndex = INT_MAX;
}
+ if (H.Handler)
+ H.Handler = MBBMap[H.Handler.get<const BasicBlock *>()];
}
}
+ for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap)
+ if (UME.Cleanup)
+ UME.Cleanup = MBBMap[UME.Cleanup.get<const BasicBlock *>()];
+ for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) {
+ const BasicBlock *BB = UME.Handler.get<const BasicBlock *>();
+ UME.Handler = MBBMap[BB];
+ }
+ for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) {
+ const BasicBlock *BB = CME.Handler.get<const BasicBlock *>();
+ CME.Handler = MBBMap[BB];
+ }
}
/// clear - Clear out all the function-specific state. This returns this
/// FunctionLoweringInfo to an empty state, ready to be used for a
/// different function.
void FunctionLoweringInfo::clear() {
- assert(CatchInfoFound.size() == CatchInfoLost.size() &&
- "Not all catch info was assigned to a landing pad!");
-
MBBMap.clear();
ValueMap.clear();
StaticAllocaMap.clear();
-#ifndef NDEBUG
- CatchInfoLost.clear();
- CatchInfoFound.clear();
-#endif
LiveOutRegInfo.clear();
VisitedBBs.clear();
ArgDbgValues.clear();
@@ -520,6 +512,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
@@ -547,10 +550,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<Function>(
- I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()));
+ if (const auto *PF = dyn_cast<Function>(
+ I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()))
+ MMI.addPersonality(PF);
if (I.isCleanup())
MMI.addCleanup(MBB);