Made changes suggested by Chris
authorSumant Kowshik <kowshik@uiuc.edu>
Wed, 4 Jun 2003 08:03:57 +0000 (08:03 +0000)
committerSumant Kowshik <kowshik@uiuc.edu>
Wed, 4 Jun 2003 08:03:57 +0000 (08:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6606 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/PoolAllocate.h
lib/Transforms/IPO/PoolAllocate.cpp

index bf6e1707802cd675df888882828b2f0b7042ecdf..c3e1db2d65a5bd1ef8852bbe57e2e30781bd6c2f 100644 (file)
@@ -90,14 +90,14 @@ class PoolAllocate : public Pass {
   EquivalenceClasses<Function *> FuncECs;
 
   // Map from an Indirect CallInst to the set of Functions that it can point to
-  map<CallInst *, vector<Function *> > CallInstTargets;
+  std::multimap<CallInst *, Function *> CallInstTargets;
 
   // This maps an equivalence class to the last pool argument number for that 
   // class. This is used because the pool arguments for all functions within
   // an equivalence class is passed to all the functions in that class.
   // If an equivalence class does not require pool arguments, it is not
   // on this map.
-  map<Function *, int> EqClass2LastPoolArg;
+  std::map<Function *, int> EqClass2LastPoolArg;
 
  public:
   bool run(Module &M);
index 453578c98f228aa95cf2ed77cd736e25ae1a5d2a..ef64d431062fb546f1525bd6c38a96899a0f58b1 100644 (file)
 #include "llvm/Support/InstVisitor.h"
 #include "Support/Statistic.h"
 #include "Support/VectorExtras.h"
-
+using std::vector;
+using std::map;
+using std::multimap;
 using namespace PA;
 
 namespace {
   const Type *VoidPtrTy = PointerType::get(Type::SByteTy);
-  // The type to allocate for a pool descriptor: { sbyte*, uint }
-  const Type *PoolDescType =
-    StructType::get(make_vector<const Type*>(VoidPtrTy, Type::UIntTy, 0));
-  const PointerType *PoolDescPtr = PointerType::get(PoolDescType);
 
+  // The type to allocate for a pool descriptor: { sbyte*, uint, uint }
+  // void *Data (the data)
+  // unsigned NodeSize  (size of an allocated node)
+  // unsigned FreeablePool (are slabs in the pool freeable upon calls to 
+  //                        poolfree?)
+  const Type *PoolDescType = 
+  StructType::get(make_vector<const Type*>(VoidPtrTy, Type::UIntTy, 
+                                          Type::UIntTy, 0));
+  
+  const PointerType *PoolDescPtr = PointerType::get(PoolDescType);
+  
   RegisterOpt<PoolAllocate>
   X("poolalloc", "Pool allocate disjoint data structures");
 }
@@ -40,7 +49,7 @@ void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
 // Prints out the functions mapped to the leader of the equivalence class they
 // belong to.
 void PoolAllocate::printFuncECs() {
-  map<Function*, Function*> leaderMap = FuncECs.getLeaderMap();
+  map<Function*, Function*> &leaderMap = FuncECs.getLeaderMap();
   std::cerr << "Indirect Function Map \n";
   for (map<Function*, Function*>::iterator LI = leaderMap.begin(),
         LE = leaderMap.end(); LI != LE; ++LI) {
@@ -73,23 +82,28 @@ void PoolAllocate::buildIndirectFunctionSets(Module &M) {
           CSE = callSites.end(); CSI != CSE ; ++CSI) {
       if (CSI->isIndirectCall()) {
        DSNode *DSN = CSI->getCalleeNode();
+       if (DSN->NodeType == DSNode::Incomplete) 
+         std::cerr << "Incomplete node " << CSI->getCallInst();
        // assert(DSN->NodeType == DSNode::GlobalNode);
-       std::vector<GlobalValue*> Callees = DSN->getGlobals();
+       std::vector<GlobalValue*> &Callees = DSN->getGlobals();
        if (Callees.size() > 0) {
          Function *firstCalledF = dyn_cast<Function>(*Callees.begin());
          FuncECs.addElement(firstCalledF);
-         CallInstTargets[&CSI->getCallInst()].push_back(firstCalledF);
+         CallInstTargets.insert(std::pair<CallInst*,Function*>
+                                (&CSI->getCallInst(),
+                                 firstCalledF));
          if (Callees.size() > 1) {
            for (std::vector<GlobalValue*>::iterator CalleesI = 
                   ++Callees.begin(), CalleesE = Callees.end(); 
                 CalleesI != CalleesE; ++CalleesI) {
              Function *calledF = dyn_cast<Function>(*CalleesI);
-             FuncECs.unionElements(firstCalledF, calledF);
-             CallInstTargets[&CSI->getCallInst()].push_back(calledF);
+             FuncECs.unionSetsWith(firstCalledF, calledF);
+             CallInstTargets.insert(std::pair<CallInst*,Function*>
+                                    (&CSI->getCallInst(), calledF));
            }
          }
        } else {
-         std::cerr << "Callee has no targets\n";
+         std::cerr << "No targets " << CSI->getCallInst();
        }
       }
     }
@@ -97,7 +111,6 @@ void PoolAllocate::buildIndirectFunctionSets(Module &M) {
   
   // Print the equivalence classes
   DEBUG(printFuncECs());
-  
 }
 
 bool PoolAllocate::run(Module &M) {
@@ -523,7 +536,7 @@ namespace {
 
     Function* getFuncClass(Value *V);
 
-    Value* retCloneIfNotFP(Value *V);
+    Value* retCloneIfFunc(Value *V);
   };
 }
 
@@ -534,13 +547,8 @@ void PoolAllocate::TransformFunctionBody(Function &F, DSGraph &G, FuncInfo &FI){
 
 // Returns true if V is a function pointer
 bool FuncTransform::isFuncPtr(Value *V) {
-  if (V->getType()->getPrimitiveID() == Type::PointerTyID) {
-    const PointerType *PTy = dyn_cast<PointerType>(V->getType());
-    
-    if (PTy->getElementType()->getPrimitiveID() == Type::FunctionTyID)
-      return true;
-  }
-
+  if (const PointerType *PTy = dyn_cast<PointerType>(V->getType()))
+     return isa<FunctionType>(PTy->getElementType());
   return false;
 }
 
@@ -569,7 +577,7 @@ Function* FuncTransform::getFuncClass(Value *V) {
   if (!DSN) {
     return 0;
   }
-  std::vector<GlobalValue*> Callees = DSN->getGlobals();
+  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");
@@ -580,40 +588,36 @@ Function* FuncTransform::getFuncClass(Value *V) {
   return 0;
 }
 
-// Returns the clone if  V is not a function pointer 
-Value* FuncTransform::retCloneIfNotFP(Value *V) {
-  if (isFuncPtr(V))
-    if (isa<Function>(V))
-      if (getFuncClass(V)) {
-       Function *fixedFunc = dyn_cast<Function>(V);
-       return PAInfo.getFuncInfo(*fixedFunc)->Clone;
-      }
+// Returns the clone if  V is a static function (not a pointer) and belongs 
+// to an equivalence class i.e. is pool allocated
+Value* FuncTransform::retCloneIfFunc(Value *V) {
+  if (Function *fixedFunc = dyn_cast<Function>(V))
+    if (getFuncClass(V))
+      return PAInfo.getFuncInfo(*fixedFunc)->Clone;
   
   return 0;
 }
 
 void FuncTransform::visitReturnInst (ReturnInst &I) {
   if (I.getNumOperands())
-    if (Value *clonedFunc = retCloneIfNotFP(I.getOperand(0))) {
+    if (Value *clonedFunc = retCloneIfFunc(I.getOperand(0))) {
       // Cast the clone of I.getOperand(0) to the non-pool-allocated type
       CastInst *CastI = new CastInst(clonedFunc, I.getOperand(0)->getType(), 
-                                    "", &I);
+                                    "tmp", &I);
       // Insert return instruction that returns the casted value
       new ReturnInst(CastI, &I);
 
       // Remove original return instruction
-      I.setName("");
       I.getParent()->getInstList().erase(&I);
     }
 }
 
 void FuncTransform::visitStoreInst (StoreInst &I) {
   // Check if a constant function is being stored
-  if (Value *clonedFunc = retCloneIfNotFP(I.getOperand(0))) {
-    CastInst *CastI = new CastInst(clonedFunc, I.getOperand(0)->getType(), "", 
-                                  &I);
+  if (Value *clonedFunc = retCloneIfFunc(I.getOperand(0))) {
+    CastInst *CastI = new CastInst(clonedFunc, I.getOperand(0)->getType(), 
+                                  "tmp", &I);
     new StoreInst(CastI, I.getOperand(1), &I);
-    I.setName("");
     I.getParent()->getInstList().erase(&I);
   }
 }
@@ -626,11 +630,11 @@ void FuncTransform::visitPHINode(PHINode &I) {
   if (isFuncPtr(&I)) {
     PHINode *V = new PHINode(I.getType(), I.getName(), &I);
     for (unsigned i = 0 ; i < I.getNumIncomingValues(); ++i) {
-      if (Value *clonedFunc = retCloneIfNotFP(I.getIncomingValue(i))) {
+      if (Value *clonedFunc = retCloneIfFunc(I.getIncomingValue(i))) {
        // Insert CastInst at the end of  I.getIncomingBlock(i)
        BasicBlock::iterator BBI = --I.getIncomingBlock(i)->end();
        // BBI now points to the terminator instruction of the basic block.
-       CastInst *CastI = new CastInst(clonedFunc, I.getType(), "", BBI);
+       CastInst *CastI = new CastInst(clonedFunc, I.getType(), "tmp", BBI);
        V->addIncoming(CastI, I.getIncomingBlock(i));
       } else {
        V->addIncoming(I.getIncomingValue(i), I.getIncomingBlock(i));
@@ -638,7 +642,6 @@ void FuncTransform::visitPHINode(PHINode &I) {
       
     }
     I.replaceAllUsesWith(V);
-    I.setName("");
     I.getParent()->getInstList().erase(&I);
   }
 }
@@ -739,8 +742,7 @@ void FuncTransform::visitCallInst(CallInst &CI) {
       if (isa<Function>(CastI->getOperand(0)) && 
          CastI->getOperand(0)->getType() == CastI->getType())
        CF = dyn_cast<Function>(CastI->getOperand(0));
-    } else if (isa<ConstantExpr>(CI.getOperand(0))) {
-      ConstantExpr *CE = dyn_cast<ConstantExpr>(CI.getOperand(0));
+    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(CI.getOperand(0))) {
       if (CE->getOpcode() == Instruction::Cast) {
        if (isa<ConstantPointerRef>(CE->getOperand(0)))
          return;
@@ -760,24 +762,25 @@ void FuncTransform::visitCallInst(CallInst &CI) {
     std::map<unsigned, Value*> PoolArgs;
     Function *FuncClass;
     
-    for (vector<Function *>::iterator TFI = PAInfo.CallInstTargets[&CI].begin(),
-          TFE = PAInfo.CallInstTargets[&CI].end(); TFI != TFE; ++TFI) {
-      if (TFI == PAInfo.CallInstTargets[&CI].begin()) {
-       FuncClass = PAInfo.FuncECs.findClass(*TFI);
+    std::pair<multimap<CallInst*, Function*>::iterator, multimap<CallInst*, Function*>::iterator> Targets = PAInfo.CallInstTargets.equal_range(&CI);
+    for (multimap<CallInst*, Function*>::iterator TFI = Targets.first,
+          TFE = Targets.second; TFI != TFE; ++TFI) {
+      if (TFI == Targets.first) {
+       FuncClass = PAInfo.FuncECs.findClass(TFI->second);
        // Nothing to transform if there are no pool arguments in this
        // equivalence class of functions.
        if (!PAInfo.EqClass2LastPoolArg.count(FuncClass))
          return;
       }
       
-      FuncInfo *CFI = PAInfo.getFuncInfo(**TFI);
+      FuncInfo *CFI = PAInfo.getFuncInfo(*TFI->second);
 
       if (!CFI->ArgNodes.size()) continue;  // Nothing to transform...
       
-      DSGraph &CG = PAInfo.getBUDataStructures().getDSGraph(**TFI);  
+      DSGraph &CG = PAInfo.getBUDataStructures().getDSGraph(*TFI->second);  
       std::map<DSNode*, DSNode*> NodeMapping;
       
-      Function::aiterator AI = (*TFI)->abegin(), AE = (*TFI)->aend();
+      Function::aiterator AI = TFI->second->abegin(), AE = TFI->second->aend();
       unsigned OpNum = 1;
       for ( ; AI != AE; ++AI, ++OpNum) {
        if (!isa<Constant>(CI.getOperand(OpNum)))
@@ -832,15 +835,16 @@ void FuncTransform::visitCallInst(CallInst &CI) {
     
     Value *NewCall;
     if (Args.size() > CI.getNumOperands() - 1) {
+      // If there are any pool arguments
       CastInst *CastI = 
        new CastInst(CI.getOperand(0), 
-                    PAInfo.getFuncInfo(*FuncClass)->Clone->getType(), "", &CI);
+                    PAInfo.getFuncInfo(*FuncClass)->Clone->getType(), "tmp", 
+                    &CI);
       NewCall = new CallInst(CastI, Args, Name, &CI);
     } else {
       NewCall = new CallInst(CI.getOperand(0), Args, Name, &CI);
     }
 
-    CI.setName("");
     CI.replaceAllUsesWith(NewCall);
     DEBUG(std::cerr << "  Result Call: " << *NewCall);
   }
@@ -914,7 +918,7 @@ void FuncTransform::visitCallInst(CallInst &CI) {
     // Add the rest of the arguments...
     Args.insert(Args.end(), CI.op_begin()+1, CI.op_end());
     
-    std::string Name = CI.getName(); CI.setName("");
+    std::string Name = CI.getName(); 
     Value *NewCall = new CallInst(CFI->Clone, Args, Name, &CI);
     CI.replaceAllUsesWith(NewCall);
     DEBUG(std::cerr << "  Result Call: " << *NewCall);