[llvm-commits] CVS: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp FunctionResolution.cpp GlobalDCE.cpp Internalize.cpp PoolAllocate.cpp

John Criswell criswell at choi.cs.uiuc.edu
Thu Jun 26 16:44:29 PDT 2003


Changes in directory llvm/lib/Transforms/IPO:

DeadArgumentElimination.cpp added (r1.3.2.1)
FunctionResolution.cpp updated: 1.31 -> 1.31.2.1
GlobalDCE.cpp updated: 1.23 -> 1.23.2.1
Internalize.cpp updated: 1.16 -> 1.16.2.1
PoolAllocate.cpp updated: 1.8 -> 1.8.2.1

---
Log message:

Merged with mainline on Thursday, June 26, 2003.


---
Diffs of the changes:

Index: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
diff -c /dev/null llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp:1.1
*** /dev/null	Thu Jun 26 16:37:37 2003
--- llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp	Tue Jun 17 17:21:05 2003
***************
*** 0 ****
--- 1,304 ----
+ //===-- DeadArgumentElimination.cpp - Eliminate dead arguments ------------===//
+ //
+ // This pass deletes dead arguments from internal functions.  Dead argument
+ // elimination removes arguments which are directly dead, as well as arguments
+ // only passed into function calls as dead arguments of other functions.
+ //
+ // This pass is often useful as a cleanup pass to run after aggressive
+ // interprocedural passes, which add possibly-dead arguments.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/Transforms/IPO.h"
+ #include "llvm/Module.h"
+ #include "llvm/Pass.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Constant.h"
+ #include "llvm/iOther.h"
+ #include "llvm/iTerminators.h"
+ #include "llvm/Support/CallSite.h"
+ #include "Support/Statistic.h"
+ #include "Support/iterator"
+ #include <set>
+ 
+ namespace {
+   Statistic<> NumArgumentsEliminated("deadargelim", "Number of args removed");
+ 
+   struct DAE : public Pass {
+     bool run(Module &M);
+   };
+   RegisterOpt<DAE> X("deadargelim", "Dead Argument Elimination");
+ }
+ 
+ // createDeadArgEliminationPass - This pass removes arguments from functions
+ // which are not used by the body of the function.
+ //
+ Pass *createDeadArgEliminationPass() { return new DAE(); }
+ 
+ 
+ // FunctionArgumentsIntrinsicallyAlive - Return true if the arguments of the
+ // specified function are intrinsically alive.
+ //
+ // We consider arguments of non-internal functions to be intrinsically alive as
+ // well as arguments to functions which have their "address taken".
+ //
+ static bool FunctionArgumentsIntrinsicallyAlive(const Function &F) {
+   if (!F.hasInternalLinkage()) return true;
+ 
+   for (Value::use_const_iterator I = F.use_begin(), E = F.use_end(); I!=E; ++I){
+     // If this use is anything other than a call site, the function is alive.
+     CallSite CS = CallSite::get(const_cast<User*>(*I));
+     if (!CS.getInstruction()) return true;  // Not a valid call site?
+ 
+     // If the function is PASSED IN as an argument, its address has been taken
+     for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); AI != E;
+          ++AI)
+       if (AI->get() == &F) return true;
+   }
+   return false;
+ }
+ 
+ namespace {
+   enum ArgumentLiveness { Alive, MaybeLive, Dead };
+ }
+ 
+ // getArgumentLiveness - Inspect an argument, determining if is known Alive
+ // (used in a computation), MaybeLive (only passed as an argument to a call), or
+ // Dead (not used).
+ static ArgumentLiveness getArgumentLiveness(const Argument &A) {
+   if (A.use_empty()) return Dead;  // First check, directly dead?
+ 
+   // Scan through all of the uses, looking for non-argument passing uses.
+   for (Value::use_const_iterator I = A.use_begin(), E = A.use_end(); I!=E;++I) {
+     CallSite CS = CallSite::get(const_cast<User*>(*I));
+     if (!CS.getInstruction()) {
+       // If its used by something that is not a call or invoke, it's alive!
+       return Alive;
+     }
+     // If it's an indirect call, mark it alive...
+     Function *Callee = CS.getCalledFunction();
+     if (!Callee) return Alive;
+ 
+     // FIXME: check to see if it's passed through a va_arg area
+   }
+ 
+   return MaybeLive;  // It must be used, but only as argument to a function
+ }
+ 
+ // isMaybeLiveArgumentNowAlive - Check to see if Arg is alive.  At this point,
+ // we know that the only uses of Arg are to be passed in as an argument to a
+ // function call.  Check to see if the formal argument passed in is in the
+ // LiveArguments set.  If so, return true.
+ //
+ static bool isMaybeLiveArgumentNowAlive(Argument *Arg,
+                                      const std::set<Argument*> &LiveArguments) {
+   for (Value::use_iterator I = Arg->use_begin(), E = Arg->use_end(); I!=E; ++I){
+     CallSite CS = CallSite::get(*I);
+ 
+     // We know that this can only be used for direct calls...
+     Function *Callee = cast<Function>(CS.getCalledValue());
+ 
+     // Loop over all of the arguments (because Arg may be passed into the call
+     // multiple times) and check to see if any are now alive...
+     CallSite::arg_iterator CSAI = CS.arg_begin();
+     for (Function::aiterator AI = Callee->abegin(), E = Callee->aend();
+          AI != E; ++AI, ++CSAI)
+       // If this is the argument we are looking for, check to see if it's alive
+       if (*CSAI == Arg && LiveArguments.count(AI))
+         return true;
+   }
+   return false;
+ }
+ 
+ // MarkArgumentLive - The MaybeLive argument 'Arg' is now known to be alive.
+ // Mark it live in the specified sets and recursively mark arguments in callers
+ // live that are needed to pass in a value.
+ //
+ static void MarkArgumentLive(Argument *Arg,
+                              std::set<Argument*> &MaybeLiveArguments,
+                              std::set<Argument*> &LiveArguments,
+                           const std::multimap<Function*, CallSite> &CallSites) {
+   DEBUG(std::cerr << "  MaybeLive argument now live: " << Arg->getName()<<"\n");
+   assert(MaybeLiveArguments.count(Arg) && !LiveArguments.count(Arg) &&
+          "Arg not MaybeLive?");
+   MaybeLiveArguments.erase(Arg);
+   LiveArguments.insert(Arg);
+   
+   // Loop over all of the call sites of the function, making any arguments
+   // passed in to provide a value for this argument live as necessary.
+   //
+   Function *Fn = Arg->getParent();
+   unsigned ArgNo = std::distance(Fn->abegin(), Function::aiterator(Arg));
+ 
+   std::multimap<Function*, CallSite>::const_iterator I =
+     CallSites.lower_bound(Fn);
+   for (; I != CallSites.end() && I->first == Fn; ++I) {
+     const CallSite &CS = I->second;
+     if (Argument *ActualArg = dyn_cast<Argument>(*(CS.arg_begin()+ArgNo)))
+       if (MaybeLiveArguments.count(ActualArg))
+         MarkArgumentLive(ActualArg, MaybeLiveArguments, LiveArguments,
+                          CallSites);
+   }
+ }
+ 
+ // RemoveDeadArgumentsFromFunction - We know that F has dead arguments, as
+ // specified by the DeadArguments list.  Transform the function and all of the
+ // callees of the function to not have these arguments.
+ //
+ static void RemoveDeadArgumentsFromFunction(Function *F,
+                                             std::set<Argument*> &DeadArguments){
+   // Start by computing a new prototype for the function, which is the same as
+   // the old function, but has fewer arguments.
+   const FunctionType *FTy = F->getFunctionType();
+   std::vector<const Type*> Params;
+ 
+   for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
+     if (!DeadArguments.count(I))
+       Params.push_back(I->getType());
+ 
+   FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params,
+                                          FTy->isVarArg());
+   
+   // Create the new function body and insert it into the module...
+   Function *NF = new Function(NFTy, Function::InternalLinkage, F->getName());
+   F->getParent()->getFunctionList().insert(F, NF);
+ 
+   // Loop over all of the callers of the function, transforming the call sites
+   // to pass in a smaller number of arguments into the new function.
+   //
+   while (!F->use_empty()) {
+     CallSite CS = CallSite::get(F->use_back());
+     Instruction *Call = CS.getInstruction();
+     CS.setCalledFunction(NF);   // Reduce the uses count of F
+     
+     // Loop over the operands, deleting dead ones...
+     CallSite::arg_iterator AI = CS.arg_begin();
+     for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
+       if (DeadArguments.count(I)) {        // Remove operands for dead arguments
+         AI = Call->op_erase(AI);
+       }  else {
+         ++AI;  // Leave live operands alone...
+       }
+   }
+ 
+   // Since we have now created the new function, splice the body of the old
+   // function right into the new function, leaving the old rotting hulk of the
+   // function empty.
+   NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
+ 
+   // Loop over the argument list, transfering uses of the old arguments over to
+   // the new arguments, also transfering over the names as well.  While we're at
+   // it, remove the dead arguments from the DeadArguments list.
+   //
+   for (Function::aiterator I = F->abegin(), E = F->aend(), I2 = NF->abegin();
+        I != E; ++I)
+     if (!DeadArguments.count(I)) {
+       // If this is a live argument, move the name and users over to the new
+       // version.
+       I->replaceAllUsesWith(I2);
+       I2->setName(I->getName());
+       ++I2;
+     } else {
+       // If this argument is dead, replace any uses of it with null constants
+       // (these are guaranteed to only be operands to call instructions which
+       // will later be simplified).
+       I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
+       DeadArguments.erase(I);
+     }
+ 
+   // Now that the old function is dead, delete it.
+   F->getParent()->getFunctionList().erase(F);
+ }
+ 
+ bool DAE::run(Module &M) {
+   // First phase: loop through the module, determining which arguments are live.
+   // We assume all arguments are dead unless proven otherwise (allowing us to
+   // determing that dead arguments passed into recursive functions are dead).
+   //
+   std::set<Argument*> LiveArguments, MaybeLiveArguments, DeadArguments;
+   std::multimap<Function*, CallSite> CallSites;
+ 
+   DEBUG(std::cerr << "DAE - Determining liveness\n");
+   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+     Function &Fn = *I;
+     // If the function is intrinsically alive, just mark the arguments alive.
+     if (FunctionArgumentsIntrinsicallyAlive(Fn)) {
+       for (Function::aiterator AI = Fn.abegin(), E = Fn.aend(); AI != E; ++AI)
+         LiveArguments.insert(AI);
+       DEBUG(std::cerr << "  Args intrinsically live for fn: " << Fn.getName()
+                       << "\n");
+     } else {
+       DEBUG(std::cerr << "  Inspecting args for fn: " << Fn.getName() << "\n");
+ 
+       // If it is not intrinsically alive, we know that all users of the
+       // function are call sites.  Mark all of the arguments live which are
+       // directly used, and keep track of all of the call sites of this function
+       // if there are any arguments we assume that are dead.
+       //
+       bool AnyMaybeLiveArgs = false;
+       for (Function::aiterator AI = Fn.abegin(), E = Fn.aend(); AI != E; ++AI)
+         switch (getArgumentLiveness(*AI)) {
+         case Alive:
+           DEBUG(std::cerr << "    Arg live by use: " << AI->getName() << "\n");
+           LiveArguments.insert(AI);
+           break;
+         case Dead:
+           DEBUG(std::cerr << "    Arg definately dead: " <<AI->getName()<<"\n");
+           DeadArguments.insert(AI);
+           break;
+         case MaybeLive:
+           DEBUG(std::cerr << "    Arg only passed to calls: "
+                           << AI->getName() << "\n");
+           AnyMaybeLiveArgs = true;
+           MaybeLiveArguments.insert(AI);
+           break;
+         }
+ 
+       // If there are any "MaybeLive" arguments, we need to check callees of
+       // this function when/if they become alive.  Record which functions are
+       // callees...
+       if (AnyMaybeLiveArgs)
+         for (Value::use_iterator I = Fn.use_begin(), E = Fn.use_end();
+              I != E; ++I)
+           CallSites.insert(std::make_pair(&Fn, CallSite::get(*I)));
+     }
+   }
+ 
+   // Now we loop over all of the MaybeLive arguments, promoting them to be live
+   // arguments if one of the calls that uses the arguments to the calls they are
+   // passed into requires them to be live.  Of course this could make other
+   // arguments live, so process callers recursively.
+   //
+   // Because elements can be removed from the MaybeLiveArguments list, copy it
+   // to a temporary vector.
+   //
+   std::vector<Argument*> TmpArgList(MaybeLiveArguments.begin(),
+                                     MaybeLiveArguments.end());
+   for (unsigned i = 0, e = TmpArgList.size(); i != e; ++i) {
+     Argument *MLA = TmpArgList[i];
+     if (MaybeLiveArguments.count(MLA) &&
+         isMaybeLiveArgumentNowAlive(MLA, LiveArguments)) {
+       MarkArgumentLive(MLA, MaybeLiveArguments, LiveArguments, CallSites);
+     }
+   }
+ 
+   // Recover memory early...
+   CallSites.clear();
+ 
+   // At this point, we know that all arguments in DeadArguments and
+   // MaybeLiveArguments are dead.  If the two sets are empty, there is nothing
+   // to do.
+   if (MaybeLiveArguments.empty() && DeadArguments.empty())
+     return false;
+   
+   // Otherwise, compact into one set, and start eliminating the arguments from
+   // the functions.
+   DeadArguments.insert(MaybeLiveArguments.begin(), MaybeLiveArguments.end());
+   MaybeLiveArguments.clear();
+ 
+   NumArgumentsEliminated += DeadArguments.size();
+   while (!DeadArguments.empty())
+     RemoveDeadArgumentsFromFunction((*DeadArguments.begin())->getParent(),
+                                     DeadArguments);
+   return true;
+ }


