//===- InstrEmitter.h - Emit MachineInstrs for the SelectionDAG -*- C++ -*--==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This declares the Emit routines for the SelectionDAG class, which creates // MachineInstrs based on the decisions of the SelectionDAG instruction // selection. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_INSTREMITTER_H #define LLVM_LIB_CODEGEN_SELECTIONDAG_INSTREMITTER_H #include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/SelectionDAGNodes.h" namespace llvm { class MachineInstrBuilder; class MCInstrDesc; class SDDbgLabel; class SDDbgValue; class SDDbgOperand; class TargetLowering; class TargetMachine; class LLVM_LIBRARY_VISIBILITY InstrEmitter { MachineFunction *MF; MachineRegisterInfo *MRI; const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; const TargetLowering *TLI; MachineBasicBlock *MBB; MachineBasicBlock::iterator InsertPos; /// Should we try to produce DBG_INSTR_REF instructions? bool EmitDebugInstrRefs; /// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an /// implicit physical register output. void EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned, Register SrcReg, DenseMap &VRBaseMap); void CreateVirtualRegisters(SDNode *Node, MachineInstrBuilder &MIB, const MCInstrDesc &II, bool IsClone, bool IsCloned, DenseMap &VRBaseMap); /// getVR - Return the virtual register corresponding to the specified result /// of the specified node. Register getVR(SDValue Op, DenseMap &VRBaseMap); /// AddRegisterOperand - Add the specified register as an operand to the /// specified machine instr. Insert register copies if the register is /// not in the required register class. void AddRegisterOperand(MachineInstrBuilder &MIB, SDValue Op, unsigned IIOpNum, const MCInstrDesc *II, DenseMap &VRBaseMap, bool IsDebug, bool IsClone, bool IsCloned); /// AddOperand - Add the specified operand to the specified machine instr. II /// specifies the instruction information for the node, and IIOpNum is the /// operand number (in the II) that we are adding. IIOpNum and II are used for /// assertions only. void AddOperand(MachineInstrBuilder &MIB, SDValue Op, unsigned IIOpNum, const MCInstrDesc *II, DenseMap &VRBaseMap, bool IsDebug, bool IsClone, bool IsCloned); /// ConstrainForSubReg - Try to constrain VReg to a register class that /// supports SubIdx sub-registers. Emit a copy if that isn't possible. /// Return the virtual register to use. Register ConstrainForSubReg(Register VReg, unsigned SubIdx, MVT VT, bool isDivergent, const DebugLoc &DL); /// EmitSubregNode - Generate machine code for subreg nodes. /// void EmitSubregNode(SDNode *Node, DenseMap &VRBaseMap, bool IsClone, bool IsCloned); /// EmitCopyToRegClassNode - Generate machine code for COPY_TO_REGCLASS nodes. /// COPY_TO_REGCLASS is just a normal copy, except that the destination /// register is constrained to be in a particular register class. /// void EmitCopyToRegClassNode(SDNode *Node, DenseMap &VRBaseMap); /// EmitRegSequence - Generate machine code for REG_SEQUENCE nodes. /// void EmitRegSequence(SDNode *Node, DenseMap &VRBaseMap, bool IsClone, bool IsCloned); public: /// CountResults - The results of target nodes have register or immediate /// operands first, then an optional chain, and optional flag operands /// (which do not go into the machine instrs.) static unsigned CountResults(SDNode *Node); void AddDbgValueLocationOps(MachineInstrBuilder &MIB, const MCInstrDesc &DbgValDesc, ArrayRef Locations, DenseMap &VRBaseMap); /// EmitDbgValue - Generate machine instruction for a dbg_value node. /// MachineInstr *EmitDbgValue(SDDbgValue *SD, DenseMap &VRBaseMap); /// Emit a dbg_value as a DBG_INSTR_REF. May produce DBG_VALUE $noreg instead /// if there is no variable location; alternately a half-formed DBG_INSTR_REF /// that refers to a virtual register and is corrected later in isel. MachineInstr *EmitDbgInstrRef(SDDbgValue *SD, DenseMap &VRBaseMap); /// Emit a DBG_VALUE $noreg, indicating a variable has no location. MachineInstr *EmitDbgNoLocation(SDDbgValue *SD); /// Emit a DBG_VALUE from the operands to SDDbgValue. MachineInstr *EmitDbgValueFromSingleOp(SDDbgValue *SD, DenseMap &VRBaseMap); /// Generate machine instruction for a dbg_label node. MachineInstr *EmitDbgLabel(SDDbgLabel *SD); /// EmitNode - Generate machine code for a node and needed dependencies. /// void EmitNode(SDNode *Node, bool IsClone, bool IsCloned, DenseMap &VRBaseMap) { if (Node->isMachineOpcode()) EmitMachineNode(Node, IsClone, IsCloned, VRBaseMap); else EmitSpecialNode(Node, IsClone, IsCloned, VRBaseMap); } /// getBlock - Return the current basic block. MachineBasicBlock *getBlock() { return MBB; } /// getInsertPos - Return the current insertion position. MachineBasicBlock::iterator getInsertPos() { return InsertPos; } /// InstrEmitter - Construct an InstrEmitter and set it to start inserting /// at the given position in the given block. InstrEmitter(const TargetMachine &TM, MachineBasicBlock *mbb, MachineBasicBlock::iterator insertpos, bool UseInstrRefDebugInfo); private: void EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, DenseMap &VRBaseMap); void EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, DenseMap &VRBaseMap); }; } // namespace llvm #endif