Implement ResolveCallSiteModRefInfo for IPModRef. computeModRef is not yet done...
authorChris Lattner <sabre@nondot.org>
Thu, 7 Nov 2002 07:12:23 +0000 (07:12 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 7 Nov 2002 07:12:23 +0000 (07:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4602 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/DataStructure/IPModRef.cpp
lib/Analysis/IPA/IPModRef.cpp

index 6b7095bcabd6626f35acff4a0be45b7e09b824d2..3631514b5576b59c3fe25d6caf141a423d335346 100644 (file)
@@ -109,8 +109,11 @@ void FunctionModRefInfo::computeModRef(const Function &func)
 //
 // NOTE: Because this clones a dsgraph and returns it, the caller is responsible
 //       for deleting the returned graph!
+// NOTE: This method may return a null pointer if it is unable to determine the
+//       requested information (because the call site calls an external
+//       function or we cannot determine the complete set of functions invoked).
 //
-DSGraph *FunctionModRefInfo::ResolveCallSiteModRefInfo(const CallInst &CI,
+DSGraph *FunctionModRefInfo::ResolveCallSiteModRefInfo(CallInst &CI,
                                std::map<const DSNode*, DSNodeHandle> &NodeMap) {
 
   // Step #1: Clone the top-down graph...
@@ -126,8 +129,46 @@ DSGraph *FunctionModRefInfo::ResolveCallSiteModRefInfo(const CallInst &CI,
   // Step #2: Clear Mod/Ref information...
   Result->maskNodeTypes(~(DSNode::Modified | DSNode::Read));
 
+  // Step #3: clone the bottom up graphs for the callees into the caller graph
+  if (const Function *F = CI.getCalledFunction()) {
+    if (F->isExternal()) {
+      delete Result;
+      return 0;   // We cannot compute Mod/Ref info for this callsite...
+    }
 
-  
+    // Build up a DSCallSite for our invocation point here...
+
+    // If the call returns a value, make sure to merge the nodes...
+    DSNodeHandle RetVal;
+    if (DS::isPointerType(CI.getType()))
+      RetVal = Result->getNodeForValue(&CI);
+
+    // Populate the arguments list...
+    std::vector<DSNodeHandle> Args;
+    for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
+      if (DS::isPointerType(CI.getOperand(i)->getType()))
+        Args.push_back(Result->getNodeForValue(CI.getOperand(i)));
+
+    // Build the call site...
+    DSCallSite CS(CI, RetVal, 0, Args);
+
+    // Perform the merging now of the graph for the callee, which will come with
+    // mod/ref bits set...
+    Result->mergeInGraph(CS, IPModRefObj.getBUDSGraph(*F),
+                         DSGraph::StripAllocaBit);
+
+  } else {
+    std::cerr << "IP Mod/Ref indirect call not implemented yet: "
+              << "Being conservative\n";
+    delete Result;
+    return 0;
+  }
+
+  // Remove trivial dead nodes... don't aggressively prune graph though... the
+  // graph is short lived anyway.
+  Result->removeTriviallyDeadNodes(false);
+
+  // Step #4: Return the clone + the mapping (by ref)
   return Result;
 }
 
@@ -145,7 +186,11 @@ FunctionModRefInfo::computeModRef(const CallInst& callInst)
 
   // Get a copy of the graph for the callee with the callee inlined
   std::map<const DSNode*, DSNodeHandle> NodeMap;
-  DSGraph* csgp = ResolveCallSiteModRefInfo(callInst, NodeMap);
+  DSGraph* csgp =
+    ResolveCallSiteModRefInfo(const_cast<CallInst&>(callInst), NodeMap);
+
+  assert(csgp && "FIXME: Cannot handle case where call site mod/ref info"
+         " is not available yet!");
 
   // For all nodes in the graph, extract the mod/ref information
   const std::vector<DSNode*>& csgNodes = csgp->getNodes();
@@ -209,7 +254,6 @@ void IPModRef::releaseMemory()
   funcToModRefInfoMap.clear();
 }
 
-
 // Run the "interprocedural" pass on each function.  This needs to do
 // NO real interprocedural work because all that has been done the
 // data structure analysis.
@@ -240,6 +284,14 @@ FunctionModRefInfo& IPModRef::getFuncInfo(const Function& func,
   return *funcInfo;
 }
 
+/// getBUDSGraph - This method returns the BU data structure graph for F through
+/// the use of the BUDataStructures object.
+///
+const DSGraph &IPModRef::getBUDSGraph(const Function &F) {
+  return getAnalysis<BUDataStructures>().getDSGraph(F);
+}
+
+
 // getAnalysisUsage - This pass requires top-down data structure graphs.
 // It modifies nothing.
 // 
index 6b7095bcabd6626f35acff4a0be45b7e09b824d2..3631514b5576b59c3fe25d6caf141a423d335346 100644 (file)
@@ -109,8 +109,11 @@ void FunctionModRefInfo::computeModRef(const Function &func)
 //
 // NOTE: Because this clones a dsgraph and returns it, the caller is responsible
 //       for deleting the returned graph!
+// NOTE: This method may return a null pointer if it is unable to determine the
+//       requested information (because the call site calls an external
+//       function or we cannot determine the complete set of functions invoked).
 //
-DSGraph *FunctionModRefInfo::ResolveCallSiteModRefInfo(const CallInst &CI,
+DSGraph *FunctionModRefInfo::ResolveCallSiteModRefInfo(CallInst &CI,
                                std::map<const DSNode*, DSNodeHandle> &NodeMap) {
 
   // Step #1: Clone the top-down graph...
@@ -126,8 +129,46 @@ DSGraph *FunctionModRefInfo::ResolveCallSiteModRefInfo(const CallInst &CI,
   // Step #2: Clear Mod/Ref information...
   Result->maskNodeTypes(~(DSNode::Modified | DSNode::Read));
 
+  // Step #3: clone the bottom up graphs for the callees into the caller graph
+  if (const Function *F = CI.getCalledFunction()) {
+    if (F->isExternal()) {
+      delete Result;
+      return 0;   // We cannot compute Mod/Ref info for this callsite...
+    }
 
-  
+    // Build up a DSCallSite for our invocation point here...
+
+    // If the call returns a value, make sure to merge the nodes...
+    DSNodeHandle RetVal;
+    if (DS::isPointerType(CI.getType()))
+      RetVal = Result->getNodeForValue(&CI);
+
+    // Populate the arguments list...
+    std::vector<DSNodeHandle> Args;
+    for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
+      if (DS::isPointerType(CI.getOperand(i)->getType()))
+        Args.push_back(Result->getNodeForValue(CI.getOperand(i)));
+
+    // Build the call site...
+    DSCallSite CS(CI, RetVal, 0, Args);
+
+    // Perform the merging now of the graph for the callee, which will come with
+    // mod/ref bits set...
+    Result->mergeInGraph(CS, IPModRefObj.getBUDSGraph(*F),
+                         DSGraph::StripAllocaBit);
+
+  } else {
+    std::cerr << "IP Mod/Ref indirect call not implemented yet: "
+              << "Being conservative\n";
+    delete Result;
+    return 0;
+  }
+
+  // Remove trivial dead nodes... don't aggressively prune graph though... the
+  // graph is short lived anyway.
+  Result->removeTriviallyDeadNodes(false);
+
+  // Step #4: Return the clone + the mapping (by ref)
   return Result;
 }
 
@@ -145,7 +186,11 @@ FunctionModRefInfo::computeModRef(const CallInst& callInst)
 
   // Get a copy of the graph for the callee with the callee inlined
   std::map<const DSNode*, DSNodeHandle> NodeMap;
-  DSGraph* csgp = ResolveCallSiteModRefInfo(callInst, NodeMap);
+  DSGraph* csgp =
+    ResolveCallSiteModRefInfo(const_cast<CallInst&>(callInst), NodeMap);
+
+  assert(csgp && "FIXME: Cannot handle case where call site mod/ref info"
+         " is not available yet!");
 
   // For all nodes in the graph, extract the mod/ref information
   const std::vector<DSNode*>& csgNodes = csgp->getNodes();
@@ -209,7 +254,6 @@ void IPModRef::releaseMemory()
   funcToModRefInfoMap.clear();
 }
 
-
 // Run the "interprocedural" pass on each function.  This needs to do
 // NO real interprocedural work because all that has been done the
 // data structure analysis.
@@ -240,6 +284,14 @@ FunctionModRefInfo& IPModRef::getFuncInfo(const Function& func,
   return *funcInfo;
 }
 
+/// getBUDSGraph - This method returns the BU data structure graph for F through
+/// the use of the BUDataStructures object.
+///
+const DSGraph &IPModRef::getBUDSGraph(const Function &F) {
+  return getAnalysis<BUDataStructures>().getDSGraph(F);
+}
+
+
 // getAnalysisUsage - This pass requires top-down data structure graphs.
 // It modifies nothing.
 //