R600: control flow optimization

Branch if we have enough instructions so that it makes sense.
Also remove branches if they don't make sense.

Patch by: Christian König

Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
Tested-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Christian König <deathsimple@vodafone.de>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170592 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tom Stellard 2012-12-19 22:10:33 +00:00
parent 6b7d99d473
commit d09d43ae53

View File

@ -63,9 +63,13 @@ namespace {
class SILowerControlFlowPass : public MachineFunctionPass {
private:
static const unsigned SkipThreshold = 12;
static char ID;
const TargetInstrInfo *TII;
void Skip(MachineInstr &MI, MachineOperand &To);
void If(MachineInstr &MI);
void Else(MachineInstr &MI);
void Break(MachineInstr &MI);
@ -74,6 +78,8 @@ private:
void Loop(MachineInstr &MI);
void EndCf(MachineInstr &MI);
void Branch(MachineInstr &MI);
public:
SILowerControlFlowPass(TargetMachine &tm) :
MachineFunctionPass(ID), TII(tm.getInstrInfo()) { }
@ -94,6 +100,31 @@ FunctionPass *llvm::createSILowerControlFlowPass(TargetMachine &tm) {
return new SILowerControlFlowPass(tm);
}
void SILowerControlFlowPass::Skip(MachineInstr &From, MachineOperand &To) {
unsigned NumInstr = 0;
for (MachineBasicBlock *MBB = *From.getParent()->succ_begin();
NumInstr < SkipThreshold && MBB != To.getMBB() && !MBB->succ_empty();
MBB = *MBB->succ_begin()) {
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
NumInstr < SkipThreshold && I != E; ++I) {
if (I->isBundle() || !I->isBundled())
++NumInstr;
}
}
if (NumInstr < SkipThreshold)
return;
DebugLoc DL = From.getDebugLoc();
BuildMI(*From.getParent(), &From, DL, TII->get(AMDGPU::S_CBRANCH_EXECZ))
.addOperand(To)
.addReg(AMDGPU::EXEC);
}
void SILowerControlFlowPass::If(MachineInstr &MI) {
MachineBasicBlock &MBB = *MI.getParent();
@ -108,6 +139,8 @@ void SILowerControlFlowPass::If(MachineInstr &MI) {
.addReg(AMDGPU::EXEC)
.addReg(Reg);
Skip(MI, MI.getOperand(2));
MI.eraseFromParent();
}
@ -125,6 +158,8 @@ void SILowerControlFlowPass::Else(MachineInstr &MI) {
.addReg(AMDGPU::EXEC)
.addReg(Dst);
Skip(MI, MI.getOperand(2));
MI.eraseFromParent();
}
@ -206,6 +241,16 @@ void SILowerControlFlowPass::EndCf(MachineInstr &MI) {
MI.eraseFromParent();
}
void SILowerControlFlowPass::Branch(MachineInstr &MI) {
MachineBasicBlock *Next = MI.getParent()->getNextNode();
MachineBasicBlock *Target = MI.getOperand(0).getMBB();
if (Target == Next)
MI.eraseFromParent();
else
assert(0);
}
bool SILowerControlFlowPass::runOnMachineFunction(MachineFunction &MF) {
bool HaveCf = false;
@ -249,6 +294,10 @@ bool SILowerControlFlowPass::runOnMachineFunction(MachineFunction &MF) {
HaveCf = true;
EndCf(MI);
break;
case AMDGPU::S_BRANCH:
Branch(MI);
break;
}
}
}