Skip to content

Commit f40af3b

Browse files
gilsaiaGroverkss
authored andcommitted
[MLIR][Presburger] Optimize for union & subtract
Added a series of optimization to the Subtract & Union function of PresburgerRelation, referring to the ISL implementation. Add isPlainEqual to Subtract & union,also some basic check to union. Tested it on a simple Benchmark implemented by myself to see that it can speed up the Subtract operation and Union operation, also decrease the result size. The Benchmark can be found here: [[ https://github.com/gilsaia/llvm-project-test-fpl/blob/develop_benchmark/mlir/benchmark/presburger/Benchmark.cpp | benchmark]] The overall results for Union & Subtract are as follows (previous benchmark has a bug,after fix that,the figure below is new) {F28455229} The results for each case are as follows {F28455234} {F28455239} {F28455245} {F28455246} Reviewed By: Groverkss Differential Revision: https://reviews.llvm.org/D156241
1 parent 19b1107 commit f40af3b

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

mlir/include/mlir/Analysis/Presburger/IntegerRelation.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ class IntegerRelation {
133133
/// (see IntegerRelation::findIntegerSample()).
134134
bool isEqual(const IntegerRelation &other) const;
135135

136+
/// Perform a quick equality check on `this` and `other`. The relations are
137+
/// equal if the check return true, but may or may not be equal if the check
138+
/// returns false. The equality check is performed in a plain manner, by
139+
/// comparing if all the equalities and inequalities in `this` and `other`
140+
/// are the same.
141+
bool isPlainEqual(const IntegerRelation &other) const;
142+
136143
/// Return whether this is a subset of the given IntegerRelation. This is
137144
/// integer-exact and somewhat expensive, since it uses the integer emptiness
138145
/// check (see IntegerRelation::findIntegerSample()).

mlir/include/mlir/Analysis/Presburger/PresburgerRelation.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ class PresburgerRelation {
152152
/// otherwise.
153153
bool isPlainUniverse() const;
154154

155+
/// Perform a quick equality check on `this` and `other`. The relations are
156+
/// equal if the check return true, but may or may not be equal if the check
157+
/// returns false. This is doing by directly comparing whether each internal
158+
/// disjunct is the same.
159+
bool isPlainEqual(const PresburgerRelation &set) const;
160+
155161
/// Return true if the set is consist of a single disjunct, without any local
156162
/// variables, false otherwise.
157163
bool isConvexNoLocals() const;

mlir/lib/Analysis/Presburger/IntegerRelation.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,30 @@ bool IntegerRelation::isEqual(const IntegerRelation &other) const {
8080
return PresburgerRelation(*this).isEqual(PresburgerRelation(other));
8181
}
8282

83+
bool IntegerRelation::isPlainEqual(const IntegerRelation &other) const {
84+
if (!space.isEqual(other.getSpace()))
85+
return false;
86+
if (getNumEqualities() != other.getNumEqualities())
87+
return false;
88+
if (getNumInequalities() != other.getNumInequalities())
89+
return false;
90+
91+
unsigned cols = getNumCols();
92+
for (unsigned i = 0, eqs = getNumEqualities(); i < eqs; ++i) {
93+
for (unsigned j = 0; j < cols; ++j) {
94+
if (atEq(i, j) != other.atEq(i, j))
95+
return false;
96+
}
97+
}
98+
for (unsigned i = 0, ineqs = getNumInequalities(); i < ineqs; ++i) {
99+
for (unsigned j = 0; j < cols; ++j) {
100+
if (atIneq(i, j) != other.atIneq(i, j))
101+
return false;
102+
}
103+
}
104+
return true;
105+
}
106+
83107
bool IntegerRelation::isSubsetOf(const IntegerRelation &other) const {
84108
assert(space.isCompatible(other.getSpace()) && "Spaces must be compatible.");
85109
return PresburgerRelation(*this).isSubsetOf(PresburgerRelation(other));

mlir/lib/Analysis/Presburger/PresburgerRelation.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,24 @@ void PresburgerRelation::unionInPlace(const IntegerRelation &disjunct) {
6363
/// to this set.
6464
void PresburgerRelation::unionInPlace(const PresburgerRelation &set) {
6565
assert(space.isCompatible(set.getSpace()) && "Spaces should match");
66+
67+
if (isPlainEqual(set))
68+
return;
69+
70+
if (isPlainEmpty()) {
71+
disjuncts = set.disjuncts;
72+
return;
73+
}
74+
if (set.isPlainEmpty())
75+
return;
76+
77+
if (isPlainUniverse())
78+
return;
79+
if (set.isPlainUniverse()) {
80+
disjuncts = set.disjuncts;
81+
return;
82+
}
83+
6684
for (const IntegerRelation &disjunct : set.disjuncts)
6785
unionInPlace(disjunct);
6886
}
@@ -511,6 +529,12 @@ PresburgerRelation
511529
PresburgerRelation::subtract(const PresburgerRelation &set) const {
512530
assert(space.isCompatible(set.getSpace()) && "Spaces should match");
513531
PresburgerRelation result(getSpace());
532+
533+
// If we know that the two sets are clearly equal, we can simply return the
534+
// empty set.
535+
if (isPlainEqual(set))
536+
return result;
537+
514538
// We compute (U_i t_i) \ (U_i set_i) as U_i (t_i \ V_i set_i).
515539
for (const IntegerRelation &disjunct : disjuncts)
516540
result.unionInPlace(getSetDifference(disjunct, set));
@@ -530,6 +554,22 @@ bool PresburgerRelation::isEqual(const PresburgerRelation &set) const {
530554
return this->isSubsetOf(set) && set.isSubsetOf(*this);
531555
}
532556

557+
bool PresburgerRelation::isPlainEqual(const PresburgerRelation &set) const {
558+
if (!space.isCompatible(set.getSpace()))
559+
return false;
560+
561+
if (getNumDisjuncts() != set.getNumDisjuncts())
562+
return false;
563+
564+
// Compare each disjunct in this PresburgerRelation with the corresponding
565+
// disjunct in the other PresburgerRelation.
566+
for (unsigned int i = 0, n = getNumDisjuncts(); i < n; ++i) {
567+
if (!getDisjunct(i).isPlainEqual(set.getDisjunct(i)))
568+
return false;
569+
}
570+
return true;
571+
}
572+
533573
/// Return true if the Presburger relation represents the universe set, false
534574
/// otherwise. It is a simple check that only check if the relation has at least
535575
/// one unconstrained disjunct, indicating the absence of constraints or

0 commit comments

Comments
 (0)