diff options
author | Bill Wendling <isanbard@gmail.com> | 2008-05-26 05:18:34 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2008-05-26 05:18:34 +0000 |
commit | 48f7f237ea5224c44e9c2782836fb7b60d8b5db1 (patch) | |
tree | d7cd0d8f2c3c13b53745d1e9361bcdb1610ca555 | |
parent | 505242f9b628a4a9b2dc53346b6f1c43670f44a7 (diff) | |
download | external_llvm-48f7f237ea5224c44e9c2782836fb7b60d8b5db1.zip external_llvm-48f7f237ea5224c44e9c2782836fb7b60d8b5db1.tar.gz external_llvm-48f7f237ea5224c44e9c2782836fb7b60d8b5db1.tar.bz2 |
A problem that's exposed when machine LICM is enabled. Consider this code:
LBB1_3: # bb
...
xorl %ebp, %ebp
subl (%ebx), %ebp
...
incl %ecx
cmpl %edi, %ecx
jl LBB1_3 # bb
Whe using machine LICM, LLVM converts it into:
xorl %esi, %esi
LBB1_3: # bb
...
movl %esi, %ebp
subl (%ebx), %ebp
...
incl %ecx
cmpl %edi, %ecx
jl LBB1_3 # bb
Two address conversion inserts the copy instruction. However, it's cheaper to
rematerialize it, and remat helps reduce register pressure.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51562 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/TwoAddressInstructionPass.cpp | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 1e24914..84491a5 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -39,6 +39,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" using namespace llvm; @@ -200,6 +201,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { DOUT << "********** REWRITING TWO-ADDR INSTRS **********\n"; DOUT << "********** Function: " << MF.getFunction()->getName() << '\n'; + SmallPtrSet<MachineInstr*, 8> ReMattedInstrs; + for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end(); mbbi != mbbe; ++mbbi) { for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); @@ -321,7 +324,14 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { InstructionRearranged: const TargetRegisterClass* rc = MF.getRegInfo().getRegClass(regA); - TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc); + MachineInstr *Orig = MRI->getVRegDef(regB); + + if (Orig && TII->isTriviallyReMaterializable(Orig)) { + TII->reMaterialize(*mbbi, mi, regA, Orig); + ReMattedInstrs.insert(Orig); + } else { + TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc); + } MachineBasicBlock::iterator prevMi = prior(mi); DOUT << "\t\tprepend:\t"; DEBUG(prevMi->print(*cerr.stream(), &TM)); @@ -357,5 +367,34 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { } } + SmallPtrSet<MachineInstr*, 8>::iterator I = ReMattedInstrs.begin(); + SmallPtrSet<MachineInstr*, 8>::iterator E = ReMattedInstrs.end(); + + for (; I != E; ++I) { + MachineInstr *MI = *I; + bool InstrDead = true; + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isRegister()) + continue; + unsigned MOReg = MO.getReg(); + if (!MOReg) + continue; + if (MO.isDef()) { + if (MO.isImplicit()) + continue; + + if (MRI->use_begin(MOReg) != MRI->use_end()) { + InstrDead = false; + break; + } + } + } + + if (InstrDead && MI->getNumOperands() > 0) + MI->eraseFromParent(); + } + return MadeChange; } |