10b57cec5SDimitry Andric //===-- FunctionLoweringInfo.cpp ------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This implements routines for translating functions from LLVM IR into 100b57cec5SDimitry Andric // Machine IR. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/CodeGen/FunctionLoweringInfo.h" 150b57cec5SDimitry Andric #include "llvm/CodeGen/Analysis.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/WasmEHFuncInfo.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/WinEHFuncInfo.h" 270b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 280b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 290b57cec5SDimitry Andric #include "llvm/IR/Function.h" 300b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 310b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 320b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 330b57cec5SDimitry Andric #include "llvm/IR/Module.h" 340b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 350b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 360b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 370b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 380b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 390b57cec5SDimitry Andric #include <algorithm> 400b57cec5SDimitry Andric using namespace llvm; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric #define DEBUG_TYPE "function-lowering-info" 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric /// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by 450b57cec5SDimitry Andric /// PHI nodes or outside of the basic block that defines it, or used by a 460b57cec5SDimitry Andric /// switch or atomic instruction, which may expand to multiple basic blocks. 470b57cec5SDimitry Andric static bool isUsedOutsideOfDefiningBlock(const Instruction *I) { 480b57cec5SDimitry Andric if (I->use_empty()) return false; 490b57cec5SDimitry Andric if (isa<PHINode>(I)) return true; 500b57cec5SDimitry Andric const BasicBlock *BB = I->getParent(); 510b57cec5SDimitry Andric for (const User *U : I->users()) 520b57cec5SDimitry Andric if (cast<Instruction>(U)->getParent() != BB || isa<PHINode>(U)) 530b57cec5SDimitry Andric return true; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric return false; 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric static ISD::NodeType getPreferredExtendForValue(const Value *V) { 590b57cec5SDimitry Andric // For the users of the source value being used for compare instruction, if 600b57cec5SDimitry Andric // the number of signed predicate is greater than unsigned predicate, we 610b57cec5SDimitry Andric // prefer to use SIGN_EXTEND. 620b57cec5SDimitry Andric // 630b57cec5SDimitry Andric // With this optimization, we would be able to reduce some redundant sign or 640b57cec5SDimitry Andric // zero extension instruction, and eventually more machine CSE opportunities 650b57cec5SDimitry Andric // can be exposed. 660b57cec5SDimitry Andric ISD::NodeType ExtendKind = ISD::ANY_EXTEND; 670b57cec5SDimitry Andric unsigned NumOfSigned = 0, NumOfUnsigned = 0; 680b57cec5SDimitry Andric for (const User *U : V->users()) { 690b57cec5SDimitry Andric if (const auto *CI = dyn_cast<CmpInst>(U)) { 700b57cec5SDimitry Andric NumOfSigned += CI->isSigned(); 710b57cec5SDimitry Andric NumOfUnsigned += CI->isUnsigned(); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric if (NumOfSigned > NumOfUnsigned) 750b57cec5SDimitry Andric ExtendKind = ISD::SIGN_EXTEND; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric return ExtendKind; 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, 810b57cec5SDimitry Andric SelectionDAG *DAG) { 820b57cec5SDimitry Andric Fn = &fn; 830b57cec5SDimitry Andric MF = &mf; 840b57cec5SDimitry Andric TLI = MF->getSubtarget().getTargetLowering(); 850b57cec5SDimitry Andric RegInfo = &MF->getRegInfo(); 860b57cec5SDimitry Andric const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); 870b57cec5SDimitry Andric unsigned StackAlign = TFI->getStackAlignment(); 880b57cec5SDimitry Andric DA = DAG->getDivergenceAnalysis(); 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric // Check whether the function can return without sret-demotion. 910b57cec5SDimitry Andric SmallVector<ISD::OutputArg, 4> Outs; 920b57cec5SDimitry Andric CallingConv::ID CC = Fn->getCallingConv(); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric GetReturnInfo(CC, Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI, 950b57cec5SDimitry Andric mf.getDataLayout()); 960b57cec5SDimitry Andric CanLowerReturn = 970b57cec5SDimitry Andric TLI->CanLowerReturn(CC, *MF, Fn->isVarArg(), Outs, Fn->getContext()); 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric // If this personality uses funclets, we need to do a bit more work. 1000b57cec5SDimitry Andric DenseMap<const AllocaInst *, TinyPtrVector<int *>> CatchObjects; 1010b57cec5SDimitry Andric EHPersonality Personality = classifyEHPersonality( 1020b57cec5SDimitry Andric Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr); 1030b57cec5SDimitry Andric if (isFuncletEHPersonality(Personality)) { 1040b57cec5SDimitry Andric // Calculate state numbers if we haven't already. 1050b57cec5SDimitry Andric WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo(); 1060b57cec5SDimitry Andric if (Personality == EHPersonality::MSVC_CXX) 1070b57cec5SDimitry Andric calculateWinCXXEHStateNumbers(&fn, EHInfo); 1080b57cec5SDimitry Andric else if (isAsynchronousEHPersonality(Personality)) 1090b57cec5SDimitry Andric calculateSEHStateNumbers(&fn, EHInfo); 1100b57cec5SDimitry Andric else if (Personality == EHPersonality::CoreCLR) 1110b57cec5SDimitry Andric calculateClrEHStateNumbers(&fn, EHInfo); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric // Map all BB references in the WinEH data to MBBs. 1140b57cec5SDimitry Andric for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { 1150b57cec5SDimitry Andric for (WinEHHandlerType &H : TBME.HandlerArray) { 1160b57cec5SDimitry Andric if (const AllocaInst *AI = H.CatchObj.Alloca) 1170b57cec5SDimitry Andric CatchObjects.insert({AI, {}}).first->second.push_back( 1180b57cec5SDimitry Andric &H.CatchObj.FrameIndex); 1190b57cec5SDimitry Andric else 1200b57cec5SDimitry Andric H.CatchObj.FrameIndex = INT_MAX; 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric if (Personality == EHPersonality::Wasm_CXX) { 1250b57cec5SDimitry Andric WasmEHFuncInfo &EHInfo = *MF->getWasmEHFuncInfo(); 1260b57cec5SDimitry Andric calculateWasmEHInfo(&fn, EHInfo); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // Initialize the mapping of values to registers. This is only set up for 1300b57cec5SDimitry Andric // instruction values that are used outside of the block that defines 1310b57cec5SDimitry Andric // them. 1320b57cec5SDimitry Andric for (const BasicBlock &BB : *Fn) { 1330b57cec5SDimitry Andric for (const Instruction &I : BB) { 1340b57cec5SDimitry Andric if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { 1350b57cec5SDimitry Andric Type *Ty = AI->getAllocatedType(); 1360b57cec5SDimitry Andric unsigned Align = 1370b57cec5SDimitry Andric std::max((unsigned)MF->getDataLayout().getPrefTypeAlignment(Ty), 1380b57cec5SDimitry Andric AI->getAlignment()); 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric // Static allocas can be folded into the initial stack frame 1410b57cec5SDimitry Andric // adjustment. For targets that don't realign the stack, don't 1420b57cec5SDimitry Andric // do this if there is an extra alignment requirement. 1430b57cec5SDimitry Andric if (AI->isStaticAlloca() && 1440b57cec5SDimitry Andric (TFI->isStackRealignable() || (Align <= StackAlign))) { 1450b57cec5SDimitry Andric const ConstantInt *CUI = cast<ConstantInt>(AI->getArraySize()); 1460b57cec5SDimitry Andric uint64_t TySize = MF->getDataLayout().getTypeAllocSize(Ty); 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric TySize *= CUI->getZExtValue(); // Get total allocated size. 1490b57cec5SDimitry Andric if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. 1500b57cec5SDimitry Andric int FrameIndex = INT_MAX; 1510b57cec5SDimitry Andric auto Iter = CatchObjects.find(AI); 1520b57cec5SDimitry Andric if (Iter != CatchObjects.end() && TLI->needsFixedCatchObjects()) { 1530b57cec5SDimitry Andric FrameIndex = MF->getFrameInfo().CreateFixedObject( 1540b57cec5SDimitry Andric TySize, 0, /*IsImmutable=*/false, /*isAliased=*/true); 1550b57cec5SDimitry Andric MF->getFrameInfo().setObjectAlignment(FrameIndex, Align); 1560b57cec5SDimitry Andric } else { 1570b57cec5SDimitry Andric FrameIndex = 1580b57cec5SDimitry Andric MF->getFrameInfo().CreateStackObject(TySize, Align, false, AI); 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric StaticAllocaMap[AI] = FrameIndex; 1620b57cec5SDimitry Andric // Update the catch handler information. 1630b57cec5SDimitry Andric if (Iter != CatchObjects.end()) { 1640b57cec5SDimitry Andric for (int *CatchObjPtr : Iter->second) 1650b57cec5SDimitry Andric *CatchObjPtr = FrameIndex; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric } else { 1680b57cec5SDimitry Andric // FIXME: Overaligned static allocas should be grouped into 1690b57cec5SDimitry Andric // a single dynamic allocation instead of using a separate 1700b57cec5SDimitry Andric // stack allocation for each one. 1710b57cec5SDimitry Andric if (Align <= StackAlign) 1720b57cec5SDimitry Andric Align = 0; 1730b57cec5SDimitry Andric // Inform the Frame Information that we have variable-sized objects. 1740b57cec5SDimitry Andric MF->getFrameInfo().CreateVariableSizedObject(Align ? Align : 1, AI); 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric // Look for inline asm that clobbers the SP register. 1790b57cec5SDimitry Andric if (isa<CallInst>(I) || isa<InvokeInst>(I)) { 1800b57cec5SDimitry Andric ImmutableCallSite CS(&I); 1810b57cec5SDimitry Andric if (isa<InlineAsm>(CS.getCalledValue())) { 1820b57cec5SDimitry Andric unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); 1830b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 1840b57cec5SDimitry Andric std::vector<TargetLowering::AsmOperandInfo> Ops = 1850b57cec5SDimitry Andric TLI->ParseConstraints(Fn->getParent()->getDataLayout(), TRI, CS); 1860b57cec5SDimitry Andric for (TargetLowering::AsmOperandInfo &Op : Ops) { 1870b57cec5SDimitry Andric if (Op.Type == InlineAsm::isClobber) { 1880b57cec5SDimitry Andric // Clobbers don't have SDValue operands, hence SDValue(). 1890b57cec5SDimitry Andric TLI->ComputeConstraintToUse(Op, SDValue(), DAG); 1900b57cec5SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> PhysReg = 1910b57cec5SDimitry Andric TLI->getRegForInlineAsmConstraint(TRI, Op.ConstraintCode, 1920b57cec5SDimitry Andric Op.ConstraintVT); 1930b57cec5SDimitry Andric if (PhysReg.first == SP) 1940b57cec5SDimitry Andric MF->getFrameInfo().setHasOpaqueSPAdjustment(true); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric // Look for calls to the @llvm.va_start intrinsic. We can omit some 2010b57cec5SDimitry Andric // prologue boilerplate for variadic functions that don't examine their 2020b57cec5SDimitry Andric // arguments. 2030b57cec5SDimitry Andric if (const auto *II = dyn_cast<IntrinsicInst>(&I)) { 2040b57cec5SDimitry Andric if (II->getIntrinsicID() == Intrinsic::vastart) 2050b57cec5SDimitry Andric MF->getFrameInfo().setHasVAStart(true); 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric // If we have a musttail call in a variadic function, we need to ensure we 2090b57cec5SDimitry Andric // forward implicit register parameters. 2100b57cec5SDimitry Andric if (const auto *CI = dyn_cast<CallInst>(&I)) { 2110b57cec5SDimitry Andric if (CI->isMustTailCall() && Fn->isVarArg()) 2120b57cec5SDimitry Andric MF->getFrameInfo().setHasMustTailInVarArgFunc(true); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric // Mark values used outside their block as exported, by allocating 2160b57cec5SDimitry Andric // a virtual register for them. 2170b57cec5SDimitry Andric if (isUsedOutsideOfDefiningBlock(&I)) 2180b57cec5SDimitry Andric if (!isa<AllocaInst>(I) || !StaticAllocaMap.count(cast<AllocaInst>(&I))) 2190b57cec5SDimitry Andric InitializeRegForValue(&I); 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric // Decide the preferred extend type for a value. 2220b57cec5SDimitry Andric PreferredExtendType[&I] = getPreferredExtendForValue(&I); 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric // Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This 2270b57cec5SDimitry Andric // also creates the initial PHI MachineInstrs, though none of the input 2280b57cec5SDimitry Andric // operands are populated. 2290b57cec5SDimitry Andric for (const BasicBlock &BB : *Fn) { 2300b57cec5SDimitry Andric // Don't create MachineBasicBlocks for imaginary EH pad blocks. These blocks 2310b57cec5SDimitry Andric // are really data, and no instructions can live here. 2320b57cec5SDimitry Andric if (BB.isEHPad()) { 2330b57cec5SDimitry Andric const Instruction *PadInst = BB.getFirstNonPHI(); 2340b57cec5SDimitry Andric // If this is a non-landingpad EH pad, mark this function as using 2350b57cec5SDimitry Andric // funclets. 2360b57cec5SDimitry Andric // FIXME: SEH catchpads do not create EH scope/funclets, so we could avoid 2370b57cec5SDimitry Andric // setting this in such cases in order to improve frame layout. 2380b57cec5SDimitry Andric if (!isa<LandingPadInst>(PadInst)) { 2390b57cec5SDimitry Andric MF->setHasEHScopes(true); 2400b57cec5SDimitry Andric MF->setHasEHFunclets(true); 2410b57cec5SDimitry Andric MF->getFrameInfo().setHasOpaqueSPAdjustment(true); 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric if (isa<CatchSwitchInst>(PadInst)) { 2440b57cec5SDimitry Andric assert(&*BB.begin() == PadInst && 2450b57cec5SDimitry Andric "WinEHPrepare failed to remove PHIs from imaginary BBs"); 2460b57cec5SDimitry Andric continue; 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric if (isa<FuncletPadInst>(PadInst)) 2490b57cec5SDimitry Andric assert(&*BB.begin() == PadInst && "WinEHPrepare failed to demote PHIs"); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(&BB); 2530b57cec5SDimitry Andric MBBMap[&BB] = MBB; 2540b57cec5SDimitry Andric MF->push_back(MBB); 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric // Transfer the address-taken flag. This is necessary because there could 2570b57cec5SDimitry Andric // be multiple MachineBasicBlocks corresponding to one BasicBlock, and only 2580b57cec5SDimitry Andric // the first one should be marked. 2590b57cec5SDimitry Andric if (BB.hasAddressTaken()) 2600b57cec5SDimitry Andric MBB->setHasAddressTaken(); 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric // Mark landing pad blocks. 2630b57cec5SDimitry Andric if (BB.isEHPad()) 2640b57cec5SDimitry Andric MBB->setIsEHPad(); 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric // Create Machine PHI nodes for LLVM PHI nodes, lowering them as 2670b57cec5SDimitry Andric // appropriate. 2680b57cec5SDimitry Andric for (const PHINode &PN : BB.phis()) { 2690b57cec5SDimitry Andric if (PN.use_empty()) 2700b57cec5SDimitry Andric continue; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric // Skip empty types 2730b57cec5SDimitry Andric if (PN.getType()->isEmptyTy()) 2740b57cec5SDimitry Andric continue; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric DebugLoc DL = PN.getDebugLoc(); 2770b57cec5SDimitry Andric unsigned PHIReg = ValueMap[&PN]; 2780b57cec5SDimitry Andric assert(PHIReg && "PHI node does not have an assigned virtual register!"); 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 2810b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), PN.getType(), ValueVTs); 2820b57cec5SDimitry Andric for (EVT VT : ValueVTs) { 2830b57cec5SDimitry Andric unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); 2840b57cec5SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 2850b57cec5SDimitry Andric for (unsigned i = 0; i != NumRegisters; ++i) 2860b57cec5SDimitry Andric BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i); 2870b57cec5SDimitry Andric PHIReg += NumRegisters; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric if (isFuncletEHPersonality(Personality)) { 2930b57cec5SDimitry Andric WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo(); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric // Map all BB references in the WinEH data to MBBs. 2960b57cec5SDimitry Andric for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { 2970b57cec5SDimitry Andric for (WinEHHandlerType &H : TBME.HandlerArray) { 2980b57cec5SDimitry Andric if (H.Handler) 2990b57cec5SDimitry Andric H.Handler = MBBMap[H.Handler.get<const BasicBlock *>()]; 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap) 3030b57cec5SDimitry Andric if (UME.Cleanup) 3040b57cec5SDimitry Andric UME.Cleanup = MBBMap[UME.Cleanup.get<const BasicBlock *>()]; 3050b57cec5SDimitry Andric for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) { 3060b57cec5SDimitry Andric const auto *BB = UME.Handler.get<const BasicBlock *>(); 3070b57cec5SDimitry Andric UME.Handler = MBBMap[BB]; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) { 3100b57cec5SDimitry Andric const auto *BB = CME.Handler.get<const BasicBlock *>(); 3110b57cec5SDimitry Andric CME.Handler = MBBMap[BB]; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric else if (Personality == EHPersonality::Wasm_CXX) { 3160b57cec5SDimitry Andric WasmEHFuncInfo &EHInfo = *MF->getWasmEHFuncInfo(); 3170b57cec5SDimitry Andric // Map all BB references in the WinEH data to MBBs. 3180b57cec5SDimitry Andric DenseMap<BBOrMBB, BBOrMBB> NewMap; 3190b57cec5SDimitry Andric for (auto &KV : EHInfo.EHPadUnwindMap) { 3200b57cec5SDimitry Andric const auto *Src = KV.first.get<const BasicBlock *>(); 3210b57cec5SDimitry Andric const auto *Dst = KV.second.get<const BasicBlock *>(); 3220b57cec5SDimitry Andric NewMap[MBBMap[Src]] = MBBMap[Dst]; 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric EHInfo.EHPadUnwindMap = std::move(NewMap); 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric /// clear - Clear out all the function-specific state. This returns this 3290b57cec5SDimitry Andric /// FunctionLoweringInfo to an empty state, ready to be used for a 3300b57cec5SDimitry Andric /// different function. 3310b57cec5SDimitry Andric void FunctionLoweringInfo::clear() { 3320b57cec5SDimitry Andric MBBMap.clear(); 3330b57cec5SDimitry Andric ValueMap.clear(); 3340b57cec5SDimitry Andric VirtReg2Value.clear(); 3350b57cec5SDimitry Andric StaticAllocaMap.clear(); 3360b57cec5SDimitry Andric LiveOutRegInfo.clear(); 3370b57cec5SDimitry Andric VisitedBBs.clear(); 3380b57cec5SDimitry Andric ArgDbgValues.clear(); 3390b57cec5SDimitry Andric DescribedArgs.clear(); 3400b57cec5SDimitry Andric ByValArgFrameIndexMap.clear(); 3410b57cec5SDimitry Andric RegFixups.clear(); 3420b57cec5SDimitry Andric RegsWithFixups.clear(); 3430b57cec5SDimitry Andric StatepointStackSlots.clear(); 3440b57cec5SDimitry Andric StatepointSpillMaps.clear(); 3450b57cec5SDimitry Andric PreferredExtendType.clear(); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric /// CreateReg - Allocate a single virtual register for the given type. 3490b57cec5SDimitry Andric unsigned FunctionLoweringInfo::CreateReg(MVT VT, bool isDivergent) { 3500b57cec5SDimitry Andric return RegInfo->createVirtualRegister( 3510b57cec5SDimitry Andric MF->getSubtarget().getTargetLowering()->getRegClassFor(VT, isDivergent)); 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric /// CreateRegs - Allocate the appropriate number of virtual registers of 3550b57cec5SDimitry Andric /// the correctly promoted or expanded types. Assign these registers 3560b57cec5SDimitry Andric /// consecutive vreg numbers and return the first assigned number. 3570b57cec5SDimitry Andric /// 3580b57cec5SDimitry Andric /// In the case that the given value has struct or array type, this function 3590b57cec5SDimitry Andric /// will assign registers for each member or element. 3600b57cec5SDimitry Andric /// 3610b57cec5SDimitry Andric unsigned FunctionLoweringInfo::CreateRegs(Type *Ty, bool isDivergent) { 3620b57cec5SDimitry Andric const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 3650b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric unsigned FirstReg = 0; 3680b57cec5SDimitry Andric for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { 3690b57cec5SDimitry Andric EVT ValueVT = ValueVTs[Value]; 3700b57cec5SDimitry Andric MVT RegisterVT = TLI->getRegisterType(Ty->getContext(), ValueVT); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric unsigned NumRegs = TLI->getNumRegisters(Ty->getContext(), ValueVT); 3730b57cec5SDimitry Andric for (unsigned i = 0; i != NumRegs; ++i) { 3740b57cec5SDimitry Andric unsigned R = CreateReg(RegisterVT, isDivergent); 3750b57cec5SDimitry Andric if (!FirstReg) FirstReg = R; 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric return FirstReg; 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric unsigned FunctionLoweringInfo::CreateRegs(const Value *V) { 3820b57cec5SDimitry Andric return CreateRegs(V->getType(), DA && !TLI->requiresUniformRegister(*MF, V) && 3830b57cec5SDimitry Andric DA->isDivergent(V)); 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the 3870b57cec5SDimitry Andric /// register is a PHI destination and the PHI's LiveOutInfo is not valid. If 3880b57cec5SDimitry Andric /// the register's LiveOutInfo is for a smaller bit width, it is extended to 3890b57cec5SDimitry Andric /// the larger bit width by zero extension. The bit width must be no smaller 3900b57cec5SDimitry Andric /// than the LiveOutInfo's existing bit width. 3910b57cec5SDimitry Andric const FunctionLoweringInfo::LiveOutInfo * 3920b57cec5SDimitry Andric FunctionLoweringInfo::GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth) { 3930b57cec5SDimitry Andric if (!LiveOutRegInfo.inBounds(Reg)) 3940b57cec5SDimitry Andric return nullptr; 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric LiveOutInfo *LOI = &LiveOutRegInfo[Reg]; 3970b57cec5SDimitry Andric if (!LOI->IsValid) 3980b57cec5SDimitry Andric return nullptr; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric if (BitWidth > LOI->Known.getBitWidth()) { 4010b57cec5SDimitry Andric LOI->NumSignBits = 1; 4020b57cec5SDimitry Andric LOI->Known = LOI->Known.zext(BitWidth, false /* => any extend */); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric return LOI; 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination 4090b57cec5SDimitry Andric /// register based on the LiveOutInfo of its operands. 4100b57cec5SDimitry Andric void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) { 4110b57cec5SDimitry Andric Type *Ty = PN->getType(); 4120b57cec5SDimitry Andric if (!Ty->isIntegerTy() || Ty->isVectorTy()) 4130b57cec5SDimitry Andric return; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric SmallVector<EVT, 1> ValueVTs; 4160b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); 4170b57cec5SDimitry Andric assert(ValueVTs.size() == 1 && 4180b57cec5SDimitry Andric "PHIs with non-vector integer types should have a single VT."); 4190b57cec5SDimitry Andric EVT IntVT = ValueVTs[0]; 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric if (TLI->getNumRegisters(PN->getContext(), IntVT) != 1) 4220b57cec5SDimitry Andric return; 4230b57cec5SDimitry Andric IntVT = TLI->getTypeToTransformTo(PN->getContext(), IntVT); 4240b57cec5SDimitry Andric unsigned BitWidth = IntVT.getSizeInBits(); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric unsigned DestReg = ValueMap[PN]; 4270b57cec5SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(DestReg)) 4280b57cec5SDimitry Andric return; 4290b57cec5SDimitry Andric LiveOutRegInfo.grow(DestReg); 4300b57cec5SDimitry Andric LiveOutInfo &DestLOI = LiveOutRegInfo[DestReg]; 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric Value *V = PN->getIncomingValue(0); 4330b57cec5SDimitry Andric if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) { 4340b57cec5SDimitry Andric DestLOI.NumSignBits = 1; 4350b57cec5SDimitry Andric DestLOI.Known = KnownBits(BitWidth); 4360b57cec5SDimitry Andric return; 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { 4400b57cec5SDimitry Andric APInt Val = CI->getValue().zextOrTrunc(BitWidth); 4410b57cec5SDimitry Andric DestLOI.NumSignBits = Val.getNumSignBits(); 4420b57cec5SDimitry Andric DestLOI.Known.Zero = ~Val; 4430b57cec5SDimitry Andric DestLOI.Known.One = Val; 4440b57cec5SDimitry Andric } else { 4450b57cec5SDimitry Andric assert(ValueMap.count(V) && "V should have been placed in ValueMap when its" 4460b57cec5SDimitry Andric "CopyToReg node was created."); 4470b57cec5SDimitry Andric unsigned SrcReg = ValueMap[V]; 4480b57cec5SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) { 4490b57cec5SDimitry Andric DestLOI.IsValid = false; 4500b57cec5SDimitry Andric return; 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); 4530b57cec5SDimitry Andric if (!SrcLOI) { 4540b57cec5SDimitry Andric DestLOI.IsValid = false; 4550b57cec5SDimitry Andric return; 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric DestLOI = *SrcLOI; 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric assert(DestLOI.Known.Zero.getBitWidth() == BitWidth && 4610b57cec5SDimitry Andric DestLOI.Known.One.getBitWidth() == BitWidth && 4620b57cec5SDimitry Andric "Masks should have the same bit width as the type."); 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) { 4650b57cec5SDimitry Andric Value *V = PN->getIncomingValue(i); 4660b57cec5SDimitry Andric if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) { 4670b57cec5SDimitry Andric DestLOI.NumSignBits = 1; 4680b57cec5SDimitry Andric DestLOI.Known = KnownBits(BitWidth); 4690b57cec5SDimitry Andric return; 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { 4730b57cec5SDimitry Andric APInt Val = CI->getValue().zextOrTrunc(BitWidth); 4740b57cec5SDimitry Andric DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, Val.getNumSignBits()); 4750b57cec5SDimitry Andric DestLOI.Known.Zero &= ~Val; 4760b57cec5SDimitry Andric DestLOI.Known.One &= Val; 4770b57cec5SDimitry Andric continue; 4780b57cec5SDimitry Andric } 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric assert(ValueMap.count(V) && "V should have been placed in ValueMap when " 4810b57cec5SDimitry Andric "its CopyToReg node was created."); 4820b57cec5SDimitry Andric unsigned SrcReg = ValueMap[V]; 4830b57cec5SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) { 4840b57cec5SDimitry Andric DestLOI.IsValid = false; 4850b57cec5SDimitry Andric return; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); 4880b57cec5SDimitry Andric if (!SrcLOI) { 4890b57cec5SDimitry Andric DestLOI.IsValid = false; 4900b57cec5SDimitry Andric return; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits); 4930b57cec5SDimitry Andric DestLOI.Known.Zero &= SrcLOI->Known.Zero; 4940b57cec5SDimitry Andric DestLOI.Known.One &= SrcLOI->Known.One; 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric /// setArgumentFrameIndex - Record frame index for the byval 4990b57cec5SDimitry Andric /// argument. This overrides previous frame index entry for this argument, 5000b57cec5SDimitry Andric /// if any. 5010b57cec5SDimitry Andric void FunctionLoweringInfo::setArgumentFrameIndex(const Argument *A, 5020b57cec5SDimitry Andric int FI) { 5030b57cec5SDimitry Andric ByValArgFrameIndexMap[A] = FI; 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric /// getArgumentFrameIndex - Get frame index for the byval argument. 5070b57cec5SDimitry Andric /// If the argument does not have any assigned frame index then 0 is 5080b57cec5SDimitry Andric /// returned. 5090b57cec5SDimitry Andric int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) { 5100b57cec5SDimitry Andric auto I = ByValArgFrameIndexMap.find(A); 5110b57cec5SDimitry Andric if (I != ByValArgFrameIndexMap.end()) 5120b57cec5SDimitry Andric return I->second; 5130b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Argument does not have assigned frame index!\n"); 5140b57cec5SDimitry Andric return INT_MAX; 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric unsigned FunctionLoweringInfo::getCatchPadExceptionPointerVReg( 5180b57cec5SDimitry Andric const Value *CPI, const TargetRegisterClass *RC) { 5190b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 5200b57cec5SDimitry Andric auto I = CatchPadExceptionPointers.insert({CPI, 0}); 5210b57cec5SDimitry Andric unsigned &VReg = I.first->second; 5220b57cec5SDimitry Andric if (I.second) 5230b57cec5SDimitry Andric VReg = MRI.createVirtualRegister(RC); 5240b57cec5SDimitry Andric assert(VReg && "null vreg in exception pointer table!"); 5250b57cec5SDimitry Andric return VReg; 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric const Value * 5290b57cec5SDimitry Andric FunctionLoweringInfo::getValueFromVirtualReg(unsigned Vreg) { 5300b57cec5SDimitry Andric if (VirtReg2Value.empty()) { 5310b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 5320b57cec5SDimitry Andric for (auto &P : ValueMap) { 5330b57cec5SDimitry Andric ValueVTs.clear(); 5340b57cec5SDimitry Andric ComputeValueVTs(*TLI, Fn->getParent()->getDataLayout(), 5350b57cec5SDimitry Andric P.first->getType(), ValueVTs); 5360b57cec5SDimitry Andric unsigned Reg = P.second; 5370b57cec5SDimitry Andric for (EVT VT : ValueVTs) { 5380b57cec5SDimitry Andric unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); 5390b57cec5SDimitry Andric for (unsigned i = 0, e = NumRegisters; i != e; ++i) 5400b57cec5SDimitry Andric VirtReg2Value[Reg++] = P.first; 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric return VirtReg2Value.lookup(Vreg); 5450b57cec5SDimitry Andric } 546