[llvm-commits] [llvm] r45444 - in /llvm/trunk/lib/Target/X86: X86InstrInfo.cpp X86InstrInfo.h
Bill Wendling
isanbard at gmail.com
Sat Dec 29 19:18:58 PST 2007
Author: void
Date: Sat Dec 29 21:18:58 2007
New Revision: 45444
URL: http://llvm.org/viewvc/llvm-project?rev=45444&view=rev
Log:
If we have a load of a global address that's not modified during the
function, then go ahead and hoist it out of the loop. This is the result:
$ cat a.c
volatile int G;
int A(int N) {
for (; N > 0; --N)
G++;
}
$ llc -o - -relocation-model=pic
_A:
..
LBB1_2: # bb
movl L_G$non_lazy_ptr-"L1$pb"(%eax), %esi
incl (%esi)
incl %edx
cmpl %ecx, %edx
jne LBB1_2 # bb
..
$ llc -o - -relocation-model=pic -machine-licm
_A:
..
movl L_G$non_lazy_ptr-"L1$pb"(%eax), %eax
LBB1_2: # bb
incl (%eax)
incl %edx
cmpl %ecx, %edx
jne LBB1_2 # bb
..
I'm limiting this to the MOV32rm x86 instruction for now.
Modified:
llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
llvm/trunk/lib/Target/X86/X86InstrInfo.h
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=45444&r1=45443&r2=45444&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Sat Dec 29 21:18:58 2007
@@ -144,6 +144,37 @@
return true;
}
+/// isDefinedInEntryBlock - Goes through the entry block to see if the given
+/// virtual register is indeed defined in the entry block.
+///
+bool X86InstrInfo::isDefinedInEntryBlock(const MachineBasicBlock &Entry,
+ unsigned VReg) const {
+ assert(MRegisterInfo::isVirtualRegister(VReg) &&
+ "Map only holds virtual registers!");
+ MachineInstrMap.grow(VReg);
+ if (MachineInstrMap[VReg]) return true;
+
+ MachineBasicBlock::const_iterator I = Entry.begin(), E = Entry.end();
+
+ for (; I != E; ++I) {
+ const MachineInstr &MI = *I;
+ unsigned NumOps = MI.getNumOperands();
+
+ for (unsigned i = 0; i < NumOps; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+
+ if(MO.isRegister() && MO.isDef() &&
+ MRegisterInfo::isVirtualRegister(MO.getReg()) &&
+ MO.getReg() == VReg) {
+ MachineInstrMap[VReg] = &MI;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
/// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this
/// method is called to determine if the specific instance of this instruction
/// has side effects. This is useful in cases of instructions, like loads, which
@@ -152,10 +183,25 @@
bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const {
switch (MI->getOpcode()) {
default: break;
+ case X86::MOV32rm:
+ if (MI->getOperand(1).isRegister()) {
+ unsigned Reg = MI->getOperand(1).getReg();
+
+ // Loads from global addresses which aren't redefined in the function are
+ // side effect free.
+ if (MRegisterInfo::isVirtualRegister(Reg) &&
+ isDefinedInEntryBlock(MI->getParent()->getParent()->front(), Reg) &&
+ MI->getOperand(2).isImmediate() &&
+ MI->getOperand(3).isRegister() &&
+ MI->getOperand(4).isGlobalAddress() &&
+ MI->getOperand(2).getImmedValue() == 1 &&
+ MI->getOperand(3).getReg() == 0)
+ return true;
+ }
+ // FALLTHROUGH
case X86::MOV8rm:
case X86::MOV16rm:
case X86::MOV16_rm:
- case X86::MOV32rm:
case X86::MOV32_rm:
case X86::MOV64rm:
case X86::LD_Fp64m:
@@ -166,8 +212,10 @@
case X86::MMX_MOVD64rm:
case X86::MMX_MOVQ64rm:
// Loads from constant pools have no side effects
- return MI->getOperand(1).isRegister() && MI->getOperand(2).isImmediate() &&
- MI->getOperand(3).isRegister() && MI->getOperand(4).isConstantPoolIndex() &&
+ return MI->getOperand(1).isRegister() &&
+ MI->getOperand(2).isImmediate() &&
+ MI->getOperand(3).isRegister() &&
+ MI->getOperand(4).isConstantPoolIndex() &&
MI->getOperand(1).getReg() == 0 &&
MI->getOperand(2).getImmedValue() == 1 &&
MI->getOperand(3).getReg() == 0;
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.h?rev=45444&r1=45443&r2=45444&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.h Sat Dec 29 21:18:58 2007
@@ -16,6 +16,8 @@
#include "llvm/Target/TargetInstrInfo.h"
#include "X86RegisterInfo.h"
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/Target/MRegisterInfo.h"
namespace llvm {
class X86RegisterInfo;
@@ -223,6 +225,13 @@
class X86InstrInfo : public TargetInstrInfo {
X86TargetMachine &TM;
const X86RegisterInfo RI;
+ mutable IndexedMap<const MachineInstr*, VirtReg2IndexFunctor> MachineInstrMap;
+
+ /// isDefinedInEntryBlock - Goes through the entry block to see if the given
+ /// virtual register is indeed defined in the entry block.
+ ///
+ bool isDefinedInEntryBlock(const MachineBasicBlock &Entry,
+ unsigned VReg) const;
public:
X86InstrInfo(X86TargetMachine &tm);
More information about the llvm-commits
mailing list