[llvm-commits] CVS: poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed Nov 12 13:58:02 PST 2003


Changes in directory poolalloc/lib/PoolAllocate:

TransformFunctionBody.cpp updated: 1.10 -> 1.11

---
Log message:

Dramatically simplify how we handle "taking the address" of functions.  This
fixes several bugs too



---
Diffs of the changes:  (+34 -88)

Index: poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp
diff -u poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.10 poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.11
--- poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.10	Wed Nov 12 13:00:59 2003
+++ poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp	Wed Nov 12 13:56:53 2003
@@ -51,34 +51,14 @@
         Set.insert(std::make_pair(AI, &I));
     }
 
+    void visitInstruction(Instruction &I);
     void visitMallocInst(MallocInst &MI);
     void visitFreeInst(FreeInst &FI);
     void visitCallSite(CallSite CS);
     void visitCallInst(CallInst &CI) { visitCallSite(&CI); }
     void visitInvokeInst(InvokeInst &II) { visitCallSite(&II); }
-    
-    // The following instructions are never modified by pool allocation
-    void visitBranchInst(BranchInst &I) { }
-    void visitUnwindInst(UnwindInst &I) { }
-    void visitBinaryOperator(Instruction &I) { }
-    void visitShiftInst (ShiftInst &I) { }
-    void visitSwitchInst (SwitchInst &I) { }
-    void visitCastInst (CastInst &I) { }
-    void visitAllocaInst(AllocaInst &I) { }
-    void visitGetElementPtrInst (GetElementPtrInst &I) { }
-
-    void visitReturnInst(ReturnInst &I);
     void visitLoadInst(LoadInst &I);
     void visitStoreInst (StoreInst &I);
-    void visitPHINode(PHINode &I);
-
-    void visitVAArgInst(VAArgInst &I) { }
-    void visitVANextInst(VANextInst &I) { }
-
-    void visitInstruction(Instruction &I) {
-      std::cerr << "PoolAllocate does not recognize this instruction:\n" << I;
-      abort();
-    }
 
   private:
     DSNodeHandle& getDSNodeHFor(Value *V) {
@@ -117,72 +97,23 @@
   if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V))
     V = CPR->getValue();
   
-  if (Function *F = dyn_cast<Function>(V)) {
-    return PAInfo.getFuncInfo(*F)->Clone;
-  }
+  if (Function *F = dyn_cast<Function>(V))
+    if (FuncInfo *FI = PAInfo.getFuncInfo(*F))
+      return FI->Clone;
 
   return 0;
 }
 
-void FuncTransform::visitReturnInst (ReturnInst &RI) {
-  if (RI.getNumOperands())
-    if (Value *clonedFunc = retCloneIfFunc(RI.getOperand(0))) {
-      // Cast the clone of RI.getOperand(0) to the non-pool-allocated type
-      CastInst *CastI = new CastInst(clonedFunc, RI.getOperand(0)->getType(), 
-				     "tmp", &RI);
-      // Insert return instruction that returns the casted value
-      ReturnInst *RetI = new ReturnInst(CastI, &RI);
-
-      // Remove original return instruction
-      RI.getParent()->getInstList().erase(&RI);
-
-      if (!FI.NewToOldValueMap.empty()) {
-	std::map<Value*,const Value*>::iterator II =
-	  FI.NewToOldValueMap.find(&RI);
-	assert(II != FI.NewToOldValueMap.end() && 
-	       "RI not found in clone?");
-	FI.NewToOldValueMap.insert(std::make_pair(RetI, II->second));
-	FI.NewToOldValueMap.erase(II);
-      }
-    }
-}
-
 void FuncTransform::visitLoadInst(LoadInst &LI) {
   if (Value *PH = getPoolHandle(LI.getOperand(0)))
     AddPoolUse(LI, PH, PoolUses);
+  visitInstruction(LI);
 }
 