Index: llvm/lib/Transforms/IPO/FunctionResolution.cpp
diff -u llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.31 llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.31.2.1
--- llvm/lib/Transforms/IPO/FunctionResolution.cpp:1.31	Sat May 31 16:57:06 2003
+++ llvm/lib/Transforms/IPO/FunctionResolution.cpp	Thu Jun 26 16:35:27 2003
@@ -36,94 +36,6 @@
   return new FunctionResolvingPass();
 }
 
-// ConvertCallTo - Convert a call to a varargs function with no arg types
-// specified to a concrete nonvarargs function.
-//
-static void ConvertCallTo(CallInst *CI, Function *Dest) {
-  const FunctionType::ParamTypes &ParamTys =
-    Dest->getFunctionType()->getParamTypes();
-  BasicBlock *BB = CI->getParent();
-
-  // Keep an iterator to where we want to insert cast instructions if the
-  // argument types don't agree.
-  //
-  unsigned NumArgsToCopy = CI->getNumOperands()-1;
-  if (NumArgsToCopy != ParamTys.size() &&
-      !(NumArgsToCopy > ParamTys.size() &&
-        Dest->getFunctionType()->isVarArg())) {
-    std::cerr << "WARNING: Call arguments do not match expected number of"
-              << " parameters.\n";
-    std::cerr << "WARNING: In function '"
-              << CI->getParent()->getParent()->getName() << "': call: " << *CI;
-    std::cerr << "Function resolved to: ";
-    WriteAsOperand(std::cerr, Dest);
-    std::cerr << "\n";
-    if (NumArgsToCopy > ParamTys.size())
-      NumArgsToCopy = ParamTys.size();
-  }
-
-  std::vector<Value*> Params;
-
-  // Convert all of the call arguments over... inserting cast instructions if
-  // the types are not compatible.
-  for (unsigned i = 1; i <= NumArgsToCopy; ++i) {
-    Value *V = CI->getOperand(i);
-
-    if (i-1 < ParamTys.size() && V->getType() != ParamTys[i-1]) {
-      // Must insert a cast...
-      V = new CastInst(V, ParamTys[i-1], "argcast", CI);
-    }
-
-    Params.push_back(V);
-  }
-  
-  // If the function takes extra parameters that are not being passed in, pass
-  // null values in now...
-  for (unsigned i = NumArgsToCopy; i < ParamTys.size(); ++i)
-    Params.push_back(Constant::getNullValue(ParamTys[i]));
-
-  // Replace the old call instruction with a new call instruction that calls
-  // the real function.
-  //
-  Instruction *NewCall = new CallInst(Dest, Params, "", CI);
-  std::string Name = CI->getName(); CI->setName("");
-
-  // Transfer the name over...
-  if (NewCall->getType() != Type::VoidTy)
-    NewCall->setName(Name);
-
-  // Replace uses of the old instruction with the appropriate values...
-  //
-  if (NewCall->getType() == CI->getType()) {
-    CI->replaceAllUsesWith(NewCall);
-    NewCall->setName(Name);
-
-  } else if (NewCall->getType() == Type::VoidTy) {
-    // Resolved function does not return a value but the prototype does.  This
-    // often occurs because undefined functions default to returning integers.
-    // Just replace uses of the call (which are broken anyway) with dummy
-    // values.
-    CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
-  } else if (CI->getType() == Type::VoidTy) {
-    // If we are gaining a new return value, we don't have to do anything
-    // special here, because it will automatically be ignored.
-  } else {
-    // Insert a cast instruction to convert the return value of the function
-    // into it's new type.  Of course we only need to do this if the return
-    // value of the function is actually USED.
-    //
-    if (!CI->use_empty()) {
-      // Insert the new cast instruction...
-      CastInst *NewCast = new CastInst(NewCall, CI->getType(), Name, CI);
-      CI->replaceAllUsesWith(NewCast);
-    }
-  }
-
-  // The old instruction is no longer needed, destroy it!
-  BB->getInstList().erase(CI);
-}
-
-
 static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
                              Function *Concrete) {
   bool Changed = false;
@@ -168,36 +80,12 @@
       // functions and that the Old function has no varargs fns specified.  In
       // otherwords it's just <retty> (...)
       //
-      for (unsigned i = 0; i < Old->use_size(); ) {
-        User *U = *(Old->use_begin()+i);
-        if (CastInst *CI = dyn_cast<CastInst>(U)) {
-          // Convert casts directly
-          assert(CI->getOperand(0) == Old);
-          CI->setOperand(0, Concrete);
-          Changed = true;
-          ++NumResolved;
-        } else if (CallInst *CI = dyn_cast<CallInst>(U)) {
-          // Can only fix up calls TO the argument, not args passed in.
-          if (CI->getCalledValue() == Old) {
-            ConvertCallTo(CI, Concrete);
-            Changed = true;
-            ++NumResolved;
-          } else {
-            ++i;
-          }
-        } else {
-          ++i;
-        }
-      }
-
-      // If there are any more uses that we could not resolve, force them to use
-      // a casted pointer now.
-      if (!Old->use_empty()) {
-        NumResolved += Old->use_size();
-        Constant *NewCPR = ConstantPointerRef::get(Concrete);
-        Old->replaceAllUsesWith(ConstantExpr::getCast(NewCPR, Old->getType()));
-        Changed = true;
-      }
+      Value *Replacement = Concrete;
+      if (Concrete->getType() != Old->getType())
+        Replacement = ConstantExpr::getCast(ConstantPointerRef::get(Concrete),
+                                            Old->getType());
+      NumResolved += Old->use_size();
+      Old->replaceAllUsesWith(Replacement);
 
       // Since there are no uses of Old anymore, remove it from the module.
       M.getFunctionList().erase(Old);


Index: llvm/lib/Transforms/IPO/GlobalDCE.cpp
diff -u llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.23 llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.23.2.1
--- llvm/lib/Transforms/IPO/GlobalDCE.cpp:1.23	Sun Oct 13 12:12:47 2002
+++ llvm/lib/Transforms/IPO/GlobalDCE.cpp	Thu Jun 26 16:35:27 2003
@@ -46,12 +46,18 @@
     // Nothing to do if no unreachable functions have been found...
     if (FunctionsToDelete.empty()) return false;
     
-    // Unreachables functions have been found and should have no references to
+    // Unreachable functions have been found and should have no references to
     // them, delete them now.
     //
     for (std::vector<CallGraphNode*>::iterator I = FunctionsToDelete.begin(),
            E = FunctionsToDelete.end(); I != E; ++I)
       delete CallGraph.removeFunctionFromModule(*I);
+
+    // Walk the function list, removing prototypes for functions which are not
+    // used.
+    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+      if (I->use_size() == 0 && I->isExternal())
+        delete CallGraph.removeFunctionFromModule(I);
     
     return true;
   }


