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; 6781ad6265SDimitry Andric for (const User *U : I->users()) { 680b57cec5SDimitry Andric if (const auto *CI = dyn_cast<CmpInst>(U)) { 690b57cec5SDimitry Andric NumOfSigned += CI->isSigned(); 700b57cec5SDimitry Andric NumOfUnsigned += CI->isUnsigned(); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric if (NumOfSigned > NumOfUnsigned) 740b57cec5SDimitry Andric ExtendKind = ISD::SIGN_EXTEND; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric return ExtendKind; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, 800b57cec5SDimitry Andric SelectionDAG *DAG) { 810b57cec5SDimitry Andric Fn = &fn; 820b57cec5SDimitry Andric MF = &mf; 830b57cec5SDimitry Andric TLI = MF->getSubtarget().getTargetLowering(); 840b57cec5SDimitry Andric RegInfo = &MF->getRegInfo(); 850b57cec5SDimitry Andric const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); 8606c3fb27SDimitry Andric UA = DAG->getUniformityInfo(); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric // Check whether the function can return without sret-demotion. 890b57cec5SDimitry Andric SmallVector<ISD::OutputArg, 4> Outs; 900b57cec5SDimitry Andric CallingConv::ID CC = Fn->getCallingConv(); 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric GetReturnInfo(CC, Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI, 930b57cec5SDimitry Andric mf.getDataLayout()); 940b57cec5SDimitry Andric CanLowerReturn = 950b57cec5SDimitry Andric TLI->CanLowerReturn(CC, *MF, Fn->isVarArg(), Outs, Fn->getContext()); 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric // If this personality uses funclets, we need to do a bit more work. 980b57cec5SDimitry Andric DenseMap<const AllocaInst *, TinyPtrVector<int *>> CatchObjects; 990b57cec5SDimitry Andric EHPersonality Personality = classifyEHPersonality( 1000b57cec5SDimitry Andric Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr); 1010b57cec5SDimitry Andric if (isFuncletEHPersonality(Personality)) { 1020b57cec5SDimitry Andric // Calculate state numbers if we haven't already. 1030b57cec5SDimitry Andric WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo(); 1040b57cec5SDimitry Andric if (Personality == EHPersonality::MSVC_CXX) 1050b57cec5SDimitry Andric calculateWinCXXEHStateNumbers(&fn, EHInfo); 1060b57cec5SDimitry Andric else if (isAsynchronousEHPersonality(Personality)) 1070b57cec5SDimitry Andric calculateSEHStateNumbers(&fn, EHInfo); 1080b57cec5SDimitry Andric else if (Personality == EHPersonality::CoreCLR) 1090b57cec5SDimitry Andric calculateClrEHStateNumbers(&fn, EHInfo); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // Map all BB references in the WinEH data to MBBs. 1120b57cec5SDimitry Andric for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { 1130b57cec5SDimitry Andric for (WinEHHandlerType &H : TBME.HandlerArray) { 1140b57cec5SDimitry Andric if (const AllocaInst *AI = H.CatchObj.Alloca) 1150b57cec5SDimitry Andric CatchObjects.insert({AI, {}}).first->second.push_back( 1160b57cec5SDimitry Andric &H.CatchObj.FrameIndex); 1170b57cec5SDimitry Andric else 1180b57cec5SDimitry Andric H.CatchObj.FrameIndex = INT_MAX; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric // Initialize the mapping of values to registers. This is only set up for 1240b57cec5SDimitry Andric // instruction values that are used outside of the block that defines 1250b57cec5SDimitry Andric // them. 1265ffd83dbSDimitry Andric const Align StackAlign = TFI->getStackAlign(); 1270b57cec5SDimitry Andric for (const BasicBlock &BB : *Fn) { 1280b57cec5SDimitry Andric for (const Instruction &I : BB) { 1290b57cec5SDimitry Andric if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { 1300b57cec5SDimitry Andric Type *Ty = AI->getAllocatedType(); 13106c3fb27SDimitry Andric Align Alignment = AI->getAlign(); 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric // Static allocas can be folded into the initial stack frame 1340b57cec5SDimitry Andric // adjustment. For targets that don't realign the stack, don't 1350b57cec5SDimitry Andric // do this if there is an extra alignment requirement. 1360b57cec5SDimitry Andric if (AI->isStaticAlloca() && 1375ffd83dbSDimitry Andric (TFI->isStackRealignable() || (Alignment <= StackAlign))) { 1380b57cec5SDimitry Andric const ConstantInt *CUI = cast<ConstantInt>(AI->getArraySize()); 139480093f4SDimitry Andric uint64_t TySize = 140bdd1243dSDimitry Andric MF->getDataLayout().getTypeAllocSize(Ty).getKnownMinValue(); 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric TySize *= CUI->getZExtValue(); // Get total allocated size. 1430b57cec5SDimitry Andric if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. 1440b57cec5SDimitry Andric int FrameIndex = INT_MAX; 1450b57cec5SDimitry Andric auto Iter = CatchObjects.find(AI); 1460b57cec5SDimitry Andric if (Iter != CatchObjects.end() && TLI->needsFixedCatchObjects()) { 1470b57cec5SDimitry Andric FrameIndex = MF->getFrameInfo().CreateFixedObject( 1480b57cec5SDimitry Andric TySize, 0, /*IsImmutable=*/false, /*isAliased=*/true); 1495ffd83dbSDimitry Andric MF->getFrameInfo().setObjectAlignment(FrameIndex, Alignment); 1500b57cec5SDimitry Andric } else { 1515ffd83dbSDimitry Andric FrameIndex = MF->getFrameInfo().CreateStackObject(TySize, Alignment, 1525ffd83dbSDimitry Andric false, AI); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 15506c3fb27SDimitry Andric // Scalable vectors and structures that contain scalable vectors may 15606c3fb27SDimitry Andric // need a special StackID to distinguish them from other (fixed size) 15706c3fb27SDimitry Andric // stack objects. 15806c3fb27SDimitry Andric if (Ty->isScalableTy()) 159480093f4SDimitry Andric MF->getFrameInfo().setStackID(FrameIndex, 160480093f4SDimitry Andric TFI->getStackIDForScalableVectors()); 161480093f4SDimitry Andric 1620b57cec5SDimitry Andric StaticAllocaMap[AI] = FrameIndex; 1630b57cec5SDimitry Andric // Update the catch handler information. 1640b57cec5SDimitry Andric if (Iter != CatchObjects.end()) { 1650b57cec5SDimitry Andric for (int *CatchObjPtr : Iter->second) 1660b57cec5SDimitry Andric *CatchObjPtr = FrameIndex; 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric } else { 1690b57cec5SDimitry Andric // FIXME: Overaligned static allocas should be grouped into 1700b57cec5SDimitry Andric // a single dynamic allocation instead of using a separate 1710b57cec5SDimitry Andric // stack allocation for each one. 1720b57cec5SDimitry Andric // Inform the Frame Information that we have variable-sized objects. 1735ffd83dbSDimitry Andric MF->getFrameInfo().CreateVariableSizedObject( 1745ffd83dbSDimitry Andric Alignment <= StackAlign ? Align(1) : Alignment, AI); 1750b57cec5SDimitry Andric } 176fe6060f1SDimitry Andric } else if (auto *Call = dyn_cast<CallBase>(&I)) { 1770b57cec5SDimitry Andric // Look for inline asm that clobbers the SP register. 1785ffd83dbSDimitry Andric if (Call->isInlineAsm()) { 179e8d8bef9SDimitry Andric Register SP = TLI->getStackPointerRegisterToSaveRestore(); 1800b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 1810b57cec5SDimitry Andric std::vector<TargetLowering::AsmOperandInfo> Ops = 1825ffd83dbSDimitry Andric TLI->ParseConstraints(Fn->getParent()->getDataLayout(), TRI, 1835ffd83dbSDimitry Andric *Call); 1840b57cec5SDimitry Andric for (TargetLowering::AsmOperandInfo &Op : Ops) { 1850b57cec5SDimitry Andric if (Op.Type == InlineAsm::isClobber) { 1860b57cec5SDimitry Andric // Clobbers don't have SDValue operands, hence SDValue(). 1870b57cec5SDimitry Andric TLI->ComputeConstraintToUse(Op, SDValue(), DAG); 1880b57cec5SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> PhysReg = 1890b57cec5SDimitry Andric TLI->getRegForInlineAsmConstraint(TRI, Op.ConstraintCode, 1900b57cec5SDimitry Andric Op.ConstraintVT); 1910b57cec5SDimitry Andric if (PhysReg.first == SP) 1920b57cec5SDimitry Andric MF->getFrameInfo().setHasOpaqueSPAdjustment(true); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric // Look for calls to the @llvm.va_start intrinsic. We can omit some 1970b57cec5SDimitry Andric // prologue boilerplate for variadic functions that don't examine their 1980b57cec5SDimitry Andric // arguments. 1990b57cec5SDimitry Andric if (const auto *II = dyn_cast<IntrinsicInst>(&I)) { 2000b57cec5SDimitry Andric if (II->getIntrinsicID() == Intrinsic::vastart) 2010b57cec5SDimitry Andric MF->getFrameInfo().setHasVAStart(true); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 204fe6060f1SDimitry Andric // If we have a musttail call in a variadic function, we need to ensure 205fe6060f1SDimitry Andric // we forward implicit register parameters. 2060b57cec5SDimitry Andric if (const auto *CI = dyn_cast<CallInst>(&I)) { 2070b57cec5SDimitry Andric if (CI->isMustTailCall() && Fn->isVarArg()) 2080b57cec5SDimitry Andric MF->getFrameInfo().setHasMustTailInVarArgFunc(true); 2090b57cec5SDimitry Andric } 210fe6060f1SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric // Mark values used outside their block as exported, by allocating 2130b57cec5SDimitry Andric // a virtual register for them. 2140b57cec5SDimitry Andric if (isUsedOutsideOfDefiningBlock(&I)) 2150b57cec5SDimitry Andric if (!isa<AllocaInst>(I) || !StaticAllocaMap.count(cast<AllocaInst>(&I))) 2160b57cec5SDimitry Andric InitializeRegForValue(&I); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric // Decide the preferred extend type for a value. 2190b57cec5SDimitry Andric PreferredExtendType[&I] = getPreferredExtendForValue(&I); 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This 2240b57cec5SDimitry Andric // also creates the initial PHI MachineInstrs, though none of the input 2250b57cec5SDimitry Andric // operands are populated. 2260b57cec5SDimitry Andric for (const BasicBlock &BB : *Fn) { 2270b57cec5SDimitry Andric // Don't create MachineBasicBlocks for imaginary EH pad blocks. These blocks 2280b57cec5SDimitry Andric // are really data, and no instructions can live here. 2290b57cec5SDimitry Andric if (BB.isEHPad()) { 2300b57cec5SDimitry Andric const Instruction *PadInst = BB.getFirstNonPHI(); 2310b57cec5SDimitry Andric // If this is a non-landingpad EH pad, mark this function as using 2320b57cec5SDimitry Andric // funclets. 2330b57cec5SDimitry Andric // FIXME: SEH catchpads do not create EH scope/funclets, so we could avoid 2340b57cec5SDimitry Andric // setting this in such cases in order to improve frame layout. 2350b57cec5SDimitry Andric if (!isa<LandingPadInst>(PadInst)) { 2360b57cec5SDimitry Andric MF->setHasEHScopes(true); 2370b57cec5SDimitry Andric MF->setHasEHFunclets(true); 2380b57cec5SDimitry Andric MF->getFrameInfo().setHasOpaqueSPAdjustment(true); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric if (isa<CatchSwitchInst>(PadInst)) { 2410b57cec5SDimitry Andric assert(&*BB.begin() == PadInst && 2420b57cec5SDimitry Andric "WinEHPrepare failed to remove PHIs from imaginary BBs"); 2430b57cec5SDimitry Andric continue; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric if (isa<FuncletPadInst>(PadInst)) 2460b57cec5SDimitry Andric assert(&*BB.begin() == PadInst && "WinEHPrepare failed to demote PHIs"); 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(&BB); 2500b57cec5SDimitry Andric MBBMap[&BB] = MBB; 2510b57cec5SDimitry Andric MF->push_back(MBB); 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric // Transfer the address-taken flag. This is necessary because there could 2540b57cec5SDimitry Andric // be multiple MachineBasicBlocks corresponding to one BasicBlock, and only 2550b57cec5SDimitry Andric // the first one should be marked. 2560b57cec5SDimitry Andric if (BB.hasAddressTaken()) 257bdd1243dSDimitry Andric MBB->setAddressTakenIRBlock(const_cast<BasicBlock *>(&BB)); 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric // Mark landing pad blocks. 2600b57cec5SDimitry Andric if (BB.isEHPad()) 2610b57cec5SDimitry Andric MBB->setIsEHPad(); 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric // Create Machine PHI nodes for LLVM PHI nodes, lowering them as 2640b57cec5SDimitry Andric // appropriate. 2650b57cec5SDimitry Andric for (const PHINode &PN : BB.phis()) { 2660b57cec5SDimitry Andric if (PN.use_empty()) 2670b57cec5SDimitry Andric continue; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric // Skip empty types 2700b57cec5SDimitry Andric if (PN.getType()->isEmptyTy()) 2710b57cec5SDimitry Andric continue; 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric DebugLoc DL = PN.getDebugLoc(); 2740b57cec5SDimitry Andric unsigned PHIReg = ValueMap[&PN]; 2750b57cec5SDimitry Andric assert(PHIReg && "PHI node does not have an assigned virtual register!"); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 2780b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), PN.getType(), ValueVTs); 2790b57cec5SDimitry Andric for (EVT VT : ValueVTs) { 2800b57cec5SDimitry Andric unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); 2810b57cec5SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 2820b57cec5SDimitry Andric for (unsigned i = 0; i != NumRegisters; ++i) 2830b57cec5SDimitry Andric BuildMI(MBB, DL, TII->get(TargetOpcode::PHI), PHIReg + i); 2840b57cec5SDimitry Andric PHIReg += NumRegisters; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric if (isFuncletEHPersonality(Personality)) { 2900b57cec5SDimitry Andric WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo(); 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric // Map all BB references in the WinEH data to MBBs. 2930b57cec5SDimitry Andric for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) { 2940b57cec5SDimitry Andric for (WinEHHandlerType &H : TBME.HandlerArray) { 2950b57cec5SDimitry Andric if (H.Handler) 29606c3fb27SDimitry Andric H.Handler = MBBMap[cast<const BasicBlock *>(H.Handler)]; 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap) 3000b57cec5SDimitry Andric if (UME.Cleanup) 30106c3fb27SDimitry Andric UME.Cleanup = MBBMap[cast<const BasicBlock *>(UME.Cleanup)]; 3020b57cec5SDimitry Andric for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) { 30306c3fb27SDimitry Andric const auto *BB = cast<const BasicBlock *>(UME.Handler); 3040b57cec5SDimitry Andric UME.Handler = MBBMap[BB]; 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) { 30706c3fb27SDimitry Andric const auto *BB = cast<const BasicBlock *>(CME.Handler); 3080b57cec5SDimitry Andric CME.Handler = MBBMap[BB]; 3090b57cec5SDimitry Andric } 310bdd1243dSDimitry Andric } else if (Personality == EHPersonality::Wasm_CXX) { 3110b57cec5SDimitry Andric WasmEHFuncInfo &EHInfo = *MF->getWasmEHFuncInfo(); 312bdd1243dSDimitry Andric calculateWasmEHInfo(&fn, EHInfo); 313bdd1243dSDimitry Andric 314fe6060f1SDimitry Andric // Map all BB references in the Wasm EH data to MBBs. 315fe6060f1SDimitry Andric DenseMap<BBOrMBB, BBOrMBB> SrcToUnwindDest; 316fe6060f1SDimitry Andric for (auto &KV : EHInfo.SrcToUnwindDest) { 31706c3fb27SDimitry Andric const auto *Src = cast<const BasicBlock *>(KV.first); 31806c3fb27SDimitry Andric const auto *Dest = cast<const BasicBlock *>(KV.second); 319fe6060f1SDimitry Andric SrcToUnwindDest[MBBMap[Src]] = MBBMap[Dest]; 3200b57cec5SDimitry Andric } 321fe6060f1SDimitry Andric EHInfo.SrcToUnwindDest = std::move(SrcToUnwindDest); 322fe6060f1SDimitry Andric DenseMap<BBOrMBB, SmallPtrSet<BBOrMBB, 4>> UnwindDestToSrcs; 323fe6060f1SDimitry Andric for (auto &KV : EHInfo.UnwindDestToSrcs) { 32406c3fb27SDimitry Andric const auto *Dest = cast<const BasicBlock *>(KV.first); 325fe6060f1SDimitry Andric UnwindDestToSrcs[MBBMap[Dest]] = SmallPtrSet<BBOrMBB, 4>(); 326fe6060f1SDimitry Andric for (const auto P : KV.second) 327fe6060f1SDimitry Andric UnwindDestToSrcs[MBBMap[Dest]].insert( 32806c3fb27SDimitry Andric MBBMap[cast<const BasicBlock *>(P)]); 329fe6060f1SDimitry Andric } 330fe6060f1SDimitry Andric EHInfo.UnwindDestToSrcs = std::move(UnwindDestToSrcs); 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric /// clear - Clear out all the function-specific state. This returns this 3350b57cec5SDimitry Andric /// FunctionLoweringInfo to an empty state, ready to be used for a 3360b57cec5SDimitry Andric /// different function. 3370b57cec5SDimitry Andric void FunctionLoweringInfo::clear() { 3380b57cec5SDimitry Andric MBBMap.clear(); 3390b57cec5SDimitry Andric ValueMap.clear(); 3400b57cec5SDimitry Andric VirtReg2Value.clear(); 3410b57cec5SDimitry Andric StaticAllocaMap.clear(); 3420b57cec5SDimitry Andric LiveOutRegInfo.clear(); 3430b57cec5SDimitry Andric VisitedBBs.clear(); 3440b57cec5SDimitry Andric ArgDbgValues.clear(); 3450b57cec5SDimitry Andric DescribedArgs.clear(); 3460b57cec5SDimitry Andric ByValArgFrameIndexMap.clear(); 3470b57cec5SDimitry Andric RegFixups.clear(); 3480b57cec5SDimitry Andric RegsWithFixups.clear(); 3490b57cec5SDimitry Andric StatepointStackSlots.clear(); 350e8d8bef9SDimitry Andric StatepointRelocationMaps.clear(); 3510b57cec5SDimitry Andric PreferredExtendType.clear(); 35206c3fb27SDimitry Andric PreprocessedDbgDeclares.clear(); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric /// CreateReg - Allocate a single virtual register for the given type. 3565ffd83dbSDimitry Andric Register FunctionLoweringInfo::CreateReg(MVT VT, bool isDivergent) { 357bdd1243dSDimitry Andric return RegInfo->createVirtualRegister(TLI->getRegClassFor(VT, isDivergent)); 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric /// CreateRegs - Allocate the appropriate number of virtual registers of 3610b57cec5SDimitry Andric /// the correctly promoted or expanded types. Assign these registers 3620b57cec5SDimitry Andric /// consecutive vreg numbers and return the first assigned number. 3630b57cec5SDimitry Andric /// 3640b57cec5SDimitry Andric /// In the case that the given value has struct or array type, this function 3650b57cec5SDimitry Andric /// will assign registers for each member or element. 3660b57cec5SDimitry Andric /// 3675ffd83dbSDimitry Andric Register FunctionLoweringInfo::CreateRegs(Type *Ty, bool isDivergent) { 3680b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 3690b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); 3700b57cec5SDimitry Andric 3715ffd83dbSDimitry Andric Register FirstReg; 3720b57cec5SDimitry Andric for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { 3730b57cec5SDimitry Andric EVT ValueVT = ValueVTs[Value]; 3740b57cec5SDimitry Andric MVT RegisterVT = TLI->getRegisterType(Ty->getContext(), ValueVT); 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric unsigned NumRegs = TLI->getNumRegisters(Ty->getContext(), ValueVT); 3770b57cec5SDimitry Andric for (unsigned i = 0; i != NumRegs; ++i) { 3785ffd83dbSDimitry Andric Register R = CreateReg(RegisterVT, isDivergent); 3790b57cec5SDimitry Andric if (!FirstReg) FirstReg = R; 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric return FirstReg; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3855ffd83dbSDimitry Andric Register FunctionLoweringInfo::CreateRegs(const Value *V) { 38606c3fb27SDimitry Andric return CreateRegs(V->getType(), UA && UA->isDivergent(V) && 3875ffd83dbSDimitry Andric !TLI->requiresUniformRegister(*MF, V)); 3880b57cec5SDimitry Andric } 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric /// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the 3910b57cec5SDimitry Andric /// register is a PHI destination and the PHI's LiveOutInfo is not valid. If 3920b57cec5SDimitry Andric /// the register's LiveOutInfo is for a smaller bit width, it is extended to 3930b57cec5SDimitry Andric /// the larger bit width by zero extension. The bit width must be no smaller 3940b57cec5SDimitry Andric /// than the LiveOutInfo's existing bit width. 3950b57cec5SDimitry Andric const FunctionLoweringInfo::LiveOutInfo * 3965ffd83dbSDimitry Andric FunctionLoweringInfo::GetLiveOutRegInfo(Register Reg, unsigned BitWidth) { 3970b57cec5SDimitry Andric if (!LiveOutRegInfo.inBounds(Reg)) 3980b57cec5SDimitry Andric return nullptr; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric LiveOutInfo *LOI = &LiveOutRegInfo[Reg]; 4010b57cec5SDimitry Andric if (!LOI->IsValid) 4020b57cec5SDimitry Andric return nullptr; 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric if (BitWidth > LOI->Known.getBitWidth()) { 4050b57cec5SDimitry Andric LOI->NumSignBits = 1; 4065ffd83dbSDimitry Andric LOI->Known = LOI->Known.anyext(BitWidth); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric return LOI; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination 4130b57cec5SDimitry Andric /// register based on the LiveOutInfo of its operands. 4140b57cec5SDimitry Andric void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) { 4150b57cec5SDimitry Andric Type *Ty = PN->getType(); 4160b57cec5SDimitry Andric if (!Ty->isIntegerTy() || Ty->isVectorTy()) 4170b57cec5SDimitry Andric return; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric SmallVector<EVT, 1> ValueVTs; 4200b57cec5SDimitry Andric ComputeValueVTs(*TLI, MF->getDataLayout(), Ty, ValueVTs); 4210b57cec5SDimitry Andric assert(ValueVTs.size() == 1 && 4220b57cec5SDimitry Andric "PHIs with non-vector integer types should have a single VT."); 4230b57cec5SDimitry Andric EVT IntVT = ValueVTs[0]; 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric if (TLI->getNumRegisters(PN->getContext(), IntVT) != 1) 4260b57cec5SDimitry Andric return; 4270b57cec5SDimitry Andric IntVT = TLI->getTypeToTransformTo(PN->getContext(), IntVT); 4280b57cec5SDimitry Andric unsigned BitWidth = IntVT.getSizeInBits(); 4290b57cec5SDimitry Andric 43081ad6265SDimitry Andric auto It = ValueMap.find(PN); 43181ad6265SDimitry Andric if (It == ValueMap.end()) 4320b57cec5SDimitry Andric return; 43381ad6265SDimitry Andric 43481ad6265SDimitry Andric Register DestReg = It->second; 43581ad6265SDimitry Andric if (DestReg == 0) 436bdd1243dSDimitry Andric return; 437bdd1243dSDimitry Andric assert(DestReg.isVirtual() && "Expected a virtual reg"); 4380b57cec5SDimitry Andric LiveOutRegInfo.grow(DestReg); 4390b57cec5SDimitry Andric LiveOutInfo &DestLOI = LiveOutRegInfo[DestReg]; 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric Value *V = PN->getIncomingValue(0); 4420b57cec5SDimitry Andric if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) { 4430b57cec5SDimitry Andric DestLOI.NumSignBits = 1; 4440b57cec5SDimitry Andric DestLOI.Known = KnownBits(BitWidth); 4450b57cec5SDimitry Andric return; 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { 44981ad6265SDimitry Andric APInt Val; 45081ad6265SDimitry Andric if (TLI->signExtendConstant(CI)) 45181ad6265SDimitry Andric Val = CI->getValue().sext(BitWidth); 45281ad6265SDimitry Andric else 45381ad6265SDimitry Andric Val = CI->getValue().zext(BitWidth); 4540b57cec5SDimitry Andric DestLOI.NumSignBits = Val.getNumSignBits(); 455e8d8bef9SDimitry Andric DestLOI.Known = KnownBits::makeConstant(Val); 4560b57cec5SDimitry Andric } else { 4570b57cec5SDimitry Andric assert(ValueMap.count(V) && "V should have been placed in ValueMap when its" 4580b57cec5SDimitry Andric "CopyToReg node was created."); 4595ffd83dbSDimitry Andric Register SrcReg = ValueMap[V]; 460bdd1243dSDimitry Andric if (!SrcReg.isVirtual()) { 4610b57cec5SDimitry Andric DestLOI.IsValid = false; 4620b57cec5SDimitry Andric return; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); 4650b57cec5SDimitry Andric if (!SrcLOI) { 4660b57cec5SDimitry Andric DestLOI.IsValid = false; 4670b57cec5SDimitry Andric return; 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric DestLOI = *SrcLOI; 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric assert(DestLOI.Known.Zero.getBitWidth() == BitWidth && 4730b57cec5SDimitry Andric DestLOI.Known.One.getBitWidth() == BitWidth && 4740b57cec5SDimitry Andric "Masks should have the same bit width as the type."); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) { 4770b57cec5SDimitry Andric Value *V = PN->getIncomingValue(i); 4780b57cec5SDimitry Andric if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) { 4790b57cec5SDimitry Andric DestLOI.NumSignBits = 1; 4800b57cec5SDimitry Andric DestLOI.Known = KnownBits(BitWidth); 4810b57cec5SDimitry Andric return; 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { 48581ad6265SDimitry Andric APInt Val; 48681ad6265SDimitry Andric if (TLI->signExtendConstant(CI)) 48781ad6265SDimitry Andric Val = CI->getValue().sext(BitWidth); 48881ad6265SDimitry Andric else 48981ad6265SDimitry Andric Val = CI->getValue().zext(BitWidth); 4900b57cec5SDimitry Andric DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, Val.getNumSignBits()); 4910b57cec5SDimitry Andric DestLOI.Known.Zero &= ~Val; 4920b57cec5SDimitry Andric DestLOI.Known.One &= Val; 4930b57cec5SDimitry Andric continue; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric assert(ValueMap.count(V) && "V should have been placed in ValueMap when " 4970b57cec5SDimitry Andric "its CopyToReg node was created."); 4985ffd83dbSDimitry Andric Register SrcReg = ValueMap[V]; 4995ffd83dbSDimitry Andric if (!SrcReg.isVirtual()) { 5000b57cec5SDimitry Andric DestLOI.IsValid = false; 5010b57cec5SDimitry Andric return; 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth); 5040b57cec5SDimitry Andric if (!SrcLOI) { 5050b57cec5SDimitry Andric DestLOI.IsValid = false; 5060b57cec5SDimitry Andric return; 5070b57cec5SDimitry Andric } 5080b57cec5SDimitry Andric DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits); 50906c3fb27SDimitry Andric DestLOI.Known = DestLOI.Known.intersectWith(SrcLOI->Known); 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric /// setArgumentFrameIndex - Record frame index for the byval 5140b57cec5SDimitry Andric /// argument. This overrides previous frame index entry for this argument, 5150b57cec5SDimitry Andric /// if any. 5160b57cec5SDimitry Andric void FunctionLoweringInfo::setArgumentFrameIndex(const Argument *A, 5170b57cec5SDimitry Andric int FI) { 5180b57cec5SDimitry Andric ByValArgFrameIndexMap[A] = FI; 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric /// getArgumentFrameIndex - Get frame index for the byval argument. 5220b57cec5SDimitry Andric /// If the argument does not have any assigned frame index then 0 is 5230b57cec5SDimitry Andric /// returned. 5240b57cec5SDimitry Andric int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) { 5250b57cec5SDimitry Andric auto I = ByValArgFrameIndexMap.find(A); 5260b57cec5SDimitry Andric if (I != ByValArgFrameIndexMap.end()) 5270b57cec5SDimitry Andric return I->second; 5280b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Argument does not have assigned frame index!\n"); 5290b57cec5SDimitry Andric return INT_MAX; 5300b57cec5SDimitry Andric } 5310b57cec5SDimitry Andric 5325ffd83dbSDimitry Andric Register FunctionLoweringInfo::getCatchPadExceptionPointerVReg( 5330b57cec5SDimitry Andric const Value *CPI, const TargetRegisterClass *RC) { 5340b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 5350b57cec5SDimitry Andric auto I = CatchPadExceptionPointers.insert({CPI, 0}); 5365ffd83dbSDimitry Andric Register &VReg = I.first->second; 5370b57cec5SDimitry Andric if (I.second) 5380b57cec5SDimitry Andric VReg = MRI.createVirtualRegister(RC); 5390b57cec5SDimitry Andric assert(VReg && "null vreg in exception pointer table!"); 5400b57cec5SDimitry Andric return VReg; 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric const Value * 5445ffd83dbSDimitry Andric FunctionLoweringInfo::getValueFromVirtualReg(Register Vreg) { 5450b57cec5SDimitry Andric if (VirtReg2Value.empty()) { 5460b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 5470b57cec5SDimitry Andric for (auto &P : ValueMap) { 5480b57cec5SDimitry Andric ValueVTs.clear(); 5490b57cec5SDimitry Andric ComputeValueVTs(*TLI, Fn->getParent()->getDataLayout(), 5500b57cec5SDimitry Andric P.first->getType(), ValueVTs); 5510b57cec5SDimitry Andric unsigned Reg = P.second; 5520b57cec5SDimitry Andric for (EVT VT : ValueVTs) { 5530b57cec5SDimitry Andric unsigned NumRegisters = TLI->getNumRegisters(Fn->getContext(), VT); 5540b57cec5SDimitry Andric for (unsigned i = 0, e = NumRegisters; i != e; ++i) 5550b57cec5SDimitry Andric VirtReg2Value[Reg++] = P.first; 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric return VirtReg2Value.lookup(Vreg); 5600b57cec5SDimitry Andric } 561