[llvm-commits] [llvm] r107380 - in /llvm/trunk: include/llvm/CodeGen/FastISel.h lib/CodeGen/SelectionDAG/FastISel.cpp test/CodeGen/X86/fast-isel-loads.ll

Dan Gohman gohman at apple.com
Wed Jun 30 20:49:38 PDT 2010


Author: djg
Date: Wed Jun 30 22:49:38 2010
New Revision: 107380

URL: http://llvm.org/viewvc/llvm-project?rev=107380&view=rev
Log:
Teach fast-isel to avoid loading a value from memory when it's already
available in a register. This is pretty primitive, but it reduces the
number of instructions in common testcases by 4%.

Added:
    llvm/trunk/test/CodeGen/X86/fast-isel-loads.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/FastISel.h
    llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp

Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=107380&r1=107379&r2=107380&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Wed Jun 30 22:49:38 2010
@@ -307,6 +307,8 @@
   }
 
 private:
+  bool SelectLoad(const User *I);
+
   bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
 
   bool SelectFNeg(const User *I);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=107380&r1=107379&r2=107380&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Wed Jun 30 22:49:38 2010
@@ -48,6 +48,7 @@
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Analysis/DebugInfo.h"
+#include "llvm/Analysis/Loads.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetLowering.h"
@@ -716,8 +717,31 @@
 }
 
 bool
+FastISel::SelectLoad(const User *I) {
+  LoadInst *LI = const_cast<LoadInst *>(cast<LoadInst>(I));
+
+  // For a load from an alloca, make a limited effort to find the value
+  // already available in a register, avoiding redundant loads.
+  if (!LI->isVolatile() && isa<AllocaInst>(LI->getPointerOperand())) {
+    BasicBlock::iterator ScanFrom = LI;
+    if (const Value *V = FindAvailableLoadedValue(LI->getPointerOperand(),
+                                                  LI->getParent(), ScanFrom)) {
+      unsigned ResultReg = getRegForValue(V);
+      if (ResultReg != 0) {
+        UpdateValueMap(I, ResultReg);
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+bool
 FastISel::SelectOperator(const User *I, unsigned Opcode) {
   switch (Opcode) {
+  case Instruction::Load:
+    return SelectLoad(I);
   case Instruction::Add:
     return SelectBinaryOp(I, ISD::ADD);
   case Instruction::FAdd:

Added: llvm/trunk/test/CodeGen/X86/fast-isel-loads.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-loads.ll?rev=107380&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-loads.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-loads.ll Wed Jun 30 22:49:38 2010
@@ -0,0 +1,23 @@
+; RUN: llc -march=x86-64 -O0 -asm-verbose=false < %s | FileCheck %s
+
+; Fast-isel shouldn't reload the argument values from the stack.
+
+; CHECK: foo:
+; CHECK-NEXT: movq  %rdi, -8(%rsp)
+; CHECK-NEXT: movq  %rsi, -16(%rsp)
+; CHECK-NEXT: movsd 128(%rsi,%rdi,8), %xmm0
+; CHECK-NEXT: ret
+
+define double @foo(i64 %x, double* %p) nounwind {
+entry:
+  %x.addr = alloca i64, align 8                   ; <i64*> [#uses=2]
+  %p.addr = alloca double*, align 8               ; <double**> [#uses=2]
+  store i64 %x, i64* %x.addr
+  store double* %p, double** %p.addr
+  %tmp = load i64* %x.addr                        ; <i64> [#uses=1]
+  %tmp1 = load double** %p.addr                   ; <double*> [#uses=1]
+  %add = add nsw i64 %tmp, 16                     ; <i64> [#uses=1]
+  %arrayidx = getelementptr inbounds double* %tmp1, i64 %add ; <double*> [#uses=1]
+  %tmp2 = load double* %arrayidx                  ; <double> [#uses=1]
+  ret double %tmp2
+}





More information about the llvm-commits mailing list