[llvm] r274592 - [CFLAA] Split out more things from CFLSteens. NFC.
George Burgess IV via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 5 17:47:21 PDT 2016
Author: gbiv
Date: Tue Jul 5 19:47:21 2016
New Revision: 274592
URL: http://llvm.org/viewvc/llvm-project?rev=274592&view=rev
Log:
[CFLAA] Split out more things from CFLSteens. NFC.
"More things" = StratifiedAttrs and various bits like interprocedural
summaries.
Patch by Jia Chen.
Differential Revision: http://reviews.llvm.org/D21964
Added:
llvm/trunk/lib/Analysis/AliasAnalysisSummary.cpp
llvm/trunk/lib/Analysis/AliasAnalysisSummary.h
Modified:
llvm/trunk/lib/Analysis/CFLGraph.h
llvm/trunk/lib/Analysis/CFLSteensAliasAnalysis.cpp
llvm/trunk/lib/Analysis/CMakeLists.txt
llvm/trunk/lib/Analysis/StratifiedSets.h
Added: llvm/trunk/lib/Analysis/AliasAnalysisSummary.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysisSummary.cpp?rev=274592&view=auto
==============================================================================
--- llvm/trunk/lib/Analysis/AliasAnalysisSummary.cpp (added)
+++ llvm/trunk/lib/Analysis/AliasAnalysisSummary.cpp Tue Jul 5 19:47:21 2016
@@ -0,0 +1,105 @@
+#include "AliasAnalysisSummary.h"
+#include "llvm/IR/Argument.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+namespace cflaa {
+
+namespace {
+LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0;
+LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1;
+LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2;
+LLVM_CONSTEXPR unsigned AttrCallerIndex = 3;
+LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4;
+LLVM_CONSTEXPR unsigned AttrLastArgIndex = NumAliasAttrs;
+LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
+
+// NOTE: These aren't AliasAttrs because bitsets don't have a constexpr
+// ctor for some versions of MSVC that we support. We could maybe refactor,
+// but...
+using AliasAttr = unsigned;
+LLVM_CONSTEXPR AliasAttr AttrNone = 0;
+LLVM_CONSTEXPR AliasAttr AttrEscaped = 1 << AttrEscapedIndex;
+LLVM_CONSTEXPR AliasAttr AttrUnknown = 1 << AttrUnknownIndex;
+LLVM_CONSTEXPR AliasAttr AttrGlobal = 1 << AttrGlobalIndex;
+LLVM_CONSTEXPR AliasAttr AttrCaller = 1 << AttrCallerIndex;
+LLVM_CONSTEXPR AliasAttr ExternalAttrMask =
+ AttrEscaped | AttrUnknown | AttrGlobal;
+}
+
+AliasAttrs getAttrNone() { return AttrNone; }
+
+AliasAttrs getAttrUnknown() { return AttrUnknown; }
+bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }
+
+AliasAttrs getAttrCaller() { return AttrCaller; }
+bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
+bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
+ return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
+}
+
+AliasAttrs getAttrEscaped() { return AttrEscaped; }
+bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }
+
+static AliasAttr argNumberToAttr(unsigned ArgNum) {
+ if (ArgNum >= AttrMaxNumArgs)
+ return AttrUnknown;
+ // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes
+ // an unsigned long long.
+ return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex));
+}
+
+AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
+ if (isa<GlobalValue>(Val))
+ return AttrGlobal;
+
+ if (auto *Arg = dyn_cast<Argument>(&Val))
+ // Only pointer arguments should have the argument attribute,
+ // because things can't escape through scalars without us seeing a
+ // cast, and thus, interaction with them doesn't matter.
+ if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
+ return argNumberToAttr(Arg->getArgNo());
+ return AttrNone;
+}
+
+bool isGlobalOrArgAttr(AliasAttrs Attr) {
+ return Attr.reset(AttrEscapedIndex)
+ .reset(AttrUnknownIndex)
+ .reset(AttrCallerIndex)
+ .any();
+}
+
+AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
+ return Attr & AliasAttrs(ExternalAttrMask);
+}
+
+Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
+ CallSite CS) {
+ auto Index = IValue.Index;
+ auto Value = (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
+ if (Value->getType()->isPointerTy())
+ return InstantiatedValue{Value, IValue.DerefLevel};
+ return None;
+}
+
+Optional<InstantiatedRelation>
+instantiateExternalRelation(ExternalRelation ERelation, CallSite CS) {
+ auto From = instantiateInterfaceValue(ERelation.From, CS);
+ if (!From)
+ return None;
+ auto To = instantiateInterfaceValue(ERelation.To, CS);
+ if (!To)
+ return None;
+ return InstantiatedRelation{*From, *To};
+}
+
+Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
+ CallSite CS) {
+ auto Value = instantiateInterfaceValue(EAttr.IValue, CS);
+ if (!Value)
+ return None;
+ return InstantiatedAttr{*Value, EAttr.Attr};
+}
+}
+}
Added: llvm/trunk/lib/Analysis/AliasAnalysisSummary.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysisSummary.h?rev=274592&view=auto
==============================================================================
--- llvm/trunk/lib/Analysis/AliasAnalysisSummary.h (added)
+++ llvm/trunk/lib/Analysis/AliasAnalysisSummary.h Tue Jul 5 19:47:21 2016
@@ -0,0 +1,158 @@
+//=====- CFLSummary.h - Abstract stratified sets implementation. --------=====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file defines various utility types and functions useful to
+/// summary-based alias analysis.
+///
+/// Summary-based analysis, also known as bottom-up analysis, is a style of
+/// interprocedrual static analysis that tries to analyze the callees before the
+/// callers get analyzed. The key idea of summary-based analysis is to first
+/// process each function indepedently, outline its behavior in a condensed
+/// summary, and then instantiate the summary at the callsite when the said
+/// function is called elsewhere. This is often in contrast to another style
+/// called top-down analysis, in which callers are always analyzed first before
+/// the callees.
+///
+/// In a summary-based analysis, functions must be examined independently and
+/// out-of-context. We have no information on the state of the memory, the
+/// arguments, the global values, and anything else external to the function. To
+/// carry out the analysis conservative assumptions have to be made about those
+/// external states. In exchange for the potential loss of precision, the
+/// summary we obtain this way is highly reusable, which makes the analysis
+/// easier to scale to large programs even if carried out context-sensitively.
+///
+/// Currently, all CFL-based alias analyses adopt the summary-based approach
+/// and therefore heavily rely on this header.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ALIASANALYSISSUMMARY_H
+#define LLVM_ANALYSIS_ALIASANALYSISSUMMARY_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/IR/CallSite.h"
+#include <bitset>
+
+namespace llvm {
+namespace cflaa {
+
+//===----------------------------------------------------------------------===//
+// AliasAttr related stuffs
+//===----------------------------------------------------------------------===//
+
+/// The number of attributes that AliasAttr 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 AliasAttr).
+static const unsigned NumAliasAttrs = 32;
+
+/// These are attributes that an alias analysis can use to mark certain special
+/// properties of a given pointer. Refer to the related functions below to see
+/// what kinds of attributes are currently defined.
+typedef std::bitset<NumAliasAttrs> AliasAttrs;
+
+/// Attr represent whether the said pointer comes from an unknown source
+/// (such as opaque memory or an integer cast).
+AliasAttrs getAttrNone();
+
+/// AttrUnknown represent whether the said pointer comes from a source not known
+/// to alias analyses (such as opaque memory or an integer cast).
+AliasAttrs getAttrUnknown();
+bool hasUnknownAttr(AliasAttrs);
+
+/// AttrCaller represent whether the said pointer comes from a source not known
+/// to the current function but known to the caller. Values pointed to by the
+/// arguments of the current function have this attribute set
+AliasAttrs getAttrCaller();
+bool hasCallerAttr(AliasAttrs);
+bool hasUnknownOrCallerAttr(AliasAttrs);
+
+/// AttrEscaped represent whether the said pointer comes from a known source but
+/// escapes to the unknown world (e.g. casted to an integer, or passed as an
+/// argument to opaque function). Unlike non-escaped pointers, escaped ones may
+/// alias pointers coming from unknown sources.
+AliasAttrs getAttrEscaped();
+bool hasEscapedAttr(AliasAttrs);
+
+/// AttrGlobal represent whether the said pointer is a global value.
+/// AttrArg represent whether the said pointer is an argument, and if so, what
+/// index the argument has.
+AliasAttrs getGlobalOrArgAttrFromValue(const Value &);
+bool isGlobalOrArgAttr(AliasAttrs);
+
+/// Given an AliasAttrs, return a new AliasAttrs that only contains attributes
+/// meaningful to the caller. This function is primarily used for
+/// interprocedural analysis
+/// Currently, externally visible AliasAttrs include AttrUnknown, AttrGlobal,
+/// and AttrEscaped
+AliasAttrs getExternallyVisibleAttrs(AliasAttrs);
+
+//===----------------------------------------------------------------------===//
+// Function summary related stuffs
+//===----------------------------------------------------------------------===//
+
+/// We use InterfaceValue to describe parameters/return value, as well as
+/// potential memory locations that are pointed to by parameters/return value,
+/// of a function.
+/// Index is an integer which represents a single parameter or a return value.
+/// When the index is 0, it refers to the return value. Non-zero index i refers
+/// to the i-th parameter.
+/// DerefLevel indicates the number of dereferences one must perform on the
+/// parameter/return value to get this InterfaceValue.
+struct InterfaceValue {
+ unsigned Index;
+ unsigned DerefLevel;
+};
+
+inline bool operator==(InterfaceValue lhs, InterfaceValue rhs) {
+ return lhs.Index == rhs.Index && lhs.DerefLevel == rhs.DerefLevel;
+}
+inline bool operator!=(InterfaceValue lhs, InterfaceValue rhs) {
+ return !(lhs == rhs);
+}
+
+/// We use ExternalRelation to describe an externally visible aliasing relations
+/// between parameters/return value of a function.
+struct ExternalRelation {
+ InterfaceValue From, To;
+};
+
+/// We use ExternalAttribute to describe an externally visible AliasAttrs
+/// for parameters/return value.
+struct ExternalAttribute {
+ InterfaceValue IValue;
+ AliasAttrs Attr;
+};
+
+/// This is the result of instantiating InterfaceValue at a particular callsite
+struct InstantiatedValue {
+ Value *Val;
+ unsigned DerefLevel;
+};
+Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue, CallSite);
+
+/// This is the result of instantiating ExternalRelation at a particular
+/// callsite
+struct InstantiatedRelation {
+ InstantiatedValue From, To;
+};
+Optional<InstantiatedRelation> instantiateExternalRelation(ExternalRelation,
+ CallSite);
+
+/// This is the result of instantiating ExternalAttribute at a particular
+/// callsite
+struct InstantiatedAttr {
+ InstantiatedValue IValue;
+ AliasAttrs Attr;
+};
+Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute,
+ CallSite);
+}
+}
+
+#endif
Modified: llvm/trunk/lib/Analysis/CFLGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CFLGraph.h?rev=274592&r1=274591&r2=274592&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CFLGraph.h (original)
+++ llvm/trunk/lib/Analysis/CFLGraph.h Tue Jul 5 19:47:21 2016
@@ -15,14 +15,11 @@
#ifndef LLVM_ANALYSIS_CFLGRAPH_H
#define LLVM_ANALYSIS_CFLGRAPH_H
-#include "StratifiedSets.h"
+#include "AliasAnalysisSummary.h"
+#include "llvm/ADT/STLExtras.h"
namespace llvm {
-
-class Value;
-
namespace cflaa {
-
/// Edges can be one of four "weights" -- each weight must have an inverse
/// weight (Assign has Assign; Reference has Dereference).
enum class EdgeType {
@@ -62,7 +59,7 @@ class CFLGraph {
struct NodeInfo {
EdgeList Edges;
- StratifiedAttrs Attr;
+ AliasAttrs Attr;
};
typedef DenseMap<Node, NodeInfo> NodeMap;
@@ -104,10 +101,12 @@ public:
const_node_iterator;
bool addNode(Node N) {
- return NodeImpls.insert(std::make_pair(N, NodeInfo{EdgeList(), 0})).second;
+ return NodeImpls
+ .insert(std::make_pair(N, NodeInfo{EdgeList(), getAttrNone()}))
+ .second;
}
- void addAttr(Node N, StratifiedAttrs Attr) {
+ void addAttr(Node N, AliasAttrs Attr) {
auto *Info = getNode(N);
assert(Info != nullptr);
Info->Attr |= Attr;
@@ -123,7 +122,7 @@ public:
ToInfo->Edges.push_back(Edge{flipWeight(Type), From});
}
- StratifiedAttrs attrFor(Node N) const {
+ AliasAttrs attrFor(Node N) const {
auto *Info = getNode(N);
assert(Info != nullptr);
return Info->Attr;
Modified: llvm/trunk/lib/Analysis/CFLSteensAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CFLSteensAliasAnalysis.cpp?rev=274592&r1=274591&r2=274592&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CFLSteensAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/CFLSteensAliasAnalysis.cpp Tue Jul 5 19:47:21 2016
@@ -37,6 +37,7 @@
#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
#include "CFLGraph.h"
+#include "StratifiedSets.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
@@ -67,39 +68,6 @@ CFLSteensAAResult::CFLSteensAAResult(CFL
: AAResultBase(std::move(Arg)), TLI(Arg.TLI) {}
CFLSteensAAResult::~CFLSteensAAResult() {}
-/// We use InterfaceValue to describe parameters/return value, as well as
-/// potential memory locations that are pointed to by parameters/return value,
-/// of a function.
-/// Index is an integer which represents a single parameter or a return value.
-/// When the index is 0, it refers to the return value. Non-zero index i refers
-/// to the i-th parameter.
-/// DerefLevel indicates the number of dereferences one must perform on the
-/// parameter/return value to get this InterfaceValue.
-struct InterfaceValue {
- unsigned Index;
- unsigned DerefLevel;
-};
-
-bool operator==(InterfaceValue lhs, InterfaceValue rhs) {
- return lhs.Index == rhs.Index && lhs.DerefLevel == rhs.DerefLevel;
-}
-bool operator!=(InterfaceValue lhs, InterfaceValue rhs) {
- return !(lhs == rhs);
-}
-
-/// We use ExternalRelation to describe an externally visible aliasing relations
-/// between parameters/return value of a function.
-struct ExternalRelation {
- InterfaceValue From, To;
-};
-
-/// We use ExternalAttribute to describe an externally visible StratifiedAttrs
-/// for parameters/return value.
-struct ExternalAttribute {
- InterfaceValue IValue;
- StratifiedAttrs Attr;
-};
-
/// Information we have about a function and would like to keep around.
class CFLSteensAAResult::FunctionInfo {
StratifiedSets<Value *> Sets;
@@ -135,26 +103,6 @@ const StratifiedIndex StratifiedLink::Se
std::numeric_limits<StratifiedIndex>::max();
namespace {
-/// StratifiedInfo Attribute things.
-LLVM_CONSTEXPR unsigned MaxStratifiedAttrIndex = NumStratifiedAttrs;
-LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0;
-LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1;
-LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2;
-LLVM_CONSTEXPR unsigned AttrCallerIndex = 3;
-LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4;
-LLVM_CONSTEXPR unsigned AttrLastArgIndex = MaxStratifiedAttrIndex;
-LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
-
-// NOTE: These aren't StratifiedAttrs because bitsets don't have a constexpr
-// ctor for some versions of MSVC that we support. We could maybe refactor,
-// but...
-using StratifiedAttr = unsigned;
-LLVM_CONSTEXPR StratifiedAttr AttrEscaped = 1 << AttrEscapedIndex;
-LLVM_CONSTEXPR StratifiedAttr AttrUnknown = 1 << AttrUnknownIndex;
-LLVM_CONSTEXPR StratifiedAttr AttrGlobal = 1 << AttrGlobalIndex;
-LLVM_CONSTEXPR StratifiedAttr AttrCaller = 1 << AttrCallerIndex;
-LLVM_CONSTEXPR StratifiedAttr ExternalAttrMask =
- AttrEscaped | AttrUnknown | AttrGlobal;
/// The maximum number of arguments we can put into a summary.
LLVM_CONSTEXPR unsigned MaxSupportedArgsInSummary = 50;
@@ -163,23 +111,6 @@ LLVM_CONSTEXPR unsigned MaxSupportedArgs
/// represent that locally.
enum class Level { Same, Above, Below };
-// This is the result of instantiating InterfaceValue at a particular callsite
-struct InterprocNode {
- Value *Val;
- unsigned DerefLevel;
-};
-
-// Interprocedural assignment edges that CFLGraph may not easily model
-struct InterprocEdge {
- InterprocNode From, To;
-};
-
-// Interprocedural attribute tagging that CFLGraph may not easily model
-struct InterprocAttr {
- InterprocNode Node;
- StratifiedAttrs Attr;
-};
-
/// Gets the edges our graph should have, based on an Instruction*
class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
CFLSteensAAResult &AA;
@@ -189,8 +120,8 @@ class GetEdgesVisitor : public InstVisit
SmallVectorImpl<Value *> &ReturnValues;
SmallPtrSetImpl<Value *> &Externals;
SmallPtrSetImpl<Value *> &Escapes;
- SmallVectorImpl<InterprocEdge> &InterprocEdges;
- SmallVectorImpl<InterprocAttr> &InterprocAttrs;
+ SmallVectorImpl<InstantiatedRelation> &InstantiatedRelations;
+ SmallVectorImpl<InstantiatedAttr> &InstantiatedAttrs;
static bool hasUsefulEdges(ConstantExpr *CE) {
// ConstantExpr doesn't have terminators, invokes, or fences, so only needs
@@ -210,7 +141,7 @@ class GetEdgesVisitor : public InstVisit
visitConstantExpr(CExpr);
}
- void addNodeWithAttr(Value *Val, StratifiedAttrs Attr) {
+ void addNodeWithAttr(Value *Val, AliasAttrs Attr) {
addNode(Val);
Graph.addAttr(Val, Attr);
}
@@ -229,11 +160,12 @@ public:
CFLGraph &Graph, SmallVectorImpl<Value *> &ReturnValues,
SmallPtrSetImpl<Value *> &Externals,
SmallPtrSetImpl<Value *> &Escapes,
- SmallVectorImpl<InterprocEdge> &InterprocEdges,
- SmallVectorImpl<InterprocAttr> &InterprocAttrs)
+ SmallVectorImpl<InstantiatedRelation> &InstantiatedRelations,
+ SmallVectorImpl<InstantiatedAttr> &InstantiatedAttrs)
: AA(AA), TLI(TLI), Graph(Graph), ReturnValues(ReturnValues),
- Externals(Externals), Escapes(Escapes), InterprocEdges(InterprocEdges),
- InterprocAttrs(InterprocAttrs) {}
+ Externals(Externals), Escapes(Escapes),
+ InstantiatedRelations(InstantiatedRelations),
+ InstantiatedAttrs(InstantiatedAttrs) {}
void visitInstruction(Instruction &) {
llvm_unreachable("Unsupported instruction encountered");
@@ -250,12 +182,12 @@ public:
void visitPtrToIntInst(PtrToIntInst &Inst) {
auto *Ptr = Inst.getOperand(0);
- addNodeWithAttr(Ptr, AttrEscaped);
+ addNodeWithAttr(Ptr, getAttrEscaped());
}
void visitIntToPtrInst(IntToPtrInst &Inst) {
auto *Ptr = &Inst;
- addNodeWithAttr(Ptr, AttrUnknown);
+ addNodeWithAttr(Ptr, getAttrUnknown());
}
void visitCastInst(CastInst &Inst) {
@@ -325,7 +257,7 @@ public:
// 2. Increments (stores to) *Ptr by some target-specific amount.
// For now, we'll handle this like a landingpad instruction (by placing the
// result in its own group, and having that group alias externals).
- addNodeWithAttr(&Inst, AttrUnknown);
+ addNodeWithAttr(&Inst, getAttrUnknown());
}
static bool isFunctionExternal(Function *Fn) {
@@ -350,35 +282,22 @@ public:
return false;
}
- auto InstantiateInterfaceIndex = [&CS](unsigned Index) {
- auto Value =
- (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
- return Value->getType()->isPointerTy() ? Value : nullptr;
- };
-
for (auto *Fn : Fns) {
auto &FnInfo = AA.ensureCached(Fn);
assert(FnInfo.hasValue());
auto &RetParamRelations = FnInfo->getRetParamRelations();
for (auto &Relation : RetParamRelations) {
- auto FromVal = InstantiateInterfaceIndex(Relation.From.Index);
- auto ToVal = InstantiateInterfaceIndex(Relation.To.Index);
- if (FromVal && ToVal) {
- auto FromLevel = Relation.From.DerefLevel;
- auto ToLevel = Relation.To.DerefLevel;
- InterprocEdges.push_back(
- InterprocEdge{InterprocNode{FromVal, FromLevel},
- InterprocNode{ToVal, ToLevel}});
- }
+ auto IRelation = instantiateExternalRelation(Relation, CS);
+ if (IRelation.hasValue())
+ InstantiatedRelations.push_back(*IRelation);
}
auto &RetParamAttributes = FnInfo->getRetParamAttributes();
for (auto &Attribute : RetParamAttributes) {
- if (auto Val = InstantiateInterfaceIndex(Attribute.IValue.Index)) {
- InterprocAttrs.push_back(InterprocAttr{
- InterprocNode{Val, Attribute.IValue.DerefLevel}, Attribute.Attr});
- }
+ auto IAttr = instantiateExternalAttribute(Attribute, CS);
+ if (IAttr.hasValue())
+ InstantiatedAttrs.push_back(*IAttr);
}
}
@@ -422,7 +341,7 @@ public:
if (Inst->getType()->isPointerTy()) {
auto *Fn = CS.getCalledFunction();
if (Fn == nullptr || !Fn->doesNotAlias(0))
- Graph.addAttr(Inst, AttrUnknown);
+ Graph.addAttr(Inst, getAttrUnknown());
}
}
@@ -447,7 +366,7 @@ public:
// Exceptions come from "nowhere", from our analysis' perspective.
// So we place the instruction its own group, noting that said group may
// alias externals
- addNodeWithAttr(&Inst, AttrUnknown);
+ addNodeWithAttr(&Inst, getAttrUnknown());
}
void visitInsertValueInst(InsertValueInst &Inst) {
@@ -495,8 +414,8 @@ class CFLGraphBuilder {
// Auxiliary structures used by the builder
SmallPtrSet<Value *, 8> ExternalValues;
SmallPtrSet<Value *, 8> EscapedValues;
- SmallVector<InterprocEdge, 8> InterprocEdges;
- SmallVector<InterprocAttr, 8> InterprocAttrs;
+ SmallVector<InstantiatedRelation, 8> InstantiatedRelations;
+ SmallVector<InstantiatedAttr, 8> InstantiatedAttrs;
// Helper functions
@@ -528,7 +447,7 @@ class CFLGraphBuilder {
return;
GetEdgesVisitor(Analysis, TLI, Graph, ReturnedValues, ExternalValues,
- EscapedValues, InterprocEdges, InterprocAttrs)
+ EscapedValues, InstantiatedRelations, InstantiatedAttrs)
.visit(Inst);
}
@@ -560,11 +479,11 @@ public:
const SmallPtrSet<Value *, 8> &getEscapedValues() const {
return EscapedValues;
}
- const SmallVector<InterprocEdge, 8> &getInterprocEdges() const {
- return InterprocEdges;
+ const SmallVector<InstantiatedRelation, 8> &getInstantiatedRelations() const {
+ return InstantiatedRelations;
}
- const SmallVector<InterprocAttr, 8> &getInterprocAttrs() const {
- return InterprocAttrs;
+ const SmallVector<InstantiatedAttr, 8> &getInstantiatedAttrs() const {
+ return InstantiatedAttrs;
}
};
}
@@ -573,20 +492,6 @@ public:
// Function declarations that require types defined in the namespace above
//===----------------------------------------------------------------------===//
-/// Given a StratifiedAttrs, returns true if it marks the corresponding values
-/// as globals or arguments
-static bool isGlobalOrArgAttr(StratifiedAttrs Attr);
-
-/// Given a StratifiedAttrs, returns true if the corresponding values come from
-/// an unknown source (such as opaque memory or an integer cast)
-static bool isUnknownAttr(StratifiedAttrs Attr);
-
-/// Given an argument number, returns the appropriate StratifiedAttr to set.
-static StratifiedAttrs argNumberToAttr(unsigned ArgNum);
-
-/// Given a Value, potentially return which StratifiedAttr it maps to.
-static Optional<StratifiedAttrs> valueToAttr(Value *Val);
-
/// Gets the "Level" that one should travel in StratifiedSets
/// given an EdgeType.
static Level directionOfEdgeType(EdgeType);
@@ -617,38 +522,6 @@ static bool getPossibleTargets(CallSite
return false;
}
-static bool isGlobalOrArgAttr(StratifiedAttrs Attr) {
- return Attr.reset(AttrEscapedIndex)
- .reset(AttrUnknownIndex)
- .reset(AttrCallerIndex)
- .any();
-}
-
-static bool isUnknownAttr(StratifiedAttrs Attr) {
- return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
-}
-
-static Optional<StratifiedAttrs> valueToAttr(Value *Val) {
- if (isa<GlobalValue>(Val))
- return StratifiedAttrs(AttrGlobal);
-
- if (auto *Arg = dyn_cast<Argument>(Val))
- // Only pointer arguments should have the argument attribute,
- // because things can't escape through scalars without us seeing a
- // cast, and thus, interaction with them doesn't matter.
- if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
- return argNumberToAttr(Arg->getArgNo());
- return None;
-}
-
-static StratifiedAttrs argNumberToAttr(unsigned ArgNum) {
- if (ArgNum >= AttrMaxNumArgs)
- return AttrUnknown;
- // N.B. MSVC complains if we use `1U` here, since StratifiedAttrs' ctor takes
- // an unsigned long long.
- return StratifiedAttrs(1ULL << (ArgNum + AttrFirstArgIndex));
-}
-
static Level directionOfEdgeType(EdgeType Weight) {
switch (Weight) {
case EdgeType::Reference:
@@ -715,7 +588,7 @@ CFLSteensAAResult::FunctionInfo::Functio
auto &Link = Sets.getLink(SetIndex);
InterfaceMap.insert(std::make_pair(SetIndex, CurrValue));
- auto ExternalAttrs = Link.Attrs & StratifiedAttrs(ExternalAttrMask);
+ auto ExternalAttrs = getExternallyVisibleAttrs(Link.Attrs);
if (ExternalAttrs.any())
RetParamAttributes.push_back(
ExternalAttribute{CurrValue, ExternalAttrs});
@@ -796,18 +669,18 @@ CFLSteensAAResult::FunctionInfo CFLSteen
// Special handling for globals and arguments
for (auto *External : GraphBuilder.getExternalValues()) {
SetBuilder.add(External);
- auto Attr = valueToAttr(External);
- if (Attr.hasValue()) {
- SetBuilder.noteAttributes(External, *Attr);
- if (*Attr == AttrGlobal)
- SetBuilder.addAttributesBelow(External, 1, AttrUnknown);
+ auto Attr = getGlobalOrArgAttrFromValue(*External);
+ if (Attr.any()) {
+ SetBuilder.noteAttributes(External, Attr);
+ if (isa<GlobalValue>(External))
+ SetBuilder.addAttributesBelow(External, 1, getAttrUnknown());
else
- SetBuilder.addAttributesBelow(External, 1, AttrCaller);
+ SetBuilder.addAttributesBelow(External, 1, getAttrCaller());
}
}
// Special handling for interprocedural aliases
- for (auto &Edge : GraphBuilder.getInterprocEdges()) {
+ for (auto &Edge : GraphBuilder.getInstantiatedRelations()) {
auto FromVal = Edge.From.Val;
auto ToVal = Edge.To.Val;
SetBuilder.add(FromVal);
@@ -817,17 +690,17 @@ CFLSteensAAResult::FunctionInfo CFLSteen
}
// Special handling for interprocedural attributes
- for (auto &IPAttr : GraphBuilder.getInterprocAttrs()) {
- auto Val = IPAttr.Node.Val;
+ for (auto &IPAttr : GraphBuilder.getInstantiatedAttrs()) {
+ auto Val = IPAttr.IValue.Val;
SetBuilder.add(Val);
- SetBuilder.addAttributesBelow(Val, IPAttr.Node.DerefLevel, IPAttr.Attr);
+ SetBuilder.addAttributesBelow(Val, IPAttr.IValue.DerefLevel, IPAttr.Attr);
}
// Special handling for opaque external functions
for (auto *Escape : GraphBuilder.getEscapedValues()) {
SetBuilder.add(Escape);
- SetBuilder.noteAttributes(Escape, AttrEscaped);
- SetBuilder.addAttributesBelow(Escape, 1, AttrUnknown);
+ SetBuilder.noteAttributes(Escape, getAttrEscaped());
+ SetBuilder.addAttributesBelow(Escape, 1, getAttrUnknown());
}
return FunctionInfo(*Fn, GraphBuilder.getReturnValues(), SetBuilder.build());
@@ -923,7 +796,7 @@ AliasResult CFLSteensAAResult::query(con
return MayAlias;
if (AttrsA.none() || AttrsB.none())
return NoAlias;
- if (isUnknownAttr(AttrsA) || isUnknownAttr(AttrsB))
+ if (hasUnknownOrCallerAttr(AttrsA) || hasUnknownOrCallerAttr(AttrsB))
return MayAlias;
if (isGlobalOrArgAttr(AttrsA) && isGlobalOrArgAttr(AttrsB))
return MayAlias;
Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=274592&r1=274591&r2=274592&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/lib/Analysis/CMakeLists.txt Tue Jul 5 19:47:21 2016
@@ -1,6 +1,7 @@
add_llvm_library(LLVMAnalysis
AliasAnalysis.cpp
AliasAnalysisEvaluator.cpp
+ AliasAnalysisSummary.cpp
AliasSetTracker.cpp
Analysis.cpp
AssumptionCache.cpp
Modified: llvm/trunk/lib/Analysis/StratifiedSets.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/StratifiedSets.h?rev=274592&r1=274591&r2=274592&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/StratifiedSets.h (original)
+++ llvm/trunk/lib/Analysis/StratifiedSets.h Tue Jul 5 19:47:21 2016
@@ -10,6 +10,7 @@
#ifndef LLVM_ADT_STRATIFIEDSETS_H
#define LLVM_ADT_STRATIFIEDSETS_H
+#include "AliasAnalysisSummary.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallSet.h"
@@ -34,17 +35,6 @@ struct StratifiedInfo {
/// 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).
-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.
-typedef std::bitset<NumStratifiedAttrs> StratifiedAttrs;
-
/// A "link" between two StratifiedSets.
struct StratifiedLink {
/// \brief This is a value used to signify "does not exist" where the
@@ -62,7 +52,7 @@ struct StratifiedLink {
StratifiedIndex Below;
/// Attributes for these StratifiedSets.
- StratifiedAttrs Attrs;
+ AliasAttrs Attrs;
StratifiedLink() : Above(SetSentinel), Below(SetSentinel) {}
@@ -243,14 +233,14 @@ template <typename T> class StratifiedSe
return Link.Above;
}
- StratifiedAttrs &getAttrs() {
+ AliasAttrs getAttrs() {
assert(!isRemapped());
return Link.Attrs;
}
- void setAttrs(const StratifiedAttrs &other) {
+ void setAttrs(AliasAttrs Other) {
assert(!isRemapped());
- Link.Attrs |= other;
+ Link.Attrs |= Other;
}
bool isRemapped() const { return Remap != StratifiedLink::SetSentinel; }
@@ -396,9 +386,9 @@ public:
return addAtMerging(ToAdd, Below);
}
- /// \brief Set the StratifiedAttrs of the set "Level"-levels below "Main". If
+ /// \brief Set the AliasAttrs of the set "Level"-levels below "Main". If
/// there is no set below "Main", create one for it.
- void addAttributesBelow(const T &Main, unsigned Level, StratifiedAttrs Attr) {
+ void addAttributesBelow(const T &Main, unsigned Level, AliasAttrs Attr) {
assert(has(Main));
auto Index = *indexOf(Main);
auto *Link = &linksAt(Index);
@@ -436,7 +426,7 @@ public:
merge(MainIndex, ToAddIndex);
}
- void noteAttributes(const T &Main, const StratifiedAttrs &NewAttrs) {
+ void noteAttributes(const T &Main, AliasAttrs NewAttrs) {
assert(has(Main));
auto *Info = *get(Main);
auto &Link = linksAt(Info->Index);
@@ -538,7 +528,7 @@ private:
// match `LinksFrom.Below`
// > If both have links above, deal with those next.
while (LinksInto->hasBelow() && LinksFrom->hasBelow()) {
- auto &FromAttrs = LinksFrom->getAttrs();
+ auto FromAttrs = LinksFrom->getAttrs();
LinksInto->setAttrs(FromAttrs);
// Remap needs to happen after getBelow(), but before
More information about the llvm-commits
mailing list