diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index c835be06e2d..41061fb6dbd 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -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 + 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 = \p Opcode [\p Ty] . + /// Build and insert = \p Opcode [ { \p Tys } ] . /// \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 Tys); - /// Build and insert = \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 = \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 = \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 MachineInstr *buildInstr(unsigned Opcode, ArrayRef 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 = \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 = \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 = \p Opcode . /// @@ -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()); + } + + /// 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 + MachineInstr *buildInstr(unsigned Opcode, unsigned Res, MoreRegs... Uses) { + return buildInstr(Opcode, ArrayRef(), Res, Uses...); + } /// Build and insert \p Res = 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, ... = G_EXTRACT Ty Src, Idx0, ...`. /// /// If \p Ty has size N bits, G_EXTRACT sets \p Res[0] to bits `[Idxs[0], diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index fbca421a22c..c581439cc2b 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -89,7 +89,7 @@ bool IRTranslator::translateBr(const Instruction &Inst) { if (BrInst.isUnconditional()) { const BasicBlock &BrTgt = *cast(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"); } diff --git a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index f18467c4bb4..fb9b296e8ac 100644 --- a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -56,12 +56,14 @@ MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() { //------------------------------------------------------------------------------ // Build instruction variants. //------------------------------------------------------------------------------ -MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty) { + +MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, ArrayRef 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 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 Results, unsigned Src, ArrayRef Indexes) {