Skip to content

Commit 239777c

Browse files
committed
[mlir][emitc] Add literal constant.
A literal constant is not emitted as a variable but rather printed inline. The form used is same as the Attribute emission form. Differential Revision: https://reviews.llvm.org/D150356
1 parent e2e3f06 commit 239777c

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,20 @@ def EmitC_IncludeOp
234234
let hasCustomAssemblyFormat = 1;
235235
}
236236

237+
def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
238+
let summary = "Literal operation";
239+
let description = [{
240+
The `literal` operation produces an SSA value equal to some constant
241+
specified by an attribute.
242+
}];
243+
244+
let arguments = (ins StrAttr:$value);
245+
let results = (outs AnyType:$result);
246+
247+
let hasVerifier = 1;
248+
let assemblyFormat = "$value attr-dict `:` type($result)";
249+
}
250+
237251
def EmitC_MulOp : EmitC_BinaryArithOp<"mul", []> {
238252
let summary = "Multiplication operation";
239253
let description = [{

mlir/lib/Dialect/EmitC/IR/EmitC.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,16 @@ ParseResult IncludeOp::parse(OpAsmParser &parser, OperationState &result) {
199199
return success();
200200
}
201201

202+
//===----------------------------------------------------------------------===//
203+
// LiteralOp
204+
//===----------------------------------------------------------------------===//
205+
206+
/// The literal op requires a non-empty value.
207+
LogicalResult emitc::LiteralOp::verify() {
208+
if (getValue().empty())
209+
return emitOpError() << "value must not be empty";
210+
return success();
211+
}
202212
//===----------------------------------------------------------------------===//
203213
// SubOp
204214
//===----------------------------------------------------------------------===//
@@ -220,7 +230,6 @@ LogicalResult SubOp::verify() {
220230
!resultType.isa<IntegerType, emitc::OpaqueType>())
221231
return emitOpError("requires that the result is an integer or of opaque "
222232
"type if lhs and rhs are pointers");
223-
224233
return success();
225234
}
226235

mlir/lib/Target/Cpp/TranslateToCpp.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ static LogicalResult printOperation(CppEmitter &emitter,
714714
// When generating code for an scf.for op, printing a trailing semicolon
715715
// is handled within the printOperation function.
716716
bool trailingSemicolon =
717-
!isa<scf::IfOp, scf::ForOp, cf::CondBranchOp>(op);
717+
!isa<cf::CondBranchOp, emitc::LiteralOp, scf::IfOp, scf::ForOp>(op);
718718

719719
if (failed(emitter.emitOperation(
720720
op, /*trailingSemicolon=*/trailingSemicolon)))
@@ -733,6 +733,8 @@ CppEmitter::CppEmitter(raw_ostream &os, bool declareVariablesAtTop)
733733

734734
/// Return the existing or a new name for a Value.
735735
StringRef CppEmitter::getOrCreateName(Value val) {
736+
if (auto literal = dyn_cast_if_present<emitc::LiteralOp>(val.getDefiningOp()))
737+
return literal.getValue();
736738
if (!valueMapper.count(val))
737739
valueMapper.insert(val, formatv("v{0}", ++valueInScopeCount.top()));
738740
return *valueMapper.begin(val);
@@ -987,12 +989,17 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
987989
// Arithmetic ops.
988990
.Case<arith::ConstantOp>(
989991
[&](auto op) { return printOperation(*this, op); })
992+
.Case<emitc::LiteralOp>([&](auto op) { return success(); })
990993
.Default([&](Operation *) {
991994
return op.emitOpError("unable to find printer for op");
992995
});
993996

994997
if (failed(status))
995998
return failure();
999+
1000+
if (isa<emitc::LiteralOp>(op))
1001+
return success();
1002+
9961003
os << (trailingSemicolon ? ";\n" : "\n");
9971004
return success();
9981005
}

mlir/test/Target/Cpp/for.mlir

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,23 @@ func.func @test_for_yield() {
8282
// CPP-DECLTOP-NEXT: [[SE]] = [[SI]];
8383
// CPP-DECLTOP-NEXT: [[PE]] = [[PI]];
8484
// CPP-DECLTOP-NEXT: return;
85+
86+
func.func @test_for_yield_2() {
87+
%start = emitc.literal "0" : index
88+
%stop = emitc.literal "10" : index
89+
%step = emitc.literal "1" : index
90+
91+
%s0 = emitc.literal "0" : i32
92+
%p0 = emitc.literal "M_PI" : f32
93+
94+
%result:2 = scf.for %iter = %start to %stop step %step iter_args(%si = %s0, %pi = %p0) -> (i32, f32) {
95+
%sn = emitc.call "add"(%si, %iter) : (i32, index) -> i32
96+
%pn = emitc.call "mul"(%pi, %iter) : (f32, index) -> f32
97+
scf.yield %sn, %pn : i32, f32
98+
}
99+
100+
return
101+
}
102+
// CPP-DEFAULT: void test_for_yield_2() {
103+
// CPP-DEFAULT: float{{.*}}= M_PI
104+
// CPP-DEFAULT: for (size_t [[IN:.*]] = 0; [[IN]] < 10; [[IN]] += 1) {

0 commit comments

Comments
 (0)