[llvm-commits] [parallel] CVS: llvm/include/llvm/Analysis/ProfileInfo.h ProfileInfoLoader.h AliasAnalysis.h DSGraph.h DSGraphTraits.h DSNode.h DSSupport.h LoopInfo.h PostDominators.h
Misha Brukman
brukman at cs.uiuc.edu
Mon Mar 1 17:58:46 PST 2004
Changes in directory llvm/include/llvm/Analysis:
ProfileInfo.h added (r1.2.2.1)
ProfileInfoLoader.h added (r1.1.2.1)
AliasAnalysis.h updated: 1.8 -> 1.8.4.1
DSGraph.h updated: 1.64 -> 1.64.4.1
DSGraphTraits.h updated: 1.18 -> 1.18.4.1
DSNode.h updated: 1.33 -> 1.33.4.1
DSSupport.h updated: 1.26 -> 1.26.4.1
LoopInfo.h updated: 1.30 -> 1.30.2.1
PostDominators.h updated: 1.7 -> 1.7.4.1
---
Log message:
Merge from trunk
---
Diffs of the changes: (+381 -89)
Index: llvm/include/llvm/Analysis/ProfileInfo.h
diff -c /dev/null llvm/include/llvm/Analysis/ProfileInfo.h:1.2.2.1
*** /dev/null Mon Mar 1 17:57:29 2004
--- llvm/include/llvm/Analysis/ProfileInfo.h Mon Mar 1 17:57:19 2004
***************
*** 0 ****
--- 1,51 ----
+ //===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- 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 file defines the generic ProfileInfo interface, which is used as the
+ // common interface used by all clients of profiling information, and
+ // implemented either by making static guestimations, or by actually reading in
+ // profiling information gathered by running the program.
+ //
+ // Note that to be useful, all profile-based optimizations should preserve
+ // ProfileInfo, which requires that they notify it when changes to the CFG are
+ // made.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #ifndef LLVM_ANALYSIS_PROFILEINFO_H
+ #define LLVM_ANALYSIS_PROFILEINFO_H
+
+ #include <string>
+
+ namespace llvm {
+ class BasicBlock;
+ class Pass;
+
+ /// createProfileLoaderPass - This function returns a Pass that loads the
+ /// profiling information for the module from the specified filename, making
+ /// it available to the optimizers.
+ Pass *createProfileLoaderPass(const std::string &Filename);
+
+ struct ProfileInfo {
+ virtual ~ProfileInfo(); // We want to be subclassed
+
+ //===------------------------------------------------------------------===//
+ /// Profile Information Queries
+ ///
+ virtual unsigned getExecutionCount(BasicBlock *BB) = 0;
+
+ //===------------------------------------------------------------------===//
+ /// Analysis Update Methods
+ ///
+
+ };
+
+ } // End llvm namespace
+
+ #endif
Index: llvm/include/llvm/Analysis/ProfileInfoLoader.h
diff -c /dev/null llvm/include/llvm/Analysis/ProfileInfoLoader.h:1.1.2.1
*** /dev/null Mon Mar 1 17:57:29 2004
--- llvm/include/llvm/Analysis/ProfileInfoLoader.h Mon Mar 1 17:57:19 2004
***************
*** 0 ****
--- 1,65 ----
+ //===- ProfileInfoLoader.h - Load & convert profile information -*- 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.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // The ProfileInfoLoader class is used to load and represent profiling
+ // information read in from the dump file. If conversions between formats are
+ // needed, it can also do this.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
+ #define LLVM_ANALYSIS_PROFILEINFOLOADER_H
+
+ #include <vector>
+ #include <string>
+ #include <utility>
+
+ namespace llvm {
+
+ class Module;
+ class Function;
+ class BasicBlock;
+
+ class ProfileInfoLoader {
+ Module &M;
+ std::vector<std::string> CommandLines;
+ std::vector<unsigned> FunctionCounts;
+ std::vector<unsigned> BlockCounts;
+ public:
+ // ProfileInfoLoader ctor - Read the specified profiling data file, exiting
+ // the program if the file is invalid or broken.
+ ProfileInfoLoader(const char *ToolName, const std::string &Filename,
+ Module &M);
+
+ unsigned getNumExecutions() const { return CommandLines.size(); }
+ const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
+
+ // getFunctionCounts - This method is used by consumers of function counting
+ // information. If we do not directly have function count information, we
+ // compute it from other, more refined, types of profile information.
+ //
+ void getFunctionCounts(std::vector<std::pair<Function*, unsigned> > &Counts);
+
+ // hasAccurateBlockCounts - Return true if we can synthesize accurate block
+ // frequency information from whatever we have.
+ //
+ bool hasAccurateBlockCounts() const {
+ return !BlockCounts.empty();
+ }
+
+ // getBlockCounts - This method is used by consumers of block counting
+ // information. If we do not directly have block count information, we
+ // compute it from other, more refined, types of profile information.
+ //
+ void getBlockCounts(std::vector<std::pair<BasicBlock*, unsigned> > &Counts);
+ };
+
+ } // End llvm namespace
+
+ #endif
Index: llvm/include/llvm/Analysis/AliasAnalysis.h
diff -u llvm/include/llvm/Analysis/AliasAnalysis.h:1.8 llvm/include/llvm/Analysis/AliasAnalysis.h:1.8.4.1
--- llvm/include/llvm/Analysis/AliasAnalysis.h:1.8 Wed Dec 10 23:05:02 2003
+++ llvm/include/llvm/Analysis/AliasAnalysis.h Mon Mar 1 17:57:19 2004
@@ -31,15 +31,13 @@
#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
#include "llvm/Support/CallSite.h"
-#include "llvm/Pass.h"
+#include "llvm/Pass.h" // Need this for IncludeFile
namespace llvm {
class LoadInst;
class StoreInst;
class TargetData;
-class AnalysisUsage;
-class Pass;
class AliasAnalysis {
const TargetData *TD;
@@ -95,6 +93,11 @@
///
virtual void getMustAliases(Value *P, std::vector<Value*> &RetVals) {}
+ /// pointsToConstantMemory - If the specified pointer is known to point into
+ /// constant global memory, return true. This allows disambiguation of store
+ /// instructions from constant pointers.
+ ///
+ virtual bool pointsToConstantMemory(const Value *P) { return false; }
//===--------------------------------------------------------------------===//
/// Simple mod/ref information...
@@ -114,7 +117,9 @@
/// pointer.
///
virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) {
- return ModRef;
+ // If P points to a constant memory location, the call definitely could not
+ // modify the memory location.
+ return pointsToConstantMemory(P) ? Ref : ModRef;
}
/// getModRefInfo - Return information about whether two call sites may refer
Index: llvm/include/llvm/Analysis/DSGraph.h
diff -u llvm/include/llvm/Analysis/DSGraph.h:1.64 llvm/include/llvm/Analysis/DSGraph.h:1.64.4.1
--- llvm/include/llvm/Analysis/DSGraph.h:1.64 Wed Nov 12 11:58:09 2003
+++ llvm/include/llvm/Analysis/DSGraph.h Mon Mar 1 17:57:19 2004
@@ -7,7 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This header defines the data structure graph.
+// This header defines the data structure graph (DSGraph) and the
+// ReachabilityCloner class.
//
//===----------------------------------------------------------------------===//
@@ -21,13 +22,86 @@
class GlobalValue;
//===----------------------------------------------------------------------===//
+/// DSScalarMap - An instance of this class is used to keep track of all of
+/// which DSNode each scalar in a function points to. This is specialized to
+/// keep track of globals with nodes in the function, and to keep track of the
+/// unique DSNodeHandle being used by the scalar map.
+///
+/// This class is crucial to the efficiency of DSA with some large SCC's. In
+/// these cases, the cost of iterating over the scalar map dominates the cost
+/// of DSA. In all of these cases, the DSA phase is really trying to identify
+/// globals or unique node handles active in the function.
+///
+class DSScalarMap {
+ typedef hash_map<Value*, DSNodeHandle> ValueMapTy;
+ ValueMapTy ValueMap;
+
+ typedef hash_set<GlobalValue*> GlobalSetTy;
+ GlobalSetTy GlobalSet;
+public:
+
+ // Compatibility methods: provide an interface compatible with a map of
+ // Value* to DSNodeHandle's.
+ typedef ValueMapTy::const_iterator const_iterator;
+ typedef ValueMapTy::iterator iterator;
+ iterator begin() { return ValueMap.begin(); }
+ iterator end() { return ValueMap.end(); }
+ const_iterator begin() const { return ValueMap.begin(); }
+ const_iterator end() const { return ValueMap.end(); }
+ iterator find(Value *V) { return ValueMap.find(V); }
+ const_iterator find(Value *V) const { return ValueMap.find(V); }
+ unsigned count(Value *V) const { return ValueMap.count(V); }
+
+ void erase(Value *V) { erase(find(V)); }
+
+ /// replaceScalar - When an instruction needs to be modified, this method can
+ /// be used to update the scalar map to remove the old and insert the new.
+ void replaceScalar(Value *Old, Value *New) {
+ iterator I = find(Old);
+ assert(I != end() && "Old value is not in the map!");
+ ValueMap.insert(std::make_pair(New, I->second));
+ erase(I);
+ }
+
+ DSNodeHandle &operator[](Value *V) {
+ std::pair<iterator,bool> IP =
+ ValueMap.insert(std::make_pair(V, DSNodeHandle()));
+ if (IP.second) { // Inserted the new entry into the map.
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(V))
+ GlobalSet.insert(GV);
+ }
+ return IP.first->second;
+ }
+
+ void erase(iterator I) {
+ assert(I != ValueMap.end() && "Cannot erase end!");
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(I->first))
+ GlobalSet.erase(GV);
+ ValueMap.erase(I);
+ }
+
+ void clear() {
+ ValueMap.clear();
+ GlobalSet.clear();
+ }
+
+ // Access to the global set: the set of all globals currently in the
+ // scalar map.
+ typedef GlobalSetTy::const_iterator global_iterator;
+ global_iterator global_begin() const { return GlobalSet.begin(); }
+ global_iterator global_end() const { return GlobalSet.end(); }
+};
+
+
+//===----------------------------------------------------------------------===//
/// DSGraph - The graph that represents a function.
///
struct DSGraph {
// Public data-type declarations...
- typedef hash_map<Value*, DSNodeHandle> ScalarMapTy;
+ typedef DSScalarMap ScalarMapTy;
typedef hash_map<Function*, DSNodeHandle> ReturnNodesTy;
- typedef hash_set<const GlobalValue*> GlobalSetTy;
+ typedef hash_set<GlobalValue*> GlobalSetTy;
+ typedef ilist<DSNode> NodeListTy;
/// NodeMapTy - This data type is used when cloning one graph into another to
/// keep track of the correspondence between the nodes in the old and new
@@ -37,7 +111,7 @@
DSGraph *GlobalsGraph; // Pointer to the common graph of global objects
bool PrintAuxCalls; // Should this graph print the Aux calls vector?
- std::vector<DSNode*> Nodes;
+ NodeListTy Nodes;
ScalarMapTy ScalarMap;
// ReturnNodes - A return value for every function merged into this graph.
@@ -104,10 +178,14 @@
void setPrintAuxCalls() { PrintAuxCalls = true; }
bool shouldPrintAuxCalls() const { return PrintAuxCalls; }
- /// getNodes - Get a vector of all the nodes in the graph
- ///
- const std::vector<DSNode*> &getNodes() const { return Nodes; }
- std::vector<DSNode*> &getNodes() { return Nodes; }
+ /// node_iterator/begin/end - Iterate over all of the nodes in the graph. Be
+ /// extremely careful with these methods because any merging of nodes could
+ /// cause the node to be removed from this list. This means that if you are
+ /// iterating over nodes and doing something that could cause _any_ node to
+ /// merge, your node_iterators into this graph can be invalidated.
+ typedef NodeListTy::compat_iterator node_iterator;
+ node_iterator node_begin() const { return Nodes.compat_begin(); }
+ node_iterator node_end() const { return Nodes.compat_end(); }
/// getFunctionNames - Return a space separated list of the name of the
/// functions in this graph (if any)
@@ -116,6 +194,7 @@
/// addNode - Add a new node to the graph.
///
void addNode(DSNode *N) { Nodes.push_back(N); }
+ void unlinkNode(DSNode *N) { Nodes.remove(N); }
/// getScalarMap - Get a map that describes what the nodes the scalars in this
/// function point to...
@@ -202,8 +281,8 @@
/// is useful for clearing out markers like Incomplete.
///
void maskNodeTypes(unsigned Mask) {
- for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
- Nodes[i]->maskNodeTypes(Mask);
+ for (node_iterator I = node_begin(), E = node_end(); I != E; ++I)
+ (*I)->maskNodeTypes(Mask);
}
void maskIncompleteMarkers() { maskNodeTypes(~DSNode::Incomplete); }
@@ -240,24 +319,11 @@
DontCloneAuxCallNodes = 1 << 2, CloneAuxCallNodes = 0,
StripModRefBits = 1 << 3, KeepModRefBits = 0,
StripIncompleteBit = 1 << 4, KeepIncompleteBit = 0,
+ UpdateInlinedGlobals = 1 << 5, DontUpdateInlinedGlobals = 0,
};
-private:
- void cloneReachableNodes(const DSNode* Node,
- unsigned BitsToClear,
- NodeMapTy& OldNodeMap,
- NodeMapTy& CompletedNodeMap);
-
-public:
void updateFromGlobalGraph();
- void cloneReachableSubgraph(const DSGraph& G,
- const hash_set<const DSNode*>& RootNodes,
- NodeMapTy& OldNodeMap,
- NodeMapTy& CompletedNodeMap,
- unsigned CloneFlags = 0);
-
-
/// computeNodeMapping - Given roots in two different DSGraphs, traverse the
/// nodes reachable from the two graphs, computing the mapping of nodes from
/// the first to the second graph.
@@ -270,6 +336,8 @@
/// cloneInto - Clone the specified DSGraph into the current graph. The
/// translated ScalarMap for the old function is filled into the OldValMap
/// member, and the translated ReturnNodes map is returned into ReturnNodes.
+ /// OldNodeMap contains a mapping from the original nodes to the newly cloned
+ /// nodes.
///
/// The CloneFlags member controls various aspects of the cloning process.
///
@@ -294,7 +362,7 @@
// Methods for checking to make sure graphs are well formed...
void AssertNodeInGraph(const DSNode *N) const {
- assert((!N || find(Nodes.begin(), Nodes.end(), N) != Nodes.end()) &&
+ assert((!N || N->getParentGraph() == this) &&
"AssertNodeInGraph: Node is not in graph!");
}
void AssertNodeContainsGlobal(const DSNode *N, GlobalValue *GV) const {
@@ -321,13 +389,6 @@
void AssertGraphOK() const;
- /// mergeInGlobalsGraph - This method is useful for clients to incorporate the
- /// globals graph into the DS, BU or TD graph for a function. This code
- /// retains all globals, i.e., does not delete unreachable globals after they
- /// are inlined.
- ///
- void mergeInGlobalsGraph();
-
/// removeTriviallyDeadNodes - After the graph has been constructed, this
/// method removes all unreachable nodes that are created because they got
/// merged with other nodes in the graph. This is used as the first step of
@@ -336,6 +397,49 @@
void removeTriviallyDeadNodes();
};
+
+ /// ReachabilityCloner - This class is used to incrementally clone and merge
+ /// nodes from a non-changing source graph into a potentially mutating
+ /// destination graph. Nodes are only cloned over on demand, either in
+ /// responds to a merge() or getClonedNH() call. When a node is cloned over,
+ /// all of the nodes reachable from it are automatically brought over as well.
+ class ReachabilityCloner {
+ DSGraph &Dest;
+ const DSGraph &Src;
+
+ /// BitsToKeep - These bits are retained from the source node when the
+ /// source nodes are merged into the destination graph.
+ unsigned BitsToKeep;
+ unsigned CloneFlags;
+
+ // NodeMap - A mapping from nodes in the source graph to the nodes that
+ // represent them in the destination graph.
+ DSGraph::NodeMapTy NodeMap;
+ public:
+ ReachabilityCloner(DSGraph &dest, const DSGraph &src, unsigned cloneFlags)
+ : Dest(dest), Src(src), CloneFlags(cloneFlags) {
+ assert(&Dest != &Src && "Cannot clone from graph to same graph!");
+ BitsToKeep = ~DSNode::DEAD;
+ if (CloneFlags & DSGraph::StripAllocaBit)
+ BitsToKeep &= ~DSNode::AllocaNode;
+ if (CloneFlags & DSGraph::StripModRefBits)
+ BitsToKeep &= ~(DSNode::Modified | DSNode::Read);
+ if (CloneFlags & DSGraph::StripIncompleteBit)
+ BitsToKeep &= ~DSNode::Incomplete;
+ }
+
+ DSNodeHandle getClonedNH(const DSNodeHandle &SrcNH);
+
+ void merge(const DSNodeHandle &NH, const DSNodeHandle &SrcNH);
+
+ /// mergeCallSite - Merge the nodes reachable from the specified src call
+ /// site into the nodes reachable from DestCS.
+ void mergeCallSite(const DSCallSite &DestCS, const DSCallSite &SrcCS);
+
+ bool clonedNode() const { return !NodeMap.empty(); }
+
+ void destroy() { NodeMap.clear(); }
+ };
} // End llvm namespace
#endif
Index: llvm/include/llvm/Analysis/DSGraphTraits.h
diff -u llvm/include/llvm/Analysis/DSGraphTraits.h:1.18 llvm/include/llvm/Analysis/DSGraphTraits.h:1.18.4.1
--- llvm/include/llvm/Analysis/DSGraphTraits.h:1.18 Tue Nov 11 16:41:30 2003
+++ llvm/include/llvm/Analysis/DSGraphTraits.h Mon Mar 1 17:57:19 2004
@@ -33,10 +33,14 @@
DSNodeIterator(NodeTy *N) : Node(N), Offset(0) {} // begin iterator
DSNodeIterator(NodeTy *N, bool) : Node(N) { // Create end iterator
- Offset = N->getNumLinks() << DS::PointerShift;
- if (Offset == 0 && Node->getForwardNode() &&
- Node->isDeadNode()) // Model Forward link
- Offset += DS::PointerSize;
+ if (N != 0) {
+ Offset = N->getNumLinks() << DS::PointerShift;
+ if (Offset == 0 && Node->getForwardNode() &&
+ Node->isDeadNode()) // Model Forward link
+ Offset += DS::PointerSize;
+ } else {
+ Offset = 0;
+ }
}
public:
DSNodeIterator(const DSNodeHandle &NH)
@@ -115,13 +119,12 @@
typedef std::pointer_to_unary_function<DSNode *, DSNode&> DerefFun;
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef mapped_iterator<std::vector<DSNode*>::iterator,
- DerefFun> nodes_iterator;
+ typedef mapped_iterator<DSGraph::node_iterator, DerefFun> nodes_iterator;
static nodes_iterator nodes_begin(DSGraph *G) {
- return map_iterator(G->getNodes().begin(), DerefFun(dereference));
+ return map_iterator(G->node_begin(), DerefFun(dereference));
}
static nodes_iterator nodes_end(DSGraph *G) {
- return map_iterator(G->getNodes().end(), DerefFun(dereference));
+ return map_iterator(G->node_end(), DerefFun(dereference));
}
static ChildIteratorType child_begin(NodeType *N) { return N->begin(); }
@@ -135,13 +138,12 @@
typedef std::pointer_to_unary_function<const DSNode *,const DSNode&> DerefFun;
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
- typedef mapped_iterator<std::vector<DSNode*>::const_iterator,
- DerefFun> nodes_iterator;
+ typedef mapped_iterator<DSGraph::node_iterator, DerefFun> nodes_iterator;
static nodes_iterator nodes_begin(const DSGraph *G) {
- return map_iterator(G->getNodes().begin(), DerefFun(dereferenceC));
+ return map_iterator(G->node_begin(), DerefFun(dereferenceC));
}
static nodes_iterator nodes_end(const DSGraph *G) {
- return map_iterator(G->getNodes().end(), DerefFun(dereferenceC));
+ return map_iterator(G->node_end(), DerefFun(dereferenceC));
}
static ChildIteratorType child_begin(const NodeType *N) { return N->begin(); }
Index: llvm/include/llvm/Analysis/DSNode.h
diff -u llvm/include/llvm/Analysis/DSNode.h:1.33 llvm/include/llvm/Analysis/DSNode.h:1.33.4.1
--- llvm/include/llvm/Analysis/DSNode.h:1.33 Tue Nov 11 16:41:30 2003
+++ llvm/include/llvm/Analysis/DSNode.h Mon Mar 1 17:57:19 2004
@@ -42,6 +42,11 @@
/// null.
DSNodeHandle ForwardNH;
+ /// Next, Prev - These instance variables are used to keep the node on a
+ /// doubly-linked ilist in the DSGraph.
+ DSNode *Next, *Prev;
+ friend class ilist_traits<DSNode>;
+
/// Size - The current size of the node. This should be equal to the size of
/// the current type record.
///
@@ -97,9 +102,16 @@
private:
unsigned short NodeType;
public:
-
+
+ /// DSNode ctor - Create a node of the specified type, inserting it into the
+ /// specified graph.
DSNode(const Type *T, DSGraph *G);
- DSNode(const DSNode &, DSGraph *G);
+
+ /// DSNode "copy ctor" - Copy the specified node, inserting it into the
+ /// specified graph. If NullLinks is true, then null out all of the links,
+ /// but keep the same number of them. This can be used for efficiency if the
+ /// links are just going to be clobbered anyway.
+ DSNode(const DSNode &, DSGraph *G, bool NullLinks = false);
~DSNode() {
dropAllReferences();
@@ -145,10 +157,20 @@
/// getForwardNode - This method returns the node that this node is forwarded
/// to, if any.
DSNode *getForwardNode() const { return ForwardNH.getNode(); }
+
+ /// isForwarding - Return true if this node is forwarding to another.
+ ///
+ bool isForwarding() const { return !ForwardNH.isNull(); }
+
+ /// stopForwarding - When the last reference to this forwarding node has been
+ /// dropped, delete the node.
void stopForwarding() {
- assert(!ForwardNH.isNull() &&
+ assert(isForwarding() &&
"Node isn't forwarding, cannot stopForwarding!");
ForwardNH.setNode(0);
+ assert(ParentGraph == 0 &&
+ "Forwarding nodes must have been removed from graph!");
+ delete this;
}
/// hasLink - Return true if this memory object has a link in slot #LinkNo
@@ -241,14 +263,24 @@
/// also marks the node with the 'G' flag if it does not already have it.
///
void addGlobal(GlobalValue *GV);
+ void mergeGlobals(const std::vector<GlobalValue*> &RHS);
const std::vector<GlobalValue*> &getGlobals() const { return Globals; }
+ typedef std::vector<GlobalValue*>::const_iterator global_iterator;
+ global_iterator global_begin() const { return Globals.begin(); }
+ global_iterator global_end() const { return Globals.end(); }
+
+
/// maskNodeTypes - Apply a mask to the node types bitfield.
///
void maskNodeTypes(unsigned Mask) {
NodeType &= Mask;
}
+ void mergeNodeFlags(unsigned RHS) {
+ NodeType |= RHS;
+ }
+
/// getNodeFlags - Return all of the flags set on the node. If the DEAD flag
/// is set, hide it from the caller.
unsigned getNodeFlags() const { return NodeType & ~DEAD; }
@@ -273,6 +305,7 @@
DSNode *setIncompleteMarker() { NodeType |= Incomplete; return this; }
DSNode *setModifiedMarker() { NodeType |= Modified; return this; }
DSNode *setReadMarker() { NodeType |= Read; return this; }
+ DSNode *setArrayMarker() { NodeType |= Array; return this; }
void makeNodeDead() {
Globals.clear();
@@ -292,7 +325,7 @@
void dropAllReferences() {
Links.clear();
- if (!ForwardNH.isNull())
+ if (isForwarding())
ForwardNH.setNode(0);
}
@@ -313,22 +346,46 @@
static void MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH);
};
+//===----------------------------------------------------------------------===//
+// Define the ilist_traits specialization for the DSGraph ilist.
+//
+template<>
+struct ilist_traits<DSNode> {
+ static DSNode *getPrev(const DSNode *N) { return N->Prev; }
+ static DSNode *getNext(const DSNode *N) { return N->Next; }
+
+ static void setPrev(DSNode *N, DSNode *Prev) { N->Prev = Prev; }
+ static void setNext(DSNode *N, DSNode *Next) { N->Next = Next; }
+
+ static DSNode *createNode() { return new DSNode(0,0); }
+ //static DSNode *createNode(const DSNode &V) { return new DSNode(V); }
+
+
+ void addNodeToList(DSNode *NTy) {}
+ void removeNodeFromList(DSNode *NTy) {}
+ void transferNodesFromList(iplist<DSNode, ilist_traits> &L2,
+ ilist_iterator<DSNode> first,
+ ilist_iterator<DSNode> last) {}
+};
+
+template<>
+struct ilist_traits<const DSNode> : public ilist_traits<DSNode> {};
//===----------------------------------------------------------------------===//
// Define inline DSNodeHandle functions that depend on the definition of DSNode
//
inline DSNode *DSNodeHandle::getNode() const {
assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
- !N->ForwardNH.isNull()) && "Node handle offset out of range!");
- if (!N || N->ForwardNH.isNull())
+ N->isForwarding()) && "Node handle offset out of range!");
+ if (N == 0 || !N->isForwarding())
return N;
return HandleForwarding();
}
-inline void DSNodeHandle::setNode(DSNode *n) {
- assert(!n || !n->getForwardNode() && "Cannot set node to a forwarded node!");
- if (N) N->NumReferrers--;
+inline void DSNodeHandle::setNode(DSNode *n) const {
+ assert(!n || !n->isForwarding() && "Cannot set node to a forwarded node!");
+ if (N) getNode()->NumReferrers--;
N = n;
if (N) {
N->NumReferrers++;
@@ -340,7 +397,7 @@
}
assert(!N || ((N->NodeType & DSNode::DEAD) == 0));
assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
- !N->ForwardNH.isNull()) && "Node handle offset out of range!");
+ N->isForwarding()) && "Node handle offset out of range!");
}
inline bool DSNodeHandle::hasLink(unsigned Num) const {
@@ -377,11 +434,14 @@
/// mergeWith - Merge the logical node pointed to by 'this' with the node
/// pointed to by 'N'.
///
-inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) {
- if (N != 0)
+inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) const {
+ if (!isNull())
getNode()->mergeWith(Node, Offset);
- else // No node to merge with, so just point to Node
- *this = Node;
+ else { // No node to merge with, so just point to Node
+ Offset = 0;
+ setNode(Node.getNode());
+ Offset = Node.getOffset();
+ }
}
} // End llvm namespace
Index: llvm/include/llvm/Analysis/DSSupport.h
diff -u llvm/include/llvm/Analysis/DSSupport.h:1.26 llvm/include/llvm/Analysis/DSSupport.h:1.26.4.1
--- llvm/include/llvm/Analysis/DSSupport.h:1.26 Tue Nov 11 16:41:31 2003
+++ llvm/include/llvm/Analysis/DSSupport.h Mon Mar 1 17:57:19 2004
@@ -28,6 +28,7 @@
class DSNode; // Each node in the graph
class DSGraph; // A graph for a function
+class ReachabilityCloner;
namespace DS { // FIXME: After the paper, this should get cleaned up
enum { PointerShift = 2, // 64bit ptrs = 3, 32 bit ptrs = 2
@@ -76,6 +77,7 @@
}
bool operator>(const DSNodeHandle &H) const { return H < *this; }
bool operator==(const DSNodeHandle &H) const { // Allow comparison
+ // getNode can change the offset, so we must call getNode() first.
return getNode() == H.getNode() && Offset == H.Offset;
}
bool operator!=(const DSNodeHandle &H) const { return !operator==(H); }
@@ -93,7 +95,7 @@
inline DSNode *getNode() const; // Defined inline in DSNode.h
unsigned getOffset() const { return Offset; }
- inline void setNode(DSNode *N); // Defined inline in DSNode.h
+ inline void setNode(DSNode *N) const; // Defined inline in DSNode.h
void setOffset(unsigned O) {
//assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
// !N->ForwardNH.isNull()) && "Node handle offset out of range!");
@@ -108,7 +110,7 @@
/// mergeWith - Merge the logical node pointed to by 'this' with the node
/// pointed to by 'N'.
///
- void mergeWith(const DSNodeHandle &N);
+ void mergeWith(const DSNodeHandle &N) const;
// hasLink - Return true if there is a link at the specified offset...
inline bool hasLink(unsigned Num) const;
@@ -127,7 +129,8 @@
} // End llvm namespace
namespace std {
- inline void swap(llvm::DSNodeHandle &NH1, llvm::DSNodeHandle &NH2) { NH1.swap(NH2); }
+ template<>
+ inline void swap<llvm::DSNodeHandle>(llvm::DSNodeHandle &NH1, llvm::DSNodeHandle &NH2) { NH1.swap(NH2); }
}
namespace llvm {
@@ -148,7 +151,7 @@
const hash_map<const DSNode*, DSNode*> &NodeMap) {
if (DSNode *N = Src.getNode()) {
hash_map<const DSNode*, DSNode*>::const_iterator I = NodeMap.find(N);
- assert(I != NodeMap.end() && "Not not in mapping!");
+ assert(I != NodeMap.end() && "Node not in mapping!");
NH.setOffset(Src.getOffset());
NH.setNode(I->second);
@@ -159,13 +162,17 @@
const hash_map<const DSNode*, DSNodeHandle> &NodeMap) {
if (DSNode *N = Src.getNode()) {
hash_map<const DSNode*, DSNodeHandle>::const_iterator I = NodeMap.find(N);
- assert(I != NodeMap.end() && "Not not in mapping!");
+ assert(I != NodeMap.end() && "Node not in mapping!");
NH.setOffset(Src.getOffset()+I->second.getOffset());
NH.setNode(I->second.getNode());
}
}
+ static void InitNH(DSNodeHandle &NH, const DSNodeHandle &Src,
+ ReachabilityCloner &RC);
+
+
DSCallSite(); // DO NOT IMPLEMENT
public:
/// Constructor. Note - This ctor destroys the argument vector passed in. On
@@ -193,7 +200,7 @@
/// This is useful when moving a call site from one graph to another.
///
template<typename MapTy>
- DSCallSite(const DSCallSite &FromCall, const MapTy &NodeMap) {
+ DSCallSite(const DSCallSite &FromCall, MapTy &NodeMap) {
Site = FromCall.Site;
InitNH(RetVal, FromCall.RetVal, NodeMap);
InitNH(CalleeN, FromCall.CalleeN, NodeMap);
@@ -234,7 +241,7 @@
assert(!CalleeN.getNode() && CalleeF); return CalleeF;
}
- unsigned getNumPtrArgs() const { return CallArgs.size(); }
+ unsigned getNumPtrArgs() const { return CallArgs.size(); }
DSNodeHandle &getPtrArg(unsigned i) {
assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
@@ -255,7 +262,7 @@
}
}
- // MergeWith - Merge the return value and parameters of the these two call
+ // mergeWith - Merge the return value and parameters of the these two call
// sites.
void mergeWith(DSCallSite &CS) {
getRetVal().mergeWith(CS.getRetVal());
@@ -288,14 +295,16 @@
}
bool operator==(const DSCallSite &CS) const {
- return RetVal == CS.RetVal && CalleeN == CS.CalleeN &&
- CalleeF == CS.CalleeF && CallArgs == CS.CallArgs;
+ return CalleeF == CS.CalleeF && CalleeN == CS.CalleeN &&
+ RetVal == CS.RetVal && CallArgs == CS.CallArgs;
}
};
} // End llvm namespace
namespace std {
- inline void swap(llvm::DSCallSite &CS1, llvm::DSCallSite &CS2) { CS1.swap(CS2); }
+ template<>
+ inline void swap<llvm::DSCallSite>(llvm::DSCallSite &CS1,
+ llvm::DSCallSite &CS2) { CS1.swap(CS2); }
}
#endif
Index: llvm/include/llvm/Analysis/LoopInfo.h
diff -u llvm/include/llvm/Analysis/LoopInfo.h:1.30 llvm/include/llvm/Analysis/LoopInfo.h:1.30.2.1
--- llvm/include/llvm/Analysis/LoopInfo.h:1.30 Wed Jan 7 18:08:22 2004
+++ llvm/include/llvm/Analysis/LoopInfo.h Mon Mar 1 17:57:19 2004
@@ -54,6 +54,7 @@
Loop *getParentLoop() const { return ParentLoop; }
/// contains - Return true of the specified basic block is in this loop
+ ///
bool contains(const BasicBlock *BB) const;
/// iterator/begin/end - Return the loops contained entirely within this loop.
Index: llvm/include/llvm/Analysis/PostDominators.h
diff -u llvm/include/llvm/Analysis/PostDominators.h:1.7 llvm/include/llvm/Analysis/PostDominators.h:1.7.4.1
--- llvm/include/llvm/Analysis/PostDominators.h:1.7 Sat Dec 6 18:35:19 2003
+++ llvm/include/llvm/Analysis/PostDominators.h Mon Mar 1 17:57:19 2004
@@ -18,7 +18,6 @@
namespace llvm {
-
/// PostDominatorSet Class - Concrete subclass of DominatorSetBase that is used
/// to compute the post-dominator set. Because there can be multiple exit nodes
/// in an LLVM function, we calculate post dominators with a special null block
@@ -31,19 +30,17 @@
virtual bool runOnFunction(Function &F);
- // getAnalysisUsage - This pass does not modify the function at all.
- //
+ /// getAnalysisUsage - This pass does not modify the function at all.
+ ///
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
};
-
-//===-------------------------------------
-// ImmediatePostDominators Class - Concrete subclass of ImmediateDominatorsBase
-// that is used to compute the immediate post-dominators.
-//
+/// ImmediatePostDominators Class - Concrete subclass of ImmediateDominatorsBase
+/// that is used to compute the immediate post-dominators.
+///
struct ImmediatePostDominators : public ImmediateDominatorsBase {
ImmediatePostDominators() : ImmediateDominatorsBase(true) {}
@@ -64,10 +61,9 @@
};
-//===-------------------------------------
-// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
-// compute the a post-dominator tree.
-//
+/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
+/// compute the a post-dominator tree.
+///
struct PostDominatorTree : public DominatorTreeBase {
PostDominatorTree() : DominatorTreeBase(true) {}
@@ -88,10 +84,9 @@
};
-//===-------------------------------------
-// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is
-// used to compute the a post-dominance frontier.
-//
+/// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is
+/// used to compute the a post-dominance frontier.
+///
struct PostDominanceFrontier : public DominanceFrontierBase {
PostDominanceFrontier() : DominanceFrontierBase(true) {}
More information about the llvm-commits
mailing list