xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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> &regs, 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