1*9880d681SAndroid Build Coastguard Worker //===--- DAGDeltaAlgorithm.cpp - A DAG Minimization Algorithm --*- C++ -*--===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*9880d681SAndroid Build Coastguard Worker //
9*9880d681SAndroid Build Coastguard Worker // The algorithm we use attempts to exploit the dependency information by
10*9880d681SAndroid Build Coastguard Worker // minimizing top-down. We start by constructing an initial root set R, and
11*9880d681SAndroid Build Coastguard Worker // then iteratively:
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker // 1. Minimize the set R using the test predicate:
14*9880d681SAndroid Build Coastguard Worker // P'(S) = P(S union pred*(S))
15*9880d681SAndroid Build Coastguard Worker //
16*9880d681SAndroid Build Coastguard Worker // 2. Extend R to R' = R union pred(R).
17*9880d681SAndroid Build Coastguard Worker //
18*9880d681SAndroid Build Coastguard Worker // until a fixed point is reached.
19*9880d681SAndroid Build Coastguard Worker //
20*9880d681SAndroid Build Coastguard Worker // The idea is that we want to quickly prune entire portions of the graph, so we
21*9880d681SAndroid Build Coastguard Worker // try to find high-level nodes that can be eliminated with all of their
22*9880d681SAndroid Build Coastguard Worker // dependents.
23*9880d681SAndroid Build Coastguard Worker //
24*9880d681SAndroid Build Coastguard Worker // FIXME: The current algorithm doesn't actually provide a strong guarantee
25*9880d681SAndroid Build Coastguard Worker // about the minimality of the result. The problem is that after adding nodes to
26*9880d681SAndroid Build Coastguard Worker // the required set, we no longer consider them for elimination. For strictly
27*9880d681SAndroid Build Coastguard Worker // well formed predicates, this doesn't happen, but it commonly occurs in
28*9880d681SAndroid Build Coastguard Worker // practice when there are unmodelled dependencies. I believe we can resolve
29*9880d681SAndroid Build Coastguard Worker // this by allowing the required set to be minimized as well, but need more test
30*9880d681SAndroid Build Coastguard Worker // cases first.
31*9880d681SAndroid Build Coastguard Worker //
32*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DAGDeltaAlgorithm.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DeltaAlgorithm.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
39*9880d681SAndroid Build Coastguard Worker #include <algorithm>
40*9880d681SAndroid Build Coastguard Worker #include <cassert>
41*9880d681SAndroid Build Coastguard Worker #include <iterator>
42*9880d681SAndroid Build Coastguard Worker #include <map>
43*9880d681SAndroid Build Coastguard Worker using namespace llvm;
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "dag-delta"
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker namespace {
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker class DAGDeltaAlgorithmImpl {
50*9880d681SAndroid Build Coastguard Worker friend class DeltaActiveSetHelper;
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker public:
53*9880d681SAndroid Build Coastguard Worker typedef DAGDeltaAlgorithm::change_ty change_ty;
54*9880d681SAndroid Build Coastguard Worker typedef DAGDeltaAlgorithm::changeset_ty changeset_ty;
55*9880d681SAndroid Build Coastguard Worker typedef DAGDeltaAlgorithm::changesetlist_ty changesetlist_ty;
56*9880d681SAndroid Build Coastguard Worker typedef DAGDeltaAlgorithm::edge_ty edge_ty;
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker private:
59*9880d681SAndroid Build Coastguard Worker typedef std::vector<change_ty>::iterator pred_iterator_ty;
60*9880d681SAndroid Build Coastguard Worker typedef std::vector<change_ty>::iterator succ_iterator_ty;
61*9880d681SAndroid Build Coastguard Worker typedef std::set<change_ty>::iterator pred_closure_iterator_ty;
62*9880d681SAndroid Build Coastguard Worker typedef std::set<change_ty>::iterator succ_closure_iterator_ty;
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithm &DDA;
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker std::vector<change_ty> Roots;
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker /// Cache of failed test results. Successful test results are never cached
69*9880d681SAndroid Build Coastguard Worker /// since we always reduce following a success. We maintain an independent
70*9880d681SAndroid Build Coastguard Worker /// cache from that used by the individual delta passes because we may get
71*9880d681SAndroid Build Coastguard Worker /// hits across multiple individual delta invocations.
72*9880d681SAndroid Build Coastguard Worker mutable std::set<changeset_ty> FailedTestsCache;
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker // FIXME: Gross.
75*9880d681SAndroid Build Coastguard Worker std::map<change_ty, std::vector<change_ty> > Predecessors;
76*9880d681SAndroid Build Coastguard Worker std::map<change_ty, std::vector<change_ty> > Successors;
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker std::map<change_ty, std::set<change_ty> > PredClosure;
79*9880d681SAndroid Build Coastguard Worker std::map<change_ty, std::set<change_ty> > SuccClosure;
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker private:
pred_begin(change_ty Node)82*9880d681SAndroid Build Coastguard Worker pred_iterator_ty pred_begin(change_ty Node) {
83*9880d681SAndroid Build Coastguard Worker assert(Predecessors.count(Node) && "Invalid node!");
84*9880d681SAndroid Build Coastguard Worker return Predecessors[Node].begin();
85*9880d681SAndroid Build Coastguard Worker }
pred_end(change_ty Node)86*9880d681SAndroid Build Coastguard Worker pred_iterator_ty pred_end(change_ty Node) {
87*9880d681SAndroid Build Coastguard Worker assert(Predecessors.count(Node) && "Invalid node!");
88*9880d681SAndroid Build Coastguard Worker return Predecessors[Node].end();
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker
pred_closure_begin(change_ty Node)91*9880d681SAndroid Build Coastguard Worker pred_closure_iterator_ty pred_closure_begin(change_ty Node) {
92*9880d681SAndroid Build Coastguard Worker assert(PredClosure.count(Node) && "Invalid node!");
93*9880d681SAndroid Build Coastguard Worker return PredClosure[Node].begin();
94*9880d681SAndroid Build Coastguard Worker }
pred_closure_end(change_ty Node)95*9880d681SAndroid Build Coastguard Worker pred_closure_iterator_ty pred_closure_end(change_ty Node) {
96*9880d681SAndroid Build Coastguard Worker assert(PredClosure.count(Node) && "Invalid node!");
97*9880d681SAndroid Build Coastguard Worker return PredClosure[Node].end();
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker
succ_begin(change_ty Node)100*9880d681SAndroid Build Coastguard Worker succ_iterator_ty succ_begin(change_ty Node) {
101*9880d681SAndroid Build Coastguard Worker assert(Successors.count(Node) && "Invalid node!");
102*9880d681SAndroid Build Coastguard Worker return Successors[Node].begin();
103*9880d681SAndroid Build Coastguard Worker }
succ_end(change_ty Node)104*9880d681SAndroid Build Coastguard Worker succ_iterator_ty succ_end(change_ty Node) {
105*9880d681SAndroid Build Coastguard Worker assert(Successors.count(Node) && "Invalid node!");
106*9880d681SAndroid Build Coastguard Worker return Successors[Node].end();
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker
succ_closure_begin(change_ty Node)109*9880d681SAndroid Build Coastguard Worker succ_closure_iterator_ty succ_closure_begin(change_ty Node) {
110*9880d681SAndroid Build Coastguard Worker assert(SuccClosure.count(Node) && "Invalid node!");
111*9880d681SAndroid Build Coastguard Worker return SuccClosure[Node].begin();
112*9880d681SAndroid Build Coastguard Worker }
succ_closure_end(change_ty Node)113*9880d681SAndroid Build Coastguard Worker succ_closure_iterator_ty succ_closure_end(change_ty Node) {
114*9880d681SAndroid Build Coastguard Worker assert(SuccClosure.count(Node) && "Invalid node!");
115*9880d681SAndroid Build Coastguard Worker return SuccClosure[Node].end();
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker
UpdatedSearchState(const changeset_ty & Changes,const changesetlist_ty & Sets,const changeset_ty & Required)118*9880d681SAndroid Build Coastguard Worker void UpdatedSearchState(const changeset_ty &Changes,
119*9880d681SAndroid Build Coastguard Worker const changesetlist_ty &Sets,
120*9880d681SAndroid Build Coastguard Worker const changeset_ty &Required) {
121*9880d681SAndroid Build Coastguard Worker DDA.UpdatedSearchState(Changes, Sets, Required);
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker /// ExecuteOneTest - Execute a single test predicate on the change set \p S.
ExecuteOneTest(const changeset_ty & S)125*9880d681SAndroid Build Coastguard Worker bool ExecuteOneTest(const changeset_ty &S) {
126*9880d681SAndroid Build Coastguard Worker // Check dependencies invariant.
127*9880d681SAndroid Build Coastguard Worker DEBUG({
128*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = S.begin(),
129*9880d681SAndroid Build Coastguard Worker ie = S.end(); it != ie; ++it)
130*9880d681SAndroid Build Coastguard Worker for (succ_iterator_ty it2 = succ_begin(*it),
131*9880d681SAndroid Build Coastguard Worker ie2 = succ_end(*it); it2 != ie2; ++it2)
132*9880d681SAndroid Build Coastguard Worker assert(S.count(*it2) && "Attempt to run invalid changeset!");
133*9880d681SAndroid Build Coastguard Worker });
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker return DDA.ExecuteOneTest(S);
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker public:
139*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithmImpl(DAGDeltaAlgorithm &DDA, const changeset_ty &Changes,
140*9880d681SAndroid Build Coastguard Worker const std::vector<edge_ty> &Dependencies);
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker changeset_ty Run();
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker /// GetTestResult - Get the test result for the active set \p Changes with
145*9880d681SAndroid Build Coastguard Worker /// \p Required changes from the cache, executing the test if necessary.
146*9880d681SAndroid Build Coastguard Worker ///
147*9880d681SAndroid Build Coastguard Worker /// \param Changes - The set of active changes being minimized, which should
148*9880d681SAndroid Build Coastguard Worker /// have their pred closure included in the test.
149*9880d681SAndroid Build Coastguard Worker /// \param Required - The set of changes which have previously been
150*9880d681SAndroid Build Coastguard Worker /// established to be required.
151*9880d681SAndroid Build Coastguard Worker /// \return - The test result.
152*9880d681SAndroid Build Coastguard Worker bool GetTestResult(const changeset_ty &Changes, const changeset_ty &Required);
153*9880d681SAndroid Build Coastguard Worker };
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker /// Helper object for minimizing an active set of changes.
156*9880d681SAndroid Build Coastguard Worker class DeltaActiveSetHelper : public DeltaAlgorithm {
157*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithmImpl &DDAI;
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker const changeset_ty &Required;
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker protected:
162*9880d681SAndroid Build Coastguard Worker /// UpdatedSearchState - Callback used when the search state changes.
UpdatedSearchState(const changeset_ty & Changes,const changesetlist_ty & Sets)163*9880d681SAndroid Build Coastguard Worker void UpdatedSearchState(const changeset_ty &Changes,
164*9880d681SAndroid Build Coastguard Worker const changesetlist_ty &Sets) override {
165*9880d681SAndroid Build Coastguard Worker DDAI.UpdatedSearchState(Changes, Sets, Required);
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
ExecuteOneTest(const changeset_ty & S)168*9880d681SAndroid Build Coastguard Worker bool ExecuteOneTest(const changeset_ty &S) override {
169*9880d681SAndroid Build Coastguard Worker return DDAI.GetTestResult(S, Required);
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker public:
DeltaActiveSetHelper(DAGDeltaAlgorithmImpl & DDAI,const changeset_ty & Required)173*9880d681SAndroid Build Coastguard Worker DeltaActiveSetHelper(DAGDeltaAlgorithmImpl &DDAI,
174*9880d681SAndroid Build Coastguard Worker const changeset_ty &Required)
175*9880d681SAndroid Build Coastguard Worker : DDAI(DDAI), Required(Required) {}
176*9880d681SAndroid Build Coastguard Worker };
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
DAGDeltaAlgorithmImpl(DAGDeltaAlgorithm & DDA,const changeset_ty & Changes,const std::vector<edge_ty> & Dependencies)180*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithmImpl::DAGDeltaAlgorithmImpl(
181*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithm &DDA, const changeset_ty &Changes,
182*9880d681SAndroid Build Coastguard Worker const std::vector<edge_ty> &Dependencies)
183*9880d681SAndroid Build Coastguard Worker : DDA(DDA) {
184*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
185*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it) {
186*9880d681SAndroid Build Coastguard Worker Predecessors.insert(std::make_pair(*it, std::vector<change_ty>()));
187*9880d681SAndroid Build Coastguard Worker Successors.insert(std::make_pair(*it, std::vector<change_ty>()));
188*9880d681SAndroid Build Coastguard Worker }
189*9880d681SAndroid Build Coastguard Worker for (std::vector<edge_ty>::const_iterator it = Dependencies.begin(),
190*9880d681SAndroid Build Coastguard Worker ie = Dependencies.end(); it != ie; ++it) {
191*9880d681SAndroid Build Coastguard Worker Predecessors[it->second].push_back(it->first);
192*9880d681SAndroid Build Coastguard Worker Successors[it->first].push_back(it->second);
193*9880d681SAndroid Build Coastguard Worker }
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker // Compute the roots.
196*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
197*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it)
198*9880d681SAndroid Build Coastguard Worker if (succ_begin(*it) == succ_end(*it))
199*9880d681SAndroid Build Coastguard Worker Roots.push_back(*it);
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker // Pre-compute the closure of the successor relation.
202*9880d681SAndroid Build Coastguard Worker std::vector<change_ty> Worklist(Roots.begin(), Roots.end());
203*9880d681SAndroid Build Coastguard Worker while (!Worklist.empty()) {
204*9880d681SAndroid Build Coastguard Worker change_ty Change = Worklist.back();
205*9880d681SAndroid Build Coastguard Worker Worklist.pop_back();
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker std::set<change_ty> &ChangeSuccs = SuccClosure[Change];
208*9880d681SAndroid Build Coastguard Worker for (pred_iterator_ty it = pred_begin(Change),
209*9880d681SAndroid Build Coastguard Worker ie = pred_end(Change); it != ie; ++it) {
210*9880d681SAndroid Build Coastguard Worker SuccClosure[*it].insert(Change);
211*9880d681SAndroid Build Coastguard Worker SuccClosure[*it].insert(ChangeSuccs.begin(), ChangeSuccs.end());
212*9880d681SAndroid Build Coastguard Worker Worklist.push_back(*it);
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker }
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker // Invert to form the predecessor closure map.
217*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
218*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it)
219*9880d681SAndroid Build Coastguard Worker PredClosure.insert(std::make_pair(*it, std::set<change_ty>()));
220*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
221*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it)
222*9880d681SAndroid Build Coastguard Worker for (succ_closure_iterator_ty it2 = succ_closure_begin(*it),
223*9880d681SAndroid Build Coastguard Worker ie2 = succ_closure_end(*it); it2 != ie2; ++it2)
224*9880d681SAndroid Build Coastguard Worker PredClosure[*it2].insert(*it);
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Worker // Dump useful debug info.
227*9880d681SAndroid Build Coastguard Worker DEBUG({
228*9880d681SAndroid Build Coastguard Worker llvm::errs() << "-- DAGDeltaAlgorithmImpl --\n";
229*9880d681SAndroid Build Coastguard Worker llvm::errs() << "Changes: [";
230*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
231*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it) {
232*9880d681SAndroid Build Coastguard Worker if (it != Changes.begin()) llvm::errs() << ", ";
233*9880d681SAndroid Build Coastguard Worker llvm::errs() << *it;
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker if (succ_begin(*it) != succ_end(*it)) {
236*9880d681SAndroid Build Coastguard Worker llvm::errs() << "(";
237*9880d681SAndroid Build Coastguard Worker for (succ_iterator_ty it2 = succ_begin(*it),
238*9880d681SAndroid Build Coastguard Worker ie2 = succ_end(*it); it2 != ie2; ++it2) {
239*9880d681SAndroid Build Coastguard Worker if (it2 != succ_begin(*it)) llvm::errs() << ", ";
240*9880d681SAndroid Build Coastguard Worker llvm::errs() << "->" << *it2;
241*9880d681SAndroid Build Coastguard Worker }
242*9880d681SAndroid Build Coastguard Worker llvm::errs() << ")";
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker }
245*9880d681SAndroid Build Coastguard Worker llvm::errs() << "]\n";
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker llvm::errs() << "Roots: [";
248*9880d681SAndroid Build Coastguard Worker for (std::vector<change_ty>::const_iterator it = Roots.begin(),
249*9880d681SAndroid Build Coastguard Worker ie = Roots.end(); it != ie; ++it) {
250*9880d681SAndroid Build Coastguard Worker if (it != Roots.begin()) llvm::errs() << ", ";
251*9880d681SAndroid Build Coastguard Worker llvm::errs() << *it;
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker llvm::errs() << "]\n";
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker llvm::errs() << "Predecessor Closure:\n";
256*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
257*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it) {
258*9880d681SAndroid Build Coastguard Worker llvm::errs() << format(" %-4d: [", *it);
259*9880d681SAndroid Build Coastguard Worker for (pred_closure_iterator_ty it2 = pred_closure_begin(*it),
260*9880d681SAndroid Build Coastguard Worker ie2 = pred_closure_end(*it); it2 != ie2; ++it2) {
261*9880d681SAndroid Build Coastguard Worker if (it2 != pred_closure_begin(*it)) llvm::errs() << ", ";
262*9880d681SAndroid Build Coastguard Worker llvm::errs() << *it2;
263*9880d681SAndroid Build Coastguard Worker }
264*9880d681SAndroid Build Coastguard Worker llvm::errs() << "]\n";
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker llvm::errs() << "Successor Closure:\n";
268*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
269*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it) {
270*9880d681SAndroid Build Coastguard Worker llvm::errs() << format(" %-4d: [", *it);
271*9880d681SAndroid Build Coastguard Worker for (succ_closure_iterator_ty it2 = succ_closure_begin(*it),
272*9880d681SAndroid Build Coastguard Worker ie2 = succ_closure_end(*it); it2 != ie2; ++it2) {
273*9880d681SAndroid Build Coastguard Worker if (it2 != succ_closure_begin(*it)) llvm::errs() << ", ";
274*9880d681SAndroid Build Coastguard Worker llvm::errs() << *it2;
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker llvm::errs() << "]\n";
277*9880d681SAndroid Build Coastguard Worker }
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker llvm::errs() << "\n\n";
280*9880d681SAndroid Build Coastguard Worker });
281*9880d681SAndroid Build Coastguard Worker }
282*9880d681SAndroid Build Coastguard Worker
GetTestResult(const changeset_ty & Changes,const changeset_ty & Required)283*9880d681SAndroid Build Coastguard Worker bool DAGDeltaAlgorithmImpl::GetTestResult(const changeset_ty &Changes,
284*9880d681SAndroid Build Coastguard Worker const changeset_ty &Required) {
285*9880d681SAndroid Build Coastguard Worker changeset_ty Extended(Required);
286*9880d681SAndroid Build Coastguard Worker Extended.insert(Changes.begin(), Changes.end());
287*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = Changes.begin(),
288*9880d681SAndroid Build Coastguard Worker ie = Changes.end(); it != ie; ++it)
289*9880d681SAndroid Build Coastguard Worker Extended.insert(pred_closure_begin(*it), pred_closure_end(*it));
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Worker if (FailedTestsCache.count(Extended))
292*9880d681SAndroid Build Coastguard Worker return false;
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker bool Result = ExecuteOneTest(Extended);
295*9880d681SAndroid Build Coastguard Worker if (!Result)
296*9880d681SAndroid Build Coastguard Worker FailedTestsCache.insert(Extended);
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker return Result;
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithm::changeset_ty
Run()302*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithmImpl::Run() {
303*9880d681SAndroid Build Coastguard Worker // The current set of changes we are minimizing, starting at the roots.
304*9880d681SAndroid Build Coastguard Worker changeset_ty CurrentSet(Roots.begin(), Roots.end());
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker // The set of required changes.
307*9880d681SAndroid Build Coastguard Worker changeset_ty Required;
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker // Iterate until the active set of changes is empty. Convergence is guaranteed
310*9880d681SAndroid Build Coastguard Worker // assuming input was a DAG.
311*9880d681SAndroid Build Coastguard Worker //
312*9880d681SAndroid Build Coastguard Worker // Invariant: CurrentSet intersect Required == {}
313*9880d681SAndroid Build Coastguard Worker // Invariant: Required == (Required union succ*(Required))
314*9880d681SAndroid Build Coastguard Worker while (!CurrentSet.empty()) {
315*9880d681SAndroid Build Coastguard Worker DEBUG({
316*9880d681SAndroid Build Coastguard Worker llvm::errs() << "DAG_DD - " << CurrentSet.size() << " active changes, "
317*9880d681SAndroid Build Coastguard Worker << Required.size() << " required changes\n";
318*9880d681SAndroid Build Coastguard Worker });
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker // Minimize the current set of changes.
321*9880d681SAndroid Build Coastguard Worker DeltaActiveSetHelper Helper(*this, Required);
322*9880d681SAndroid Build Coastguard Worker changeset_ty CurrentMinSet = Helper.Run(CurrentSet);
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker // Update the set of required changes. Since
325*9880d681SAndroid Build Coastguard Worker // CurrentMinSet subset CurrentSet
326*9880d681SAndroid Build Coastguard Worker // and after the last iteration,
327*9880d681SAndroid Build Coastguard Worker // succ(CurrentSet) subset Required
328*9880d681SAndroid Build Coastguard Worker // then
329*9880d681SAndroid Build Coastguard Worker // succ(CurrentMinSet) subset Required
330*9880d681SAndroid Build Coastguard Worker // and our invariant on Required is maintained.
331*9880d681SAndroid Build Coastguard Worker Required.insert(CurrentMinSet.begin(), CurrentMinSet.end());
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker // Replace the current set with the predecssors of the minimized set of
334*9880d681SAndroid Build Coastguard Worker // active changes.
335*9880d681SAndroid Build Coastguard Worker CurrentSet.clear();
336*9880d681SAndroid Build Coastguard Worker for (changeset_ty::const_iterator it = CurrentMinSet.begin(),
337*9880d681SAndroid Build Coastguard Worker ie = CurrentMinSet.end(); it != ie; ++it)
338*9880d681SAndroid Build Coastguard Worker CurrentSet.insert(pred_begin(*it), pred_end(*it));
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker // FIXME: We could enforce CurrentSet intersect Required == {} here if we
341*9880d681SAndroid Build Coastguard Worker // wanted to protect against cyclic graphs.
342*9880d681SAndroid Build Coastguard Worker }
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker return Required;
345*9880d681SAndroid Build Coastguard Worker }
346*9880d681SAndroid Build Coastguard Worker
anchor()347*9880d681SAndroid Build Coastguard Worker void DAGDeltaAlgorithm::anchor() {
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithm::changeset_ty
Run(const changeset_ty & Changes,const std::vector<edge_ty> & Dependencies)351*9880d681SAndroid Build Coastguard Worker DAGDeltaAlgorithm::Run(const changeset_ty &Changes,
352*9880d681SAndroid Build Coastguard Worker const std::vector<edge_ty> &Dependencies) {
353*9880d681SAndroid Build Coastguard Worker return DAGDeltaAlgorithmImpl(*this, Changes, Dependencies).Run();
354*9880d681SAndroid Build Coastguard Worker }
355