[llvm-commits] [poolalloc] r124808 - in /poolalloc/trunk: include/dsa/TypeSafety.h lib/DSA/TypeSafety.cpp

John Criswell criswell at uiuc.edu
Thu Feb 3 11:32:54 PST 2011


Author: criswell
Date: Thu Feb  3 13:32:54 2011
New Revision: 124808

URL: http://llvm.org/viewvc/llvm-project?rev=124808&view=rev
Log:
Added the TypeSafety pass.  This convenience pass will properly interpret DSA
results to see if a pointer points to a memory object that is used in a
type-safe fashion.

Added:
    poolalloc/trunk/include/dsa/TypeSafety.h
    poolalloc/trunk/lib/DSA/TypeSafety.cpp

Added: poolalloc/trunk/include/dsa/TypeSafety.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/TypeSafety.h?rev=124808&view=auto
==============================================================================
--- poolalloc/trunk/include/dsa/TypeSafety.h (added)
+++ poolalloc/trunk/include/dsa/TypeSafety.h Thu Feb  3 13:32:54 2011
@@ -0,0 +1,83 @@
+//===- TypeSafety.h - Find Type-Safe Pointers ---------------------*- C++ -*--//
+// 
+//                     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 analysis pass determines which pointers within a program are used in
+// a type-safe fashion.  It uses DSA to determine type-consistency and
+// abstracts the details of interpreting DSA's results.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef DSA_TYPESAFETY_H
+#define DSA_TYPESAFETY_H
+
+#include "dsa/DataStructure.h"
+#include "dsa/DSGraph.h"
+
+#include "llvm/Pass.h"
+
+#include <set>
+
+using namespace llvm;
+
+namespace dsa {
+
+//
+// Pass: TypeSafety
+//
+// Description:
+//  This pass determines which pointers within a function are type-safe.  It is
+//  used to abstract away the interpretation of the DSNode flags and fields
+//  for clients.
+//
+// Template parameters:
+//  dsa - The name of the DSA Pass which this pass should use.
+//
+template<class dsa>
+struct TypeSafety : public ModulePass {
+  protected:
+    // Methods
+    DSNodeHandle getDSNodeHandle (const Value * V, const Function * F);
+    void findTypeSafeDSNodes (const DSGraph * Graph);
+    bool isTypeSafe (const DSNode * N);
+    bool typeFieldsOverlap (const DSNode * N);
+
+    // Pointers to prerequisite passes
+    TargetData * TD;
+    dsa * dsaPass;
+
+    // Data structures
+    std::set<const DSNode *> TypeSafeNodes;
+
+  public:
+    static char ID;
+    TypeSafety() : ModulePass((intptr_t)(&ID)) {}
+    virtual bool runOnModule (Module & M);
+
+    const char *getPassName() const {
+      return "DSA Type-Safety Analysis";
+    }
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<TargetData>();
+      AU.addRequired<dsa>();
+      AU.setPreservesAll();
+    }
+
+    virtual void releaseMemory () {
+      TypeSafeNodes.clear();
+      return;
+    }
+
+    // Methods for clients to use
+    virtual bool isTypeSafe (const Value * V, const Function * F);
+};
+
+}
+#endif
+

