Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ def EmitC_IncludeOp
let hasCustomAssemblyFormat = 1;
}

def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {
def EmitC_LiteralOp : EmitC_Op<"literal", [Pure, CExpressionInterface]> {
let summary = "Literal operation";
let description = [{
The `emitc.literal` operation produces an SSA value equal to some constant
Expand All @@ -896,6 +896,12 @@ def EmitC_LiteralOp : EmitC_Op<"literal", [Pure]> {

let hasVerifier = 1;
let assemblyFormat = "$value attr-dict `:` type($result)";

let extraClassDeclaration = [{
bool hasSideEffects() {
return false;
}
}];
}

def EmitC_LogicalAndOp : EmitC_BinaryOp<"logical_and", []> {
Expand Down
6 changes: 3 additions & 3 deletions mlir/lib/Dialect/EmitC/Transforms/FormExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ struct FormExpressionsPass
// Wrap each C operator op with an expression op.
OpBuilder builder(context);
auto matchFun = [&](Operation *op) {
if (isa<emitc::CExpressionInterface>(*op) &&
!op->getParentOfType<emitc::ExpressionOp>() &&
op->getNumResults() == 1)
if (op->getNumResults() == 1 && !isa<emitc::LiteralOp>(op) &&
isa<emitc::CExpressionInterface>(*op) &&
!op->getParentOfType<emitc::ExpressionOp>())
createExpression(op, builder);
};
rootOp->walk(matchFun);
Expand Down
23 changes: 15 additions & 8 deletions mlir/lib/Target/Cpp/TranslateToCpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ static FailureOr<int> getOperatorPrecedence(Operation *operation) {
.Case<emitc::ConstantOp>([&](auto op) { return 17; })
.Case<emitc::DivOp>([&](auto op) { return 13; })
.Case<emitc::LoadOp>([&](auto op) { return 16; })
.Case<emitc::LiteralOp>([&](auto op) { return 17; })
.Case<emitc::LogicalAndOp>([&](auto op) { return 4; })
.Case<emitc::LogicalNotOp>([&](auto op) { return 15; })
.Case<emitc::LogicalOrOp>([&](auto op) { return 3; })
Expand Down Expand Up @@ -452,6 +453,16 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::LoadOp loadOp) {
return emitter.emitOperand(loadOp.getOperand());
}

static LogicalResult printOperation(CppEmitter &emitter,
emitc::LiteralOp literalOp) {
// If literalOp is used inside an expression, we treat it as an inlined one.
if (emitter.isPartOfCurrentExpression(literalOp.getResult()))
return emitter.ostream() << literalOp.getValue(), success();

emitter.cacheDeferredOpResult(literalOp.getResult(), literalOp.getValue());
return success();
}

static LogicalResult printBinaryOperation(CppEmitter &emitter,
Operation *operation,
StringRef binaryOperator) {
Expand Down Expand Up @@ -1714,10 +1725,10 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
emitc::DeclareFuncOp, emitc::DivOp, emitc::ExpressionOp,
emitc::FieldOp, emitc::FileOp, emitc::ForOp, emitc::FuncOp,
emitc::GlobalOp, emitc::IfOp, emitc::IncludeOp, emitc::LoadOp,
emitc::LogicalAndOp, emitc::LogicalNotOp, emitc::LogicalOrOp,
emitc::MulOp, emitc::RemOp, emitc::ReturnOp, emitc::SubOp,
emitc::SwitchOp, emitc::UnaryMinusOp, emitc::UnaryPlusOp,
emitc::VariableOp, emitc::VerbatimOp>(
emitc::LiteralOp, emitc::LogicalAndOp, emitc::LogicalNotOp,
emitc::LogicalOrOp, emitc::MulOp, emitc::RemOp, emitc::ReturnOp,
emitc::SubOp, emitc::SwitchOp, emitc::UnaryMinusOp,
emitc::UnaryPlusOp, emitc::VariableOp, emitc::VerbatimOp>(

[&](auto op) { return printOperation(*this, op); })
// Func ops.
Expand All @@ -1731,10 +1742,6 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
cacheDeferredOpResult(op.getResult(), op.getFieldName());
return success();
})
.Case<emitc::LiteralOp>([&](auto op) {
cacheDeferredOpResult(op.getResult(), op.getValue());
return success();
})
.Case<emitc::MemberOp>([&](auto op) {
cacheDeferredOpResult(op.getResult(), createMemberAccess(op));
return success();
Expand Down
42 changes: 42 additions & 0 deletions mlir/test/Target/Cpp/expressions.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,45 @@ emitc.func @expression_with_call_opaque_with_args_array(%0 : i32, %1 : i32) {
}
return
}


// CPP-DEFAULT: bool expression_with_literal(int32_t [[VAL_1:v[0-9]+]]) {
// CPP-DEFAULT-NEXT: bool [[VAL_2:v[0-9]+]] = (1 + [[VAL_1]]) / 2 < 3;
// CPP-DEFAULT-NEXT: return [[VAL_2]];
// CPP-DEFAULT-NEXT: }

// CPP-DECLTOP: bool expression_with_literal(int32_t [[VAL_1:v[0-9]+]]) {
// CPP-DECLTOP-NEXT: bool [[VAL_2:v[0-9]+]];
// CPP-DECLTOP-NEXT: [[VAL_2]] = (1 + [[VAL_1]]) / 2 < 3;
// CPP-DECLTOP-NEXT: return [[VAL_2]];
// CPP-DECLTOP-NEXT: }

func.func @expression_with_literal(%arg0 : i32) -> i1 {
%ret = emitc.expression %arg0 noinline : (i32) -> i1 {
%literal1 = emitc.literal "1" : i32
%literal2 = emitc.literal "2" : i32
%add = add %literal1, %arg0 : (i32, i32) -> i32
%div = div %add, %literal2 : (i32, i32) -> i32
%literal3 = emitc.literal "3" : i32
%cmp = emitc.cmp lt, %div, %literal3 : (i32, i32) -> i1
emitc.yield %cmp : i1
}
return %ret : i1
}


// CPP-DEFAULT: int32_t single_literal_in_expression() {
// CPP-DEFAULT-NEXT: return 42;
// CPP-DEFAULT-NEXT: }

// CPP-DECLTOP: int32_t single_literal_in_expression() {
// CPP-DECLTOP-NEXT: return 42;
// CPP-DECLTOP-NEXT: }

func.func @single_literal_in_expression() -> i32 {
%ret = emitc.expression : () -> i32 {
%literal = emitc.literal "42" : i32
emitc.yield %literal : i32
}
return %ret : i32
}