forked from OSchip/llvm-project
169 lines
6.8 KiB
C++
169 lines
6.8 KiB
C++
//===- 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<SDValue, Register> &VRBaseMap);
|
|
|
|
void CreateVirtualRegisters(SDNode *Node,
|
|
MachineInstrBuilder &MIB,
|
|
const MCInstrDesc &II,
|
|
bool IsClone, bool IsCloned,
|
|
DenseMap<SDValue, Register> &VRBaseMap);
|
|
|
|
/// getVR - Return the virtual register corresponding to the specified result
|
|
/// of the specified node.
|
|
Register getVR(SDValue Op,
|
|
DenseMap<SDValue, Register> &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<SDValue, Register> &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<SDValue, Register> &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<SDValue, Register> &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<SDValue, Register> &VRBaseMap);
|
|
|
|
/// EmitRegSequence - Generate machine code for REG_SEQUENCE nodes.
|
|
///
|
|
void EmitRegSequence(SDNode *Node, DenseMap<SDValue, Register> &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<SDDbgOperand> Locations,
|
|
DenseMap<SDValue, Register> &VRBaseMap);
|
|
|
|
/// EmitDbgValue - Generate machine instruction for a dbg_value node.
|
|
///
|
|
MachineInstr *EmitDbgValue(SDDbgValue *SD,
|
|
DenseMap<SDValue, Register> &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<SDValue, Register> &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<SDValue, Register> &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<SDValue, Register> &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<SDValue, Register> &VRBaseMap);
|
|
void EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
|
|
DenseMap<SDValue, Register> &VRBaseMap);
|
|
};
|
|
} // namespace llvm
|
|
|
|
#endif
|