@@ -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 = [{
@@ -1134,106 +1134,6 @@ def BrCondOp : CIR_Op<"brcond",
1134
1134
}];
1135
1135
}
1136
1136
1137
- //===----------------------------------------------------------------------===//
1138
- // LoopOp
1139
- //===----------------------------------------------------------------------===//
1140
-
1141
- def LoopOpKind_For : I32EnumAttrCase<"For", 1, "for">;
1142
-
1143
- def LoopOpKind : I32EnumAttr<
1144
- "LoopOpKind",
1145
- "Loop kind",
1146
- [LoopOpKind_For]> {
1147
- let cppNamespace = "::mlir::cir";
1148
- }
1149
-
1150
- def LoopOp : CIR_Op<"loop",
1151
- [LoopOpInterface,
1152
- DeclareOpInterfaceMethods<LoopLikeOpInterface>,
1153
- DeclareOpInterfaceMethods<RegionBranchOpInterface>,
1154
- RecursivelySpeculatable, NoRegionArguments]> {
1155
- let summary = "Loop";
1156
- let description = [{
1157
- `cir.loop` represents C/C++ loop forms. It defines 3 blocks:
1158
- - `cond`: region can contain multiple blocks, terminated by regular
1159
- `cir.yield` when control should yield back to the parent, and
1160
- `cir.continue` when execution continues to the next region.
1161
- The region destination depends on the loop form specified.
1162
- - `step`: region with one block, containing code to compute the
1163
- loop step, must be terminated with `cir.yield`.
1164
- - `body`: region for the loop's body, can contain an arbitrary
1165
- number of blocks.
1166
-
1167
- The loop form: `for`, `while` and `dowhile` must also be specified and
1168
- each implies the loop regions execution order.
1169
-
1170
- ```mlir
1171
- // while (true) {
1172
- // i = i + 1;
1173
- // }
1174
- cir.loop while(cond : {
1175
- cir.continue
1176
- }, step : {
1177
- cir.yield
1178
- }) {
1179
- %3 = cir.load %1 : cir.ptr <i32>, i32
1180
- %4 = cir.const(1 : i32) : i32
1181
- %5 = cir.binop(add, %3, %4) : i32
1182
- cir.store %5, %1 : i32, cir.ptr <i32>
1183
- cir.yield
1184
- }
1185
- ```
1186
- }];
1187
-
1188
- let arguments = (ins Arg<LoopOpKind, "loop kind">:$kind);
1189
- let regions = (region AnyRegion:$cond, AnyRegion:$body,
1190
- SizedRegion<1>:$step);
1191
-
1192
- let assemblyFormat = [{
1193
- $kind
1194
- `(`
1195
- `cond` `:` $cond `,`
1196
- `step` `:` $step
1197
- `)`
1198
- $body
1199
- attr-dict
1200
- }];
1201
-
1202
- let skipDefaultBuilders = 1;
1203
- let builders = [
1204
- OpBuilder<(ins
1205
- "cir::LoopOpKind":$kind,
1206
- CArg<"function_ref<void(OpBuilder &, Location)>",
1207
- "nullptr">:$condBuilder,
1208
- CArg<"function_ref<void(OpBuilder &, Location)>",
1209
- "nullptr">:$bodyBuilder,
1210
- CArg<"function_ref<void(OpBuilder &, Location)>",
1211
- "nullptr">:$stepBuilder
1212
- )>
1213
- ];
1214
-
1215
- let hasVerifier = 1;
1216
-
1217
- let extraClassDeclaration = [{
1218
- Region *maybeGetStep() {
1219
- if (getKind() == LoopOpKind::For)
1220
- return &getStep();
1221
- return nullptr;
1222
- }
1223
-
1224
- llvm::SmallVector<Region *> getRegionsInExecutionOrder() {
1225
- switch(getKind()) {
1226
- case LoopOpKind::For:
1227
- return llvm::SmallVector<Region *, 3>{&getCond(), &getBody(), &getStep()};
1228
- case LoopOpKind::While:
1229
- return llvm::SmallVector<Region *, 2>{&getCond(), &getBody()};
1230
- case LoopOpKind::DoWhile:
1231
- return llvm::SmallVector<Region *, 2>{&getBody(), &getCond()};
1232
- }
1233
- }
1234
- }];
1235
- }
1236
-
1237
1137
//===----------------------------------------------------------------------===//
1238
1138
// While & DoWhileOp
1239
1139
//===----------------------------------------------------------------------===//
@@ -1312,6 +1212,73 @@ def DoWhileOp : WhileOpBase<"do"> {
1312
1212
}];
1313
1213
}
1314
1214
1215
+ //===----------------------------------------------------------------------===//
1216
+ // ForOp
1217
+ //===----------------------------------------------------------------------===//
1218
+
1219
+ def ForOp : CIR_Op<"for", [LoopOpInterface, NoRegionArguments]> {
1220
+ let summary = "C/C++ for loop counterpart";
1221
+ let description = [{
1222
+ Represents a C/C++ for loop. It consists of three regions:
1223
+
1224
+ - `cond`: single block region with the loop's condition. Should be
1225
+ terminated with a `cir.condition` operation.
1226
+ - `body`: contains the loop body and an arbitrary number of blocks.
1227
+ - `step`: single block region with the loop's step.
1228
+
1229
+ Example:
1230
+
1231
+ ```mlir
1232
+ cir.for cond {
1233
+ cir.condition(%val)
1234
+ } body {
1235
+ cir.break
1236
+ ^bb2:
1237
+ cir.yield
1238
+ } step {
1239
+ cir.yield
1240
+ }
1241
+ ```
1242
+ }];
1243
+
1244
+ let regions = (region SizedRegion<1>:$cond,
1245
+ MinSizedRegion<1>:$body,
1246
+ SizedRegion<1>:$step);
1247
+ let assemblyFormat = [{
1248
+ `:` `cond` $cond
1249
+ `body` $body
1250
+ `step` $step
1251
+ attr-dict
1252
+ }];
1253
+
1254
+ let builders = [
1255
+ OpBuilder<(ins "function_ref<void(OpBuilder &, Location)>":$condBuilder,
1256
+ "function_ref<void(OpBuilder &, Location)>":$bodyBuilder,
1257
+ "function_ref<void(OpBuilder &, Location)>":$stepBuilder), [{
1258
+ OpBuilder::InsertionGuard guard($_builder);
1259
+
1260
+ // Build condition region.
1261
+ $_builder.createBlock($_state.addRegion());
1262
+ condBuilder($_builder, $_state.location);
1263
+
1264
+ // Build body region.
1265
+ $_builder.createBlock($_state.addRegion());
1266
+ bodyBuilder($_builder, $_state.location);
1267
+
1268
+ // Build step region.
1269
+ $_builder.createBlock($_state.addRegion());
1270
+ stepBuilder($_builder, $_state.location);
1271
+ }]>
1272
+ ];
1273
+
1274
+ let extraClassDeclaration = [{
1275
+ Region *maybeGetStep() { return &getStep(); }
1276
+ llvm::SmallVector<Region *> getRegionsInExecutionOrder() {
1277
+ return llvm::SmallVector<Region *, 3>{&getCond(), &getBody(), &getStep()};
1278
+ }
1279
+ }];
1280
+ }
1281
+
1315
1282
//===----------------------------------------------------------------------===//
1316
1283
// GlobalOp
1317
1284
//===----------------------------------------------------------------------===//
@@ -2659,7 +2626,7 @@ def AllocException : CIR_Op<"alloc_exception", [
2659
2626
2660
2627
def ThrowOp : CIR_Op<"throw", [
2661
2628
ParentOneOf<["FuncOp", "ScopeOp", "IfOp", "SwitchOp",
2662
- "DoWhileOp", "WhileOp", "LoopOp "]>,
2629
+ "DoWhileOp", "WhileOp", "ForOp "]>,
2663
2630
Terminator]> {
2664
2631
let summary = "(Re)Throws an exception";
2665
2632
let description = [{
0 commit comments