Skip to content

Commit 62459f4

Browse files
authored
Merge pull request #360 from Xilinx/bump_to_e47b5075
[AutoBump] Merge with fixes of e47b507 (Aug 20) (7)
2 parents 573742a + 531bda7 commit 62459f4

File tree

30 files changed

+847
-412
lines changed

30 files changed

+847
-412
lines changed

mlir/include/mlir/Dialect/EmitC/IR/EmitC.td

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,17 @@ def EmitC_ApplyOp : EmitC_Op<"apply", [CExpression]> {
139139

140140
```mlir
141141
// Custom form of applying the & operator.
142-
%0 = emitc.apply "&"(%arg0) : (i32) -> !emitc.ptr<i32>
142+
%0 = emitc.apply "&"(%arg0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
143143

144144
// Generic form of the same operation.
145145
%0 = "emitc.apply"(%arg0) {applicableOperator = "&"}
146-
: (i32) -> !emitc.ptr<i32>
146+
: (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
147147

148148
```
149149
}];
150150
let arguments = (ins
151151
Arg<StrAttr, "the operator to apply">:$applicableOperator,
152-
EmitCType:$operand
152+
AnyTypeOf<[EmitCType, EmitC_LValueType]>:$operand
153153
);
154154
let results = (outs EmitCType:$result);
155155
let assemblyFormat = [{
@@ -895,6 +895,35 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
895895
let assemblyFormat = "operands attr-dict `:` type(operands)";
896896
}
897897

898+
def EmitC_LoadOp : EmitC_Op<"load", [
899+
TypesMatchWith<"result type matches value type of 'operand'",
900+
"operand", "result",
901+
"::llvm::cast<LValueType>($_self).getValueType()">
902+
]> {
903+
let summary = "Load an lvalue into an SSA value.";
904+
let description = [{
905+
This operation loads the content of a modifiable lvalue into an SSA value.
906+
Modifications of the lvalue executed after the load are not observable on
907+
the produced value.
908+
909+
Example:
910+
911+
```mlir
912+
%1 = emitc.load %0 : !emitc.lvalue<i32>
913+
```
914+
```c++
915+
// Code emitted for the operation above.
916+
int32_t v2 = v1;
917+
```
918+
}];
919+
920+
let arguments = (ins
921+
Res<EmitC_LValueType, "", [MemRead<DefaultResource, 0, FullEffect>]>:$operand);
922+
let results = (outs AnyType:$result);
923+
924+
let assemblyFormat = "$operand attr-dict `:` type($operand)";
925+
}
926+
898927
def EmitC_MulOp : EmitC_BinaryOp<"mul", [CExpression]> {
899928
let summary = "Multiplication operation";
900929
let description = [{
@@ -977,15 +1006,15 @@ def EmitC_MemberOp : EmitC_Op<"member"> {
9771006

9781007
```mlir
9791008
%0 = "emitc.member" (%arg0) {member = "a"}
980-
: (!emitc.opaque<"mystruct">) -> i32
1009+
: (!emitc.lvalue<!emitc.opaque<"mystruct">>) -> !emitc.lvalue<i32>
9811010
```
9821011
}];
9831012

9841013
let arguments = (ins
9851014
Arg<StrAttr, "the member to access">:$member,
986-
EmitC_OpaqueType:$operand
1015+
EmitC_LValueOf<[EmitC_OpaqueType]>:$operand
9871016
);
988-
let results = (outs EmitCType);
1017+
let results = (outs EmitC_LValueOf<[EmitCType]>);
9891018
}
9901019

9911020
def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
@@ -998,15 +1027,16 @@ def EmitC_MemberOfPtrOp : EmitC_Op<"member_of_ptr"> {
9981027

9991028
```mlir
10001029
%0 = "emitc.member_of_ptr" (%arg0) {member = "a"}
1001-
: (!emitc.ptr<!emitc.opaque<"mystruct">>) -> i32
1030+
: (!emitc.lvalue<!emitc.ptr<!emitc.opaque<"mystruct">>>)
1031+
-> !emitc.lvalue<i32>
10021032
```
10031033
}];
10041034

10051035
let arguments = (ins
10061036
Arg<StrAttr, "the member to access">:$member,
1007-
AnyTypeOf<[EmitC_OpaqueType,EmitC_PointerType]>:$operand
1037+
EmitC_LValueOf<[EmitC_OpaqueType,EmitC_PointerType]>:$operand
10081038
);
1009-
let results = (outs EmitCType);
1039+
let results = (outs EmitC_LValueOf<[EmitCType]>);
10101040
}
10111041

