[llvm-commits] [poolalloc] r151704 - in /poolalloc/trunk: include/assistDS/DSNodeEquivs.h lib/AssistDS/DSNodeEquivs.cpp

Matthew Wala mttjwl at gmail.com
Tue Feb 28 19:35:59 PST 2012


Author: wala1
Date: Tue Feb 28 21:35:59 2012
New Revision: 151704

URL: http://llvm.org/viewvc/llvm-project?rev=151704&view=rev
Log:
Initial version of DSNodeEquivs.

Added:
    poolalloc/trunk/include/assistDS/DSNodeEquivs.h
    poolalloc/trunk/lib/AssistDS/DSNodeEquivs.cpp

Added: poolalloc/trunk/include/assistDS/DSNodeEquivs.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/DSNodeEquivs.h?rev=151704&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/DSNodeEquivs.h (added)
+++ poolalloc/trunk/include/assistDS/DSNodeEquivs.h Tue Feb 28 21:35:59 2012
@@ -0,0 +1,60 @@
+//===- DSNodeEquivs.h - Build DSNode equivalence classes ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass computes equivalence classes of DSNodes across DSGraphs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DSNODEEQUIVS_H
+#define DSNODEEQUIVS_H
+
+#include "dsa/DataStructure.h"
+#include "dsa/DSGraph.h"
+#include "dsa/DSNode.h"
+
+#include "llvm/ADT/EquivalenceClasses.h"
+
+#include <vector>
+#include <set>
+
+namespace llvm {
+
+typedef std::vector<const Function *> FunctionList;
+typedef FunctionList::iterator FunctionList_it;
+
+class DSNodeEquivs : public ModulePass {
+private:
+  EquivalenceClasses<const DSNode*> Classes;
+
+  void buildDSNodeEquivs(Module &M);
+
+  FunctionList getCallees(CallSite &CS);
+  void equivNodesThroughCallsite(CallInst *CI);
+  void equivNodesToGlobals(DSGraph *G);
+  void equivNodeMapping(DSGraph::NodeMapTy & NM);
+  
+public:
+  static char ID;
+
+  DSNodeEquivs() : ModulePass(ID) {}
+
+  void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.addRequiredTransitive<TDDataStructures>();
+    AU.setPreservesAll();
+  }
+
+  bool runOnModule(Module &M);
+
+  // Returns the computed equivalence classes.
+  const EquivalenceClasses<const DSNode*> &getEquivalenceClasses();
+};
+
+}
+
+#endif // DSNODEEQUIVS_H

