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,
125 bool ExecuteOneTest(
const changeset_ty &S) {
128 for (changeset_ty::const_iterator it = S.begin(), ie = S.end(); it != ie;
132 assert(S.count(*it2) &&
"Attempt to run invalid changeset!");
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,
174 const changeset_ty &Required)
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(), ie = Changes.end();
232 if (it != Changes.begin())
250 for (std::vector<change_ty>::const_iterator it = Roots.begin(),
253 if (it != Roots.begin())
260 for (changeset_ty::const_iterator it = Changes.begin(), ie = Changes.end();
263 for (pred_closure_iterator_ty it2 = pred_closure_begin(*it),
264 ie2 = pred_closure_end(*it);
266 if (it2 != pred_closure_begin(*it))
274 for (changeset_ty::const_iterator it = Changes.begin(), ie = Changes.end();
277 for (succ_closure_iterator_ty it2 = succ_closure_begin(*it),
278 ie2 = succ_closure_end(*it);
280 if (it2 != succ_closure_begin(*it))
291 bool DAGDeltaAlgorithmImpl::GetTestResult(
const changeset_ty &Changes,
293 changeset_ty Extended(Required);
294 Extended.insert(Changes.begin(), Changes.end());
295 for (changeset_ty::const_iterator it = Changes.begin(),
296 ie = Changes.end(); it != ie; ++it)
297 Extended.insert(pred_closure_begin(*it), pred_closure_end(*it));
299 if (FailedTestsCache.count(Extended))
302 bool Result = ExecuteOneTest(Extended);
304 FailedTestsCache.insert(Extended);
310 DAGDeltaAlgorithmImpl::Run() {
312 changeset_ty CurrentSet(Roots.begin(), Roots.end());
322 while (!CurrentSet.empty()) {
324 llvm::errs() <<
"DAG_DD - " << CurrentSet.size() <<
" active changes, " 325 << Required.size() <<
" required changes\n";
329 DeltaActiveSetHelper Helper(*
this, Required);
330 changeset_ty CurrentMinSet = Helper.Run(CurrentSet);
339 Required.insert(CurrentMinSet.begin(), CurrentMinSet.end());
344 for (changeset_ty::const_iterator it = CurrentMinSet.begin(),
345 ie = CurrentMinSet.end(); it != ie; ++it)
355 void DAGDeltaAlgorithm::anchor() {
360 const std::vector<edge_ty> &Dependencies) {
361 return DAGDeltaAlgorithmImpl(*
this, Changes, Dependencies).Run();
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DAGDeltaAlgorithm - Implements a "delta debugging" algorithm for minimizing directed acyclic graphs u...
This class represents lattice values for constants.
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
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...
std::vector< changeset_ty > changesetlist_ty
Interval::succ_iterator succ_end(Interval *I)
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)
virtual bool ExecuteOneTest(const changeset_ty &S)=0
ExecuteOneTest - Execute a single test predicate on the change set S.
std::pair< change_ty, change_ty > edge_ty
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...
virtual void UpdatedSearchState(const changeset_ty &Changes, const changesetlist_ty &Sets, const changeset_ty &Required)
UpdatedSearchState - Callback used when the search state changes.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())