aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/R600/SILowerControlFlow.cpp
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2012-12-19 22:10:33 +0000
committerTom Stellard <thomas.stellard@amd.com>2012-12-19 22:10:33 +0000
commitd09d43ae53e1eba83dc5516a148748001b8ff812 (patch)
tree9f86e90aa500f167463f6b9e320987b4f492f4f8 /lib/Target/R600/SILowerControlFlow.cpp
parent6b7d99d47321ebb478b22afd2e317fe89d2149db (diff)
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
Diffstat (limited to 'lib/Target/R600/SILowerControlFlow.cpp')
-rw-r--r--lib/Target/R600/SILowerControlFlow.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/Target/R600/SILowerControlFlow.cpp b/lib/Target/R600/SILowerControlFlow.cpp
index 1abcb8805a..507cb54f13 100644
--- a/lib/Target/R600/SILowerControlFlow.cpp
+++ b/lib/Target/R600/SILowerControlFlow.cpp
@@ -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;
}
}
}