@@ -185,6 +185,10 @@ struct CppEmitter {
185185 // / Return the existing or a new name for a Value.
186186 StringRef getOrCreateName (Value val);
187187
188+ // / Return the existing or a new name for a loop induction variable of an
189+ // / emitc::ForOp.
190+ StringRef getOrCreateName (emitc::ForOp forOp);
191+
188192 // Returns the textual representation of a subscript operation.
189193 std::string getSubscriptName (emitc::SubscriptOp op);
190194
@@ -200,23 +204,39 @@ struct CppEmitter {
200204 // / Whether to map an mlir integer to a unsigned integer in C++.
201205 bool shouldMapToUnsigned (IntegerType::SignednessSemantics val);
202206
203- // / RAII helper function to manage entering/exiting C++ scopes.
207+ // / Abstract RAII helper function to manage entering/exiting C++ scopes.
204208 struct Scope {
209+ ~Scope () { emitter.labelInScopeCount .pop (); }
210+
211+ private:
212+ llvm::ScopedHashTableScope<Value, std::string> valueMapperScope;
213+ llvm::ScopedHashTableScope<Block *, std::string> blockMapperScope;
214+
215+ protected:
205216 Scope (CppEmitter &emitter)
206217 : valueMapperScope(emitter.valueMapper),
207218 blockMapperScope (emitter.blockMapper), emitter(emitter) {
208- emitter.valueInScopeCount .push (emitter.valueInScopeCount .top ());
209219 emitter.labelInScopeCount .push (emitter.labelInScopeCount .top ());
210220 }
211- ~Scope () {
212- emitter.valueInScopeCount .pop ();
213- emitter.labelInScopeCount .pop ();
221+ CppEmitter &emitter;
222+ };
223+
224+ // / RAII helper function to manage entering/exiting functions, while re-using
225+ // / value names.
226+ struct FunctionScope : Scope {
227+ FunctionScope (CppEmitter &emitter) : Scope(emitter) {
228+ // Re-use value names
229+ emitter.resetValueCounter ();
214230 }
231+ };
215232
216- private:
217- llvm::ScopedHashTableScope<Value, std::string> valueMapperScope;
218- llvm::ScopedHashTableScope<Block *, std::string> blockMapperScope;
219- CppEmitter &emitter;
233+ // / RAII helper function to manage entering/exiting emitc::forOp loops and
234+ // / handle induction variable naming.
235+ struct LoopScope : Scope {
236+ LoopScope (CppEmitter &emitter) : Scope(emitter) {
237+ emitter.increaseLoopNestingLevel ();
238+ }
239+ ~LoopScope () { emitter.decreaseLoopNestingLevel (); }
220240 };
221241
222242 // / Returns wether the Value is assigned to a C++ variable in the scope.
@@ -264,6 +284,15 @@ struct CppEmitter {
264284 // / This emitter will only emit translation units whos id matches this value.
265285 StringRef willOnlyEmitTu () { return onlyTu; }
266286
287+ // Resets the value counter to 0
288+ void resetValueCounter ();
289+
290+ // Increases the loop nesting level by 1
291+ void increaseLoopNestingLevel ();
292+
293+ // Decreases the loop nesting level by 1
294+ void decreaseLoopNestingLevel ();
295+
267296private:
268297 using ValueMapper = llvm::ScopedHashTable<Value, std::string>;
269298 using BlockMapper = llvm::ScopedHashTable<Block *, std::string>;
@@ -288,11 +317,19 @@ struct CppEmitter {
288317 // / Map from block to name of C++ label.
289318 BlockMapper blockMapper;
290319
291- // / The number of values in the current scope. This is used to declare the
292- // / names of values in a scope.
293- std::stack<int64_t > valueInScopeCount;
320+ // / Default values representing outermost scope
321+ llvm::ScopedHashTableScope<Value, std::string> defaultValueMapperScope;
322+ llvm::ScopedHashTableScope<Block *, std::string> defaultBlockMapperScope;
323+
294324 std::stack<int64_t > labelInScopeCount;
295325
326+ // / Keeps track of the amount of nested loops the emitter currently operates
327+ // / in.
328+ uint64_t loopNestingLevel{0 };
329+
330+ // / Emitter-level count of created values to enable unique identifiers.
331+ unsigned int valueCount{0 };
332+
296333 // / State of the current expression being emitted.
297334 ExpressionOp emittedExpression;
298335 SmallVector<int > emittedExpressionPrecedence;
@@ -911,7 +948,6 @@ static LogicalResult printOperation(CppEmitter &emitter,
911948}
912949
913950static LogicalResult printOperation (CppEmitter &emitter, emitc::ForOp forOp) {
914-
915951 raw_indented_ostream &os = emitter.ostream ();
916952
917953 // Utility function to determine whether a value is an expression that will be
@@ -930,12 +966,12 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::ForOp forOp) {
930966 emitter.emitType (forOp.getLoc (), forOp.getInductionVar ().getType ())))
931967 return failure ();
932968 os << " " ;
933- os << emitter.getOrCreateName (forOp. getInductionVar () );
969+ os << emitter.getOrCreateName (forOp);
934970 os << " = " ;
935971 if (failed (emitter.emitOperand (forOp.getLowerBound ())))
936972 return failure ();
937973 os << " ; " ;
938- os << emitter.getOrCreateName (forOp. getInductionVar () );
974+ os << emitter.getOrCreateName (forOp);
939975 os << " < " ;
940976 Value upperBound = forOp.getUpperBound ();
941977 bool upperBoundRequiresParentheses = requiresParentheses (upperBound);
@@ -946,13 +982,15 @@ static LogicalResult printOperation(CppEmitter &emitter, emitc::ForOp forOp) {
946982 if (upperBoundRequiresParentheses)
947983 os << " )" ;
948984 os << " ; " ;
949- os << emitter.getOrCreateName (forOp. getInductionVar () );
985+ os << emitter.getOrCreateName (forOp);
950986 os << " += " ;
951987 if (failed (emitter.emitOperand (forOp.getStep ())))
952988 return failure ();
953989 os << " ) {\n " ;
954990 os.indent ();
955991
992+ CppEmitter::LoopScope lScope (emitter);
993+
956994 Region &forRegion = forOp.getRegion ();
957995 auto regionOps = forRegion.getOps ();
958996
@@ -1039,8 +1077,6 @@ static LogicalResult printOperation(CppEmitter &emitter,
10391077}
10401078
10411079static LogicalResult printOperation (CppEmitter &emitter, ModuleOp moduleOp) {
1042- CppEmitter::Scope scope (emitter);
1043-
10441080 for (Operation &op : moduleOp) {
10451081 if (failed (emitter.emitOperation (op, /* trailingSemicolon=*/ false )))
10461082 return failure ();
@@ -1052,8 +1088,6 @@ static LogicalResult printOperation(CppEmitter &emitter, TranslationUnitOp tu) {
10521088 if (!emitter.shouldEmitTu (tu))
10531089 return success ();
10541090
1055- CppEmitter::Scope scope (emitter);
1056-
10571091 for (Operation &op : tu) {
10581092 if (failed (emitter.emitOperation (op, /* trailingSemicolon=*/ false )))
10591093 return failure ();
@@ -1216,7 +1250,7 @@ static LogicalResult printOperation(CppEmitter &emitter,
12161250 return functionOp.emitOpError () << " cannot emit array type as result type" ;
12171251 }
12181252
1219- CppEmitter::Scope scope (emitter);
1253+ CppEmitter::FunctionScope scope (emitter);
12201254 raw_indented_ostream &os = emitter.ostream ();
12211255 if (failed (emitter.emitTypes (functionOp.getLoc (),
12221256 functionOp.getFunctionType ().getResults ())))
@@ -1244,7 +1278,7 @@ static LogicalResult printOperation(CppEmitter &emitter,
12441278 " with multiple blocks needs variables declared at top" );
12451279 }
12461280
1247- CppEmitter::Scope scope (emitter);
1281+ CppEmitter::FunctionScope scope (emitter);
12481282 raw_indented_ostream &os = emitter.ostream ();
12491283 if (functionOp.getSpecifiers ()) {
12501284 for (Attribute specifier : functionOp.getSpecifiersAttr ()) {
@@ -1278,7 +1312,6 @@ static LogicalResult printOperation(CppEmitter &emitter,
12781312
12791313static LogicalResult printOperation (CppEmitter &emitter,
12801314 DeclareFuncOp declareFuncOp) {
1281- CppEmitter::Scope scope (emitter);
12821315 raw_indented_ostream &os = emitter.ostream ();
12831316
12841317 auto functionOp = SymbolTable::lookupNearestSymbolFrom<emitc::FuncOp>(
@@ -1310,8 +1343,9 @@ static LogicalResult printOperation(CppEmitter &emitter,
13101343CppEmitter::CppEmitter (raw_ostream &os, bool declareVariablesAtTop,
13111344 StringRef onlyTu, bool constantsAsVariables)
13121345 : os(os), declareVariablesAtTop(declareVariablesAtTop),
1313- onlyTu(onlyTu.str()), constantsAsVariables(constantsAsVariables) {
1314- valueInScopeCount.push (0 );
1346+ onlyTu (onlyTu.str()), constantsAsVariables(constantsAsVariables),
1347+ defaultValueMapperScope(valueMapper),
1348+ defaultBlockMapperScope(blockMapper) {
13151349 labelInScopeCount.push (0 );
13161350}
13171351
@@ -1352,7 +1386,29 @@ StringRef CppEmitter::getOrCreateName(Value val) {
13521386 assert (!hasDeferredEmission (val.getDefiningOp ()) &&
13531387 " cacheDeferredOpResult should have been called on this value, "
13541388 " update the emitOperation function." );
1355- valueMapper.insert (val, formatv (" v{0}" , ++valueInScopeCount.top ()));
1389+
1390+ valueMapper.insert (val, formatv (" v{0}" , ++valueCount));
1391+ }
1392+ return *valueMapper.begin (val);
1393+ }
1394+
1395+ // / Return the existing or a new name for a loop induction variable Value.
1396+ // / Loop induction variables follow natural naming: i, j, k,...
1397+ StringRef CppEmitter::getOrCreateName (emitc::ForOp forOp) {
1398+ Value val = forOp.getInductionVar ();
1399+
1400+ if (!valueMapper.count (val)) {
1401+
1402+ int64_t identifier = ' i' + loopNestingLevel;
1403+
1404+ if (identifier >= ' i' && identifier <= ' z' ) {
1405+ valueMapper.insert (val,
1406+ formatv (" {0}_{1}" , (char )identifier, ++valueCount));
1407+ } else {
1408+ // If running out of letters, continue with zX
1409+ valueMapper.insert (
1410+ val, formatv (" z{0}_{1}" , identifier - ' z' - 1 , ++valueCount));
1411+ }
13561412 }
13571413 return *valueMapper.begin (val);
13581414}
@@ -1946,6 +2002,12 @@ LogicalResult CppEmitter::emitTupleType(Location loc, ArrayRef<Type> types) {
19462002 return success ();
19472003}
19482004
2005+ void CppEmitter::resetValueCounter () { valueCount = 0 ; }
2006+
2007+ void CppEmitter::increaseLoopNestingLevel () { loopNestingLevel++; }
2008+
2009+ void CppEmitter::decreaseLoopNestingLevel () { loopNestingLevel--; }
2010+
19492011LogicalResult emitc::translateToCpp (Operation *op, raw_ostream &os,
19502012 bool declareVariablesAtTop,
19512013 StringRef onlyTu,
0 commit comments