aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorUsman Nadeem <mnadeem@quicinc.com>2022-08-22 10:24:49 -0700
committerUsman Nadeem <mnadeem@quicinc.com>2022-08-22 11:10:42 -0700
commitef5ede52efbff6ffa9f8c40dc3c6276146e6ff45 (patch)
tree6aa5fdc45c195b7d09f13c7d03ec4b6af883ce3d /flang
parent274f86e7a6d5468b38be7a4a4008a883a27ce008 (diff)
downloadllvm-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.def11
-rw-r--r--flang/include/flang/Frontend/CodeGenOptions.h9
-rw-r--r--flang/lib/Frontend/CodeGenOptions.cpp1
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp33
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp15
-rw-r--r--flang/test/Driver/driver-help.f904
-rw-r--r--flang/test/Driver/pic-flags.f9085
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