[llvm-commits] CVS: llvm/lib/Transforms/IPO/GlobalOpt.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Sep 26 10:07:20 PDT 2005



Changes in directory llvm/lib/Transforms/IPO:

GlobalOpt.cpp updated: 1.51 -> 1.52
---
Log message:

Add support for alloca, implementing ctor-list-opt.ll:CTOR6


---
Diffs of the changes:  (+48 -17)

 GlobalOpt.cpp |   65 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 48 insertions(+), 17 deletions(-)


Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp
diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.51 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.52
--- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.51	Mon Sep 26 02:34:35 2005
+++ llvm/lib/Transforms/IPO/GlobalOpt.cpp	Mon Sep 26 12:07:09 2005
@@ -1380,21 +1380,28 @@
   /// we can only evaluate any one basic block at most once.  This set keeps
   /// track of what we have executed so we can detect recursive cases etc.
   std::set<BasicBlock*> ExecutedBlocks;
+  
+  /// AllocaTmps - To 'execute' an alloca, we create a temporary global variable
+  /// to represent its body.  This allows us to delete the temporary globals
+  /// when we are done.
+  std::vector<GlobalVariable*> AllocaTmps;
 
   // CurInst - The current instruction we're evaluating.
   BasicBlock::iterator CurInst = F->begin()->begin();
   ExecutedBlocks.insert(F->begin());
   
+  bool EvaluationSuccessful = false;
+  
   // This is the main evaluation loop.
   while (1) {
     Constant *InstResult = 0;
     
     if (StoreInst *SI = dyn_cast<StoreInst>(CurInst)) {
-      if (SI->isVolatile()) return false;  // no volatile accesses.
+      if (SI->isVolatile()) break;  // no volatile accesses.
       Constant *Ptr = getVal(Values, SI->getOperand(1));
       if (!isSimpleEnoughPointerToCommit(Ptr))
         // If this is too complex for us to commit, reject it.
-        return false;
+        break;
       Constant *Val = getVal(Values, SI->getOperand(0));
       MutatedMemory[Ptr] = Val;
     } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) {
@@ -1419,10 +1426,18 @@
         GEPOps.push_back(getVal(Values, GEP->getOperand(i)));
       InstResult = ConstantExpr::getGetElementPtr(P, GEPOps);
     } else if (LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {
-      if (LI->isVolatile()) return false;  // no volatile accesses.
+      if (LI->isVolatile()) break;  // no volatile accesses.
       InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)),
                                      MutatedMemory);
-      if (InstResult == 0) return false; // Could not evaluate load.
+      if (InstResult == 0) break; // Could not evaluate load.
+    } else if (AllocaInst *AI = dyn_cast<AllocaInst>(CurInst)) {
+      if (AI->isArrayAllocation()) break;  // Cannot handle array allocs.
+      const Type *Ty = AI->getType()->getElementType();
+      AllocaTmps.push_back(new GlobalVariable(Ty, false,
+                                              GlobalValue::InternalLinkage,
+                                              UndefValue::get(Ty),
+                                              AI->getName()));
+      InstResult = AllocaTmps.back();      
     } else if (TerminatorInst *TI = dyn_cast<TerminatorInst>(CurInst)) {
       BasicBlock *NewBB = 0;
       if (BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {
@@ -1431,27 +1446,28 @@
         } else {
           ConstantBool *Cond =
             dyn_cast<ConstantBool>(getVal(Values, BI->getCondition()));
-          if (!Cond) return false;  // Cannot determine.
+          if (!Cond) break;  // Cannot determine.
           NewBB = BI->getSuccessor(!Cond->getValue());          
         }
       } else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurInst)) {
         ConstantInt *Val =
           dyn_cast<ConstantInt>(getVal(Values, SI->getCondition()));
-        if (!Val) return false;  // Cannot determine.
+        if (!Val) break;  // Cannot determine.
         NewBB = SI->getSuccessor(SI->findCaseValue(Val));
       } else if (ReturnInst *RI = dyn_cast<ReturnInst>(CurInst)) {
         assert(RI->getNumOperands() == 0);
+        EvaluationSuccessful = true;
         break;  // We succeeded at evaluating this ctor!
       } else {
         // unwind, unreachable.
-        return false;  // Cannot handle this terminator.
+        break;  // Cannot handle this terminator.
       }
       
       // Okay, we succeeded in evaluating this control flow.  See if we have
       // executed the new block before.  If so, we have a looping or recursive
       // function, which we cannot evaluate in reasonable time.
       if (!ExecutedBlocks.insert(NewBB).second)
-        return false;  // Recursed!
+        break;  // Recursed/looped!
       
       // Okay, we have never been in this block before.  Check to see if there
       // are any PHI nodes.  If so, evaluate them with information about where
@@ -1468,7 +1484,7 @@
       // TODO: use ConstantFoldCall for function calls.
       
       // Did not know how to evaluate this!
-      return false;
+      break;
     }
     
     if (!CurInst->use_empty())
@@ -1477,16 +1493,31 @@
     // Advance program counter.
     ++CurInst;
   }
+
+  if (EvaluationSuccessful) {
+    // We succeeded at evaluation: commit the result.
+    DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" <<
+          F->getName() << "'\n");
+    for (std::map<Constant*, Constant*>::iterator I = MutatedMemory.begin(),
+         E = MutatedMemory.end(); I != E; ++I)
+      CommitValueTo(I->second, I->first);
+  }
   
-  // If we get here, we know that we succeeded at evaluation: commit the result.
-  //
-  for (std::map<Constant*, Constant*>::iterator I = MutatedMemory.begin(),
-       E = MutatedMemory.end(); I != E; ++I)
-    CommitValueTo(I->second, I->first);
+  // At this point, we are done interpreting.  If we created any 'alloca'
+  // temporaries, release them now.
+  while (!AllocaTmps.empty()) {
+    GlobalVariable *Tmp = AllocaTmps.back();
+    AllocaTmps.pop_back();
+
+    // If there are still users of the alloca, the program is doing something
+    // silly, e.g. storing the address of the alloca somewhere and using it
+    // later.  Since this is undefined, we'll just make it be null.
+    if (!Tmp->use_empty())
+      Tmp->replaceAllUsesWith(Constant::getNullValue(Tmp->getType()));
+    delete Tmp;
+  }
   
-  DEBUG(std::cerr << "FULLY EVALUATED GLOBAL CTOR FUNCTION '" <<
-        F->getName() << "'\n");
-  return true;
+  return EvaluationSuccessful;
 }
 
 






More information about the llvm-commits mailing list