Added: poolalloc/trunk/lib/AssistDS/DSNodeEquivs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/DSNodeEquivs.cpp?rev=151704&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/DSNodeEquivs.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/DSNodeEquivs.cpp Tue Feb 28 21:35:59 2012
@@ -0,0 +1,200 @@
+//===- DSNodeEquivs.cpp -  Build DSNode equivalence classes ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a pass to compute DSNode equivalence classes across
+// DSGraphs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "assistDS/DSNodeEquivs.h"
+
+#include "llvm/Constants.h"
+#include "llvm/Module.h"
+#include "llvm/Support/InstIterator.h"
+
+namespace llvm {
+
+char DSNodeEquivs::ID = 0;
+
+static RegisterPass<DSNodeEquivs>
+X("dsnodeequivs", "Compute DSNode equivalence classes");
+
+// Build equivalence classes of DSNodes that are mapped between graphs.
+void DSNodeEquivs::buildDSNodeEquivs(Module &M) {
+  TDDataStructures &TDDS = getAnalysis<TDDataStructures>();
+
+  Module::iterator FuncIt = M.begin(), FuncItEnd = M.end();
+  for (; FuncIt != FuncItEnd; ++FuncIt) {
+    Function &F = *FuncIt;
+
+    if (!TDDS.hasDSGraph(F))
+      continue;
+
+    inst_iterator InstIt = inst_begin(F), InstItEnd = inst_end(F);
+    for (; InstIt != InstItEnd; ++InstIt) {
+      if (CallInst *Call = dyn_cast<CallInst>(&*InstIt)) {
+        equivNodesThroughCallsite(Call);
+      }
+    }
+    
+    equivNodesToGlobals(TDDS.getDSGraph(F));
+  }
+}
+
+FunctionList DSNodeEquivs::getCallees(CallSite &CS) {
+  const Function *CalledFunc = CS.getCalledFunction();
+
+  // If the called function is casted from one function type to another, peer
+  // into the cast instruction and pull out the actual function being called.
+  if (ConstantExpr *CExpr = dyn_cast<ConstantExpr>(CS.getCalledValue())) {
+    if (CExpr->getOpcode() == Instruction::BitCast &&
+        isa<Function>(CExpr->getOperand(0)))
+      CalledFunc = cast<Function>(CExpr->getOperand(0));
+  }
+
+  FunctionList Callees;
+
+  // Direct calls are simple.
+  if (CalledFunc) {
+    Callees.push_back(CalledFunc);
+    return Callees;
+  }
+
+  // Okay, indirect call.
+  // Ask the DSCallGraph what this calls...
+
+  TDDataStructures &TDDS = getAnalysis<TDDataStructures>();
+  const DSCallGraph &DSCG = TDDS.getCallGraph();
+
+  DSCallGraph::callee_iterator CalleeIt = DSCG.callee_begin(CS);
+  DSCallGraph::callee_iterator CalleeItEnd = DSCG.callee_end(CS);
+  for (; CalleeIt != CalleeItEnd; ++CalleeIt)
+    Callees.push_back(*CalleeIt);
+
+  // If the callgraph doesn't give us what we want, query the DSGraph
+  // ourselves.
+  if (Callees.empty()) {
+    Instruction *Inst = CS.getInstruction();
+    Function *Parent = Inst->getParent()->getParent();
+    DSNodeHandle &NH = TDDS.getDSGraph(*Parent)->getNodeForValue(CS.getCalledValue());
+
+    if (!NH.isNull()) {
+      DSNode *Node = NH.getNode();
+      Node->addFullFunctionList(Callees);
+    }
+  }
+
+  // For debugging, dump out the callsites we are unable to get callees for.
+  if (Callees.empty()) {
+    errs() << "Failed to get callees for callsite:\n";
+    CS.getInstruction()->dump();
+  }
+
+  return Callees;
+}
+
+// Compute mappings through the given call site.
+void DSNodeEquivs::equivNodesThroughCallsite(CallInst *CI) {
+  TDDataStructures &TDDS = getAnalysis<TDDataStructures>();
+  DSGraph &Graph = *TDDS.getDSGraph(*CI->getParent()->getParent());
+  CallSite CS(CI);
+  FunctionList Callees = getCallees(CS);
+
+  FunctionList_it CalleeIt = Callees.begin(), CalleeItEnd = Callees.end();
+  for (; CalleeIt != CalleeItEnd; ++CalleeIt) {
+    const Function &Callee = **CalleeIt;
+
+    // We can't merge through graphs that don't exist.
+    if (!TDDS.hasDSGraph(Callee))
+      continue;
+    
+    DSGraph &CalleeGraph = *TDDS.getDSGraph(Callee);
+    DSGraph::NodeMapTy NodeMap;
+
+    // Heavily lifted/inspired by PA code
+
+    // Map arguments
+    Function::const_arg_iterator FArgIt = Callee.arg_begin();
+    Function::const_arg_iterator FArgItEnd = Callee.arg_end();
+    CallSite::arg_iterator ArgIt = CS.arg_begin(), ArgItEnd = CS.arg_end();
+    for (; FArgIt != FArgItEnd && ArgIt != ArgItEnd; ++FArgIt, ++ArgIt) {
+      if (isa<Constant>(*ArgIt))
+        continue;
+
+      DSNodeHandle &CalleeArgNH = CalleeGraph.getNodeForValue(FArgIt);
+      DSNodeHandle &CSArgNH = Graph.getNodeForValue(*ArgIt);
+      DSGraph::computeNodeMapping(CalleeArgNH, CSArgNH, NodeMap, false);
+    }
+
+    // Map return value
+    if (isa<PointerType>(CI->getType())) {
+      DSNodeHandle &CalleeRetNH = CalleeGraph.getReturnNodeFor(Callee);
+      DSNodeHandle &CINH = Graph.getNodeForValue(CI);
+      DSGraph::computeNodeMapping(CalleeRetNH, CINH, NodeMap, false);
+    }
+
+    // Merge information from the computed node mapping into the equivalence
+    // classes.
+    equivNodeMapping(NodeMap);
+  }
+}
+
+// Compute mappings with the globals graph.
+void DSNodeEquivs::equivNodesToGlobals(DSGraph *G) {
+  DSGraph *GlobalsGr = G->getGlobalsGraph();
+  DSGraph::NodeMapTy NodeMap;
+  DSScalarMap &ScalarMap = GlobalsGr->getScalarMap();
+
+  DSScalarMap::global_iterator GlobalIt = ScalarMap.global_begin();
+  DSScalarMap::global_iterator GlobalItEnd = ScalarMap.global_end();
+  for (; GlobalIt != GlobalItEnd; ++GlobalIt) {
+    const GlobalValue *Global = *GlobalIt;
+
+    DSNode *LocalNode = G->getNodeForValue(Global).getNode();
+    DSNode *GlobalNode = GlobalsGr->getNodeForValue(Global).getNode();
+    assert(LocalNode && "No node for global in local scalar map?");
+    assert(GlobalNode && "No node for global in global scalar map?");
+
+    // Map the two together and all reachable from each...
+    DSGraph::computeNodeMapping(LocalNode, GlobalNode, NodeMap, false);
+
+    // Build EC's with this mapping.
+    equivNodeMapping(NodeMap);
+  }
+}
+
+// Utility function to put nodes that map together into equivalence classes.
+void DSNodeEquivs::equivNodeMapping(DSGraph::NodeMapTy &NodeMap) {
+  DSGraph::NodeMapTy::iterator NodeMapIt = NodeMap.begin();
+  DSGraph::NodeMapTy::iterator NodeMapItEnd = NodeMap.end();
+  for (; NodeMapIt != NodeMapItEnd; ++NodeMapIt) {
+    DSNodeHandle &NH = NodeMapIt->second;
+    if (NH.isNull())
+      continue;
+
+    const DSNode *N1 = NodeMapIt->first;
+    const DSNode *N2 = NH.getNode();
+
+    Classes.unionSets(N1, N2);
+  }
+}
+
+bool DSNodeEquivs::runOnModule(Module &M) {
+  buildDSNodeEquivs(M);
+  // Does not modify module.
+  return false;
+}
+
+// Returns the computed equivalence classes.
+const EquivalenceClasses<const DSNode *> &
+DSNodeEquivs::getEquivalenceClasses() {
+  return Classes;
+}
+
+}





More information about the llvm-commits mailing list