Skip to content
Open
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
40 changes: 19 additions & 21 deletions mlir/lib/Target/Cpp/TranslateToCpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ static FailureOr<int> getOperatorPrecedence(Operation *operation) {
.Default([](auto op) { return op->emitError("unsupported operation"); });
}

static bool shouldBeInlined(Operation *op);

namespace {
/// Emitter that uses dialect specific emitters to emit C++ code.
struct CppEmitter {
Expand Down Expand Up @@ -254,24 +256,19 @@ struct CppEmitter {
}

/// Is expression currently being emitted.
bool isEmittingExpression() { return emittedExpression; }
bool isEmittingExpression() { return !emittedExpressionPrecedence.empty(); }

/// Determine whether given value is part of the expression potentially being
/// emitted.
bool isPartOfCurrentExpression(Value value) {
if (!emittedExpression)
return false;
Operation *def = value.getDefiningOp();
if (!def)
return false;
return isPartOfCurrentExpression(def);
return def ? isPartOfCurrentExpression(def) : false;
}

/// Determine whether given operation is part of the expression potentially
/// being emitted.
bool isPartOfCurrentExpression(Operation *def) {
auto operandExpression = dyn_cast<ExpressionOp>(def->getParentOp());
return operandExpression && operandExpression == emittedExpression;
return isEmittingExpression() && shouldBeInlined(def);
};

// Resets the value counter to 0.
Expand Down Expand Up @@ -318,7 +315,6 @@ struct CppEmitter {
unsigned int valueCount{0};

/// State of the current expression being emitted.
ExpressionOp emittedExpression;
SmallVector<int> emittedExpressionPrecedence;

void pushExpressionPrecedence(int precedence) {
Expand All @@ -341,12 +337,22 @@ static bool hasDeferredEmission(Operation *op) {
emitc::GetFieldOp>(op);
}

/// Determine whether expression \p expressionOp should be emitted inline, i.e.
/// Determine whether operation \p op should be emitted inline, i.e.
/// as part of its user. This function recommends inlining of any expressions
/// that can be inlined unless it is used by another expression, under the
/// assumption that any expression fusion/re-materialization was taken care of
/// by transformations run by the backend.
static bool shouldBeInlined(ExpressionOp expressionOp) {
static bool shouldBeInlined(Operation *op) {
// CExpression operations are inlined if and only if they reside within an
// ExpressionOp.
if (isa<CExpressionInterface>(op))
return isa<ExpressionOp>(op->getParentOp());

// Only other inlinable operation is ExpressionOp itself.
ExpressionOp expressionOp = dyn_cast<ExpressionOp>(op);
if (!expressionOp)
return false;

// Do not inline if expression is marked as such.
if (expressionOp.getDoNotInline())
return false;
Expand Down Expand Up @@ -1564,7 +1570,6 @@ LogicalResult CppEmitter::emitExpression(ExpressionOp expressionOp) {
"Expected precedence stack to be empty");
Operation *rootOp = expressionOp.getRootOp();

emittedExpression = expressionOp;
FailureOr<int> precedence = getOperatorPrecedence(rootOp);
if (failed(precedence))
return failure();
Expand All @@ -1576,7 +1581,6 @@ LogicalResult CppEmitter::emitExpression(ExpressionOp expressionOp) {
popExpressionPrecedence();
assert(emittedExpressionPrecedence.empty() &&
"Expected precedence stack to be empty");
emittedExpression = nullptr;

return success();
}
Expand Down Expand Up @@ -1617,14 +1621,8 @@ LogicalResult CppEmitter::emitOperand(Value value, bool isInBrackets) {
// If this operand is a block argument of an expression, emit instead the
// matching expression parameter.
Operation *argOp = arg.getParentBlock()->getParentOp();
if (auto expressionOp = dyn_cast<ExpressionOp>(argOp)) {
// This scenario is only expected when one of the operations within the
// expression being emitted references one of the expression's block
// arguments.
assert(expressionOp == emittedExpression &&
"Expected expression being emitted");
value = expressionOp->getOperand(arg.getArgNumber());
}
if (auto expressionOp = dyn_cast<ExpressionOp>(argOp))
return emitOperand(expressionOp->getOperand(arg.getArgNumber()));
}

os << getOrCreateName(value);
Expand Down