Index: lib/Analysis/CFLAliasAnalysis.cpp =================================================================== --- lib/Analysis/CFLAliasAnalysis.cpp +++ lib/Analysis/CFLAliasAnalysis.cpp @@ -102,14 +102,16 @@ typedef unsigned StratifiedAttr; LLVM_CONSTEXPR unsigned MaxStratifiedAttrIndex = NumStratifiedAttrs; LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0; -LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1; -LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2; -LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 3; +LLVM_CONSTEXPR unsigned AttrExternalIndex = 1; +LLVM_CONSTEXPR unsigned AttrUnknownIndex = 2; +LLVM_CONSTEXPR unsigned AttrGlobalIndex = 3; +LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4; LLVM_CONSTEXPR unsigned AttrLastArgIndex = MaxStratifiedAttrIndex; LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex; LLVM_CONSTEXPR StratifiedAttr AttrNone = 0; LLVM_CONSTEXPR StratifiedAttr AttrEscaped = 1 << AttrEscapedIndex; +LLVM_CONSTEXPR StratifiedAttr AttrExternal = 1 << AttrExternalIndex; LLVM_CONSTEXPR StratifiedAttr AttrUnknown = 1 << AttrUnknownIndex; LLVM_CONSTEXPR StratifiedAttr AttrGlobal = 1 << AttrGlobalIndex; @@ -653,9 +655,14 @@ // Function declarations that require types defined in the namespace above //===----------------------------------------------------------------------===// -/// Given a StratifiedAttrs, returns true if it marks the corresponding values -/// as unknown, globals or arguments -static bool isNonLocalAttr(StratifiedAttrs Attr); +/// Given a StratifiedAttrs, returns true if the corresponding values come from +/// unknown sources (such as opaque memory or integer cast) +static bool isUnknownAttr(StratifiedAttrs Attr); + +/// Given a StratifiedAttrs, returns true if the corresponding values come from +/// known sources (such as global/argument values) but may point to unknown +/// locations +static bool isExternalAttr(StratifiedAttrs Attr); /// Given an argument number, returns the appropriate StratifiedAttr to set. static StratifiedAttr argNumberToAttr(unsigned ArgNum); @@ -746,8 +753,12 @@ CE->getOpcode() != Instruction::FCmp; } -static bool isNonLocalAttr(StratifiedAttrs Attr) { - return Attr.reset(AttrEscapedIndex).any(); +static bool isUnknownAttr(StratifiedAttrs Attr) { + return Attr.reset(AttrEscapedIndex).reset(AttrExternalIndex).any(); +} + +static bool isExternalAttr(StratifiedAttrs Attr) { + return Attr == AttrExternal; } static Optional valueToAttr(Value *Val) { @@ -970,7 +981,7 @@ Optional MaybeCurAttr = valueToAttr(CurValue); if (MaybeCurAttr) - Builder.noteAttributes(CurValue, *MaybeCurAttr); + Builder.noteAttributes(CurValue, AttrExternal); for (const auto &EdgeTuple : Graph.edgesFor(Node)) { auto Weight = std::get<0>(EdgeTuple); @@ -982,7 +993,8 @@ continue; bool Added; - switch (directionOfEdgeType(Label)) { + auto Direction = directionOfEdgeType(Label); + switch (Direction) { case Level::Above: Added = Builder.addAbove(CurValue, OtherValue); break; @@ -995,13 +1007,19 @@ } auto Aliasing = Weight.second; - if (MaybeCurAttr) - Aliasing |= *MaybeCurAttr; - if (auto MaybeOtherAttr = valueToAttr(OtherValue)) - Aliasing |= *MaybeOtherAttr; Builder.noteAttributes(CurValue, Aliasing); Builder.noteAttributes(OtherValue, Aliasing); + if (MaybeCurAttr && Direction == Level::Below) + Builder.noteAttributes(OtherValue, *MaybeCurAttr); + + Optional MaybeOtherAttr = valueToAttr(OtherValue); + if (MaybeOtherAttr) { + Builder.noteAttributes(OtherValue, AttrExternal); + if (Direction == Level::Above) + Builder.noteAttributes(CurValue, *MaybeOtherAttr); + } + if (Added) Worklist.push_back(OtherNode); } @@ -1016,9 +1034,8 @@ if (!Builder.add(&Arg)) continue; - auto Attr = valueToAttr(&Arg); - if (Attr.hasValue()) - Builder.noteAttributes(&Arg, *Attr); + if (valueToAttr(&Arg).hasValue()) + Builder.noteAttributes(&Arg, AttrExternal); } return FunctionInfo(Builder.build(), std::move(ReturnedValues)); @@ -1100,16 +1117,20 @@ // AttrNone or AttrEscaped), then we know that CFLAA fully models them: they // may-alias each other if and only if they are in the same set // If at least one value is non-local (meaning it either is global/argument or - // it comes from unknown sources like integer cast), the situation becomes a - // bit more interesting. We follow three general rules described below: + // it comes from unknown sources like external memory or an integer cast), the + // situation becomes a bit more interesting. We follow three general rules + // described below: // - Non-local values may alias each other // - AttrNone values do not alias any non-local values - // - AttrEscaped may alias non-local values + // - AttrEscaped may alias AttrUnknown values, but do not alias AttrExternal + // values if (SetA.Index == SetB.Index) return MayAlias; if (AttrsA.none() || AttrsB.none()) return NoAlias; - if (isNonLocalAttr(AttrsA) || isNonLocalAttr(AttrsB)) + if (isUnknownAttr(AttrsA) || isUnknownAttr(AttrsB)) + return MayAlias; + if (isExternalAttr(AttrsA) && isExternalAttr(AttrsB)) return MayAlias; return NoAlias; }