From d6c2d3722d795381d3cdf11fe00f63780ad0725a Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 31 May 2012 20:35:18 -0400 Subject: [PATCH] radeon/llvm: Eliminate CFGStructurizer dependency on AMDIL instructions Add some hooks to the R600,SI InstrInfo and RegisterInfo classes, so that the CFGStructurizer pass can run without any relying on AMDIL instructions. --- .../drivers/radeon/AMDILCFGStructurizer.cpp | 93 +++++++++++-------- src/gallium/drivers/radeon/AMDILInstrInfo.h | 5 + .../drivers/radeon/AMDILRegisterInfo.h | 5 + src/gallium/drivers/radeon/R600InstrInfo.cpp | 16 ++++ src/gallium/drivers/radeon/R600InstrInfo.h | 6 +- .../drivers/radeon/R600RegisterInfo.cpp | 8 ++ src/gallium/drivers/radeon/R600RegisterInfo.h | 4 + src/gallium/drivers/radeon/SIInstrInfo.cpp | 11 +++ src/gallium/drivers/radeon/SIInstrInfo.h | 5 + src/gallium/drivers/radeon/SIRegisterInfo.cpp | 8 ++ src/gallium/drivers/radeon/SIRegisterInfo.h | 4 + 11 files changed, 124 insertions(+), 41 deletions(-) diff --git a/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp b/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp index e47c2d8faa3..26559a0371d 100644 --- a/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp +++ b/src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp @@ -11,6 +11,7 @@ #define DEBUG_TYPE "structcfg" #include "AMDIL.h" +#include "AMDILInstrInfo.h" #include "AMDILRegisterInfo.h" #include "AMDILUtilityFunctions.h" #include "llvm/ADT/SCCIterator.h" @@ -295,10 +296,10 @@ public: ~CFGStructurizer(); /// Perform the CFG structurization - bool run(FuncT &Func, PassT &Pass); + bool run(FuncT &Func, PassT &Pass, const AMDILRegisterInfo *tri); /// Perform the CFG preparation - bool prepare(FuncT &Func, PassT &Pass); + bool prepare(FuncT &Func, PassT &Pass, const AMDILRegisterInfo *tri); private: void orderBlocks(); @@ -402,6 +403,7 @@ private: BlockInfoMap blockInfoMap; LoopLandInfoMap loopLandInfoMap; SmallVector orderedBlks; + const AMDILRegisterInfo *TRI; }; //template class CFGStructurizer @@ -417,9 +419,11 @@ template CFGStructurizer::~CFGStructurizer() { } template -bool CFGStructurizer::prepare(FuncT &func, PassT &pass) { +bool CFGStructurizer::prepare(FuncT &func, PassT &pass, + const AMDILRegisterInfo * tri) { passRep = &pass; funcRep = &func; + TRI = tri; bool changed = false; //func.RenumberBlocks(); @@ -504,9 +508,11 @@ bool CFGStructurizer::prepare(FuncT &func, PassT &pass) { } //CFGStructurizer::prepare template -bool CFGStructurizer::run(FuncT &func, PassT &pass) { +bool CFGStructurizer::run(FuncT &func, PassT &pass, + const AMDILRegisterInfo * tri) { passRep = &pass; funcRep = &func; + TRI = tri; //func.RenumberBlocks(); @@ -1333,8 +1339,10 @@ int CFGStructurizer::improveSimpleJumpintoIf(BlockT *headBlk, // if (initReg !=2) {...} // // add initReg = initVal to headBlk + + const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); unsigned initReg = - funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass); + funcRep->getRegInfo().createVirtualRegister(I32RC); if (!migrateTrue || !migrateFalse) { int initVal = migrateTrue ? 0 : 1; CFGTraits::insertAssignInstrBefore(headBlk, passRep, initReg, initVal); @@ -1370,10 +1378,10 @@ int CFGStructurizer::improveSimpleJumpintoIf(BlockT *headBlk, if (landBlkHasOtherPred) { unsigned immReg = - funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass); + funcRep->getRegInfo().createVirtualRegister(I32RC); CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 2); unsigned cmpResReg = - funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass); + funcRep->getRegInfo().createVirtualRegister(I32RC); CFGTraits::insertCompareInstrBefore(landBlk, insertPos, passRep, cmpResReg, initReg, immReg); @@ -1439,11 +1447,12 @@ void CFGStructurizer::handleLoopbreak(BlockT *exitingBlk, errs() << "Trying to break loop-depth = " << getLoopDepth(exitLoop) << " from loop-depth = " << getLoopDepth(exitingLoop) << "\n"; } + const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); RegiT initReg = INVALIDREGNUM; if (exitingLoop != exitLoop) { initReg = static_cast - (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass)); + (funcRep->getRegInfo().createVirtualRegister(I32RC)); assert(initReg != INVALIDREGNUM); addLoopBreakInitReg(exitLoop, initReg); while (exitingLoop != exitLoop && exitingLoop) { @@ -1472,9 +1481,10 @@ void CFGStructurizer::handleLoopcontBlock(BlockT *contingBlk, } RegiT initReg = INVALIDREGNUM; + const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); if (contingLoop != contLoop) { initReg = static_cast - (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass)); + (funcRep->getRegInfo().createVirtualRegister(I32RC)); assert(initReg != INVALIDREGNUM); addLoopContInitReg(contLoop, initReg); while (contingLoop && contingLoop->getParentLoop() != contLoop) { @@ -1862,10 +1872,12 @@ typename CFGStructurizer::BlockT * CFGStructurizer::addLoopEndbranchBlock(LoopT *loopRep, BlockTSmallerVector &exitingBlks, BlockTSmallerVector &exitBlks) { - const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); + const AMDILInstrInfo *tii = + static_cast(passRep->getTargetInstrInfo()); + const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); RegiT endBranchReg = static_cast - (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass)); + (funcRep->getRegInfo().createVirtualRegister(I32RC)); assert(endBranchReg >= 0); // reg = 0 before entering the loop @@ -1925,14 +1937,16 @@ CFGStructurizer::addLoopEndbranchBlock(LoopT *loopRep, DebugLoc DL; RegiT preValReg = static_cast - (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass)); - BuildMI(preBranchBlk, DL, tii->get(AMDIL::LOADCONST_i32), preValReg) - .addImm(i - 1); //preVal + (funcRep->getRegInfo().createVirtualRegister(I32RC)); + + preBranchBlk->insert(preBranchBlk->begin(), + tii->getMovImmInstr(preBranchBlk->getParent(), preValReg, + i - 1)); // condResReg = (endBranchReg == preValReg) RegiT condResReg = static_cast - (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass)); - BuildMI(preBranchBlk, DL, tii->get(AMDIL::IEQ), condResReg) + (funcRep->getRegInfo().createVirtualRegister(I32RC)); + BuildMI(preBranchBlk, DL, tii->get(tii->getIEQOpcode()), condResReg) .addReg(endBranchReg).addReg(preValReg); BuildMI(preBranchBlk, DL, tii->get(AMDIL::BRANCH_COND_i32)) @@ -2136,6 +2150,7 @@ CFGStructurizer::normalizeInfiniteLoopExit(LoopT* LoopRep) { loopHeader = LoopRep->getHeader(); loopLatch = LoopRep->getLoopLatch(); BlockT *dummyExitBlk = NULL; + const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); if (loopHeader!=NULL && loopLatch!=NULL) { InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(loopLatch); if (branchInstr!=NULL && CFGTraits::isUncondBranch(branchInstr)) { @@ -2148,7 +2163,7 @@ CFGStructurizer::normalizeInfiniteLoopExit(LoopT* LoopRep) { typename BlockT::iterator insertPos = CFGTraits::getInstrPos(loopLatch, branchInstr); unsigned immReg = - funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass); + funcRep->getRegInfo().createVirtualRegister(I32RC); CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 1); InstrT *newInstr = CFGTraits::insertInstrBefore(insertPos, AMDIL::BRANCH_COND_i32, passRep); @@ -2615,12 +2630,11 @@ public: typedef MachinePostDominatorTree PostDominatortreeType; typedef MachineDomTreeNode DomTreeNodeType; typedef MachineLoop LoopType; -//private: + +protected: TargetMachine &TM; const TargetInstrInfo *TII; - -//public: -// static char ID; + const AMDILRegisterInfo *TRI; public: AMDILCFGStructurizer(char &pid, TargetMachine &tm AMDIL_OPT_LEVEL_DECL); @@ -2635,7 +2649,9 @@ private: } //end of namespace llvm AMDILCFGStructurizer::AMDILCFGStructurizer(char &pid, TargetMachine &tm AMDIL_OPT_LEVEL_DECL) -: MachineFunctionPass(pid), TM(tm), TII(tm.getInstrInfo()) { +: MachineFunctionPass(pid), TM(tm), TII(tm.getInstrInfo()), + TRI(static_cast(tm.getRegisterInfo()) + ) { } const TargetInstrInfo *AMDILCFGStructurizer::getTargetInstrInfo() const { @@ -3071,14 +3087,11 @@ struct CFGStructTraits AMDILCFGStructurizer *passRep, RegiT regNum, int regVal) { MachineInstr *oldInstr = &(*instrPos); - const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); + const AMDILInstrInfo *tii = + static_cast(passRep->getTargetInstrInfo()); MachineBasicBlock *blk = oldInstr->getParent(); - MachineInstr *newInstr = - blk->getParent()->CreateMachineInstr(tii->get(AMDIL::LOADCONST_i32), - DebugLoc()); - MachineInstrBuilder(newInstr).addReg(regNum, RegState::Define); //set target - MachineInstrBuilder(newInstr).addImm(regVal); //set src value - + MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum, + regVal); blk->insert(instrPos, newInstr); SHOWNEWINSTR(newInstr); @@ -3087,14 +3100,11 @@ struct CFGStructTraits static void insertAssignInstrBefore(MachineBasicBlock *blk, AMDILCFGStructurizer *passRep, RegiT regNum, int regVal) { - const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); - - MachineInstr *newInstr = - blk->getParent()->CreateMachineInstr(tii->get(AMDIL::LOADCONST_i32), - DebugLoc()); - MachineInstrBuilder(newInstr).addReg(regNum, RegState::Define); //set target - MachineInstrBuilder(newInstr).addImm(regVal); //set src value + const AMDILInstrInfo *tii = + static_cast(passRep->getTargetInstrInfo()); + MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum, + regVal); if (blk->begin() != blk->end()) { blk->insert(blk->begin(), newInstr); } else { @@ -3110,9 +3120,10 @@ struct CFGStructTraits AMDILCFGStructurizer *passRep, RegiT dstReg, RegiT src1Reg, RegiT src2Reg) { - const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); + const AMDILInstrInfo *tii = + static_cast(passRep->getTargetInstrInfo()); MachineInstr *newInstr = - blk->getParent()->CreateMachineInstr(tii->get(AMDIL::IEQ), DebugLoc()); + blk->getParent()->CreateMachineInstr(tii->get(tii->getIEQOpcode()), DebugLoc()); MachineInstrBuilder(newInstr).addReg(dstReg, RegState::Define); //set target MachineInstrBuilder(newInstr).addReg(src1Reg); //set src value @@ -3212,7 +3223,8 @@ FunctionPass *llvm::createAMDILCFGPreparationPass(TargetMachine &tm bool AMDILCFGPrepare::runOnMachineFunction(MachineFunction &func) { return llvmCFGStruct::CFGStructurizer().prepare(func, - *this); + *this, + TRI); } // createAMDILCFGStructurizerPass- Returns a pass @@ -3223,7 +3235,8 @@ FunctionPass *llvm::createAMDILCFGStructurizerPass(TargetMachine &tm bool AMDILCFGPerform::runOnMachineFunction(MachineFunction &func) { return llvmCFGStruct::CFGStructurizer().run(func, - *this); + *this, + TRI); } //end of file newline goes below diff --git a/src/gallium/drivers/radeon/AMDILInstrInfo.h b/src/gallium/drivers/radeon/AMDILInstrInfo.h index 6aa03e713ae..211c881e7b9 100644 --- a/src/gallium/drivers/radeon/AMDILInstrInfo.h +++ b/src/gallium/drivers/radeon/AMDILInstrInfo.h @@ -147,6 +147,11 @@ public: bool isLocalAtomic(llvm::MachineInstr *MI) const; bool isGlobalAtomic(llvm::MachineInstr *MI) const; bool isArenaAtomic(llvm::MachineInstr *MI) const; + + virtual MachineInstr * getMovImmInstr(MachineFunction *MF, unsigned DstReg, + int64_t Imm) const = 0; + + virtual unsigned getIEQOpcode() const = 0; }; } diff --git a/src/gallium/drivers/radeon/AMDILRegisterInfo.h b/src/gallium/drivers/radeon/AMDILRegisterInfo.h index 7627bdec045..4bfb9a742bd 100644 --- a/src/gallium/drivers/radeon/AMDILRegisterInfo.h +++ b/src/gallium/drivers/radeon/AMDILRegisterInfo.h @@ -80,6 +80,11 @@ namespace llvm int64_t getStackSize() const; + + virtual const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT) + const { + return AMDIL::GPRI32RegisterClass; + } private: mutable int64_t baseOffset; mutable int64_t nextFuncOffset; diff --git a/src/gallium/drivers/radeon/R600InstrInfo.cpp b/src/gallium/drivers/radeon/R600InstrInfo.cpp index 99153574675..05c291f1b89 100644 --- a/src/gallium/drivers/radeon/R600InstrInfo.cpp +++ b/src/gallium/drivers/radeon/R600InstrInfo.cpp @@ -100,3 +100,19 @@ unsigned R600InstrInfo::getLSHRop() const return AMDIL::LSHR_eg; } } + +MachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF, + unsigned DstReg, int64_t Imm) const +{ + MachineInstr * MI = MF->CreateMachineInstr(get(AMDIL::MOV), DebugLoc()); + MachineInstrBuilder(MI).addReg(DstReg, RegState::Define); + MachineInstrBuilder(MI).addReg(AMDIL::ALU_LITERAL_X); + MachineInstrBuilder(MI).addImm(Imm); + + return MI; +} + +unsigned R600InstrInfo::getIEQOpcode() const +{ + return AMDIL::SETE_INT; +} diff --git a/src/gallium/drivers/radeon/R600InstrInfo.h b/src/gallium/drivers/radeon/R600InstrInfo.h index 9dca4839090..2b5e5c42995 100644 --- a/src/gallium/drivers/radeon/R600InstrInfo.h +++ b/src/gallium/drivers/radeon/R600InstrInfo.h @@ -47,7 +47,11 @@ namespace llvm { unsigned getLSHRop() const; unsigned getASHRop() const; - }; + virtual MachineInstr * getMovImmInstr(MachineFunction *MF, unsigned DstReg, + int64_t Imm) const; + + virtual unsigned getIEQOpcode() const; +}; } // End llvm namespace diff --git a/src/gallium/drivers/radeon/R600RegisterInfo.cpp b/src/gallium/drivers/radeon/R600RegisterInfo.cpp index de559bd2dfa..ad6deabf802 100644 --- a/src/gallium/drivers/radeon/R600RegisterInfo.cpp +++ b/src/gallium/drivers/radeon/R600RegisterInfo.cpp @@ -94,4 +94,12 @@ unsigned R600RegisterInfo::getHWRegChan(unsigned reg) const } } +const TargetRegisterClass * R600RegisterInfo::getCFGStructurizerRegClass( + MVT VT) const +{ + switch(VT.SimpleTy) { + default: + case MVT::i32: return AMDIL::R600_TReg32RegisterClass; + } +} #include "R600HwRegInfo.include" diff --git a/src/gallium/drivers/radeon/R600RegisterInfo.h b/src/gallium/drivers/radeon/R600RegisterInfo.h index 7525a97d50a..4ed831ad848 100644 --- a/src/gallium/drivers/radeon/R600RegisterInfo.h +++ b/src/gallium/drivers/radeon/R600RegisterInfo.h @@ -42,6 +42,10 @@ struct R600RegisterInfo : public AMDGPURegisterInfo /// getHWRegChan - get the HW encoding for a register's channel. unsigned getHWRegChan(unsigned reg) const; + /// getCFGStructurizerRegClass - get the register class of the specified + /// type to use in the CFGStructurizer + virtual const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT) const; + private: /// getHWRegIndexGen - Generated function returns a register's encoding unsigned getHWRegIndexGen(unsigned reg) const; diff --git a/src/gallium/drivers/radeon/SIInstrInfo.cpp b/src/gallium/drivers/radeon/SIInstrInfo.cpp index 4ee3e5d5f8d..cd4e227e33b 100644 --- a/src/gallium/drivers/radeon/SIInstrInfo.cpp +++ b/src/gallium/drivers/radeon/SIInstrInfo.cpp @@ -105,3 +105,14 @@ unsigned SIInstrInfo::getISAOpcode(unsigned AMDILopcode) const default: return AMDILopcode; } } + +MachineInstr * SIInstrInfo::getMovImmInstr(MachineFunction *MF, unsigned DstReg, + int64_t Imm) const +{ + MachineInstr * MI = MF->CreateMachineInstr(get(AMDIL::V_MOV_IMM), DebugLoc()); + MachineInstrBuilder(MI).addReg(DstReg, RegState::Define); + MachineInstrBuilder(MI).addImm(Imm); + + return MI; + +} diff --git a/src/gallium/drivers/radeon/SIInstrInfo.h b/src/gallium/drivers/radeon/SIInstrInfo.h index 0614638517a..996dceeb075 100644 --- a/src/gallium/drivers/radeon/SIInstrInfo.h +++ b/src/gallium/drivers/radeon/SIInstrInfo.h @@ -51,6 +51,11 @@ public: /// returns an equivalent SI opcode. virtual unsigned getISAOpcode(unsigned AMDILopcode) const; + virtual MachineInstr * getMovImmInstr(MachineFunction *MF, unsigned DstReg, + int64_t Imm) const; + + virtual unsigned getIEQOpcode() const { assert(!"Implement"); return 0;} + }; } // End namespace llvm diff --git a/src/gallium/drivers/radeon/SIRegisterInfo.cpp b/src/gallium/drivers/radeon/SIRegisterInfo.cpp index 04e2e17d7ec..2abe6884da2 100644 --- a/src/gallium/drivers/radeon/SIRegisterInfo.cpp +++ b/src/gallium/drivers/radeon/SIRegisterInfo.cpp @@ -53,4 +53,12 @@ SIRegisterInfo::getISARegClass(const TargetRegisterClass * rc) const } } +const TargetRegisterClass * SIRegisterInfo::getCFGStructurizerRegClass( + MVT VT) const +{ + switch(VT.SimpleTy) { + default: + case MVT::i32: return AMDIL::VReg_32RegisterClass; + } +} #include "SIRegisterGetHWRegNum.inc" diff --git a/src/gallium/drivers/radeon/SIRegisterInfo.h b/src/gallium/drivers/radeon/SIRegisterInfo.h index 949a1e2f6b7..99005cbccc1 100644 --- a/src/gallium/drivers/radeon/SIRegisterInfo.h +++ b/src/gallium/drivers/radeon/SIRegisterInfo.h @@ -43,6 +43,10 @@ struct SIRegisterInfo : public AMDGPURegisterInfo /// a register unsigned getHWRegNum(unsigned reg) const; + /// getCFGStructurizerRegClass - get the register class of the specified + /// type to use in the CFGStructurizer + virtual const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT) const; + }; } // End namespace llvm -- 2.30.2