10b57cec5SDimitry Andric //===- SelectionDAGBuilder.h - Selection-DAG building -----------*- C++ -*-===// 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 from LLVM IR into SelectionDAG IR. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SELECTIONDAGBUILDER_H 140b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_SELECTIONDAG_SELECTIONDAGBUILDER_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "StatepointLowering.h" 170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 190b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 21bdd1243dSDimitry Andric #include "llvm/CodeGen/AssignmentTrackingAnalysis.h" 22349cc55cSDimitry Andric #include "llvm/CodeGen/CodeGenCommonISel.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/ISDOpcodes.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGNodes.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/SwitchLoweringUtils.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/ValueTypes.h" 28*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h" 290b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 300b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 310b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h" 320b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 330b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 340b57cec5SDimitry Andric #include <algorithm> 350b57cec5SDimitry Andric #include <cassert> 360b57cec5SDimitry Andric #include <cstdint> 37bdd1243dSDimitry Andric #include <optional> 380b57cec5SDimitry Andric #include <utility> 390b57cec5SDimitry Andric #include <vector> 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric namespace llvm { 420b57cec5SDimitry Andric 43e8d8bef9SDimitry Andric class AAResults; 440b57cec5SDimitry Andric class AllocaInst; 450b57cec5SDimitry Andric class AtomicCmpXchgInst; 460b57cec5SDimitry Andric class AtomicRMWInst; 47bdd1243dSDimitry Andric class AssumptionCache; 480b57cec5SDimitry Andric class BasicBlock; 490b57cec5SDimitry Andric class BranchInst; 500b57cec5SDimitry Andric class CallInst; 510b57cec5SDimitry Andric class CallBrInst; 520b57cec5SDimitry Andric class CatchPadInst; 530b57cec5SDimitry Andric class CatchReturnInst; 540b57cec5SDimitry Andric class CatchSwitchInst; 550b57cec5SDimitry Andric class CleanupPadInst; 560b57cec5SDimitry Andric class CleanupReturnInst; 570b57cec5SDimitry Andric class Constant; 580b57cec5SDimitry Andric class ConstrainedFPIntrinsic; 590b57cec5SDimitry Andric class DbgValueInst; 600b57cec5SDimitry Andric class DataLayout; 610b57cec5SDimitry Andric class DIExpression; 620b57cec5SDimitry Andric class DILocalVariable; 630b57cec5SDimitry Andric class DILocation; 640b57cec5SDimitry Andric class FenceInst; 650b57cec5SDimitry Andric class FunctionLoweringInfo; 660b57cec5SDimitry Andric class GCFunctionInfo; 670b57cec5SDimitry Andric class GCRelocateInst; 680b57cec5SDimitry Andric class GCResultInst; 69e8d8bef9SDimitry Andric class GCStatepointInst; 700b57cec5SDimitry Andric class IndirectBrInst; 710b57cec5SDimitry Andric class InvokeInst; 720b57cec5SDimitry Andric class LandingPadInst; 730b57cec5SDimitry Andric class LLVMContext; 740b57cec5SDimitry Andric class LoadInst; 750b57cec5SDimitry Andric class MachineBasicBlock; 760b57cec5SDimitry Andric class PHINode; 770b57cec5SDimitry Andric class ResumeInst; 780b57cec5SDimitry Andric class ReturnInst; 790b57cec5SDimitry Andric class SDDbgValue; 805ffd83dbSDimitry Andric class SelectionDAG; 810b57cec5SDimitry Andric class StoreInst; 820b57cec5SDimitry Andric class SwiftErrorValueTracking; 830b57cec5SDimitry Andric class SwitchInst; 840b57cec5SDimitry Andric class TargetLibraryInfo; 850b57cec5SDimitry Andric class TargetMachine; 860b57cec5SDimitry Andric class Type; 870b57cec5SDimitry Andric class VAArgInst; 880b57cec5SDimitry Andric class UnreachableInst; 890b57cec5SDimitry Andric class Use; 900b57cec5SDimitry Andric class User; 910b57cec5SDimitry Andric class Value; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 940b57cec5SDimitry Andric /// SelectionDAGBuilder - This is the common target-independent lowering 950b57cec5SDimitry Andric /// implementation that is parameterized by a TargetLowering object. 960b57cec5SDimitry Andric /// 970b57cec5SDimitry Andric class SelectionDAGBuilder { 980b57cec5SDimitry Andric /// The current instruction being visited. 990b57cec5SDimitry Andric const Instruction *CurInst = nullptr; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric DenseMap<const Value*, SDValue> NodeMap; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// Maps argument value for unused arguments. This is used 1040b57cec5SDimitry Andric /// to preserve debug information for incoming arguments. 1050b57cec5SDimitry Andric DenseMap<const Value*, SDValue> UnusedArgNodeMap; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// Helper type for DanglingDebugInfoMap. 1080b57cec5SDimitry Andric class DanglingDebugInfo { 1090b57cec5SDimitry Andric unsigned SDNodeOrder = 0; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric public: 1125f757f3fSDimitry Andric DILocalVariable *Variable; 1135f757f3fSDimitry Andric DIExpression *Expression; 1145f757f3fSDimitry Andric DebugLoc dl; 1150b57cec5SDimitry Andric DanglingDebugInfo() = default; 1165f757f3fSDimitry Andric DanglingDebugInfo(DILocalVariable *Var, DIExpression *Expr, DebugLoc DL, 1175f757f3fSDimitry Andric unsigned SDNO) 1185f757f3fSDimitry Andric : SDNodeOrder(SDNO), Variable(Var), Expression(Expr), 1195f757f3fSDimitry Andric dl(std::move(DL)) {} 1200b57cec5SDimitry Andric 1215f757f3fSDimitry Andric DILocalVariable *getVariable() const { return Variable; } 1225f757f3fSDimitry Andric DIExpression *getExpression() const { return Expression; } 1235f757f3fSDimitry Andric DebugLoc getDebugLoc() const { return dl; } 124bdd1243dSDimitry Andric unsigned getSDNodeOrder() const { return SDNodeOrder; } 125bdd1243dSDimitry Andric 126bdd1243dSDimitry Andric /// Helper for printing DanglingDebugInfo. This hoop-jumping is to 1275f757f3fSDimitry Andric /// store a Value pointer, so that we can print a whole DDI as one object. 128bdd1243dSDimitry Andric /// Call SelectionDAGBuilder::printDDI instead of using directly. 129bdd1243dSDimitry Andric struct Print { 1305f757f3fSDimitry Andric Print(const Value *V, const DanglingDebugInfo &DDI) : V(V), DDI(DDI) {} 1315f757f3fSDimitry Andric const Value *V; 132bdd1243dSDimitry Andric const DanglingDebugInfo &DDI; 133bdd1243dSDimitry Andric friend raw_ostream &operator<<(raw_ostream &OS, 134bdd1243dSDimitry Andric const DanglingDebugInfo::Print &P) { 1355f757f3fSDimitry Andric OS << "DDI(var=" << *P.DDI.getVariable(); 1365f757f3fSDimitry Andric if (P.V) 1375f757f3fSDimitry Andric OS << ", val=" << *P.V; 1385f757f3fSDimitry Andric else 1395f757f3fSDimitry Andric OS << ", val=nullptr"; 1405f757f3fSDimitry Andric 1415f757f3fSDimitry Andric OS << ", expr=" << *P.DDI.getExpression() 142bdd1243dSDimitry Andric << ", order=" << P.DDI.getSDNodeOrder() 143bdd1243dSDimitry Andric << ", loc=" << P.DDI.getDebugLoc() << ")"; 144bdd1243dSDimitry Andric return OS; 145bdd1243dSDimitry Andric } 1460b57cec5SDimitry Andric }; 147bdd1243dSDimitry Andric }; 148bdd1243dSDimitry Andric 149bdd1243dSDimitry Andric /// Returns an object that defines `raw_ostream &operator<<` for printing. 150bdd1243dSDimitry Andric /// Usage example: 151bdd1243dSDimitry Andric //// errs() << printDDI(MyDanglingInfo) << " is dangling\n"; 1525f757f3fSDimitry Andric DanglingDebugInfo::Print printDDI(const Value *V, 1535f757f3fSDimitry Andric const DanglingDebugInfo &DDI) { 1545f757f3fSDimitry Andric return DanglingDebugInfo::Print(V, DDI); 155bdd1243dSDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric /// Helper type for DanglingDebugInfoMap. 1580b57cec5SDimitry Andric typedef std::vector<DanglingDebugInfo> DanglingDebugInfoVector; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric /// Keeps track of dbg_values for which we have not yet seen the referent. 1610b57cec5SDimitry Andric /// We defer handling these until we do see it. 1620b57cec5SDimitry Andric MapVector<const Value*, DanglingDebugInfoVector> DanglingDebugInfoMap; 1630b57cec5SDimitry Andric 16406c3fb27SDimitry Andric /// Cache the module flag for whether we should use debug-info assignment 16506c3fb27SDimitry Andric /// tracking. 16606c3fb27SDimitry Andric bool AssignmentTrackingEnabled = false; 16706c3fb27SDimitry Andric 1680b57cec5SDimitry Andric public: 1690b57cec5SDimitry Andric /// Loads are not emitted to the program immediately. We bunch them up and 1700b57cec5SDimitry Andric /// then emit token factor nodes when possible. This allows us to get simple 1710b57cec5SDimitry Andric /// disambiguation between loads without worrying about alias analysis. 1720b57cec5SDimitry Andric SmallVector<SDValue, 8> PendingLoads; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric /// State used while lowering a statepoint sequence (gc_statepoint, 1750b57cec5SDimitry Andric /// gc_relocate, and gc_result). See StatepointLowering.hpp/cpp for details. 1760b57cec5SDimitry Andric StatepointLoweringState StatepointLowering; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric private: 1790b57cec5SDimitry Andric /// CopyToReg nodes that copy values to virtual registers for export to other 1800b57cec5SDimitry Andric /// blocks need to be emitted before any terminator instruction, but they have 1810b57cec5SDimitry Andric /// no other ordering requirements. We bunch them up and the emit a single 1820b57cec5SDimitry Andric /// tokenfactor for them just before terminator instructions. 1830b57cec5SDimitry Andric SmallVector<SDValue, 8> PendingExports; 1840b57cec5SDimitry Andric 185480093f4SDimitry Andric /// Similar to loads, nodes corresponding to constrained FP intrinsics are 186480093f4SDimitry Andric /// bunched up and emitted when necessary. These can be moved across each 187480093f4SDimitry Andric /// other and any (normal) memory operation (load or store), but not across 188480093f4SDimitry Andric /// calls or instructions having unspecified side effects. As a special 189480093f4SDimitry Andric /// case, constrained FP intrinsics using fpexcept.strict may not be deleted 190480093f4SDimitry Andric /// even if otherwise unused, so they need to be chained before any 191480093f4SDimitry Andric /// terminator instruction (like PendingExports). We track the latter 192480093f4SDimitry Andric /// set of nodes in a separate list. 193480093f4SDimitry Andric SmallVector<SDValue, 8> PendingConstrainedFP; 194480093f4SDimitry Andric SmallVector<SDValue, 8> PendingConstrainedFPStrict; 195480093f4SDimitry Andric 196480093f4SDimitry Andric /// Update root to include all chains from the Pending list. 197480093f4SDimitry Andric SDValue updateRoot(SmallVectorImpl<SDValue> &Pending); 198480093f4SDimitry Andric 1990b57cec5SDimitry Andric /// A unique monotonically increasing number used to order the SDNodes we 2000b57cec5SDimitry Andric /// create. 2010b57cec5SDimitry Andric unsigned SDNodeOrder; 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric /// Emit comparison and split W into two subtrees. 2040b57cec5SDimitry Andric void splitWorkItem(SwitchCG::SwitchWorkList &WorkList, 2050b57cec5SDimitry Andric const SwitchCG::SwitchWorkListItem &W, Value *Cond, 2060b57cec5SDimitry Andric MachineBasicBlock *SwitchMBB); 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric /// Lower W. 2090b57cec5SDimitry Andric void lowerWorkItem(SwitchCG::SwitchWorkListItem W, Value *Cond, 2100b57cec5SDimitry Andric MachineBasicBlock *SwitchMBB, 2110b57cec5SDimitry Andric MachineBasicBlock *DefaultMBB); 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Peel the top probability case if it exceeds the threshold 2140b57cec5SDimitry Andric MachineBasicBlock * 2150b57cec5SDimitry Andric peelDominantCaseCluster(const SwitchInst &SI, 2160b57cec5SDimitry Andric SwitchCG::CaseClusterVector &Clusters, 2170b57cec5SDimitry Andric BranchProbability &PeeledCaseProb); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric private: 2200b57cec5SDimitry Andric const TargetMachine &TM; 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric public: 2230b57cec5SDimitry Andric /// Lowest valid SDNodeOrder. The special case 0 is reserved for scheduling 2240b57cec5SDimitry Andric /// nodes without a corresponding SDNode. 2250b57cec5SDimitry Andric static const unsigned LowestSDNodeOrder = 1; 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric SelectionDAG &DAG; 228e8d8bef9SDimitry Andric AAResults *AA = nullptr; 229bdd1243dSDimitry Andric AssumptionCache *AC = nullptr; 23006c3fb27SDimitry Andric const TargetLibraryInfo *LibInfo = nullptr; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric class SDAGSwitchLowering : public SwitchCG::SwitchLowering { 2330b57cec5SDimitry Andric public: 2340b57cec5SDimitry Andric SDAGSwitchLowering(SelectionDAGBuilder *sdb, FunctionLoweringInfo &funcinfo) 2350b57cec5SDimitry Andric : SwitchCG::SwitchLowering(funcinfo), SDB(sdb) {} 2360b57cec5SDimitry Andric 237972a253aSDimitry Andric void addSuccessorWithProb( 2380b57cec5SDimitry Andric MachineBasicBlock *Src, MachineBasicBlock *Dst, 2390b57cec5SDimitry Andric BranchProbability Prob = BranchProbability::getUnknown()) override { 2400b57cec5SDimitry Andric SDB->addSuccessorWithProb(Src, Dst, Prob); 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric private: 24406c3fb27SDimitry Andric SelectionDAGBuilder *SDB = nullptr; 2450b57cec5SDimitry Andric }; 2460b57cec5SDimitry Andric 2475ffd83dbSDimitry Andric // Data related to deferred switch lowerings. Used to construct additional 2485ffd83dbSDimitry Andric // Basic Blocks in SelectionDAGISel::FinishBasicBlock. 2490b57cec5SDimitry Andric std::unique_ptr<SDAGSwitchLowering> SL; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric /// A StackProtectorDescriptor structure used to communicate stack protector 2520b57cec5SDimitry Andric /// information in between SelectBasicBlock and FinishBasicBlock. 2530b57cec5SDimitry Andric StackProtectorDescriptor SPDescriptor; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric // Emit PHI-node-operand constants only once even if used by multiple 2560b57cec5SDimitry Andric // PHI nodes. 2570b57cec5SDimitry Andric DenseMap<const Constant *, unsigned> ConstantsOut; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric /// Information about the function as a whole. 2600b57cec5SDimitry Andric FunctionLoweringInfo &FuncInfo; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric /// Information about the swifterror values used throughout the function. 2630b57cec5SDimitry Andric SwiftErrorValueTracking &SwiftError; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric /// Garbage collection metadata for the function. 26606c3fb27SDimitry Andric GCFunctionInfo *GFI = nullptr; 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric /// Map a landing pad to the call site indexes. 2690b57cec5SDimitry Andric DenseMap<MachineBasicBlock *, SmallVector<unsigned, 4>> LPadToCallSiteMap; 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric /// This is set to true if a call in the current block has been translated as 2720b57cec5SDimitry Andric /// a tail call. In this case, no subsequent DAG nodes should be created. 2730b57cec5SDimitry Andric bool HasTailCall = false; 2740b57cec5SDimitry Andric 27506c3fb27SDimitry Andric LLVMContext *Context = nullptr; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric SelectionDAGBuilder(SelectionDAG &dag, FunctionLoweringInfo &funcinfo, 2785f757f3fSDimitry Andric SwiftErrorValueTracking &swifterror, CodeGenOptLevel ol) 2790b57cec5SDimitry Andric : SDNodeOrder(LowestSDNodeOrder), TM(dag.getTarget()), DAG(dag), 2805f757f3fSDimitry Andric SL(std::make_unique<SDAGSwitchLowering>(this, funcinfo)), 2815f757f3fSDimitry Andric FuncInfo(funcinfo), SwiftError(swifterror) {} 2820b57cec5SDimitry Andric 283bdd1243dSDimitry Andric void init(GCFunctionInfo *gfi, AAResults *AA, AssumptionCache *AC, 2840b57cec5SDimitry Andric const TargetLibraryInfo *li); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric /// Clear out the current SelectionDAG and the associated state and prepare 2870b57cec5SDimitry Andric /// this SelectionDAGBuilder object to be used for a new block. This doesn't 2880b57cec5SDimitry Andric /// clear out information about additional blocks that are needed to complete 2890b57cec5SDimitry Andric /// switch lowering or PHI node updating; that information is cleared out as 2900b57cec5SDimitry Andric /// it is consumed. 2910b57cec5SDimitry Andric void clear(); 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric /// Clear the dangling debug information map. This function is separated from 2940b57cec5SDimitry Andric /// the clear so that debug information that is dangling in a basic block can 2950b57cec5SDimitry Andric /// be properly resolved in a different basic block. This allows the 2960b57cec5SDimitry Andric /// SelectionDAG to resolve dangling debug information attached to PHI nodes. 2970b57cec5SDimitry Andric void clearDanglingDebugInfo(); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric /// Return the current virtual root of the Selection DAG, flushing any 3000b57cec5SDimitry Andric /// PendingLoad items. This must be done before emitting a store or any other 301480093f4SDimitry Andric /// memory node that may need to be ordered after any prior load instructions. 302480093f4SDimitry Andric SDValue getMemoryRoot(); 303480093f4SDimitry Andric 304480093f4SDimitry Andric /// Similar to getMemoryRoot, but also flushes PendingConstrainedFP(Strict) 305480093f4SDimitry Andric /// items. This must be done before emitting any call other any other node 306480093f4SDimitry Andric /// that may need to be ordered after FP instructions due to other side 307480093f4SDimitry Andric /// effects. 3080b57cec5SDimitry Andric SDValue getRoot(); 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric /// Similar to getRoot, but instead of flushing all the PendingLoad items, 311480093f4SDimitry Andric /// flush all the PendingExports (and PendingConstrainedFPStrict) items. 312480093f4SDimitry Andric /// It is necessary to do this before emitting a terminator instruction. 3130b57cec5SDimitry Andric SDValue getControlRoot(); 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric SDLoc getCurSDLoc() const { 3160b57cec5SDimitry Andric return SDLoc(CurInst, SDNodeOrder); 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric DebugLoc getCurDebugLoc() const { 3200b57cec5SDimitry Andric return CurInst ? CurInst->getDebugLoc() : DebugLoc(); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 32381ad6265SDimitry Andric void CopyValueToVirtualRegister(const Value *V, unsigned Reg, 32481ad6265SDimitry Andric ISD::NodeType ExtendType = ISD::ANY_EXTEND); 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric void visit(const Instruction &I); 3275f757f3fSDimitry Andric void visitDbgInfo(const Instruction &I); 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric void visit(unsigned Opcode, const User &I); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric /// If there was virtual register allocated for the value V emit CopyFromReg 3320b57cec5SDimitry Andric /// of the specified type Ty. Return empty SDValue() otherwise. 3330b57cec5SDimitry Andric SDValue getCopyFromRegs(const Value *V, Type *Ty); 3340b57cec5SDimitry Andric 335fe6060f1SDimitry Andric /// Register a dbg_value which relies on a Value which we have not yet seen. 3365f757f3fSDimitry Andric void addDanglingDebugInfo(SmallVectorImpl<Value *> &Values, 3375f757f3fSDimitry Andric DILocalVariable *Var, DIExpression *Expr, 3385f757f3fSDimitry Andric bool IsVariadic, DebugLoc DL, unsigned Order); 339fe6060f1SDimitry Andric 3400b57cec5SDimitry Andric /// If we have dangling debug info that describes \p Variable, or an 3410b57cec5SDimitry Andric /// overlapping part of variable considering the \p Expr, then this method 3420b57cec5SDimitry Andric /// will drop that debug info as it isn't valid any longer. 3430b57cec5SDimitry Andric void dropDanglingDebugInfo(const DILocalVariable *Variable, 3440b57cec5SDimitry Andric const DIExpression *Expr); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric /// If we saw an earlier dbg_value referring to V, generate the debug data 3470b57cec5SDimitry Andric /// structures now that we've seen its definition. 3480b57cec5SDimitry Andric void resolveDanglingDebugInfo(const Value *V, SDValue Val); 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric /// For the given dangling debuginfo record, perform last-ditch efforts to 3510b57cec5SDimitry Andric /// resolve the debuginfo to something that is represented in this DAG. If 3520b57cec5SDimitry Andric /// this cannot be done, produce an Undef debug value record. 3535f757f3fSDimitry Andric void salvageUnresolvedDbgValue(const Value *V, DanglingDebugInfo &DDI); 3540b57cec5SDimitry Andric 355fe6060f1SDimitry Andric /// For a given list of Values, attempt to create and record a SDDbgValue in 356fe6060f1SDimitry Andric /// the SelectionDAG. 357fe6060f1SDimitry Andric bool handleDebugValue(ArrayRef<const Value *> Values, DILocalVariable *Var, 358bdd1243dSDimitry Andric DIExpression *Expr, DebugLoc DbgLoc, unsigned Order, 359bdd1243dSDimitry Andric bool IsVariadic); 3600b57cec5SDimitry Andric 36106c3fb27SDimitry Andric /// Create a record for a kill location debug intrinsic. 36206c3fb27SDimitry Andric void handleKillDebugValue(DILocalVariable *Var, DIExpression *Expr, 36306c3fb27SDimitry Andric DebugLoc DbgLoc, unsigned Order); 36406c3fb27SDimitry Andric 3655f757f3fSDimitry Andric void handleDebugDeclare(Value *Address, DILocalVariable *Variable, 3665f757f3fSDimitry Andric DIExpression *Expression, DebugLoc DL); 3675f757f3fSDimitry Andric 3680b57cec5SDimitry Andric /// Evict any dangling debug information, attempting to salvage it first. 3690b57cec5SDimitry Andric void resolveOrClearDbgInfo(); 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric SDValue getValue(const Value *V); 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric SDValue getNonRegisterValue(const Value *V); 3740b57cec5SDimitry Andric SDValue getValueImpl(const Value *V); 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric void setValue(const Value *V, SDValue NewN) { 3770b57cec5SDimitry Andric SDValue &N = NodeMap[V]; 3780b57cec5SDimitry Andric assert(!N.getNode() && "Already set a value for this node!"); 3790b57cec5SDimitry Andric N = NewN; 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric void setUnusedArgValue(const Value *V, SDValue NewN) { 3830b57cec5SDimitry Andric SDValue &N = UnusedArgNodeMap[V]; 3840b57cec5SDimitry Andric assert(!N.getNode() && "Already set a value for this node!"); 3850b57cec5SDimitry Andric N = NewN; 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 388*0fca6ea1SDimitry Andric bool shouldKeepJumpConditionsTogether( 389*0fca6ea1SDimitry Andric const FunctionLoweringInfo &FuncInfo, const BranchInst &I, 390*0fca6ea1SDimitry Andric Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs, 391*0fca6ea1SDimitry Andric TargetLoweringBase::CondMergingParams Params) const; 392*0fca6ea1SDimitry Andric 3930b57cec5SDimitry Andric void FindMergedConditions(const Value *Cond, MachineBasicBlock *TBB, 3940b57cec5SDimitry Andric MachineBasicBlock *FBB, MachineBasicBlock *CurBB, 3950b57cec5SDimitry Andric MachineBasicBlock *SwitchBB, 3960b57cec5SDimitry Andric Instruction::BinaryOps Opc, BranchProbability TProb, 3970b57cec5SDimitry Andric BranchProbability FProb, bool InvertCond); 3980b57cec5SDimitry Andric void EmitBranchForMergedCondition(const Value *Cond, MachineBasicBlock *TBB, 3990b57cec5SDimitry Andric MachineBasicBlock *FBB, 4000b57cec5SDimitry Andric MachineBasicBlock *CurBB, 4010b57cec5SDimitry Andric MachineBasicBlock *SwitchBB, 4020b57cec5SDimitry Andric BranchProbability TProb, BranchProbability FProb, 4030b57cec5SDimitry Andric bool InvertCond); 4040b57cec5SDimitry Andric bool ShouldEmitAsBranches(const std::vector<SwitchCG::CaseBlock> &Cases); 4050b57cec5SDimitry Andric bool isExportableFromCurrentBlock(const Value *V, const BasicBlock *FromBB); 4060b57cec5SDimitry Andric void CopyToExportRegsIfNeeded(const Value *V); 4070b57cec5SDimitry Andric void ExportFromCurrentBlock(const Value *V); 4085ffd83dbSDimitry Andric void LowerCallTo(const CallBase &CB, SDValue Callee, bool IsTailCall, 409*0fca6ea1SDimitry Andric bool IsMustTailCall, const BasicBlock *EHPadBB = nullptr, 410*0fca6ea1SDimitry Andric const TargetLowering::PtrAuthInfo *PAI = nullptr); 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric // Lower range metadata from 0 to N to assert zext to an integer of nearest 4130b57cec5SDimitry Andric // floor power of two. 4140b57cec5SDimitry Andric SDValue lowerRangeToAssertZExt(SelectionDAG &DAG, const Instruction &I, 4150b57cec5SDimitry Andric SDValue Op); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric void populateCallLoweringInfo(TargetLowering::CallLoweringInfo &CLI, 4180b57cec5SDimitry Andric const CallBase *Call, unsigned ArgIdx, 4190b57cec5SDimitry Andric unsigned NumArgs, SDValue Callee, 4205f757f3fSDimitry Andric Type *ReturnTy, AttributeSet RetAttrs, 4215f757f3fSDimitry Andric bool IsPatchPoint); 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric std::pair<SDValue, SDValue> 4240b57cec5SDimitry Andric lowerInvokable(TargetLowering::CallLoweringInfo &CLI, 4250b57cec5SDimitry Andric const BasicBlock *EHPadBB = nullptr); 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric /// When an MBB was split during scheduling, update the 4280b57cec5SDimitry Andric /// references that need to refer to the last resulting block. 4290b57cec5SDimitry Andric void UpdateSplitBlock(MachineBasicBlock *First, MachineBasicBlock *Last); 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric /// Describes a gc.statepoint or a gc.statepoint like thing for the purposes 4320b57cec5SDimitry Andric /// of lowering into a STATEPOINT node. 4330b57cec5SDimitry Andric struct StatepointLoweringInfo { 4340b57cec5SDimitry Andric /// Bases[i] is the base pointer for Ptrs[i]. Together they denote the set 4350b57cec5SDimitry Andric /// of gc pointers this STATEPOINT has to relocate. 4360b57cec5SDimitry Andric SmallVector<const Value *, 16> Bases; 4370b57cec5SDimitry Andric SmallVector<const Value *, 16> Ptrs; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric /// The set of gc.relocate calls associated with this gc.statepoint. 4400b57cec5SDimitry Andric SmallVector<const GCRelocateInst *, 16> GCRelocates; 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric /// The full list of gc arguments to the gc.statepoint being lowered. 4430b57cec5SDimitry Andric ArrayRef<const Use> GCArgs; 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric /// The gc.statepoint instruction. 4460b57cec5SDimitry Andric const Instruction *StatepointInstr = nullptr; 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric /// The list of gc transition arguments present in the gc.statepoint being 4490b57cec5SDimitry Andric /// lowered. 4500b57cec5SDimitry Andric ArrayRef<const Use> GCTransitionArgs; 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric /// The ID that the resulting STATEPOINT instruction has to report. 453*0fca6ea1SDimitry Andric uint64_t ID = -1; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric /// Information regarding the underlying call instruction. 4560b57cec5SDimitry Andric TargetLowering::CallLoweringInfo CLI; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric /// The deoptimization state associated with this gc.statepoint call, if 4590b57cec5SDimitry Andric /// any. 4600b57cec5SDimitry Andric ArrayRef<const Use> DeoptState; 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric /// Flags associated with the meta arguments being lowered. 4630b57cec5SDimitry Andric uint64_t StatepointFlags = -1; 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric /// The number of patchable bytes the call needs to get lowered into. 4660b57cec5SDimitry Andric unsigned NumPatchBytes = -1; 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric /// The exception handling unwind destination, in case this represents an 4690b57cec5SDimitry Andric /// invoke of gc.statepoint. 4700b57cec5SDimitry Andric const BasicBlock *EHPadBB = nullptr; 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric explicit StatepointLoweringInfo(SelectionDAG &DAG) : CLI(DAG) {} 4730b57cec5SDimitry Andric }; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric /// Lower \p SLI into a STATEPOINT instruction. 4760b57cec5SDimitry Andric SDValue LowerAsSTATEPOINT(StatepointLoweringInfo &SI); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric // This function is responsible for the whole statepoint lowering process. 4790b57cec5SDimitry Andric // It uniformly handles invoke and call statepoints. 4805ffd83dbSDimitry Andric void LowerStatepoint(const GCStatepointInst &I, 4810b57cec5SDimitry Andric const BasicBlock *EHPadBB = nullptr); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric void LowerCallSiteWithDeoptBundle(const CallBase *Call, SDValue Callee, 4840b57cec5SDimitry Andric const BasicBlock *EHPadBB); 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric void LowerDeoptimizeCall(const CallInst *CI); 4870b57cec5SDimitry Andric void LowerDeoptimizingReturn(); 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric void LowerCallSiteWithDeoptBundleImpl(const CallBase *Call, SDValue Callee, 4900b57cec5SDimitry Andric const BasicBlock *EHPadBB, 4910b57cec5SDimitry Andric bool VarArgDisallowed, 4920b57cec5SDimitry Andric bool ForceVoidReturnTy); 4930b57cec5SDimitry Andric 494*0fca6ea1SDimitry Andric void LowerCallSiteWithPtrAuthBundle(const CallBase &CB, 495*0fca6ea1SDimitry Andric const BasicBlock *EHPadBB); 496*0fca6ea1SDimitry Andric 4970b57cec5SDimitry Andric /// Returns the type of FrameIndex and TargetFrameIndex nodes. 4980b57cec5SDimitry Andric MVT getFrameIndexTy() { 4990b57cec5SDimitry Andric return DAG.getTargetLoweringInfo().getFrameIndexTy(DAG.getDataLayout()); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric private: 5030b57cec5SDimitry Andric // Terminator instructions. 5040b57cec5SDimitry Andric void visitRet(const ReturnInst &I); 5050b57cec5SDimitry Andric void visitBr(const BranchInst &I); 5060b57cec5SDimitry Andric void visitSwitch(const SwitchInst &I); 5070b57cec5SDimitry Andric void visitIndirectBr(const IndirectBrInst &I); 5080b57cec5SDimitry Andric void visitUnreachable(const UnreachableInst &I); 5090b57cec5SDimitry Andric void visitCleanupRet(const CleanupReturnInst &I); 5100b57cec5SDimitry Andric void visitCatchSwitch(const CatchSwitchInst &I); 5110b57cec5SDimitry Andric void visitCatchRet(const CatchReturnInst &I); 5120b57cec5SDimitry Andric void visitCatchPad(const CatchPadInst &I); 5130b57cec5SDimitry Andric void visitCleanupPad(const CleanupPadInst &CPI); 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric BranchProbability getEdgeProbability(const MachineBasicBlock *Src, 5160b57cec5SDimitry Andric const MachineBasicBlock *Dst) const; 5170b57cec5SDimitry Andric void addSuccessorWithProb( 5180b57cec5SDimitry Andric MachineBasicBlock *Src, MachineBasicBlock *Dst, 5190b57cec5SDimitry Andric BranchProbability Prob = BranchProbability::getUnknown()); 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric public: 5220b57cec5SDimitry Andric void visitSwitchCase(SwitchCG::CaseBlock &CB, MachineBasicBlock *SwitchBB); 5230b57cec5SDimitry Andric void visitSPDescriptorParent(StackProtectorDescriptor &SPD, 5240b57cec5SDimitry Andric MachineBasicBlock *ParentBB); 5250b57cec5SDimitry Andric void visitSPDescriptorFailure(StackProtectorDescriptor &SPD); 5260b57cec5SDimitry Andric void visitBitTestHeader(SwitchCG::BitTestBlock &B, 5270b57cec5SDimitry Andric MachineBasicBlock *SwitchBB); 5280b57cec5SDimitry Andric void visitBitTestCase(SwitchCG::BitTestBlock &BB, MachineBasicBlock *NextMBB, 5290b57cec5SDimitry Andric BranchProbability BranchProbToNext, unsigned Reg, 5300b57cec5SDimitry Andric SwitchCG::BitTestCase &B, MachineBasicBlock *SwitchBB); 5310b57cec5SDimitry Andric void visitJumpTable(SwitchCG::JumpTable &JT); 5320b57cec5SDimitry Andric void visitJumpTableHeader(SwitchCG::JumpTable &JT, 5330b57cec5SDimitry Andric SwitchCG::JumpTableHeader &JTH, 5340b57cec5SDimitry Andric MachineBasicBlock *SwitchBB); 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric private: 5370b57cec5SDimitry Andric // These all get lowered before this pass. 5380b57cec5SDimitry Andric void visitInvoke(const InvokeInst &I); 5390b57cec5SDimitry Andric void visitCallBr(const CallBrInst &I); 54006c3fb27SDimitry Andric void visitCallBrLandingPad(const CallInst &I); 5410b57cec5SDimitry Andric void visitResume(const ResumeInst &I); 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric void visitUnary(const User &I, unsigned Opcode); 5440b57cec5SDimitry Andric void visitFNeg(const User &I) { visitUnary(I, ISD::FNEG); } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric void visitBinary(const User &I, unsigned Opcode); 5470b57cec5SDimitry Andric void visitShift(const User &I, unsigned Opcode); 5480b57cec5SDimitry Andric void visitAdd(const User &I) { visitBinary(I, ISD::ADD); } 5490b57cec5SDimitry Andric void visitFAdd(const User &I) { visitBinary(I, ISD::FADD); } 5500b57cec5SDimitry Andric void visitSub(const User &I) { visitBinary(I, ISD::SUB); } 551e8d8bef9SDimitry Andric void visitFSub(const User &I) { visitBinary(I, ISD::FSUB); } 5520b57cec5SDimitry Andric void visitMul(const User &I) { visitBinary(I, ISD::MUL); } 5530b57cec5SDimitry Andric void visitFMul(const User &I) { visitBinary(I, ISD::FMUL); } 5540b57cec5SDimitry Andric void visitURem(const User &I) { visitBinary(I, ISD::UREM); } 5550b57cec5SDimitry Andric void visitSRem(const User &I) { visitBinary(I, ISD::SREM); } 5560b57cec5SDimitry Andric void visitFRem(const User &I) { visitBinary(I, ISD::FREM); } 5570b57cec5SDimitry Andric void visitUDiv(const User &I) { visitBinary(I, ISD::UDIV); } 5580b57cec5SDimitry Andric void visitSDiv(const User &I); 5590b57cec5SDimitry Andric void visitFDiv(const User &I) { visitBinary(I, ISD::FDIV); } 5600b57cec5SDimitry Andric void visitAnd (const User &I) { visitBinary(I, ISD::AND); } 5610b57cec5SDimitry Andric void visitOr (const User &I) { visitBinary(I, ISD::OR); } 5620b57cec5SDimitry Andric void visitXor (const User &I) { visitBinary(I, ISD::XOR); } 5630b57cec5SDimitry Andric void visitShl (const User &I) { visitShift(I, ISD::SHL); } 5640b57cec5SDimitry Andric void visitLShr(const User &I) { visitShift(I, ISD::SRL); } 5650b57cec5SDimitry Andric void visitAShr(const User &I) { visitShift(I, ISD::SRA); } 566*0fca6ea1SDimitry Andric void visitICmp(const ICmpInst &I); 567*0fca6ea1SDimitry Andric void visitFCmp(const FCmpInst &I); 5680b57cec5SDimitry Andric // Visit the conversion instructions 5690b57cec5SDimitry Andric void visitTrunc(const User &I); 5700b57cec5SDimitry Andric void visitZExt(const User &I); 5710b57cec5SDimitry Andric void visitSExt(const User &I); 5720b57cec5SDimitry Andric void visitFPTrunc(const User &I); 5730b57cec5SDimitry Andric void visitFPExt(const User &I); 5740b57cec5SDimitry Andric void visitFPToUI(const User &I); 5750b57cec5SDimitry Andric void visitFPToSI(const User &I); 5760b57cec5SDimitry Andric void visitUIToFP(const User &I); 5770b57cec5SDimitry Andric void visitSIToFP(const User &I); 5780b57cec5SDimitry Andric void visitPtrToInt(const User &I); 5790b57cec5SDimitry Andric void visitIntToPtr(const User &I); 5800b57cec5SDimitry Andric void visitBitCast(const User &I); 5810b57cec5SDimitry Andric void visitAddrSpaceCast(const User &I); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric void visitExtractElement(const User &I); 5840b57cec5SDimitry Andric void visitInsertElement(const User &I); 5850b57cec5SDimitry Andric void visitShuffleVector(const User &I); 5860b57cec5SDimitry Andric 58781ad6265SDimitry Andric void visitExtractValue(const ExtractValueInst &I); 588753f127fSDimitry Andric void visitInsertValue(const InsertValueInst &I); 5890b57cec5SDimitry Andric void visitLandingPad(const LandingPadInst &LP); 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric void visitGetElementPtr(const User &I); 5920b57cec5SDimitry Andric void visitSelect(const User &I); 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric void visitAlloca(const AllocaInst &I); 5950b57cec5SDimitry Andric void visitLoad(const LoadInst &I); 5960b57cec5SDimitry Andric void visitStore(const StoreInst &I); 5970b57cec5SDimitry Andric void visitMaskedLoad(const CallInst &I, bool IsExpanding = false); 5980b57cec5SDimitry Andric void visitMaskedStore(const CallInst &I, bool IsCompressing = false); 5990b57cec5SDimitry Andric void visitMaskedGather(const CallInst &I); 6000b57cec5SDimitry Andric void visitMaskedScatter(const CallInst &I); 6010b57cec5SDimitry Andric void visitAtomicCmpXchg(const AtomicCmpXchgInst &I); 6020b57cec5SDimitry Andric void visitAtomicRMW(const AtomicRMWInst &I); 6030b57cec5SDimitry Andric void visitFence(const FenceInst &I); 6040b57cec5SDimitry Andric void visitPHI(const PHINode &I); 6050b57cec5SDimitry Andric void visitCall(const CallInst &I); 606e8d8bef9SDimitry Andric bool visitMemCmpBCmpCall(const CallInst &I); 6070b57cec5SDimitry Andric bool visitMemPCpyCall(const CallInst &I); 6080b57cec5SDimitry Andric bool visitMemChrCall(const CallInst &I); 6090b57cec5SDimitry Andric bool visitStrCpyCall(const CallInst &I, bool isStpcpy); 6100b57cec5SDimitry Andric bool visitStrCmpCall(const CallInst &I); 6110b57cec5SDimitry Andric bool visitStrLenCall(const CallInst &I); 6120b57cec5SDimitry Andric bool visitStrNLenCall(const CallInst &I); 6130b57cec5SDimitry Andric bool visitUnaryFloatCall(const CallInst &I, unsigned Opcode); 6140b57cec5SDimitry Andric bool visitBinaryFloatCall(const CallInst &I, unsigned Opcode); 6150b57cec5SDimitry Andric void visitAtomicLoad(const LoadInst &I); 6160b57cec5SDimitry Andric void visitAtomicStore(const StoreInst &I); 6170b57cec5SDimitry Andric void visitLoadFromSwiftError(const LoadInst &I); 6180b57cec5SDimitry Andric void visitStoreToSwiftError(const StoreInst &I); 619480093f4SDimitry Andric void visitFreeze(const FreezeInst &I); 6200b57cec5SDimitry Andric 621fe6060f1SDimitry Andric void visitInlineAsm(const CallBase &Call, 622fe6060f1SDimitry Andric const BasicBlock *EHPadBB = nullptr); 6235f757f3fSDimitry Andric 6247a6dacacSDimitry Andric bool visitEntryValueDbgValue(ArrayRef<const Value *> Values, 6257a6dacacSDimitry Andric DILocalVariable *Variable, DIExpression *Expr, 6267a6dacacSDimitry Andric DebugLoc DbgLoc); 6270b57cec5SDimitry Andric void visitIntrinsicCall(const CallInst &I, unsigned Intrinsic); 6280b57cec5SDimitry Andric void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic); 6290b57cec5SDimitry Andric void visitConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI); 630*0fca6ea1SDimitry Andric void visitConvergenceControl(const CallInst &I, unsigned Intrinsic); 631*0fca6ea1SDimitry Andric void visitVectorHistogram(const CallInst &I, unsigned IntrinsicID); 632bdd1243dSDimitry Andric void visitVPLoad(const VPIntrinsic &VPIntrin, EVT VT, 63306c3fb27SDimitry Andric const SmallVectorImpl<SDValue> &OpValues); 634bdd1243dSDimitry Andric void visitVPStore(const VPIntrinsic &VPIntrin, 63506c3fb27SDimitry Andric const SmallVectorImpl<SDValue> &OpValues); 636bdd1243dSDimitry Andric void visitVPGather(const VPIntrinsic &VPIntrin, EVT VT, 63706c3fb27SDimitry Andric const SmallVectorImpl<SDValue> &OpValues); 638bdd1243dSDimitry Andric void visitVPScatter(const VPIntrinsic &VPIntrin, 63906c3fb27SDimitry Andric const SmallVectorImpl<SDValue> &OpValues); 64081ad6265SDimitry Andric void visitVPStridedLoad(const VPIntrinsic &VPIntrin, EVT VT, 64106c3fb27SDimitry Andric const SmallVectorImpl<SDValue> &OpValues); 64281ad6265SDimitry Andric void visitVPStridedStore(const VPIntrinsic &VPIntrin, 64306c3fb27SDimitry Andric const SmallVectorImpl<SDValue> &OpValues); 64481ad6265SDimitry Andric void visitVPCmp(const VPCmpIntrinsic &VPIntrin); 645e8d8bef9SDimitry Andric void visitVectorPredicationIntrinsic(const VPIntrinsic &VPIntrin); 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric void visitVAStart(const CallInst &I); 6480b57cec5SDimitry Andric void visitVAArg(const VAArgInst &I); 6490b57cec5SDimitry Andric void visitVAEnd(const CallInst &I); 6500b57cec5SDimitry Andric void visitVACopy(const CallInst &I); 6510b57cec5SDimitry Andric void visitStackmap(const CallInst &I); 6525ffd83dbSDimitry Andric void visitPatchpoint(const CallBase &CB, const BasicBlock *EHPadBB = nullptr); 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric // These two are implemented in StatepointLowering.cpp 6550b57cec5SDimitry Andric void visitGCRelocate(const GCRelocateInst &Relocate); 6560b57cec5SDimitry Andric void visitGCResult(const GCResultInst &I); 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric void visitVectorReduce(const CallInst &I, unsigned Intrinsic); 659fe6060f1SDimitry Andric void visitVectorReverse(const CallInst &I); 660fe6060f1SDimitry Andric void visitVectorSplice(const CallInst &I); 66106c3fb27SDimitry Andric void visitVectorInterleave(const CallInst &I); 66206c3fb27SDimitry Andric void visitVectorDeinterleave(const CallInst &I); 663fe6060f1SDimitry Andric void visitStepVector(const CallInst &I); 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric void visitUserOp1(const Instruction &I) { 6660b57cec5SDimitry Andric llvm_unreachable("UserOp1 should not exist at instruction selection time!"); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric void visitUserOp2(const Instruction &I) { 6690b57cec5SDimitry Andric llvm_unreachable("UserOp2 should not exist at instruction selection time!"); 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric void processIntegerCallValue(const Instruction &I, 6730b57cec5SDimitry Andric SDValue Value, bool IsSigned); 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); 6760b57cec5SDimitry Andric 6775ffd83dbSDimitry Andric void emitInlineAsmError(const CallBase &Call, const Twine &Message); 6780b57cec5SDimitry Andric 67981ad6265SDimitry Andric /// An enum that states to emit func argument dbg value the kind of intrinsic 68081ad6265SDimitry Andric /// it originally had. This controls the internal behavior of 68181ad6265SDimitry Andric /// EmitFuncArgumentDbgValue. 68281ad6265SDimitry Andric enum class FuncArgumentDbgValueKind { 68381ad6265SDimitry Andric Value, // This was originally a llvm.dbg.value. 68481ad6265SDimitry Andric Declare, // This was originally a llvm.dbg.declare. 68581ad6265SDimitry Andric }; 68681ad6265SDimitry Andric 6870b57cec5SDimitry Andric /// If V is an function argument then create corresponding DBG_VALUE machine 6880b57cec5SDimitry Andric /// instruction for it now. At the end of instruction selection, they will be 6890b57cec5SDimitry Andric /// inserted to the entry BB. 6900b57cec5SDimitry Andric bool EmitFuncArgumentDbgValue(const Value *V, DILocalVariable *Variable, 6910b57cec5SDimitry Andric DIExpression *Expr, DILocation *DL, 69281ad6265SDimitry Andric FuncArgumentDbgValueKind Kind, 69381ad6265SDimitry Andric const SDValue &N); 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric /// Return the next block after MBB, or nullptr if there is none. 6960b57cec5SDimitry Andric MachineBasicBlock *NextBlock(MachineBasicBlock *MBB); 6970b57cec5SDimitry Andric 6980b57cec5SDimitry Andric /// Update the DAG and DAG builder with the relevant information after 6990b57cec5SDimitry Andric /// a new root node has been created which could be a tail call. 7000b57cec5SDimitry Andric void updateDAGForMaybeTailCall(SDValue MaybeTC); 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric /// Return the appropriate SDDbgValue based on N. 7030b57cec5SDimitry Andric SDDbgValue *getDbgValue(SDValue N, DILocalVariable *Variable, 7040b57cec5SDimitry Andric DIExpression *Expr, const DebugLoc &dl, 7050b57cec5SDimitry Andric unsigned DbgSDNodeOrder); 7060b57cec5SDimitry Andric 7070b57cec5SDimitry Andric /// Lowers CallInst to an external symbol. 7080b57cec5SDimitry Andric void lowerCallToExternalSymbol(const CallInst &I, const char *FunctionName); 709fe6060f1SDimitry Andric 710fe6060f1SDimitry Andric SDValue lowerStartEH(SDValue Chain, const BasicBlock *EHPadBB, 711fe6060f1SDimitry Andric MCSymbol *&BeginLabel); 712fe6060f1SDimitry Andric SDValue lowerEndEH(SDValue Chain, const InvokeInst *II, 713fe6060f1SDimitry Andric const BasicBlock *EHPadBB, MCSymbol *BeginLabel); 7140b57cec5SDimitry Andric }; 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric /// This struct represents the registers (physical or virtual) 7170b57cec5SDimitry Andric /// that a particular set of values is assigned, and the type information about 7180b57cec5SDimitry Andric /// the value. The most common situation is to represent one value at a time, 7190b57cec5SDimitry Andric /// but struct or array values are handled element-wise as multiple values. The 7200b57cec5SDimitry Andric /// splitting of aggregates is performed recursively, so that we never have 7210b57cec5SDimitry Andric /// aggregate-typed registers. The values at this point do not necessarily have 7220b57cec5SDimitry Andric /// legal types, so each value may require one or more registers of some legal 7230b57cec5SDimitry Andric /// type. 7240b57cec5SDimitry Andric /// 7250b57cec5SDimitry Andric struct RegsForValue { 7260b57cec5SDimitry Andric /// The value types of the values, which may not be legal, and 7270b57cec5SDimitry Andric /// may need be promoted or synthesized from one or more registers. 7280b57cec5SDimitry Andric SmallVector<EVT, 4> ValueVTs; 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric /// The value types of the registers. This is the same size as ValueVTs and it 7310b57cec5SDimitry Andric /// records, for each value, what the type of the assigned register or 7320b57cec5SDimitry Andric /// registers are. (Individual values are never synthesized from more than one 7330b57cec5SDimitry Andric /// type of register.) 7340b57cec5SDimitry Andric /// 7350b57cec5SDimitry Andric /// With virtual registers, the contents of RegVTs is redundant with TLI's 7360b57cec5SDimitry Andric /// getRegisterType member function, however when with physical registers 7370b57cec5SDimitry Andric /// it is necessary to have a separate record of the types. 7380b57cec5SDimitry Andric SmallVector<MVT, 4> RegVTs; 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric /// This list holds the registers assigned to the values. 7410b57cec5SDimitry Andric /// Each legal or promoted value requires one register, and each 7420b57cec5SDimitry Andric /// expanded value requires multiple registers. 7430b57cec5SDimitry Andric SmallVector<unsigned, 4> Regs; 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric /// This list holds the number of registers for each value. 7460b57cec5SDimitry Andric SmallVector<unsigned, 4> RegCount; 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric /// Records if this value needs to be treated in an ABI dependant manner, 7490b57cec5SDimitry Andric /// different to normal type legalization. 750bdd1243dSDimitry Andric std::optional<CallingConv::ID> CallConv; 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric RegsForValue() = default; 7530b57cec5SDimitry Andric RegsForValue(const SmallVector<unsigned, 4> ®s, MVT regvt, EVT valuevt, 754bdd1243dSDimitry Andric std::optional<CallingConv::ID> CC = std::nullopt); 7550b57cec5SDimitry Andric RegsForValue(LLVMContext &Context, const TargetLowering &TLI, 7560b57cec5SDimitry Andric const DataLayout &DL, unsigned Reg, Type *Ty, 757bdd1243dSDimitry Andric std::optional<CallingConv::ID> CC); 7580b57cec5SDimitry Andric 75981ad6265SDimitry Andric bool isABIMangled() const { return CallConv.has_value(); } 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric /// Add the specified values to this one. 7620b57cec5SDimitry Andric void append(const RegsForValue &RHS) { 7630b57cec5SDimitry Andric ValueVTs.append(RHS.ValueVTs.begin(), RHS.ValueVTs.end()); 7640b57cec5SDimitry Andric RegVTs.append(RHS.RegVTs.begin(), RHS.RegVTs.end()); 7650b57cec5SDimitry Andric Regs.append(RHS.Regs.begin(), RHS.Regs.end()); 7660b57cec5SDimitry Andric RegCount.push_back(RHS.Regs.size()); 7670b57cec5SDimitry Andric } 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric /// Emit a series of CopyFromReg nodes that copies from this value and returns 7700b57cec5SDimitry Andric /// the result as a ValueVTs value. This uses Chain/Flag as the input and 7710b57cec5SDimitry Andric /// updates them for the output Chain/Flag. If the Flag pointer is NULL, no 7720b57cec5SDimitry Andric /// flag is used. 7730b57cec5SDimitry Andric SDValue getCopyFromRegs(SelectionDAG &DAG, FunctionLoweringInfo &FuncInfo, 77406c3fb27SDimitry Andric const SDLoc &dl, SDValue &Chain, SDValue *Glue, 7750b57cec5SDimitry Andric const Value *V = nullptr) const; 7760b57cec5SDimitry Andric 7770b57cec5SDimitry Andric /// Emit a series of CopyToReg nodes that copies the specified value into the 7780b57cec5SDimitry Andric /// registers specified by this object. This uses Chain/Flag as the input and 7790b57cec5SDimitry Andric /// updates them for the output Chain/Flag. If the Flag pointer is nullptr, no 7800b57cec5SDimitry Andric /// flag is used. If V is not nullptr, then it is used in printing better 7810b57cec5SDimitry Andric /// diagnostic messages on error. 7820b57cec5SDimitry Andric void getCopyToRegs(SDValue Val, SelectionDAG &DAG, const SDLoc &dl, 78306c3fb27SDimitry Andric SDValue &Chain, SDValue *Glue, const Value *V = nullptr, 7840b57cec5SDimitry Andric ISD::NodeType PreferredExtendType = ISD::ANY_EXTEND) const; 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric /// Add this value to the specified inlineasm node operand list. This adds the 7870b57cec5SDimitry Andric /// code marker, matching input operand index (if applicable), and includes 7880b57cec5SDimitry Andric /// the number of values added into it. 7895f757f3fSDimitry Andric void AddInlineAsmOperands(InlineAsm::Kind Code, bool HasMatching, 7900b57cec5SDimitry Andric unsigned MatchingIdx, const SDLoc &dl, 7910b57cec5SDimitry Andric SelectionDAG &DAG, std::vector<SDValue> &Ops) const; 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric /// Check if the total RegCount is greater than one. 7940b57cec5SDimitry Andric bool occupiesMultipleRegs() const { 7950b57cec5SDimitry Andric return std::accumulate(RegCount.begin(), RegCount.end(), 0) > 1; 7960b57cec5SDimitry Andric } 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric /// Return a list of registers and their sizes. 799e8d8bef9SDimitry Andric SmallVector<std::pair<unsigned, TypeSize>, 4> getRegsAndSizes() const; 8000b57cec5SDimitry Andric }; 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric } // end namespace llvm 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_SELECTIONDAG_SELECTIONDAGBUILDER_H 805