[llvm-commits] CVS: llvm/lib/Transforms/Scalar/LICM.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Mar 14 22:12:01 PST 2004


Changes in directory llvm/lib/Transforms/Scalar:

LICM.cpp updated: 1.56 -> 1.57

---
Log message:

Implement LICM of calls in simple cases.  This is sufficient to move around
sin/cos/strlen calls and stuff.  This implements: 
  LICM/call_sink_pure_function.ll
  LICM/call_sink_const_function.ll


---
Diffs of the changes:  (+31 -1)

Index: llvm/lib/Transforms/Scalar/LICM.cpp
diff -u llvm/lib/Transforms/Scalar/LICM.cpp:1.56 llvm/lib/Transforms/Scalar/LICM.cpp:1.57
--- llvm/lib/Transforms/Scalar/LICM.cpp:1.56	Mon Feb  2 14:09:22 2004
+++ llvm/lib/Transforms/Scalar/LICM.cpp	Sun Mar 14 22:11:30 2004
@@ -57,6 +57,7 @@
   Statistic<> NumSunk("licm", "Number of instructions sunk out of loop");
   Statistic<> NumHoisted("licm", "Number of instructions hoisted out of loop");
   Statistic<> NumMovedLoads("licm", "Number of load insts hoisted or sunk");
+  Statistic<> NumMovedCalls("licm", "Number of call insts hoisted or sunk");
   Statistic<> NumPromoted("licm",
                           "Number of memory locations promoted to registers");
 
@@ -360,9 +361,35 @@
 
     // Don't hoist loads which have may-aliased stores in loop.
     return !pointerInvalidatedByLoop(LI->getOperand(0));
+  } else if (CallInst *CI = dyn_cast<CallInst>(&I)) {
+    // Handle obvious cases efficiently.
+    if (Function *Callee = CI->getCalledFunction()) {
+      if (AA->doesNotAccessMemory(Callee))
+        return true;
+      else if (AA->onlyReadsMemory(Callee)) {
+        // If this call only reads from memory and there are no writes to memory
+        // in the loop, we can hoist or sink the call as appropriate.
+        bool FoundMod = false;
+        for (AliasSetTracker::iterator I = CurAST->begin(), E = CurAST->end();
+             I != E; ++I) {
+          AliasSet &AS = *I;
+          if (!AS.isForwardingAliasSet() && AS.isMod()) {
+            FoundMod = true;
+            break;
+          }
+        }
+        if (!FoundMod) return true;
+      }
+    }
+
+    // FIXME: This should use mod/ref information to see if we can hoist or sink
+    // the call.
+    
+    return false;
   }
 
   return isa<BinaryOperator>(I) || isa<ShiftInst>(I) || isa<CastInst>(I) || 
+         isa<SelectInst>(I) ||
          isa<GetElementPtrInst>(I) || isa<VANextInst>(I) || isa<VAArgInst>(I);
 }
 
@@ -412,6 +439,7 @@
   const std::vector<BasicBlock*> &ExitBlocks = CurLoop->getExitBlocks();
 
   if (isa<LoadInst>(I)) ++NumMovedLoads;
+  else if (isa<CallInst>(I)) ++NumMovedCalls;
   ++NumSunk;
   Changed = true;
 
@@ -541,6 +569,7 @@
   Preheader->getInstList().insert(Preheader->getTerminator(), &I);
   
   if (isa<LoadInst>(I)) ++NumMovedLoads;
+  else if (isa<CallInst>(I)) ++NumMovedCalls;
   ++NumHoisted;
   Changed = true;
 }
@@ -679,7 +708,8 @@
        I != E; ++I) {
     AliasSet &AS = *I;
     // We can promote this alias set if it has a store, if it is a "Must" alias
-    // set, if the pointer is loop invariant, if if we are not eliminating any volatile loads or stores.
+    // set, if the pointer is loop invariant, if if we are not eliminating any
+    // volatile loads or stores.
     if (!AS.isForwardingAliasSet() && AS.isMod() && AS.isMustAlias() &&
         !AS.isVolatile() && isLoopInvariant(AS.begin()->first)) {
       assert(AS.begin() != AS.end() &&





More information about the llvm-commits mailing list