bool TargetInstrInfo::getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx, unsigned &Size, unsigned &Offset, const MachineFunction &MF) const { if (!SubIdx) { Size = RC->getSize(); Offset = 0; return true; } const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); unsigned BitSize = TRI->getSubRegIdxSize(SubIdx); // Convert bit size to byte size to be consistent with // MCRegisterClass::getSize(). if (BitSize % 8) return false; int BitOffset = TRI->getSubRegIdxOffset(SubIdx); if (BitOffset < 0 || BitOffset % 8) return false; Size = BitSize /= 8; Offset = (unsigned)BitOffset / 8; assert(RC->getSize() >= (Offset + Size) && "bad subregister range"); if (!MF.getDataLayout().isLittleEndian()) { Offset = RC->getSize() - (Offset + Size); } return true; }
void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, SelectionDAG *DAG) { Fn = &fn; MF = &mf; TLI = MF->getSubtarget().getTargetLowering(); RegInfo = &MF->getRegInfo(); const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); unsigned StackAlign = TFI->getStackAlignment(); // Check whether the function can return without sret-demotion. SmallVector<ISD::OutputArg, 4> Outs; GetReturnInfo(Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI, mf.getDataLayout()); CanLowerReturn = TLI->CanLowerReturn(Fn->getCallingConv(), *MF, Fn->isVarArg(), Outs, Fn->getContext()); // If this personality uses funclets, we need to do a bit more work. DenseMap<const AllocaInst *, TinyPtrVector<int *>> CatchObjects; EHPersonality Personality = classifyEHPersonality( Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr); if (isFuncletEHPersonality(Personality)) { // 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); // Map all BB references in the WinEH data to MBBs. for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { for (WinEHHandlerType &H : TBME.HandlerArray) { if (const AllocaInst *AI = H.CatchObj.Alloca) CatchObjects.insert({AI, {}}).first->second.push_back( &H.CatchObj.FrameIndex); else H.CatchObj.FrameIndex = INT_MAX; } } } // Initialize the mapping of values to registers. This is only set up for // instruction values that are used outside of the block that defines // them. for (const BasicBlock &BB : *Fn) { for (const Instruction &I : BB) { if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { Type *Ty = AI->getAllocatedType(); unsigned Align = std::max((unsigned)MF->getDataLayout().getPrefTypeAlignment(Ty), AI->getAlignment()); // 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()); uint64_t TySize = MF->getDataLayout().getTypeAllocSize(Ty); TySize *= CUI->getZExtValue(); // Get total allocated size. if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. int FrameIndex = INT_MAX; auto Iter = CatchObjects.find(AI); if (Iter != CatchObjects.end() && TLI->needsFixedCatchObjects()) { FrameIndex = MF->getFrameInfo().CreateFixedObject( TySize, 0, /*Immutable=*/false, /*isAliased=*/true); MF->getFrameInfo().setObjectAlignment(FrameIndex, Align); } else { FrameIndex = MF->getFrameInfo().CreateStackObject(TySize, Align, false, AI); } StaticAllocaMap[AI] = FrameIndex; // Update the catch handler information. if (Iter != CatchObjects.end()) { for (int *CatchObjPtr : Iter->second) *CatchObjPtr = FrameIndex; } } else { // 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. MF->getFrameInfo().CreateVariableSizedObject(Align ? Align : 1, AI); } } // Look for inline asm that clobbers the SP register. if (isa<CallInst>(I) || isa<InvokeInst>(I)) { ImmutableCallSite CS(&I); if (isa<InlineAsm>(CS.getCalledValue())) { unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); std::vector<TargetLowering::AsmOperandInfo> Ops = TLI->ParseConstraints(Fn->getParent()->getDataLayout(), TRI, CS); for (TargetLowering::AsmOperandInfo &Op : Ops) { if (Op.Type == InlineAsm::isClobber) { // Clobbers don't have SDValue operands, hence SDValue(). TLI->ComputeConstraintToUse(Op, SDValue(), DAG); std::pair<unsigned, const TargetRegisterClass *> PhysReg = TLI->getRegForInlineAsmConstraint(TRI, Op.ConstraintCode, Op.ConstraintVT); if (PhysReg.first == SP) MF->getFrameInfo().setHasOpaqueSPAdjustment(true); } } } } // Look for calls to the @llvm.va_start intrinsic. We can omit some // prologue boilerplate for variadic functions that don't examine their // arguments. if (const auto *II = dyn_cast<IntrinsicInst>(&I)) { if (II->getIntrinsicID() == Intrinsic::vastart) MF->getFrameInfo().setHasVAStart(true); } // 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()) MF->getFrameInfo().setHasMustTailInVarArgFunc(true); } // 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); // Decide the preferred extend type for a value. 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 (const BasicBlock &BB : *Fn) { // 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 *PadInst = 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>(PadInst)) { MF->setHasEHFunclets(true); MF->getFrameInfo().setHasOpaqueSPAdjustment(true); } if (isa<CatchSwitchInst>(PadInst)) { assert(&*BB.begin() == PadInst && "WinEHPrepare failed to remove PHIs from imaginary BBs"); continue; } if (isa<FuncletPadInst>(PadInst)) assert(&*BB.begin() == PadInst && "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 // be multiple MachineBasicBlocks corresponding to one BasicBlock, and only // the first one should be marked. if (BB.hasAddressTaken()) MBB->setHasAddressTaken(); // Mark landing pad blocks. if (BB.isEHPad()) MBB->setIsEHPad(); // Create Machine PHI nodes for LLVM PHI nodes, lowering them as // appropriate. for (BasicBlock::const_iterator I = BB.begin(); const PHINode *PN = dyn_cast<PHINode>(I); ++I) { if (PN->use_empty()) continue; // Skip empty types if (PN->getType()->isEmptyTy()) continue; DebugLoc DL = PN->getDebugLoc(); unsigned PHIReg = ValueMap[PN]; assert(PHIReg && "PHI node does not have an assigned virtual register!"); SmallVector<EVT, 4> ValueVTs; ComputeValueVTs(*TLI, MF->getDataLayout(), PN->getType(), ValueVTs); for (EVT VT : ValueVTs) { unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); for (unsigned i = 0; i != NumRegisters; ++i) BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i); PHIReg += NumRegisters; } } } if (!isFuncletEHPersonality(Personality)) return; WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo(); // Map all BB references in the WinEH data to MBBs. for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { for (WinEHHandlerType &H : TBME.HandlerArray) { 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]; } }
void AArch64FrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.begin(); const MachineFrameInfo *MFI = MF.getFrameInfo(); const Function *Fn = MF.getFunction(); const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo(); const TargetInstrInfo *TII = Subtarget.getInstrInfo(); MachineModuleInfo &MMI = MF.getMMI(); AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); bool needsFrameMoves = MMI.hasDebugInfo() || Fn->needsUnwindTableEntry(); bool HasFP = hasFP(MF); // Debug location must be unknown since the first debug location is used // to determine the end of the prologue. DebugLoc DL; // All calls are tail calls in GHC calling conv, and functions have no // prologue/epilogue. if (MF.getFunction()->getCallingConv() == CallingConv::GHC) return; int NumBytes = (int)MFI->getStackSize(); if (!AFI->hasStackFrame()) { assert(!HasFP && "unexpected function without stack frame but with FP"); // All of the stack allocation is for locals. AFI->setLocalStackSize(NumBytes); // Label used to tie together the PROLOG_LABEL and the MachineMoves. MCSymbol *FrameLabel = MMI.getContext().createTempSymbol(); // REDZONE: If the stack size is less than 128 bytes, we don't need // to actually allocate. if (NumBytes && !canUseRedZone(MF)) { emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP, -NumBytes, TII, MachineInstr::FrameSetup); // Encode the stack size of the leaf function. unsigned CFIIndex = MMI.addFrameInst( MCCFIInstruction::createDefCfaOffset(FrameLabel, -NumBytes)); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameSetup); } else if (NumBytes) { ++NumRedZoneFunctions; } return; } // Only set up FP if we actually need to. int FPOffset = 0; if (HasFP) FPOffset = getFPOffsetInPrologue(MBBI); // Move past the saves of the callee-saved registers. while (isCSSave(MBBI)) { ++MBBI; NumBytes -= 16; } assert(NumBytes >= 0 && "Negative stack allocation size!?"); if (HasFP) { // Issue sub fp, sp, FPOffset or // mov fp,sp when FPOffset is zero. // Note: All stores of callee-saved registers are marked as "FrameSetup". // This code marks the instruction(s) that set the FP also. emitFrameOffset(MBB, MBBI, DL, AArch64::FP, AArch64::SP, FPOffset, TII, MachineInstr::FrameSetup); } // All of the remaining stack allocations are for locals. AFI->setLocalStackSize(NumBytes); // Allocate space for the rest of the frame. const unsigned Alignment = MFI->getMaxAlignment(); const bool NeedsRealignment = RegInfo->needsStackRealignment(MF); unsigned scratchSPReg = AArch64::SP; if (NumBytes && NeedsRealignment) { // Use the first callee-saved register as a scratch register. scratchSPReg = AArch64::X9; } // If we're a leaf function, try using the red zone. if (NumBytes && !canUseRedZone(MF)) // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have // the correct value here, as NumBytes also includes padding bytes, // which shouldn't be counted here. emitFrameOffset(MBB, MBBI, DL, scratchSPReg, AArch64::SP, -NumBytes, TII, MachineInstr::FrameSetup); if (NumBytes && NeedsRealignment) { const unsigned NrBitsToZero = countTrailingZeros(Alignment); assert(NrBitsToZero > 1); assert(scratchSPReg != AArch64::SP); // SUB X9, SP, NumBytes // -- X9 is temporary register, so shouldn't contain any live data here, // -- free to use. This is already produced by emitFrameOffset above. // AND SP, X9, 0b11111...0000 // The logical immediates have a non-trivial encoding. The following // formula computes the encoded immediate with all ones but // NrBitsToZero zero bits as least significant bits. uint32_t andMaskEncoded = (1 <<12) // = N | ((64-NrBitsToZero) << 6) // immr | ((64-NrBitsToZero-1) << 0) // imms ; BuildMI(MBB, MBBI, DL, TII->get(AArch64::ANDXri), AArch64::SP) .addReg(scratchSPReg, RegState::Kill) .addImm(andMaskEncoded); } // If we need a base pointer, set it up here. It's whatever the value of the // stack pointer is at this point. Any variable size objects will be allocated // after this, so we can still use the base pointer to reference locals. // // FIXME: Clarify FrameSetup flags here. // Note: Use emitFrameOffset() like above for FP if the FrameSetup flag is // needed. if (RegInfo->hasBasePointer(MF)) { TII->copyPhysReg(MBB, MBBI, DL, RegInfo->getBaseRegister(), AArch64::SP, false); } if (needsFrameMoves) { const DataLayout &TD = MF.getDataLayout(); const int StackGrowth = -TD.getPointerSize(0); unsigned FramePtr = RegInfo->getFrameRegister(MF); // An example of the prologue: // // .globl __foo // .align 2 // __foo: // Ltmp0: // .cfi_startproc // .cfi_personality 155, ___gxx_personality_v0 // Leh_func_begin: // .cfi_lsda 16, Lexception33 // // stp xa,bx, [sp, -#offset]! // ... // stp x28, x27, [sp, #offset-32] // stp fp, lr, [sp, #offset-16] // add fp, sp, #offset - 16 // sub sp, sp, #1360 // // The Stack: // +-------------------------------------------+ // 10000 | ........ | ........ | ........ | ........ | // 10004 | ........ | ........ | ........ | ........ | // +-------------------------------------------+ // 10008 | ........ | ........ | ........ | ........ | // 1000c | ........ | ........ | ........ | ........ | // +===========================================+ // 10010 | X28 Register | // 10014 | X28 Register | // +-------------------------------------------+ // 10018 | X27 Register | // 1001c | X27 Register | // +===========================================+ // 10020 | Frame Pointer | // 10024 | Frame Pointer | // +-------------------------------------------+ // 10028 | Link Register | // 1002c | Link Register | // +===========================================+ // 10030 | ........ | ........ | ........ | ........ | // 10034 | ........ | ........ | ........ | ........ | // +-------------------------------------------+ // 10038 | ........ | ........ | ........ | ........ | // 1003c | ........ | ........ | ........ | ........ | // +-------------------------------------------+ // // [sp] = 10030 :: >>initial value<< // sp = 10020 :: stp fp, lr, [sp, #-16]! // fp = sp == 10020 :: mov fp, sp // [sp] == 10020 :: stp x28, x27, [sp, #-16]! // sp == 10010 :: >>final value<< // // The frame pointer (w29) points to address 10020. If we use an offset of // '16' from 'w29', we get the CFI offsets of -8 for w30, -16 for w29, -24 // for w27, and -32 for w28: // // Ltmp1: // .cfi_def_cfa w29, 16 // Ltmp2: // .cfi_offset w30, -8 // Ltmp3: // .cfi_offset w29, -16 // Ltmp4: // .cfi_offset w27, -24 // Ltmp5: // .cfi_offset w28, -32 if (HasFP) { // Define the current CFA rule to use the provided FP. unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true); unsigned CFIIndex = MMI.addFrameInst( MCCFIInstruction::createDefCfa(nullptr, Reg, 2 * StackGrowth)); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameSetup); // Record the location of the stored LR unsigned LR = RegInfo->getDwarfRegNum(AArch64::LR, true); CFIIndex = MMI.addFrameInst( MCCFIInstruction::createOffset(nullptr, LR, StackGrowth)); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameSetup); // Record the location of the stored FP CFIIndex = MMI.addFrameInst( MCCFIInstruction::createOffset(nullptr, Reg, 2 * StackGrowth)); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameSetup); } else { // Encode the stack size of the leaf function. unsigned CFIIndex = MMI.addFrameInst( MCCFIInstruction::createDefCfaOffset(nullptr, -MFI->getStackSize())); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameSetup); } // Now emit the moves for whatever callee saved regs we have. emitCalleeSavedFrameMoves(MBB, MBBI, FramePtr); } }
MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) { return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace()); }
bool GcInfoRecorder::runOnMachineFunction(MachineFunction &MF) { const Function *F = MF.getFunction(); if (!GcInfo::isGcFunction(F)) { return false; } LLILCJitContext *Context = LLILCJit::TheJit->getLLILCJitContext(); GcFuncInfo *GcFuncInfo = Context->GcInfo->getGcInfo(F); ValueMap<const AllocaInst *, AllocaInfo> &AllocaMap = GcFuncInfo->AllocaMap; #if !defined(NDEBUG) bool EmitLogs = Context->Options->LogGcInfo; if (EmitLogs) { dbgs() << "GcInfoRecorder: " << MF.getFunction()->getName() << "\n"; } #endif // !NDEBUG const MachineFrameInfo *FrameInfo = MF.getFrameInfo(); int ObjectIndexBegin = FrameInfo->getObjectIndexBegin(); int ObjectIndexEnd = FrameInfo->getObjectIndexEnd(); // FrameInfo reports the allocation offsets in terms of the // incoming (caller's) StackPointer. Convert these in terms of the // current (callee's) StackPointer. uint64_t StackPointerSize = MF.getDataLayout().getPointerSize(); uint64_t SpOffset = FrameInfo->getStackSize() + StackPointerSize; for (int Idx = ObjectIndexBegin; Idx < ObjectIndexEnd; Idx++) { const AllocaInst *Alloca = FrameInfo->getObjectAllocation(Idx); if (Alloca == nullptr) { continue; } if (GcFuncInfo->hasRecord(Alloca)) { int32_t SlotOffset = SpOffset + FrameInfo->getObjectOffset(Idx); AllocaInfo &AllocaInfo = AllocaMap[Alloca]; assert(SlotOffset >= 0); assert(AllocaInfo.Offset == GcInfo::InvalidPointerOffset && "Two slots for the same alloca!"); AllocaInfo.Offset = SlotOffset; #if !defined(NDEBUG) if (AllocaInfo.isGcAggregate()) { assert(isa<StructType>(Alloca->getAllocatedType()) && "Unhandled Type of GcAggregate"); } else if (AllocaInfo.isGcPointer()) { assert(GcInfo::isGcPointer(Alloca->getAllocatedType())); } else { assert(!GcInfo::isGcAllocation(Alloca)); } if (EmitLogs) { dbgs() << AllocaInfo.getAllocTypeString() << " @ sp+" << SlotOffset << " ["; Alloca->printAsOperand(dbgs(), false); dbgs() << "]\n"; } #endif // !NDEBUG } else { // All GC-aggregate Allocas must be registered before this phase. // This ensures that the allocations are properly initialized, // and marked as frame-escaped if necessary. // // TODO: The following check should be: // assert(!GcInfo::isGcAllocation(Alloca) && // "Gc Allocation Record missing"); #if !defined(NDEBUG) if (GcInfo::isGcAllocation(Alloca)) { // However, some Gc-pointer slots created by WinEHPrepare phase // go unrecorded currently because the AllocaInfos are recorded // by the Reader post-pass. // TODO: Report the Spill slots created by WinEHPrepare // https://github.com/dotnet/llilc/issues/901 assert(Alloca->hasName()); assert(Alloca->getName().find(".wineh.spillslot") != StringRef::npos); // WinEH shouldn't spill GC-aggregates assert(!GcInfo::isGcAggregate(Alloca->getAllocatedType())); // The unreported slots are live across safepoints in the // EH path, so the execution is correct unless we take the // exception path. assert(!(Context->Options->ExecuteHandlers && Context->Options->DoInsertStatepoints) && "Untested: Use at your own risk"); } #endif // !NDEBUG } } return false; // success }
void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, SelectionDAG *DAG) { Fn = &fn; MF = &mf; TLI = MF->getSubtarget().getTargetLowering(); RegInfo = &MF->getRegInfo(); MachineModuleInfo &MMI = MF->getMMI(); // Check whether the function can return without sret-demotion. SmallVector<ISD::OutputArg, 4> Outs; GetReturnInfo(Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI, mf.getDataLayout()); CanLowerReturn = TLI->CanLowerReturn(Fn->getCallingConv(), *MF, Fn->isVarArg(), Outs, Fn->getContext()); // Initialize the mapping of values to registers. This is only set up for // instruction values that are used outside of the block that defines // them. Function::const_iterator BB = Fn->begin(), EB = Fn->end(); for (; BB != EB; ++BB) 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()) { 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(); if (Align <= StackAlign) Align = 0; // Inform the Frame Information that we have variable-sized objects. MF->getFrameInfo()->CreateVariableSizedObject(Align ? Align : 1, AI); } } // Look for inline asm that clobbers the SP register. if (isa<CallInst>(I) || isa<InvokeInst>(I)) { ImmutableCallSite CS(I); if (isa<InlineAsm>(CS.getCalledValue())) { unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); std::vector<TargetLowering::AsmOperandInfo> Ops = 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) { // Clobbers don't have SDValue operands, hence SDValue(). TLI->ComputeConstraintToUse(Op, SDValue(), DAG); std::pair<unsigned, const TargetRegisterClass *> PhysReg = TLI->getRegForInlineAsmConstraint(TRI, Op.ConstraintCode, Op.ConstraintVT); if (PhysReg.first == SP) MF->getFrameInfo()->setHasOpaqueSPAdjustment(true); } } } } // Look for calls to the @llvm.va_start intrinsic. We can omit some // prologue boilerplate for variadic functions that don't examine their // arguments. if (const auto *II = dyn_cast<IntrinsicInst>(I)) { if (II->getIntrinsicID() == Intrinsic::vastart) MF->getFrameInfo()->setHasVAStart(true); } // If we have a musttail call in a variadic funciton, we need to ensure we // forward implicit register parameters. if (const auto *CI = dyn_cast<CallInst>(I)) { if (CI->isMustTailCall() && Fn->isVarArg()) MF->getFrameInfo()->setHasMustTailInVarArgFunc(true); } // 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); // Collect llvm.dbg.declare information. This is done now instead of // during the initial isel pass through the IR so that it is done // in a predictable order. if (const DbgDeclareInst *DI = dyn_cast<DbgDeclareInst>(I)) { 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). const Value *Address = DI->getAddress(); if (Address) { if (const BitCastInst *BCI = dyn_cast<BitCastInst>(Address)) Address = BCI->getOperand(0); if (const AllocaInst *AI = dyn_cast<AllocaInst>(Address)) { DenseMap<const AllocaInst *, int>::iterator SI = StaticAllocaMap.find(AI); if (SI != StaticAllocaMap.end()) { // Check for VLAs. int FI = SI->second; MMI.setVariableDbgInfo(DI->getVariable(), DI->getExpression(), FI, DI->getDebugLoc()); } } } } } // Decide the preferred extend type for a value. 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) { // 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<LandingPadInst>(I)) MMI.setHasEHFunclets(true); if (isa<CatchEndPadInst>(I) || isa<CleanupEndPadInst>(I)) { assert(&*BB->begin() == I && "WinEHPrepare failed to remove PHIs from imaginary BBs"); continue; } if (isa<CatchPadInst>(I) || isa<CleanupPadInst>(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 // be multiple MachineBasicBlocks corresponding to one BasicBlock, and only // the first one should be marked. if (BB->hasAddressTaken()) MBB->setHasAddressTaken(); // Create Machine PHI nodes for LLVM PHI nodes, lowering them as // appropriate. for (BasicBlock::const_iterator I = BB->begin(); const PHINode *PN = dyn_cast<PHINode>(I); ++I) { if (PN->use_empty()) continue; // Skip empty types if (PN->getType()->isEmptyTy()) continue; DebugLoc DL = PN->getDebugLoc(); unsigned PHIReg = ValueMap[PN]; assert(PHIReg && "PHI node does not have an assigned virtual register!"); SmallVector<EVT, 4> 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); const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); for (unsigned i = 0; i != NumRegisters; ++i) BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i); PHIReg += NumRegisters; } } } // Mark landing pad blocks. SmallVector<const LandingPadInst *, 4> LPads; for (BB = Fn->begin(); BB != EB; ++BB) { 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 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); } // 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); else if (Personality == EHPersonality::CoreCLR) calculateClrEHStateNumbers(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<BasicBlock>(H.Handler.get<const Value *>())) H.Handler = MBBMap[BB]; } } for (WinEHUnwindMapEntry &UME : EHInfo.UnwindMap) if (UME.Cleanup) if (const auto *BB = dyn_cast<BasicBlock>(UME.Cleanup.get<const Value *>())) UME.Cleanup = MBBMap[BB]; 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]; } // 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.EHPadStateMap[LP]); } } }