static AliasAttrMap buildAttrMap(const CFLGraph &Graph, const ReachabilitySet &ReachSet) { AliasAttrMap AttrMap; std::vector<InstantiatedValue> WorkList, NextList; // Initialize each node with its original AliasAttrs in CFLGraph for (const auto &Mapping : Graph.value_mappings()) { auto Val = Mapping.first; auto &ValueInfo = Mapping.second; for (unsigned I = 0, E = ValueInfo.getNumLevels(); I < E; ++I) { auto Node = InstantiatedValue{Val, I}; AttrMap.add(Node, ValueInfo.getNodeInfoAtLevel(I).Attr); WorkList.push_back(Node); } } while (!WorkList.empty()) { for (const auto &Dst : WorkList) { auto DstAttr = AttrMap.getAttrs(Dst); if (DstAttr.none()) continue; // Propagate attr on the same level for (const auto &Mapping : ReachSet.reachableValueAliases(Dst)) { auto Src = Mapping.first; if (AttrMap.add(Src, DstAttr)) NextList.push_back(Src); } // Propagate attr to the levels below auto DstBelow = getNodeBelow(Graph, Dst); while (DstBelow) { if (AttrMap.add(*DstBelow, DstAttr)) { NextList.push_back(*DstBelow); break; } DstBelow = getNodeBelow(Graph, *DstBelow); } } WorkList.swap(NextList); NextList.clear(); } return AttrMap; }
static void initializeWorkList(std::vector<WorkListItem> &WorkList, ReachabilitySet &ReachSet, const CFLGraph &Graph) { for (const auto &Mapping : Graph.value_mappings()) { auto Val = Mapping.first; auto &ValueInfo = Mapping.second; assert(ValueInfo.getNumLevels() > 0); // Insert all immediate assignment neighbors to the worklist for (unsigned I = 0, E = ValueInfo.getNumLevels(); I < E; ++I) { auto Src = InstantiatedValue{Val, I}; // If there's an assignment edge from X to Y, it means Y is reachable from // X at S2 and X is reachable from Y at S1 for (auto &Edge : ValueInfo.getNodeInfoAtLevel(I).Edges) { propagate(Edge.Other, Src, MatchState::FlowFrom, ReachSet, WorkList); propagate(Src, Edge.Other, MatchState::FlowTo, ReachSet, WorkList); } } } }