diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2007-12-01 02:07:52 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2007-12-01 02:07:52 +0000 |
| commit | 69fda0a7167048ae647675536fd7b2e4bb02f5a6 (patch) | |
| tree | d1c03a1a47b4bf6b6c5199e5b85394c8a95a8320 /llvm/lib/Target/X86/X86RegisterInfo.cpp | |
| parent | e62b441b516089f04648120d5ed9b4581d4fafe4 (diff) | |
| download | bcm5719-llvm-69fda0a7167048ae647675536fd7b2e4bb02f5a6.tar.gz bcm5719-llvm-69fda0a7167048ae647675536fd7b2e4bb02f5a6.zip | |
Allow some reloads to be folded in multi-use cases. Specifically testl r, r -> cmpl [mem], 0.
llvm-svn: 44479
Diffstat (limited to 'llvm/lib/Target/X86/X86RegisterInfo.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.cpp | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 25b6375ce32..29f401ab7bd 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -1149,6 +1149,31 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNu return foldMemoryOperand(MI, OpNum, MOs); } +MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, + SmallVectorImpl<unsigned> &UseOps, + int FrameIndex) const { + // Check switch flag + if (NoFusing) return NULL; + + if (UseOps.size() == 1) + return foldMemoryOperand(MI, UseOps[0], FrameIndex); + else if (UseOps.size() != 2 || UseOps[0] != 0 && UseOps[1] != 1) + return NULL; + + unsigned NewOpc = 0; + switch (MI->getOpcode()) { + default: return NULL; + case X86::TEST8rr: NewOpc = X86::CMP8ri; break; + case X86::TEST16rr: NewOpc = X86::CMP16ri; break; + case X86::TEST32rr: NewOpc = X86::CMP32ri; break; + case X86::TEST64rr: NewOpc = X86::CMP64ri32; break; + } + // Change to CMPXXri r, 0 first. + MI->setInstrDescriptor(TII.get(NewOpc)); + MI->getOperand(1).ChangeToImmediate(0); + return foldMemoryOperand(MI, 0, FrameIndex); +} + MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, MachineInstr *LoadMI) const { // Check switch flag @@ -1160,6 +1185,31 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNu return foldMemoryOperand(MI, OpNum, MOs); } +MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, + SmallVectorImpl<unsigned> &UseOps, + MachineInstr *LoadMI) const { + // Check switch flag + if (NoFusing) return NULL; + + if (UseOps.size() == 1) + return foldMemoryOperand(MI, UseOps[0], LoadMI); + else if (UseOps.size() != 2 || UseOps[0] != 0 && UseOps[1] != 1) + return NULL; + unsigned NewOpc = 0; + switch (MI->getOpcode()) { + default: return NULL; + case X86::TEST8rr: NewOpc = X86::CMP8ri; break; + case X86::TEST16rr: NewOpc = X86::CMP16ri; break; + case X86::TEST32rr: NewOpc = X86::CMP32ri; break; + case X86::TEST64rr: NewOpc = X86::CMP64ri32; break; + } + // Change to CMPXXri r, 0 first. + MI->setInstrDescriptor(TII.get(NewOpc)); + MI->getOperand(1).ChangeToImmediate(0); + return foldMemoryOperand(MI, 0, LoadMI); +} + + unsigned X86RegisterInfo::getOpcodeAfterMemoryFold(unsigned Opc, unsigned OpNum) const { // Check switch flag @@ -1270,7 +1320,30 @@ bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, MachineOperand &MO = ImpOps[i]; MIB.addReg(MO.getReg(), MO.isDef(), true, MO.isKill(), MO.isDead()); } - NewMIs.push_back(MIB); + // Change CMP32ri r, 0 back to TEST32rr r, r, etc. + unsigned NewOpc = 0; + switch (DataMI->getOpcode()) { + default: break; + case X86::CMP64ri32: + case X86::CMP32ri: + case X86::CMP16ri: + case X86::CMP8ri: { + MachineOperand &MO0 = DataMI->getOperand(0); + MachineOperand &MO1 = DataMI->getOperand(1); + if (MO1.getImm() == 0) { + switch (DataMI->getOpcode()) { + default: break; + case X86::CMP64ri32: NewOpc = X86::TEST64rr; break; + case X86::CMP32ri: NewOpc = X86::TEST32rr; break; + case X86::CMP16ri: NewOpc = X86::TEST16rr; break; + case X86::CMP8ri: NewOpc = X86::TEST8rr; break; + } + DataMI->setInstrDescriptor(TII.get(NewOpc)); + MO1.ChangeToRegister(MO0.getReg(), false); + } + } + } + NewMIs.push_back(DataMI); // Emit the store instruction. if (UnfoldStore) { |

