@@ -1178,107 +1178,6 @@ OpFoldResult OrOp::fold(FoldAdaptor adaptor) {
1178
1178
return constFoldAssociativeOp (inputs, hw::PEO::Or);
1179
1179
}
1180
1180
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
-
1282
1181
LogicalResult OrOp::canonicalize (OrOp op, PatternRewriter &rewriter) {
1283
1182
auto inputs = op.getInputs ();
1284
1183
auto size = inputs.size ();
@@ -1328,16 +1227,6 @@ LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
1328
1227
}
1329
1228
}
1330
1229
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
-
1341
1230
// extracts only of or(...) -> or(extract()...)
1342
1231
if (narrowOperationWidth (op, true , rewriter))
1343
1232
return success ();
0 commit comments