-void FuncTransform::visitStoreInst (StoreInst &SI) {
-  // Check if a constant function is being stored
-  if (Value *clonedFunc = retCloneIfFunc(SI.getOperand(0))) {
-    CastInst *CastI = new CastInst(clonedFunc, SI.getOperand(0)->getType(), 
-				   "tmp", &SI);
-    StoreInst *StoreI = new StoreInst(CastI, SI.getOperand(1), &SI);
-    SI.getParent()->getInstList().erase(&SI);
-    
-    // Update the NewToOldValueMap if this is a clone
-    if (!FI.NewToOldValueMap.empty()) {
-      std::map<Value*,const Value*>::iterator II =
-	FI.NewToOldValueMap.find(&SI);
-      assert(II != FI.NewToOldValueMap.end() && 
-	     "SI not found in clone?");
-      FI.NewToOldValueMap.insert(std::make_pair(StoreI, II->second));
-      FI.NewToOldValueMap.erase(II);
-    }
-  }
-
+void FuncTransform::visitStoreInst(StoreInst &SI) {
   if (Value *PH = getPoolHandle(SI.getOperand(1)))
     AddPoolUse(SI, PH, PoolUses);
-}
-
-void FuncTransform::visitPHINode(PHINode &PI) {
-  // If any of the operands of the PHI node is a constant function pointer
-  // that is cloned, the cast instruction has to be inserted at the end of the
-  // previous basic block
-  
-  for (unsigned i = 0; i != PI.getNumIncomingValues(); ++i)
-    if (Function *clonedFunc = retCloneIfFunc(PI.getIncomingValue(i)))
-      PI.setIncomingValue(i, ConstantExpr::getCast(ConstantPointerRef::get(clonedFunc), PI.getType()));
+  visitInstruction(SI);
 }
 
 void FuncTransform::visitMallocInst(MallocInst &MI) {
@@ -304,7 +235,10 @@
 
   if (CF) {   // Direct calls are nice and simple.
     FuncInfo *CFI = PAInfo.getFuncInfo(*CF);
-    if (CFI == 0 || CFI->Clone == 0) return;  // Nothing to transform...
+    if (CFI == 0 || CFI->Clone == 0) {   // Nothing to transform...
+      visitInstruction(*TheCall);
+      return;
+    }
     NewCallee = CFI->Clone;
     ArgNodes = CFI->ArgNodes;
     
@@ -371,18 +305,15 @@
 
   // Okay, now that we have established our mapping, we can figure out which
   // pool descriptors to pass in...
-  std::vector<Value*> Args;  
+  std::vector<Value*> Args;
   for (unsigned i = 0, e = ArgNodes.size(); i != e; ++i) {
-    if (NodeMapping.count(ArgNodes[i])) {
-      if (DSNode *LocalNode = NodeMapping[ArgNodes[i]].getNode()) {
-        assert(FI.PoolDescriptors.count(LocalNode) &&
-               "Node not pool allocated?");
-        Args.push_back(FI.PoolDescriptors.find(LocalNode)->second);
-      } else
-        Args.push_back(Constant::getNullValue(PoolAllocate::PoolDescPtrTy));
-    } else {
-      Args.push_back(Constant::getNullValue(PoolAllocate::PoolDescPtrTy));
-    }
+    Value *ArgVal = 0;
+    if (NodeMapping.count(ArgNodes[i]))
+      if (DSNode *LocalNode = NodeMapping[ArgNodes[i]].getNode())
+        if (FI.PoolDescriptors.count(LocalNode))
+          ArgVal = FI.PoolDescriptors.find(LocalNode)->second;
+    Args.push_back(ArgVal ? ArgVal : 
+                   Constant::getNullValue(PoolAllocate::PoolDescPtrTy));
   }
 
   // Add the rest of the arguments...
@@ -429,4 +360,19 @@
   }
 
   TheCall->getParent()->getInstList().erase(TheCall);
+  visitInstruction(*NewCall);
+}
+
+
+// visitInstruction - For all instructions in the transformed function bodies,
+// replace any references to the original calls with references to the
+// transformed calls.  Many instructions can "take the address of" a function,
+// and we must make sure to catch each of these uses, and transform it into a
+// reference to the new, transformed, function.
+void FuncTransform::visitInstruction(Instruction &I) {
+  for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+    if (Function *clonedFunc = retCloneIfFunc(I.getOperand(i))) {
+      Constant *CF = ConstantPointerRef::get(clonedFunc);
+      I.setOperand(i, ConstantExpr::getCast(CF, I.getOperand(i)->getType()));
+    }
 }





More information about the llvm-commits mailing list