Skip to content

Commit 93b9f50

Browse files
committed
[MLIR][Presburger] IntegerRelation: implement partial rollback support
It is often necessary to "rollback" IntegerRelations to an earlier state. Although providing full rollback support is non-trivial, we really only need to support the case where the only changes made are to append ids or append constraints, and then rollback these additions. This patch adds support to rollback in such situations by recording the number of ids and constraints of each kind and providing support to truncate the IntegerRelation to those counts by removing appended ids and constraints. This already simplifies subtraction a little bit and will also be useful in the implementation of symbolic integer lexmin. Reviewed By: Groverkss Differential Revision: https://reviews.llvm.org/D122178
1 parent 9a8a0a3 commit 93b9f50

File tree

5 files changed

+63
-7
lines changed

5 files changed

+63
-7
lines changed

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,30 @@ class IntegerRelation : public PresburgerLocalSpace {
148148
return inequalities.getRow(idx);
149149
}
150150

151+
/// The struct CountsSnapshot stores the count of each IdKind, and also of
152+
/// each constraint type. getCounts() returns a CountsSnapshot object
153+
/// describing the current state of the IntegerRelation. truncate() truncates
154+
/// all ids of each IdKind and all constraints of both kinds beyond the counts
155+
/// in the specified CountsSnapshot object. This can be used to achieve
156+
/// rudimentary rollback support. As long as none of the existing constraints
157+
/// or ids are disturbed, and only additional ids or constraints are added,
158+
/// this addition can be rolled back using truncate.
159+
struct CountsSnapshot {
160+
public:
161+
CountsSnapshot(const PresburgerLocalSpace &space, unsigned numIneqs,
162+
unsigned numEqs)
163+
: space(space), numIneqs(numIneqs), numEqs(numEqs) {}
164+
const PresburgerLocalSpace &getSpace() const { return space; };
165+
unsigned getNumIneqs() const { return numIneqs; }
166+
unsigned getNumEqs() const { return numEqs; }
167+
168+
private:
169+
PresburgerLocalSpace space;
170+
unsigned numIneqs, numEqs;
171+
};
172+
CountsSnapshot getCounts() const;
173+
void truncate(const CountsSnapshot &counts);
174+
151175
/// Insert `num` identifiers of the specified kind at position `pos`.
152176
/// Positions are relative to the kind of identifier. The coefficient columns
153177
/// corresponding to the added identifiers are initialized to zero. Return the
@@ -491,6 +515,11 @@ class IntegerRelation : public PresburgerLocalSpace {
491515
/// arrays as needed.
492516
void removeIdRange(unsigned idStart, unsigned idLimit);
493517

518+
using PresburgerSpace::truncateIdKind;
519+
/// Truncate the ids to the number in the space of the specified
520+
/// CountsSnapshot.
521+
void truncateIdKind(IdKind kind, const CountsSnapshot &counts);
522+
494523
/// A parameter that controls detection of an unrealistic number of
495524
/// constraints. If the number of constraints is this many times the number of
496525
/// variables, we consider such a system out of line with the intended use

mlir/include/mlir/Analysis/Presburger/PresburgerSpace.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ class PresburgerSpace {
109109
/// idLimit). The range is relative to the kind of identifier.
110110
virtual void removeIdRange(IdKind kind, unsigned idStart, unsigned idLimit);
111111

112+
/// Truncate the ids of the specified kind to the specified number by dropping
113+
/// some ids at the end. `num` must be less than the current number.
114+
void truncateIdKind(IdKind kind, unsigned num);
115+
112116
/// Returns true if both the spaces are equal i.e. if both spaces have the
113117
/// same number of identifiers of each kind (excluding Local Identifiers).
114118
bool isEqual(const PresburgerSpace &other) const;

mlir/lib/Analysis/Presburger/IntegerRelation.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,26 @@ void removeConstraintsInvolvingIdRange(IntegerRelation &poly, unsigned begin,
126126
if (!rangeIsZero(poly.getInequality(i - 1).slice(begin, count)))
127127
poly.removeInequality(i - 1);
128128
}
129+
130+
IntegerRelation::CountsSnapshot IntegerRelation::getCounts() const {
131+
return {PresburgerLocalSpace(*this), getNumInequalities(),
132+
getNumEqualities()};
133+
}
134+
135+
void IntegerRelation::truncateIdKind(IdKind kind,
136+
const CountsSnapshot &counts) {
137+
truncateIdKind(kind, counts.getSpace().getNumIdKind(kind));
138+
}
139+
140+
void IntegerRelation::truncate(const CountsSnapshot &counts) {
141+
truncateIdKind(IdKind::Domain, counts);
142+
truncateIdKind(IdKind::Range, counts);
143+
truncateIdKind(IdKind::Symbol, counts);
144+
truncateIdKind(IdKind::Local, counts);
145+
removeInequalityRange(counts.getNumIneqs(), getNumInequalities());
146+
removeInequalityRange(counts.getNumEqs(), getNumEqualities());
147+
}
148+
129149
unsigned IntegerRelation::insertId(IdKind kind, unsigned pos, unsigned num) {
130150
assert(pos <= getNumIdKind(kind));
131151

mlir/lib/Analysis/Presburger/PresburgerRelation.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,12 @@ static void subtractRecursively(IntegerRelation &b, Simplex &simplex,
153153
// rollback b to its initial state before returning, which we will do by
154154
// removing all constraints beyond the original number of inequalities
155155
// and equalities, so we store these counts first.
156-
const unsigned bInitNumIneqs = b.getNumInequalities();
157-
const unsigned bInitNumEqs = b.getNumEqualities();
158-
const unsigned bInitNumLocals = b.getNumLocalIds();
156+
const IntegerRelation::CountsSnapshot bCounts = b.getCounts();
159157
// Similarly, we also want to rollback simplex to its original state.
160158
const unsigned initialSnapshot = simplex.getSnapshot();
161159

162160
auto restoreState = [&]() {
163-
b.removeIdRange(IdKind::Local, bInitNumLocals, b.getNumLocalIds());
164-
b.removeInequalityRange(bInitNumIneqs, b.getNumInequalities());
165-
b.removeEqualityRange(bInitNumEqs, b.getNumEqualities());
161+
b.truncate(bCounts);
166162
simplex.rollback(initialSnapshot);
167163
};
168164

@@ -198,7 +194,8 @@ static void subtractRecursively(IntegerRelation &b, Simplex &simplex,
198194
}
199195

200196
unsigned offset = simplex.getNumConstraints();
201-
unsigned numLocalsAdded = b.getNumLocalIds() - bInitNumLocals;
197+
unsigned numLocalsAdded =
198+
b.getNumLocalIds() - bCounts.getSpace().getNumLocalIds();
202199
simplex.appendVariable(numLocalsAdded);
203200

204201
unsigned snapshotBeforeIntersect = simplex.getSnapshot();

mlir/lib/Analysis/Presburger/PresburgerSpace.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ void PresburgerSpace::removeIdRange(IdKind kind, unsigned idStart,
9191
llvm_unreachable("PresburgerSpace does not support local identifiers!");
9292
}
9393

94+
void PresburgerSpace::truncateIdKind(IdKind kind, unsigned num) {
95+
unsigned curNum = getNumIdKind(kind);
96+
assert(num <= curNum && "Can't truncate to more ids!");
97+
removeIdRange(kind, num, curNum);
98+
}
99+
94100
unsigned PresburgerLocalSpace::insertId(IdKind kind, unsigned pos,
95101
unsigned num) {
96102
if (kind == IdKind::Local) {

0 commit comments

Comments
 (0)