// 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()); }