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