@@ -88,17 +88,17 @@ def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression]> {
88
88
89
89
```mlir
90
90
// Custom form of applying the & operator.
91
- %0 = emitc.apply "&"(%arg0) : (i32) -> !emitc.ptr<i32>
91
+ %0 = emitc.apply "&"(%arg0) : (!emitc.lvalue< i32> ) -> !emitc.ptr<i32>
92
92
93
93
// Generic form of the same operation.
94
94
%0 = "emitc.apply"(%arg0) {applicableOperator = "&"}
95
- : (i32) -> !emitc.ptr<i32>
95
+ : (!emitc.lvalue< i32> ) -> !emitc.ptr<i32>
96
96
97
97
```
98
98
}];
99
99
let arguments = (ins
100
100
Arg<StrAttr, "the operator to apply">:$applicableOperator,
101
- EmitCType:$operand
101
+ AnyTypeOf<[ EmitCType, EmitC_LValueType]> :$operand
102
102
);
103
103
let results = (outs EmitCType:$result);
104
104
let assemblyFormat = [{
@@ -836,6 +836,35 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
836
836
let assemblyFormat = "operands attr-dict `:` type(operands)";
837
837
}
838
838
839
+ def EmitC_LoadOp : EmitC_Op<"load", [
840
+ TypesMatchWith<"result type matches value type of 'operand'",
841
+ "operand", "result",
842
+ "::llvm::cast<LValueType>($_self).getValueType()">
843
+ ]> {
844
+ let summary = "Load an lvalue into an SSA value.";
845
+ let description = [{
846
+ This operation loads the content of a modifiable lvalue into an SSA value.
847
+ Modifications of the lvalue executed after the load are not observable on
848
+ the produced value.
849
+
850
+ Example:
851
+
852
+ ```mlir
853
+ %1 = emitc.load %0 : !emitc.lvalue<i32>
854
+ ```
855
+ ```c++
856
+ // Code emitted for the operation above.
857
+ int32_t v2 = v1;
858
+ ```
859
+ }];
860
+
861
+ let arguments = (ins
862
+ Res<EmitC_LValueType, "", [MemRead<DefaultResource, 0, FullEffect>]>:$operand);
863
+ let results = (outs AnyType:$result);
864
+
865
+ let assemblyFormat = "$operand attr-dict `:` type($operand)";
866
+ }
867
+
839
868
def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
840
869
let summary = "Multiplication operation";
841
870
let description = [{
@@ -918,15 +947,15 @@ def EmitC_MemberOp : EmitC_Op<"member"> {
918
947
919
948
```mlir
920
949
%0 = "emitc.member" (%arg0) {member = "a"}
921
- : (!emitc.opaque<"mystruct">) -> i32
950
+ : (!emitc.lvalue<!emitc. opaque<"mystruct">> ) -> !emitc.lvalue< i32>
922
951
```
923
952
}];
924
953
925
954
let arguments = (ins
926
955
Arg<StrAttr, "the member to access">:$member,
927
- EmitC_OpaqueType:$operand
956
+ EmitC_LValueOf<[ EmitC_OpaqueType]> :$operand
928
957
);
929
- let results = (outs EmitCType);
958
+ let results = (outs EmitC_LValueOf<[ EmitCType]> );
930
959
}
931
960
932
961
def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
@@ -939,15 +968,16 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
939
968
940
969
```mlir
941
970
%0 = "emitc.member_of_ptr" (%arg0) {member = "a"}
942
- : (!emitc.ptr<!emitc.opaque<"mystruct">>) -> i32
971
+ : (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>)
972
+ -> !emitc.lvalue<i32>
943
973
```
944
974
}];
945
975
946
976
let arguments = (ins
947
977
Arg<StrAttr, "the member to access">:$member,
948
- AnyTypeOf <[EmitC_OpaqueType,EmitC_PointerType]>:$operand
978
+ EmitC_LValueOf <[EmitC_OpaqueType,EmitC_PointerType]>:$operand
949
979
);
950
- let results = (outs EmitCType);
980
+ let results = (outs EmitC_LValueOf<[ EmitCType]> );
951
981
}
952
982
953
983
def EmitC_ConditionalOp : EmitC_Op<"conditional",
@@ -1031,28 +1061,29 @@ def EmitC_VariableOp : EmitC_Op<"variable", []> {
1031
1061
1032
1062
```mlir
1033
1063
// Integer variable
1034
- %0 = "emitc.variable"(){value = 42 : i32} : () -> i32
1064
+ %0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue< i32>
1035
1065
1036
1066
// Variable emitted as `int32_t* = NULL;`
1037
1067
%1 = "emitc.variable"() {value = #emitc.opaque<"NULL">}
1038
- : () -> !emitc.ptr<!emitc.opaque<"int32_t">>
1068
+ : () -> !emitc.lvalue<!emitc. ptr<!emitc.opaque<"int32_t"> >>
1039
1069
```
1040
1070
1041
1071
Since folding is not supported, it can be used with pointers.
1042
1072
As an example, it is valid to create pointers to `variable` operations
1043
1073
by using `apply` operations and pass these to a `call` operation.
1044
1074
```mlir
1045
- %0 = "emitc.variable"() {value = 0 : i32} : () -> i32
1046
- %1 = "emitc.variable"() {value = 0 : i32} : () -> i32
1047
- %2 = emitc.apply "&"(%0) : (i32) -> !emitc.ptr<i32>
1048
- %3 = emitc.apply "&"(%1) : (i32) -> !emitc.ptr<i32>
1075
+ %0 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue< i32>
1076
+ %1 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue< i32>
1077
+ %2 = emitc.apply "&"(%0) : (!emitc.lvalue< i32> ) -> !emitc.ptr<i32>
1078
+ %3 = emitc.apply "&"(%1) : (!emitc.lvalue< i32> ) -> !emitc.ptr<i32>
1049
1079
emitc.call_opaque "write"(%2, %3)
1050
1080
: (!emitc.ptr<i32>, !emitc.ptr<i32>) -> ()
1051
1081
```
1052
1082
}];
1053
1083
1054
1084
let arguments = (ins EmitC_OpaqueOrTypedAttr:$value);
1055
- let results = (outs EmitCType);
1085
+ let results = (outs Res<AnyTypeOf<[EmitC_ArrayType, EmitC_LValueType]>, "",
1086
+ [MemAlloc<DefaultResource, 0, FullEffect>]>);
1056
1087
1057
1088
let hasVerifier = 1;
1058
1089
}
@@ -1118,11 +1149,12 @@ def EmitC_GetGlobalOp : EmitC_Op<"get_global",
1118
1149
1119
1150
```mlir
1120
1151
%x = emitc.get_global @foo : !emitc.array<2xf32>
1152
+ %y = emitc.get_global @bar : !emitc.lvalue<i32>
1121
1153
```
1122
1154
}];
1123
1155
1124
1156
let arguments = (ins FlatSymbolRefAttr:$name);
1125
- let results = (outs EmitCType :$result);
1157
+ let results = (outs AnyTypeOf<[EmitC_ArrayType, EmitC_LValueType]> :$result);
1126
1158
let assemblyFormat = "$name `:` type($result) attr-dict";
1127
1159
}
1128
1160
@@ -1172,15 +1204,17 @@ def EmitC_AssignOp : EmitC_Op<"assign", []> {
1172
1204
1173
1205
```mlir
1174
1206
// Integer variable
1175
- %0 = "emitc.variable"(){value = 42 : i32} : () -> i32
1207
+ %0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue< i32>
1176
1208
%1 = emitc.call_opaque "foo"() : () -> (i32)
1177
1209
1178
1210
// Assign emitted as `... = ...;`
1179
- "emitc.assign"(%0, %1) : (i32, i32) -> ()
1211
+ "emitc.assign"(%0, %1) : (!emitc.lvalue< i32> , i32) -> ()
1180
1212
```
1181
1213
}];
1182
1214
1183
- let arguments = (ins EmitCType:$var, EmitCType:$value);
1215
+ let arguments = (ins
1216
+ Res<EmitC_LValueType, "", [MemWrite<DefaultResource, 1, FullEffect>]>:$var,
1217
+ EmitCType:$value);
1184
1218
let results = (outs);
1185
1219
1186
1220
let hasVerifier = 1;
@@ -1276,8 +1310,10 @@ def EmitC_SubscriptOp : EmitC_Op<"subscript", []> {
1276
1310
```mlir
1277
1311
%i = index.constant 1
1278
1312
%j = index.constant 7
1279
- %0 = emitc.subscript %arg0[%i, %j] : !emitc.array<4x8xf32>, index, index
1280
- %1 = emitc.subscript %arg1[%i] : !emitc.ptr<i32>, index
1313
+ %0 = emitc.subscript %arg0[%i, %j] : (!emitc.array<4x8xf32>, index, index)
1314
+ -> !emitc.lvalue<f32>
1315
+ %1 = emitc.subscript %arg1[%i] : (!emitc.ptr<i32>, index)
1316
+ -> !emitc.lvalue<i32>
1281
1317
```
1282
1318
}];
1283
1319
let arguments = (ins Arg<AnyTypeOf<[
@@ -1286,15 +1322,26 @@ def EmitC_SubscriptOp : EmitC_Op<"subscript", []> {
1286
1322
EmitC_PointerType]>,
1287
1323
"the value to subscript">:$value,
1288
1324
Variadic<EmitCType>:$indices);
1289
- let results = (outs EmitCType :$result);
1325
+ let results = (outs EmitC_LValueType :$result);
1290
1326
1291
1327
let builders = [
1292
1328
OpBuilder<(ins "TypedValue<ArrayType>":$array, "ValueRange":$indices), [{
1293
- build($_builder, $_state, array.getType().getElementType(), array, indices);
1329
+ build(
1330
+ $_builder,
1331
+ $_state,
1332
+ emitc::LValueType::get(array.getType().getElementType()),
1333
+ array,
1334
+ indices
1335
+ );
1294
1336
}]>,
1295
1337
OpBuilder<(ins "TypedValue<PointerType>":$pointer, "Value":$index), [{
1296
- build($_builder, $_state, pointer.getType().getPointee(), pointer,
1297
- ValueRange{index});
1338
+ build(
1339
+ $_builder,
1340
+ $_state,
1341
+ emitc::LValueType::get(pointer.getType().getPointee()),
1342
+ pointer,
1343
+ ValueRange{index}
1344
+ );
1298
1345
}]>
1299
1346
];
1300
1347
@@ -1338,7 +1385,7 @@ def EmitC_SwitchOp : EmitC_Op<"switch", [RecursiveMemoryEffects,
1338
1385
emitc.yield
1339
1386
}
1340
1387
default {
1341
- %3 = "emitc.variable "(){value = 42.0 : f32} : () -> f32
1388
+ %3 = "emitc.constant "(){value = 42.0 : f32} : () -> f32
1342
1389
emitc.call_opaque "func2" (%3) : (f32) -> ()
1343
1390
}
1344
1391
```
0 commit comments