Add comment.
[oota-llvm.git] / lib / Transforms / Scalar / LICM.cpp
index e461c887ea2b36afd56fffe608c7d5fc0a1039da..33bfbf0a7ac58b1d7e7c37afe82f89a84fce6ac0 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -84,6 +84,11 @@ namespace {
     }
 
     bool doFinalization() {
+      // Free the values stored in the map
+      for (std::map<Loop *, AliasSetTracker *>::iterator
+             I = LoopToAliasMap.begin(), E = LoopToAliasMap.end(); I != E; ++I)
+        delete I->second;
+
       LoopToAliasMap.clear();
       return false;
     }
@@ -366,28 +371,26 @@ bool LICM::canSinkOrHoistInst(Instruction &I) {
     // Don't hoist loads which have may-aliased stores in loop.
     unsigned Size = 0;
     if (LI->getType()->isSized())
-      Size = AA->getTargetData().getTypeSize(LI->getType());
+      Size = AA->getTargetData().getTypeStoreSize(LI->getType());
     return !pointerInvalidatedByLoop(LI->getOperand(0), Size);
   } else if (CallInst *CI = dyn_cast<CallInst>(&I)) {
     // Handle obvious cases efficiently.
-    if (Function *Callee = CI->getCalledFunction()) {
-      AliasAnalysis::ModRefBehavior Behavior =AA->getModRefBehavior(Callee, CI);
-      if (Behavior == AliasAnalysis::DoesNotAccessMemory)
-        return true;
-      else if (Behavior == AliasAnalysis::OnlyReadsMemory) {
-        // 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;
-          }
+    AliasAnalysis::ModRefBehavior Behavior = AA->getModRefBehavior(CI);
+    if (Behavior == AliasAnalysis::DoesNotAccessMemory)
+      return true;
+    else if (Behavior == AliasAnalysis::OnlyReadsMemory) {
+      // 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;
       }
+      if (!FoundMod) return true;
     }
 
     // FIXME: This should use mod/ref information to see if we can hoist or sink
@@ -473,7 +476,7 @@ void LICM::sink(Instruction &I) {
       while (isa<PHINode>(InsertPt)) ++InsertPt;
       ExitBlocks[0]->getInstList().insert(InsertPt, &I);
     }
-  } else if (ExitBlocks.size() == 0) {
+  } else if (ExitBlocks.empty()) {
     // The instruction is actually dead if there ARE NO exit blocks.
     CurAST->deleteValue(&I);
     if (!I.use_empty())  // If I has users in unreachable blocks, eliminate.
@@ -786,7 +789,7 @@ void LICM::FindPromotableValuesInLoop(
     // volatile loads or stores.
     if (!AS.isForwardingAliasSet() && AS.isMod() && AS.isMustAlias() &&
         !AS.isVolatile() && CurLoop->isLoopInvariant(AS.begin()->first)) {
-      assert(AS.begin() != AS.end() &&
+      assert(!AS.empty() &&
              "Must alias set should have at least one pointer element in it!");
       Value *V = AS.begin()->first;
 
@@ -800,24 +803,15 @@ void LICM::FindPromotableValuesInLoop(
           break;
         }
 
-      // Do not promote null values because it may be unsafe to do so.
-      if (isa<ConstantPointerNull>(V))
-        PointerOk = false;
-
-      if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
-        // If GEP base is NULL then the calculated address used by Store or
-        // Load instruction is invalid. Do not promote this value because
-        // it may expose load and store instruction that are covered by
-        // condition which may not yet folded.
-        if (isa<ConstantPointerNull>(GEP->getOperand(0)))
-          PointerOk = false;
-      }
-
-      // If value V use is not dominating loop exit then promoting
-      // it may expose unsafe load and store instructions unconditinally.
-      if (PointerOk)
+      // If one use of value V inside the loop is safe then it is OK to promote 
+      // this value. On the otherside if there is not any unsafe use inside the
+      // loop then also it is OK to promote this value. Otherwise it is
+      // unsafe to promote this value.
+      if (PointerOk) {
+        bool oneSafeUse = false;
+        bool oneUnsafeUse = false;
         for(Value::use_iterator UI = V->use_begin(), UE = V->use_end();
-            UI != UE && PointerOk; ++UI) {
+            UI != UE; ++UI) {
           Instruction *Use = dyn_cast<Instruction>(*UI);
           if (!Use || !CurLoop->contains(Use->getParent()))
             continue;
@@ -825,16 +819,25 @@ void LICM::FindPromotableValuesInLoop(
                  ExitI = LoopExits.begin(), ExitE = LoopExits.end();
                ExitI != ExitE; ++ExitI) {
             Instruction *Ex = *ExitI;
-            if (!DT->dominates(Use, Ex)){
-              PointerOk = false;
+            if (!isa<PHINode>(Use) && DT->dominates(Use, Ex)) {
+              oneSafeUse = true;
               break;
             }
+            else 
+              oneUnsafeUse = true;
           }
-          
-          if (!PointerOk)
+
+          if (oneSafeUse)
             break;
         }
-      
+
+        if (oneSafeUse)
+          PointerOk = true;
+        else if (!oneUnsafeUse)
+          PointerOk = true;
+        else
+          PointerOk = false;
+      }
       
       if (PointerOk) {
         const Type *Ty = cast<PointerType>(V->getType())->getElementType();