From 13f26f33a7f48ceef08c85b7d1bc0e5351bb766f Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 26 Jul 2016 16:45:26 +0000 Subject: [PATCH] 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 --- .../CodeGen/GlobalISel/MachineIRBuilder.h | 96 +++++++++++-------- lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 +- lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 60 +++--------- 3 files changed, 66 insertions(+), 92 deletions(-) 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) {