diff --git a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h index 6618fbc54261..218829aec063 100644 --- a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h +++ b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h @@ -32,11 +32,9 @@ class CIRGenAction : public clang::ASTFrontendAction { public: enum class OutputType { EmitAssembly, - EmitCIR, - EmitCIRFlat, + EmitMLIR, EmitLLVM, EmitBC, - EmitMLIR, EmitObj, None }; @@ -73,20 +71,6 @@ class CIRGenAction : public clang::ASTFrontendAction { OutputType action; }; -class EmitCIRAction : public CIRGenAction { - virtual void anchor(); - -public: - EmitCIRAction(mlir::MLIRContext *mlirCtx = nullptr); -}; - -class EmitCIRFlatAction : public CIRGenAction { - virtual void anchor(); - -public: - EmitCIRFlatAction(mlir::MLIRContext *mlirCtx = nullptr); -}; - class EmitCIROnlyAction : public CIRGenAction { virtual void anchor(); diff --git a/clang/include/clang/CIR/LowerToLLVM.h b/clang/include/clang/CIR/LowerToLLVM.h index 2992163196e7..dfa4e59b5e1c 100644 --- a/clang/include/clang/CIR/LowerToLLVM.h +++ b/clang/include/clang/CIR/LowerToLLVM.h @@ -29,13 +29,19 @@ class ModuleOp; namespace cir { namespace direct { +mlir::ModuleOp lowerDirectlyFromCIRToLLVMDialect(mlir::ModuleOp theModule, + bool disableVerifier = false, + bool disableCCLowering = false, + bool disableDebugInfo = false); + +// Lower directly from pristine CIR to LLVMIR. std::unique_ptr lowerDirectlyFromCIRToLLVMIR( mlir::ModuleOp theModule, llvm::LLVMContext &llvmCtx, bool disableVerifier = false, bool disableCCLowering = false, bool disableDebugInfo = false); -} -// Lower directly from pristine CIR to LLVMIR. +} // namespace direct + std::unique_ptr lowerFromCIRToMLIRToLLVMIR(mlir::ModuleOp theModule, std::unique_ptr mlirCtx, diff --git a/clang/include/clang/CIR/LowerToMLIR.h b/clang/include/clang/CIR/LowerToMLIR.h index 567deb7abc7d..1ddced958cee 100644 --- a/clang/include/clang/CIR/LowerToMLIR.h +++ b/clang/include/clang/CIR/LowerToMLIR.h @@ -12,10 +12,16 @@ #ifndef CLANG_CIR_LOWERTOMLIR_H #define CLANG_CIR_LOWERTOMLIR_H +#include "mlir/Transforms/DialectConversion.h" + namespace cir { void populateCIRLoopToSCFConversionPatterns(mlir::RewritePatternSet &patterns, mlir::TypeConverter &converter); + +mlir::ModuleOp +lowerFromCIRToMLIRToLLVMDialect(mlir::ModuleOp theModule, + mlir::MLIRContext *mlirCtx = nullptr); } // namespace cir #endif // CLANG_CIR_LOWERTOMLIR_H_ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3bd0fce9ab29..62016c25fa20 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3113,14 +3113,25 @@ defm clangir_call_conv_lowering : BoolFOption<"clangir-call-conv-lowering", NegFlag, BothFlags<[], [ClangOption, CC1Option], "">>; +def emit_mlir : Flag<["-"], "emit-mlir">, Visibility<[ClangOption]>, Group, + HelpText<"Build ASTs and then lower through ClangIR to MLIR (standard dialects " + "when `-fno-clangir-direct-lowering` is used or the LLVM dialect when " + "`-fclangir-direct-lowering` is used), emit the .mlir file.">; +def emit_mlir_EQ : Joined<["-"], "emit-mlir=">, Visibility<[ClangOption, CC1Option]>, Group, + HelpText<"Build ASTs and then lower through ClangIR to the selected MLIR dialect, emit the .mlir file. " + "Allowed values are `core` for MLIR standard dialects and `llvm` for the LLVM dialect.">, + Values<"core,llvm,cir,cir-flat">, + NormalizedValuesScope<"frontend">, + NormalizedValues<["MLIR_CORE", "MLIR_LLVM", "MLIR_CIR", "MLIR_CIR_FLAT"]>, + MarshallingInfoEnum, "MLIR_CORE">; def emit_cir : Flag<["-"], "emit-cir">, Visibility<[ClangOption, CC1Option]>, - Group, HelpText<"Build ASTs and then lower to ClangIR, emit the .cir file">; + Group, Alias, AliasArgs<["cir"]>, + HelpText<"Build ASTs and then lower to ClangIR, emit the .cir file">; def emit_cir_only : Flag<["-"], "emit-cir-only">, HelpText<"Build ASTs and convert to CIR, discarding output">; def emit_cir_flat : Flag<["-"], "emit-cir-flat">, Visibility<[ClangOption, CC1Option]>, - Group, HelpText<"Similar to -emit-cir but also lowers structured CFG into basic blocks.">; -def emit_mlir : Flag<["-"], "emit-mlir">, Visibility<[CC1Option]>, Group, - HelpText<"Build ASTs and then lower through ClangIR to MLIR, emit the .milr file">; + Group, Alias, AliasArgs<["cir-flat"]>, + HelpText<"Similar to -emit-cir but also lowers structured CFG into basic blocks.">; /// ClangIR-specific options - END def flto : Flag<["-"], "flto">, diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 2c4d227bf07f..6bc0ff0f4af3 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -99,8 +99,6 @@ TYPE("ir", LLVM_BC, INVALID, "bc", phases TYPE("lto-ir", LTO_IR, INVALID, "s", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("lto-bc", LTO_BC, INVALID, "o", phases::Compile, phases::Backend, phases::Assemble, phases::Link) -TYPE("cir", CIR, INVALID, "cir", phases::Compile, phases::Backend, phases::Assemble, phases::Link) -TYPE("cir-flat", CIR_FLAT, INVALID, "cir", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("mlir", MLIR, INVALID, "mlir", phases::Compile, phases::Backend, phases::Assemble, phases::Link) // Misc. diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index c20744b49136..66f8d250cec4 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -65,12 +65,6 @@ enum ActionKind { /// Translate input source into HTML. EmitHTML, - /// Emit a .cir file - EmitCIR, - - /// Emit a .cir file with flat ClangIR - EmitCIRFlat, - /// Generate CIR, bud don't emit anything. EmitCIROnly, @@ -160,6 +154,8 @@ enum ActionKind { PrintDependencyDirectivesSourceMinimizerOutput }; +enum MLIRDialectKind { MLIR_CORE, MLIR_LLVM, MLIR_CIR, MLIR_CIR_FLAT }; + } // namespace frontend /// The kind of a file that we've been handed as an input. @@ -530,6 +526,8 @@ class FrontendOptions { std::string ClangIRIdiomRecognizerOpts; std::string ClangIRLibOptOpts; + frontend::MLIRDialectKind MLIRTargetDialect; + /// The input kind, either specified via -x argument or deduced from the input /// file name. InputKind DashX; diff --git a/clang/lib/CIR/CodeGen/CIRPasses.cpp b/clang/lib/CIR/CodeGen/CIRPasses.cpp index 04582af2f517..59d2445cb16e 100644 --- a/clang/lib/CIR/CodeGen/CIRPasses.cpp +++ b/clang/lib/CIR/CodeGen/CIRPasses.cpp @@ -28,7 +28,7 @@ mlir::LogicalResult runCIRToCIRPasses( llvm::StringRef lifetimeOpts, bool enableIdiomRecognizer, llvm::StringRef idiomRecognizerOpts, bool enableLibOpt, llvm::StringRef libOptOpts, std::string &passOptParsingFailure, - bool enableCIRSimplify, bool flattenCIR, bool emitMLIR, + bool enableCIRSimplify, bool flattenCIR, bool emitCore, bool enableCallConvLowering, bool enableMem2Reg) { llvm::TimeTraceScope scope("CIR To CIR Passes"); @@ -81,7 +81,7 @@ mlir::LogicalResult runCIRToCIRPasses( if (enableMem2Reg) pm.addPass(mlir::createMem2Reg()); - if (emitMLIR) + if (emitCore) pm.addPass(mlir::createSCFPreparePass()); // FIXME: once CIRCodenAction fixes emission other than CIR we diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp index 5cb81e89388f..051525ddb068 100644 --- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp +++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp @@ -26,6 +26,7 @@ #include "clang/CIR/CIRToCIRPasses.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/LowerToLLVM.h" +#include "clang/CIR/LowerToMLIR.h" #include "clang/CIR/Passes.h" #include "clang/CodeGen/BackendUtil.h" #include "clang/CodeGen/ModuleBuilder.h" @@ -201,8 +202,16 @@ class CIRGenConsumer : public clang::ASTConsumer { if (feOptions.ClangIRLibOpt) libOptOpts = sanitizePassOptions(feOptions.ClangIRLibOptOpts); - bool enableCCLowering = feOptions.ClangIRCallConvLowering && - action != CIRGenAction::OutputType::EmitCIR; + bool enableCCLowering = + feOptions.ClangIRCallConvLowering && + !(action == CIRGenAction::OutputType::EmitMLIR && + feOptions.MLIRTargetDialect == frontend::MLIR_CIR); + bool flattenCIR = + action == CIRGenAction::OutputType::EmitMLIR && + feOptions.MLIRTargetDialect == clang::frontend::MLIR_CIR_FLAT; + + bool emitCore = action == CIRGenAction::OutputType::EmitMLIR && + feOptions.MLIRTargetDialect == clang::frontend::MLIR_CORE; // Setup and run CIR pipeline. std::string passOptParsingFailure; @@ -211,10 +220,8 @@ class CIRGenConsumer : public clang::ASTConsumer { feOptions.ClangIRLifetimeCheck, lifetimeOpts, feOptions.ClangIRIdiomRecognizer, idiomRecognizerOpts, feOptions.ClangIRLibOpt, libOptOpts, passOptParsingFailure, - codeGenOptions.OptimizationLevel > 0, - action == CIRGenAction::OutputType::EmitCIRFlat, - action == CIRGenAction::OutputType::EmitMLIR, enableCCLowering, - feOptions.ClangIREnableMem2Reg) + codeGenOptions.OptimizationLevel > 0, flattenCIR, emitCore, + enableCCLowering, feOptions.ClangIREnableMem2Reg) .failed()) { if (!passOptParsingFailure.empty()) diagnosticsEngine.Report(diag::err_drv_cir_pass_opt_parsing) @@ -260,25 +267,39 @@ class CIRGenConsumer : public clang::ASTConsumer { } } - switch (action) { - case CIRGenAction::OutputType::EmitCIR: - case CIRGenAction::OutputType::EmitCIRFlat: - if (outputStream && mlirMod) { - // FIXME: we cannot roundtrip prettyForm=true right now. - mlir::OpPrintingFlags flags; - flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false); - if (feOptions.ClangIRDisableCIRVerifier) - flags.assumeVerified(); - mlirMod->print(*outputStream, flags); - } - break; - case CIRGenAction::OutputType::EmitMLIR: { - auto loweredMlirModule = lowerFromCIRToMLIR(mlirMod, mlirCtx.get()); + auto emitMLIR = [&](mlir::Operation *mlirMod, bool verify) { + assert(mlirMod && + "MLIR module does not exist, but lowering did not fail?"); assert(outputStream && "Why are we here without an output stream?"); // FIXME: we cannot roundtrip prettyForm=true right now. mlir::OpPrintingFlags flags; flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false); - loweredMlirModule->print(*outputStream, flags); + if (!verify) + flags.assumeVerified(); + mlirMod->print(*outputStream, flags); + }; + + switch (action) { + case CIRGenAction::OutputType::EmitMLIR: { + switch (feOptions.MLIRTargetDialect) { + case clang::frontend::MLIR_CORE: + // case for direct lowering is already checked in compiler invocation + // no need to check here + emitMLIR(lowerFromCIRToMLIR(mlirMod, mlirCtx.get()), false); + break; + case clang::frontend::MLIR_LLVM: { + mlir::ModuleOp loweredMLIRModule = + feOptions.ClangIRDirectLowering + ? direct::lowerDirectlyFromCIRToLLVMDialect(mlirMod) + : lowerFromCIRToMLIRToLLVMDialect(mlirMod, mlirCtx.get()); + emitMLIR(loweredMLIRModule, false); + break; + } + case clang::frontend::MLIR_CIR: + case clang::frontend::MLIR_CIR_FLAT: + emitMLIR(mlirMod, feOptions.ClangIRDisableCIRVerifier); + break; + } break; } case CIRGenAction::OutputType::EmitLLVM: @@ -356,10 +377,6 @@ getOutputStream(CompilerInstance &ci, StringRef inFile, switch (action) { case CIRGenAction::OutputType::EmitAssembly: return ci.createDefaultOutputFile(false, inFile, "s"); - case CIRGenAction::OutputType::EmitCIR: - return ci.createDefaultOutputFile(false, inFile, "cir"); - case CIRGenAction::OutputType::EmitCIRFlat: - return ci.createDefaultOutputFile(false, inFile, "cir"); case CIRGenAction::OutputType::EmitMLIR: return ci.createDefaultOutputFile(false, inFile, "mlir"); case CIRGenAction::OutputType::EmitLLVM: @@ -456,14 +473,6 @@ void EmitAssemblyAction::anchor() {} EmitAssemblyAction::EmitAssemblyAction(mlir::MLIRContext *_MLIRContext) : CIRGenAction(OutputType::EmitAssembly, _MLIRContext) {} -void EmitCIRAction::anchor() {} -EmitCIRAction::EmitCIRAction(mlir::MLIRContext *_MLIRContext) - : CIRGenAction(OutputType::EmitCIR, _MLIRContext) {} - -void EmitCIRFlatAction::anchor() {} -EmitCIRFlatAction::EmitCIRFlatAction(mlir::MLIRContext *_MLIRContext) - : CIRGenAction(OutputType::EmitCIRFlat, _MLIRContext) {} - void EmitCIROnlyAction::anchor() {} EmitCIROnlyAction::EmitCIROnlyAction(mlir::MLIRContext *_MLIRContext) : CIRGenAction(OutputType::None, _MLIRContext) {} diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 0331122f35d2..b3aad00aadd5 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -4689,11 +4689,11 @@ void populateCIRToLLVMPasses(mlir::OpPassManager &pm, bool useCCLowering) { extern void registerCIRDialectTranslation(mlir::MLIRContext &context); -std::unique_ptr -lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp theModule, LLVMContext &llvmCtx, - bool disableVerifier, bool disableCCLowering, - bool disableDebugInfo) { - llvm::TimeTraceScope scope("lower from CIR to LLVM directly"); +mlir::ModuleOp lowerDirectlyFromCIRToLLVMDialect(mlir::ModuleOp theModule, + bool disableVerifier, + bool disableCCLowering, + bool disableDebugInfo) { + llvm::TimeTraceScope scope("lower from CIR to LLVM Dialect"); mlir::MLIRContext *mlirCtx = theModule.getContext(); mlir::PassManager pm(mlirCtx); @@ -4722,6 +4722,20 @@ lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp theModule, LLVMContext &llvmCtx, if (theModule.verify().failed()) report_fatal_error("Verification of the final LLVMIR dialect failed!"); + return theModule; +} + +std::unique_ptr +lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp theModule, LLVMContext &llvmCtx, + bool disableVerifier, bool disableCCLowering, + bool disableDebugInfo) { + llvm::TimeTraceScope scope("lower from CIR to LLVM directly"); + + lowerDirectlyFromCIRToLLVMDialect(theModule, disableVerifier, + disableCCLowering, disableDebugInfo); + + mlir::MLIRContext *mlirCtx = theModule.getContext(); + mlir::registerBuiltinDialectTranslation(*mlirCtx); mlir::registerLLVMDialectTranslation(*mlirCtx); mlir::registerOpenMPDialectTranslation(*mlirCtx); diff --git a/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp b/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp index 8a3e6227b072..75c905299bdb 100644 --- a/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp +++ b/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp @@ -47,6 +47,7 @@ #include "mlir/Transforms/DialectConversion.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "clang/CIR/LowerToLLVM.h" #include "clang/CIR/LowerToMLIR.h" #include "clang/CIR/LoweringHelpers.h" #include "clang/CIR/Passes.h" @@ -1458,13 +1459,14 @@ void ConvertCIRToMLIRPass::runOnOperation() { signalPassFailure(); } -std::unique_ptr -lowerFromCIRToMLIRToLLVMIR(mlir::ModuleOp theModule, - std::unique_ptr mlirCtx, - LLVMContext &llvmCtx) { - llvm::TimeTraceScope scope("Lower from CIR to MLIR To LLVM"); +mlir::ModuleOp lowerFromCIRToMLIRToLLVMDialect(mlir::ModuleOp theModule, + mlir::MLIRContext *mlirCtx) { + llvm::TimeTraceScope scope("Lower from CIR to MLIR To LLVM Dialect"); + if (!mlirCtx) { + mlirCtx = theModule.getContext(); + } - mlir::PassManager pm(mlirCtx.get()); + mlir::PassManager pm(mlirCtx); pm.addPass(createConvertCIRToMLIRPass()); pm.addPass(createConvertMLIRToLLVMPass()); @@ -1478,6 +1480,17 @@ lowerFromCIRToMLIRToLLVMIR(mlir::ModuleOp theModule, if (theModule.verify().failed()) report_fatal_error("Verification of the final LLVMIR dialect failed!"); + return theModule; +} + +std::unique_ptr +lowerFromCIRToMLIRToLLVMIR(mlir::ModuleOp theModule, + std::unique_ptr mlirCtx, + LLVMContext &llvmCtx) { + llvm::TimeTraceScope scope("Lower from CIR to MLIR To LLVM"); + + lowerFromCIRToMLIRToLLVMDialect(theModule, mlirCtx.get()); + mlir::registerBuiltinDialectTranslation(*mlirCtx); mlir::registerLLVMDialectTranslation(*mlirCtx); mlir::registerOpenMPDialectTranslation(*mlirCtx); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 384fd7f4f2a9..67957c7f50ba 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -413,15 +413,16 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || - (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) || + (PhaseArg = + DAL.getLastArg(options::OPT_print_enabled_extensions)) || (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || (PhaseArg = DAL.getLastArg(options::OPT__analyze)) || - (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) || - (PhaseArg = DAL.getLastArg(options::OPT_emit_cir_flat)) || + (PhaseArg = DAL.getLastArg(options::OPT_emit_mlir)) || + (PhaseArg = DAL.getLastArg(options::OPT_emit_mlir_EQ)) || (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { FinalPhase = phases::Compile; @@ -5083,10 +5084,10 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction(Input, types::TY_Remap); if (Args.hasArg(options::OPT_emit_ast)) return C.MakeAction(Input, types::TY_AST); - if (Args.hasArg(options::OPT_emit_cir)) - return C.MakeAction(Input, types::TY_CIR); - if (Args.hasArg(options::OPT_emit_cir_flat)) - return C.MakeAction(Input, types::TY_CIR_FLAT); + if (Args.hasArg(options::OPT_emit_mlir)) + return C.MakeAction(Input, types::TY_MLIR); + if (Args.hasArg(options::OPT_emit_mlir_EQ)) + return C.MakeAction(Input, types::TY_MLIR); if (Args.hasArg(options::OPT_module_file_info)) return C.MakeAction(Input, types::TY_ModuleFile); if (Args.hasArg(options::OPT_verify_pch)) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 7961007757a9..fa578bd09406 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5242,8 +5242,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (Args.hasArg(options::OPT_fclangir) || - Args.hasArg(options::OPT_emit_cir) || - Args.hasArg(options::OPT_emit_cir_flat)) + Args.hasArg(options::OPT_emit_mlir) || + Args.hasArg(options::OPT_emit_mlir_EQ)) CmdArgs.push_back("-fclangir"); Args.addOptOutFlag(CmdArgs, options::OPT_fclangir_direct_lowering, @@ -5414,10 +5414,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } else if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR) { CmdArgs.push_back("-emit-llvm"); - } else if (JA.getType() == types::TY_CIR) { - CmdArgs.push_back("-emit-cir"); - } else if (JA.getType() == types::TY_CIR_FLAT) { - CmdArgs.push_back("-emit-cir-flat"); + } else if (JA.getType() == types::TY_MLIR) { + if (Args.hasArg(options::OPT_emit_mlir)) { + if (Args.hasArg(options::OPT_fno_clangir_direct_lowering)) { + CmdArgs.push_back("-emit-mlir=core"); + } else { + CmdArgs.push_back("-emit-mlir=llvm"); + } + } else { + CmdArgs.push_back(Args.MakeArgString( + Twine("-emit-mlir=") + + Args.getLastArgValue(options::OPT_emit_mlir_EQ))); + } } else if (JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC) { // Emit textual llvm IR for AMDGPU offloading for -emit-llvm -S diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index a505b5412448..4b2a2e3d76a4 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2734,10 +2734,9 @@ static const auto &getFrontendActionTable() { {frontend::DumpTokens, OPT_dump_tokens}, {frontend::EmitAssembly, OPT_S}, {frontend::EmitBC, OPT_emit_llvm_bc}, - {frontend::EmitCIR, OPT_emit_cir}, - {frontend::EmitCIRFlat, OPT_emit_cir_flat}, {frontend::EmitCIROnly, OPT_emit_cir_only}, {frontend::EmitMLIR, OPT_emit_mlir}, + {frontend::EmitMLIR, OPT_emit_mlir_EQ}, {frontend::EmitHTML, OPT_emit_html}, {frontend::EmitLLVM, OPT_emit_llvm}, {frontend::EmitLLVMOnly, OPT_emit_llvm_only}, @@ -2849,6 +2848,13 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts, }; } + if (Opts.ProgramAction == frontend::EmitMLIR) { + GenerateProgramAction = [&]() { + if (Opts.MLIRTargetDialect == clang::frontend::MLIR_CORE) + GenerateArg(Consumer, OPT_emit_mlir_EQ, "core"); + }; + } + if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) { GenerateProgramAction = [&]() { GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix); @@ -3109,8 +3115,8 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (Opts.ProgramAction != frontend::GenerateModule && Opts.IsSystemModule) Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module" << "-emit-module"; - if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir) || - Args.hasArg(OPT_emit_cir_flat)) + if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_mlir) || + Args.hasArg(OPT_emit_mlir_EQ)) Opts.UseClangIRPipeline = true; if (Args.hasArg(OPT_fclangir_direct_lowering)) @@ -4665,8 +4671,6 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::ASTView: case frontend::EmitAssembly: case frontend::EmitBC: - case frontend::EmitCIR: - case frontend::EmitCIRFlat: case frontend::EmitCIROnly: case frontend::EmitMLIR: case frontend::EmitHTML: diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 4a54d90a6591..f97007882b14 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -54,15 +54,19 @@ CreateFrontendBaseAction(CompilerInstance &CI) { auto UseCIR = CI.getFrontendOpts().UseClangIRPipeline; auto Act = CI.getFrontendOpts().ProgramAction; auto CIRAnalysisOnly = CI.getFrontendOpts().ClangIRAnalysisOnly; - auto EmitsCIR = Act == EmitCIR || Act == EmitCIRFlat || Act == EmitCIROnly; + auto EmitsCIR = + Act == EmitCIROnly || + (Act == EmitMLIR && + (CI.getFrontendOpts().MLIRTargetDialect == frontend::MLIR_CIR || + CI.getFrontendOpts().MLIRTargetDialect == frontend::MLIR_CIR_FLAT)); if (!UseCIR && EmitsCIR) - llvm::report_fatal_error( - "-emit-cir and -emit-cir-only only valid when using -fclangir"); + llvm::report_fatal_error("emitting mlir only valid when using -fclangir"); - if (CI.getFrontendOpts().ClangIRDirectLowering && Act == EmitMLIR) - llvm::report_fatal_error( - "ClangIR direct lowering is incompatible with -emit-mlir"); + if (Act == EmitMLIR && CI.getFrontendOpts().ClangIRDirectLowering && + CI.getFrontendOpts().MLIRTargetDialect == frontend::MLIR_CORE) + llvm::report_fatal_error("ClangIR direct lowering is incompatible with " + "emitting of MLIR standard dialects"); switch (CI.getFrontendOpts().ProgramAction) { case ASTDeclList: return std::make_unique(); @@ -91,18 +95,13 @@ CreateFrontendBaseAction(CompilerInstance &CI) { return std::make_unique(); } #if CLANG_ENABLE_CIR - case EmitCIR: - return std::make_unique(); - case EmitCIRFlat: - return std::make_unique(); case EmitCIROnly: return std::make_unique(); case EmitMLIR: return std::make_unique(); #else - case EmitCIR: - case EmitCIRFlat: case EmitCIROnly: + case EmitMLIR: llvm_unreachable("CIR suppport not built into clang"); #endif case EmitHTML: return std::make_unique(); diff --git a/clang/test/CIR/Lowering/ThroughMLIR/binop.cpp b/clang/test/CIR/Lowering/ThroughMLIR/binop.cpp index 7f3c8b98cfd1..83ef9c3d1411 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/binop.cpp +++ b/clang/test/CIR/Lowering/ThroughMLIR/binop.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s void testSignedIntBinOps(int a, int b) { diff --git a/clang/test/CIR/Lowering/ThroughMLIR/bit.c b/clang/test/CIR/Lowering/ThroughMLIR/bit.c index 7d21f991215a..b3acc49c5f69 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/bit.c +++ b/clang/test/CIR/Lowering/ThroughMLIR/bit.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s int clz_u16(unsigned short x) { diff --git a/clang/test/CIR/Lowering/ThroughMLIR/call.c b/clang/test/CIR/Lowering/ThroughMLIR/call.c index a325db5f2dd4..3edb7bc83cdc 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/call.c +++ b/clang/test/CIR/Lowering/ThroughMLIR/call.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s void foo(int i) {} diff --git a/clang/test/CIR/Lowering/ThroughMLIR/cmp.cpp b/clang/test/CIR/Lowering/ThroughMLIR/cmp.cpp index 607f8ad5005f..e5b2f0cb109f 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/cmp.cpp +++ b/clang/test/CIR/Lowering/ThroughMLIR/cmp.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s bool testSignedIntCmpOps(int a, int b) { diff --git a/clang/test/CIR/Lowering/ThroughMLIR/doWhile.c b/clang/test/CIR/Lowering/ThroughMLIR/doWhile.c index 5974734740a2..2a4adb1f0091 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/doWhile.c +++ b/clang/test/CIR/Lowering/ThroughMLIR/doWhile.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s int sum() { diff --git a/clang/test/CIR/Lowering/ThroughMLIR/for.cpp b/clang/test/CIR/Lowering/ThroughMLIR/for.cpp index 3ed99718369a..2a6137a0cdc3 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/for.cpp +++ b/clang/test/CIR/Lowering/ThroughMLIR/for.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s int a[101], b[101]; diff --git a/clang/test/CIR/Lowering/ThroughMLIR/global.cpp b/clang/test/CIR/Lowering/ThroughMLIR/global.cpp index d7627139ff6c..a79707746eff 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/global.cpp +++ b/clang/test/CIR/Lowering/ThroughMLIR/global.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s float f[32000]; diff --git a/clang/test/CIR/Lowering/ThroughMLIR/if.c b/clang/test/CIR/Lowering/ThroughMLIR/if.c index dec3f9968d6a..a7d95d3a104a 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/if.c +++ b/clang/test/CIR/Lowering/ThroughMLIR/if.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s void foo() { diff --git a/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp b/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp index 81c9fe063260..fb5bdae0b69a 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp +++ b/clang/test/CIR/Lowering/ThroughMLIR/vectype.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s typedef int vi4 __attribute__((vector_size(16))); diff --git a/clang/test/CIR/Lowering/ThroughMLIR/while.c b/clang/test/CIR/Lowering/ThroughMLIR/while.c index 68454f3bea99..983be1b1d1ea 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/while.c +++ b/clang/test/CIR/Lowering/ThroughMLIR/while.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s void singleWhile() { diff --git a/clang/test/CIR/cc1.c b/clang/test/CIR/cc1.c index 176ea42d44de..5461562e09f6 100644 --- a/clang/test/CIR/cc1.c +++ b/clang/test/CIR/cc1.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir %s -o %t.mlir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir=core %s -o %t.mlir // RUN: FileCheck --input-file=%t.mlir %s -check-prefix=MLIR // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM diff --git a/clang/test/CIR/emit-mlir.c b/clang/test/CIR/emit-mlir.c new file mode 100644 index 000000000000..fc7b04809352 --- /dev/null +++ b/clang/test/CIR/emit-mlir.c @@ -0,0 +1,44 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-mlir %s -o - | FileCheck %s -check-prefix=LLVM +// RUN: %clang -target x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir %s -o - | FileCheck %s -check-prefix=CORE + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=llvm %s -o - | FileCheck %s -check-prefix=LLVM +// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=core %s -o - 2>&1 | FileCheck %s -check-prefix=CORE_ERR + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir=llvm %s -o - | FileCheck %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir=core %s -o - | FileCheck %s -check-prefix=CORE + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=cir %s -o - | FileCheck %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-mlir=cir-flat %s -o - | FileCheck %s -check-prefix=CIR_FLAT + +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-mlir %s -o - | FileCheck %s -check-prefix=LLVM +// RUN: %clang -target x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir %s -o - | FileCheck %s -check-prefix=CORE + +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-mlir %s -o - -### 2>&1 | FileCheck %s -check-prefix=OPTS_LLVM +// RUN: %clang -target x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir %s -o - -### 2>&1 | FileCheck %s -check-prefix=OPTS_CORE + +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-mlir=llvm %s -o - -### 2>&1 | FileCheck %s -check-prefix=OPTS_LLVM +// RUN: %clang -target x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir=core %s -o - -### 2>&1 | FileCheck %s -check-prefix=OPTS_CORE +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-mlir=cir %s -o - -### 2>&1 | FileCheck %s -check-prefix=OPTS_CIR +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-mlir=cir-flat %s -o - -### 2>&1 | FileCheck %s -check-prefix=OPTS_CIR_FLAT + +int foo(int a, int b) { + int c; + if (a) { + c = a; + } + c = b; + return c; +} + +// LLVM: llvm.func @foo +// CORE: func.func @foo +// CIR: cir.func @foo +// CIR: cir.scope +// CIR_FLAT: cir.func @foo +// CIR_FLAT: ^bb1 +// CIR_FLAT-NOT: cir.scope +// CORE_ERR: ClangIR direct lowering is incompatible with emitting of MLIR standard dialects +// OPTS_LLVM: "-emit-mlir=llvm" +// OPTS_CORE: "-emit-mlir=core" +// OPTS_CIR: "-emit-mlir=cir" +// OPTS_CIR_FLAT: "-emit-mlir=cir-flat" diff --git a/clang/test/CIR/mlirprint.c b/clang/test/CIR/mlirprint.c index 3514eb895381..a28e4e851992 100644 --- a/clang/test/CIR/mlirprint.c +++ b/clang/test/CIR/mlirprint.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -mmlir --mlir-print-ir-after-all %s -o %t.cir 2>&1 | FileCheck %s -check-prefix=CIR // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir-flat -mmlir --mlir-print-ir-after-all %s -o %t.cir 2>&1 | FileCheck %s -check-prefix=CIRFLAT -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir -mmlir --mlir-print-ir-after-all %s -o %t.cir 2>&1 | FileCheck %s -check-prefix=CIRMLIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fno-clangir-direct-lowering -emit-mlir=core -mmlir --mlir-print-ir-after-all %s -o %t.cir 2>&1 | FileCheck %s -check-prefix=CIRMLIR // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -mmlir --mlir-print-ir-after-all -mllvm -print-after-all %s -o %t.ll 2>&1 | FileCheck %s -check-prefix=CIR -check-prefix=LLVM // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -mmlir --mlir-print-ir-after=cir-drop-ast %s -o %t.cir 2>&1 | FileCheck %s -check-prefix=CIRPASS // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir-flat -mmlir --mlir-print-ir-before=cir-flatten-cfg %s -o %t.cir 2>&1 | FileCheck %s -check-prefix=CFGPASS