*** empty log message ***

llvm-svn: 87524
diff --git a/safecode/include/InsertPoolChecks.h b/safecode/include/InsertPoolChecks.h
index 7331931..4d6c530 100755
--- a/safecode/include/InsertPoolChecks.h
+++ b/safecode/include/InsertPoolChecks.h
@@ -102,6 +102,7 @@
       AU.addRequired<PreInsertPoolChecks>();
       AU.addRequired<ConvertUnsafeAllocas>();
       AU.addRequired<ScalarEvolution>();
+      AU.addRequired<LoopInfo>();
 #if 0
       AU.addRequired<CompleteBUDataStructures>();
       AU.addRequired<TDDataStructures>();
@@ -122,6 +123,7 @@
     PreInsertPoolChecks * preSCPass;
     CUA::ConvertUnsafeAllocas * cuaPass;
     ScalarEvolution * scevPass;
+    LoopInfo *LI;
     TargetData * TD;
 #ifndef  LLVA_KERNEL
     PoolAllocate * paPass;
diff --git a/safecode/lib/InsertPoolChecks/insert.cpp b/safecode/lib/InsertPoolChecks/insert.cpp
index b7e7ae0..b7aaf7c 100755
--- a/safecode/lib/InsertPoolChecks/insert.cpp
+++ b/safecode/lib/InsertPoolChecks/insert.cpp
@@ -22,7 +22,8 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ConstantRange.h"
-
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "llvm/Analysis/LoopInfo.h" 
 #include <iostream>
 #include <vector>
 #include <set>
@@ -76,6 +77,10 @@
                                       cl::init(false),
                                       cl::desc("Disable Intrinsic Checks"));
 
+cl::opt<bool> EnableMonotonicOptimisation("enable-monotonic", cl::Hidden,
+                                          cl::init(false),
+                   cl::desc("Enable LICM for bounds checks on monotonic loops"));
+
 // Options for where to insert various initialization code
 cl::opt<string> InitFunctionName ("initfunc",
                                   cl::desc("Specify name of initialization "
@@ -132,6 +137,9 @@
 // Other statistics
 static Statistic<> StructGEPsRemoved  ("safecode", "Structure GEP Checks Removed");
 
+//MonotonicOpts
+static Statistic<> MonotonicOpts  ("safecode", "Number of monotonic LICM bounds check optimisations");
+
 // The set of values that already have run-time checks
 static std::set<Value *> CheckedValues;
 
@@ -744,7 +752,7 @@
         Instruction* IP = i->getInstruction()->getNext();
         Value* VRP = castTo (i->getInstruction(), VoidPtrType, IP);
         CallInst *len = new CallInst(KmemCachegetSize, VP, "", IP);
-          
+
         args.clear();
         args.push_back (VMP); //MetaPool
         args.push_back (VRP); //object 
@@ -2064,6 +2072,7 @@
   cuaPass   = &getAnalysis<ConvertUnsafeAllocas>();
   TD        = &getAnalysis<TargetData>();
   scevPass  = &getAnalysis<ScalarEvolution>();
+  LI        = &getAnalysis<LoopInfo>();
 #ifdef LLVA_KERNEL  
   TDPass  = &getAnalysis<TDDataStructures>();
 #else
@@ -2820,12 +2829,63 @@
             abort();
           }
         } else {
-          //
-          // Insert a bounds check and use its return value in all subsequent
-          // uses.
-          //
-          Instruction *nextIns = MAI->getNext();
-          insertBoundsCheck (MAI, MAI->getPointerOperand(), MAI, nextIns);
+          // Now check if the GEP is inside a loop with monotonically increasing
+          //loop bounds
+          //We use the LoopInfo Pass this
+          Loop *L = LI->getLoopFor(MAI->getParent());
+          bool monotonicOpt = false;
+          if (L && (MAI->getNumOperands() == 2)) {
+            bool HasConstantItCount = isa<SCEVConstant>(scevPass->getIterationCount(L));
+            Value *vIndex = MAI->getOperand(1);
+            if (Instruction *Index = dyn_cast<Instruction>(vIndex)) {
+              //If it is not an instruction then it must already be loop invariant
+              if (L->isLoopInvariant(MAI->getPointerOperand())) { 
+                SCEVHandle SH = scevPass->getSCEV(Index);
+                if (SH->hasComputableLoopEvolution(L) ||    // Varies predictably
+                    HasConstantItCount) {
+                  if (SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(SH))
+                    if (AR->isAffine()) {
+                      SCEVHandle EntryValue = AR->getStart();
+                      //                      EntryValue->getValueRange().dump();
+                      //                      Index->dump();
+                      SCEVHandle ExitValue = scevPass->getSCEVAtScope(Index, L->getParentLoop());
+                      BasicBlock *Preheader = L->getLoopPreheader();
+                      if (!isa<SCEVCouldNotCompute>(ExitValue)) {
+                        SCEVExpander Rewriter(*scevPass, *LI);
+                        Instruction *ptIns = Preheader->getTerminator();
+                        Value *NewVal = Rewriter.expandCodeFor(ExitValue, ptIns,
+                                                               Index->getType());
+                        //                        NewVal->dump();
+                        if (!isa<SCEVCouldNotCompute>(EntryValue)) {
+                          Value *NewVal2 = Rewriter.expandCodeFor(EntryValue, ptIns,
+                                                                  Index->getType());
+                          //                          NewVal2->dump();
+                          //Inserted the values now insert GEPs and add checks
+                          std::vector<Value *> gepargs1(1,NewVal);
+                          GetElementPtrInst *GEPUpper =
+                            new GetElementPtrInst(MAI->getPointerOperand(), gepargs1, MAI->getName()+"upbc", ptIns);
+                          insertBoundsCheck (MAI, GEPUpper->getPointerOperand(), GEPUpper, ptIns);
+                          std::vector<Value *> gepargs2(1,NewVal2);
+                          GetElementPtrInst *GEPLower =
+                            new GetElementPtrInst(MAI->getPointerOperand(), gepargs2, MAI->getName()+"lobc", ptIns);
+                          insertBoundsCheck (MAI, GEPLower->getPointerOperand(), GEPLower, ptIns);
+                          monotonicOpt = true;
+                          ++MonotonicOpts;
+                        }
+                      }
+                    }
+                }
+              }
+            }
+          }
+          if (!monotonicOpt) {
+            //
+            // Insert a bounds check and use its return value in all subsequent
+            // uses.
+            //
+            Instruction *nextIns = MAI->getNext();
+            insertBoundsCheck (MAI, MAI->getPointerOperand(), MAI, nextIns);
+          }
         }
       }
     } else {