#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
MachineFunction *MF;
MachineInstr *MI;
public:
- MachineInstrBuilder() : MF(0), MI(0) {}
- explicit MachineInstrBuilder(MachineInstr *mi) : MF(0), MI(mi) {}
+ MachineInstrBuilder() : MF(nullptr), MI(nullptr) {}
/// Create a MachineInstrBuilder for manipulating an existing instruction.
/// F must be the machine function that was used to allocate I.
MachineInstr *operator->() const { return MI; }
operator MachineBasicBlock::iterator() const { return MI; }
+ /// If conversion operators fail, use this method to get the MachineInstr
+ /// explicitly.
+ MachineInstr *getInstr() const { return MI; }
+
/// addReg - Add a new virtual register operand...
///
const
unsigned SubReg = 0) const {
assert((flags & 0x1) == 0 &&
"Passing in 'true' to addReg is forbidden! Use enums instead.");
- MI->addOperand(MachineOperand::CreateReg(RegNo,
- flags & RegState::Define,
- flags & RegState::Implicit,
- flags & RegState::Kill,
- flags & RegState::Dead,
- flags & RegState::Undef,
- flags & RegState::EarlyClobber,
- SubReg,
- flags & RegState::Debug,
- flags & RegState::InternalRead));
+ MI->addOperand(*MF, MachineOperand::CreateReg(RegNo,
+ flags & RegState::Define,
+ flags & RegState::Implicit,
+ flags & RegState::Kill,
+ flags & RegState::Dead,
+ flags & RegState::Undef,
+ flags & RegState::EarlyClobber,
+ SubReg,
+ flags & RegState::Debug,
+ flags & RegState::InternalRead));
return *this;
}
/// addImm - Add a new immediate operand.
///
const MachineInstrBuilder &addImm(int64_t Val) const {
- MI->addOperand(MachineOperand::CreateImm(Val));
+ MI->addOperand(*MF, MachineOperand::CreateImm(Val));
return *this;
}
const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
- MI->addOperand(MachineOperand::CreateCImm(Val));
+ MI->addOperand(*MF, MachineOperand::CreateCImm(Val));
return *this;
}
const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
- MI->addOperand(MachineOperand::CreateFPImm(Val));
+ MI->addOperand(*MF, MachineOperand::CreateFPImm(Val));
return *this;
}
const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateMBB(MBB, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateMBB(MBB, TargetFlags));
return *this;
}
const MachineInstrBuilder &addFrameIndex(int Idx) const {
- MI->addOperand(MachineOperand::CreateFI(Idx));
+ MI->addOperand(*MF, MachineOperand::CreateFI(Idx));
return *this;
}
const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
int Offset = 0,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateCPI(Idx, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateTargetIndex(Idx, Offset,
+ TargetFlags));
return *this;
}
const MachineInstrBuilder &addJumpTableIndex(unsigned Idx,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateJTI(Idx, TargetFlags));
return *this;
}
const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV,
int64_t Offset = 0,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateGA(GV, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addExternalSymbol(const char *FnName,
unsigned char TargetFlags = 0) const {
- MI->addOperand(MachineOperand::CreateES(FnName, TargetFlags));
+ MI->addOperand(*MF, MachineOperand::CreateES(FnName, TargetFlags));
+ return *this;
+ }
+
+ const MachineInstrBuilder &addBlockAddress(const BlockAddress *BA,
+ int64_t Offset = 0,
+ unsigned char TargetFlags = 0) const {
+ MI->addOperand(*MF, MachineOperand::CreateBA(BA, Offset, TargetFlags));
return *this;
}
const MachineInstrBuilder &addRegMask(const uint32_t *Mask) const {
- MI->addOperand(MachineOperand::CreateRegMask(Mask));
+ MI->addOperand(*MF, MachineOperand::CreateRegMask(Mask));
return *this;
}
const MachineInstrBuilder &addMemOperand(MachineMemOperand *MMO) const {
- MI->addMemOperand(*MI->getParent()->getParent(), MMO);
+ MI->addMemOperand(*MF, MMO);
return *this;
}
const MachineInstrBuilder &addOperand(const MachineOperand &MO) const {
- MI->addOperand(MO);
+ MI->addOperand(*MF, MO);
return *this;
}
const MachineInstrBuilder &addMetadata(const MDNode *MD) const {
- MI->addOperand(MachineOperand::CreateMetadata(MD));
+ MI->addOperand(*MF, MachineOperand::CreateMetadata(MD));
+ assert((MI->isDebugValue() ? MI->getDebugVariable().Verify() : true) &&
+ "first MDNode argument of a DBG_VALUE not a DIVariable");
return *this;
}
-
+
+ const MachineInstrBuilder &addCFIIndex(unsigned CFIIndex) const {
+ MI->addOperand(*MF, MachineOperand::CreateCFIIndex(CFIIndex));
+ return *this;
+ }
+
const MachineInstrBuilder &addSym(MCSymbol *Sym) const {
- MI->addOperand(MachineOperand::CreateMCSymbol(Sym));
+ MI->addOperand(*MF, MachineOperand::CreateMCSymbol(Sym));
return *this;
}
}
}
}
+
+ /// Copy all the implicit operands from OtherMI onto this one.
+ const MachineInstrBuilder ©ImplicitOps(const MachineInstr *OtherMI) {
+ MI->copyImplicitOps(*MF, OtherMI);
+ return *this;
+ }
};
/// BuildMI - Builder interface. Specify how to create the initial instruction
return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
}
+/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
+/// for either a value in a register or a register-indirect+offset
+/// address. The convention is that a DBG_VALUE is indirect iff the
+/// second operand is an immediate.
+///
+inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL,
+ const MCInstrDesc &MCID, bool IsIndirect,
+ unsigned Reg, unsigned Offset,
+ const MDNode *Variable, const MDNode *Expr) {
+ assert(DIVariable(Variable).Verify() && "not a DIVariable");
+ assert(DIExpression(Expr).Verify() && "not a DIExpression");
+ if (IsIndirect)
+ return BuildMI(MF, DL, MCID)
+ .addReg(Reg, RegState::Debug)
+ .addImm(Offset)
+ .addMetadata(Variable)
+ .addMetadata(Expr);
+ else {
+ assert(Offset == 0 && "A direct address cannot have an offset.");
+ return BuildMI(MF, DL, MCID)
+ .addReg(Reg, RegState::Debug)
+ .addReg(0U, RegState::Debug)
+ .addMetadata(Variable)
+ .addMetadata(Expr);
+ }
+}
+
+/// BuildMI - This version of the builder builds a DBG_VALUE intrinsic
+/// for either a value in a register or a register-indirect+offset
+/// address and inserts it at position I.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I, DebugLoc DL,
+ const MCInstrDesc &MCID, bool IsIndirect,
+ unsigned Reg, unsigned Offset,
+ const MDNode *Variable, const MDNode *Expr) {
+ assert(DIVariable(Variable).Verify() && "not a DIVariable");
+ assert(DIExpression(Expr).Verify() && "not a DIExpression");
+ MachineFunction &MF = *BB.getParent();
+ MachineInstr *MI =
+ BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MF, MI);
+}
+
+
inline unsigned getDefRegState(bool B) {
return B ? RegState::Define : 0;
}
inline unsigned getInternalReadRegState(bool B) {
return B ? RegState::InternalRead : 0;
}
+inline unsigned getDebugRegState(bool B) {
+ return B ? RegState::Debug : 0;
+}
/// Helper class for constructing bundles of MachineInstrs.
/// Create an MIBundleBuilder representing an existing instruction or bundle
/// that has MI as its head.
explicit MIBundleBuilder(MachineInstr *MI)
- : MBB(*MI->getParent()), Begin(MI) {
- MachineBasicBlock::iterator I = MI;
- ++I;
- End = I.getInstrIterator();
- }
+ : MBB(*MI->getParent()), Begin(MI), End(getBundleEnd(MI)) {}
/// Return a reference to the basic block containing this bundle.
MachineBasicBlock &getMBB() const { return MBB; }