1 //===--- DeltaAlgorithm.cpp - A Set Minimization Algorithm -----*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/DeltaAlgorithm.h"
14 DeltaAlgorithm::~DeltaAlgorithm() {
17 bool DeltaAlgorithm::GetTestResult(const changeset_ty &Changes) {
18 if (FailedTestsCache.count(Changes))
21 bool Result = ExecuteOneTest(Changes);
23 FailedTestsCache.insert(Changes);
28 void DeltaAlgorithm::Split(const changeset_ty &S, changesetlist_ty &Res) {
29 // FIXME: Allow clients to provide heuristics for improved splitting.
30 // Get the iterator to the middle.
31 unsigned N = S.size() / 2;
32 changeset_ty::iterator middle(S.begin());
33 std::advance(middle, N);
35 // Create each vector using the middle as the split.
36 changeset_ty LHS(S.begin(), middle);
37 changeset_ty RHS(middle, S.end());
45 DeltaAlgorithm::changeset_ty
46 DeltaAlgorithm::Delta(const changeset_ty &Changes,
47 const changesetlist_ty &Sets) {
48 // Invariant: union(Res) == Changes
49 UpdatedSearchState(Changes, Sets);
51 // If there is nothing left we can remove, we are done.
55 // Look for a passing subset.
57 if (Search(Changes, Sets, Res))
60 // Otherwise, partition the sets if possible; if not we are done.
61 changesetlist_ty SplitSets;
62 for (changesetlist_ty::const_iterator it = Sets.begin(),
63 ie = Sets.end(); it != ie; ++it)
64 Split(*it, SplitSets);
65 if (SplitSets.size() == Sets.size())
68 return Delta(Changes, SplitSets);
71 bool DeltaAlgorithm::Search(const changeset_ty &Changes,
72 const changesetlist_ty &Sets,
74 // FIXME: Parallelize.
75 for (changesetlist_ty::const_iterator it = Sets.begin(),
76 ie = Sets.end(); it != ie; ++it) {
77 // If the test passes on this subset alone, recurse.
78 if (GetTestResult(*it)) {
79 changesetlist_ty Sets;
81 Res = Delta(*it, Sets);
85 // Otherwise, if we have more than two sets, see if test passes on the
87 if (Sets.size() > 2) {
88 // FIXME: This is really slow.
89 changeset_ty Complement;
91 Changes.begin(), Changes.end(), it->begin(), it->end(),
92 std::insert_iterator<changeset_ty>(Complement, Complement.begin()));
93 if (GetTestResult(Complement)) {
94 changesetlist_ty ComplementSets;
95 ComplementSets.insert(ComplementSets.end(), Sets.begin(), it);
96 ComplementSets.insert(ComplementSets.end(), it + 1, Sets.end());
97 Res = Delta(Complement, ComplementSets);
106 DeltaAlgorithm::changeset_ty DeltaAlgorithm::Run(const changeset_ty &Changes) {
107 // Check empty set first to quickly find poor test functions.
108 if (GetTestResult(changeset_ty()))
109 return changeset_ty();
111 // Otherwise run the real delta algorithm.
112 changesetlist_ty Sets;
113 Split(Changes, Sets);
115 return Delta(Changes, Sets);