42#define DEBUG_TYPE "dag-delta"
46class DAGDeltaAlgorithmImpl {
47 friend class DeltaActiveSetHelper;
56 using pred_iterator_ty = std::vector<change_ty>::iterator;
57 using succ_iterator_ty = std::vector<change_ty>::iterator;
58 using pred_closure_iterator_ty = std::set<change_ty>::iterator;
59 using succ_closure_iterator_ty = std::set<change_ty>::iterator;
63 std::vector<change_ty> Roots;
69 mutable std::set<changeset_ty> FailedTestsCache;
72 std::map<change_ty, std::vector<change_ty> > Predecessors;
73 std::map<change_ty, std::vector<change_ty> > Successors;
75 std::map<change_ty, std::set<change_ty> > PredClosure;
76 std::map<change_ty, std::set<change_ty> > SuccClosure;
80 assert(Predecessors.count(
Node) &&
"Invalid node!");
81 return Predecessors[
Node].begin();
84 assert(Predecessors.count(
Node) &&
"Invalid node!");
85 return Predecessors[
Node].end();
88 pred_closure_iterator_ty pred_closure_begin(change_ty
Node) {
89 assert(PredClosure.count(
Node) &&
"Invalid node!");
90 return PredClosure[
Node].begin();
92 pred_closure_iterator_ty pred_closure_end(change_ty
Node) {
93 assert(PredClosure.count(
Node) &&
"Invalid node!");
94 return PredClosure[
Node].end();
98 assert(Successors.count(
Node) &&
"Invalid node!");
99 return Successors[
Node].begin();
102 assert(Successors.count(
Node) &&
"Invalid node!");
103 return Successors[
Node].end();
106 succ_closure_iterator_ty succ_closure_begin(change_ty
Node) {
107 assert(SuccClosure.count(
Node) &&
"Invalid node!");
108 return SuccClosure[
Node].begin();
110 succ_closure_iterator_ty succ_closure_end(change_ty
Node) {
111 assert(SuccClosure.count(
Node) &&
"Invalid node!");
112 return SuccClosure[
Node].end();
115 void UpdatedSearchState(
const changeset_ty &Changes,
116 const changesetlist_ty &Sets,
122 bool ExecuteOneTest(
const changeset_ty &S) {
125 for (changeset_ty::const_iterator it = S.begin(), ie = S.end(); it != ie;
129 assert(S.count(*it2) &&
"Attempt to run invalid changeset!");
137 const std::vector<edge_ty> &Dependencies);
149 bool GetTestResult(
const changeset_ty &Changes,
const changeset_ty &
Required);
154 DAGDeltaAlgorithmImpl &DDAI;
160 void UpdatedSearchState(
const changeset_ty &Changes,
161 const changesetlist_ty &Sets)
override {
162 DDAI.UpdatedSearchState(Changes, Sets,
Required);
165 bool ExecuteOneTest(
const changeset_ty &S)
override {
166 return DDAI.GetTestResult(S,
Required);
170 DeltaActiveSetHelper(DAGDeltaAlgorithmImpl &DDAI,
177DAGDeltaAlgorithmImpl::DAGDeltaAlgorithmImpl(
179 const std::vector<edge_ty> &Dependencies)
181 for (change_ty Change : Changes) {
182 Predecessors.try_emplace(Change);
183 Successors.try_emplace(Change);
185 for (
const edge_ty &Dep : Dependencies) {
186 Predecessors[Dep.second].push_back(Dep.first);
187 Successors[Dep.first].push_back(Dep.second);
191 for (change_ty Change : Changes)
193 Roots.push_back(Change);
196 std::vector<change_ty> Worklist(Roots.begin(), Roots.end());
197 while (!Worklist.empty()) {
198 change_ty Change = Worklist.back();
201 std::set<change_ty> &ChangeSuccs = SuccClosure[Change];
202 for (pred_iterator_ty it = pred_begin(Change),
203 ie = pred_end(Change); it != ie; ++it) {
204 auto &SC = SuccClosure[*it];
206 SC.insert(ChangeSuccs.begin(), ChangeSuccs.end());
207 Worklist.push_back(*it);
212 for (change_ty Change : Changes)
213 PredClosure.try_emplace(Change);
214 for (change_ty Change : Changes)
215 for (succ_closure_iterator_ty it2 = succ_closure_begin(Change),
216 ie2 = succ_closure_end(Change);
218 PredClosure[*it2].insert(Change);
222 llvm::errs() <<
"-- DAGDeltaAlgorithmImpl --\n";
224 for (changeset_ty::const_iterator it = Changes.begin(), ie = Changes.end();
226 if (it != Changes.begin())
244 for (std::vector<change_ty>::const_iterator it = Roots.begin(),
247 if (it != Roots.begin())
254 for (change_ty Change : Changes) {
256 for (pred_closure_iterator_ty it2 = pred_closure_begin(Change),
257 ie2 = pred_closure_end(Change);
259 if (it2 != pred_closure_begin(Change))
267 for (change_ty Change : Changes) {
269 for (succ_closure_iterator_ty it2 = succ_closure_begin(Change),
270 ie2 = succ_closure_end(Change);
272 if (it2 != succ_closure_begin(Change))
283bool DAGDeltaAlgorithmImpl::GetTestResult(
const changeset_ty &Changes,
286 Extended.insert(Changes.begin(), Changes.end());
287 for (change_ty Change : Changes)
288 Extended.insert(pred_closure_begin(Change), pred_closure_end(Change));
290 if (FailedTestsCache.count(Extended))
293 bool Result = ExecuteOneTest(Extended);
295 FailedTestsCache.insert(Extended);
301DAGDeltaAlgorithmImpl::Run() {
303 changeset_ty CurrentSet(Roots.begin(), Roots.end());
313 while (!CurrentSet.empty()) {
315 llvm::errs() <<
"DAG_DD - " << CurrentSet.size() <<
" active changes, "
316 <<
Required.size() <<
" required changes\n";
320 DeltaActiveSetHelper Helper(*
this,
Required);
321 changeset_ty CurrentMinSet = Helper.Run(CurrentSet);
330 Required.insert(CurrentMinSet.begin(), CurrentMinSet.end());
335 for (change_ty CT : CurrentMinSet)
345void DAGDeltaAlgorithm::anchor() {
350 const std::vector<edge_ty> &Dependencies) {
351 return DAGDeltaAlgorithmImpl(*
this, Changes, Dependencies).Run();
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Implements a "delta debugging" algorithm for minimizing directed acyclic graphs using a predicate fun...
virtual bool ExecuteOneTest(const changeset_ty &S)=0
Execute a single test predicate on the change set S.
std::vector< changeset_ty > changesetlist_ty
std::set< change_ty > changeset_ty
std::pair< change_ty, change_ty > edge_ty
virtual void UpdatedSearchState(const changeset_ty &Changes, const changesetlist_ty &Sets, const changeset_ty &Required)
Callback used when the search state changes.
changeset_ty Run(const changeset_ty &Changes, const std::vector< edge_ty > &Dependencies)
Minimize the DAG formed by the Changes vertices and the Dependencies edges by executing.
Implements the delta debugging algorithm (A.
This is an optimization pass for GlobalISel generic memory operations.
auto pred_end(const MachineBasicBlock *BB)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
auto pred_begin(const MachineBasicBlock *BB)