awarzynski created this revision. awarzynski added reviewers: rovka, clementval, schweitz, Leporacanthicus. Herald added subscribers: Chia-hungDuan, mehdi_amini, dang, rriddle, pengfei, kristof.beyls, mgorny. Herald added a reviewer: sscalpone. Herald added a project: Flang. awarzynski requested review of this revision. Herald added subscribers: cfe-commits, stephenneuendorffer, jdoerfert. Herald added a project: clang.
This patch adds support for: - `-S` in Flang's compiler and frontend drivers and implements (these options were already available as placeholders): - `-emit-obj` in Flang's frontend driver and `-c` in Flang's compiler driver The semantics of these options in Clang and Flang are identical. The `EmitObjAction` frontend action is renamed as `BackendAction`. The new name more accurately reflects the fact that this action will primarily run the code-gen/backend pipeline in LLVM. It also makes more sense as an action implementing both `-emit-obj` and `-S` (originally it was just `-emit-obj`). `tripleName` in FirContext.cpp is updated from `fir.triple` to `llvm.target_triple`. The former was effectively ignored. The latter is used when lowering from the LLVM dialect in MLIR to LLVM IR (i.e. it's embedded in the generated LLVM IR module). The driver can then re-use that when configuring the backend. With this change, the LLVM IR files generated by e.g. `tco` will from now on contain the correct target triple. The code-gen.f90 test is replaced with code-gen-x86.f90 and code-gen-aarch64.f90. With 2 seperate files we can verify that `--target` is correctly taken into account. LIT configuration is updated to enable e.g.: ! REQUIRES: aarch64-registered-target Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D120568 Files: clang/include/clang/Driver/Options.td flang/include/flang/Frontend/FrontendActions.h flang/include/flang/Frontend/FrontendOptions.h flang/lib/Frontend/CMakeLists.txt flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Frontend/FrontendActions.cpp flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp flang/lib/Optimizer/Support/FIRContext.cpp flang/test/CMakeLists.txt flang/test/Driver/code-gen-aarch64.f90 flang/test/Driver/code-gen-x86.f90 flang/test/Driver/code-gen.f90 flang/test/Driver/driver-help-hidden.f90 flang/test/Driver/driver-help.f90 flang/test/Driver/emit-asm-aarch64.f90 flang/test/Driver/emit-asm-x86.f90 flang/test/Driver/syntax-only.f90 flang/test/Fir/target-rewrite-triple.fir flang/test/lit.cfg.py flang/test/lit.site.cfg.py.in flang/tools/flang-driver/fc1_main.cpp flang/unittests/Frontend/CMakeLists.txt flang/unittests/Frontend/FrontendActionTest.cpp
Index: flang/unittests/Frontend/FrontendActionTest.cpp =================================================================== --- flang/unittests/Frontend/FrontendActionTest.cpp +++ flang/unittests/Frontend/FrontendActionTest.cpp @@ -11,6 +11,7 @@ #include "flang/Frontend/FrontendOptions.h" #include "flang/FrontendTool/Utils.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" @@ -188,4 +189,35 @@ EXPECT_TRUE(llvm::StringRef(outputFileBuffer.data()) .contains("define void @_QQmain()")); } + +TEST_F(FrontendActionTest, EmitAsm) { + // Populate the input file with the pre-defined input and flush it. + *(inputFileOs_) << "end program"; + inputFileOs_.reset(); + + // Set-up the action kind. + compInst_.invocation().frontendOpts().programAction = EmitAssembly; + compInst_.invocation().preprocessorOpts().noReformat = true; + + // Initialise LLVM backend + llvm::InitializeAllTargets(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmPrinters(); + + // Set-up the output stream. We are using output buffer wrapped as an output + // stream, as opposed to an actual file (or a file descriptor). + llvm::SmallVector<char, 256> outputFileBuffer; + std::unique_ptr<llvm::raw_pwrite_stream> outputFileStream( + new llvm::raw_svector_ostream(outputFileBuffer)); + compInst_.set_outputStream(std::move(outputFileStream)); + + // Execute the action. + bool success = ExecuteCompilerInvocation(&compInst_); + + // Validate the expected output. + EXPECT_TRUE(success); + EXPECT_TRUE(!outputFileBuffer.empty()); + + EXPECT_TRUE(llvm::StringRef(outputFileBuffer.data()).contains("_QQmain")); +} } // namespace Index: flang/unittests/Frontend/CMakeLists.txt =================================================================== --- flang/unittests/Frontend/CMakeLists.txt +++ flang/unittests/Frontend/CMakeLists.txt @@ -1,3 +1,7 @@ +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} +) + add_flang_unittest(FlangFrontendTests CompilerInstanceTest.cpp FrontendActionTest.cpp Index: flang/tools/flang-driver/fc1_main.cpp =================================================================== --- flang/tools/flang-driver/fc1_main.cpp +++ flang/tools/flang-driver/fc1_main.cpp @@ -20,6 +20,7 @@ #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" +#include "llvm/Support/TargetSelect.h" #include <cstdio> @@ -48,6 +49,11 @@ bool success = CompilerInvocation::CreateFromArgs(flang->invocation(), argv, diags); + // Initialize targets first, so that --version shows registered targets. + llvm::InitializeAllTargets(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmPrinters(); + diagsBuffer->FlushDiagnostics(flang->diagnostics()); if (!success) Index: flang/test/lit.site.cfg.py.in =================================================================== --- flang/test/lit.site.cfg.py.in +++ flang/test/lit.site.cfg.py.in @@ -18,6 +18,7 @@ config.flang_standalone_build = @FLANG_STANDALONE_BUILD@ config.has_plugins = @LLVM_ENABLE_PLUGINS@ config.cc = "@CMAKE_C_COMPILER@" +config.targets_to_build = "@TARGETS_TO_BUILD@" # Support substitution of the tools_dir with user parameters. This is # used when we can't determine the tool dir at configuration time. Index: flang/test/lit.cfg.py =================================================================== --- flang/test/lit.cfg.py +++ flang/test/lit.cfg.py @@ -39,6 +39,11 @@ llvm_config.feature_config( [('--assertion-mode', {'ON': 'asserts'})]) +# Targets +config.targets = frozenset(config.targets_to_build.split()) +for arch in config.targets_to_build.split(): + config.available_features.add(arch.lower() + '-registered-target') + # excludes: A list of directories to exclude from the testsuite. The 'Inputs' # subdirectories contain auxiliary inputs for various tests in their parent # directories. Index: flang/test/Fir/target-rewrite-triple.fir =================================================================== --- flang/test/Fir/target-rewrite-triple.fir +++ flang/test/Fir/target-rewrite-triple.fir @@ -1,10 +1,10 @@ // RUN: fir-opt --target-rewrite %s | FileCheck %s --check-prefix=UNCHANGED // RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s --check-prefix=CHANGED -// UNCHANGED: fir.triple = "aarch64-unknown-linux-gnu" -// CHANGED: fir.triple = "x86_64-unknown-linux-gnu" -// CHANGED-NOT: fir.triple = "aarch64-unknown-linux-gnu" -module attributes {fir.triple = "aarch64-unknown-linux-gnu"} { +// UNCHANGED: llvm.target_triple = "aarch64-unknown-linux-gnu" +// CHANGED: llvm.target_triple = "x86_64-unknown-linux-gnu" +// CHANGED-NOT: llvm.target_triple = "aarch64-unknown-linux-gnu" +module attributes {llvm.target_triple = "aarch64-unknown-linux-gnu"} { func @dummyfunc() -> () { return } Index: flang/test/Driver/syntax-only.f90 =================================================================== --- flang/test/Driver/syntax-only.f90 +++ flang/test/Driver/syntax-only.f90 @@ -13,14 +13,15 @@ ! RUN: %flang -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty ! RUN: %flang_fc1 %s 2>&1 | FileCheck %s --allow-empty -! RUN: not %flang %s 2>&1 | FileCheck %s --check-prefix=NO_FSYNTAX_ONLY -! RUN: not %flang_fc1 -emit-obj %s 2>&1 | FileCheck %s --check-prefix=NO_FSYNTAX_ONLY +! RUN: rm -rf %t/non-existent-dir/ +! RUN: not %flang -c %s -o %t/non-existent-dir/syntax-only.o 2>&1 | FileCheck %s --check-prefix=NO_FSYNTAX_ONLY +! RUN: not %flang_fc1 -emit-obj %s -o %t/non-existent-dir/syntax-only.o 2>&1 | FileCheck %s --check-prefix=NO_FSYNTAX_ONLY !----------------- ! EXPECTED OUTPUT !----------------- ! CHECK-NOT: error -! NO_FSYNTAX_ONLY: error: code-generation is not available yet +! NO_FSYNTAX_ONLY: error: failed to create the output file !------- ! INPUT Index: flang/test/Driver/emit-asm-x86.f90 =================================================================== --- /dev/null +++ flang/test/Driver/emit-asm-x86.f90 @@ -0,0 +1,21 @@ +! Test -S (X86) + +! REQUIRES: x86-registered-target + +!------------- +! RUN COMMANDS +!------------- +! RUN: %flang_fc1 -S -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s +! RUN: %flang -S -target x86_64-unknown-linux-gnu %s -o - | FileCheck %s + +!---------------- +! EXPECTED OUTPUT +!---------------- +! CHECK-LABEL: _QQmain: +! CHECK-NEXT: .Lfunc_begin0: +! CHECK: ret + +!------ +! INPUT +!------ +end program Index: flang/test/Driver/emit-asm-aarch64.f90 =================================================================== --- /dev/null +++ flang/test/Driver/emit-asm-aarch64.f90 @@ -0,0 +1,21 @@ +! Test -S (AArch64) + +! REQUIRES: aarch64-registered-target + +!------------- +! RUN COMMANDS +!------------- +! RUN: %flang_fc1 -S -triple aarch64-unknown-linux-gnu %s -o - | FileCheck %s +! RUN: %flang -S -target aarch64-unknown-linux-gnu %s -o - | FileCheck %s + +!---------------- +! EXPECTED OUTPUT +!---------------- +! CHECK-LABEL: _QQmain: +! CHECK-NEXT: .Lfunc_begin0: +! CHECK: ret + +!------ +! INPUT +!------ +end program Index: flang/test/Driver/driver-help.f90 =================================================================== --- flang/test/Driver/driver-help.f90 +++ flang/test/Driver/driver-help.f90 @@ -55,6 +55,7 @@ ! HELP-NEXT: -print-target-triple Print the normalized target triple ! HELP-NEXT: -P Disable linemarker output in -E mode ! HELP-NEXT: -std=<value> Language standard to compile for +! HELP-NEXT: -S Only run preprocess and compilation steps ! HELP-NEXT: --target=<value> Generate code for the given target ! HELP-NEXT: -U <macro> Undefine macro <macro> ! HELP-NEXT: --version Print version information @@ -127,6 +128,7 @@ ! HELP-FC1-NEXT: -plugin <name> Use the named plugin action instead of the default action (use "help" to list available options) ! HELP-FC1-NEXT: -P Disable linemarker output in -E mode ! HELP-FC1-NEXT: -std=<value> Language standard to compile for +! HELP-FC1-NEXT: -S Only run preprocess and compilation steps ! HELP-FC1-NEXT: -test-io Run the InputOuputTest action. Use for development and testing only. ! HELP-FC1-NEXT: -triple <value> Specify target triple (e.g. i686-apple-darwin9) ! HELP-FC1-NEXT: -U <macro> Undefine macro <macro> Index: flang/test/Driver/driver-help-hidden.f90 =================================================================== --- flang/test/Driver/driver-help-hidden.f90 +++ flang/test/Driver/driver-help-hidden.f90 @@ -55,6 +55,7 @@ ! CHECK-NEXT: -print-target-triple Print the normalized target triple ! CHECK-NEXT: -P Disable linemarker output in -E mode ! CHECK-NEXT: -std=<value> Language standard to compile for +! CHECK-NEXT: -S Only run preprocess and compilation steps ! CHECK-NEXT: --target=<value> Generate code for the given target ! CHECK-NEXT: -U <macro> Undefine macro <macro> ! CHECK-NEXT: --version Print version information Index: flang/test/Driver/code-gen.f90 =================================================================== --- flang/test/Driver/code-gen.f90 +++ /dev/null @@ -1,19 +0,0 @@ -! Although code-generation is not yet available, we do have frontend actions -! that correspond to `-c` and `-emit-obj`. For now these actions are just a -! placeholder and running them leads to a driver error. This test makes sure -! that these actions are indeed run (rather than `-c` or `-emit-obj` being -! rejected earlier). -! TODO: Replace this file with a proper test once code-generation is available. - -!----------- -! RUN LINES -!----------- -! RUN: not %flang %s 2>&1 | FileCheck %s --check-prefix=ERROR -! RUN: not %flang -c %s 2>&1 | FileCheck %s --check-prefix=ERROR -! RUN: not %flang -emit-obj %s 2>&1 | FileCheck %s --check-prefix=ERROR -! RUN: not %flang -fc1 -emit-obj %s 2>&1 | FileCheck %s --check-prefix=ERROR - -!----------------------- -! EXPECTED OUTPUT -!----------------------- -! ERROR: code-generation is not available yet Index: flang/test/Driver/code-gen-x86.f90 =================================================================== --- /dev/null +++ flang/test/Driver/code-gen-x86.f90 @@ -0,0 +1,32 @@ +! Test -emit-obj (X86) + +! REQUIRES: x86-registered-target, aarch64-registered-target +! UNSUPPORTED: darwin, macos + +!------------- +! RUN COMMANDS +!------------- +! RUN: rm -f %t.o +! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-obj %s -o %t.o +! RUN: llvm-objdump --triple x86_64-unknown-linux-gnu --disassemble-all %t.o | FileCheck %s --check-prefix=CORRECT_TRIPLE +! RUN: rm -f %t.o +! RUN: %flang --target=x86_64-unknown-linux-gnu -c %s -o %t.o +! RUN: llvm-objdump --triple x86_64-unknown-linux-gnu --disassemble-all %t.o | FileCheck %s --check-prefix=CORRECT_TRIPLE + +! RUN: %flang -c --target=x86_64-unknown-linux-gnu %s -o %t.o +! RUN: llvm-objdump --triple aarch64-unknown-linux-gnu --disassemble-all %t.o | FileCheck %s --check-prefix=INCORRECT_TRIPLE + +!---------------- +! EXPECTED OUTPUT +!---------------- +! CORRECT_TRIPLE-LABEL: <_QQmain>: +! CORRECT_TRIPLE-NEXT: retq + +! When incorrect triple is used to disassemble, there won't be a ret(q) instruction at all. +! INCORRECT_TRIPLE-LABEL: <_QQmain>: +! INCORRECT_TRIPLE-NOT: ret + +!------ +! INPUT +!------ +end program Index: flang/test/Driver/code-gen-aarch64.f90 =================================================================== --- /dev/null +++ flang/test/Driver/code-gen-aarch64.f90 @@ -0,0 +1,31 @@ +! Test -emit-obj (X86) + +! REQUIRES: aarch64-registered-target, x86-registered-target + +!------------- +! RUN COMMANDS +!------------- +! RUN: rm -f %t.o +! RUN: %flang_fc1 -emit-obj -triple aarch64-unknown-linux-gnu %s -o %t.o +! RUN: llvm-objdump --triple aarch64-unknown-linux-gnu --disassemble-all %t.o | FileCheck %s --check-prefix=CORRECT_TRIPLE +! RUN: rm -f %t.o +! RUN: %flang -c --target=aarch64-unknown-linux-gnu %s -o %t.o +! RUN: llvm-objdump --triple aarch64-unknown-linux-gnu --disassemble-all %t.o | FileCheck %s --check-prefix=CORRECT_TRIPLE + +! RUN: %flang -c --target=aarch64-unknown-linux-gnu %s -o %t.o +! RUN: llvm-objdump --triple x86_64-unknown-linux-gnu --disassemble-all %t.o | FileCheck %s --check-prefix=INCORRECT_TRIPLE + +!---------------- +! EXPECTED OUTPUT +!---------------- +! CORRECT_TRIPLE-LABEL: <_QQmain>: +! CORRECT_TRIPLE-NEXT: ret + +! When incorrect triple is used to disassemble, there won't be a ret instruction at all. +! INCORRECT_TRIPLE-LABEL: <_QQmain>: +! INCORRECT_TRIPLE-NOT: ret + +!------ +! INPUT +!------ +end program Index: flang/test/CMakeLists.txt =================================================================== --- flang/test/CMakeLists.txt +++ flang/test/CMakeLists.txt @@ -46,7 +46,7 @@ flang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py) set(FLANG_TEST_DEPENDS - flang-new llvm-config FileCheck count not module_files fir-opt tco bbc + flang-new llvm-config FileCheck count not module_files fir-opt tco bbc llvm-objdump ) if (FLANG_INCLUDE_TESTS) Index: flang/lib/Optimizer/Support/FIRContext.cpp =================================================================== --- flang/lib/Optimizer/Support/FIRContext.cpp +++ flang/lib/Optimizer/Support/FIRContext.cpp @@ -16,7 +16,7 @@ #include "mlir/IR/BuiltinOps.h" #include "llvm/Support/Host.h" -static constexpr const char *tripleName = "fir.triple"; +static constexpr const char *tripleName = "llvm.target_triple"; void fir::setTargetTriple(mlir::ModuleOp mod, llvm::StringRef triple) { auto target = fir::determineTargetTriple(triple); Index: flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -38,7 +38,11 @@ case EmitLLVM: return std::make_unique<EmitLLVMAction>(); case EmitObj: - return std::make_unique<EmitObjAction>(); + return std::make_unique<BackendAction>( + BackendAction::BackendActionTy::Backend_EmitObj); + case EmitAssembly: + return std::make_unique<BackendAction>( + BackendAction::BackendActionTy::Backend_EmitAssembly); case DebugUnparse: return std::make_unique<DebugUnparseAction>(); case DebugUnparseNoSema: Index: flang/lib/Frontend/FrontendActions.cpp =================================================================== --- flang/lib/Frontend/FrontendActions.cpp +++ flang/lib/Frontend/FrontendActions.cpp @@ -31,11 +31,16 @@ #include "mlir/Pass/PassManager.h" #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "llvm/ADT/StringRef.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetMachine.h" #include <clang/Basic/Diagnostic.h> #include <memory> using namespace Fortran::frontend; +using namespace llvm; //===----------------------------------------------------------------------===// // Custom BeginSourceFileAction @@ -417,7 +422,6 @@ pm.addPass(std::make_unique<Fortran::lower::VerifierPass>()); pm.enableVerifier(/*verifyPasses=*/true); - mlir::PassPipelineCLParser passPipeline("", "Compiler passes to run"); // Create the pass pipeline fir::createMLIRToLLVMPassPipeline(pm); @@ -490,11 +494,85 @@ mlirModule->print(*os); } -void EmitObjAction::ExecuteAction() { +void BackendAction::ExecuteAction() { CompilerInstance &ci = this->instance(); - unsigned DiagID = ci.diagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Error, "code-generation is not available yet"); - ci.diagnostics().Report(DiagID); + // Generate an LLVM module if it's not already present (it will already be + // present if the input file is an LLVM IR/BC file). + if (!llvmModule) + GenerateLLVMIR(); + + // Create `Target` + std::string error; + std::string theTriple = llvmModule->getTargetTriple(); + const llvm::Target *theTarget = + TargetRegistry::lookupTarget(theTriple, error); + assert(theTarget && "Failed to create Target"); + + // Create `TargetMachine` + std::unique_ptr<TargetMachine> TM; + TM.reset(theTarget->createTargetMachine( + theTriple, /*CPU=*/"", /*Features=*/"", llvm::TargetOptions(), None)); + llvmModule->setDataLayout(TM->createDataLayout()); + assert(TM && "Failed to create TargetMachine"); + + // If the output stream is a file, generate it and define the corresponding + // output stream. If a pre-defined output stream is available, we will use + // that instead. + // + // NOTE: `os` is a smart pointer that will be destroyed at the end of this + // method. However, it won't be written to until `CodeGenPasses` is + // destroyed. By defining `os` before `CodeGenPasses`, we make sure that the + // output stream won't be destroyed before it is written to. This only + // applies when an output file is used (i.e. there is no pre-defined output + // stream). + // TODO: Revisit once the new PM is ready (i.e. when `CodeGenPasses` is + // updated to use it). + std::unique_ptr<llvm::raw_pwrite_stream> os; + if (ci.IsOutputStreamNull()) { + // Get the output buffer/file + switch (action) { + case BackendActionTy::Backend_EmitAssembly: + os = ci.CreateDefaultOutputFile( + /*Binary=*/false, /*InFile=*/GetCurrentFileOrBufferName(), "s"); + break; + case BackendActionTy::Backend_EmitObj: + os = ci.CreateDefaultOutputFile( + /*Binary=*/true, /*InFile=*/GetCurrentFileOrBufferName(), "o"); + break; + } + if (!os) { + unsigned diagID = ci.diagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "failed to create the output file"); + ci.diagnostics().Report(diagID); + return; + } + } + + // Create an LLVM code-gen pass pipeline. Currently only the legacy pass + // manager is supported. + // TODO: Switch to the new PM once it's available in the backend. + legacy::PassManager CodeGenPasses; + CodeGenPasses.add(createTargetTransformInfoWrapperPass(TargetIRAnalysis())); + Triple triple(llvmModule->getTargetTriple()); + std::unique_ptr<llvm::TargetLibraryInfoImpl> TLII = + std::make_unique<llvm::TargetLibraryInfoImpl>(triple); + CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); + + llvm::CodeGenFileType cgft = (action == BackendActionTy::Backend_EmitAssembly) + ? llvm::CodeGenFileType::CGFT_AssemblyFile + : llvm::CodeGenFileType::CGFT_ObjectFile; + if (TM->addPassesToEmitFile(CodeGenPasses, + ci.IsOutputStreamNull() ? *os : ci.GetOutputStream(), nullptr, + cgft)) { + unsigned diagID = + ci.diagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, + "emission of this file type is not supported"); + ci.diagnostics().Report(diagID); + return; + } + + // Run the code-gen passes + CodeGenPasses.run(*llvmModule); } void InitOnlyAction::ExecuteAction() { Index: flang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- flang/lib/Frontend/CompilerInvocation.cpp +++ flang/lib/Frontend/CompilerInvocation.cpp @@ -153,6 +153,9 @@ case clang::driver::options::OPT_emit_obj: opts.programAction = EmitObj; break; + case clang::driver::options::OPT_S: + opts.programAction = EmitAssembly; + break; case clang::driver::options::OPT_fdebug_unparse: opts.programAction = DebugUnparse; break; Index: flang/lib/Frontend/CMakeLists.txt =================================================================== --- flang/lib/Frontend/CMakeLists.txt +++ flang/lib/Frontend/CMakeLists.txt @@ -25,6 +25,7 @@ FortranLower clangBasic clangDriver + LLVMAnalysis FIRDialect FIRSupport FIRBuilder Index: flang/include/flang/Frontend/FrontendOptions.h =================================================================== --- flang/include/flang/Frontend/FrontendOptions.h +++ flang/include/flang/Frontend/FrontendOptions.h @@ -40,6 +40,9 @@ /// Emit a .o file. EmitObj, + /// Emit a .s file. + EmitAssembly, + /// Parse, unparse the parse-tree and output a Fortran source file DebugUnparse, Index: flang/include/flang/Frontend/FrontendActions.h =================================================================== --- flang/include/flang/Frontend/FrontendActions.h +++ flang/include/flang/Frontend/FrontendActions.h @@ -188,8 +188,19 @@ void ExecuteAction() override; }; -class EmitObjAction : public CodeGenAction { +class BackendAction : public CodeGenAction { +public: + enum class BackendActionTy { + Backend_EmitAssembly, ///< Emit native assembly files + Backend_EmitObj ///< Emit native object files + }; + + BackendAction(BackendActionTy act) : action{act} {}; + +private: void ExecuteAction() override; + + BackendActionTy action; }; } // namespace Fortran::frontend Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -750,7 +750,7 @@ "name matches the given POSIX regular expression">; def R_Joined : Joined<["-"], "R">, Group<R_Group>, Flags<[CC1Option, CoreOption]>, MetaVarName<"<remark>">, HelpText<"Enable the specified remark">; -def S : Flag<["-"], "S">, Flags<[NoXarchOption,CC1Option]>, Group<Action_Group>, +def S : Flag<["-"], "S">, Flags<[NoXarchOption,CC1Option,FlangOption,FC1Option]>, Group<Action_Group>, HelpText<"Only run preprocess and compilation steps">; def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>, MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits