[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