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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user