10121042
def EmitC_ConditionalOp : EmitC_Op<"conditional",
@@ -1090,28 +1120,29 @@ def EmitC_VariableOp : EmitC_Op<"variable", []> {
10901120

10911121
```mlir
10921122
// Integer variable
1093-
%0 = "emitc.variable"(){value = 42 : i32} : () -> i32
1123+
%0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue<i32>
10941124

10951125
// Variable emitted as `int32_t* = NULL;`
10961126
%1 = "emitc.variable"() {value = #emitc.opaque<"NULL">}
1097-
: () -> !emitc.ptr<!emitc.opaque<"int32_t">>
1127+
: () -> !emitc.lvalue<!emitc.ptr<!emitc.opaque<"int32_t">>>
10981128
```
10991129

11001130
Since folding is not supported, it can be used with pointers.
11011131
As an example, it is valid to create pointers to `variable` operations
11021132
by using `apply` operations and pass these to a `call` operation.
11031133
```mlir
1104-
%0 = "emitc.variable"() {value = 0 : i32} : () -> i32
1105-
%1 = "emitc.variable"() {value = 0 : i32} : () -> i32
1106-
%2 = emitc.apply "&"(%0) : (i32) -> !emitc.ptr<i32>
1107-
%3 = emitc.apply "&"(%1) : (i32) -> !emitc.ptr<i32>
1134+
%0 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue<i32>
1135+
%1 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue<i32>
1136+
%2 = emitc.apply "&"(%0) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
1137+
%3 = emitc.apply "&"(%1) : (!emitc.lvalue<i32>) -> !emitc.ptr<i32>
11081138
emitc.call_opaque "write"(%2, %3)
11091139
: (!emitc.ptr<i32>, !emitc.ptr<i32>) -> ()
11101140
```
11111141
}];
11121142

11131143
let arguments = (ins EmitC_OpaqueOrTypedAttr:$value);
1114-
let results = (outs EmitCType);
1144+
let results = (outs Res<AnyTypeOf<[EmitC_ArrayType, EmitC_LValueType]>, "",
1145+
[MemAlloc<DefaultResource, 0, FullEffect>]>);
11151146

11161147
let hasVerifier = 1;
11171148
}
@@ -1179,11 +1210,12 @@ def EmitC_GetGlobalOp : EmitC_Op<"get_global",
11791210

11801211
```mlir
11811212
%x = emitc.get_global @foo : !emitc.array<2xf32>
1213+
%y = emitc.get_global @bar : !emitc.lvalue<i32>
11821214
```
11831215
}];
11841216

11851217
let arguments = (ins FlatSymbolRefAttr:$name);
1186-
let results = (outs EmitCType:$result);
1218+
let results = (outs AnyTypeOf<[EmitC_ArrayType, EmitC_LValueType]>:$result);
11871219
let assemblyFormat = "$name `:` type($result) attr-dict";
11881220
}
11891221

@@ -1250,15 +1282,17 @@ def EmitC_AssignOp : EmitC_Op<"assign", []> {
12501282

12511283
```mlir
12521284
// Integer variable
1253-
%0 = "emitc.variable"(){value = 42 : i32} : () -> i32
1285+
%0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue<i32>
12541286
%1 = emitc.call_opaque "foo"() : () -> (i32)
12551287

12561288
// Assign emitted as `... = ...;`
1257-
"emitc.assign"(%0, %1) : (i32, i32) -> ()
1289+
"emitc.assign"(%0, %1) : (!emitc.lvalue<i32>, i32) -> ()
12581290
```
12591291
}];
12601292

