@@ -254,6 +254,16 @@ struct CppEmitter {
254254 return operandExpression == emittedExpression;
255255 };
256256
257+ // / Determine whether expression \p expressionOp should be emitted inline,
258+ // / i.e. as part of its user. This function recommends inlining of any
259+ // / expressions that can be inlined unless it is used by another expression,
260+ // / under the assumption that any expression fusion/re-materialization was
261+ // / taken care of by transformations run by the backend.
262+ bool shouldBeInlined (ExpressionOp expressionOp);
263+
264+ // / This emitter will only emit translation units whos id matches this value.
265+ StringRef willOnlyEmitTu () { return onlyTu; }
266+
257267private:
258268 using ValueMapper = llvm::ScopedHashTable<Value, std::string>;
259269 using BlockMapper = llvm::ScopedHashTable<Block *, std::string>;
@@ -297,21 +307,22 @@ struct CppEmitter {
297307 return lowestPrecedence ();
298308 return emittedExpressionPrecedence.back ();
299309 }
310+
311+ // / Determine whether expression \p op should be emitted in a deferred way.
312+ bool hasDeferredEmission (Operation *op);
300313};
301314} // namespace
302315
303- // / Determine whether expression \p op should be emitted in a deferred way.
304- static bool hasDeferredEmission (Operation *op) {
316+ bool CppEmitter::hasDeferredEmission (Operation *op) {
317+ if (llvm::isa_and_nonnull<emitc::ConstantOp>(op)) {
318+ return !shouldUseConstantsAsVariables ();
319+ }
320+
305321 return isa_and_nonnull<emitc::GetGlobalOp, emitc::LiteralOp, emitc::MemberOp,
306322 emitc::MemberOfPtrOp, emitc::SubscriptOp>(op);
307323}
308324
309- // / Determine whether expression \p expressionOp should be emitted inline, i.e.
310- // / as part of its user. This function recommends inlining of any expressions
311- // / that can be inlined unless it is used by another expression, under the
312- // / assumption that any expression fusion/re-materialization was taken care of
313- // / by transformations run by the backend.
314- static bool shouldBeInlined (ExpressionOp expressionOp) {
325+ bool CppEmitter::shouldBeInlined (ExpressionOp expressionOp) {
315326 // Do not inline if expression is marked as such.
316327 if (expressionOp.getDoNotInline ())
317328 return false ;
@@ -373,6 +384,25 @@ static LogicalResult printConstantOp(CppEmitter &emitter, Operation *operation,
373384static LogicalResult printOperation (CppEmitter &emitter,
374385 emitc::ConstantOp constantOp) {
375386 if (!emitter.shouldUseConstantsAsVariables ()) {
387+ std::string out;
388+ llvm::raw_string_ostream ss (out);
389+
390+ // / Temporary emitter object that writes to our stream instead of the output
391+ // / allowing for the capture and caching of the produced string.
392+ CppEmitter sniffer = CppEmitter (ss, emitter.shouldDeclareVariablesAtTop (),
393+ emitter.willOnlyEmitTu (),
394+ emitter.shouldUseConstantsAsVariables ());
395+
396+ ss << " (" ;
397+ if (failed (sniffer.emitType (constantOp.getLoc (), constantOp.getType ())))
398+ return failure ();
399+ ss << " ) " ;
400+
401+ if (failed (
402+ sniffer.emitAttribute (constantOp.getLoc (), constantOp.getValue ())))
403+ return failure ();
404+
405+ emitter.cacheDeferredOpResult (constantOp.getResult (), out);
376406 return success ();
377407 }
378408
@@ -838,7 +868,7 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::CastOp castOp) {
838868
839869static LogicalResult printOperation (CppEmitter &emitter,
840870 emitc::ExpressionOp expressionOp) {
841- if (shouldBeInlined (expressionOp))
871+ if (emitter. shouldBeInlined (expressionOp))
842872 return success ();
843873
844874 Operation &op = *expressionOp.getOperation ();
@@ -892,7 +922,7 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::ForOp forOp) {
892922 dyn_cast_if_present<ExpressionOp>(value.getDefiningOp ());
893923 if (!expressionOp)
894924 return false ;
895- return shouldBeInlined (expressionOp);
925+ return emitter. shouldBeInlined (expressionOp);
896926 };
897927
898928 os << " for (" ;
@@ -1114,7 +1144,7 @@ static LogicalResult printFunctionBody(CppEmitter &emitter,
11141144 functionOp->walk <WalkOrder::PreOrder>([&](Operation *op) -> WalkResult {
11151145 if (isa<emitc::ExpressionOp>(op->getParentOp ()) ||
11161146 (isa<emitc::ExpressionOp>(op) &&
1117- shouldBeInlined (cast<emitc::ExpressionOp>(op))))
1147+ emitter. shouldBeInlined (cast<emitc::ExpressionOp>(op))))
11181148 return WalkResult::skip ();
11191149 for (OpResult result : op->getResults ()) {
11201150 if (failed (emitter.emitVariableDeclaration (
@@ -1494,22 +1524,6 @@ LogicalResult CppEmitter::emitExpression(ExpressionOp expressionOp) {
14941524
14951525LogicalResult CppEmitter::emitOperand (Value value) {
14961526 Operation *def = value.getDefiningOp ();
1497- if (!shouldUseConstantsAsVariables ()) {
1498- if (auto constant = dyn_cast_if_present<ConstantOp>(def)) {
1499- os << " ((" ;
1500-
1501- if (failed (emitType (constant.getLoc (), constant.getType ()))) {
1502- return failure ();
1503- }
1504- os << " ) " ;
1505-
1506- if (failed (emitAttribute (constant.getLoc (), constant.getValue ()))) {
1507- return failure ();
1508- }
1509- os << " )" ;
1510- return success ();
1511- }
1512- }
15131527
15141528 if (isPartOfCurrentExpression (value)) {
15151529 assert (def && " Expected operand to be defined by an operation" );
@@ -1721,11 +1735,7 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
17211735 cacheDeferredOpResult (op.getResult (), op.getValue ());
17221736 return success ();
17231737 })
1724- .Case <emitc::MemberOp>([&](auto op) {
1725- cacheDeferredOpResult (op.getResult (), createMemberAccess (op));
1726- return success ();
1727- })
1728- .Case <emitc::MemberOfPtrOp>([&](auto op) {
1738+ .Case <emitc::MemberOp, emitc::MemberOfPtrOp>([&](auto op) {
17291739 cacheDeferredOpResult (op.getResult (), createMemberAccess (op));
17301740 return success ();
17311741 })
0 commit comments