[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