forked from OSchip/llvm-project
[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
This commit is contained in:
parent
9d2350fd19
commit
dd56939a4b
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -37,6 +37,9 @@ enum ActionKind {
|
|||
/// Emit an .ll file
|
||||
EmitLLVM,
|
||||
|
||||
/// Emit a .bc file
|
||||
EmitLLVMBitcode,
|
||||
|
||||
/// Emit a .o file.
|
||||
EmitObj,
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ add_flang_library(flangFrontend
|
|||
FIRBuilder
|
||||
FIRCodeGen
|
||||
FIRTransforms
|
||||
LLVMPasses
|
||||
MLIRTransforms
|
||||
MLIRLLVMToLLVMIRTranslation
|
||||
MLIRSCFToControlFlow
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -55,6 +55,7 @@ set(FLANG_TEST_DEPENDS
|
|||
fir-opt
|
||||
tco
|
||||
bbc
|
||||
llvm-dis
|
||||
llvm-objdump
|
||||
split-file
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue