xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===- InstrEmitter.h - Emit MachineInstrs for the SelectionDAG -*- 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 declares the Emit routines for the SelectionDAG class, which creates
100b57cec5SDimitry Andric // MachineInstrs based on the decisions of the SelectionDAG instruction
110b57cec5SDimitry Andric // selection.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_INSTREMITTER_H
160b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_SELECTIONDAG_INSTREMITTER_H
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
205ffd83dbSDimitry Andric #include "llvm/CodeGen/SelectionDAGNodes.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric class MachineInstrBuilder;
250b57cec5SDimitry Andric class MCInstrDesc;
265ffd83dbSDimitry Andric class SDDbgLabel;
270b57cec5SDimitry Andric class SDDbgValue;
28fe6060f1SDimitry Andric class SDDbgOperand;
295ffd83dbSDimitry Andric class TargetLowering;
30e8d8bef9SDimitry Andric class TargetMachine;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY InstrEmitter {
330b57cec5SDimitry Andric   MachineFunction *MF;
340b57cec5SDimitry Andric   MachineRegisterInfo *MRI;
350b57cec5SDimitry Andric   const TargetInstrInfo *TII;
360b57cec5SDimitry Andric   const TargetRegisterInfo *TRI;
370b57cec5SDimitry Andric   const TargetLowering *TLI;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   MachineBasicBlock *MBB;
400b57cec5SDimitry Andric   MachineBasicBlock::iterator InsertPos;
410b57cec5SDimitry Andric 
42e8d8bef9SDimitry Andric   /// Should we try to produce DBG_INSTR_REF instructions?
43e8d8bef9SDimitry Andric   bool EmitDebugInstrRefs;
44e8d8bef9SDimitry Andric 
450b57cec5SDimitry Andric   /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
460b57cec5SDimitry Andric   /// implicit physical register output.
47*bdd1243dSDimitry Andric   void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
48*bdd1243dSDimitry Andric                        Register SrcReg, DenseMap<SDValue, Register> &VRBaseMap);
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   void CreateVirtualRegisters(SDNode *Node,
510b57cec5SDimitry Andric                               MachineInstrBuilder &MIB,
520b57cec5SDimitry Andric                               const MCInstrDesc &II,
530b57cec5SDimitry Andric                               bool IsClone, bool IsCloned,
545ffd83dbSDimitry Andric                               DenseMap<SDValue, Register> &VRBaseMap);
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   /// getVR - Return the virtual register corresponding to the specified result
570b57cec5SDimitry Andric   /// of the specified node.
585ffd83dbSDimitry Andric   Register getVR(SDValue Op,
595ffd83dbSDimitry Andric                  DenseMap<SDValue, Register> &VRBaseMap);
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   /// AddRegisterOperand - Add the specified register as an operand to the
620b57cec5SDimitry Andric   /// specified machine instr. Insert register copies if the register is
630b57cec5SDimitry Andric   /// not in the required register class.
640b57cec5SDimitry Andric   void AddRegisterOperand(MachineInstrBuilder &MIB,
650b57cec5SDimitry Andric                           SDValue Op,
660b57cec5SDimitry Andric                           unsigned IIOpNum,
670b57cec5SDimitry Andric                           const MCInstrDesc *II,
685ffd83dbSDimitry Andric                           DenseMap<SDValue, Register> &VRBaseMap,
690b57cec5SDimitry Andric                           bool IsDebug, bool IsClone, bool IsCloned);
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   /// AddOperand - Add the specified operand to the specified machine instr.  II
720b57cec5SDimitry Andric   /// specifies the instruction information for the node, and IIOpNum is the
730b57cec5SDimitry Andric   /// operand number (in the II) that we are adding. IIOpNum and II are used for
740b57cec5SDimitry Andric   /// assertions only.
750b57cec5SDimitry Andric   void AddOperand(MachineInstrBuilder &MIB,
760b57cec5SDimitry Andric                   SDValue Op,
770b57cec5SDimitry Andric                   unsigned IIOpNum,
780b57cec5SDimitry Andric                   const MCInstrDesc *II,
795ffd83dbSDimitry Andric                   DenseMap<SDValue, Register> &VRBaseMap,
800b57cec5SDimitry Andric                   bool IsDebug, bool IsClone, bool IsCloned);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   /// ConstrainForSubReg - Try to constrain VReg to a register class that
830b57cec5SDimitry Andric   /// supports SubIdx sub-registers.  Emit a copy if that isn't possible.
840b57cec5SDimitry Andric   /// Return the virtual register to use.
855ffd83dbSDimitry Andric   Register ConstrainForSubReg(Register VReg, unsigned SubIdx, MVT VT,
860b57cec5SDimitry Andric                               bool isDivergent, const DebugLoc &DL);
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   /// EmitSubregNode - Generate machine code for subreg nodes.
890b57cec5SDimitry Andric   ///
905ffd83dbSDimitry Andric   void EmitSubregNode(SDNode *Node, DenseMap<SDValue, Register> &VRBaseMap,
910b57cec5SDimitry Andric                       bool IsClone, bool IsCloned);
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   /// EmitCopyToRegClassNode - Generate machine code for COPY_TO_REGCLASS nodes.
940b57cec5SDimitry Andric   /// COPY_TO_REGCLASS is just a normal copy, except that the destination
950b57cec5SDimitry Andric   /// register is constrained to be in a particular register class.
960b57cec5SDimitry Andric   ///
970b57cec5SDimitry Andric   void EmitCopyToRegClassNode(SDNode *Node,
985ffd83dbSDimitry Andric                               DenseMap<SDValue, Register> &VRBaseMap);
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   /// EmitRegSequence - Generate machine code for REG_SEQUENCE nodes.
1010b57cec5SDimitry Andric   ///
1025ffd83dbSDimitry Andric   void EmitRegSequence(SDNode *Node, DenseMap<SDValue, Register> &VRBaseMap,
1030b57cec5SDimitry Andric                        bool IsClone, bool IsCloned);
1040b57cec5SDimitry Andric public:
1050b57cec5SDimitry Andric   /// CountResults - The results of target nodes have register or immediate
1060b57cec5SDimitry Andric   /// operands first, then an optional chain, and optional flag operands
1070b57cec5SDimitry Andric   /// (which do not go into the machine instrs.)
1080b57cec5SDimitry Andric   static unsigned CountResults(SDNode *Node);
1090b57cec5SDimitry Andric 
110fe6060f1SDimitry Andric   void AddDbgValueLocationOps(MachineInstrBuilder &MIB,
111fe6060f1SDimitry Andric                               const MCInstrDesc &DbgValDesc,
112fe6060f1SDimitry Andric                               ArrayRef<SDDbgOperand> Locations,
113fe6060f1SDimitry Andric                               DenseMap<SDValue, Register> &VRBaseMap);
114fe6060f1SDimitry Andric 
1150b57cec5SDimitry Andric   /// EmitDbgValue - Generate machine instruction for a dbg_value node.
1160b57cec5SDimitry Andric   ///
1170b57cec5SDimitry Andric   MachineInstr *EmitDbgValue(SDDbgValue *SD,
1185ffd83dbSDimitry Andric                              DenseMap<SDValue, Register> &VRBaseMap);
1190b57cec5SDimitry Andric 
120fe6060f1SDimitry Andric   /// Emit a dbg_value as a DBG_INSTR_REF. May produce DBG_VALUE $noreg instead
121fe6060f1SDimitry Andric   /// if there is no variable location; alternately a half-formed DBG_INSTR_REF
122fe6060f1SDimitry Andric   /// that refers to a virtual register and is corrected later in isel.
123e8d8bef9SDimitry Andric   MachineInstr *EmitDbgInstrRef(SDDbgValue *SD,
124e8d8bef9SDimitry Andric                                 DenseMap<SDValue, Register> &VRBaseMap);
125e8d8bef9SDimitry Andric 
126fe6060f1SDimitry Andric   /// Emit a DBG_VALUE $noreg, indicating a variable has no location.
127fe6060f1SDimitry Andric   MachineInstr *EmitDbgNoLocation(SDDbgValue *SD);
128fe6060f1SDimitry Andric 
129*bdd1243dSDimitry Andric   /// Emit a DBG_VALUE_LIST from the operands to SDDbgValue.
130*bdd1243dSDimitry Andric   MachineInstr *EmitDbgValueList(SDDbgValue *SD,
131*bdd1243dSDimitry Andric                                  DenseMap<SDValue, Register> &VRBaseMap);
132*bdd1243dSDimitry Andric 
133fe6060f1SDimitry Andric   /// Emit a DBG_VALUE from the operands to SDDbgValue.
134fe6060f1SDimitry Andric   MachineInstr *EmitDbgValueFromSingleOp(SDDbgValue *SD,
135fe6060f1SDimitry Andric                                     DenseMap<SDValue, Register> &VRBaseMap);
136fe6060f1SDimitry Andric 
1370b57cec5SDimitry Andric   /// Generate machine instruction for a dbg_label node.
1380b57cec5SDimitry Andric   MachineInstr *EmitDbgLabel(SDDbgLabel *SD);
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   /// EmitNode - Generate machine code for a node and needed dependencies.
1410b57cec5SDimitry Andric   ///
EmitNode(SDNode * Node,bool IsClone,bool IsCloned,DenseMap<SDValue,Register> & VRBaseMap)1420b57cec5SDimitry Andric   void EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
1435ffd83dbSDimitry Andric                 DenseMap<SDValue, Register> &VRBaseMap) {
1440b57cec5SDimitry Andric     if (Node->isMachineOpcode())
1450b57cec5SDimitry Andric       EmitMachineNode(Node, IsClone, IsCloned, VRBaseMap);
1460b57cec5SDimitry Andric     else
1470b57cec5SDimitry Andric       EmitSpecialNode(Node, IsClone, IsCloned, VRBaseMap);
1480b57cec5SDimitry Andric   }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric   /// getBlock - Return the current basic block.
getBlock()1510b57cec5SDimitry Andric   MachineBasicBlock *getBlock() { return MBB; }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   /// getInsertPos - Return the current insertion position.
getInsertPos()1540b57cec5SDimitry Andric   MachineBasicBlock::iterator getInsertPos() { return InsertPos; }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   /// InstrEmitter - Construct an InstrEmitter and set it to start inserting
1570b57cec5SDimitry Andric   /// at the given position in the given block.
158e8d8bef9SDimitry Andric   InstrEmitter(const TargetMachine &TM, MachineBasicBlock *mbb,
159*bdd1243dSDimitry Andric                MachineBasicBlock::iterator insertpos);
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric private:
1620b57cec5SDimitry Andric   void EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
1635ffd83dbSDimitry Andric                        DenseMap<SDValue, Register> &VRBaseMap);
1640b57cec5SDimitry Andric   void EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
1655ffd83dbSDimitry Andric                        DenseMap<SDValue, Register> &VRBaseMap);
1660b57cec5SDimitry Andric };
167fe6060f1SDimitry Andric } // namespace llvm
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric #endif
170