Author: Andrzej Warzynski Date: 2022-04-13T10:19:56Z New Revision: dd56939a4b04072a449a05701373e95d00cc494f
URL: https://github.com/llvm/llvm-project/commit/dd56939a4b04072a449a05701373e95d00cc494f DIFF: https://github.com/llvm/llvm-project/commit/dd56939a4b04072a449a05701373e95d00cc494f.diff LOG: [flang][driver] Add support for generating LLVM bytecode files Support for generating LLVM BC files is added in Flang's compiler and frontend drivers. This requires the `BitcodeWriterPass` pass to be run on the input LLVM IR module and is implemented as a dedicated frontend aciton. The new functionality as seen by the user (compiler driver): ``` flang-new -c -emit-llvm file.90 ``` or (frontend driver): ``` flang-new -fc1 -emit-llvm-bc file.f90 ``` The new behaviour is consistent with `clang` and `clang -cc1`. Differential Revision: https://reviews.llvm.org/D123211 Added: flang/test/Driver/emit-llvm-bc.f90 Modified: 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/test/CMakeLists.txt flang/test/Driver/driver-help.f90 Removed: ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9ffc79a52b0ed..483f0cc549ab4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5678,8 +5678,6 @@ def emit_header_unit : Flag<["-"], "emit-header-unit">, HelpText<"Generate C++20 header units from header files">; def emit_pch : Flag<["-"], "emit-pch">, HelpText<"Generate pre-compiled header file">; -def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">, - HelpText<"Build ASTs then convert to LLVM, emit .bc file">; def emit_llvm_only : Flag<["-"], "emit-llvm-only">, HelpText<"Build ASTs and convert to LLVM, discarding output">; def emit_codegen_only : Flag<["-"], "emit-codegen-only">, @@ -6143,6 +6141,8 @@ def emit_obj : Flag<["-"], "emit-obj">, HelpText<"Emit native object files">; def init_only : Flag<["-"], "init-only">, HelpText<"Only execute frontend initialization">; +def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">, + HelpText<"Build ASTs then convert to LLVM, emit .bc file">; } // let Group = Action_Group diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h index 34cabea590485..48836c6d41e21 100644 --- a/flang/include/flang/Frontend/FrontendActions.h +++ b/flang/include/flang/Frontend/FrontendActions.h @@ -192,6 +192,10 @@ class EmitLLVMAction : public CodeGenAction { void ExecuteAction() override; }; +class EmitLLVMBitcodeAction : public CodeGenAction { + void ExecuteAction() override; +}; + class BackendAction : public CodeGenAction { public: enum class BackendActionTy { diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h index 5d97580af5a56..d0459e4bf06ff 100644 --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/include/flang/Frontend/FrontendOptions.h @@ -37,6 +37,9 @@ enum ActionKind { /// Emit an .ll file EmitLLVM, + /// Emit a .bc file + EmitLLVMBitcode, + /// Emit a .o file. EmitObj, diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt index d6520e705dc9f..45692a5342094 100644 --- a/flang/lib/Frontend/CMakeLists.txt +++ b/flang/lib/Frontend/CMakeLists.txt @@ -32,6 +32,7 @@ add_flang_library(flangFrontend FIRBuilder FIRCodeGen FIRTransforms + LLVMPasses MLIRTransforms MLIRLLVMToLLVMIRTranslation MLIRSCFToControlFlow diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index d1f427a15005f..ea5accd76bca2 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -148,6 +148,9 @@ static bool ParseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args, case clang::driver::options::OPT_emit_llvm: opts.programAction = EmitLLVM; break; + case clang::driver::options::OPT_emit_llvm_bc: + opts.programAction = EmitLLVMBitcode; + break; case clang::driver::options::OPT_emit_obj: opts.programAction = EmitObj; break; diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index e30f6af7d489a..e93781e87fe00 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -33,6 +33,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Passes/PassBuilder.h" @@ -472,6 +473,48 @@ void EmitLLVMAction::ExecuteAction() { llvmModule->print(*os, /*AssemblyAnnotationWriter=*/nullptr); } +void EmitLLVMBitcodeAction::ExecuteAction() { + CompilerInstance &ci = this->instance(); + // 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 and configure `Target` + std::string error; + std::string theTriple = llvmModule->getTargetTriple(); + const llvm::Target *theTarget = + llvm::TargetRegistry::lookupTarget(theTriple, error); + assert(theTarget && "Failed to create Target"); + + // Create and configure `TargetMachine` + std::unique_ptr<llvm::TargetMachine> TM( + theTarget->createTargetMachine(theTriple, /*CPU=*/"", + /*Features=*/"", llvm::TargetOptions(), llvm::None)); + assert(TM && "Failed to create TargetMachine"); + llvmModule->setDataLayout(TM->createDataLayout()); + + // Generate an output file + std::unique_ptr<llvm::raw_ostream> os = ci.CreateDefaultOutputFile( + /*Binary=*/true, /*InFile=*/GetCurrentFileOrBufferName(), "bc"); + if (!os) { + unsigned diagID = ci.diagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "failed to create the output file"); + ci.diagnostics().Report(diagID); + return; + } + + // Set-up the pass manager + llvm::ModulePassManager MPM; + llvm::ModuleAnalysisManager MAM; + llvm::PassBuilder PB(TM.get()); + PB.registerModuleAnalyses(MAM); + MPM.addPass(llvm::BitcodeWriterPass(*os)); + + // Run the passes + MPM.run(*llvmModule, MAM); +} + void EmitMLIRAction::ExecuteAction() { CompilerInstance &ci = this->instance(); diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 0f91d6e1a44b0..04e00e5187817 100644 --- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -37,6 +37,8 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction( return std::make_unique<EmitMLIRAction>(); case EmitLLVM: return std::make_unique<EmitLLVMAction>(); + case EmitLLVMBitcode: + return std::make_unique<EmitLLVMBitcodeAction>(); case EmitObj: return std::make_unique<BackendAction>( BackendAction::BackendActionTy::Backend_EmitObj); diff --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt index cd2cae200cdb9..850b545db748e 100644 --- a/flang/test/CMakeLists.txt +++ b/flang/test/CMakeLists.txt @@ -55,6 +55,7 @@ set(FLANG_TEST_DEPENDS fir-opt tco bbc + llvm-dis llvm-objdump split-file ) diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index e020fa3801fd9..3ebc6202df863 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -71,6 +71,7 @@ ! HELP-FC1-NEXT:OPTIONS: ! HELP-FC1-NEXT: -cpp Enable predefined and command line preprocessor macros ! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted) +! HELP-FC1-NEXT: -emit-llvm-bc Build ASTs then convert to LLVM, emit .bc file ! HELP-FC1-NEXT: -emit-llvm Use the LLVM representation for assembler and object files ! HELP-FC1-NEXT: -emit-mlir Build the parse tree, then lower it to MLIR ! HELP-FC1-NEXT: -emit-obj Emit native object files diff --git a/flang/test/Driver/emit-llvm-bc.f90 b/flang/test/Driver/emit-llvm-bc.f90 new file mode 100644 index 0000000000000..6634a117b7356 --- /dev/null +++ b/flang/test/Driver/emit-llvm-bc.f90 @@ -0,0 +1,19 @@ +! Test the options for generating LLVM byte-code `-emit-llvm-bc` option + +!------------- +! RUN COMMANDS +!------------- +! RUN: %flang -emit-llvm -c %s -o - | llvm-dis -o - | FileCheck %s +! RUN: %flang_fc1 -emit-llvm-bc %s -o - | llvm-dis -o - | FileCheck %s + +!---------------- +! EXPECTED OUTPUT +!---------------- +! CHECK: define void @_QQmain() +! CHECK-NEXT: ret void +! CHECK-NEXT: } + +!------ +! INPUT +!------ +end program _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits