[llvm] r266262 - [CFLAA] Fix up code style a bit. NFC.
George Burgess IV via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 13 16:27:37 PDT 2016
Author: gbiv
Date: Wed Apr 13 18:27:37 2016
New Revision: 266262
URL: http://llvm.org/viewvc/llvm-project?rev=266262&view=rev
Log:
[CFLAA] Fix up code style a bit. NFC.
Modified:
llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
llvm/trunk/lib/Analysis/StratifiedSets.h
Modified: llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp?rev=266262&r1=266261&r2=266262&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp Wed Apr 13 18:27:37 2016
@@ -62,7 +62,7 @@ CFLAAResult::CFLAAResult() : AAResultBas
CFLAAResult::CFLAAResult(CFLAAResult &&Arg) : AAResultBase(std::move(Arg)) {}
CFLAAResult::~CFLAAResult() {}
-// \brief Information we have about a function and would like to keep around
+/// Information we have about a function and would like to keep around.
struct CFLAAResult::FunctionInfo {
StratifiedSets<Value *> Sets;
// Lots of functions have < 4 returns. Adjust as necessary.
@@ -72,33 +72,31 @@ struct CFLAAResult::FunctionInfo {
: Sets(std::move(S)), ReturnedValues(std::move(RV)) {}
};
-// Try to go from a Value* to a Function*. Never returns nullptr.
+/// Try to go from a Value* to a Function*. Never returns nullptr.
static Optional<Function *> parentFunctionOfValue(Value *);
-// Returns possible functions called by the Inst* into the given
-// SmallVectorImpl. Returns true if targets found, false otherwise.
-// This is templated because InvokeInst/CallInst give us the same
-// set of functions that we care about, and I don't like repeating
-// myself.
+/// Returns possible functions called by the Inst* into the given
+/// SmallVectorImpl. Returns true if targets found, false otherwise. This is
+/// templated so we can use it with CallInsts and InvokeInsts.
template <typename Inst>
static bool getPossibleTargets(Inst *, SmallVectorImpl<Function *> &);
-// Some instructions need to have their users tracked. Instructions like
-// `add` require you to get the users of the Instruction* itself, other
-// instructions like `store` require you to get the users of the first
-// operand. This function gets the "proper" value to track for each
-// type of instruction we support.
+/// Some instructions need to have their users tracked. Instructions like
+/// `add` require you to get the users of the Instruction* itself, other
+/// instructions like `store` require you to get the users of the first
+/// operand. This function gets the "proper" value to track for each
+/// type of instruction we support.
static Optional<Value *> getTargetValue(Instruction *);
-// There are certain instructions (i.e. FenceInst, etc.) that we ignore.
-// This notes that we should ignore those.
+/// Determines whether or not we an instruction is useless to us (e.g.
+/// FenceInst)
static bool hasUsefulEdges(Instruction *);
const StratifiedIndex StratifiedLink::SetSentinel =
std::numeric_limits<StratifiedIndex>::max();
namespace {
-// StratifiedInfo Attribute things.
+/// StratifiedInfo Attribute things.
typedef unsigned StratifiedAttr;
LLVM_CONSTEXPR unsigned MaxStratifiedAttrIndex = NumStratifiedAttrs;
LLVM_CONSTEXPR unsigned AttrAllIndex = 0;
@@ -112,53 +110,53 @@ LLVM_CONSTEXPR StratifiedAttr AttrNone =
LLVM_CONSTEXPR StratifiedAttr AttrUnknown = 1 << AttrUnknownIndex;
LLVM_CONSTEXPR StratifiedAttr AttrAll = ~AttrNone;
-// \brief StratifiedSets call for knowledge of "direction", so this is how we
-// represent that locally.
+/// StratifiedSets call for knowledge of "direction", so this is how we
+/// represent that locally.
enum class Level { Same, Above, Below };
-// \brief Edges can be one of four "weights" -- each weight must have an inverse
-// weight (Assign has Assign; Reference has Dereference).
+/// Edges can be one of four "weights" -- each weight must have an inverse
+/// weight (Assign has Assign; Reference has Dereference).
enum class EdgeType {
- // The weight assigned when assigning from or to a value. For example, in:
- // %b = getelementptr %a, 0
- // ...The relationships are %b assign %a, and %a assign %b. This used to be
- // two edges, but having a distinction bought us nothing.
+ /// The weight assigned when assigning from or to a value. For example, in:
+ /// %b = getelementptr %a, 0
+ /// ...The relationships are %b assign %a, and %a assign %b. This used to be
+ /// two edges, but having a distinction bought us nothing.
Assign,
- // The edge used when we have an edge going from some handle to a Value.
- // Examples of this include:
- // %b = load %a (%b Dereference %a)
- // %b = extractelement %a, 0 (%a Dereference %b)
+ /// The edge used when we have an edge going from some handle to a Value.
+ /// Examples of this include:
+ /// %b = load %a (%b Dereference %a)
+ /// %b = extractelement %a, 0 (%a Dereference %b)
Dereference,
- // The edge used when our edge goes from a value to a handle that may have
- // contained it at some point. Examples:
- // %b = load %a (%a Reference %b)
- // %b = extractelement %a, 0 (%b Reference %a)
+ /// The edge used when our edge goes from a value to a handle that may have
+ /// contained it at some point. Examples:
+ /// %b = load %a (%a Reference %b)
+ /// %b = extractelement %a, 0 (%b Reference %a)
Reference
};
// \brief Encodes the notion of a "use"
struct Edge {
- // \brief Which value the edge is coming from
+ /// Which value the edge is coming from
Value *From;
- // \brief Which value the edge is pointing to
+ /// Which value the edge is pointing to
Value *To;
- // \brief Edge weight
+ /// Edge weight
EdgeType Weight;
- // \brief Whether we aliased any external values along the way that may be
- // invisible to the analysis (i.e. landingpad for exceptions, calls for
- // interprocedural analysis, etc.)
+ /// Whether we aliased any external values along the way that may be
+ /// invisible to the analysis (i.e. landingpad for exceptions, calls for
+ /// interprocedural analysis, etc.)
StratifiedAttrs AdditionalAttrs;
Edge(Value *From, Value *To, EdgeType W, StratifiedAttrs A)
: From(From), To(To), Weight(W), AdditionalAttrs(A) {}
};
-// \brief Gets the edges our graph should have, based on an Instruction*
+/// Gets the edges our graph should have, based on an Instruction*
class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
CFLAAResult &AA;
SmallVectorImpl<Edge> &Output;
@@ -258,8 +256,8 @@ public:
return Fn->isDeclaration() || !Fn->hasLocalLinkage();
}
- // Gets whether the sets at Index1 above, below, or equal to the sets at
- // Index2. Returns None if they are not in the same set chain.
+ /// Gets whether the sets at Index1 above, below, or equal to the sets at
+ /// Index2. Returns None if they are not in the same set chain.
static Optional<Level> getIndexRelation(const StratifiedSets<Value *> &Sets,
StratifiedIndex Index1,
StratifiedIndex Index2) {
@@ -291,8 +289,8 @@ public:
const unsigned MaxSupportedArgs = 50;
assert(Fns.size() > 0);
- // I put this here to give us an upper bound on time taken by IPA. Is it
- // really (realistically) needed? Keep in mind that we do have an n^2 algo.
+ // This algorithm is n^2, so an arbitrary upper-bound of 50 args was
+ // selected, so it doesn't take too long in insane cases.
if (std::distance(Args.begin(), Args.end()) > (int)MaxSupportedArgs)
return false;
@@ -351,12 +349,12 @@ public:
if (Parameters.size() != Arguments.size())
return false;
- // Adding edges between arguments for arguments that may end up aliasing
- // each other. This is necessary for functions such as
- // void foo(int** a, int** b) { *a = *b; }
- // (Technically, the proper sets for this would be those below
- // Arguments[I] and Arguments[X], but our algorithm will produce
- // extremely similar, and equally correct, results either way)
+ /// Adding edges between arguments for arguments that may end up aliasing
+ /// each other. This is necessary for functions such as
+ /// void foo(int** a, int** b) { *a = *b; }
+ /// (Technically, the proper sets for this would be those below
+ /// Arguments[I] and Arguments[X], but our algorithm will produce
+ /// extremely similar, and equally correct, results either way)
for (unsigned I = 0, E = Arguments.size(); I != E; ++I) {
auto &MainVal = Arguments[I];
auto &MainInfo = Parameters[I];
@@ -406,11 +404,10 @@ public:
void visitInvokeInst(InvokeInst &Inst) { visitCallLikeInst(Inst); }
- // Because vectors/aggregates are immutable and unaddressable,
- // there's nothing we can do to coax a value out of them, other
- // than calling Extract{Element,Value}. We can effectively treat
- // them as pointers to arbitrary memory locations we can store in
- // and load from.
+ /// Because vectors/aggregates are immutable and unaddressable, there's
+ /// nothing we can do to coax a value out of them, other than calling
+ /// Extract{Element,Value}. We can effectively treat them as pointers to
+ /// arbitrary memory locations we can store in and load from.
void visitExtractElementInst(ExtractElementInst &Inst) {
auto *Ptr = Inst.getVectorOperand();
auto *Val = &Inst;
@@ -464,16 +461,16 @@ public:
}
};
-// For a given instruction, we need to know which Value* to get the
-// users of in order to build our graph. In some cases (i.e. add),
-// we simply need the Instruction*. In other cases (i.e. store),
-// finding the users of the Instruction* is useless; we need to find
-// the users of the first operand. This handles determining which
-// value to follow for us.
-//
-// Note: we *need* to keep this in sync with GetEdgesVisitor. Add
-// something to GetEdgesVisitor, add it here -- remove something from
-// GetEdgesVisitor, remove it here.
+/// For a given instruction, we need to know which Value* to get the
+/// users of in order to build our graph. In some cases (i.e. add),
+/// we simply need the Instruction*. In other cases (i.e. store),
+/// finding the users of the Instruction* is useless; we need to find
+/// the users of the first operand. This handles determining which
+/// value to follow for us.
+///
+/// Note: we *need* to keep this in sync with GetEdgesVisitor. Add
+/// something to GetEdgesVisitor, add it here -- remove something from
+/// GetEdgesVisitor, remove it here.
class GetTargetValueVisitor
: public InstVisitor<GetTargetValueVisitor, Value *> {
public:
@@ -498,7 +495,7 @@ public:
}
};
-// Set building requires a weighted bidirectional graph.
+/// Set building requires a weighted bidirectional graph.
template <typename EdgeTypeT> class WeightedBidirectionalGraph {
public:
typedef std::size_t Node;
@@ -531,12 +528,10 @@ private:
NodeImpl &getNode(Node N) { return NodeImpls[N]; }
public:
- // ----- Various Edge iterators for the graph ----- //
-
- // \brief Iterator for edges. Because this graph is bidirected, we don't
- // allow modification of the edges using this iterator. Additionally, the
- // iterator becomes invalid if you add edges to or from the node you're
- // getting the edges of.
+ /// \brief Iterator for edges. Because this graph is bidirected, we don't
+ /// allow modification of the edges using this iterator. Additionally, the
+ /// iterator becomes invalid if you add edges to or from the node you're
+ /// getting the edges of.
struct EdgeIterator : public std::iterator<std::forward_iterator_tag,
std::tuple<EdgeTypeT, Node *>> {
EdgeIterator(const typename std::vector<Edge>::const_iterator &Iter)
@@ -573,7 +568,7 @@ public:
std::tuple<EdgeTypeT, Node> Store;
};
- // Wrapper for EdgeIterator with begin()/end() calls.
+ /// Wrapper for EdgeIterator with begin()/end() calls.
struct EdgeIterable {
EdgeIterable(const std::vector<Edge> &Edges)
: BeginIter(Edges.begin()), EndIter(Edges.end()) {}
@@ -617,16 +612,16 @@ public:
ToNode.Edges.push_back(Edge(ReverseWeight, From));
}
- EdgeIterable edgesFor(const Node &N) const {
+ iterator_range<EdgeIterator> edgesFor(const Node &N) const {
const auto &Node = getNode(N);
- return EdgeIterable(Node.Edges);
+ return make_range(EdgeIterator(Node.Edges.begin()),
+ EdgeIterator(Node.Edges.end()));
}
bool empty() const { return NodeImpls.empty(); }
std::size_t size() const { return NodeImpls.size(); }
- // \brief Gets an arbitrary node in the graph as a starting point for
- // traversal.
+ /// Gets an arbitrary node in the graph as a starting point for traversal.
Node getEntryNode() {
assert(inbounds(StartNode));
return StartNode;
@@ -641,47 +636,47 @@ typedef DenseMap<Value *, GraphT::Node>
// Function declarations that require types defined in the namespace above
//===----------------------------------------------------------------------===//
-// Given an argument number, returns the appropriate Attr index to set.
-static StratifiedAttr argNumberToAttrIndex(StratifiedAttr);
+/// Given an argument number, returns the appropriate Attr index to set.
+static StratifiedAttr argNumberToAttrIndex(unsigned ArgNum);
-// Given a Value, potentially return which AttrIndex it maps to.
+/// Given a Value, potentially return which AttrIndex it maps to.
static Optional<StratifiedAttr> valueToAttrIndex(Value *Val);
-// Gets the inverse of a given EdgeType.
-static EdgeType flipWeight(EdgeType);
+/// Gets the inverse of a given EdgeType.
+static EdgeType flipWeight(EdgeType Initial);
-// Gets edges of the given Instruction*, writing them to the SmallVector*.
+/// Gets edges of the given Instruction*, writing them to the SmallVector*.
static void argsToEdges(CFLAAResult &, Instruction *, SmallVectorImpl<Edge> &);
-// Gets edges of the given ConstantExpr*, writing them to the SmallVector*.
+/// Gets edges of the given ConstantExpr*, writing them to the SmallVector*.
static void argsToEdges(CFLAAResult &, ConstantExpr *, SmallVectorImpl<Edge> &);
-// Gets the "Level" that one should travel in StratifiedSets
-// given an EdgeType.
+/// Gets the "Level" that one should travel in StratifiedSets
+/// given an EdgeType.
static Level directionOfEdgeType(EdgeType);
-// Builds the graph needed for constructing the StratifiedSets for the
-// given function
+/// Builds the graph needed for constructing the StratifiedSets for the
+/// given function
static void buildGraphFrom(CFLAAResult &, Function *,
SmallVectorImpl<Value *> &, NodeMapT &, GraphT &);
-// Gets the edges of a ConstantExpr as if it was an Instruction. This
-// function also acts on any nested ConstantExprs, adding the edges
-// of those to the given SmallVector as well.
+/// Gets the edges of a ConstantExpr as if it was an Instruction. This function
+/// also acts on any nested ConstantExprs, adding the edges of those to the
+/// given SmallVector as well.
static void constexprToEdges(CFLAAResult &, ConstantExpr &,
SmallVectorImpl<Edge> &);
-// Given an Instruction, this will add it to the graph, along with any
-// Instructions that are potentially only available from said Instruction
-// For example, given the following line:
-// %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
-// addInstructionToGraph would add both the `load` and `getelementptr`
-// instructions to the graph appropriately.
+/// Given an Instruction, this will add it to the graph, along with any
+/// Instructions that are potentially only available from said Instruction
+/// For example, given the following line:
+/// %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
+/// addInstructionToGraph would add both the `load` and `getelementptr`
+/// instructions to the graph appropriately.
static void addInstructionToGraph(CFLAAResult &, Instruction &,
SmallVectorImpl<Value *> &, NodeMapT &,
GraphT &);
-// Notes whether it would be pointless to add the given Value to our sets.
+/// Determines whether it would be pointless to add the given Value to our sets.
static bool canSkipAddingToSets(Value *Val);
static Optional<Function *> parentFunctionOfValue(Value *Val) {
@@ -848,7 +843,7 @@ static void addInstructionToGraph(CFLAAR
return;
}
- const auto addEdgeToGraph = [&Graph, &findOrInsertNode](const Edge &E) {
+ auto addEdgeToGraph = [&](const Edge &E) {
auto To = findOrInsertNode(E.To);
auto From = findOrInsertNode(E.From);
auto FlippedWeight = flipWeight(E.Weight);
@@ -873,13 +868,11 @@ static void addInstructionToGraph(CFLAAR
}
}
-// Aside: We may remove graph construction entirely, because it doesn't really
-// buy us much that we don't already have. I'd like to add interprocedural
-// analysis prior to this however, in case that somehow requires the graph
-// produced by this for efficient execution
static void buildGraphFrom(CFLAAResult &Analysis, Function *Fn,
SmallVectorImpl<Value *> &ReturnedValues,
NodeMapT &Map, GraphT &Graph) {
+ // (N.B. We may remove graph construction entirely, because it doesn't really
+ // buy us much.)
for (auto &Bb : Fn->getBasicBlockList())
for (auto &Inst : Bb.getInstList())
addInstructionToGraph(Analysis, Inst, ReturnedValues, Map, Graph);
@@ -1003,15 +996,14 @@ void CFLAAResult::scan(Function *Fn) {
assert(InsertPair.second &&
"Trying to scan a function that has already been cached");
- FunctionInfo Info(buildSetsFrom(Fn));
- Cache[Fn] = std::move(Info);
+ Cache[Fn] = buildSetsFrom(Fn);
Handles.push_front(FunctionHandle(Fn, this));
}
void CFLAAResult::evict(Function *Fn) { Cache.erase(Fn); }
-/// \brief Ensures that the given function is available in the cache.
-/// Returns the appropriate entry from the cache.
+/// Ensures that the given function is available in the cache, and returns the
+/// entry.
const Optional<CFLAAResult::FunctionInfo> &
CFLAAResult::ensureCached(Function *Fn) {
auto Iter = Cache.find(Fn);
@@ -1033,8 +1025,8 @@ AliasResult CFLAAResult::query(const Mem
auto MaybeFnA = parentFunctionOfValue(ValA);
auto MaybeFnB = parentFunctionOfValue(ValB);
if (!MaybeFnA.hasValue() && !MaybeFnB.hasValue()) {
- // The only times this is known to happen are when globals + InlineAsm
- // are involved
+ // The only times this is known to happen are when globals + InlineAsm are
+ // involved
DEBUG(dbgs() << "CFLAA: could not extract parent function information.\n");
return MayAlias;
}
@@ -1067,28 +1059,23 @@ AliasResult CFLAAResult::query(const Mem
// Stratified set attributes are used as markets to signify whether a member
// of a StratifiedSet (or a member of a set above the current set) has
- // interacted with either arguments or globals. "Interacted with" meaning
- // its value may be different depending on the value of an argument or
- // global. The thought behind this is that, because arguments and globals
- // may alias each other, if AttrsA and AttrsB have touched args/globals,
- // we must conservatively say that they alias. However, if at least one of
- // the sets has no values that could legally be altered by changing the value
- // of an argument or global, then we don't have to be as conservative.
+ // interacted with either arguments or globals. "Interacted with" meaning its
+ // value may be different depending on the value of an argument or global. The
+ // thought behind this is that, because arguments and globals may alias each
+ // other, if AttrsA and AttrsB have touched args/globals, we must
+ // conservatively say that they alias. However, if at least one of the sets
+ // has no values that could legally be altered by changing the value of an
+ // argument or global, then we don't have to be as conservative.
if (AttrsA.any() && AttrsB.any())
return MayAlias;
// We currently unify things even if the accesses to them may not be in
- // bounds, so we can't return partial alias here because we don't
- // know whether the pointer is really within the object or not.
- // IE Given an out of bounds GEP and an alloca'd pointer, we may
- // unify the two. We can't return partial alias for this case.
- // Since we do not currently track enough information to
- // differentiate
-
- if (SetA.Index == SetB.Index)
- return MayAlias;
-
- return NoAlias;
+ // bounds, so we can't return partial alias here because we don't know whether
+ // the pointer is really within the object or not.
+ // e.g. Given an out of bounds GEP and an alloca'd pointer, we may unify the
+ // two. We can't return partial alias for this case. Since we do not currently
+ // track enough information to differentiate.
+ return SetA.Index == SetB.Index ? MayAlias : NoAlias;
}
char CFLAA::PassID;
Modified: llvm/trunk/lib/Analysis/StratifiedSets.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/StratifiedSets.h?rev=266262&r1=266261&r2=266262&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/StratifiedSets.h (original)
+++ llvm/trunk/lib/Analysis/StratifiedSets.h Wed Apr 13 18:27:37 2016
@@ -25,44 +25,45 @@
#include <vector>
namespace llvm {
-// \brief An index into Stratified Sets.
+/// An index into Stratified Sets.
typedef unsigned StratifiedIndex;
-// NOTE: ^ This can't be a short -- bootstrapping clang has a case where
-// ~1M sets exist.
+/// NOTE: ^ This can't be a short -- bootstrapping clang has a case where
+/// ~1M sets exist.
// \brief Container of information related to a value in a StratifiedSet.
struct StratifiedInfo {
StratifiedIndex Index;
- // For field sensitivity, etc. we can tack attributes on to this struct.
+ /// For field sensitivity, etc. we can tack fields on here.
};
-// The number of attributes that StratifiedAttrs should contain. Attributes are
-// described below, and 32 was an arbitrary choice because it fits nicely in 32
-// bits (because we use a bitset for StratifiedAttrs).
+/// The number of attributes that StratifiedAttrs should contain. Attributes are
+/// described below, and 32 was an arbitrary choice because it fits nicely in 32
+/// bits (because we use a bitset for StratifiedAttrs).
static const unsigned NumStratifiedAttrs = 32;
-// These are attributes that the users of StratifiedSets/StratifiedSetBuilders
-// may use for various purposes. These also have the special property of that
-// they are merged down. So, if set A is above set B, and one decides to set an
-// attribute in set A, then the attribute will automatically be set in set B.
+/// These are attributes that the users of StratifiedSets/StratifiedSetBuilders
+/// may use for various purposes. These also have the special property of that
+/// they are merged down. So, if set A is above set B, and one decides to set an
+/// attribute in set A, then the attribute will automatically be set in set B.
typedef std::bitset<NumStratifiedAttrs> StratifiedAttrs;
-// \brief A "link" between two StratifiedSets.
+/// A "link" between two StratifiedSets.
struct StratifiedLink {
- // \brief This is a value used to signify "does not exist" where
- // the StratifiedIndex type is used. This is used instead of
- // Optional<StratifiedIndex> because Optional<StratifiedIndex> would
- // eat up a considerable amount of extra memory, after struct
- // padding/alignment is taken into account.
+ /// \brief This is a value used to signify "does not exist" where the
+ /// StratifiedIndex type is used.
+ ///
+ /// This is used instead of Optional<StratifiedIndex> because
+ /// Optional<StratifiedIndex> would eat up a considerable amount of extra
+ /// memory, after struct padding/alignment is taken into account.
static const StratifiedIndex SetSentinel;
- // \brief The index for the set "above" current
+ /// The index for the set "above" current
StratifiedIndex Above;
- // \brief The link for the set "below" current
+ /// The link for the set "below" current
StratifiedIndex Below;
- // \brief Attributes for these StratifiedSets.
+ /// Attributes for these StratifiedSets.
StratifiedAttrs Attrs;
StratifiedLink() : Above(SetSentinel), Below(SetSentinel) {}
@@ -74,25 +75,25 @@ struct StratifiedLink {
void clearAbove() { Above = SetSentinel; }
};
-// \brief These are stratified sets, as described in "Fast algorithms for
-// Dyck-CFL-reachability with applications to Alias Analysis" by Zhang Q, Lyu M
-// R, Yuan H, and Su Z. -- in short, this is meant to represent different sets
-// of Value*s. If two Value*s are in the same set, or if both sets have
-// overlapping attributes, then the Value*s are said to alias.
-//
-// Sets may be related by position, meaning that one set may be considered as
-// above or below another. In CFL Alias Analysis, this gives us an indication
-// of how two variables are related; if the set of variable A is below a set
-// containing variable B, then at some point, a variable that has interacted
-// with B (or B itself) was either used in order to extract the variable A, or
-// was used as storage of variable A.
-//
-// Sets may also have attributes (as noted above). These attributes are
-// generally used for noting whether a variable in the set has interacted with
-// a variable whose origins we don't quite know (i.e. globals/arguments), or if
-// the variable may have had operations performed on it (modified in a function
-// call). All attributes that exist in a set A must exist in all sets marked as
-// below set A.
+/// \brief These are stratified sets, as described in "Fast algorithms for
+/// Dyck-CFL-reachability with applications to Alias Analysis" by Zhang Q, Lyu M
+/// R, Yuan H, and Su Z. -- in short, this is meant to represent different sets
+/// of Value*s. If two Value*s are in the same set, or if both sets have
+/// overlapping attributes, then the Value*s are said to alias.
+///
+/// Sets may be related by position, meaning that one set may be considered as
+/// above or below another. In CFL Alias Analysis, this gives us an indication
+/// of how two variables are related; if the set of variable A is below a set
+/// containing variable B, then at some point, a variable that has interacted
+/// with B (or B itself) was either used in order to extract the variable A, or
+/// was used as storage of variable A.
+///
+/// Sets may also have attributes (as noted above). These attributes are
+/// generally used for noting whether a variable in the set has interacted with
+/// a variable whose origins we don't quite know (i.e. globals/arguments), or if
+/// the variable may have had operations performed on it (modified in a function
+/// call). All attributes that exist in a set A must exist in all sets marked as
+/// below set A.
template <typename T> class StratifiedSets {
public:
StratifiedSets() {}
@@ -111,9 +112,8 @@ public:
Optional<StratifiedInfo> find(const T &Elem) const {
auto Iter = Values.find(Elem);
- if (Iter == Values.end()) {
- return NoneType();
- }
+ if (Iter == Values.end())
+ return None;
return Iter->second;
}
@@ -129,91 +129,91 @@ private:
bool inbounds(StratifiedIndex Idx) const { return Idx < Links.size(); }
};
-// \brief Generic Builder class that produces StratifiedSets instances.
-//
-// The goal of this builder is to efficiently produce correct StratifiedSets
-// instances. To this end, we use a few tricks:
-// > Set chains (A method for linking sets together)
-// > Set remaps (A method for marking a set as an alias [irony?] of another)
-//
-// ==== Set chains ====
-// This builder has a notion of some value A being above, below, or with some
-// other value B:
-// > The `A above B` relationship implies that there is a reference edge going
-// from A to B. Namely, it notes that A can store anything in B's set.
-// > The `A below B` relationship is the opposite of `A above B`. It implies
-// that there's a dereference edge going from A to B.
-// > The `A with B` relationship states that there's an assignment edge going
-// from A to B, and that A and B should be treated as equals.
-//
-// As an example, take the following code snippet:
-//
-// %a = alloca i32, align 4
-// %ap = alloca i32*, align 8
-// %app = alloca i32**, align 8
-// store %a, %ap
-// store %ap, %app
-// %aw = getelementptr %ap, 0
-//
-// Given this, the follow relations exist:
-// - %a below %ap & %ap above %a
-// - %ap below %app & %app above %ap
-// - %aw with %ap & %ap with %aw
-//
-// These relations produce the following sets:
-// [{%a}, {%ap, %aw}, {%app}]
-//
-// ...Which states that the only MayAlias relationship in the above program is
-// between %ap and %aw.
-//
-// Life gets more complicated when we actually have logic in our programs. So,
-// we either must remove this logic from our programs, or make consessions for
-// it in our AA algorithms. In this case, we have decided to select the latter
-// option.
-//
-// First complication: Conditionals
-// Motivation:
-// %ad = alloca int, align 4
-// %a = alloca int*, align 8
-// %b = alloca int*, align 8
-// %bp = alloca int**, align 8
-// %c = call i1 @SomeFunc()
-// %k = select %c, %ad, %bp
-// store %ad, %a
-// store %b, %bp
-//
-// %k has 'with' edges to both %a and %b, which ordinarily would not be linked
-// together. So, we merge the set that contains %a with the set that contains
-// %b. We then recursively merge the set above %a with the set above %b, and
-// the set below %a with the set below %b, etc. Ultimately, the sets for this
+/// Generic Builder class that produces StratifiedSets instances.
+///
+/// The goal of this builder is to efficiently produce correct StratifiedSets
+/// instances. To this end, we use a few tricks:
+/// > Set chains (A method for linking sets together)
+/// > Set remaps (A method for marking a set as an alias [irony?] of another)
+///
+/// ==== Set chains ====
+/// This builder has a notion of some value A being above, below, or with some
+/// other value B:
+/// > The `A above B` relationship implies that there is a reference edge
+/// going from A to B. Namely, it notes that A can store anything in B's set.
+/// > The `A below B` relationship is the opposite of `A above B`. It implies
+/// that there's a dereference edge going from A to B.
+/// > The `A with B` relationship states that there's an assignment edge going
+/// from A to B, and that A and B should be treated as equals.
+///
+/// As an example, take the following code snippet:
+///
+/// %a = alloca i32, align 4
+/// %ap = alloca i32*, align 8
+/// %app = alloca i32**, align 8
+/// store %a, %ap
+/// store %ap, %app
+/// %aw = getelementptr %ap, 0
+///
+/// Given this, the follow relations exist:
+/// - %a below %ap & %ap above %a
+/// - %ap below %app & %app above %ap
+/// - %aw with %ap & %ap with %aw
+///
+/// These relations produce the following sets:
+/// [{%a}, {%ap, %aw}, {%app}]
+///
+/// ...Which states that the only MayAlias relationship in the above program is
+/// between %ap and %aw.
+///
+/// Life gets more complicated when we actually have logic in our programs. So,
+/// we either must remove this logic from our programs, or make consessions for
+/// it in our AA algorithms. In this case, we have decided to select the latter
+/// option.
+///
+/// First complication: Conditionals
+/// Motivation:
+/// %ad = alloca int, align 4
+/// %a = alloca int*, align 8
+/// %b = alloca int*, align 8
+/// %bp = alloca int**, align 8
+/// %c = call i1 @SomeFunc()
+/// %k = select %c, %ad, %bp
+/// store %ad, %a
+/// store %b, %bp
+///
+/// %k has 'with' edges to both %a and %b, which ordinarily would not be linked
+/// together. So, we merge the set that contains %a with the set that contains
+/// %b. We then recursively merge the set above %a with the set above %b, and
+/// the set below %a with the set below %b, etc. Ultimately, the sets for this
// program would end up like: {%ad}, {%a, %b, %k}, {%bp}, where {%ad} is below
-// {%a, %b, %c} is below {%ad}.
-//
-// Second complication: Arbitrary casts
-// Motivation:
-// %ip = alloca int*, align 8
-// %ipp = alloca int**, align 8
-// %i = bitcast ipp to int
-// store %ip, %ipp
-// store %i, %ip
-//
-// This is impossible to construct with any of the rules above, because a set
-// containing both {%i, %ipp} is supposed to exist, the set with %i is supposed
-// to be below the set with %ip, and the set with %ip is supposed to be below
-// the set with %ipp. Because we don't allow circular relationships like this,
-// we merge all concerned sets into one. So, the above code would generate a
-// single StratifiedSet: {%ip, %ipp, %i}.
-//
-// ==== Set remaps ====
-// More of an implementation detail than anything -- when merging sets, we need
-// to update the numbers of all of the elements mapped to those sets. Rather
-// than doing this at each merge, we note in the BuilderLink structure that a
-// remap has occurred, and use this information so we can defer renumbering set
-// elements until build time.
+/// {%a, %b, %c} is below {%ad}.
+///
+/// Second complication: Arbitrary casts
+/// Motivation:
+/// %ip = alloca int*, align 8
+/// %ipp = alloca int**, align 8
+/// %i = bitcast ipp to int
+/// store %ip, %ipp
+/// store %i, %ip
+///
+/// This is impossible to construct with any of the rules above, because a set
+/// containing both {%i, %ipp} is supposed to exist, the set with %i is supposed
+/// to be below the set with %ip, and the set with %ip is supposed to be below
+/// the set with %ipp. Because we don't allow circular relationships like this,
+/// we merge all concerned sets into one. So, the above code would generate a
+/// single StratifiedSet: {%ip, %ipp, %i}.
+///
+/// ==== Set remaps ====
+/// More of an implementation detail than anything -- when merging sets, we need
+/// to update the numbers of all of the elements mapped to those sets. Rather
+/// than doing this at each merge, we note in the BuilderLink structure that a
+/// remap has occurred, and use this information so we can defer renumbering set
+/// elements until build time.
template <typename T> class StratifiedSetsBuilder {
- // \brief Represents a Stratified Set, with information about the Stratified
- // Set above it, the set below it, and whether the current set has been
- // remapped to another.
+ /// \brief Represents a Stratified Set, with information about the Stratified
+ /// Set above it, the set below it, and whether the current set has been
+ /// remapped to another.
struct BuilderLink {
const StratifiedIndex Number;
@@ -281,7 +281,7 @@ template <typename T> class StratifiedSe
bool isRemapped() const { return Remap != StratifiedLink::SetSentinel; }
- // \brief For initial remapping to another set
+ /// For initial remapping to another set
void remapTo(StratifiedIndex Other) {
assert(!isRemapped());
Remap = Other;
@@ -292,15 +292,15 @@ template <typename T> class StratifiedSe
return Remap;
}
- // \brief Should only be called when we're already remapped.
+ /// Should only be called when we're already remapped.
void updateRemap(StratifiedIndex Other) {
assert(isRemapped());
Remap = Other;
}
- // \brief Prefer the above functions to calling things directly on what's
- // returned from this -- they guard against unexpected calls when the
- // current BuilderLink is remapped.
+ /// Prefer the above functions to calling things directly on what's returned
+ /// from this -- they guard against unexpected calls when the current
+ /// BuilderLink is remapped.
const StratifiedLink &getLink() const { return Link; }
private:
@@ -308,15 +308,14 @@ template <typename T> class StratifiedSe
StratifiedIndex Remap;
};
- // \brief This function performs all of the set unioning/value renumbering
- // that we've been putting off, and generates a vector<StratifiedLink> that
- // may be placed in a StratifiedSets instance.
+ /// \brief This function performs all of the set unioning/value renumbering
+ /// that we've been putting off, and generates a vector<StratifiedLink> that
+ /// may be placed in a StratifiedSets instance.
void finalizeSets(std::vector<StratifiedLink> &StratLinks) {
DenseMap<StratifiedIndex, StratifiedIndex> Remaps;
for (auto &Link : Links) {
- if (Link.isRemapped()) {
+ if (Link.isRemapped())
continue;
- }
StratifiedIndex Number = StratLinks.size();
Remaps.insert(std::make_pair(Link.Number, Number));
@@ -348,8 +347,8 @@ template <typename T> class StratifiedSe
}
}
- // \brief There's a guarantee in StratifiedLink where all bits set in a
- // Link.externals will be set in all Link.externals "below" it.
+ /// \brief There's a guarantee in StratifiedLink where all bits set in a
+ /// Link.externals will be set in all Link.externals "below" it.
static void propagateAttrs(std::vector<StratifiedLink> &Links) {
const auto getHighestParentAbove = [&Links](StratifiedIndex Idx) {
const auto *Link = &Links[Idx];
@@ -363,9 +362,8 @@ template <typename T> class StratifiedSe
SmallSet<StratifiedIndex, 16> Visited;
for (unsigned I = 0, E = Links.size(); I < E; ++I) {
auto CurrentIndex = getHighestParentAbove(I);
- if (!Visited.insert(CurrentIndex).second) {
+ if (!Visited.insert(CurrentIndex).second)
continue;
- }
while (Links[CurrentIndex].hasBelow()) {
auto &CurrentBits = Links[CurrentIndex].Attrs;
@@ -378,8 +376,8 @@ template <typename T> class StratifiedSe
}
public:
- // \brief Builds a StratifiedSet from the information we've been given since
- // either construction or the prior build() call.
+ /// Builds a StratifiedSet from the information we've been given since either
+ /// construction or the prior build() call.
StratifiedSets<T> build() {
std::vector<StratifiedLink> StratLinks;
finalizeSets(StratLinks);
@@ -401,9 +399,9 @@ public:
return addAtMerging(Main, NewIndex);
}
- // \brief Restructures the stratified sets as necessary to make "ToAdd" in a
- // set above "Main". There are some cases where this is not possible (see
- // above), so we merge them such that ToAdd and Main are in the same set.
+ /// \brief Restructures the stratified sets as necessary to make "ToAdd" in a
+ /// set above "Main". There are some cases where this is not possible (see
+ /// above), so we merge them such that ToAdd and Main are in the same set.
bool addAbove(const T &Main, const T &ToAdd) {
assert(has(Main));
auto Index = *indexOf(Main);
@@ -414,9 +412,9 @@ public:
return addAtMerging(ToAdd, Above);
}
- // \brief Restructures the stratified sets as necessary to make "ToAdd" in a
- // set below "Main". There are some cases where this is not possible (see
- // above), so we merge them such that ToAdd and Main are in the same set.
+ /// \brief Restructures the stratified sets as necessary to make "ToAdd" in a
+ /// set below "Main". There are some cases where this is not possible (see
+ /// above), so we merge them such that ToAdd and Main are in the same set.
bool addBelow(const T &Main, const T &ToAdd) {
assert(has(Main));
auto Index = *indexOf(Main);
@@ -467,9 +465,9 @@ public:
return Attrs[AttrNum];
}
- // \brief Gets the attributes that have been applied to the set that Main
- // belongs to. It ignores attributes in any sets above the one that Main
- // resides in.
+ /// \brief Gets the attributes that have been applied to the set that Main
+ /// belongs to. It ignores attributes in any sets above the one that Main
+ /// resides in.
StratifiedAttrs getRawAttributes(const T &Main) {
assert(has(Main));
auto *Info = *get(Main);
@@ -477,9 +475,9 @@ public:
return Link.getAttrs();
}
- // \brief Gets an attribute from the attributes that have been applied to the
- // set that Main belongs to. It ignores attributes in any sets above the one
- // that Main resides in.
+ /// \brief Gets an attribute from the attributes that have been applied to the
+ /// set that Main belongs to. It ignores attributes in any sets above the one
+ /// that Main resides in.
bool getRawAttribute(const T &Main, unsigned AttrNum) {
assert(AttrNum < StratifiedLink::SetSentinel);
auto Attrs = getRawAttributes(Main);
@@ -490,8 +488,7 @@ private:
DenseMap<T, StratifiedInfo> Values;
std::vector<BuilderLink> Links;
- // \brief Adds the given element at the given index, merging sets if
- // necessary.
+ /// Adds the given element at the given index, merging sets if necessary.
bool addAtMerging(const T &ToAdd, StratifiedIndex Index) {
StratifiedInfo Info = {Index};
auto Pair = Values.insert(std::make_pair(ToAdd, Info));
@@ -509,8 +506,8 @@ private:
return false;
}
- // \brief Gets the BuilderLink at the given index, taking set remapping into
- // account.
+ /// Gets the BuilderLink at the given index, taking set remapping into
+ /// account.
BuilderLink &linksAt(StratifiedIndex Index) {
auto *Start = &Links[Index];
if (!Start->isRemapped())
@@ -534,8 +531,8 @@ private:
return *Current;
}
- // \brief Merges two sets into one another. Assumes that these sets are not
- // already one in the same
+ /// \brief Merges two sets into one another. Assumes that these sets are not
+ /// already one in the same.
void merge(StratifiedIndex Idx1, StratifiedIndex Idx2) {
assert(inbounds(Idx1) && inbounds(Idx2));
assert(&linksAt(Idx1) != &linksAt(Idx2) &&
@@ -555,8 +552,8 @@ private:
mergeDirect(Idx1, Idx2);
}
- // \brief Merges two sets assuming that the set at `Idx1` is unreachable from
- // traversing above or below the set at `Idx2`.
+ /// \brief Merges two sets assuming that the set at `Idx1` is unreachable from
+ /// traversing above or below the set at `Idx2`.
void mergeDirect(StratifiedIndex Idx1, StratifiedIndex Idx2) {
assert(inbounds(Idx1) && inbounds(Idx2));
@@ -602,9 +599,9 @@ private:
LinksFrom->remapTo(LinksInto->Number);
}
- // \brief Checks to see if lowerIndex is at a level lower than upperIndex.
- // If so, it will merge lowerIndex with upperIndex (and all of the sets
- // between) and return true. Otherwise, it will return false.
+ /// Checks to see if lowerIndex is at a level lower than upperIndex. If so, it
+ /// will merge lowerIndex with upperIndex (and all of the sets between) and
+ /// return true. Otherwise, it will return false.
bool tryMergeUpwards(StratifiedIndex LowerIndex, StratifiedIndex UpperIndex) {
assert(inbounds(LowerIndex) && inbounds(UpperIndex));
auto *Lower = &linksAt(LowerIndex);
@@ -644,21 +641,21 @@ private:
Optional<const StratifiedInfo *> get(const T &Val) const {
auto Result = Values.find(Val);
if (Result == Values.end())
- return NoneType();
+ return None;
return &Result->second;
}
Optional<StratifiedInfo *> get(const T &Val) {
auto Result = Values.find(Val);
if (Result == Values.end())
- return NoneType();
+ return None;
return &Result->second;
}
Optional<StratifiedIndex> indexOf(const T &Val) {
auto MaybeVal = get(Val);
if (!MaybeVal.hasValue())
- return NoneType();
+ return None;
auto *Info = *MaybeVal;
auto &Link = linksAt(Info->Index);
return Link.Number;
More information about the llvm-commits
mailing list