diff options
author | Evan Cheng <evan.cheng@apple.com> | 2011-05-12 20:30:01 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2011-05-12 20:30:01 +0000 |
commit | 7139d3516526317497e70348e33a57b52ddc053c (patch) | |
tree | 2ce77ff4dc4b356455da2967ff3c3ddad33b7f16 | |
parent | b11f80e94b590c90d07254dfa2406cf504e09cd3 (diff) |
Re-enable branchfolding common code hoisting optimization. Fixed a liveness test bug and also taught it to update liveins.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131241 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/BranchFolding.cpp | 51 | ||||
-rw-r--r-- | test/CodeGen/X86/hoist-common.ll | 28 |
2 files changed, 66 insertions, 13 deletions
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index 6fc077bc12..0ca54ac386 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -1354,10 +1354,6 @@ ReoptimizeBlock: /// NOTE: This optimization does not update live-in information so it must be /// run after all passes that require correct liveness information. bool BranchFolder::HoistCommonCode(MachineFunction &MF) { -#if 1 - // FIXME: Temporarily disabled. - return false; -#endif bool MadeChange = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ) { MachineBasicBlock *MBB = I++; @@ -1472,10 +1468,10 @@ MachineBasicBlock::iterator findHoistingInsertPosAndDeps(MachineBasicBlock *MBB, Uses.erase(Reg); for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) Uses.erase(*SR); // Use getSubRegisters to be conservative - Defs.insert(Reg); - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) - Defs.insert(*AS); } + Defs.insert(Reg); + for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) + Defs.insert(*AS); } } @@ -1511,7 +1507,8 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) { return false; bool HasDups = false; - SmallSet<unsigned, 4> LocalDefs; + SmallVector<unsigned, 4> LocalDefs; + SmallSet<unsigned, 4> LocalDefsSet; MachineBasicBlock::iterator TIB = TBB->begin(); MachineBasicBlock::iterator FIB = FBB->begin(); MachineBasicBlock::iterator TIE = TBB->end(); @@ -1568,11 +1565,7 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) { IsSafe = false; break; } - - LocalDefs.insert(Reg); - for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) - LocalDefs.insert(*SR); - } else if (!LocalDefs.count(Reg)) { + } else if (!LocalDefsSet.count(Reg)) { if (Defs.count(Reg)) { // Use is defined by the instruction at the point of insertion. IsSafe = false; @@ -1587,6 +1580,28 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) { if (!TIB->isSafeToMove(TII, 0, DontMoveAcrossStore)) break; + // Track local defs so we can update liveins. + for (unsigned i = 0, e = TIB->getNumOperands(); i != e; ++i) { + MachineOperand &MO = TIB->getOperand(i); + if (!MO.isReg()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (MO.isDef()) { + if (!MO.isDead()) { + LocalDefs.push_back(Reg); + LocalDefsSet.insert(Reg); + for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) + LocalDefsSet.insert(*SR); + } + } else if (MO.isKill() && LocalDefsSet.count(Reg)) { + LocalDefsSet.erase(Reg); + for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) + LocalDefsSet.erase(*SR); + } + } + HasDups = true;; ++TIB; ++FIB; @@ -1597,6 +1612,16 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) { MBB->splice(Loc, TBB, TBB->begin(), TIB); FBB->erase(FBB->begin(), FIB); + + // Update livein's. + for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { + unsigned Def = LocalDefs[i]; + if (LocalDefsSet.count(Def)) { + TBB->addLiveIn(Def); + FBB->addLiveIn(Def); + } + } + ++NumHoist; return true; } diff --git a/test/CodeGen/X86/hoist-common.ll b/test/CodeGen/X86/hoist-common.ll new file mode 100644 index 0000000000..2b1550a4ff --- /dev/null +++ b/test/CodeGen/X86/hoist-common.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; Common "xorb al, al" instruction in the two successor blocks should be +; moved to the entry block above the test + je. + +; rdar://9145558 + +define zeroext i1 @t(i32 %c) nounwind ssp { +entry: +; CHECK: t: +; CHECK: xorb %al, %al +; CHECK: test +; CHECK: je + %tobool = icmp eq i32 %c, 0 + br i1 %tobool, label %return, label %if.then + +if.then: +; CHECK: callq + %call = tail call zeroext i1 (...)* @foo() nounwind + br label %return + +return: +; CHECK: ret + %retval.0 = phi i1 [ %call, %if.then ], [ false, %entry ] + ret i1 %retval.0 +} + +declare zeroext i1 @foo(...) |