#include "llvm/CodeGen/GlobalISel/Types.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/LowLevelType.h"
#include "llvm/IR/DebugLoc.h"
return *TII;
}
+ static void addRegs(MachineInstrBuilder &MIB) {}
+
+ template <typename... MoreRegs>
+ static void addRegs(MachineInstrBuilder &MIB, unsigned Reg,
+ MoreRegs... Regs) {
+ MIB.addReg(Reg);
+ addRegs(MIB, Regs...);
+ }
+
+
public:
/// Getter for the function we currently build.
MachineFunction &getMF() {
/// Set the debug location to \p DL for all the next build instructions.
void setDebugLoc(const DebugLoc &DL) { this->DL = DL; }
- /// Build and insert <empty> = \p Opcode [\p Ty] <empty>.
+ /// Build and insert <empty> = \p Opcode [ { \p Tys } ] <empty>.
/// \p Ty is the type of the instruction if \p Opcode describes
- /// a generic machine instruction. \p Ty must be nullptr if \p Opcode
+ /// a generic machine instruction. \p Ty must be LLT{} if \p Opcode
/// does not describe a generic instruction.
/// The insertion point is the one set by the last call of either
/// setBasicBlock or setMI.
///
/// \pre setBasicBlock or setMI must have been called.
- /// \pre Ty == nullptr or isPreISelGenericOpcode(Opcode)
- ///
- /// \return The newly created instruction.
- MachineInstr *buildInstr(unsigned Opcode, LLT Ty);
-
- /// Build and insert <empty> = \p Opcode [\p Ty] \p BB.
- ///
- /// \pre setBasicBlock or setMI must have been called.
- /// \pre Ty == nullptr or isPreISelGenericOpcode(Opcode)
+ /// \pre Ty == LLT{} or isPreISelGenericOpcode(Opcode)
///
/// \return The newly created instruction.
- MachineInstr *buildInstr(unsigned Opcode, LLT Ty, MachineBasicBlock &BB);
+ MachineInstr *buildInstr(unsigned Opcode, ArrayRef<LLT> Tys);
- /// Build and insert \p Res<def> = \p Opcode [\p Ty] \p Op0, \p Op1.
- ///
- /// \pre setBasicBlock or setMI must have been called.
- /// \pre Ty == nullptr or isPreISelGenericOpcode(Opcode)
- ///
- /// \return The newly created instruction.
- MachineInstr *buildInstr(unsigned Opcode, LLT Ty, unsigned Res,
- unsigned Op0, unsigned Op1);
-
- /// Build and insert \p Res<def> = \p Opcode {[\p Tys]} \p Op0, \p Op1.
+ /// Build and insert \p Res = \p Opcode [\p Ty] \p Uses....
+ /// \p Ty is the type of the instruction if \p Opcode describes
+ /// a generic machine instruction. \p Ty must be LLT{} if \p Opcode
+ /// does not describe a generic instruction.
+ /// The insertion point is the one set by the last call of either
+ /// setBasicBlock or setMI.
///
/// \pre setBasicBlock or setMI must have been called.
- /// \pre Tys empty or isPreISelGenericOpcode(Opcode)
+ /// \pre Ty == LLT{} or isPreISelGenericOpcode(Opcode)
///
/// \return The newly created instruction.
+ template <typename... MoreRegs>
MachineInstr *buildInstr(unsigned Opcode, ArrayRef<LLT> Tys, unsigned Res,
- unsigned Op0);
+ MoreRegs... Uses) {
+ MachineInstr *NewMI = buildInstr(Opcode, Tys);
+ MachineInstrBuilder MIB{getMF(), NewMI};
+ MIB.addReg(Res, RegState::Define);
+ addRegs(MIB, Uses...);
- /// Build and insert \p Res<def> = \p Opcode \p Op0, \p Op1.
- /// I.e., instruction with a non-generic opcode.
- ///
- /// \pre setBasicBlock or setMI must have been called.
- /// \pre not isPreISelGenericOpcode(\p Opcode)
- ///
- /// \return The newly created instruction.
- MachineInstr *buildInstr(unsigned Opcode, unsigned Res, unsigned Op0,
- unsigned Op1);
+ return NewMI;
+ }
- /// Build and insert \p Res<def> = \p Opcode \p Op0.
+ /// Build and insert <empty> = \p Opcode <empty>.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre not isPreISelGenericOpcode(\p Opcode)
///
/// \return The newly created instruction.
- MachineInstr *buildInstr(unsigned Opcode, unsigned Res, unsigned Op0);
+ MachineInstr *buildInstr(unsigned Opcode) {
+ return buildInstr(Opcode, ArrayRef<LLT>());
+ }
- /// Build and insert <empty> = \p Opcode <empty>.
+ /// Build and insert \p Res = \p Opcode \p Uses....
+ /// The insertion point is the one set by the last call of either
+ /// setBasicBlock or setMI.
///
/// \pre setBasicBlock or setMI must have been called.
- /// \pre not isPreISelGenericOpcode(\p Opcode)
///
/// \return The newly created instruction.
- MachineInstr *buildInstr(unsigned Opcode);
+ template <typename... MoreRegs>
+ MachineInstr *buildInstr(unsigned Opcode, unsigned Res, MoreRegs... Uses) {
+ return buildInstr(Opcode, ArrayRef<LLT>(), Res, Uses...);
+ }
/// Build and insert \p Res<def> = G_FRAME_INDEX \p Ty \p Idx
///
/// \return The newly created instruction.
MachineInstr *buildAdd(LLT Ty, unsigned Res, unsigned Op0, unsigned Op1);
+ /// Build and insert G_BR unsized \p Dest
+ ///
+ /// G_BR is an unconditional branch to \p Dest.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return The newly created instruction.
+ MachineInstr *buildBr(MachineBasicBlock &BB);
+
/// Build and insert `Res0<def>, ... = G_EXTRACT Ty Src, Idx0, ...`.
///
/// If \p Ty has size N bits, G_EXTRACT sets \p Res[0] to bits `[Idxs[0],
//------------------------------------------------------------------------------
// Build instruction variants.
//------------------------------------------------------------------------------
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty) {
+
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef<LLT> Tys) {
MachineInstr *NewMI = BuildMI(getMF(), DL, getTII().get(Opcode));
- if (Ty.isValid()) {
+ if (Tys.size() > 0) {
assert(isPreISelGenericOpcode(Opcode) &&
"Only generic instruction can have a type");
- NewMI->setType(Ty);
+ for (unsigned i = 0; i < Tys.size(); ++i)
+ NewMI->setType(Tys[i], i);
} else
assert(!isPreISelGenericOpcode(Opcode) &&
"Generic instruction must have a type");
return NewMI;
}
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
- unsigned Op0, unsigned Op1) {
- return buildInstr(Opcode, LLT{}, Res, Op0, Op1);
-}
-
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
- unsigned Res, unsigned Op0,
- unsigned Op1) {
- MachineInstr *NewMI = buildInstr(Opcode, Ty);
- MachineInstrBuilder(getMF(), NewMI)
- .addReg(Res, RegState::Define)
- .addReg(Op0)
- .addReg(Op1);
- return NewMI;
-}
-
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef<LLT> Tys,
- unsigned Res, unsigned Op0) {
- MachineInstr *NewMI = buildInstr(Opcode, Tys[0]);
- for (unsigned i = 1; i < Tys.size(); ++i)
- NewMI->setType(Tys[i], i);
-
- MachineInstrBuilder(getMF(), NewMI)
- .addReg(Res, RegState::Define)
- .addReg(Op0);
- return NewMI;
-}
-
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
- unsigned Op0) {
- MachineInstr *NewMI = buildInstr(Opcode, LLT{});
- MachineInstrBuilder(getMF(), NewMI).addReg(Res, RegState::Define).addReg(Op0);
- return NewMI;
-}
-
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode) {
- return buildInstr(Opcode, LLT{});
-}
-
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
- MachineBasicBlock &BB) {
- MachineInstr *NewMI = buildInstr(Opcode, Ty);
- MachineInstrBuilder(getMF(), NewMI).addMBB(&BB);
- return NewMI;
-}
-
MachineInstr *MachineIRBuilder::buildFrameIndex(LLT Ty, unsigned Res, int Idx) {
MachineInstr *NewMI = buildInstr(TargetOpcode::G_FRAME_INDEX, Ty);
auto MIB = MachineInstrBuilder(getMF(), NewMI);
return buildInstr(TargetOpcode::G_ADD, Ty, Res, Op0, Op1);
}
+MachineInstr *MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
+ MachineInstr *NewMI = buildInstr(TargetOpcode::G_BR, LLT::unsized());
+ MachineInstrBuilder(getMF(), NewMI).addMBB(&Dest);
+ return NewMI;
+}
+
MachineInstr *MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results,
unsigned Src,
ArrayRef<unsigned> Indexes) {