diff options
author | Usman Nadeem <mnadeem@quicinc.com> | 2022-08-22 10:24:49 -0700 |
---|---|---|
committer | Usman Nadeem <mnadeem@quicinc.com> | 2022-08-22 11:10:42 -0700 |
commit | ef5ede52efbff6ffa9f8c40dc3c6276146e6ff45 (patch) | |
tree | 6aa5fdc45c195b7d09f13c7d03ec4b6af883ce3d /flang | |
parent | 274f86e7a6d5468b38be7a4a4008a883a27ce008 (diff) | |
download | llvm-ef5ede52efbff6ffa9f8c40dc3c6276146e6ff45.zip llvm-ef5ede52efbff6ffa9f8c40dc3c6276146e6ff45.tar.gz llvm-ef5ede52efbff6ffa9f8c40dc3c6276146e6ff45.tar.bz2 |
[Flang][Driver] Add support for PIC
This patch does the following:
- Consumes the PIC flags (fPIC/fPIE/fropi/frwpi etc) in flang-new.
tools::ParsePICArgs() in ToolChains/CommonArgs.cpp is used for this.
- Adds FC1Option to "-mrelocation-model", "-pic-level", and "-pic-is-pie"
command line options.
- Adds the above options to flang/Frontend/CodeGenOptions' data structure.
- Sets the relocation model in the target machine, and
- Sets module flags for the respective PIC/PIE type in LLVM IR.
I have tried my best to replicate how clang does things.
Differential Revision: https://reviews.llvm.org/D131533
Change-Id: I68fe64910be28147dc5617826641cea71b92d94d
Diffstat (limited to 'flang')
-rw-r--r-- | flang/include/flang/Frontend/CodeGenOptions.def | 11 | ||||
-rw-r--r-- | flang/include/flang/Frontend/CodeGenOptions.h | 9 | ||||
-rw-r--r-- | flang/lib/Frontend/CodeGenOptions.cpp | 1 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 33 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 15 | ||||
-rw-r--r-- | flang/test/Driver/driver-help.f90 | 4 | ||||
-rw-r--r-- | flang/test/Driver/pic-flags.f90 | 85 |
7 files changed, 141 insertions, 17 deletions
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index d67f383..966f9f8 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -14,9 +14,20 @@ # error Define the CODEGENOPT macro to handle language options #endif +#ifndef ENUM_CODEGENOPT +# define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ +CODEGENOPT(Name, Bits, Default) +#endif + CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified. CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. +CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module. +CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level. + +ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use. + #undef CODEGENOPT +#undef ENUM_CODEGENOPT diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index fe25bfd..025f67c 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -32,10 +32,12 @@ class CodeGenOptionsBase { public: #define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits; +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) #include "flang/Frontend/CodeGenOptions.def" protected: #define CODEGENOPT(Name, Bits, Default) +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits; #include "flang/Frontend/CodeGenOptions.def" }; @@ -44,6 +46,13 @@ protected: class CodeGenOptions : public CodeGenOptionsBase { public: + // Define accessors/mutators for code generation options of enumeration type. +#define CODEGENOPT(Name, Bits, Default) +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } +#include "flang/Frontend/CodeGenOptions.def" + CodeGenOptions(); }; diff --git a/flang/lib/Frontend/CodeGenOptions.cpp b/flang/lib/Frontend/CodeGenOptions.cpp index 87641d9..a794718 100644 --- a/flang/lib/Frontend/CodeGenOptions.cpp +++ b/flang/lib/Frontend/CodeGenOptions.cpp @@ -17,6 +17,7 @@ namespace Fortran::frontend { CodeGenOptions::CodeGenOptions() { #define CODEGENOPT(Name, Bits, Default) Name = Default; +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default); #include "flang/Frontend/CodeGenOptions.def" } diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index a75c04d..cce4da3 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -124,6 +124,39 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (args.hasFlag(clang::driver::options::OPT_fdebug_pass_manager, clang::driver::options::OPT_fno_debug_pass_manager, false)) opts.DebugPassManager = 1; + + // -mrelocation-model option. + if (const llvm::opt::Arg *A = + args.getLastArg(clang::driver::options::OPT_mrelocation_model)) { + llvm::StringRef ModelName = A->getValue(); + auto RM = llvm::StringSwitch<llvm::Optional<llvm::Reloc::Model>>(ModelName) + .Case("static", llvm::Reloc::Static) + .Case("pic", llvm::Reloc::PIC_) + .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC) + .Case("ropi", llvm::Reloc::ROPI) + .Case("rwpi", llvm::Reloc::RWPI) + .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI) + .Default(llvm::None); + if (RM.has_value()) + opts.setRelocationModel(*RM); + else + diags.Report(clang::diag::err_drv_invalid_value) + << A->getAsString(args) << ModelName; + } + + // -pic-level and -pic-is-pie option. + if (int PICLevel = getLastArgIntValue( + args, clang::driver::options::OPT_pic_level, 0, diags)) { + if (PICLevel > 2) + diags.Report(clang::diag::err_drv_invalid_value) + << args.getLastArg(clang::driver::options::OPT_pic_level) + ->getAsString(args) + << PICLevel; + + opts.PICLevel = PICLevel; + if (args.hasArg(clang::driver::options::OPT_pic_is_pie)) + opts.IsPIE = 1; + } } /// Parses all target input arguments and populates the target diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index b56d949b..be91a79 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -529,6 +529,14 @@ void CodeGenAction::generateLLVMIR() { llvmModule = mlir::translateModuleToLLVMIR( *mlirModule, *llvmCtx, moduleName ? *moduleName : "FIRModule"); + // Set PIC/PIE level LLVM module flags. + if (opts.PICLevel > 0) { + llvmModule->setPICLevel(static_cast<llvm::PICLevel::Level>(opts.PICLevel)); + if (opts.IsPIE) + llvmModule->setPIELevel( + static_cast<llvm::PIELevel::Level>(opts.PICLevel)); + } + if (!llvmModule) { unsigned diagID = ci.getDiagnostics().getCustomDiagID( clang::DiagnosticsEngine::Error, "failed to create the LLVM module"); @@ -571,11 +579,12 @@ void CodeGenAction::setUpTargetMachine() { assert(theTarget && "Failed to create Target"); // Create `TargetMachine` - llvm::CodeGenOpt::Level OptLevel = - getCGOptLevel(ci.getInvocation().getCodeGenOpts()); + const auto &CGOpts = ci.getInvocation().getCodeGenOpts(); + llvm::CodeGenOpt::Level OptLevel = getCGOptLevel(CGOpts); tm.reset(theTarget->createTargetMachine( theTriple, /*CPU=*/"", - /*Features=*/"", llvm::TargetOptions(), /*Reloc::Model=*/llvm::None, + /*Features=*/"", llvm::TargetOptions(), + /*Reloc::Model=*/CGOpts.getRelocationModel(), /*CodeModel::Model=*/llvm::None, OptLevel)); assert(tm && "Failed to create TargetMachine"); } diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index 3df94d2..99201e0 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -130,9 +130,13 @@ ! HELP-FC1-NEXT: -mmlir <value> Additional arguments to forward to MLIR's option processing ! HELP-FC1-NEXT: -module-dir <dir> Put MODULE files in <dir> ! HELP-FC1-NEXT: -module-suffix <suffix> Use <suffix> as the suffix for module files (the default value is `.mod`) +! HELP-FC1-NEXT: -mrelocation-model <value> +! HELP-FC1-NEXT: The relocation model to use ! HELP-FC1-NEXT: -nocpp Disable predefined and command line preprocessor macros ! HELP-FC1-NEXT: -o <file> Write output to <file> ! HELP-FC1-NEXT: -pedantic Warn on language extensions +! HELP-FC1-NEXT: -pic-is-pie File is for a position independent executable +! HELP-FC1-NEXT: -pic-level <value> Value for __PIC__ ! 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 diff --git a/flang/test/Driver/pic-flags.f90 b/flang/test/Driver/pic-flags.f90 index 99a87c7..2f4842f 100644 --- a/flang/test/Driver/pic-flags.f90 +++ b/flang/test/Driver/pic-flags.f90 @@ -1,18 +1,75 @@ -! Verify that in contrast to Clang, Flang does not default to generating position independent executables/code +! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fno-pie 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-STATIC,CHECK-STATIC-IR -! RUN: %flang -### %s --target=aarch64-linux-gnu 2>&1 | FileCheck %s --check-prefix=CHECK-NOPIE -! RUN: %flang -### %s --target=aarch64-linux-gnu -fno-pie 2>&1 | FileCheck %s --check-prefix=CHECK-NOPIE +! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PIE-LEVEL2,CHECK-PIE-LEVEL2-IR +! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fpie 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PIE-LEVEL1,CHECK-PIE-LEVEL1-IR +! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fPIE 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PIE-LEVEL2,CHECK-PIE-LEVEL2-IR -! RUN: %flang -### %s --target=aarch64-linux-gnu -fpie 2>&1 | FileCheck %s --check-prefix=CHECK-PIE +! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fpic 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PIC-LEVEL1,CHECK-PIC-LEVEL1-IR +! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fPIC 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PIC-LEVEL2,CHECK-PIC-LEVEL2-IR -! CHECK-NOPIE: "-fc1" -! CHECk-NOPIE-NOT: "-fpic" -! CHECK-NOPIE: "{{.*}}ld" -! CHECK-NOPIE-NOT: "-pie" +! RUN: %flang -v -### -o - %s --target=i386-apple-darwin -mdynamic-no-pic 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-DYNAMIC-NO-PIC-32 +! RUN: %flang -v -### -o - %s --target=x86_64-apple-darwin -mdynamic-no-pic 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-DYNAMIC-NO-PIC-64 -! CHECK-PIE: "-fc1" -!! TODO Once Flang supports `-fpie`, it //should// use -fpic when invoking `flang -fc1`. Update the following line once `-fpie` is -! available. -! CHECk-PIE-NOT: "-fpic" -! CHECK-PIE: "{{.*}}ld" -! CHECK-PIE-NOT: "-pie" +! RUN: %flang -v -### -o - %s --target=arm-none-eabi -fropi 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-ROPI +! RUN: %flang -v -### -o - %s --target=arm-none-eabi -frwpi 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-RWPI +! RUN: %flang -v -### -o - %s --target=arm-none-eabi -fropi -frwpi 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-ROPI-RWPI + + +! CHECK: -fc1 + + +!! -fno-pie. +! CHECK-STATIC: -mrelocation-model static +! CHECK-STATIC-NOT: -pic + +! CHECK-STATIC-IR-NOT: {{PIE|PIC}} Level + + +!! -fpic. +! CHECK-PIC-LEVEL1: -mrelocation-model pic -pic-level 1 +! CHECK-PIC-LEVEL1-NOT: -pic-is-pie + +! CHECK-PIC-LEVEL1-IR-NOT: "PIE Level" +! CHECK-PIC-LEVEL1-IR: !"PIC Level", i32 1} +! CHECK-PIC-LEVEL1-IR-NOT: "PIE Level" + + +!! -fPIC. +! CHECK-PIC-LEVEL2: -mrelocation-model pic -pic-level 2 +! CHECK-PIC-LEVEL2-NOT: -pic-is-pie + +! CHECK-PIC-LEVEL2-IR-NOT: "PIE Level" +! CHECK-PIC-LEVEL2-IR: !"PIC Level", i32 2} +! CHECK-PIC-LEVEL2-IR-NOT: "PIE Level" + + +!! -fpie. +! CHECK-PIE-LEVEL1: -mrelocation-model pic -pic-level 1 -pic-is-pie +! CHECK-PIE-LEVEL1-IR: !"PIC Level", i32 1} +! CHECK-PIE-LEVEL1-IR: !"PIE Level", i32 1} + + +!! -fPIE. +! CHECK-PIE-LEVEL2: -mrelocation-model pic -pic-level 2 -pic-is-pie +! CHECK-PIE-LEVEL2-IR: !"PIC Level", i32 2} +! CHECK-PIE-LEVEL2-IR: !"PIE Level", i32 2} + + +!! -mdynamic-no-pic +! CHECK-DYNAMIC-NO-PIC-32: "-mrelocation-model" "dynamic-no-pic" +! CHECK-DYNAMIC-NO-PIC-32-NOT: "-pic-level" +! CHECK-DYNAMIC-NO-PIC-32-NOT: "-pic-is-pie" + +! CHECK-DYNAMIC-NO-PIC-64: "-mrelocation-model" "dynamic-no-pic" "-pic-level" "2" +! CHECK-DYNAMIC-NO-PIC-64-NOT: "-pic-is-pie" + + +!! -fropi -frwpi +! CHECK-ROPI: "-mrelocation-model" "ropi" +! CHECK-ROPI-NOT: "-pic + +! CHECK-RWPI: "-mrelocation-model" "rwpi" +! CHECK-RWPI-NOT: "-pic + +! CHECK-ROPI-RWPI: "-mrelocation-model" "ropi-rwpi" +! CHECK-ROPI-RWPI-NOT: "-pic |