[llvm-commits] [llvm] r137993 - in /llvm/trunk: include/llvm/CodeGen/FastISel.h lib/CodeGen/SelectionDAG/FastISel.cpp test/CodeGen/ARM/debug-info-blocks.ll test/CodeGen/X86/fast-isel-x86-64.ll

Ivan Krasin krasin at chromium.org
Thu Aug 18 15:06:11 PDT 2011


Author: krasin
Date: Thu Aug 18 17:06:10 2011
New Revision: 137993

URL: http://llvm.org/viewvc/llvm-project?rev=137993&view=rev
Log:
FastISel: avoid function calls between the materialization of the constant and its use.


Modified:
    llvm/trunk/include/llvm/CodeGen/FastISel.h
    llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
    llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll
    llvm/trunk/test/CodeGen/X86/fast-isel-x86-64.ll

Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=137993&r1=137992&r2=137993&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Thu Aug 18 17:06:10 2011
@@ -54,8 +54,18 @@
   const TargetInstrInfo &TII;
   const TargetLowering &TLI;
   const TargetRegisterInfo &TRI;
+
+  /// The position of the last instruction for materializing constants
+  /// for use in the current block. It resets to EmitStartPt when it
+  /// makes sense (for example, it's usually profitable to avoid function
+  /// calls between the definition and the use)
   MachineInstr *LastLocalValue;
 
+  /// The top most instruction in the current block that is allowed for
+  /// emitting local variables. LastLocalValue resets to EmitStartPt when
+  /// it makes sense (for example, on function calls)
+  MachineInstr *EmitStartPt;
+
 public:
   /// getLastLocalValue - Return the position of the last instruction
   /// emitted for materializing constants for use in the current block.
@@ -63,7 +73,10 @@
 
   /// setLastLocalValue - Update the position of the last instruction
   /// emitted for materializing constants for use in the current block.
-  void setLastLocalValue(MachineInstr *I) { LastLocalValue = I; }
+  void setLastLocalValue(MachineInstr *I) {
+    EmitStartPt = I;
+    LastLocalValue = I;
+  }
 
   /// startNewBlock - Set the current block to which generated machine
   /// instructions will be appended, and clear the local CSE map.
@@ -358,6 +371,11 @@
   /// be materialized with new instructions.
   unsigned materializeRegForValue(const Value *V, MVT VT);
 
+  /// flushLocalValueMap - clears LocalValueMap and moves the area for the
+  /// new local variables to the beginning of the block. It helps to avoid
+  /// spilling cached variables across heavy instructions like calls.
+  void flushLocalValueMap();
+
   /// hasTrivialKill - Test whether the given value has exactly one use.
   bool hasTrivialKill(const Value *V) const;
 };

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=137993&r1=137992&r2=137993&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Aug 18 17:06:10 2011
@@ -66,17 +66,22 @@
 void FastISel::startNewBlock() {
   LocalValueMap.clear();
 
-  // Start out as null, meaining no local-value instructions have
-  // been emitted.
-  LastLocalValue = 0;
+  EmitStartPt = 0;
 
-  // Advance the last local value past any EH_LABEL instructions.
+  // Advance the emit start point past any EH_LABEL instructions.
   MachineBasicBlock::iterator
     I = FuncInfo.MBB->begin(), E = FuncInfo.MBB->end();
   while (I != E && I->getOpcode() == TargetOpcode::EH_LABEL) {
-    LastLocalValue = I;
+    EmitStartPt = I;
     ++I;
   }
+  LastLocalValue = EmitStartPt;
+}
+
+void FastISel::flushLocalValueMap() {
+  LocalValueMap.clear();
+  LastLocalValue = EmitStartPt;
+  recomputeInsertPt();
 }
 
 bool FastISel::hasTrivialKill(const Value *V) const {
@@ -645,6 +650,16 @@
   }
   }
 
+  // Usually, it does not make sense to initialize a value,
+  // make an unrelated function call and use the value, because
+  // it tends to be spilled on the stack. So, we move the pointer
+  // to the last local value to the beginning of the block, so that
+  // all the values which have already been materialized,
+  // appear after the call. It also makes sense to skip intrinsics
+  // since they tend to be inlined.
+  if (!isa<IntrinsicInst>(F))
+    flushLocalValueMap();
+
   // An arbitrary call. Bail.
   return false;
 }

Modified: llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll?rev=137993&r1=137992&r2=137993&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/debug-info-blocks.ll Thu Aug 18 17:06:10 2011
@@ -1,5 +1,5 @@
 ; RUN: llc -O0 < %s | FileCheck %s
-; CHECK: @DEBUG_VALUE: mydata <- [sp+#8]+#0
+; CHECK: @DEBUG_VALUE: mydata <- [sp+#4]+#0
 ; Radar 9331779
 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
 target triple = "thumbv7-apple-macosx10.7.0"

Modified: llvm/trunk/test/CodeGen/X86/fast-isel-x86-64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-x86-64.ll?rev=137993&r1=137992&r2=137993&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-x86-64.ll (original)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-x86-64.ll Thu Aug 18 17:06:10 2011
@@ -259,4 +259,27 @@
 ; CHECK: test21:
 ; CHECK-NOT: pxor
 ; CHECK: movsd	LCPI
-}
\ No newline at end of file
+}
+
+; Check that immediate arguments to a function
+; do not cause massive spilling and are used
+; as immediates just before the call.
+define void @test22() nounwind {
+entry:
+  call void @foo22(i32 0)
+  call void @foo22(i32 1)
+  call void @foo22(i32 2)
+  call void @foo22(i32 3)
+  ret void
+; CHECK: test22:
+; CHECK: movl	$0, %edi
+; CHECK: callq	_foo22
+; CHECK: movl	$1, %edi
+; CHECK: callq	_foo22
+; CHECK: movl	$2, %edi
+; CHECK: callq	_foo22
+; CHECK: movl	$3, %edi
+; CHECK: callq	_foo22
+}
+
+declare void @foo22(i32)





More information about the llvm-commits mailing list