Inherit CallGraphSCCPass directly from Pass.
[oota-llvm.git] / lib / Transforms / IPO / GlobalOpt.cpp
index bdec082cd063474d967904a52f5db7fa54921030..d9ba12c7845df9b4371fc53f685c5e358b009c67 100644 (file)
 #include <set>
 using namespace llvm;
 
-namespace {
-  Statistic<> NumMarked   ("globalopt", "Number of globals marked constant");
-  Statistic<> NumSRA      ("globalopt", "Number of aggregate globals broken "
-                           "into scalars");
-  Statistic<> NumHeapSRA  ("globalopt", "Number of heap objects SRA'd");
-  Statistic<> NumSubstitute("globalopt",
-                        "Number of globals with initializers stored into them");
-  Statistic<> NumDeleted  ("globalopt", "Number of globals deleted");
-  Statistic<> NumFnDeleted("globalopt", "Number of functions deleted");
-  Statistic<> NumGlobUses ("globalopt", "Number of global uses devirtualized");
-  Statistic<> NumLocalized("globalopt", "Number of globals localized");
-  Statistic<> NumShrunkToBool("globalopt",
-                              "Number of global vars shrunk to booleans");
-  Statistic<> NumFastCallFns("globalopt",
-                             "Number of functions converted to fastcc");
-  Statistic<> NumCtorsEvaluated("globalopt","Number of static ctors evaluated");
+STATISTIC(NumMarked    , "Number of globals marked constant");
+STATISTIC(NumSRA       , "Number of aggregate globals broken into scalars");
+STATISTIC(NumHeapSRA   , "Number of heap objects SRA'd");
+STATISTIC(NumSubstitute,"Number of globals with initializers stored into them");
+STATISTIC(NumDeleted   , "Number of globals deleted");
+STATISTIC(NumFnDeleted , "Number of functions deleted");
+STATISTIC(NumGlobUses  , "Number of global uses devirtualized");
+STATISTIC(NumLocalized , "Number of globals localized");
+STATISTIC(NumShrunkToBool  , "Number of global vars shrunk to booleans");
+STATISTIC(NumFastCallFns   , "Number of functions converted to fastcc");
+STATISTIC(NumCtorsEvaluated, "Number of static ctors evaluated");
 
+namespace {
   struct GlobalOpt : public ModulePass {
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.addRequired<TargetData>();
@@ -242,7 +238,7 @@ static bool AnalyzeGlobal(Value *V, GlobalStatus &GS,
           if (AnalyzeGlobal(I, GS, PHIUsers)) return true;
         GS.isNotSuitableForSRA = true;
         GS.HasPHIUser = true;
-      } else if (isa<SetCondInst>(I)) {
+      } else if (isa<CmpInst>(I)) {
         GS.isNotSuitableForSRA = true;
       } else if (isa<MemCpyInst>(I) || isa<MemMoveInst>(I)) {
         if (I->getOperand(1) == V)
@@ -329,7 +325,7 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
         if (Init)
           SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
         Changed |= CleanupConstantGlobalUsers(CE, SubInit);
-      } else if (CE->getOpcode() == Instruction::Cast &&
+      } else if (CE->getOpcode() == Instruction::BitCast && 
                  isa<PointerType>(CE->getType())) {
         // Pointer cast, delete any stores and memsets to the global.
         Changed |= CleanupConstantGlobalUsers(CE, 0);
@@ -388,7 +384,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
     NewGlobals.reserve(STy->getNumElements());
     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
       Constant *In = getAggregateConstantElement(Init,
-                                            ConstantInt::get(Type::UIntTy, i));
+                                            ConstantInt::get(Type::Int32Ty, i));
       assert(In && "Couldn't get element of initializer?");
       GlobalVariable *NGV = new GlobalVariable(STy->getElementType(i), false,
                                                GlobalVariable::InternalLinkage,
@@ -410,7 +406,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
     NewGlobals.reserve(NumElements);
     for (unsigned i = 0, e = NumElements; i != e; ++i) {
       Constant *In = getAggregateConstantElement(Init,
-                                            ConstantInt::get(Type::UIntTy, i));
+                                            ConstantInt::get(Type::Int32Ty, i));
       assert(In && "Couldn't get element of initializer?");
 
       GlobalVariable *NGV = new GlobalVariable(STy->getElementType(), false,
@@ -426,7 +422,7 @@ static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
 
   DOUT << "PERFORMING GLOBAL SRA ON: " << *GV;
 
-  Constant *NullInt = Constant::getNullValue(Type::IntTy);
+  Constant *NullInt = Constant::getNullValue(Type::Int32Ty);
 
   // Loop over all of the uses of the global, replacing the constantexpr geps,
   // with smaller constantexpr geps or direct references.
@@ -494,28 +490,28 @@ static bool AllUsesOfValueWillTrapIfNull(Value *V) {
       // Will trap.
     } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
       if (SI->getOperand(0) == V) {
-        //llvm_cerr << "NONTRAPPING USE: " << **UI;
+        //cerr << "NONTRAPPING USE: " << **UI;
         return false;  // Storing the value.
       }
     } else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
       if (CI->getOperand(0) != V) {
-        //llvm_cerr << "NONTRAPPING USE: " << **UI;
+        //cerr << "NONTRAPPING USE: " << **UI;
         return false;  // Not calling the ptr
       }
     } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
       if (II->getOperand(0) != V) {
-        //llvm_cerr << "NONTRAPPING USE: " << **UI;
+        //cerr << "NONTRAPPING USE: " << **UI;
         return false;  // Not calling the ptr
       }
     } else if (CastInst *CI = dyn_cast<CastInst>(*UI)) {
       if (!AllUsesOfValueWillTrapIfNull(CI)) return false;
     } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI)) {
       if (!AllUsesOfValueWillTrapIfNull(GEPI)) return false;
-    } else if (isa<SetCondInst>(*UI) &&
+    } else if (isa<ICmpInst>(*UI) &&
                isa<ConstantPointerNull>(UI->getOperand(1))) {
       // Ignore setcc X, null
     } else {
-      //llvm_cerr << "NONTRAPPING USE: " << **UI;
+      //cerr << "NONTRAPPING USE: " << **UI;
       return false;
     }
   return true;
