static FunctionInfo buildSetsFrom(CFLAliasAnalysis &Analysis, Function *Fn) { NodeMapT Map; GraphT Graph; SmallVector<Value *, 4> ReturnedValues; buildGraphFrom(Analysis, Fn, ReturnedValues, Map, Graph); DenseMap<GraphT::Node, Value *> NodeValueMap; NodeValueMap.resize(Map.size()); for (const auto &Pair : Map) NodeValueMap.insert(std::make_pair(Pair.second, Pair.first)); const auto findValueOrDie = [&NodeValueMap](GraphT::Node Node) { auto ValIter = NodeValueMap.find(Node); assert(ValIter != NodeValueMap.end()); return ValIter->second; }; StratifiedSetsBuilder<Value *> Builder; SmallVector<GraphT::Node, 16> Worklist; for (auto &Pair : Map) { Worklist.clear(); auto *Value = Pair.first; Builder.add(Value); auto InitialNode = Pair.second; Worklist.push_back(InitialNode); while (!Worklist.empty()) { auto Node = Worklist.pop_back_val(); auto *CurValue = findValueOrDie(Node); if (isa<Constant>(CurValue) && !isa<GlobalValue>(CurValue)) continue; for (const auto &EdgeTuple : Graph.edgesFor(Node)) { auto Weight = std::get<0>(EdgeTuple); auto Label = Weight.first; auto &OtherNode = std::get<1>(EdgeTuple); auto *OtherValue = findValueOrDie(OtherNode); if (isa<Constant>(OtherValue) && !isa<GlobalValue>(OtherValue)) continue; bool Added; switch (directionOfEdgeType(Label)) { case Level::Above: Added = Builder.addAbove(CurValue, OtherValue); break; case Level::Below: Added = Builder.addBelow(CurValue, OtherValue); break; case Level::Same: Added = Builder.addWith(CurValue, OtherValue); break; } if (Added) { auto Aliasing = Weight.second; if (auto MaybeCurIndex = valueToAttrIndex(CurValue)) Aliasing.set(*MaybeCurIndex); if (auto MaybeOtherIndex = valueToAttrIndex(OtherValue)) Aliasing.set(*MaybeOtherIndex); Builder.noteAttributes(CurValue, Aliasing); Builder.noteAttributes(OtherValue, Aliasing); Worklist.push_back(OtherNode); } } } } // There are times when we end up with parameters not in our graph (i.e. if // it's only used as the condition of a branch). Other bits of code depend on // things that were present during construction being present in the graph. // So, we add all present arguments here. for (auto &Arg : Fn->args()) { Builder.add(&Arg); } return FunctionInfo(Builder.build(), std::move(ReturnedValues)); }
// Builds the graph + StratifiedSets for a function. CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) { CFLGraphBuilder GraphBuilder(*this, TLI, *Fn); StratifiedSetsBuilder<Value *> SetBuilder; auto &Graph = GraphBuilder.getCFLGraph(); SmallVector<Value *, 16> Worklist; for (auto Node : Graph.nodes()) Worklist.push_back(Node); while (!Worklist.empty()) { auto *CurValue = Worklist.pop_back_val(); SetBuilder.add(CurValue); if (canSkipAddingToSets(CurValue)) continue; for (const auto &Edge : Graph.edgesFor(CurValue)) { auto Label = Edge.Type; auto *OtherValue = Edge.Other; if (canSkipAddingToSets(OtherValue)) continue; bool Added; switch (directionOfEdgeType(Label)) { case Level::Above: Added = SetBuilder.addAbove(CurValue, OtherValue); break; case Level::Below: Added = SetBuilder.addBelow(CurValue, OtherValue); break; case Level::Same: Added = SetBuilder.addWith(CurValue, OtherValue); break; } auto Aliasing = Edge.Attr; SetBuilder.noteAttributes(CurValue, Aliasing); SetBuilder.noteAttributes(OtherValue, Aliasing); if (Added) Worklist.push_back(OtherValue); } } // 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); SetBuilder.addAttributesBelow(External, AttrUnknown); } } for (auto *Escape : GraphBuilder.getEscapedValues()) { SetBuilder.add(Escape); SetBuilder.noteAttributes(Escape, AttrEscaped); SetBuilder.addAttributesBelow(Escape, AttrUnknown); } return FunctionInfo(SetBuilder.build(), GraphBuilder.takeReturnValues()); }
// 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; 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); if (canSkipAddingToSets(CurValue)) continue; if (isa<GlobalValue>(CurValue)) Globals.insert(CurValue); for (const auto &Edge : Graph.edgesFor(CurValue)) { auto Label = Edge.Type; auto *OtherValue = Edge.Other; if (canSkipAddingToSets(OtherValue)) continue; if (isa<GlobalValue>(OtherValue)) Globals.insert(OtherValue); bool Added; switch (directionOfEdgeType(Label)) { case Level::Above: Added = Builder.addAbove(CurValue, OtherValue); break; case Level::Below: Added = Builder.addBelow(CurValue, OtherValue); break; case Level::Same: Added = Builder.addWith(CurValue, OtherValue); break; } auto Aliasing = Edge.Attr; Builder.noteAttributes(CurValue, Aliasing); Builder.noteAttributes(OtherValue, Aliasing); if (Added) Worklist.push_back(OtherValue); } } // Special handling for globals and arguments auto ProcessGlobalOrArgValue = [&Builder](Value &Val) { Builder.add(&Val); auto Attr = valueToAttr(&Val); if (Attr.hasValue()) { Builder.noteAttributes(&Val, *Attr); // TODO: do we need to filter out non-pointer values here? Builder.addAttributesBelow(&Val, AttrUnknown); } }; for (auto &Arg : Fn->args()) ProcessGlobalOrArgValue(Arg); for (auto *Global : Globals) ProcessGlobalOrArgValue(*Global); return FunctionInfo(Builder.build(), std::move(ReturnedValues)); }
// Builds the graph + StratifiedSets for a function. CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) { CFLGraphBuilder GraphBuilder(*this, TLI, *Fn); StratifiedSetsBuilder<Value *> SetBuilder; auto &Graph = GraphBuilder.getCFLGraph(); SmallVector<Value *, 16> Worklist; for (auto Node : Graph.nodes()) Worklist.push_back(Node); while (!Worklist.empty()) { auto *CurValue = Worklist.pop_back_val(); SetBuilder.add(CurValue); if (canSkipAddingToSets(CurValue)) continue; auto Attr = Graph.attrFor(CurValue); SetBuilder.noteAttributes(CurValue, Attr); for (const auto &Edge : Graph.edgesFor(CurValue)) { auto Label = Edge.Type; auto *OtherValue = Edge.Other; if (canSkipAddingToSets(OtherValue)) continue; bool Added; switch (directionOfEdgeType(Label)) { case Level::Above: Added = SetBuilder.addAbove(CurValue, OtherValue); break; case Level::Below: Added = SetBuilder.addBelow(CurValue, OtherValue); break; case Level::Same: Added = SetBuilder.addWith(CurValue, OtherValue); break; } if (Added) Worklist.push_back(OtherValue); } } // 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); else SetBuilder.addAttributesBelow(External, 1, AttrCaller); } } // Special handling for interprocedural aliases for (auto &Edge : GraphBuilder.getInterprocEdges()) { auto FromVal = Edge.From.Val; auto ToVal = Edge.To.Val; SetBuilder.add(FromVal); SetBuilder.add(ToVal); SetBuilder.addBelowWith(FromVal, Edge.From.DerefLevel, ToVal, Edge.To.DerefLevel); } // Special handling for interprocedural attributes for (auto &IPAttr : GraphBuilder.getInterprocAttrs()) { auto Val = IPAttr.Node.Val; SetBuilder.add(Val); SetBuilder.addAttributesBelow(Val, IPAttr.Node.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); } return FunctionInfo(*Fn, GraphBuilder.getReturnValues(), SetBuilder.build()); }