Index: llvm/lib/Transforms/IPO/Internalize.cpp
diff -u llvm/lib/Transforms/IPO/Internalize.cpp:1.16 llvm/lib/Transforms/IPO/Internalize.cpp:1.16.2.1
--- llvm/lib/Transforms/IPO/Internalize.cpp:1.16	Thu May 22 15:27:13 2003
+++ llvm/lib/Transforms/IPO/Internalize.cpp	Thu Jun 26 16:35:27 2003
@@ -87,6 +87,14 @@
       for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
         if (!I->isExternal() && !I->hasInternalLinkage() &&
             !ExternalNames.count(I->getName())) {
+          // Special case handling of the global ctor and dtor list.  When we
+          // internalize it, we mark it constant, which allows elimination of
+          // the list if it's empty.
+          //
+          if (I->hasAppendingLinkage() && (I->getName() == "llvm.global_ctors"||
+                                           I->getName() == "llvm.global_dtors"))
+            I->setConstant(true);
+
           I->setLinkage(GlobalValue::InternalLinkage);
           Changed = true;
           ++NumGlobals;


Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp
diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.8 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.8.2.1
--- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.8	Sat Jun  7 15:29:58 2003
+++ llvm/lib/Transforms/IPO/PoolAllocate.cpp	Thu Jun 26 16:35:27 2003
@@ -82,10 +82,10 @@
 	   CSE = callSites.end(); CSI != CSE ; ++CSI) {
       if (CSI->isIndirectCall()) {
 	DSNode *DSN = CSI->getCalleeNode();
-	if (DSN->NodeType == DSNode::Incomplete) 
+	if (DSN->isIncomplete())
 	  std::cerr << "Incomplete node " << CSI->getCallInst();
-	// assert(DSN->NodeType == DSNode::GlobalNode);
-	std::vector<GlobalValue*> &Callees = DSN->getGlobals();
+	// assert(DSN->isGlobalNode());
+	const std::vector<GlobalValue*> &Callees = DSN->getGlobals();
 	if (Callees.size() > 0) {
 	  Function *firstCalledF = dyn_cast<Function>(*Callees.begin());
 	  FuncECs.addElement(firstCalledF);
@@ -93,7 +93,7 @@
 				 (&CSI->getCallInst(),
 				  firstCalledF));
 	  if (Callees.size() > 1) {
-	    for (std::vector<GlobalValue*>::iterator CalleesI = 
+	    for (std::vector<GlobalValue*>::const_iterator CalleesI = 
 		   Callees.begin()+1, CalleesE = Callees.end(); 
 		 CalleesI != CalleesE; ++CalleesI) {
 	      Function *calledF = dyn_cast<Function>(*CalleesI);
@@ -229,13 +229,13 @@
   // Mark globals and incomplete nodes as live... (this handles arguments)
   if (F.getName() != "main")
     for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-      if (Nodes[i]->NodeType & (DSNode::GlobalNode | DSNode::Incomplete) &&
-          Nodes[i]->NodeType & (DSNode::HeapNode))
+      if ((Nodes[i]->isGlobalNode() || Nodes[i]->isIncomplete()) &&
+          Nodes[i]->isHeapNode())
         Nodes[i]->markReachableNodes(MarkedNodes);
 
   // Marked the returned node as alive...
   if (DSNode *RetNode = G.getRetNode().getNode())
-    if (RetNode->NodeType & DSNode::HeapNode)
+    if (RetNode->isHeapNode())
       RetNode->markReachableNodes(MarkedNodes);
 
   if (MarkedNodes.empty())   // We don't need to clone the function if there
@@ -411,7 +411,7 @@
   // ones to the NodesToPA vector.
   std::vector<DSNode*> NodesToPA;
   for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-    if (Nodes[i]->NodeType & DSNode::HeapNode &&   // Pick nodes with heap elems
+    if (Nodes[i]->isHeapNode() &&   // Pick nodes with heap elems
         !MarkedNodes.count(Nodes[i]))              // Can't be marked
       NodesToPA.push_back(Nodes[i]);
   
@@ -577,7 +577,7 @@
   if (!DSN) {
     return 0;
   }
-  std::vector<GlobalValue*> &Callees = DSN->getGlobals();
+  const std::vector<GlobalValue*> &Callees = DSN->getGlobals();
   if (Callees.size() > 0) {
     Function *calledF = dyn_cast<Function>(*Callees.begin());
     assert(PAInfo.FuncECs.findClass(calledF) && "should exist in some eq. class");





More information about the llvm-commits mailing list