@@ -174,6 +174,9 @@ struct CppEmitter {
174
174
// / Emit an expression as a C expression.
175
175
LogicalResult emitExpression (ExpressionOp expressionOp);
176
176
177
+ // / Insert the expression representing the operation into the value cache.
178
+ void cacheDeferredOpResult (Value value, StringRef str);
179
+
177
180
// / Return the existing or a new name for a Value.
178
181
StringRef getOrCreateName (Value val);
179
182
@@ -273,6 +276,12 @@ struct CppEmitter {
273
276
};
274
277
} // namespace
275
278
279
+ // / Determine whether expression \p op should be emitted in a deferred way.
280
+ static bool hasDeferredEmission (Operation *op) {
281
+ return isa_and_nonnull<emitc::GetGlobalOp, emitc::LiteralOp,
282
+ emitc::SubscriptOp>(op);
283
+ }
284
+
276
285
// / Determine whether expression \p expressionOp should be emitted inline, i.e.
277
286
// / as part of its user. This function recommends inlining of any expressions
278
287
// / that can be inlined unless it is used by another expression, under the
@@ -295,10 +304,9 @@ static bool shouldBeInlined(ExpressionOp expressionOp) {
295
304
296
305
Operation *user = *result.getUsers ().begin ();
297
306
298
- // Do not inline expressions used by subscript operations, since the
299
- // way the subscript operation translation is implemented requires that
300
- // variables be materialized.
301
- if (isa<emitc::SubscriptOp>(user))
307
+ // Do not inline expressions used by operations with deferred emission, since
308
+ // their translation requires the materialization of variables.
309
+ if (hasDeferredEmission (user))
302
310
return false ;
303
311
304
312
// Do not inline expressions used by ops with the CExpression trait. If this
@@ -370,20 +378,6 @@ static LogicalResult printOperation(CppEmitter &emitter,
370
378
return emitter.emitOperand (assignOp.getValue ());
371
379
}
372
380
373
- static LogicalResult printOperation (CppEmitter &emitter,
374
- emitc::GetGlobalOp op) {
375
- // Add name to cache so that `hasValueInScope` works.
376
- emitter.getOrCreateName (op.getResult ());
377
- return success ();
378
- }
379
-
380
- static LogicalResult printOperation (CppEmitter &emitter,
381
- emitc::SubscriptOp subscriptOp) {
382
- // Add name to cache so that `hasValueInScope` works.
383
- emitter.getOrCreateName (subscriptOp.getResult ());
384
- return success ();
385
- }
386
-
387
381
static LogicalResult printBinaryOperation (CppEmitter &emitter,
388
382
Operation *operation,
389
383
StringRef binaryOperator) {
@@ -621,9 +615,7 @@ static LogicalResult printOperation(CppEmitter &emitter,
621
615
if (t.getType ().isIndex ()) {
622
616
int64_t idx = t.getInt ();
623
617
Value operand = op.getOperand (idx);
624
- auto literalDef =
625
- dyn_cast_if_present<LiteralOp>(operand.getDefiningOp ());
626
- if (!literalDef && !emitter.hasValueInScope (operand))
618
+ if (!emitter.hasValueInScope (operand))
627
619
return op.emitOpError (" operand " )
628
620
<< idx << " 's value not defined in scope" ;
629
621
os << emitter.getOrCreateName (operand);
@@ -948,8 +940,7 @@ static LogicalResult printFunctionBody(CppEmitter &emitter,
948
940
// regions.
949
941
WalkResult result =
950
942
functionOp->walk <WalkOrder::PreOrder>([&](Operation *op) -> WalkResult {
951
- if (isa<emitc::LiteralOp>(op) ||
952
- isa<emitc::ExpressionOp>(op->getParentOp ()) ||
943
+ if (isa<emitc::ExpressionOp>(op->getParentOp ()) ||
953
944
(isa<emitc::ExpressionOp>(op) &&
954
945
shouldBeInlined (cast<emitc::ExpressionOp>(op))))
955
946
return WalkResult::skip ();
@@ -1001,7 +992,7 @@ static LogicalResult printFunctionBody(CppEmitter &emitter,
1001
992
// trailing semicolon is handled within the printOperation function.
1002
993
bool trailingSemicolon =
1003
994
!isa<cf::CondBranchOp, emitc::DeclareFuncOp, emitc::ForOp,
1004
- emitc::IfOp, emitc::LiteralOp, emitc:: VerbatimOp>(op);
995
+ emitc::IfOp, emitc::VerbatimOp>(op);
1005
996
1006
997
if (failed (emitter.emitOperation (
1007
998
op, /* trailingSemicolon=*/ trailingSemicolon)))
@@ -1134,20 +1125,18 @@ std::string CppEmitter::getSubscriptName(emitc::SubscriptOp op) {
1134
1125
return out;
1135
1126
}
1136
1127
1128
+ void CppEmitter::cacheDeferredOpResult (Value value, StringRef str) {
1129
+ if (!valueMapper.count (value))
1130
+ valueMapper.insert (value, str.str ());
1131
+ }
1132
+
1137
1133
// / Return the existing or a new name for a Value.
1138
1134
StringRef CppEmitter::getOrCreateName (Value val) {
1139
- if (auto literal = dyn_cast_if_present<emitc::LiteralOp>(val.getDefiningOp ()))
1140
- return literal.getValue ();
1141
1135
if (!valueMapper.count (val)) {
1142
- if (auto subscript =
1143
- dyn_cast_if_present<emitc::SubscriptOp>(val.getDefiningOp ())) {
1144
- valueMapper.insert (val, getSubscriptName (subscript));
1145
- } else if (auto getGlobal = dyn_cast_if_present<emitc::GetGlobalOp>(
1146
- val.getDefiningOp ())) {
1147
- valueMapper.insert (val, getGlobal.getName ().str ());
1148
- } else {
1149
- valueMapper.insert (val, formatv (" v{0}" , ++valueInScopeCount.top ()));
1150
- }
1136
+ assert (!hasDeferredEmission (val.getDefiningOp ()) &&
1137
+ " cacheDeferredOpResult should have been called on this value, "
1138
+ " update the emitOperation function." );
1139
+ valueMapper.insert (val, formatv (" v{0}" , ++valueInScopeCount.top ()));
1151
1140
}
1152
1141
return *valueMapper.begin (val);
1153
1142
}
@@ -1341,9 +1330,6 @@ LogicalResult CppEmitter::emitOperand(Value value) {
1341
1330
if (expressionOp && shouldBeInlined (expressionOp))
1342
1331
return emitExpression (expressionOp);
1343
1332
1344
- auto literalOp = dyn_cast_if_present<LiteralOp>(value.getDefiningOp ());
1345
- if (!literalOp && !hasValueInScope (value))
1346
- return failure ();
1347
1333
os << getOrCreateName (value);
1348
1334
return success ();
1349
1335
}
@@ -1399,7 +1385,7 @@ LogicalResult CppEmitter::emitVariableAssignment(OpResult result) {
1399
1385
1400
1386
LogicalResult CppEmitter::emitVariableDeclaration (OpResult result,
1401
1387
bool trailingSemicolon) {
1402
- if (isa<emitc::SubscriptOp> (result.getDefiningOp ()))
1388
+ if (hasDeferredEmission (result.getDefiningOp ()))
1403
1389
return success ();
1404
1390
if (hasValueInScope (result)) {
1405
1391
return result.getDefiningOp ()->emitError (
@@ -1498,24 +1484,35 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
1498
1484
emitc::CallOpaqueOp, emitc::CastOp, emitc::CmpOp,
1499
1485
emitc::ConditionalOp, emitc::ConstantOp, emitc::DeclareFuncOp,
1500
1486
emitc::DivOp, emitc::ExpressionOp, emitc::ForOp, emitc::FuncOp,
1501
- emitc::GlobalOp, emitc::GetGlobalOp , emitc::IfOp ,
1502
- emitc::IncludeOp , emitc::LogicalAndOp , emitc::LogicalNotOp ,
1503
- emitc::LogicalOrOp , emitc::MulOp , emitc::RemOp , emitc::ReturnOp ,
1504
- emitc::SubOp , emitc::SubscriptOp , emitc::UnaryMinusOp ,
1505
- emitc::UnaryPlusOp, emitc::VariableOp, emitc:: VerbatimOp>(
1487
+ emitc::GlobalOp, emitc::IfOp , emitc::IncludeOp ,
1488
+ emitc::LogicalAndOp , emitc::LogicalNotOp , emitc::LogicalOrOp ,
1489
+ emitc::MulOp , emitc::RemOp , emitc::ReturnOp , emitc::SubOp ,
1490
+ emitc::UnaryMinusOp , emitc::UnaryPlusOp , emitc::VariableOp ,
1491
+ emitc::VerbatimOp>(
1506
1492
[&](auto op) { return printOperation (*this , op); })
1507
1493
// Func ops.
1508
1494
.Case <func::CallOp, func::FuncOp, func::ReturnOp>(
1509
1495
[&](auto op) { return printOperation (*this , op); })
1510
- .Case <emitc::LiteralOp>([&](auto op) { return success (); })
1496
+ .Case <emitc::GetGlobalOp>([&](auto op) {
1497
+ cacheDeferredOpResult (op.getResult (), op.getName ());
1498
+ return success ();
1499
+ })
1500
+ .Case <emitc::LiteralOp>([&](auto op) {
1501
+ cacheDeferredOpResult (op.getResult (), op.getValue ());
1502
+ return success ();
1503
+ })
1504
+ .Case <emitc::SubscriptOp>([&](auto op) {
1505
+ cacheDeferredOpResult (op.getResult (), getSubscriptName (op));
1506
+ return success ();
1507
+ })
1511
1508
.Default ([&](Operation *) {
1512
1509
return op.emitOpError (" unable to find printer for op" );
1513
1510
});
1514
1511
1515
1512
if (failed (status))
1516
1513
return failure ();
1517
1514
1518
- if (isa<emitc::LiteralOp, emitc::SubscriptOp, emitc::GetGlobalOp>( op))
1515
+ if (hasDeferredEmission (& op))
1519
1516
return success ();
1520
1517
1521
1518
if (getEmittedExpression () ||
0 commit comments