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" 155ffd83dbSDimitry Andric #include "llvm/ADT/APInt.h" 1606c3fb27SDimitry Andric #include "llvm/Analysis/UniformityAnalysis.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/Analysis.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/WasmEHFuncInfo.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/WinEHFuncInfo.h" 290b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 300b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 310b57cec5SDimitry Andric #include "llvm/IR/Function.h" 320b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 330b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 340b57cec5SDimitry Andric #include "llvm/IR/Module.h" 350b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 360b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 370b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 380b57cec5SDimitry Andric #include <algorithm> 390b57cec5SDimitry Andric using namespace llvm; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric #define DEBUG_TYPE "function-lowering-info" 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric /// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by 440b57cec5SDimitry Andric /// PHI nodes or outside of the basic block that defines it, or used by a 450b57cec5SDimitry Andric /// switch or atomic instruction, which may expand to multiple basic blocks. 460b57cec5SDimitry Andric static bool isUsedOutsideOfDefiningBlock(const Instruction *I) { 470b57cec5SDimitry Andric if (I->use_empty()) return false; 480b57cec5SDimitry Andric if (isa<PHINode>(I)) return true; 490b57cec5SDimitry Andric const BasicBlock *BB = I->getParent(); 500b57cec5SDimitry Andric for (const User *U : I->users()) 510b57cec5SDimitry Andric if (cast<Instruction>(U)->getParent() != BB || isa<PHINode>(U)) 520b57cec5SDimitry Andric return true; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric return false; 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 5781ad6265SDimitry Andric static ISD::NodeType getPreferredExtendForValue(const Instruction *I) { 580b57cec5SDimitry Andric // For the users of the source value being used for compare instruction, if 590b57cec5SDimitry Andric // the number of signed predicate is greater than unsigned predicate, we 600b57cec5SDimitry Andric // prefer to use SIGN_EXTEND. 610b57cec5SDimitry Andric // 620b57cec5SDimitry Andric // With this optimization, we would be able to reduce some redundant sign or 630b57cec5SDimitry Andric // zero extension instruction, and eventually more machine CSE opportunities 640b57cec5SDimitry Andric // can be exposed. 650b57cec5SDimitry Andric ISD::NodeType ExtendKind = ISD::ANY_EXTEND; 660b57cec5SDimitry Andric unsigned NumOfSigned = 0, NumOfUnsigned = 0; 675f757f3fSDimitry Andric for (const Use &U : I->uses()) { 685f757f3fSDimitry Andric if (const auto *CI = dyn_cast<CmpInst>(U.getUser())) { 690b57cec5SDimitry Andric NumOfSigned += CI->isSigned(); 700b57cec5SDimitry Andric NumOfUnsigned += CI->isUnsigned(); 710b57cec5SDimitry Andric } 725f757f3fSDimitry Andric if (const auto *CallI = dyn_cast<CallBase>(U.getUser())) { 735f757f3fSDimitry Andric if (!CallI->isArgOperand(&U)) 745f757f3fSDimitry Andric continue; 755f757f3fSDimitry Andric unsigned ArgNo = CallI->getArgOperandNo(&U); 765f757f3fSDimitry Andric NumOfUnsigned += CallI->paramHasAttr(ArgNo, Attribute::ZExt); 775f757f3fSDimitry Andric NumOfSigned += CallI->paramHasAttr(ArgNo, Attribute::SExt); 785f757f3fSDimitry Andric } 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric if (NumOfSigned > NumOfUnsigned) 810b57cec5SDimitry Andric ExtendKind = ISD::SIGN_EXTEND; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric return ExtendKind; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, 870b57cec5SDimitry Andric SelectionDAG *DAG) { 880b57cec5SDimitry Andric Fn = &fn; 890b57cec5SDimitry Andric MF = &mf; 900b57cec5SDimitry Andric TLI = MF->getSubtarget().getTargetLowering(); 910b57cec5SDimitry Andric RegInfo = &MF->getRegInfo(); 920b57cec5SDimitry Andric const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); 9306c3fb27SDimitry Andric UA = DAG->getUniformityInfo(); 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric // Check whether the function can return without sret-demotion. 960b57cec5SDimitry Andric SmallVector<ISD::OutputArg, 4> Outs; 970b57cec5SDimitry Andric CallingConv::ID CC = Fn->getCallingConv(); 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric GetReturnInfo(CC, Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI, 1000b57cec5SDimitry Andric mf.getDataLayout()); 1010b57cec5SDimitry Andric CanLowerReturn = 1020b57cec5SDimitry Andric TLI->CanLowerReturn(CC, *MF, Fn->isVarArg(), Outs, Fn->getContext()); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // If this personality uses funclets, we need to do a bit more work. 1050b57cec5SDimitry Andric DenseMap<const AllocaInst *, TinyPtrVector<int *>> CatchObjects; 1060b57cec5SDimitry Andric EHPersonality Personality = classifyEHPersonality( 1070b57cec5SDimitry Andric Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr); 1080b57cec5SDimitry Andric if (isFuncletEHPersonality(Personality)) { 1090b57cec5SDimitry Andric // Calculate state numbers if we haven't already. 1100b57cec5SDimitry Andric WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo(); 1110b57cec5SDimitry Andric if (Personality == EHPersonality::MSVC_CXX) 1120b57cec5SDimitry Andric calculateWinCXXEHStateNumbers(&fn, EHInfo); 1130b57cec5SDimitry Andric else if (isAsynchronousEHPersonality(Personality)) 1140b57cec5SDimitry Andric calculateSEHStateNumbers(&fn, EHInfo); 1150b57cec5SDimitry Andric else if (Personality == EHPersonality::CoreCLR) 1160b57cec5SDimitry Andric calculateClrEHStateNumbers(&fn, EHInfo); 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric // Map all BB references in the WinEH data to MBBs. 1190b57cec5SDimitry Andric for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { 1200b57cec5SDimitry Andric for (WinEHHandlerType &H : TBME.HandlerArray) { 1210b57cec5SDimitry Andric if (const AllocaInst *AI = H.CatchObj.Alloca) 1220b57cec5SDimitry Andric CatchObjects.insert({AI, {}}).first->second.push_back( 1230b57cec5SDimitry Andric &H.CatchObj.FrameIndex); 1240b57cec5SDimitry Andric else 1250b57cec5SDimitry Andric H.CatchObj.FrameIndex = INT_MAX; 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // Initialize the mapping of values to registers. This is only set up for 1310b57cec5SDimitry Andric // instruction values that are used outside of the block that defines 1320b57cec5SDimitry Andric // them. 1335ffd83dbSDimitry Andric const Align StackAlign = TFI->getStackAlign(); 1340b57cec5SDimitry Andric for (const BasicBlock &BB : *Fn) { 1350b57cec5SDimitry Andric for (const Instruction &I : BB) { 1360b57cec5SDimitry Andric if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { 1370b57cec5SDimitry Andric Type *Ty = AI->getAllocatedType(); 13806c3fb27SDimitry Andric Align Alignment = AI->getAlign(); 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() && 1445ffd83dbSDimitry Andric (TFI->isStackRealignable() || (Alignment <= StackAlign))) { 1450b57cec5SDimitry Andric const ConstantInt *CUI = cast<ConstantInt>(AI->getArraySize()); 146480093f4SDimitry Andric uint64_t TySize = 147bdd1243dSDimitry Andric MF->getDataLayout().getTypeAllocSize(Ty).getKnownMinValue(); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric TySize *= CUI->getZExtValue(); // Get total allocated size. 1500b57cec5SDimitry Andric if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. 1510b57cec5SDimitry Andric int FrameIndex = INT_MAX; 1520b57cec5SDimitry Andric auto Iter = CatchObjects.find(AI); 1530b57cec5SDimitry Andric if (Iter != CatchObjects.end() && TLI->needsFixedCatchObjects()) { 1540b57cec5SDimitry Andric FrameIndex = MF->getFrameInfo().CreateFixedObject( 1550b57cec5SDimitry Andric TySize, 0, /*IsImmutable=*/false, /*isAliased=*/true); 1565ffd83dbSDimitry Andric MF->getFrameInfo().setObjectAlignment(FrameIndex, Alignment); 1570b57cec5SDimitry Andric } else { 1585ffd83dbSDimitry Andric FrameIndex = MF->getFrameInfo().CreateStackObject(TySize, Alignment, 1595ffd83dbSDimitry Andric false, AI); 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 16206c3fb27SDimitry Andric // Scalable vectors and structures that contain scalable vectors may 16306c3fb27SDimitry Andric // need a special StackID to distinguish them from other (fixed size) 16406c3fb27SDimitry Andric // stack objects. 16506c3fb27SDimitry Andric if (Ty->isScalableTy()) 166480093f4SDimitry Andric MF->getFrameInfo().setStackID(FrameIndex, 167480093f4SDimitry Andric TFI->getStackIDForScalableVectors()); 168480093f4SDimitry Andric 1690b57cec5SDimitry Andric StaticAllocaMap[AI] = FrameIndex; 1700b57cec5SDimitry Andric // Update the catch handler information. 1710b57cec5SDimitry Andric if (Iter != CatchObjects.end()) { 1720b57cec5SDimitry Andric for (int *CatchObjPtr : Iter->second) 1730b57cec5SDimitry Andric *CatchObjPtr = FrameIndex; 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric } else { 1760b57cec5SDimitry Andric // FIXME: Overaligned static allocas should be grouped into 1770b57cec5SDimitry Andric // a single dynamic allocation instead of using a separate 1780b57cec5SDimitry Andric // stack allocation for each one. 1790b57cec5SDimitry Andric // Inform the Frame Information that we have variable-sized objects. 1805ffd83dbSDimitry Andric MF->getFrameInfo().CreateVariableSizedObject( 1815ffd83dbSDimitry Andric Alignment <= StackAlign ? Align(1) : Alignment, AI); 1820b57cec5SDimitry Andric } 183fe6060f1SDimitry Andric } else if (auto *Call = dyn_cast<CallBase>(&I)) { 1840b57cec5SDimitry Andric // Look for inline asm that clobbers the SP register. 1855ffd83dbSDimitry Andric if (Call->isInlineAsm()) { 186e8d8bef9SDimitry Andric Register SP = TLI->getStackPointerRegisterToSaveRestore(); 1870b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 1880b57cec5SDimitry Andric std::vector<TargetLowering::AsmOperandInfo> Ops = 189*0fca6ea1SDimitry Andric TLI->ParseConstraints(Fn->getDataLayout(), TRI, 1905ffd83dbSDimitry Andric *Call); 1910b57cec5SDimitry Andric for (TargetLowering::AsmOperandInfo &Op : Ops) { 1920b57cec5SDimitry Andric if (Op.Type == InlineAsm::isClobber) { 1930b57cec5SDimitry Andric // Clobbers don't have SDValue operands, hence SDValue(). 1940b57cec5SDimitry Andric TLI->ComputeConstraintToUse(Op, SDValue(), DAG); 1950b57cec5SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> PhysReg = 1960b57cec5SDimitry Andric TLI->getRegForInlineAsmConstraint(TRI, Op.ConstraintCode, 1970b57cec5SDimitry Andric Op.ConstraintVT); 1980b57cec5SDimitry Andric if (PhysReg.first == SP) 1990b57cec5SDimitry Andric MF->getFrameInfo().setHasOpaqueSPAdjustment(true); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric // Look for calls to the @llvm.va_start intrinsic. We can omit some 2040b57cec5SDimitry Andric // prologue boilerplate for variadic functions that don't examine their 2050b57cec5SDimitry Andric // arguments. 2060b57cec5SDimitry Andric if (const auto *II = dyn_cast<IntrinsicInst>(&I)) { 2070b57cec5SDimitry Andric if (II->getIntrinsicID() == Intrinsic::vastart) 2080b57cec5SDimitry Andric MF->getFrameInfo().setHasVAStart(true); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 211fe6060f1SDimitry Andric // If we have a musttail call in a variadic function, we need to ensure 212fe6060f1SDimitry Andric // we forward implicit register parameters. 2130b57cec5SDimitry Andric if (const auto *CI = dyn_cast<CallInst>(&I)) { 2140b57cec5SDimitry Andric if (CI->isMustTailCall() && Fn->isVarArg()) 2150b57cec5SDimitry Andric MF->getFrameInfo().setHasMustTailInVarArgFunc(true); 2160b57cec5SDimitry Andric } 217*0fca6ea1SDimitry Andric 218*0fca6ea1SDimitry Andric // Determine if there is a call to setjmp in the machine function. 219*0fca6ea1SDimitry Andric if (Call->hasFnAttr(Attribute::ReturnsTwice)) 220*0fca6ea1SDimitry Andric MF->setExposesReturnsTwice(true); 221fe6060f1SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // Mark values used outside their block as exported, by allocating 2240b57cec5SDimitry Andric // a virtual register for them. 2250b57cec5SDimitry Andric if (isUsedOutsideOfDefiningBlock(&I)) 2260b57cec5SDimitry Andric if (!isa<AllocaInst>(I) || !StaticAllocaMap.count(cast<AllocaInst>(&I))) 2270b57cec5SDimitry Andric InitializeRegForValue(&I); 2280b57cec5SDimitry Andric 229*0fca6ea1SDimitry Andric // Decide the preferred extend type for a value. This iterates over all 230*0fca6ea1SDimitry Andric // users and therefore isn't cheap, so don't do this at O0. 231*0fca6ea1SDimitry Andric if (DAG->getOptLevel() != CodeGenOptLevel::None) 2320b57cec5SDimitry Andric PreferredExtendType[&I] = getPreferredExtendForValue(&I); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This 2370b57cec5SDimitry Andric // also creates the initial PHI MachineInstrs, though none of the input 2380b57cec5SDimitry Andric // operands are populated. 2390b57cec5SDimitry Andric for (const BasicBlock &BB : *Fn) { 2400b57cec5SDimitry Andric // Don't create MachineBasicBlocks for imaginary EH pad blocks. These blocks 2410b57cec5SDimitry Andric // are really data, and no instructions can live here. 2420b57cec5SDimitry Andric if (BB.isEHPad()) { 2430b57cec5SDimitry Andric const Instruction *PadInst = BB.getFirstNonPHI(); 2440b57cec5SDimitry Andric // If this is a non-landingpad EH pad, mark this function as using 2450b57cec5SDimitry Andric // funclets. 2460b57cec5SDimitry Andric // FIXME: SEH catchpads do not create EH scope/funclets, so we could avoid 2470b57cec5SDimitry Andric // setting this in such cases in order to improve frame layout. 2480b57cec5SDimitry Andric if (!isa<LandingPadInst>(PadInst)) { 2490b57cec5SDimitry Andric MF->setHasEHScopes(true); 2500b57cec5SDimitry Andric MF->setHasEHFunclets(true); 2510b57cec5SDimitry Andric MF->getFrameInfo().setHasOpaqueSPAdjustment(true); 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric if (isa<CatchSwitchInst>(PadInst)) { 2540b57cec5SDimitry Andric assert(&*BB.begin() == PadInst && 2550b57cec5SDimitry Andric "WinEHPrepare failed to remove PHIs from imaginary BBs"); 2560b57cec5SDimitry Andric continue; 2570b57cec5SDimitry Andric } 258*0fca6ea1SDimitry Andric if (isa<FuncletPadInst>(PadInst) && 259*0fca6ea1SDimitry Andric Personality != EHPersonality::Wasm_CXX) 2600b57cec5SDimitry Andric assert(&*BB.begin() == PadInst && "WinEHPrepare failed to demote PHIs"); 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(&BB); 2640b57cec5SDimitry Andric MBBMap[&BB] = MBB; 2650b57cec5SDimitry Andric MF->push_back(MBB); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric // Transfer the address-taken flag. This is necessary because there could 2680b57cec5SDimitry Andric // be multiple MachineBasicBlocks corresponding to one BasicBlock, and only 2690b57cec5SDimitry Andric // the first one should be marked. 2700b57cec5SDimitry Andric if (BB.hasAddressTaken()) 271bdd1243dSDimitry Andric MBB->setAddressTakenIRBlock(const_cast<BasicBlock *>(&BB)); 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric // Mark landing pad blocks. 2740b57cec5SDimitry Andric if (BB.isEHPad()) 2750b57cec5SDimitry Andric MBB->setIsEHPad(); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // Create Machine PHI nodes for LLVM PHI nodes, lowering them as 2780b57cec5SDimitry Andric // appropriate. 2790b57cec5SDimitry Andric for (const PHINode &PN : BB.phis()) { 2800b57cec5SDimitry Andric if (PN.use_empty()) 2810b57cec5SDimitry Andric continue; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric // Skip empty types 2840b57cec5SDimitry Andric if (PN.getType()->isEmptyTy()) 2850b57cec5SDimitry Andric continue; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric DebugLoc DL = PN.getDebugLoc(); 2880b57cec5SDimitry Andric unsigned PHIReg = ValueMap[&PN]; 2890b57cec5SDimitry Andric assert(PHIReg && "PHI node does not have an assigned virtual register!"); 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 2920b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), PN.getType(), ValueVTs); 2930b57cec5SDimitry Andric for (EVT VT : ValueVTs) { 2940b57cec5SDimitry Andric unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); 2950b57cec5SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 2960b57cec5SDimitry Andric for (unsigned i = 0; i != NumRegisters; ++i) 2970b57cec5SDimitry Andric BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i); 2980b57cec5SDimitry Andric PHIReg += NumRegisters; 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric if (isFuncletEHPersonality(Personality)) { 3040b57cec5SDimitry Andric WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo(); 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric // Map all BB references in the WinEH data to MBBs. 3070b57cec5SDimitry Andric for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { 3080b57cec5SDimitry Andric for (WinEHHandlerType &H : TBME.HandlerArray) { 3090b57cec5SDimitry Andric if (H.Handler) 31006c3fb27SDimitry Andric H.Handler = MBBMap[cast<const BasicBlock *>(H.Handler)]; 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap) 3140b57cec5SDimitry Andric if (UME.Cleanup) 31506c3fb27SDimitry Andric UME.Cleanup = MBBMap[cast<const BasicBlock *>(UME.Cleanup)]; 3160b57cec5SDimitry Andric for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) { 31706c3fb27SDimitry Andric const auto *BB = cast<const BasicBlock *>(UME.Handler); 3180b57cec5SDimitry Andric UME.Handler = MBBMap[BB]; 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) { 32106c3fb27SDimitry Andric const auto *BB = cast<const BasicBlock *>(CME.Handler); 3220b57cec5SDimitry Andric CME.Handler = MBBMap[BB]; 3230b57cec5SDimitry Andric } 324bdd1243dSDimitry Andric } else if (Personality == EHPersonality::Wasm_CXX) { 3250b57cec5SDimitry Andric WasmEHFuncInfo &EHInfo = *MF->getWasmEHFuncInfo(); 326bdd1243dSDimitry Andric calculateWasmEHInfo(&fn, EHInfo); 327bdd1243dSDimitry Andric 328fe6060f1SDimitry Andric // Map all BB references in the Wasm EH data to MBBs. 329fe6060f1SDimitry Andric DenseMap<BBOrMBB, BBOrMBB> SrcToUnwindDest; 330fe6060f1SDimitry Andric for (auto &KV : EHInfo.SrcToUnwindDest) { 33106c3fb27SDimitry Andric const auto *Src = cast<const BasicBlock *>(KV.first); 33206c3fb27SDimitry Andric const auto *Dest = cast<const BasicBlock *>(KV.second); 333fe6060f1SDimitry Andric SrcToUnwindDest[MBBMap[Src]] = MBBMap[Dest]; 3340b57cec5SDimitry Andric } 335fe6060f1SDimitry Andric EHInfo.SrcToUnwindDest = std::move(SrcToUnwindDest); 336fe6060f1SDimitry Andric DenseMap<BBOrMBB, SmallPtrSet<BBOrMBB, 4>> UnwindDestToSrcs; 337fe6060f1SDimitry Andric for (auto &KV : EHInfo.UnwindDestToSrcs) { 33806c3fb27SDimitry Andric const auto *Dest = cast<const BasicBlock *>(KV.first); 339fe6060f1SDimitry Andric UnwindDestToSrcs[MBBMap[Dest]] = SmallPtrSet<BBOrMBB, 4>(); 340fe6060f1SDimitry Andric for (const auto P : KV.second) 341fe6060f1SDimitry Andric UnwindDestToSrcs[MBBMap[Dest]].insert( 34206c3fb27SDimitry Andric MBBMap[cast<const BasicBlock *>(P)]); 343fe6060f1SDimitry Andric } 344fe6060f1SDimitry Andric EHInfo.UnwindDestToSrcs = std::move(UnwindDestToSrcs); 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric /// clear - Clear out all the function-specific state. This returns this 3490b57cec5SDimitry Andric /// FunctionLoweringInfo to an empty state, ready to be used for a 3500b57cec5SDimitry Andric /// different function. 3510b57cec5SDimitry Andric void FunctionLoweringInfo::clear() { 3520b57cec5SDimitry Andric MBBMap.clear(); 3530b57cec5SDimitry Andric ValueMap.clear(); 3540b57cec5SDimitry Andric VirtReg2Value.clear(); 3550b57cec5SDimitry Andric StaticAllocaMap.clear(); 3560b57cec5SDimitry Andric LiveOutRegInfo.clear(); 3570b57cec5SDimitry Andric VisitedBBs.clear(); 3580b57cec5SDimitry Andric ArgDbgValues.clear(); 3590b57cec5SDimitry Andric DescribedArgs.clear(); 3600b57cec5SDimitry Andric ByValArgFrameIndexMap.clear(); 3610b57cec5SDimitry Andric RegFixups.clear(); 3620b57cec5SDimitry Andric RegsWithFixups.clear(); 3630b57cec5SDimitry Andric StatepointStackSlots.clear(); 364e8d8bef9SDimitry Andric StatepointRelocationMaps.clear(); 3650b57cec5SDimitry Andric PreferredExtendType.clear(); 36606c3fb27SDimitry Andric PreprocessedDbgDeclares.clear(); 367*0fca6ea1SDimitry Andric PreprocessedDVRDeclares.clear(); 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric /// CreateReg - Allocate a single virtual register for the given type. 3715ffd83dbSDimitry Andric Register FunctionLoweringInfo::CreateReg(MVT VT, bool isDivergent) { 372bdd1243dSDimitry Andric return RegInfo->createVirtualRegister(TLI->getRegClassFor(VT, isDivergent)); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric /// CreateRegs - Allocate the appropriate number of virtual registers of 3760b57cec5SDimitry Andric /// the correctly promoted or expanded types. Assign these registers 3770b57cec5SDimitry Andric /// consecutive vreg numbers and return the first assigned number. 3780b57cec5SDimitry Andric /// 3790b57cec5SDimitry Andric /// In the case that the given value has struct or array type, this function 3800b57cec5SDimitry Andric /// will assign registers for each member or element. 3810b57cec5SDimitry Andric /// 3825ffd83dbSDimitry Andric Register FunctionLoweringInfo::CreateRegs(Type *Ty, bool isDivergent) { 3830b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 3840b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); 3850b57cec5SDimitry Andric 3865ffd83dbSDimitry Andric Register FirstReg; 387cb14a3feSDimitry Andric for (EVT ValueVT : ValueVTs) { 3880b57cec5SDimitry Andric MVT RegisterVT = TLI->getRegisterType(Ty->getContext(), ValueVT); 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric unsigned NumRegs = TLI->getNumRegisters(Ty->getContext(), ValueVT); 3910b57cec5SDimitry Andric for (unsigned i = 0; i != NumRegs; ++i) { 3925ffd83dbSDimitry Andric Register R = CreateReg(RegisterVT, isDivergent); 3930b57cec5SDimitry Andric if (!FirstReg) FirstReg = R; 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric } 3960b57cec5SDimitry Andric return FirstReg; 3970b57cec5SDimitry Andric } 3980b57cec5SDimitry Andric 3995ffd83dbSDimitry Andric Register FunctionLoweringInfo::CreateRegs(const Value *V) { 40006c3fb27SDimitry Andric return CreateRegs(V->getType(), UA && UA->isDivergent(V) && 4015ffd83dbSDimitry Andric !TLI->requiresUniformRegister(*MF, V)); 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric 404*0fca6ea1SDimitry Andric Register FunctionLoweringInfo::InitializeRegForValue(const Value *V) { 405*0fca6ea1SDimitry Andric // Tokens live in vregs only when used for convergence control. 406*0fca6ea1SDimitry Andric if (V->getType()->isTokenTy() && !isa<ConvergenceControlInst>(V)) 407*0fca6ea1SDimitry Andric return 0; 408*0fca6ea1SDimitry Andric Register &R = ValueMap[V]; 409*0fca6ea1SDimitry Andric assert(R == Register() && "Already initialized this value register!"); 410*0fca6ea1SDimitry Andric assert(VirtReg2Value.empty()); 411*0fca6ea1SDimitry Andric return R = CreateRegs(V); 412*0fca6ea1SDimitry Andric } 413*0fca6ea1SDimitry Andric 4140b57cec5SDimitry Andric /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the 4150b57cec5SDimitry Andric /// register is a PHI destination and the PHI's LiveOutInfo is not valid. If 4160b57cec5SDimitry Andric /// the register's LiveOutInfo is for a smaller bit width, it is extended to 4170b57cec5SDimitry Andric /// the larger bit width by zero extension. The bit width must be no smaller 4180b57cec5SDimitry Andric /// than the LiveOutInfo's existing bit width. 4190b57cec5SDimitry Andric const FunctionLoweringInfo::LiveOutInfo * 4205ffd83dbSDimitry Andric FunctionLoweringInfo::GetLiveOutRegInfo(Register Reg, unsigned BitWidth) { 4210b57cec5SDimitry Andric if (!LiveOutRegInfo.inBounds(Reg)) 4220b57cec5SDimitry Andric return nullptr; 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric LiveOutInfo *LOI = &LiveOutRegInfo[Reg]; 4250b57cec5SDimitry Andric if (!LOI->IsValid) 4260b57cec5SDimitry Andric return nullptr; 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric if (BitWidth > LOI->Known.getBitWidth()) { 4290b57cec5SDimitry Andric LOI->NumSignBits = 1; 4305ffd83dbSDimitry Andric LOI->Known = LOI->Known.anyext(BitWidth); 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric return LOI; 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination 4370b57cec5SDimitry Andric /// register based on the LiveOutInfo of its operands. 4380b57cec5SDimitry Andric void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) { 4390b57cec5SDimitry Andric Type *Ty = PN->getType(); 4400b57cec5SDimitry Andric if (!Ty->isIntegerTy() || Ty->isVectorTy()) 4410b57cec5SDimitry Andric return; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric SmallVector<EVT, 1> ValueVTs; 4440b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); 4450b57cec5SDimitry Andric assert(ValueVTs.size() == 1 && 4460b57cec5SDimitry Andric "PHIs with non-vector integer types should have a single VT."); 4470b57cec5SDimitry Andric EVT IntVT = ValueVTs[0]; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric if (TLI->getNumRegisters(PN->getContext(), IntVT) != 1) 4500b57cec5SDimitry Andric return; 451*0fca6ea1SDimitry Andric IntVT = TLI->getRegisterType(PN->getContext(), IntVT); 4520b57cec5SDimitry Andric unsigned BitWidth = IntVT.getSizeInBits(); 4530b57cec5SDimitry Andric 45481ad6265SDimitry Andric auto It = ValueMap.find(PN); 45581ad6265SDimitry Andric if (It == ValueMap.end()) 4560b57cec5SDimitry Andric return; 45781ad6265SDimitry Andric 45881ad6265SDimitry Andric Register DestReg = It->second; 45981ad6265SDimitry Andric if (DestReg == 0) 460bdd1243dSDimitry Andric return; 461bdd1243dSDimitry Andric assert(DestReg.isVirtual() && "Expected a virtual reg"); 4620b57cec5SDimitry Andric LiveOutRegInfo.grow(DestReg); 4630b57cec5SDimitry Andric LiveOutInfo &DestLOI = LiveOutRegInfo[DestReg]; 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric Value *V = PN->getIncomingValue(0); 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)) { 47381ad6265SDimitry Andric APInt Val; 47481ad6265SDimitry Andric if (TLI->signExtendConstant(CI)) 47581ad6265SDimitry Andric Val = CI->getValue().sext(BitWidth); 47681ad6265SDimitry Andric else 47781ad6265SDimitry Andric Val = CI->getValue().zext(BitWidth); 4780b57cec5SDimitry Andric DestLOI.NumSignBits = Val.getNumSignBits(); 479e8d8bef9SDimitry Andric DestLOI.Known = KnownBits::makeConstant(Val); 4800b57cec5SDimitry Andric } else { 4810b57cec5SDimitry Andric assert(ValueMap.count(V) && "V should have been placed in ValueMap when its" 4820b57cec5SDimitry Andric "CopyToReg node was created."); 4835ffd83dbSDimitry Andric Register SrcReg = ValueMap[V]; 484bdd1243dSDimitry Andric if (!SrcReg.isVirtual()) { 4850b57cec5SDimitry Andric DestLOI.IsValid = false; 4860b57cec5SDimitry Andric return; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); 4890b57cec5SDimitry Andric if (!SrcLOI) { 4900b57cec5SDimitry Andric DestLOI.IsValid = false; 4910b57cec5SDimitry Andric return; 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric DestLOI = *SrcLOI; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric assert(DestLOI.Known.Zero.getBitWidth() == BitWidth && 4970b57cec5SDimitry Andric DestLOI.Known.One.getBitWidth() == BitWidth && 4980b57cec5SDimitry Andric "Masks should have the same bit width as the type."); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) { 5010b57cec5SDimitry Andric Value *V = PN->getIncomingValue(i); 5020b57cec5SDimitry Andric if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) { 5030b57cec5SDimitry Andric DestLOI.NumSignBits = 1; 5040b57cec5SDimitry Andric DestLOI.Known = KnownBits(BitWidth); 5050b57cec5SDimitry Andric return; 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { 50981ad6265SDimitry Andric APInt Val; 51081ad6265SDimitry Andric if (TLI->signExtendConstant(CI)) 51181ad6265SDimitry Andric Val = CI->getValue().sext(BitWidth); 51281ad6265SDimitry Andric else 51381ad6265SDimitry Andric Val = CI->getValue().zext(BitWidth); 5140b57cec5SDimitry Andric DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, Val.getNumSignBits()); 5150b57cec5SDimitry Andric DestLOI.Known.Zero &= ~Val; 5160b57cec5SDimitry Andric DestLOI.Known.One &= Val; 5170b57cec5SDimitry Andric continue; 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric assert(ValueMap.count(V) && "V should have been placed in ValueMap when " 5210b57cec5SDimitry Andric "its CopyToReg node was created."); 5225ffd83dbSDimitry Andric Register SrcReg = ValueMap[V]; 5235ffd83dbSDimitry Andric if (!SrcReg.isVirtual()) { 5240b57cec5SDimitry Andric DestLOI.IsValid = false; 5250b57cec5SDimitry Andric return; 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); 5280b57cec5SDimitry Andric if (!SrcLOI) { 5290b57cec5SDimitry Andric DestLOI.IsValid = false; 5300b57cec5SDimitry Andric return; 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits); 53306c3fb27SDimitry Andric DestLOI.Known = DestLOI.Known.intersectWith(SrcLOI->Known); 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric /// setArgumentFrameIndex - Record frame index for the byval 5380b57cec5SDimitry Andric /// argument. This overrides previous frame index entry for this argument, 5390b57cec5SDimitry Andric /// if any. 5400b57cec5SDimitry Andric void FunctionLoweringInfo::setArgumentFrameIndex(const Argument *A, 5410b57cec5SDimitry Andric int FI) { 5420b57cec5SDimitry Andric ByValArgFrameIndexMap[A] = FI; 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric /// getArgumentFrameIndex - Get frame index for the byval argument. 5460b57cec5SDimitry Andric /// If the argument does not have any assigned frame index then 0 is 5470b57cec5SDimitry Andric /// returned. 5480b57cec5SDimitry Andric int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) { 5490b57cec5SDimitry Andric auto I = ByValArgFrameIndexMap.find(A); 5500b57cec5SDimitry Andric if (I != ByValArgFrameIndexMap.end()) 5510b57cec5SDimitry Andric return I->second; 5520b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Argument does not have assigned frame index!\n"); 5530b57cec5SDimitry Andric return INT_MAX; 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric 5565ffd83dbSDimitry Andric Register FunctionLoweringInfo::getCatchPadExceptionPointerVReg( 5570b57cec5SDimitry Andric const Value *CPI, const TargetRegisterClass *RC) { 5580b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 5590b57cec5SDimitry Andric auto I = CatchPadExceptionPointers.insert({CPI, 0}); 5605ffd83dbSDimitry Andric Register &VReg = I.first->second; 5610b57cec5SDimitry Andric if (I.second) 5620b57cec5SDimitry Andric VReg = MRI.createVirtualRegister(RC); 5630b57cec5SDimitry Andric assert(VReg && "null vreg in exception pointer table!"); 5640b57cec5SDimitry Andric return VReg; 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric const Value * 5685ffd83dbSDimitry Andric FunctionLoweringInfo::getValueFromVirtualReg(Register Vreg) { 5690b57cec5SDimitry Andric if (VirtReg2Value.empty()) { 5700b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 5710b57cec5SDimitry Andric for (auto &P : ValueMap) { 5720b57cec5SDimitry Andric ValueVTs.clear(); 573*0fca6ea1SDimitry Andric ComputeValueVTs(*TLI, Fn->getDataLayout(), 5740b57cec5SDimitry Andric P.first->getType(), ValueVTs); 5750b57cec5SDimitry Andric unsigned Reg = P.second; 5760b57cec5SDimitry Andric for (EVT VT : ValueVTs) { 5770b57cec5SDimitry Andric unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); 5780b57cec5SDimitry Andric for (unsigned i = 0, e = NumRegisters; i != e; ++i) 5790b57cec5SDimitry Andric VirtReg2Value[Reg++] = P.first; 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric } 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric return VirtReg2Value.lookup(Vreg); 5840b57cec5SDimitry Andric } 585