@@ -533,7 +529,7 @@ static bool AllUsesOfLoadedValueWillTrapIfNull(GlobalVariable *GV) {
       // Ignore stores to the global.
     } else {
       // We don't know or understand this user, bail out.
-      //llvm_cerr << "UNKNOWN USER OF GLOBAL!: " << **UI;
+      //cerr << "UNKNOWN USER OF GLOBAL!: " << **UI;
       return false;
     }
 
@@ -572,7 +568,8 @@ static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
       }
     } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
       Changed |= OptimizeAwayTrappingUsesOfValue(CI,
-                                    ConstantExpr::getCast(NewV, CI->getType()));
+                                ConstantExpr::getCast(CI->getOpcode(),
+                                                      NewV, CI->getType()));
       if (CI->use_empty()) {
         Changed = true;
         CI->eraseFromParent();
@@ -670,7 +667,7 @@ static void ConstantPropUsersOf(Value *V) {
 /// variable, and transforms the program as if it always contained the result of
 /// the specified malloc.  Because it is always the result of the specified
 /// malloc, there is no reason to actually DO the malloc.  Instead, turn the
-/// malloc into a global, and any laods of GV as uses of the new global.
+/// malloc into a global, and any loads of GV as uses of the new global.
 static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
                                                      MallocInst *MI) {
   DOUT << "PROMOTING MALLOC GLOBAL: " << *GV << "  MALLOC = " << *MI;
@@ -682,10 +679,10 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
     Type *NewTy = ArrayType::get(MI->getAllocatedType(),
                                  NElements->getZExtValue());
     MallocInst *NewMI =
-      new MallocInst(NewTy, Constant::getNullValue(Type::UIntTy),
+      new MallocInst(NewTy, Constant::getNullValue(Type::Int32Ty),
                      MI->getAlignment(), MI->getName(), MI);
     std::vector<Value*> Indices;
-    Indices.push_back(Constant::getNullValue(Type::IntTy));
+    Indices.push_back(Constant::getNullValue(Type::Int32Ty));
     Indices.push_back(Indices[0]);
     Value *NewGEP = new GetElementPtrInst(NewMI, Indices,
                                           NewMI->getName()+".el0", MI);
@@ -707,13 +704,14 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
 
   Constant *RepValue = NewGV;
   if (NewGV->getType() != GV->getType()->getElementType())
-    RepValue = ConstantExpr::getCast(RepValue, GV->getType()->getElementType());
+    RepValue = ConstantExpr::getBitCast(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 =
-    new GlobalVariable(Type::BoolTy, false, GlobalValue::InternalLinkage,
-                       ConstantBool::getFalse(), GV->getName()+".init");
+    new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage,
+                       ConstantInt::getFalse(), GV->getName()+".init");
   bool InitBoolUsed = false;
 
   // Loop over all uses of GV, processing them in turn.
@@ -722,36 +720,40 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
     if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
       while (!LI->use_empty()) {
         Use &LoadUse = LI->use_begin().getUse();
-        if (!isa<SetCondInst>(LoadUse.getUser()))
+        if (!isa<ICmpInst>(LoadUse.getUser()))
           LoadUse = RepValue;
         else {
-          // 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);
+          ICmpInst *CI = cast<ICmpInst>(LoadUse.getUser());
+          // Replace the cmp X, 0 with a use of the bool value.
+          Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", CI);
           InitBoolUsed = true;
-          switch (SCI->getOpcode()) {
-          default: assert(0 && "Unknown opcode!");
-          case Instruction::SetLT:
-            LV = ConstantBool::getFalse();   // X < null -> always false
+          switch (CI->getPredicate()) {
+          default: assert(0 && "Unknown ICmp Predicate!");
+          case ICmpInst::ICMP_ULT:
+          case ICmpInst::ICMP_SLT:
+            LV = ConstantInt::getFalse();   // X < null -> always false
             break;
-          case Instruction::SetEQ:
-          case Instruction::SetLE:
-            LV = BinaryOperator::createNot(LV, "notinit", SCI);
+          case ICmpInst::ICMP_ULE:
+          case ICmpInst::ICMP_SLE:
+          case ICmpInst::ICMP_EQ:
+            LV = BinaryOperator::createNot(LV, "notinit", CI);
             break;
-          case Instruction::SetNE:
-          case Instruction::SetGE:
-          case Instruction::SetGT:
+          case ICmpInst::ICMP_NE:
+          case ICmpInst::ICMP_UGE:
+          case ICmpInst::ICMP_SGE:
+          case ICmpInst::ICMP_UGT:
+          case ICmpInst::ICMP_SGT:
             break;  // no change.
           }
-          SCI->replaceAllUsesWith(LV);
-          SCI->eraseFromParent();
+          CI->replaceAllUsesWith(LV);
+          CI->eraseFromParent();
         }
       }
       LI->eraseFromParent();
     } else {
       StoreInst *SI = cast<StoreInst>(GV->use_back());
       // The global is initialized when the store to it occurs.
-      new StoreInst(ConstantBool::getTrue(), InitBool, SI);
+      new StoreInst(ConstantInt::getTrue(), InitBool, SI);
       SI->eraseFromParent();
     }
 
@@ -785,7 +787,7 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
 static bool ValueIsOnlyUsedLocallyOrStoredToOneGlobal(Instruction *V,
                                                       GlobalVariable *GV) {
   for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI)
-    if (isa<LoadInst>(*UI) || isa<SetCondInst>(*UI)) {
+    if (isa<LoadInst>(*UI) || isa<CmpInst>(*UI)) {
       // Fine, ignore.
     } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
       if (SI->getOperand(0) == V && SI->getOperand(1) != GV)
@@ -834,8 +836,8 @@ static bool GlobalLoadUsesSimpleEnoughForHeapSRA(GlobalVariable *GV) {
       for (Value::use_iterator UI = LI->use_begin(), E = LI->use_end(); UI != E; 
            ++UI) {
         // Comparison against null is ok.
-        if (SetCondInst *SCI = dyn_cast<SetCondInst>(*UI)) {
-          if (!isa<ConstantPointerNull>(SCI->getOperand(1)))
+        if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
+          if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
             return false;
           continue;
         }
@@ -867,7 +869,7 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Ptr,
     Instruction *User = Ptr->use_back();
     
     // If this is a comparison against null, handle it.
-    if (SetCondInst *SCI = dyn_cast<SetCondInst>(User)) {
+    if (ICmpInst *SCI = dyn_cast<ICmpInst>(User)) {
       assert(isa<ConstantPointerNull>(SCI->getOperand(1)));
       // If we have a setcc of the loaded pointer, we can use a setcc of any
       // field.
@@ -879,9 +881,9 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Ptr,
         NPtr = InsertedLoadsForPtr.back();
       }
       
-      Value *New = new SetCondInst(SCI->getOpcode(), NPtr,
-                                   Constant::getNullValue(NPtr->getType()),
-                                   SCI->getName(), SCI);
+      Value *New = new ICmpInst(SCI->getPredicate(), NPtr,
+                                Constant::getNullValue(NPtr->getType()),
+                                SCI->getName(), SCI);
       SCI->replaceAllUsesWith(New);
       SCI->eraseFromParent();
       continue;
@@ -890,7 +892,6 @@ static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Ptr,
     // Otherwise, this should be: 'getelementptr Ptr, Idx, uint FieldNo ...'
     GetElementPtrInst *GEPI = cast<GetElementPtrInst>(User);
     assert(GEPI->getNumOperands() >= 3 && isa<ConstantInt>(GEPI->getOperand(2))
-           && GEPI->getOperand(2)->getType()->isUnsigned()
            && "Unexpected GEPI!");
     
     // Load the pointer for this field.
@@ -961,7 +962,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
   //    }
   Value *RunningOr = 0;
   for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) {
-    Value *Cond = new SetCondInst(Instruction::SetEQ, FieldMallocs[i],
+    Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, FieldMallocs[i],
                              Constant::getNullValue(FieldMallocs[i]->getType()),
                                   "isnull", MI);
     if (!RunningOr)
@@ -988,9 +989,9 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
   // pointer, because some may be null while others are not.
   for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
     Value *GVVal = new LoadInst(FieldGlobals[i], "tmp", NullPtrBlock);
-    Value *Cmp = new SetCondInst(Instruction::SetNE, GVVal, 
-                                 Constant::getNullValue(GVVal->getType()),
-                                 "tmp", NullPtrBlock);
+    Value *Cmp = new ICmpInst(ICmpInst::ICMP_NE, GVVal, 
+                              Constant::getNullValue(GVVal->getType()),
+                              "tmp", NullPtrBlock);
     BasicBlock *FreeBlock = new BasicBlock("free_it", OrigBB->getParent());
     BasicBlock *NextBlock = new BasicBlock("next", OrigBB->getParent());
     new BranchInst(FreeBlock, NextBlock, Cmp, NullPtrBlock);
@@ -1015,9 +1016,25 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
   // loads, and all uses of those loads are simple.  Rewrite them to use loads
   // of the per-field globals instead.
   while (!GV->use_empty()) {
-    LoadInst *LI = cast<LoadInst>(GV->use_back());
-    RewriteUsesOfLoadForHeapSRoA(LI, FieldGlobals);
-    LI->eraseFromParent();
+    if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
+      RewriteUsesOfLoadForHeapSRoA(LI, FieldGlobals);
+      LI->eraseFromParent();
+    } else {
+      // Must be a store of null.
+      StoreInst *SI = cast<StoreInst>(GV->use_back());
+      assert(isa<Constant>(SI->getOperand(0)) &&
+             cast<Constant>(SI->getOperand(0))->isNullValue() &&
+             "Unexpected heap-sra user!");
+      
+      // Insert a store of null into each global.
+      for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
+        Constant *Null = 
+          Constant::getNullValue(FieldGlobals[i]->getType()->getElementType());
+        new StoreInst(Null, FieldGlobals[i], SI);
+      }
+      // Erase the original store.
+      SI->eraseFromParent();
+    }
   }
 
   // The old global is now dead, remove it.
@@ -1056,7 +1073,7 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
       GV->getInitializer()->isNullValue()) {
     if (Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
       if (GV->getInitializer()->getType() != SOVC->getType())
-        SOVC = ConstantExpr::getCast(SOVC, GV->getInitializer()->getType());
+        SOVC = ConstantExpr::getBitCast(SOVC, GV->getInitializer()->getType());
 
       // Optimize away any trapping uses of the loaded value.
       if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC))
@@ -1122,13 +1139,13 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
 /// values ever stored into GV are its initializer and OtherVal.
 static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
   // Create the new global, initializing it to false.
-  GlobalVariable *NewGV = new GlobalVariable(Type::BoolTy, false,
-         GlobalValue::InternalLinkage, ConstantBool::getFalse(),
+  GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false,
+         GlobalValue::InternalLinkage, ConstantInt::getFalse(),
                                              GV->getName()+".b");
   GV->getParent()->getGlobalList().insert(GV, NewGV);
 
   Constant *InitVal = GV->getInitializer();
-  assert(InitVal->getType() != Type::BoolTy && "No reason to shrink to bool!");
+  assert(InitVal->getType() != Type::Int1Ty && "No reason to shrink to bool!");
 
   // If initialized to zero and storing one into the global, we can use a cast
   // instead of a select to synthesize the desired value.
@@ -1144,7 +1161,7 @@ static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
       // Only do this if we weren't storing a loaded value.
       Value *StoreVal;
       if (StoringOther || SI->getOperand(0) == InitVal)
-        StoreVal = ConstantBool::get(StoringOther);
+        StoreVal = ConstantInt::get(Type::Int1Ty, StoringOther);
       else {
         // Otherwise, we are storing a previously loaded copy.  To do this,
         // change the copy from copying the original value to just copying the
@@ -1174,7 +1191,7 @@ static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
       LoadInst *NLI = new LoadInst(NewGV, Name+".b", LI);
       Value *NSI;
       if (IsOneZero)
-        NSI = new CastInst(NLI, LI->getType(), Name, LI);
+        NSI = new ZExtInst(NLI, LI->getType(), Name, LI);
       else
         NSI = new SelectInst(NLI, OtherVal, InitVal, Name, LI);
       LI->replaceAllUsesWith(NSI);
@@ -1203,25 +1220,25 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
 
   if (!AnalyzeGlobal(GV, GS, PHIUsers)) {
 #if 0
-    llvm_cerr << "Global: " << *GV;
-    llvm_cerr << "  isLoaded = " << GS.isLoaded << "\n";
-    llvm_cerr << "  StoredType = ";
+    cerr << "Global: " << *GV;
+    cerr << "  isLoaded = " << GS.isLoaded << "\n";
+    cerr << "  StoredType = ";
     switch (GS.StoredType) {
-    case GlobalStatus::NotStored: llvm_cerr << "NEVER STORED\n"; break;
-    case GlobalStatus::isInitializerStored: llvm_cerr << "INIT STORED\n"; break;
-    case GlobalStatus::isStoredOnce: llvm_cerr << "STORED ONCE\n"; break;
-    case GlobalStatus::isStored: llvm_cerr << "stored\n"; break;
+    case GlobalStatus::NotStored: cerr << "NEVER STORED\n"; break;
+    case GlobalStatus::isInitializerStored: cerr << "INIT STORED\n"; break;
+    case GlobalStatus::isStoredOnce: cerr << "STORED ONCE\n"; break;
+    case GlobalStatus::isStored: cerr << "stored\n"; break;
     }
     if (GS.StoredType == GlobalStatus::isStoredOnce && GS.StoredOnceValue)
-      llvm_cerr << "  StoredOnceValue = " << *GS.StoredOnceValue << "\n";
+      cerr << "  StoredOnceValue = " << *GS.StoredOnceValue << "\n";
     if (GS.AccessingFunction && !GS.HasMultipleAccessingFunctions)
-      llvm_cerr << "  AccessingFunction = " << GS.AccessingFunction->getName()
+      cerr << "  AccessingFunction = " << GS.AccessingFunction->getName()
                 << "\n";
-    llvm_cerr << "  HasMultipleAccessingFunctions =  "
+    cerr << "  HasMultipleAccessingFunctions =  "
               << GS.HasMultipleAccessingFunctions << "\n";
-    llvm_cerr << "  HasNonInstructionUser = " << GS.HasNonInstructionUser<<"\n";
-    llvm_cerr << "  isNotSuitableForSRA = " << GS.isNotSuitableForSRA << "\n";
-    llvm_cerr << "\n";
+    cerr << "  HasNonInstructionUser = " << GS.HasNonInstructionUser<<"\n";
+    cerr << "  isNotSuitableForSRA = " << GS.isNotSuitableForSRA << "\n";
+    cerr << "\n";
 #endif
     
     // If this is a first class global and has only one accessing function
@@ -1324,8 +1341,9 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
       // Otherwise, if the global was not a boolean, we can shrink it to be a
       // boolean.
       if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue))
-        if (GV->getType()->getElementType() != Type::BoolTy &&
+        if (GV->getType()->getElementType() != Type::Int1Ty &&
             !GV->getType()->getElementType()->isFloatingPoint() &&
+            !isa<PackedType>(GV->getType()->getElementType()) &&
             !GS.HasPHIUser) {
           DOUT << "   *** SHRINKING TO BOOL: " << *GV;
           ShrinkGlobalToBoolean(GV, SOVConstant);
@@ -1413,7 +1431,7 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) {
       if (!ATy) return 0;
       const StructType *STy = dyn_cast<StructType>(ATy->getElementType());
       if (!STy || STy->getNumElements() != 2 ||
-          STy->getElementType(0) != Type::IntTy) return 0;
+          STy->getElementType(0) != Type::Int32Ty) return 0;
       const PointerType *PFTy = dyn_cast<PointerType>(STy->getElementType(1));
       if (!PFTy) return 0;
       const FunctionType *FTy = dyn_cast<FunctionType>(PFTy->getElementType());
@@ -1466,7 +1484,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
                                           const std::vector<Function*> &Ctors) {
   // If we made a change, reassemble the initializer list.
   std::vector<Constant*> CSVals;
-  CSVals.push_back(ConstantInt::get(Type::IntTy, 65535));
+  CSVals.push_back(ConstantInt::get(Type::Int32Ty, 65535));
   CSVals.push_back(0);
   
   // Create the new init list.
@@ -1479,7 +1497,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
                                           std::vector<const Type*>(), false);
       const PointerType *PFTy = PointerType::get(FTy);
       CSVals[1] = Constant::getNullValue(PFTy);
-      CSVals[0] = ConstantInt::get(Type::IntTy, 2147483647);
+      CSVals[0] = ConstantInt::get(Type::Int32Ty, 2147483647);
     }
     CAList.push_back(ConstantStruct::get(CSVals));
   }
@@ -1507,7 +1525,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
   if (!GCL->use_empty()) {
     Constant *V = NGV;
     if (V->getType() != GCL->getType())
-      V = ConstantExpr::getCast(V, GCL->getType());
+      V = ConstantExpr::getBitCast(V, GCL->getType());
     GCL->replaceAllUsesWith(V);
   }
   GCL->eraseFromParent();
@@ -1712,8 +1730,13 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
       InstResult = ConstantExpr::get(SI->getOpcode(),
                                      getVal(Values, SI->getOperand(0)),
                                      getVal(Values, SI->getOperand(1)));
+    } else if (CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
+      InstResult = ConstantExpr::getCompare(CI->getPredicate(),
+                                            getVal(Values, CI->getOperand(0)),
+                                            getVal(Values, CI->getOperand(1)));
     } else if (CastInst *CI = dyn_cast<CastInst>(CurInst)) {
-      InstResult = ConstantExpr::getCast(getVal(Values, CI->getOperand(0)),
+      InstResult = ConstantExpr::getCast(CI->getOpcode(),
+                                         getVal(Values, CI->getOperand(0)),
                                          CI->getType());
     } else if (SelectInst *SI = dyn_cast<SelectInst>(CurInst)) {
       InstResult = ConstantExpr::getSelect(getVal(Values, SI->getOperand(0)),
@@ -1775,10 +1798,11 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
         if (BI->isUnconditional()) {
           NewBB = BI->getSuccessor(0);
         } else {
-          ConstantBool *Cond =
-            dyn_cast<ConstantBool>(getVal(Values, BI->getCondition()));
+          ConstantInt *Cond =
+            dyn_cast<ConstantInt>(getVal(Values, BI->getCondition()));
           if (!Cond) return false;  // Cannot determine.
-          NewBB = BI->getSuccessor(!Cond->getValue());          
+
+          NewBB = BI->getSuccessor(!Cond->getZExtValue());          
         }
       } else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurInst)) {
         ConstantInt *Val =