summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2012-05-31 20:35:18 -0400
committerTom Stellard <thomas.stellard@amd.com>2012-05-31 20:38:25 -0400
commit28e6be8fe989ed57152619f14a482de901343d31 (patch)
treee9a100acad6f9ba4fcd1687b0130b1ca0ba551ba
parentc35e51f0ec14b13cbcc0efe9a3a1dbc0c780142c (diff)
radeon/llvm: Eliminate CFGStructurizer dependency on AMDIL instructionsgallium-compute-r600-June1
Add some hooks to the R600,SI InstrInfo and RegisterInfo classes, so that the CFGStructurizer pass can run without any relying on AMDIL instructions.
-rw-r--r--src/gallium/drivers/radeon/AMDILCFGStructurizer.cpp93
-rw-r--r--src/gallium/drivers/radeon/AMDILInstrInfo.h5
-rw-r--r--src/gallium/drivers/radeon/AMDILRegisterInfo.h5
-rw-r--r--src/gallium/drivers/radeon/R600InstrInfo.cpp16
-rw-r--r--src/gallium/drivers/radeon/R600InstrInfo.h6
-rw-r--r--src/gallium/drivers/radeon/R600RegisterInfo.cpp8
-rw-r--r--src/gallium/drivers/radeon/R600RegisterInfo.h4
-rw-r--r--src/gallium/drivers/radeon/SIInstrInfo.cpp11
-rw-r--r--src/gallium/drivers/radeon/SIInstrInfo.h5
-rw-r--r--src/gallium/drivers/radeon/SIRegisterInfo.cpp8
-rw-r--r--src/gallium/drivers/radeon/SIRegisterInfo.h4
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