From 20bbac3435bfd7d275d2672f84d5a7e92c8646ed Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 14 Jan 2008 01:17:44 +0000 Subject: [PATCH] Make the 'shrink global to bool' optimization more self contained, and thus easier to show that its safe. No functionality change. llvm-svn: 45946 --- llvm/lib/Transforms/IPO/GlobalOpt.cpp | 35 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index c3c0530bb1c5..4b017507f09f 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -1257,9 +1257,28 @@ static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal, return false; } -/// ShrinkGlobalToBoolean - At this point, we have learned that the only two -/// values ever stored into GV are its initializer and OtherVal. -static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { +/// TryToShrinkGlobalToBoolean - At this point, we have learned that the only +/// two values ever stored into GV are its initializer and OtherVal. See if we +/// can shrink the global into a boolean and select between the two values +/// whenever it is used. This exposes the values to other scalar optimizations. +static bool TryToShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { + const Type *GVElType = GV->getType()->getElementType(); + + // If GVElType is already i1, it is already shrunk. If the type of the GV is + // an FP value or vector, don't do this optimization because a select between + // them is very expensive and unlikely to lead to later simplification. + if (GVElType == Type::Int1Ty || GVElType->isFloatingPoint() || + isa(GVElType)) + return false; + + // Walk the use list of the global seeing if all the uses are load or store. + // If there is anything else, bail out. + for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I) + if (!isa(I) && !isa(I)) + return false; + + DOUT << " *** SHRINKING TO BOOL: " << *GV; + // Create the new global, initializing it to false. GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage, ConstantInt::getFalse(), @@ -1307,7 +1326,7 @@ static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { } } new StoreInst(StoreVal, NewGV, SI); - } else if (!UI->use_empty()) { + } else { // Change the load into a load of bool then a select. LoadInst *LI = cast(UI); LoadInst *NLI = new LoadInst(NewGV, LI->getName()+".b", LI); @@ -1323,6 +1342,7 @@ static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) { } GV->eraseFromParent(); + return true; } @@ -1464,12 +1484,7 @@ 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(GS.StoredOnceValue)) - if (GV->getType()->getElementType() != Type::Int1Ty && - !GV->getType()->getElementType()->isFloatingPoint() && - !isa(GV->getType()->getElementType()) && - !GS.HasPHIUser && !GS.isNotSuitableForSRA) { - DOUT << " *** SHRINKING TO BOOL: " << *GV; - ShrinkGlobalToBoolean(GV, SOVConstant); + if (TryToShrinkGlobalToBoolean(GV, SOVConstant)) { ++NumShrunkToBool; return true; }