1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00

GlobalISel: give MachineInstrBuilder a uniform interface. NFC.

Instead of an ad-hoc collection of "buildInstr" functions with varying numbers
of registers, this uses variadic templates to provide for as many regs as
needed!

Also make IRtranslator use new "buildBr" function instead of some weird generic
one that no-one else would really use.

llvm-svn: 276762
This commit is contained in:
Tim Northover 2016-07-26 16:45:26 +00:00
parent 4aa9b69215
commit 13f26f33a7
3 changed files with 66 additions and 92 deletions

View File

@ -17,6 +17,7 @@
#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"
@ -51,6 +52,16 @@ class MachineIRBuilder {
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() {
@ -86,62 +97,40 @@ public:
/// 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)
/// \pre Ty == LLT{} or isPreISelGenericOpcode(Opcode)
///
/// \return The newly created instruction.
MachineInstr *buildInstr(unsigned Opcode, LLT Ty);
MachineInstr *buildInstr(unsigned Opcode, ArrayRef<LLT> Tys);
/// Build and insert <empty> = \p Opcode [\p Ty] \p BB.
/// 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 Ty == nullptr or isPreISelGenericOpcode(Opcode)
///
/// \return The newly created instruction.
MachineInstr *buildInstr(unsigned Opcode, LLT Ty, MachineBasicBlock &BB);
/// 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.
///
/// \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);
/// Build and insert \p Res<def> = \p Opcode \p Op0.
///
/// \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);
return NewMI;
}
/// Build and insert <empty> = \p Opcode <empty>.
///
@ -149,7 +138,21 @@ public:
/// \pre not isPreISelGenericOpcode(\p Opcode)
///
/// \return The newly created instruction.
MachineInstr *buildInstr(unsigned Opcode);
MachineInstr *buildInstr(unsigned Opcode) {
return buildInstr(Opcode, ArrayRef<LLT>());
}
/// 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.
///
/// \return The newly created instruction.
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
///
@ -171,6 +174,15 @@ public:
/// \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],

View File

@ -89,7 +89,7 @@ bool IRTranslator::translateBr(const Instruction &Inst) {
if (BrInst.isUnconditional()) {
const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getOperand(0));
MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt);
MIRBuilder.buildInstr(TargetOpcode::G_BR, LLT{*BrTgt.getType()}, TgtBB);
MIRBuilder.buildBr(TgtBB);
} else {
assert(0 && "Not yet implemented");
}

View File

@ -56,12 +56,14 @@ MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() {
//------------------------------------------------------------------------------
// 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");
@ -69,52 +71,6 @@ MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty) {
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);
@ -128,6 +84,12 @@ MachineInstr *MachineIRBuilder::buildAdd(LLT Ty, unsigned Res, unsigned Op0,
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) {