@@ -442,7 +442,7 @@ def StoreOp : CIR_Op<"store", [
442
442
443
443
def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", "ScopeOp", "IfOp",
444
444
"SwitchOp", "DoWhileOp",
445
- "WhileOp", "LoopOp "]>,
445
+ "WhileOp", "ForOp "]>,
446
446
Terminator]> {
447
447
let summary = "Return from function";
448
448
let description = [{
@@ -635,7 +635,7 @@ def ConditionOp : CIR_Op<"condition", [
635
635
//===----------------------------------------------------------------------===//
636
636
637
637
def YieldOp : CIR_Op<"yield", [ReturnLike, Terminator,
638
- ParentOneOf<["IfOp", "ScopeOp", "SwitchOp", "WhileOp", "LoopOp ", "AwaitOp",
638
+ ParentOneOf<["IfOp", "ScopeOp", "SwitchOp", "WhileOp", "ForOp ", "AwaitOp",
639
639
"TernaryOp", "GlobalOp", "DoWhileOp"]>]> {
640
640
let summary = "Represents the default branching behaviour of a region";
641
641
let description = [{
@@ -1159,106 +1159,6 @@ def BrCondOp : CIR_Op<"brcond",
1159
1159
}];
1160
1160
}
1161
1161
1162
- //===----------------------------------------------------------------------===//
1163
- // LoopOp
1164
- //===----------------------------------------------------------------------===//
1165
-
1166
- def LoopOpKind_For : I32EnumAttrCase<"For", 1, "for">;
1167
-
1168
- def LoopOpKind : I32EnumAttr<
1169
- "LoopOpKind",
1170
- "Loop kind",
1171
- [LoopOpKind_For]> {
1172
- let cppNamespace = "::mlir::cir";
1173
- }
1174
-
1175
- def LoopOp : CIR_Op<"loop",
1176
- [LoopOpInterface,
1177
- DeclareOpInterfaceMethods<LoopLikeOpInterface>,
1178
- DeclareOpInterfaceMethods<RegionBranchOpInterface>,
1179
- RecursivelySpeculatable, NoRegionArguments]> {
1180
- let summary = "Loop";
1181
- let description = [{
1182
- `cir.loop` represents C/C++ loop forms. It defines 3 blocks:
1183
- - `cond`: region can contain multiple blocks, terminated by regular
1184
- `cir.yield` when control should yield back to the parent, and
1185
- `cir.continue` when execution continues to the next region.
1186
- The region destination depends on the loop form specified.
1187
- - `step`: region with one block, containing code to compute the
1188
- loop step, must be terminated with `cir.yield`.
1189
- - `body`: region for the loop's body, can contain an arbitrary
1190
- number of blocks.
1191
-
1192
- The loop form: `for`, `while` and `dowhile` must also be specified and
1193
- each implies the loop regions execution order.
1194
-
1195
- ```mlir
1196
- // while (true) {
1197
- // i = i + 1;
1198
- // }
1199
- cir.loop while(cond : {
1200
- cir.continue
1201
- }, step : {
1202
- cir.yield
1203
- }) {
1204
- %3 = cir.load %1 : cir.ptr <i32>, i32
1205
- %4 = cir.const(1 : i32) : i32
1206
- %5 = cir.binop(add, %3, %4) : i32
1207
- cir.store %5, %1 : i32, cir.ptr <i32>
1208
- cir.yield
1209
- }
1210
- ```
1211
- }];
1212
-
1213
- let arguments = (ins Arg<LoopOpKind, "loop kind">:$kind);
1214
- let regions = (region AnyRegion:$cond, AnyRegion:$body,
1215
- SizedRegion<1>:$step);
1216
-
1217
- let assemblyFormat = [{
1218
- $kind
1219
- `(`
1220
- `cond` `:` $cond `,`
1221
- `step` `:` $step
1222
- `)`
1223
- $body
1224
- attr-dict
1225
- }];
1226
-
1227
- let skipDefaultBuilders = 1;
1228
- let builders = [
1229
- OpBuilder<(ins
1230
- "cir::LoopOpKind":$kind,
1231
- CArg<"function_ref<void(OpBuilder &, Location)>",
1232
- "nullptr">:$condBuilder,
1233
- CArg<"function_ref<void(OpBuilder &, Location)>",
1234
- "nullptr">:$bodyBuilder,
1235
- CArg<"function_ref<void(OpBuilder &, Location)>",
1236
- "nullptr">:$stepBuilder
1237
- )>
1238
- ];
1239
-
1240
- let hasVerifier = 1;
1241
-
1242
- let extraClassDeclaration = [{
1243
- Region *maybeGetStep() {
1244
- if (getKind() == LoopOpKind::For)
1245
- return &getStep();
1246
- return nullptr;
1247
- }
1248
-
1249
- llvm::SmallVector<Region *> getRegionsInExecutionOrder() {
1250
- switch(getKind()) {
1251
- case LoopOpKind::For:
1252
- return llvm::SmallVector<Region *, 3>{&getCond(), &getBody(), &getStep()};
1253
- // case LoopOpKind::While:
1254
- // return llvm::SmallVector<Region *, 2>{&getCond(), &getBody()};
1255
- // case LoopOpKind::DoWhile:
1256
- // return llvm::SmallVector<Region *, 2>{&getBody(), &getCond()};
1257
- }
1258
- }
1259
- }];
1260
- }
1261
-
1262
1162
//===----------------------------------------------------------------------===//
1263
1163
// While & DoWhileOp
1264
1164
//===----------------------------------------------------------------------===//
@@ -1337,6 +1237,73 @@ def DoWhileOp : WhileOpBase<"do"> {
1337
1237
}];
1338
1238
}
1339
1239
1240
+ //===----------------------------------------------------------------------===//
1241
+ // ForOp
1242
+ //===----------------------------------------------------------------------===//
1243
+
1244
+ def ForOp : CIR_Op<"for", [LoopOpInterface, NoRegionArguments]> {
1245
+ let summary = "C/C++ for loop counterpart";
1246
+ let description = [{
1247
+ Represents a C/C++ for loop. It consists of three regions:
1248
+
1249
+ - `cond`: single block region with the loop's condition. Should be
1250
+ terminated with a `cir.condition` operation.
1251
+ - `body`: contains the loop body and an arbitrary number of blocks.
1252
+ - `step`: single block region with the loop's step.
1253
+
1254
+ Example:
1255
+
1256
+ ```mlir
1257
+ cir.for cond {
1258
+ cir.condition(%val)
1259
+ } body {
1260
+ cir.break
1261
+ ^bb2:
1262
+ cir.yield
1263
+ } step {
1264
+ cir.yield
1265
+ }
1266
+ ```
1267
+ }];
1268
+
1269
+ let regions = (region SizedRegion<1>:$cond,
1270
+ MinSizedRegion<1>:$body,
1271
+ SizedRegion<1>:$step);
1272
+ let assemblyFormat = [{
1273
+ `:` `cond` $cond
1274
+ `body` $body
1275
+ `step` $step
1276
+ attr-dict
1277
+ }];
1278
+
1279
+ let builders = [
1280
+ OpBuilder<(ins "function_ref<void(OpBuilder &, Location)>":$condBuilder,
1281
+ "function_ref<void(OpBuilder &, Location)>":$bodyBuilder,
1282
+ "function_ref<void(OpBuilder &, Location)>":$stepBuilder), [{
1283
+ OpBuilder::InsertionGuard guard($_builder);
1284
+
1285
+ // Build condition region.
1286
+ $_builder.createBlock($_state.addRegion());
1287
+ condBuilder($_builder, $_state.location);
1288
+
1289
+ // Build body region.
1290
+ $_builder.createBlock($_state.addRegion());
1291
+ bodyBuilder($_builder, $_state.location);
1292
+
1293
+ // Build step region.
1294
+ $_builder.createBlock($_state.addRegion());
1295
+ stepBuilder($_builder, $_state.location);
1296
+ }]>
1297
+ ];
1298
+
1299
+ let extraClassDeclaration = [{
1300
+ Region *maybeGetStep() { return &getStep(); }
1301
+ llvm::SmallVector<Region *> getRegionsInExecutionOrder() {
1302
+ return llvm::SmallVector<Region *, 3>{&getCond(), &getBody(), &getStep()};
1303
+ }
1304
+ }];
1305
+ }
1306
+
1340
1307
//===----------------------------------------------------------------------===//
1341
1308
// GlobalOp
1342
1309
//===----------------------------------------------------------------------===//
@@ -2684,7 +2651,7 @@ def AllocException : CIR_Op<"alloc_exception", [
2684
2651
2685
2652
def ThrowOp : CIR_Op<"throw", [
2686
2653
ParentOneOf<["FuncOp", "ScopeOp", "IfOp", "SwitchOp",
2687
- "DoWhileOp", "WhileOp", "LoopOp "]>,
2654
+ "DoWhileOp", "WhileOp", "ForOp "]>,
2688
2655
Terminator]> {
2689
2656
let summary = "(Re)Throws an exception";
2690
2657
let description = [{
0 commit comments