Added: poolalloc/trunk/lib/DSA/TypeSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TypeSafety.cpp?rev=124808&view=auto
==============================================================================
--- poolalloc/trunk/lib/DSA/TypeSafety.cpp (added)
+++ poolalloc/trunk/lib/DSA/TypeSafety.cpp Thu Feb  3 13:32:54 2011
@@ -0,0 +1,281 @@
+//===- TypeSafety.cpp - Find type-safe pointers --------------------------- --//
+// 
+//                     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 implements code that determines if memory objects are used in
+// a type-consistent fashion.  It is built using DSA and essentially abstracts
+// away the details of interpreting DSNodes.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "type-safety"
+
+#include "dsa/TypeSafety.h"
+
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Module.h"
+
+static RegisterPass<dsa::TypeSafety<EQTDDataStructures> >
+X ("typesafety", "Find type-safe pointers");
+
+// Pass Statistics
+namespace {
+  //STATISTIC (TypeSafeNodes, "Type-safe DSNodes");
+}
+
+namespace dsa {
+
+template<typename dsa>
+char TypeSafety<dsa>::ID = 0;
+
+// Method: getDSNodeHandle()
+//
+// Description:
+//  This method looks up the DSNodeHandle for a given LLVM value.  The context
+//  of the value is the specified function, although if it is a global value,
+//  the DSNodeHandle may exist within the global DSGraph.
+//
+// Return value:
+//  A DSNodeHandle for the value is returned.  This DSNodeHandle could either
+//  be in the function's DSGraph or from the GlobalsGraph.  Note that the
+//  DSNodeHandle may represent a NULL DSNode.
+//
+template<class dsa> DSNodeHandle
+TypeSafety<dsa>::getDSNodeHandle (const Value * V, const Function * F) {
+  //
+  // Ensure that the function has a DSGraph
+  //
+  assert (dsaPass->hasDSGraph(*F) && "No DSGraph for function!\n");
+
+  //
+  // Lookup the DSNode for the value in the function's DSGraph.
+  //
+  DSGraph * TDG = dsaPass->getDSGraph(*F);
+  DSNodeHandle DSH = TDG->getNodeForValue(V);
+
+  //
+  // If the value wasn't found in the function's DSGraph, then maybe we can
+  // find the value in the globals graph.
+  //
+  if ((DSH.isNull()) && (isa<GlobalValue>(V))) {
+    //
+    // Try looking up this DSNode value in the globals graph.  Note that
+    // globals are put into equivalence classes; we may need to first find the
+    // equivalence class to which our global belongs, find the global that
+    // represents all globals in that equivalence class, and then look up the
+    // DSNode Handle for *that* global.
+    //
+    DSGraph * GlobalsGraph = TDG->getGlobalsGraph ();
+    DSH = GlobalsGraph->getNodeForValue(V);
+    if (DSH.isNull()) {
+      //
+      // DSA does not currently handle global aliases.
+      //
+      if (!isa<GlobalAlias>(V)) {
+        //
+        // We have to dig into the globalEC of the DSGraph to find the DSNode.
+        //
+        const GlobalValue * GV = dyn_cast<GlobalValue>(V);
+        const GlobalValue * Leader;
+        Leader = GlobalsGraph->getGlobalECs().getLeaderValue(GV);
+        DSH = GlobalsGraph->getNodeForValue(Leader);
+      }
+    }
+  }
+
+  return DSH;
+}
+
+template<class dsa> bool
+TypeSafety<dsa>::isTypeSafe (const Value * V, const Function * F) {
+  //
+  // Get the DSNode for the specified value.
+  //
+  DSNodeHandle DH = getDSNodeHandle (V, F);
+
+  //
+  // If there is no DSNode, claim that it is not type safe.
+  //
+  if (DH.isNull())
+    return false;
+
+  //
+  // See if the DSNode is one that we think is type-safe.
+  //
+  if (TypeSafeNodes.count (DH.getNode()))
+    return true;
+
+  return false;
+}
+
+//
+// Method: typeFieldsOverlap()
+//
+// Description:
+//  Determine if any of the type fields can overlap within the DSNode.
+//
+// Notes:
+//  o) We take advantage of the fact that a std::map keeps its elements sorted
+//     by key.
+//
+template<class dsa> bool
+TypeSafety<dsa>::typeFieldsOverlap (const DSNode * N) {
+  //
+  // There are no overlapping fields if the DSNode has no fields.
+  //
+  if (N->type_begin() == N->type_end())
+    return false;
+
+  //
+  // Iterate through the DSNode to see if the previous fields overlaps with the
+  // current field.
+  //
+  DSNode::const_type_iterator tn =  N->type_begin();
+  bool overlaps = false;
+  while (!overlaps) {
+    //
+    // Get the information about the current field.
+    //
+    unsigned offset = tn->first;
+    SuperSet<const Type*>::setPtr TypeSet = tn->second;
+
+    //
+    // If this is the last field, then we are done searching.
+    //
+    if ((++tn) == N->type_end()) {
+      break;
+    }
+
+    //
+    // Get the offset of the next field.
+    //
+    unsigned next_offset = tn->first;
+
+    //
+    // Check to see if any of the types in the current field extend into the
+    // next field.
+    //
+    if (TypeSet) {
+      for (svset<const Type*>::const_iterator ni = TypeSet->begin(),
+           ne = TypeSet->end(); ni != ne; ++ni) {
+        unsigned field_length = TD->getTypeStoreSize (*ni);
+        if ((offset + field_length) > next_offset) {
+          overlaps = true;
+          break;
+        }
+      }
+    }
+  }
+
+  //
+  // Return the result.
+  //
+  return overlaps;
+}
+
+//
+// Method: isTypeSafe()
+//
+// Description:
+//  Determine whether a DSNode represents a piece of memory that is accessed
+//  in a type-safe fasion.
+//
+// Inputs:
+//  N - A pointer to a DSNode representing the memory object.
+//
+// Return value:
+//  true  - The memory object is used in a type-safe fasion.
+//  false - The memory object *may* be used in a type-unsafe fasion.
+//
+template<class dsa> bool
+TypeSafety<dsa>::isTypeSafe (const DSNode * N) {
+  //
+  // If the DSNode is completely folded, then we know for sure that it is not
+  // type-safe.
+  //
+  if (N->isNodeCompletelyFolded())
+    return false;
+
+  //
+  // If the memory object represented by this DSNode can be manipulated by
+  // external code or DSA has otherwise not finished analyzing all operations
+  // on it, declare it type-unsafe.
+  //
+  if (N->isExternalNode() || N->isIncompleteNode())
+    return false;
+
+  //
+  // If the pointer to the memory object came from some source not understood
+  // by DSA or somehow came from/escape to the realm of integers, declare it
+  // type-unsafe.
+  //
+  if (N->isUnknownNode() || N->isIntToPtrNode() || N->isPtrToIntNode()) {
+    return false;
+  }
+
+  //
+  // Scan through all of the fields within the DSNode and see if any overlap.
+  // If they do, then the DSNode is not type-safe.
+  //
+  if (typeFieldsOverlap (N))
+    return false;
+
+  //
+  // We have run out of reasons for this DSNode to be type-unsafe.  Declare it
+  // type-safe.
+  //
+  return true;
+}
+
+//
+// Method: findTypeSafeDSNodes()
+//
+// Description:
+//  Find and record all type-safe DSNodes.
+//
+// Inputs:
+//  Graph - The DSGraph for which we should search for type-safe nodes.
+//
+// Side-effects:
+//  Class level data structures are updated to record which DSNodes are
+//  type-safe.
+//
+template<class dsa> void
+TypeSafety<dsa>::findTypeSafeDSNodes (const DSGraph * Graph) {
+  DSGraph::node_const_iterator N = Graph->node_begin();
+  DSGraph::node_const_iterator NE = Graph->node_end();
+  for (; N != NE; ++N) {
+    if (isTypeSafe (N)) {
+      TypeSafeNodes.insert (&*N);
+    }
+  }
+}
+
+template<class dsa> bool
+TypeSafety<dsa>::runOnModule(Module & M) {
+  //
+  // Get access to prerequisite passes.
+  //
+  TD      = &getAnalysis<TargetData>();
+  dsaPass = &getAnalysis<dsa>();
+
+  //
+  // For every DSGraph, find which DSNodes are type-safe.
+  //
+  findTypeSafeDSNodes (dsaPass->getGlobalsGraph());
+  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
+    if (dsaPass->hasDSGraph (*F)) {
+      findTypeSafeDSNodes (dsaPass->getDSGraph (*F));
+    }
+  }
+
+  return false;
+}
+
+}
+





More information about the llvm-commits mailing list