diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td index bfb4d5d80b0b9..7ef98a4a2ec4c 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td @@ -57,23 +57,21 @@ def IntegerIndexOrOpaqueType : Type; def FloatIntegerIndexOrOpaqueType : AnyTypeOf<[EmitCFloatType, IntegerIndexOrOpaqueType]>; -def EmitC_TranslationUnitOp : EmitC_Op<"tu", - [IsolatedFromAbove, NoRegionArguments, SymbolTable, - OpAsmOpInterface - ] # GraphRegionNoTerminator.traits> { - let summary = "A translation unit container operation"; +def EmitC_FileOp + : EmitC_Op<"file", [IsolatedFromAbove, NoRegionArguments, SymbolTable, + OpAsmOpInterface]#GraphRegionNoTerminator.traits> { + let summary = "A file container operation"; let description = [{ - A `tu` represents a translation unit that can be emitted - into a single C++ file. + A `file` represents a single C/C++ file. - `mlir-translate` emits only the translation unit selected via - the `-translation-unit-id=id` flag. By default, no translation units are - emitted. + `mlir-translate` ignores the body of all `emitc.file` ops + unless the `-file-id=id` flag is used. With that flag, all `emitc.file` ops + with matching id are emitted. Example: ```mlir - emitc.tu "main" { + emitc.file "main" { emitc.func @func_one() { emitc.return } @@ -87,15 +85,14 @@ def EmitC_TranslationUnitOp : EmitC_Op<"tu", let assemblyFormat = "$id attr-dict-with-keyword $bodyRegion"; let builders = [OpBuilder<(ins CArg<"StringRef">:$id)>]; let extraClassDeclaration = [{ - /// Construct a module from the given location with an optional name. - static TranslationUnitOp create(Location loc, StringRef name); + /// Construct a file op from the given location with a name. + static FileOp create(Location loc, StringRef name); //===------------------------------------------------------------------===// // OpAsmOpInterface Methods //===------------------------------------------------------------------===// - /// EmitC ops in the body of the translation_unit can omit their 'emitc.' - /// prefix in the assembly. + /// EmitC ops in the body can omit their 'emitc.' prefix in the assembly. static ::llvm::StringRef getDefaultDialect() { return "emitc"; } diff --git a/mlir/include/mlir/Target/Cpp/CppEmitter.h b/mlir/include/mlir/Target/Cpp/CppEmitter.h index 1c7ba78eba0c9..e7b655e898ec9 100644 --- a/mlir/include/mlir/Target/Cpp/CppEmitter.h +++ b/mlir/include/mlir/Target/Cpp/CppEmitter.h @@ -24,9 +24,11 @@ namespace emitc { /// the region of 'op' need almost all be in EmitC dialect. The parameter /// 'declareVariablesAtTop' enforces that all variables for op results and block /// arguments are declared at the beginning of the function. +/// If parameter 'fileId' is non-empty, then body of `emitc.file` ops +/// with matching id are emitted. LogicalResult translateToCpp(Operation *op, raw_ostream &os, bool declareVariablesAtTop = false, - StringRef onlyTu = "", + StringRef fileId = {}, bool constantsAsVariables = true); } // namespace emitc } // namespace mlir diff --git a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp index 0c8b2bb11426d..26c2565cd79ac 100644 --- a/mlir/lib/Dialect/EmitC/IR/EmitC.cpp +++ b/mlir/lib/Dialect/EmitC/IR/EmitC.cpp @@ -1479,10 +1479,9 @@ void SwitchOp::getRegionInvocationBounds( } //===----------------------------------------------------------------------===// -// TranslationUnitOp +// FileOp //===----------------------------------------------------------------------===// -void TranslationUnitOp::build(OpBuilder &builder, OperationState &state, - StringRef id) { +void FileOp::build(OpBuilder &builder, OperationState &state, StringRef id) { state.addRegion()->emplaceBlock(); state.attributes.push_back( builder.getNamedAttr("id", builder.getStringAttr(id))); diff --git a/mlir/lib/Target/Cpp/TranslateRegistration.cpp b/mlir/lib/Target/Cpp/TranslateRegistration.cpp index dfe8bcb106f12..7a21d03bbff95 100644 --- a/mlir/lib/Target/Cpp/TranslateRegistration.cpp +++ b/mlir/lib/Target/Cpp/TranslateRegistration.cpp @@ -29,9 +29,8 @@ void registerToCppTranslation() { llvm::cl::desc("Declare variables at top when emitting C/C++"), llvm::cl::init(false)); - static llvm::cl::opt onlyTu( - "translation-unit-id", - llvm::cl::desc("Only emit the translation unit with the matching id"), + static llvm::cl::opt fileId( + "file-id", llvm::cl::desc("Emit emitc.file ops with matching id"), llvm::cl::init("")); static llvm::cl::opt constantsAsVariables( @@ -45,7 +44,7 @@ void registerToCppTranslation() { return emitc::translateToCpp( op, output, /*declareVariablesAtTop=*/declareVariablesAtTop, - /*onlyTu=*/onlyTu, + /*fileId=*/fileId, /*constantsAsVariables=*/constantsAsVariables); }, [](DialectRegistry ®istry) { diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp index 8f7b495396309..60cb51f60301e 100644 --- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp +++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp @@ -116,7 +116,7 @@ namespace { /// Emitter that uses dialect specific emitters to emit C++ code. struct CppEmitter { explicit CppEmitter(raw_ostream &os, bool declareVariablesAtTop, - StringRef onlyTu, bool constantsAsVariables); + StringRef fileId, bool constantsAsVariables); /// Emits attribute or returns failure. LogicalResult emitAttribute(Location loc, Attribute attr); @@ -257,7 +257,9 @@ struct CppEmitter { bool shouldDeclareVariablesAtTop() { return declareVariablesAtTop; }; /// Returns whether this translation unit should be emitted - bool shouldEmitTu(TranslationUnitOp tu) { return tu.getId() == onlyTu; } + bool shouldEmitFile(FileOp file) { + return !fileId.empty() && file.getId() == fileId; + } /// Returns whether the value of ConstantOps should be stored in variables /// or emmited directly in their usage locations. @@ -285,8 +287,8 @@ struct CppEmitter { /// taken care of by transformations run by the backend. bool shouldBeInlined(ExpressionOp expressionOp); - /// This emitter will only emit translation units whos id matches this value. - StringRef willOnlyEmitTu() { return onlyTu; } + /// This emitter will only emit a file whos id matches this value. + StringRef willOnlyEmitFile() { return fileId; } // Resets the value counter to 0 void resetValueCounter(); @@ -309,8 +311,8 @@ struct CppEmitter { /// includes results from ops located in nested regions. bool declareVariablesAtTop; - /// Only emit translation units whos id matches this value. - std::string onlyTu; + /// Only emit file ops whos id matches this value. + std::string fileId; /// Use variables to hold the constant values bool constantsAsVariables; @@ -431,7 +433,7 @@ static LogicalResult printOperation(CppEmitter &emitter, /// Temporary emitter object that writes to our stream instead of the output /// allowing for the capture and caching of the produced string. CppEmitter sniffer = CppEmitter(ss, emitter.shouldDeclareVariablesAtTop(), - emitter.willOnlyEmitTu(), + emitter.willOnlyEmitFile(), emitter.shouldUseConstantsAsVariables()); ss << "("; @@ -1091,11 +1093,11 @@ static LogicalResult printOperation(CppEmitter &emitter, ModuleOp moduleOp) { return success(); } -static LogicalResult printOperation(CppEmitter &emitter, TranslationUnitOp tu) { - if (!emitter.shouldEmitTu(tu)) +static LogicalResult printOperation(CppEmitter &emitter, FileOp file) { + if (!emitter.shouldEmitFile(file)) return success(); - for (Operation &op : tu) { + for (Operation &op : file) { if (failed(emitter.emitOperation(op, /*trailingSemicolon=*/false))) return failure(); } @@ -1348,9 +1350,9 @@ static LogicalResult printOperation(CppEmitter &emitter, } CppEmitter::CppEmitter(raw_ostream &os, bool declareVariablesAtTop, - StringRef onlyTu, bool constantsAsVariables) + StringRef fileId, bool constantsAsVariables) : os(os), declareVariablesAtTop(declareVariablesAtTop), - onlyTu(onlyTu.str()), constantsAsVariables(constantsAsVariables), + fileId(fileId.str()), constantsAsVariables(constantsAsVariables), defaultValueMapperScope(valueMapper), defaultBlockMapperScope(blockMapper) { labelInScopeCount.push(0); @@ -1778,11 +1780,11 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) { emitc::BitwiseRightShiftOp, emitc::BitwiseXorOp, emitc::CallOp, emitc::CallOpaqueOp, emitc::CastOp, emitc::CmpOp, emitc::ConditionalOp, emitc::ConstantOp, emitc::DeclareFuncOp, - emitc::DivOp, emitc::ExpressionOp, 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::TranslationUnitOp, emitc::UnaryMinusOp, + emitc::DivOp, emitc::ExpressionOp, 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>( [&](auto op) { return printOperation(*this, op); }) // Func ops. @@ -1814,7 +1816,7 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) { if (hasDeferredEmission(&op)) return success(); - if (isa(op)) + if (isa(op)) return success(); // skip adding newlines if (getEmittedExpression() || @@ -1822,8 +1824,9 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) { shouldBeInlined(cast(op)))) return success(); - if (isa(op)) { + if (isa( + op)) { trailingSemicolon = false; } @@ -2015,8 +2018,8 @@ void CppEmitter::decreaseLoopNestingLevel() { loopNestingLevel--; } LogicalResult emitc::translateToCpp(Operation *op, raw_ostream &os, bool declareVariablesAtTop, - StringRef onlyTu, + StringRef fileId, bool constantsAsVariables) { - CppEmitter emitter(os, declareVariablesAtTop, onlyTu, constantsAsVariables); + CppEmitter emitter(os, declareVariablesAtTop, fileId, constantsAsVariables); return emitter.emitOperation(*op, /*trailingSemicolon=*/false); } diff --git a/mlir/test/Target/Cpp/file.mlir b/mlir/test/Target/Cpp/file.mlir new file mode 100644 index 0000000000000..9533611a9fa13 --- /dev/null +++ b/mlir/test/Target/Cpp/file.mlir @@ -0,0 +1,29 @@ +// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s --check-prefix NO-FILTER --allow-empty +// RUN: mlir-translate -mlir-to-cpp -file-id=non-existing %s | FileCheck %s --check-prefix NON-EXISTING --allow-empty +// RUN: mlir-translate -mlir-to-cpp -file-id=file_one %s | FileCheck %s --check-prefix FILE-ONE --allow-empty +// RUN: mlir-translate -mlir-to-cpp -file-id=file_two %s | FileCheck %s --check-prefix FILE-TWO --allow-empty + + +// NO-FILTER-NOT: func_one +// NO-FILTER-NOT: func_two + +// NON-EXISTING-NOT: func_one +// NON-EXISTING-NOT: func_two + +// FILE-ONE: func_one +// FILE-ONE-NOT: func_two + +// FILE-TWO-NOT: func_one +// FILE-TWO: func_two + +emitc.file "file_one" { + emitc.func @func_one(%arg: f32) { + emitc.return + } +} + +emitc.file "file_two" { + emitc.func @func_two(%arg: f32) { + emitc.return + } +} diff --git a/mlir/test/Target/Cpp/tu.mlir b/mlir/test/Target/Cpp/tu.mlir deleted file mode 100644 index 7d15f5a502fe6..0000000000000 --- a/mlir/test/Target/Cpp/tu.mlir +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: mlir-translate -mlir-to-cpp %s | FileCheck %s --check-prefix NO-FILTER --allow-empty -// RUN: mlir-translate -mlir-to-cpp -translation-unit-id=non-existing %s | FileCheck %s --check-prefix NON-EXISTING --allow-empty -// RUN: mlir-translate -mlir-to-cpp -translation-unit-id=tu_one %s | FileCheck %s --check-prefix TU-ONE -// RUN: mlir-translate -mlir-to-cpp -translation-unit-id=tu_two %s | FileCheck %s --check-prefix TU-TWO - - -// NO-FILTER-NOT: func_one -// NO-FILTER-NOT: func_two - -// NON-EXISTING-NOT: func_one -// NON-EXISTING-NOT: func_two - -// TU-ONE: func_one -// TU-ONE-NOT: func_two - -// TU-TWO-NOT: func_one -// TU-TWO: func_two - -emitc.tu "tu_one" { - emitc.func @func_one(%arg: f32) { - emitc.return - } -} - -emitc.tu "tu_two" { - emitc.func @func_two(%arg: f32) { - emitc.return - } -}