Skip to content

Commit 6f7cba6

Browse files
authored
[Comb] delete slow canonicalizer (#8014)
This canonicalizer does not have a functional issue, but is causing bad performance issues. This change removes it until it can be fixed properly.
1 parent 40c2014 commit 6f7cba6

File tree

2 files changed

+0
-192
lines changed

2 files changed

+0
-192
lines changed

lib/Dialect/Comb/CombFolds.cpp

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,107 +1178,6 @@ OpFoldResult OrOp::fold(FoldAdaptor adaptor) {
11781178
return constFoldAssociativeOp(inputs, hw::PEO::Or);
11791179
}
11801180

1181-
/// Simplify concat ops in an or op when a constant operand is present in either
1182-
/// concat.
1183-
///
1184-
/// This will invert an or(concat, concat) into concat(or, or, ...), which can
1185-
/// often be further simplified due to the smaller or ops being easier to fold.
1186-
///
1187-
/// For example:
1188-
///
1189-
/// or(..., concat(x, 0), concat(0, y))
1190-
/// ==> or(..., concat(x, 0, y)), when x and y don't overlap.
1191-
///
1192-
/// or(..., concat(x: i2, cst1: i4), concat(cst2: i5, y: i1))
1193-
/// ==> or(..., concat(or(x: i2, extract(cst2, 4..3)),
1194-
/// or(extract(cst1, 3..1), extract(cst2, 2..0)),
1195-
/// or(extract(cst1, 0..0), y: i1))
1196-
static bool canonicalizeOrOfConcatsWithCstOperands(OrOp op, size_t concatIdx1,
1197-
size_t concatIdx2,
1198-
PatternRewriter &rewriter) {
1199-
assert(concatIdx1 < concatIdx2 && "concatIdx1 must be < concatIdx2");
1200-
1201-
auto inputs = op.getInputs();
1202-
auto concat1 = inputs[concatIdx1].getDefiningOp<ConcatOp>();
1203-
auto concat2 = inputs[concatIdx2].getDefiningOp<ConcatOp>();
1204-
1205-
assert(concat1 && concat2 && "expected indexes to point to ConcatOps");
1206-
1207-
// We can simplify as long as a constant is present in either concat.
1208-
bool hasConstantOp1 =
1209-
llvm::any_of(concat1->getOperands(), [&](Value operand) -> bool {
1210-
return operand.getDefiningOp<hw::ConstantOp>();
1211-
});
1212-
if (!hasConstantOp1) {
1213-
bool hasConstantOp2 =
1214-
llvm::any_of(concat2->getOperands(), [&](Value operand) -> bool {
1215-
return operand.getDefiningOp<hw::ConstantOp>();
1216-
});
1217-
if (!hasConstantOp2)
1218-
return false;
1219-
}
1220-
1221-
SmallVector<Value> newConcatOperands;
1222-
1223-
// Simultaneously iterate over the operands of both concat ops, from MSB to
1224-
// LSB, pushing out or's of overlapping ranges of the operands. When operands
1225-
// span different bit ranges, we extract only the maximum overlap.
1226-
auto operands1 = concat1->getOperands();
1227-
auto operands2 = concat2->getOperands();
1228-
// Number of bits already consumed from operands 1 and 2, respectively.
1229-
unsigned consumedWidth1 = 0;
1230-
unsigned consumedWidth2 = 0;
1231-
for (auto it1 = operands1.begin(), end1 = operands1.end(),
1232-
it2 = operands2.begin(), end2 = operands2.end();
1233-
it1 != end1 && it2 != end2;) {
1234-
auto operand1 = *it1;
1235-
auto operand2 = *it2;
1236-
1237-
unsigned remainingWidth1 =
1238-
hw::getBitWidth(operand1.getType()) - consumedWidth1;
1239-
unsigned remainingWidth2 =
1240-
hw::getBitWidth(operand2.getType()) - consumedWidth2;
1241-
unsigned widthToConsume = std::min(remainingWidth1, remainingWidth2);
1242-
auto narrowedType = rewriter.getIntegerType(widthToConsume);
1243-
1244-
auto extract1 = rewriter.createOrFold<ExtractOp>(
1245-
op.getLoc(), narrowedType, operand1, remainingWidth1 - widthToConsume);
1246-
auto extract2 = rewriter.createOrFold<ExtractOp>(
1247-
op.getLoc(), narrowedType, operand2, remainingWidth2 - widthToConsume);
1248-
1249-
newConcatOperands.push_back(
1250-
rewriter.createOrFold<OrOp>(op.getLoc(), extract1, extract2, false));
1251-
1252-
consumedWidth1 += widthToConsume;
1253-
consumedWidth2 += widthToConsume;
1254-
1255-
if (widthToConsume == remainingWidth1) {
1256-
++it1;
1257-
consumedWidth1 = 0;
1258-
}
1259-
if (widthToConsume == remainingWidth2) {
1260-
++it2;
1261-
consumedWidth2 = 0;
1262-
}
1263-
}
1264-
1265-
ConcatOp newOp = rewriter.create<ConcatOp>(op.getLoc(), newConcatOperands);
1266-
1267-
// Copy the old operands except for concatIdx1 and concatIdx2, and append the
1268-
// new ConcatOp to the end.
1269-
SmallVector<Value> newOrOperands;
1270-
newOrOperands.append(inputs.begin(), inputs.begin() + concatIdx1);
1271-
newOrOperands.append(inputs.begin() + concatIdx1 + 1,
1272-
inputs.begin() + concatIdx2);
1273-
newOrOperands.append(inputs.begin() + concatIdx2 + 1,
1274-
inputs.begin() + inputs.size());
1275-
newOrOperands.push_back(newOp);
1276-
1277-
replaceOpWithNewOpAndCopyName<OrOp>(rewriter, op, op.getType(),
1278-
newOrOperands);
1279-
return true;
1280-
}
1281-
12821181
LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
12831182
auto inputs = op.getInputs();
12841183
auto size = inputs.size();
@@ -1328,16 +1227,6 @@ LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
13281227
}
13291228
}
13301229

