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.
This commit is contained in:
Tom Stellard
2012-05-31 20:35:18 -04:00
parent 65917004d9
commit d6c2d3722d
11 changed files with 124 additions and 41 deletions
@@ -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
@@ -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;
};
}
@@ -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;
@@ -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;
}
+5 -1
View File
@@ -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
@@ -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"
@@ -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;
@@ -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;
}
+5
View File
@@ -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
@@ -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"
@@ -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