1261-
let arguments = (ins EmitCType:$var, EmitCType:$value);
1293+
let arguments = (ins
1294+
Res<EmitC_LValueType, "", [MemWrite<DefaultResource, 1, FullEffect>]>:$var,
1295+
EmitCType:$value);
12621296
let results = (outs);
12631297

12641298
let hasVerifier = 1;
@@ -1354,8 +1388,10 @@ def EmitC_SubscriptOp : EmitC_Op<"subscript", []> {
13541388
```mlir
13551389
%i = index.constant 1
13561390
%j = index.constant 7
1357-
%0 = emitc.subscript %arg0[%i, %j] : !emitc.array<4x8xf32>, index, index
1358-
%1 = emitc.subscript %arg1[%i] : !emitc.ptr<i32>, index
1391+
%0 = emitc.subscript %arg0[%i, %j] : (!emitc.array<4x8xf32>, index, index)
1392+
-> !emitc.lvalue<f32>
1393+
%1 = emitc.subscript %arg1[%i] : (!emitc.ptr<i32>, index)
1394+
-> !emitc.lvalue<i32>
13591395
```
13601396
}];
13611397
let arguments = (ins Arg<AnyTypeOf<[
@@ -1364,15 +1400,26 @@ def EmitC_SubscriptOp : EmitC_Op<"subscript", []> {
13641400
EmitC_PointerType]>,
13651401
"the value to subscript">:$value,
13661402
Variadic<EmitCType>:$indices);
1367-
let results = (outs EmitCType:$result);
1403+
let results = (outs EmitC_LValueType:$result);
13681404

13691405
let builders = [
13701406
OpBuilder<(ins "TypedValue<ArrayType>":$array, "ValueRange":$indices), [{
1371-
build($_builder, $_state, array.getType().getElementType(), array, indices);
1407+
build(
1408+
$_builder,
1409+
$_state,
1410+
emitc::LValueType::get(array.getType().getElementType()),
1411+
array,
1412+
indices
1413+
);
13721414
}]>,
13731415
OpBuilder<(ins "TypedValue<PointerType>":$pointer, "Value":$index), [{
1374-
build($_builder, $_state, pointer.getType().getPointee(), pointer,
1375-
ValueRange{index});
1416+
build(
1417+
$_builder,
1418+
$_state,
1419+
emitc::LValueType::get(pointer.getType().getPointee()),
1420+
pointer,
1421+
ValueRange{index}
1422+
);
13761423
}]>
13771424
];
13781425

@@ -1416,7 +1463,7 @@ def EmitC_SwitchOp : EmitC_Op<"switch", [RecursiveMemoryEffects,
14161463
emitc.yield
14171464
}
14181465
default {
1419-
%3 = "emitc.variable"(){value = 42.0 : f32} : () -> f32
1466+
%3 = "emitc.constant"(){value = 42.0 : f32} : () -> f32
14201467
emitc.call_opaque "func2" (%3) : (f32) -> ()
14211468
}
14221469
```

mlir/include/mlir/Dialect/EmitC/IR/EmitCTypes.td

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,23 @@ def EmitC_ArrayType : EmitC_Type<"Array", "array", [ShapedTypeInterface]> {
8484
let hasCustomAssemblyFormat = 1;
8585
}
8686

87+
def EmitC_LValueType : EmitC_Type<"LValue", "lvalue"> {
88+
let summary = "EmitC lvalue type";
89+
90+
let description = [{
91+
Values of this type can be assigned to and their address can be taken.
92+
}];
93+
94+
let parameters = (ins "Type":$valueType);
95+
let builders = [
96+
TypeBuilderWithInferredContext<(ins "Type":$valueType), [{
97+
return $_get(valueType.getContext(), valueType);
98+
}]>
99+
];
100+
let assemblyFormat = "`<` qualified($valueType) `>`";
101+
let genVerifyDecl = 1;
102+
}
103+
87104
def EmitC_OpaqueType : EmitC_Type<"Opaque", "opaque"> {
88105
let summary = "EmitC opaque type";
89106

@@ -136,6 +153,7 @@ def EmitC_PointerType : EmitC_Type<"Pointer", "ptr"> {
136153
}]>
137154
];
138155
let assemblyFormat = "`<` qualified($pointee) `>`";
156+
let genVerifyDecl = 1;
139157
}
140158

141159
def EmitC_SignedSizeT : EmitC_Type<"SignedSizeT", "ssize_t"> {
@@ -165,4 +183,13 @@ def EmitC_SizeT : EmitC_Type<"SizeT", "size_t"> {
165183
}];
166184
}
167185

186+
class EmitC_LValueOf<list<Type> allowedTypes> :
187+
ContainerType<
188+
AnyTypeOf<allowedTypes>,
189+
CPred<"::llvm::isa<::mlir::emitc::LValueType>($_self)">,
190+
"::llvm::cast<::mlir::emitc::LValueType>($_self).getValueType()",
191+
"emitc.lvalue",
192+
"::mlir::emitc::LValueType"
193+
>;
194+
168195
#endif // MLIR_DIALECT_EMITC_IR_EMITCTYPES

mlir/lib/Conversion/MemRefToEmitC/MemRefToEmitC.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,7 @@ struct ConvertLoad final : public OpConversionPattern<memref::LoadOp> {
139139
auto subscript = rewriter.create<emitc::SubscriptOp>(
140140
op.getLoc(), arrayValue, operands.getIndices());
141141

142-
auto noInit = emitc::OpaqueAttr::get(getContext(), "");
143-
auto var =
144-
rewriter.create<emitc::VariableOp>(op.getLoc(), resultTy, noInit);
145-
146-
rewriter.create<emitc::AssignOp>(op.getLoc(), var, subscript);
147-
rewriter.replaceOp(op, var);
142+
rewriter.replaceOpWithNewOp<emitc::LoadOp>(op, resultTy, subscript);
148143
return success();
149144
}
150145
};

mlir/lib/Conversion/SCFToEmitC/SCFToEmitC.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ createVariablesForResults(T op, const TypeConverter *typeConverter,
6868
Type resultType = typeConverter->convertType(result.getType());
6969
if (!resultType)
7070
return rewriter.notifyMatchFailure(op, "result type conversion failed");
71+
Type varType = emitc::LValueType::get(resultType);
7172
emitc::OpaqueAttr noInit = emitc::OpaqueAttr::get(context, "");
7273
emitc::VariableOp var =
73-
rewriter.create<emitc::VariableOp>(loc, resultType, noInit);
74+
rewriter.create<emitc::VariableOp>(loc, varType, noInit);
7475
resultVariables.push_back(var);
7576
}
7677

@@ -85,6 +86,14 @@ static void assignValues(ValueRange values, ValueRange variables,
8586
rewriter.create<emitc::AssignOp>(loc, var, value);
8687
}
8788

89+
SmallVector<Value> loadValues(const SmallVector<Value> &variables,
90+
PatternRewriter &rewriter, Location loc) {
91+
return llvm::map_to_vector<>(variables, [&](Value var) {
92+
Type type = cast<emitc::LValueType>(var.getType()).getValueType();
93+
return rewriter.create<emitc::LoadOp>(loc, type, var).getResult();
94+
});
95+
}
96+
8897
static LogicalResult lowerYield(Operation *op, ValueRange resultVariables,
8998
ConversionPatternRewriter &rewriter,
9099
scf::YieldOp yield) {
@@ -143,6 +152,14 @@ ForLowering::matchAndRewrite(ForOp forOp, OpAdaptor adaptor,
143152
// Erase the auto-generated terminator for the lowered for op.
144153
rewriter.eraseOp(loweredBody->getTerminator());
145154

155+
IRRewriter::InsertPoint ip = rewriter.saveInsertionPoint();
156+
rewriter.setInsertionPointToEnd(loweredBody);
157+
158+
SmallVector<Value> iterArgsValues =
159+
loadValues(resultVariables, rewriter, loc);
160+
161+
rewriter.restoreInsertionPoint(ip);
162+
146163
// Convert the original region types into the new types by adding unrealized
147164
// casts in the beginning of the loop. This performs the conversion in place.
148165
if (failed(rewriter.convertRegionTypes(&forOp.getRegion(),
@@ -155,7 +172,7 @@ ForLowering::matchAndRewrite(ForOp forOp, OpAdaptor adaptor,
155172
Block *scfBody = &(forOp.getRegion().front());
156173
SmallVector<Value> replacingValues;
157174
replacingValues.push_back(loweredFor.getInductionVar());
158-
replacingValues.append(resultVariables.begin(), resultVariables.end());
175+
replacingValues.append(iterArgsValues.begin(), iterArgsValues.end());
159176
rewriter.mergeBlocks(scfBody, loweredBody, replacingValues);
160177

161178
auto result = lowerYield(forOp, resultVariables, rewriter,
@@ -165,7 +182,10 @@ ForLowering::matchAndRewrite(ForOp forOp, OpAdaptor adaptor,
165182
return result;
166183
}
167184

168-
rewriter.replaceOp(forOp, resultVariables);
185+
// Load variables into SSA values after the for loop.
186+
SmallVector<Value> resultValues = loadValues(resultVariables, rewriter, loc);
187+
188+
rewriter.replaceOp(forOp, resultValues);
169189
return success();
170190
}
171191

@@ -233,7 +253,10 @@ IfLowering::matchAndRewrite(IfOp ifOp, OpAdaptor adaptor,
233253
}
234254
}
235255

236-
rewriter.replaceOp(ifOp, resultVariables);
256+
rewriter.setInsertionPointAfter(ifOp);
257+
SmallVector<Value> results = loadValues(resultVariables, rewriter, loc);
258+
259+
rewriter.replaceOp(ifOp, results);
237260
return success();
238261
}
239262

@@ -280,7 +303,10 @@ LogicalResult IndexSwitchOpLowering::matchAndRewrite(
280303
return failure();
281304
}
282305

283-
rewriter.replaceOp(indexSwitchOp, resultVariables);
306+
rewriter.setInsertionPointAfter(indexSwitchOp);
307+
SmallVector<Value> results = loadValues(resultVariables, rewriter, loc);
308+
309+
rewriter.replaceOp(indexSwitchOp, results);
284310
return success();
285311
}
286312

mlir/lib/Conversion/UBToEmitC/UBToEmitC.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,22 @@ struct PoisonOpLowering : public OpConversionPattern<ub::PoisonOp> {
5252
Attribute value;
5353
if (noInitialization) {
5454
value = emitc::OpaqueAttr::get(op->getContext(), "");
55-
} else if (emitc::isIntegerIndexOrOpaqueType(convertedType)) {
55+
auto var = rewriter.create<emitc::VariableOp>(op.getLoc(), emitc::LValueType::get(convertedType), value);
56+
rewriter.replaceOpWithNewOp<emitc::LoadOp>(op, convertedType, var);
57+
return success();
58+
}
59+
60+
// Any constant will be fine to lower a poison op
61+
if (emitc::isIntegerIndexOrOpaqueType(convertedType)) {
5662
value = IntegerAttr::get((emitc::isPointerWideType(convertedType))
5763
? IndexType::get(op.getContext())
5864
: convertedType,
5965
42);
6066
} else if (emitc::isSupportedFloatType(convertedType)) {
6167
value = FloatAttr::get(convertedType, 42.0f);
6268
}
63-
64-
// Any constant will be fine to lower a poison op
65-
rewriter.replaceOpWithNewOp<emitc::VariableOp>(op, convertedType, value);
69+
rewriter.replaceOpWithNewOp<emitc::ConstantOp>(op, convertedType, value);
70+
6671
return success();
6772
}
6873
};

0 commit comments

Comments
 (0)