[LLVMdev] LICM/store-aliasing of global loads

Stefanus Du Toit sdt at rapidmind.com
Mon Jul 21 15:51:32 PDT 2008


Our frontend can guarantee that loads from globals are  
rematerializable and do not alias with any stores in any function in  
the given module. We'd like the optimization passes (and ideally the  
register allocator as well) to be able to use this fact. The globals  
are not constant "forever" but are constant during the calling of any  
given function in the module.

There seem to be two major ways to expose this to the optimization  
passes and code gen:
  - build a custom alias analysis pass that indicates that these loads  
never alias with any stores in a given function
  - declare these globals as external constants within the module

The former should give optimizations like LICM the freedom to move  
these loads around, allow them to be CSE'd, etc.

The latter should technically allow the same freedom to these  
optimizations, but doesn't currently seem to. Furthermore, the latter  
should give the RA enough information to rematerialize these loads  
instead of spilling them if necessary.

Below is a simple example module that illustrates this. It's just a  
memcpy loop copying between two external arrays. With unmodified TOT,  
opt -basicaa -licm for example will not move the invariant loads of @b  
and @a (into %tmp3 and %tmp5) out of the body of the for loop.

If I apply the patch found further down, LICM moves the loads out (as  
expected), but of course this is a fairly specific fix.

What's the right way to handle this? Should Basic AA handle this case?  
Will the RA be aware that it can remat these loads or do I need to do  
something else to allow it to know this? Will the scheduler be aware  
that it can reorder them?

Obviously I can also move the loads to the entry block of the  
function, but that does not address the RA/scheduling issues and is  
difficult to do in general due to some additional semantics in our  
frontend.

Thanks!

Stefanus

=== Example ===
@b = external constant float*
@a = external constant float*

define void @test(i32 %count) {
entry:
         br label %forcond

forcond:                ; preds = %forinc, %entry
         %i.0 = phi i32 [ 0, %entry ], [ %inc, %forinc ]         ;  
<i32> [#uses=4]
         %cmp = icmp ult i32 %i.0, %count                ; <i1>  
[#uses=1]
         br i1 %cmp, label %forbody, label %afterfor

forbody:                ; preds = %forcond
         %tmp3 = load float** @b         ; <float*> [#uses=1]
         %arrayidx = getelementptr float* %tmp3, i32 %i. 
0                ; <float*> [#uses=1]
         %tmp5 = load float** @a         ; <float*> [#uses=1]
         %arrayidx6 = getelementptr float* %tmp5, i32 %i. 
0               ; <float*> [#uses=1]
         %tmp7 = load float* %arrayidx6          ; <float> [#uses=1]
         store float %tmp7, float* %arrayidx
         br label %forinc

forinc:         ; preds = %forbody
         %inc = add i32 %i.0, 1          ; <i32> [#uses=1]
         br label %forcond

afterfor:               ; preds = %forcond
         ret void
}

=== Patch ===
Index: lib/Transforms/Scalar/LICM.cpp
===================================================================
--- lib/Transforms/Scalar/LICM.cpp      (revision 53694)
+++ lib/Transforms/Scalar/LICM.cpp      (working copy)
@@ -36,6 +36,7 @@
  #include "llvm/Constants.h"
  #include "llvm/DerivedTypes.h"
  #include "llvm/Instructions.h"
+#include "llvm/GlobalVariable.h"
  #include "llvm/Target/TargetData.h"
  #include "llvm/Analysis/LoopInfo.h"
  #include "llvm/Analysis/LoopPass.h"
@@ -370,6 +371,12 @@
      if (LI->isVolatile())
        return false;        // Don't hoist volatile loads!

+    if (GlobalVariable* gv = dyn_cast<GlobalVariable>(LI- 
 >getOperand(0))) {
+      if (gv->isConstant()) {
+        return true;
+      }
+    }
+
      // Don't hoist loads which have may-aliased stores in loop.
      unsigned Size = 0;
      if (LI->getType()->isSized())


--
Stefanus Du Toit <stefanus.dutoit at rapidmind.com>
   RapidMind Inc.
   phone: +1 519 885 5455 x116 -- fax: +1 519 885 1463






More information about the llvm-dev mailing list