[llvm] r272688 - [CFLAA] Refactor graph-building code. NFC.
George Burgess IV via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 14 11:02:27 PDT 2016
Author: gbiv
Date: Tue Jun 14 13:02:27 2016
New Revision: 272688
URL: http://llvm.org/viewvc/llvm-project?rev=272688&view=rev
Log:
[CFLAA] Refactor graph-building code. NFC.
This patch refactors CFLAA's graph building code. This makes keeping
track of common state (TargetLibraryInfo, ...) easier.
Patch by Jia Chen.
Differential Revision: http://reviews.llvm.org/D21261
Modified:
llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
Modified: llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp?rev=272688&r1=272687&r2=272688&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp Tue Jun 14 13:02:27 2016
@@ -90,10 +90,6 @@ static bool getPossibleTargets(Inst *, S
/// type of instruction we support.
static Optional<Value *> getTargetValue(Instruction *);
-/// 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();
@@ -514,7 +510,6 @@ public:
/// The Program Expression Graph (PEG) of CFL analysis
class CFLGraph {
-private:
typedef Value *Node;
struct Edge {
@@ -587,6 +582,152 @@ public:
bool empty() const { return NodeImpls.empty(); }
std::size_t size() const { return NodeImpls.size(); }
};
+
+class CFLGraphBuilder {
+ // Input of the builder
+ CFLAAResult &Analysis;
+ const TargetLibraryInfo &TLI;
+
+ // Output of the builder
+ CFLGraph Graph;
+ SmallVector<Value *, 4> ReturnedValues;
+
+ // Auxiliary structures used by the builder
+
+ // Helper functions
+
+ // Determines whether or not we an instruction is useless to us (e.g.
+ // FenceInst)
+ static bool hasUsefulEdges(Instruction *Inst) {
+ bool IsNonInvokeTerminator =
+ isa<TerminatorInst>(Inst) && !isa<InvokeInst>(Inst);
+ return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) &&
+ !IsNonInvokeTerminator;
+ }
+
+ static bool hasUsefulEdges(ConstantExpr *CE) {
+ // ConstantExpr doesn't have terminators, invokes, or fences, so only needs
+ // to check for compares.
+ return CE->getOpcode() != Instruction::ICmp &&
+ CE->getOpcode() != Instruction::FCmp;
+ }
+
+ // Gets edges of the given Instruction*, writing them to the SmallVector*.
+ void argsToEdges(Instruction *Inst, SmallVectorImpl<Edge> &Output) {
+ assert(hasUsefulEdges(Inst) &&
+ "Expected instructions to have 'useful' edges");
+ GetEdgesVisitor v(Analysis, Output, TLI);
+ v.visit(Inst);
+ }
+
+ // Gets edges of the given ConstantExpr*, writing them to the SmallVector*.
+ void argsToEdges(ConstantExpr *CE, SmallVectorImpl<Edge> &Output) {
+ assert(hasUsefulEdges(CE) &&
+ "Expected constant expr to have 'useful' edges");
+ GetEdgesVisitor v(Analysis, Output, TLI);
+ v.visitConstantExpr(CE);
+ }
+
+ // 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.
+ void constexprToEdges(ConstantExpr &CExprToCollapse,
+ SmallVectorImpl<Edge> &Results) {
+ SmallVector<ConstantExpr *, 4> Worklist;
+ Worklist.push_back(&CExprToCollapse);
+
+ SmallVector<Edge, 8> ConstexprEdges;
+ SmallPtrSet<ConstantExpr *, 4> Visited;
+ while (!Worklist.empty()) {
+ auto *CExpr = Worklist.pop_back_val();
+
+ if (!hasUsefulEdges(CExpr))
+ continue;
+
+ ConstexprEdges.clear();
+ argsToEdges(CExpr, ConstexprEdges);
+ for (auto &Edge : ConstexprEdges) {
+ if (auto *Nested = dyn_cast<ConstantExpr>(Edge.From))
+ if (Visited.insert(Nested).second)
+ Worklist.push_back(Nested);
+
+ if (auto *Nested = dyn_cast<ConstantExpr>(Edge.To))
+ if (Visited.insert(Nested).second)
+ Worklist.push_back(Nested);
+ }
+
+ Results.append(ConstexprEdges.begin(), ConstexprEdges.end());
+ }
+ }
+
+ // Builds the graph needed for constructing the StratifiedSets for the given
+ // function
+ void buildGraphFrom(Function &Fn) {
+ for (auto &Bb : Fn.getBasicBlockList())
+ for (auto &Inst : Bb.getInstList())
+ addInstructionToGraph(Inst);
+ }
+
+ // 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.
+ void addInstructionToGraph(Instruction &Inst) {
+ // We don't want the edges of most "return" instructions, but we *do* want
+ // to know what can be returned.
+ if (isa<ReturnInst>(&Inst))
+ ReturnedValues.push_back(&Inst);
+
+ if (!hasUsefulEdges(&Inst))
+ return;
+
+ SmallVector<Edge, 8> Edges;
+ argsToEdges(&Inst, Edges);
+
+ // In the case of an unused alloca (or similar), edges may be empty. Note
+ // that it exists so we can potentially answer NoAlias.
+ if (Edges.empty()) {
+ auto MaybeVal = getTargetValue(&Inst);
+ assert(MaybeVal.hasValue());
+ auto *Target = *MaybeVal;
+ Graph.addNode(Target);
+ return;
+ }
+
+ auto addEdgeToGraph = [this](const Edge &E) {
+ Graph.addEdge(E.From, E.To, E.Weight, E.AdditionalAttrs);
+ };
+
+ SmallVector<ConstantExpr *, 4> ConstantExprs;
+ for (const Edge &E : Edges) {
+ addEdgeToGraph(E);
+ if (auto *Constexpr = dyn_cast<ConstantExpr>(E.To))
+ ConstantExprs.push_back(Constexpr);
+ if (auto *Constexpr = dyn_cast<ConstantExpr>(E.From))
+ ConstantExprs.push_back(Constexpr);
+ }
+
+ for (ConstantExpr *CE : ConstantExprs) {
+ Edges.clear();
+ constexprToEdges(*CE, Edges);
+ std::for_each(Edges.begin(), Edges.end(), addEdgeToGraph);
+ }
+ }
+
+public:
+ CFLGraphBuilder(CFLAAResult &Analysis, const TargetLibraryInfo &TLI,
+ Function &Fn)
+ : Analysis(Analysis), TLI(TLI) {
+ buildGraphFrom(Fn);
+ }
+
+ const CFLGraph &getCFLGraph() { return Graph; }
+ SmallVector<Value *, 4> takeReturnValues() {
+ return std::move(ReturnedValues);
+ }
+};
}
//===----------------------------------------------------------------------===//
@@ -607,41 +748,10 @@ static StratifiedAttr argNumberToAttr(un
/// Given a Value, potentially return which StratifiedAttr it maps to.
static Optional<StratifiedAttr> valueToAttr(Value *Val);
-/// Gets edges of the given Instruction*, writing them to the SmallVector*.
-static void argsToEdges(CFLAAResult &, Instruction *, SmallVectorImpl<Edge> &,
- const TargetLibraryInfo &);
-
-/// Gets edges of the given ConstantExpr*, writing them to the SmallVector*.
-static void argsToEdges(CFLAAResult &, ConstantExpr *, SmallVectorImpl<Edge> &,
- const TargetLibraryInfo &);
-
/// 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
-static void buildGraphFrom(CFLAAResult &, Function *,
- SmallVectorImpl<Value *> &, CFLGraph &,
- const TargetLibraryInfo &);
-
-/// 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> &,
- const TargetLibraryInfo &);
-
-/// 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 *> &, CFLGraph &,
- const TargetLibraryInfo &);
-
/// Determines whether it would be pointless to add the given Value to our sets.
static bool canSkipAddingToSets(Value *Val);
@@ -674,19 +784,6 @@ static Optional<Value *> getTargetValue(
return V.visit(Inst);
}
-static bool hasUsefulEdges(Instruction *Inst) {
- bool IsNonInvokeTerminator =
- isa<TerminatorInst>(Inst) && !isa<InvokeInst>(Inst);
- return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) && !IsNonInvokeTerminator;
-}
-
-static bool hasUsefulEdges(ConstantExpr *CE) {
- // ConstantExpr doesn't have terminators, invokes, or fences, so only needs
- // to check for compares.
- return CE->getOpcode() != Instruction::ICmp &&
- CE->getOpcode() != Instruction::FCmp;
-}
-
static bool isGlobalOrArgAttr(StratifiedAttrs Attr) {
return Attr.reset(AttrEscapedIndex).reset(AttrUnknownIndex).any();
}
@@ -714,23 +811,6 @@ static StratifiedAttr argNumberToAttr(un
return 1 << (ArgNum + AttrFirstArgIndex);
}
-static void argsToEdges(CFLAAResult &Analysis, Instruction *Inst,
- SmallVectorImpl<Edge> &Output,
- const TargetLibraryInfo &TLI) {
- assert(hasUsefulEdges(Inst) &&
- "Expected instructions to have 'useful' edges");
- GetEdgesVisitor v(Analysis, Output, TLI);
- v.visit(Inst);
-}
-
-static void argsToEdges(CFLAAResult &Analysis, ConstantExpr *CE,
- SmallVectorImpl<Edge> &Output,
- const TargetLibraryInfo &TLI) {
- assert(hasUsefulEdges(CE) && "Expected constant expr to have 'useful' edges");
- GetEdgesVisitor v(Analysis, Output, TLI);
- v.visitConstantExpr(CE);
-}
-
static Level directionOfEdgeType(EdgeType Weight) {
switch (Weight) {
case EdgeType::Reference:
@@ -743,92 +823,6 @@ static Level directionOfEdgeType(EdgeTyp
llvm_unreachable("Incomplete switch coverage");
}
-static void constexprToEdges(CFLAAResult &Analysis,
- ConstantExpr &CExprToCollapse,
- SmallVectorImpl<Edge> &Results,
- const TargetLibraryInfo &TLI) {
- SmallVector<ConstantExpr *, 4> Worklist;
- Worklist.push_back(&CExprToCollapse);
-
- SmallVector<Edge, 8> ConstexprEdges;
- SmallPtrSet<ConstantExpr *, 4> Visited;
- while (!Worklist.empty()) {
- auto *CExpr = Worklist.pop_back_val();
-
- if (!hasUsefulEdges(CExpr))
- continue;
-
- ConstexprEdges.clear();
- argsToEdges(Analysis, CExpr, ConstexprEdges, TLI);
- for (auto &Edge : ConstexprEdges) {
- if (auto *Nested = dyn_cast<ConstantExpr>(Edge.From))
- if (Visited.insert(Nested).second)
- Worklist.push_back(Nested);
-
- if (auto *Nested = dyn_cast<ConstantExpr>(Edge.To))
- if (Visited.insert(Nested).second)
- Worklist.push_back(Nested);
- }
-
- Results.append(ConstexprEdges.begin(), ConstexprEdges.end());
- }
-}
-
-static void addInstructionToGraph(CFLAAResult &Analysis, Instruction &Inst,
- SmallVectorImpl<Value *> &ReturnedValues,
- CFLGraph &Graph,
- const TargetLibraryInfo &TLI) {
- // We don't want the edges of most "return" instructions, but we *do* want
- // to know what can be returned.
- if (isa<ReturnInst>(&Inst))
- ReturnedValues.push_back(&Inst);
-
- if (!hasUsefulEdges(&Inst))
- return;
-
- SmallVector<Edge, 8> Edges;
- argsToEdges(Analysis, &Inst, Edges, TLI);
-
- // In the case of an unused alloca (or similar), edges may be empty. Note
- // that it exists so we can potentially answer NoAlias.
- if (Edges.empty()) {
- auto MaybeVal = getTargetValue(&Inst);
- assert(MaybeVal.hasValue());
- auto *Target = *MaybeVal;
- Graph.addNode(Target);
- return;
- }
-
- auto addEdgeToGraph = [&Graph](const Edge &E) {
- Graph.addEdge(E.From, E.To, E.Weight, E.AdditionalAttrs);
- };
-
- SmallVector<ConstantExpr *, 4> ConstantExprs;
- for (const Edge &E : Edges) {
- addEdgeToGraph(E);
- if (auto *Constexpr = dyn_cast<ConstantExpr>(E.To))
- ConstantExprs.push_back(Constexpr);
- if (auto *Constexpr = dyn_cast<ConstantExpr>(E.From))
- ConstantExprs.push_back(Constexpr);
- }
-
- for (ConstantExpr *CE : ConstantExprs) {
- Edges.clear();
- constexprToEdges(Analysis, *CE, Edges, TLI);
- std::for_each(Edges.begin(), Edges.end(), addEdgeToGraph);
- }
-}
-
-static void buildGraphFrom(CFLAAResult &Analysis, Function *Fn,
- SmallVectorImpl<Value *> &ReturnedValues,
- CFLGraph &Graph, const TargetLibraryInfo &TLI) {
- // (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, Graph, TLI);
-}
-
static bool canSkipAddingToSets(Value *Val) {
// Constants can share instances, which may falsely unify multiple
// sets, e.g. in
@@ -852,22 +846,18 @@ static bool canSkipAddingToSets(Value *V
// Builds the graph + StratifiedSets for a function.
CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
- CFLGraph Graph;
- SmallVector<Value *, 4> ReturnedValues;
-
- buildGraphFrom(*this, Fn, ReturnedValues, Graph, TLI);
-
- StratifiedSetsBuilder<Value *> Builder;
+ CFLGraphBuilder GraphBuilder(*this, TLI, *Fn);
+ StratifiedSetsBuilder<Value *> SetBuilder;
+ auto &Graph = GraphBuilder.getCFLGraph();
SmallVector<Value *, 16> Worklist;
SmallPtrSet<Value *, 16> Globals;
-
for (auto Node : Graph.nodes())
Worklist.push_back(Node);
while (!Worklist.empty()) {
auto *CurValue = Worklist.pop_back_val();
- Builder.add(CurValue);
+ SetBuilder.add(CurValue);
if (canSkipAddingToSets(CurValue))
continue;
@@ -886,19 +876,19 @@ CFLAAResult::FunctionInfo CFLAAResult::b
bool Added;
switch (directionOfEdgeType(Label)) {
case Level::Above:
- Added = Builder.addAbove(CurValue, OtherValue);
+ Added = SetBuilder.addAbove(CurValue, OtherValue);
break;
case Level::Below:
- Added = Builder.addBelow(CurValue, OtherValue);
+ Added = SetBuilder.addBelow(CurValue, OtherValue);
break;
case Level::Same:
- Added = Builder.addWith(CurValue, OtherValue);
+ Added = SetBuilder.addWith(CurValue, OtherValue);
break;
}
auto Aliasing = Edge.Attr;
- Builder.noteAttributes(CurValue, Aliasing);
- Builder.noteAttributes(OtherValue, Aliasing);
+ SetBuilder.noteAttributes(CurValue, Aliasing);
+ SetBuilder.noteAttributes(OtherValue, Aliasing);
if (Added)
Worklist.push_back(OtherValue);
@@ -906,13 +896,13 @@ CFLAAResult::FunctionInfo CFLAAResult::b
}
// Special handling for globals and arguments
- auto ProcessGlobalOrArgValue = [&Builder](Value &Val) {
- Builder.add(&Val);
+ auto ProcessGlobalOrArgValue = [&SetBuilder](Value &Val) {
+ SetBuilder.add(&Val);
auto Attr = valueToAttr(&Val);
if (Attr.hasValue()) {
- Builder.noteAttributes(&Val, *Attr);
+ SetBuilder.noteAttributes(&Val, *Attr);
// TODO: do we need to filter out non-pointer values here?
- Builder.addAttributesBelow(&Val, AttrUnknown);
+ SetBuilder.addAttributesBelow(&Val, AttrUnknown);
}
};
@@ -921,7 +911,7 @@ CFLAAResult::FunctionInfo CFLAAResult::b
for (auto *Global : Globals)
ProcessGlobalOrArgValue(*Global);
- return FunctionInfo(Builder.build(), std::move(ReturnedValues));
+ return FunctionInfo(SetBuilder.build(), GraphBuilder.takeReturnValues());
}
void CFLAAResult::scan(Function *Fn) {
More information about the llvm-commits
mailing list