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

Chris Lattner lattner at cs.uiuc.edu
Thu Oct 21 23:43:39 PDT 2004



Changes in directory llvm/lib/Transforms/IPO:

GlobalOpt.cpp updated: 1.25 -> 1.26
---
Log message:



---
Diffs of the changes:  (+47 -4)

Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp
diff -u llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.25 llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.26
--- llvm/lib/Transforms/IPO/GlobalOpt.cpp:1.25	Sat Oct 16 13:09:00 2004
+++ llvm/lib/Transforms/IPO/GlobalOpt.cpp	Fri Oct 22 01:43:28 2004
@@ -458,6 +458,9 @@
       if (!AllUsesOfValueWillTrapIfNull(CI)) return false;
     } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI)) {
       if (!AllUsesOfValueWillTrapIfNull(GEPI)) return false;
+    } else if (isa<SetCondInst>(*UI) && 
+               isa<ConstantPointerNull>(UI->getOperand(1))) {
+      // Ignore setcc X, null
     } else {
       //std::cerr << "NONTRAPPING USE: " << **UI;
       return false;
@@ -466,7 +469,8 @@
 }
 
 /// AllUsesOfLoadedValueWillTrapIfNull - Return true if all uses of any loads
-/// from GV will trap if the loaded value is null.
+/// from GV will trap if the loaded value is null.  Note that this also permits
+/// comparisons of the loaded value against null, as a special case.
 static bool AllUsesOfLoadedValueWillTrapIfNull(GlobalVariable *GV) {
   for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); UI!=E; ++UI)
     if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
@@ -653,24 +657,63 @@
   
   // Anything that used the malloc now uses the global directly.
   MI->replaceAllUsesWith(NewGV);
-  MI->eraseFromParent();
 
   Constant *RepValue = NewGV;
   if (NewGV->getType() != GV->getType()->getElementType())
     RepValue = ConstantExpr::getCast(RepValue, GV->getType()->getElementType());
 
+  // If there is a comparison against null, we will insert a global bool to
+  // keep track of whether the global was initialized yet or not.
+  GlobalVariable *InitBool = 0;
+
   // Loop over all uses of GV, processing them in turn.
   while (!GV->use_empty())
     if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
-      LI->replaceAllUsesWith(RepValue);
+      while (!LI->use_empty()) {
+        // FIXME: the iterator should expose a getUse() method.
+        Use &LoadUse = *(const iplist<Use>::iterator&)LI->use_begin();
+        if (!isa<SetCondInst>(LoadUse.getUser()))
+          LoadUse = RepValue;
+        else {
+          if (InitBool == 0) {
+            InitBool = new GlobalVariable(Type::BoolTy, false,
+                                          GlobalValue::InternalLinkage, 
+                                          ConstantBool::False,
+                                          GV->getName()+".init");
+            GV->getParent()->getGlobalList().insert(GV, InitBool);
+            // The global is initialized when the malloc is run.
+            new StoreInst(ConstantBool::True, InitBool, MI);
+          }
+          // Replace the setcc X, 0 with a use of the bool value.
+          SetCondInst *SCI = cast<SetCondInst>(LoadUse.getUser());
+          Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", SCI);
+          switch (SCI->getOpcode()) {
+          default: assert(0 && "Unknown opcode!");
+          case Instruction::SetLT:
+            LV = ConstantBool::False;   // X < null -> always false
+            break;
+          case Instruction::SetEQ:
+          case Instruction::SetLE:
+            LV = BinaryOperator::createNot(LV, "notinit", SCI);
+            break;
+          case Instruction::SetNE:
+          case Instruction::SetGE:
+          case Instruction::SetGT:
+            break;  // no change.
+          }
+          SCI->replaceAllUsesWith(LV);
+          SCI->eraseFromParent();
+        }
+      }
       LI->eraseFromParent();
     } else {
       StoreInst *SI = cast<StoreInst>(GV->use_back());
       SI->eraseFromParent();
     }
 
-  // Now the GV is dead, nuke it.
+  // Now the GV is dead, nuke it and the malloc.
   GV->eraseFromParent();
+  MI->eraseFromParent();
 
   // To further other optimizations, loop over all users of NewGV and try to
   // constant prop them.  This will promote GEP instructions with constant






More information about the llvm-commits mailing list