1331-
// or(..., concat(x, cst1), concat(cst2, y)
1332-
// ==> or(..., concat(x, cst3, y)), when x and y don't overlap.
1333-
for (size_t i = 0; i < size - 1; ++i) {
1334-
if (auto concat = inputs[i].getDefiningOp<ConcatOp>())
1335-
for (size_t j = i + 1; j < size; ++j)
1336-
if (auto concat = inputs[j].getDefiningOp<ConcatOp>())
1337-
if (canonicalizeOrOfConcatsWithCstOperands(op, i, j, rewriter))
1338-
return success();
1339-
}
1340-
13411230
// extracts only of or(...) -> or(extract()...)
13421231
if (narrowOperationWidth(op, true, rewriter))
13431232
return success();

test/Dialect/Comb/canonicalization.mlir

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -181,87 +181,6 @@ hw.module @dedupLong(in %arg0 : i7, in %arg1 : i7, in %arg2: i7, out resAnd: i7,
181181
hw.output %0, %1 : i7, i7
182182
}
183183

184-
// CHECK-LABEL: hw.module @orExclusiveConcats
185-
hw.module @orExclusiveConcats(in %arg0 : i6, in %arg1 : i2, out o: i9) {
186-
// CHECK-NEXT: %false = hw.constant false
187-
// CHECK-NEXT: %0 = comb.concat %arg1, %false, %arg0 : i2, i1, i6
188-
// CHECK-NEXT: hw.output %0 : i9
189-
%c0 = hw.constant 0 : i3
190-
%0 = comb.concat %c0, %arg0 : i3, i6
191-
%c1 = hw.constant 0 : i7
192-
%1 = comb.concat %arg1, %c1 : i2, i7
193-
%2 = comb.or %0, %1 : i9
194-
hw.output %2 : i9
195-
}
196-
197-
// When two concats are or'd together and have mutually-exclusive fields, they
198-
// can be merged together into a single concat.
199-
// concat0: 0aaa aaa0 0000 0bb0
200-
// concat1: 0000 0000 ccdd d000
201-
// merged: 0aaa aaa0 ccdd dbb0
202-
// CHECK-LABEL: hw.module @orExclusiveConcats2
203-
hw.module @orExclusiveConcats2(in %arg0 : i6, in %arg1 : i2, in %arg2: i2, in %arg3: i3, out o: i16) {
204-
// CHECK-NEXT: %false = hw.constant false
205-
// CHECK-NEXT: %0 = comb.concat %false, %arg0, %false, %arg2, %arg3, %arg1, %false : i1, i6, i1, i2, i3, i2, i1
206-
// CHECK-NEXT: hw.output %0 : i16
207-
%c0 = hw.constant 0 : i1
208-
%c1 = hw.constant 0 : i6
209-
%c2 = hw.constant 0 : i1
210-
%0 = comb.concat %c0, %arg0, %c1, %arg1, %c2: i1, i6, i6, i2, i1
211-
%c3 = hw.constant 0 : i8
212-
%c4 = hw.constant 0 : i3
213-
%1 = comb.concat %c3, %arg2, %arg3, %c4 : i8, i2, i3, i3
214-
%2 = comb.or %0, %1 : i16
215-
hw.output %2 : i16
216-
}
217-
218-
// When two concats are or'd together and have mutually-exclusive fields, they
219-
// can be merged together into a single concat.
220-
// concat0: aaaa 1111
221-
// concat1: 1111 10bb
222-
// merged: 1111 1111
223-
// CHECK-LABEL: hw.module @orExclusiveConcats3
224-
hw.module @orExclusiveConcats3(in %arg0 : i4, in %arg1 : i2, out o: i8) {
225-
// CHECK-NEXT: [[RES:%[a-z0-9_-]+]] = hw.constant -1 : i8
226-
// CHECK-NEXT: hw.output [[RES]] : i8
227-
%c0 = hw.constant -1 : i4
228-
%0 = comb.concat %arg0, %c0: i4, i4
229-
%c1 = hw.constant -1 : i5
230-
%c2 = hw.constant 0 : i1
231-
%1 = comb.concat %c1, %c2, %arg1 : i5, i1, i2
232-
%2 = comb.or %0, %1 : i8
233-
hw.output %2 : i8
234-
}
235-
236-
// CHECK-LABEL: hw.module @orMultipleExclusiveConcats
237-
hw.module @orMultipleExclusiveConcats(in %arg0 : i2, in %arg1 : i2, in %arg2: i2, out o: i6) {
238-
// CHECK-NEXT: %0 = comb.concat %arg0, %arg1, %arg2 : i2, i2, i2
239-
// CHECK-NEXT: hw.output %0 : i6
240-
%c2 = hw.constant 0 : i2
241-
%c4 = hw.constant 0 : i4
242-
%0 = comb.concat %arg0, %c4: i2, i4
243-
%1 = comb.concat %c2, %arg1, %c2: i2, i2, i2
244-
%2 = comb.concat %c4, %arg2: i4, i2
245-
%out = comb.or %0, %1, %2 : i6
246-
hw.output %out : i6
247-
}
248-
249-
// CHECK-LABEL: hw.module @orConcatsWithMux
250-
hw.module @orConcatsWithMux(in %bit: i1, in %cond: i1, out o: i6) {
251-
// CHECK-NEXT: [[RES:%[a-z0-9_-]+]] = hw.constant 0 : i4
252-
// CHECK-NEXT: %0 = comb.concat [[RES]], %cond, %bit : i4, i1, i1
253-
// CHECK-NEXT: hw.output %0 : i6
254-
%c0 = hw.constant 0 : i5
255-
%0 = comb.concat %c0, %bit: i5, i1
256-
%c1 = hw.constant 0 : i4
257-
%c2 = hw.constant 2 : i2
258-
%c3 = hw.constant 0 : i2
259-
%1 = comb.mux %cond, %c2, %c3 : i2
260-
%2 = comb.concat %c1, %1 : i4, i2
261-
%3 = comb.or %0, %2 : i6
262-
hw.output %3 : i6
263-
}
264-
265184
// CHECK-LABEL: @extractNested
266185
hw.module @extractNested(in %0: i5, out o1 : i1) {
267186
// Multiple layers of nested extract is a weak evidence that the cannonicalization

0 commit comments

Comments
 (0)