42#define DEBUG_TYPE "dag-delta"
46class DAGDeltaAlgorithmImpl {
47 friend class DeltaActiveSetHelper;
56 typedef std::vector<change_ty>::iterator pred_iterator_ty;
57 typedef std::vector<change_ty>::iterator succ_iterator_ty;
58 typedef std::set<change_ty>::iterator pred_closure_iterator_ty;
59 typedef std::set<change_ty>::iterator succ_closure_iterator_ty;
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!")
DAGDeltaAlgorithm - Implements a "delta debugging" algorithm for minimizing directed acyclic graphs u...
virtual bool ExecuteOneTest(const changeset_ty &S)=0
ExecuteOneTest - 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)
UpdatedSearchState - Callback used when the search state changes.
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.
DeltaAlgorithm - 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)