diff options
author | Tom Stellard <[email protected]> | 2012-05-31 20:35:18 -0400 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2012-06-01 11:28:11 -0400 |
commit | d6c2d3722d795381d3cdf11fe00f63780ad0725a (patch) | |
tree | 05b75b2f5a1ac26b476d1851cc62b27fbcc5640a /src/gallium | |
parent | 65917004d99ccb79f709e621f8f6cf66715ffdca (diff) |
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.
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp | 93 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/AMDILInstrInfo.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/AMDILRegisterInfo.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/R600InstrInfo.cpp | 16 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/R600InstrInfo.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/R600RegisterInfo.cpp | 8 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/R600RegisterInfo.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/SIInstrInfo.cpp | 11 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/SIInstrInfo.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/SIRegisterInfo.cpp | 8 | ||||
-rw-r--r-- | 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<BlockT *, DEFAULT_VEC_SLOTS> orderedBlks; + const AMDILRegisterInfo *TRI; }; //template class CFGStructurizer @@ -417,9 +419,11 @@ template<class PassT> CFGStructurizer<PassT>::~CFGStructurizer() { } template<class PassT> -bool CFGStructurizer<PassT>::prepare(FuncT &func, PassT &pass) { +bool CFGStructurizer<PassT>::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<PassT>::prepare(FuncT &func, PassT &pass) { } //CFGStructurizer::prepare template<class PassT> -bool CFGStructurizer<PassT>::run(FuncT &func, PassT &pass) { +bool CFGStructurizer<PassT>::run(FuncT &func, PassT &pass, + const AMDILRegisterInfo * tri) { passRep = &pass; funcRep = &func; + TRI = tri; //func.RenumberBlocks(); @@ -1333,8 +1339,10 @@ int CFGStructurizer<PassT>::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<PassT>::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<PassT>::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<int> - (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<PassT>::handleLoopcontBlock(BlockT *contingBlk, } RegiT initReg = INVALIDREGNUM; + const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); if (contingLoop != contLoop) { initReg = static_cast<int> - (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<PassT>::BlockT * CFGStructurizer<PassT>::addLoopEndbranchBlock(LoopT *loopRep, BlockTSmallerVector &exitingBlks, BlockTSmallerVector &exitBlks) { - const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); + const AMDILInstrInfo *tii = + static_cast<const AMDILInstrInfo *>(passRep->getTargetInstrInfo()); + const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); RegiT endBranchReg = static_cast<int> - (funcRep->getRegInfo().createVirtualRegister(&AMDIL::GPRI32RegClass)); + (funcRep->getRegInfo().createVirtualRegister(I32RC)); assert(endBranchReg >= 0); // reg = 0 before entering the loop @@ -1925,14 +1937,16 @@ CFGStructurizer<PassT>::addLoopEndbranchBlock(LoopT *loopRep, DebugLoc DL; RegiT preValReg = static_cast<int> - (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<int> - (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<PassT>::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<PassT>::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<const AMDILRegisterInfo *>(tm.getRegisterInfo()) + ) { } const TargetInstrInfo *AMDILCFGStructurizer::getTargetInstrInfo() const { @@ -3071,14 +3087,11 @@ struct CFGStructTraits<AMDILCFGStructurizer> AMDILCFGStructurizer *passRep, RegiT regNum, int regVal) { MachineInstr *oldInstr = &(*instrPos); - const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); + const AMDILInstrInfo *tii = + static_cast<const AMDILInstrInfo *>(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<AMDILCFGStructurizer> 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<const AMDILInstrInfo *>(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> AMDILCFGStructurizer *passRep, RegiT dstReg, RegiT src1Reg, RegiT src2Reg) { - const TargetInstrInfo *tii = passRep->getTargetInstrInfo(); + const AMDILInstrInfo *tii = + static_cast<const AMDILInstrInfo *>(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<AMDILCFGStructurizer>().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<AMDILCFGStructurizer>().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 |