45 #define DEBUG_TYPE "dag-delta"
49 class DAGDeltaAlgorithmImpl {
50 friend class DeltaActiveSetHelper;
59 typedef std::vector<change_ty>::iterator pred_iterator_ty;
60 typedef std::vector<change_ty>::iterator succ_iterator_ty;
61 typedef std::set<change_ty>::iterator pred_closure_iterator_ty;
62 typedef std::set<change_ty>::iterator succ_closure_iterator_ty;
66 std::vector<change_ty> Roots;
72 mutable std::set<changeset_ty> FailedTestsCache;
75 std::map<change_ty, std::vector<change_ty> > Predecessors;
76 std::map<change_ty, std::vector<change_ty> > Successors;
78 std::map<change_ty, std::set<change_ty> > PredClosure;
79 std::map<change_ty, std::set<change_ty> > SuccClosure;
83 assert(Predecessors.count(Node) &&
"Invalid node!");
84 return Predecessors[Node].begin();
86 pred_iterator_ty
pred_end(change_ty Node) {
87 assert(Predecessors.count(Node) &&
"Invalid node!");
88 return Predecessors[Node].end();
91 pred_closure_iterator_ty pred_closure_begin(change_ty Node) {
92 assert(PredClosure.count(Node) &&
"Invalid node!");
93 return PredClosure[Node].begin();
95 pred_closure_iterator_ty pred_closure_end(change_ty Node) {
96 assert(PredClosure.count(Node) &&
"Invalid node!");
97 return PredClosure[Node].end();
101 assert(Successors.count(Node) &&
"Invalid node!");
102 return Successors[Node].begin();
104 succ_iterator_ty
succ_end(change_ty Node) {
105 assert(Successors.count(Node) &&
"Invalid node!");
106 return Successors[Node].end();
109 succ_closure_iterator_ty succ_closure_begin(change_ty Node) {
110 assert(SuccClosure.count(Node) &&
"Invalid node!");
111 return SuccClosure[Node].begin();
113 succ_closure_iterator_ty succ_closure_end(change_ty Node) {
114 assert(SuccClosure.count(Node) &&
"Invalid node!");
115 return SuccClosure[Node].end();
118 void UpdatedSearchState(
const changeset_ty &Changes,
119 const changesetlist_ty &Sets,
121 DDA.UpdatedSearchState(Changes, Sets, Required);
125 bool ExecuteOneTest(
const changeset_ty &S) {
128 for (changeset_ty::const_iterator it = S.begin(),
129 ie = S.end(); it != ie; ++it)
131 ie2 =
succ_end(*it); it2 != ie2; ++it2)
132 assert(S.count(*it2) &&
"Attempt to run invalid changeset!");
135 return DDA.ExecuteOneTest(S);
140 const std::vector<edge_ty> &Dependencies);
152 bool GetTestResult(
const changeset_ty &Changes,
const changeset_ty &Required);
157 DAGDeltaAlgorithmImpl &DDAI;
163 void UpdatedSearchState(
const changeset_ty &Changes,
164 const changesetlist_ty &Sets)
override {
165 DDAI.UpdatedSearchState(Changes, Sets,
Required);
168 bool ExecuteOneTest(
const changeset_ty &S)
override {
169 return DDAI.GetTestResult(S,
Required);
173 DeltaActiveSetHelper(DAGDeltaAlgorithmImpl &DDAI,
180 DAGDeltaAlgorithmImpl::DAGDeltaAlgorithmImpl(
182 const std::vector<edge_ty> &Dependencies)
184 for (changeset_ty::const_iterator it = Changes.begin(),
185 ie = Changes.end(); it != ie; ++it) {
186 Predecessors.insert(std::make_pair(*it, std::vector<change_ty>()));
187 Successors.insert(std::make_pair(*it, std::vector<change_ty>()));
189 for (std::vector<edge_ty>::const_iterator it = Dependencies.begin(),
190 ie = Dependencies.end(); it != ie; ++it) {
191 Predecessors[it->second].push_back(it->first);
192 Successors[it->first].push_back(it->second);
196 for (changeset_ty::const_iterator it = Changes.begin(),
197 ie = Changes.end(); it != ie; ++it)
199 Roots.push_back(*it);
202 std::vector<change_ty> Worklist(Roots.begin(), Roots.end());
203 while (!Worklist.empty()) {
204 change_ty Change = Worklist.back();
207 std::set<change_ty> &ChangeSuccs = SuccClosure[Change];
208 for (pred_iterator_ty it =
pred_begin(Change),
209 ie =
pred_end(Change); it != ie; ++it) {
210 SuccClosure[*it].insert(Change);
211 SuccClosure[*it].insert(ChangeSuccs.begin(), ChangeSuccs.end());
212 Worklist.push_back(*it);
217 for (changeset_ty::const_iterator it = Changes.begin(),
218 ie = Changes.end(); it != ie; ++it)
219 PredClosure.insert(std::make_pair(*it, std::set<change_ty>()));
220 for (changeset_ty::const_iterator it = Changes.begin(),
221 ie = Changes.end(); it != ie; ++it)
222 for (succ_closure_iterator_ty it2 = succ_closure_begin(*it),
223 ie2 = succ_closure_end(*it); it2 != ie2; ++it2)
224 PredClosure[*it2].insert(*it);
228 llvm::errs() <<
"-- DAGDeltaAlgorithmImpl --\n";
230 for (changeset_ty::const_iterator it = Changes.begin(),
231 ie = Changes.end(); it != ie; ++it) {
232 if (it != Changes.begin())
llvm::errs() <<
", ";
238 ie2 =
succ_end(*it); it2 != ie2; ++it2) {
248 for (std::vector<change_ty>::const_iterator it = Roots.begin(),
249 ie = Roots.end(); it != ie; ++it) {
250 if (it != Roots.begin())
llvm::errs() <<
", ";
256 for (changeset_ty::const_iterator it = Changes.begin(),
257 ie = Changes.end(); it != ie; ++it) {
259 for (pred_closure_iterator_ty it2 = pred_closure_begin(*it),
260 ie2 = pred_closure_end(*it); it2 != ie2; ++it2) {
261 if (it2 != pred_closure_begin(*it))
llvm::errs() <<
", ";
268 for (changeset_ty::const_iterator it = Changes.begin(),
269 ie = Changes.end(); it != ie; ++it) {
271 for (succ_closure_iterator_ty it2 = succ_closure_begin(*it),
272 ie2 = succ_closure_end(*it); it2 != ie2; ++it2) {
273 if (it2 != succ_closure_begin(*it))
llvm::errs() <<
", ";
283 bool DAGDeltaAlgorithmImpl::GetTestResult(
const changeset_ty &Changes,
285 changeset_ty Extended(Required);
286 Extended.insert(Changes.begin(), Changes.end());
287 for (changeset_ty::const_iterator it = Changes.begin(),
288 ie = Changes.end(); it != ie; ++it)
289 Extended.insert(pred_closure_begin(*it), pred_closure_end(*it));
291 if (FailedTestsCache.count(Extended))
294 bool Result = ExecuteOneTest(Extended);
296 FailedTestsCache.insert(Extended);
302 DAGDeltaAlgorithmImpl::Run() {
304 changeset_ty CurrentSet(Roots.begin(), Roots.end());
314 while (!CurrentSet.empty()) {
316 llvm::errs() <<
"DAG_DD - " << CurrentSet.size() <<
" active changes, "
317 << Required.size() <<
" required changes\n";
321 DeltaActiveSetHelper Helper(*
this, Required);
322 changeset_ty CurrentMinSet = Helper.Run(CurrentSet);
331 Required.insert(CurrentMinSet.begin(), CurrentMinSet.end());
336 for (changeset_ty::const_iterator it = CurrentMinSet.begin(),
337 ie = CurrentMinSet.end(); it != ie; ++it)
347 void DAGDeltaAlgorithm::anchor() {
352 const std::vector<edge_ty> &Dependencies) {
353 return DAGDeltaAlgorithmImpl(*
this, Changes, Dependencies).Run();
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
std::pair< change_ty, change_ty > edge_ty
DAGDeltaAlgorithm - Implements a "delta debugging" algorithm for minimizing directed acyclic graphs u...
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Interval::succ_iterator succ_end(Interval *I)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
std::set< change_ty > changeset_ty
DeltaAlgorithm - Implements the delta debugging algorithm (A.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Interval::pred_iterator pred_end(Interval *I)
changeset_ty Run(const changeset_ty &Changes, const std::vector< edge_ty > &Dependencies)
Run - Minimize the DAG formed by the Changes vertices and the Dependencies edges by executing...
std::vector< changeset_ty > changesetlist_ty