mnadeem created this revision.
mnadeem added a project: Flang.
Herald added a subscriber: jdoerfert.
Herald added a reviewer: sscalpone.
Herald added a reviewer: awarzynski.
Herald added a project: All.
mnadeem requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.
This patch does the following:
Allow consumption of PIC flags (flags similar to clang) in flang-new and fc1.
Set relocation model in the target machine.
Set LLVM module flags for the respective PIC/PIE type.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D131533
Files:
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/CommonArgs.h
clang/lib/Driver/ToolChains/Flang.cpp
clang/lib/Driver/ToolChains/Linux.cpp
flang/include/flang/Frontend/FrontendOptions.h
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
flang/test/Driver/driver-help.f90
flang/test/Driver/pic-flags.f90
Index: flang/test/Driver/pic-flags.f90
===================================================================
--- flang/test/Driver/pic-flags.f90
+++ flang/test/Driver/pic-flags.f90
@@ -1,18 +1,36 @@
! Verify that in contrast to Clang, Flang does not default to generating position independent executables/code
-! 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 -### %s --target=aarch64-linux-gnu -fpie 2>&1 | FileCheck %s --check-prefix=CHECK-PIE
-
-! CHECK-NOPIE: "-fc1"
-! CHECk-NOPIE-NOT: "-fpic"
-! CHECK-NOPIE: "{{.*}}ld"
-! CHECK-NOPIE-NOT: "-pie"
-
-! 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 -S -emit-llvm -o - %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-PIC,CHECK-PIE-LEVEL2
+! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fpie 2>&1 | FileCheck %s --check-prefixes=CHECK-PIC,CHECK-PIE-LEVEL1
+! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fPIE 2>&1 | FileCheck %s --check-prefixes=CHECK-PIC,CHECK-PIE-LEVEL2
+
+! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fpic 2>&1 | FileCheck %s --check-prefixes=CHECK-PIC,CHECK-PIC-LEVEL1
+! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fPIC 2>&1 | FileCheck %s --check-prefixes=CHECK-PIC,CHECK-PIC-LEVEL2
+
+! CHECK-NOPIE: -fc1
+! CHECK-NOPIE: -mrelocation-model static
+! CHECK-NOPIE-NOT: pic-level
+
+! CHECK-PIC: -fc1
+
+! CHECK-PIC-LEVEL1: -mrelocation-model pic -pic-level 1
+! CHECK-PIC-LEVEL1-NOT: -pic-is-pie
+! CHECK-PIC-LEVEL1-NOT: "PIE Level"
+! CHECK-PIC-LEVEL1: !"PIC Level", i32 1}
+! CHECK-PIC-LEVEL1-NOT: "PIE Level"
+
+! CHECK-PIC-LEVEL2: -mrelocation-model pic -pic-level 2
+! CHECK-PIC-LEVEL2-NOT: -pic-is-pie
+! CHECK-PIC-LEVEL1-NOT: "PIE Level"
+! CHECK-PIC-LEVEL2: !"PIC Level", i32 2}
+! CHECK-PIC-LEVEL1-NOT: "PIE Level"
+
+! CHECK-PIE-LEVEL1: -mrelocation-model pic -pic-level 1 -pic-is-pie
+! CHECK-PIE-LEVEL1: !"PIC Level", i32 1}
+! CHECK-PIE-LEVEL1: !"PIE Level", i32 1}
+! CHECK-PIE-LEVEL2: -mrelocation-model pic -pic-level 2 -pic-is-pie
+! CHECK-PIE-LEVEL2: !"PIC Level", i32 2}
+! CHECK-PIE-LEVEL2: !"PIE Level", i32 2}
+
Index: flang/test/Driver/driver-help.f90
===================================================================
--- flang/test/Driver/driver-help.f90
+++ flang/test/Driver/driver-help.f90
@@ -128,9 +128,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
Index: flang/lib/Frontend/FrontendActions.cpp
===================================================================
--- flang/lib/Frontend/FrontendActions.cpp
+++ flang/lib/Frontend/FrontendActions.cpp
@@ -528,6 +528,12 @@
llvmModule = mlir::translateModuleToLLVMIR(
*mlirModule, *llvmCtx, moduleName ? *moduleName : "FIRModule");
+ // Set PIC/PIE level LLVM module flags.
+ if (auto PICLevel = ci.getInvocation().getFrontendOpts().PICLevel)
+ llvmModule->setPICLevel(*PICLevel);
+ if (auto PIELevel = ci.getInvocation().getFrontendOpts().PIELevel)
+ llvmModule->setPIELevel(*PIELevel);
+
if (!llvmModule) {
unsigned diagID = ci.getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Error, "failed to create the LLVM module");
@@ -574,7 +580,8 @@
getCGOptLevel(ci.getInvocation().getCodeGenOpts());
tm.reset(theTarget->createTargetMachine(
theTriple, /*CPU=*/"",
- /*Features=*/"", llvm::TargetOptions(), /*Reloc::Model=*/llvm::None,
+ /*Features=*/"", llvm::TargetOptions(),
+ /*Reloc::Model=*/ci.getInvocation().getFrontendOpts().RelocModel,
/*CodeModel::Model=*/llvm::None, OptLevel));
assert(tm && "Failed to create TargetMachine");
}
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -147,6 +147,22 @@
opts.needProvenanceRangeToCharBlockMappings = true;
}
+static llvm::Reloc::Model getRelocationFromName(llvm::StringRef model) {
+ if (model.equals("static"))
+ return llvm::Reloc::Static;
+ if (model.equals("pic"))
+ return llvm::Reloc::PIC_;
+ if (model.equals("dynamic-no-pic"))
+ return llvm::Reloc::DynamicNoPIC;
+ if (model.equals("ropi"))
+ return llvm::Reloc::ROPI;
+ if (model.equals("rwpi"))
+ return llvm::Reloc::RWPI;
+ if (model.equals("ropi-rwpi"))
+ return llvm::Reloc::ROPI_RWPI;
+ llvm_unreachable("Unknown relocation model.");
+}
+
static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
unsigned numErrorsBefore = diags.getNumErrors();
@@ -271,6 +287,19 @@
}
}
+ // Parse the PIC related -pic-level/-pic-is-pie/-mrelocation-model options.
+ if (int PICLevel = getLastArgIntValue(
+ args, clang::driver::options::OPT_pic_level, 0, diags)) {
+ opts.PICLevel = static_cast<llvm::PICLevel::Level>(PICLevel);
+ if (args.hasArg(clang::driver::options::OPT_pic_is_pie))
+ opts.PIELevel = static_cast<llvm::PIELevel::Level>(PICLevel);
+ }
+ if (args.hasArg(clang::driver::options::OPT_mrelocation_model)) {
+ llvm::StringRef model =
+ args.getLastArgValue(clang::driver::options::OPT_mrelocation_model);
+ opts.RelocModel = getRelocationFromName(model);
+ }
+
// Parsing -load <dsopath> option and storing shared object path
if (llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_load)) {
opts.plugins.push_back(a->getValue());
Index: flang/include/flang/Frontend/FrontendOptions.h
===================================================================
--- flang/include/flang/Frontend/FrontendOptions.h
+++ flang/include/flang/Frontend/FrontendOptions.h
@@ -17,6 +17,7 @@
#include "flang/Parser/characters.h"
#include "flang/Parser/unparse.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cstdint>
#include <string>
@@ -286,6 +287,13 @@
/// should only be used for debugging and experimental features.
std::vector<std::string> mlirArgs;
+ /// Some targets need the pic levels. These are stored as
+ /// LLVM module flags.
+ llvm::Optional<llvm::PICLevel::Level> PICLevel;
+ llvm::Optional<llvm::PIELevel::Level> PIELevel;
+ /// For setting up the target machine.
+ llvm::Optional<llvm::Reloc::Model> RelocModel;
+
// Return the appropriate input kind for a file extension. For example,
/// "*.f" would return Language::Fortran.
///
Index: clang/lib/Driver/ToolChains/Linux.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Linux.cpp
+++ clang/lib/Driver/ToolChains/Linux.cpp
@@ -699,11 +699,8 @@
}
bool Linux::isPIEDefault(const llvm::opt::ArgList &Args) const {
- // TODO: Remove the special treatment for Flang once its frontend driver can
- // generate position independent code.
- return !getDriver().IsFlangMode() &&
- (CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() ||
- getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE());
+ return CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() ||
+ getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE();
}
bool Linux::IsAArch64OutlineAtomicsDefault(const ArgList &Args) const {
Index: clang/lib/Driver/ToolChains/Flang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Flang.cpp
+++ clang/lib/Driver/ToolChains/Flang.cpp
@@ -117,6 +117,23 @@
if (D.getDiags().getDiagnosticOptions().ShowColors)
CmdArgs.push_back("-fcolor-diagnostics");
+ // -fPIC/-fPIE and their variants. Similar to clang.
+ llvm::Reloc::Model RelocationModel;
+ unsigned PICLevel;
+ bool IsPIE;
+ std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(TC, Args);
+
+ if (auto *RMName = RelocationModelName(RelocationModel)) {
+ CmdArgs.push_back("-mrelocation-model");
+ CmdArgs.push_back(RMName);
+ }
+ if (PICLevel > 0) {
+ CmdArgs.push_back("-pic-level");
+ CmdArgs.push_back(PICLevel == 1 ? "1" : "2");
+ if (IsPIE)
+ CmdArgs.push_back("-pic-is-pie");
+ }
+
// Add other compile options
AddOtherOptions(Args, CmdArgs);
Index: clang/lib/Driver/ToolChains/CommonArgs.h
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.h
+++ clang/lib/Driver/ToolChains/CommonArgs.h
@@ -93,6 +93,8 @@
llvm::opt::ArgStringList &CmdArgs, const InputInfo &Output,
const InputInfo &Input, bool IsThinLTO);
+const char *RelocationModelName(llvm::Reloc::Model Model);
+
std::tuple<llvm::Reloc::Model, unsigned, bool>
ParsePICArgs(const ToolChain &ToolChain, const llvm::opt::ArgList &Args);
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1200,6 +1200,24 @@
options::OPT_fauto_profile_EQ);
}
+const char *tools::RelocationModelName(llvm::Reloc::Model Model) {
+ switch (Model) {
+ case llvm::Reloc::Static:
+ return "static";
+ case llvm::Reloc::PIC_:
+ return "pic";
+ case llvm::Reloc::DynamicNoPIC:
+ return "dynamic-no-pic";
+ case llvm::Reloc::ROPI:
+ return "ropi";
+ case llvm::Reloc::RWPI:
+ return "rwpi";
+ case llvm::Reloc::ROPI_RWPI:
+ return "ropi-rwpi";
+ }
+ llvm_unreachable("Unknown Reloc::Model kind");
+}
+
/// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments. Then,
/// smooshes them together with platform defaults, to decide whether
/// this compile should be using PIC mode or not. Returns a tuple of
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1152,23 +1152,6 @@
}
}
-static const char *RelocationModelName(llvm::Reloc::Model Model) {
- switch (Model) {
- case llvm::Reloc::Static:
- return "static";
- case llvm::Reloc::PIC_:
- return "pic";
- case llvm::Reloc::DynamicNoPIC:
- return "dynamic-no-pic";
- case llvm::Reloc::ROPI:
- return "ropi";
- case llvm::Reloc::RWPI:
- return "rwpi";
- case llvm::Reloc::ROPI_RWPI:
- return "ropi-rwpi";
- }
- llvm_unreachable("Unknown Reloc::Model kind");
-}
static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
const ArgList &Args,
ArgStringList &CmdArgs,
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -5276,11 +5276,6 @@
"Note this may change .s semantics and shouldn't generally be used "
"on compiler-generated code.">,
MarshallingInfoFlag<CodeGenOpts<"SaveTempLabels">>;
-def mrelocation_model : Separate<["-"], "mrelocation-model">,
- HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">,
- NormalizedValuesScope<"llvm::Reloc">,
- NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>,
- MarshallingInfoEnum<CodeGenOpts<"RelocationModel">, "PIC_">;
def fno_math_builtin : Flag<["-"], "fno-math-builtin">,
HelpText<"Disable implicit builtin knowledge of math functions">,
MarshallingInfoFlag<LangOpts<"NoMathBuiltin">>;
@@ -5956,6 +5951,13 @@
Flags<[CC1Option, CC1AsOption, FC1Option, NoDriverOption]>,
MarshallingInfoFlag<FrontendOpts<"ShowVersion">>;
+def mrelocation_model : Separate<["-"], "mrelocation-model">,
+ HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">,
+ Flags<[CC1Option, CC1AsOption, FC1Option, NoDriverOption]>,
+ NormalizedValuesScope<"llvm::Reloc">,
+ NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>,
+ MarshallingInfoEnum<CodeGenOpts<"RelocationModel">, "PIC_">;
+
def main_file_name : Separate<["-"], "main-file-name">,
HelpText<"Main file name to use for debug info and source if missing">,
Flags<[CC1Option, CC1AsOption, NoDriverOption]>,
@@ -6005,12 +6007,6 @@
def function_alignment : Separate<["-"], "function-alignment">,
HelpText<"default alignment for functions">,
MarshallingInfoInt<LangOpts<"FunctionAlignment">>;
-def pic_level : Separate<["-"], "pic-level">,
- HelpText<"Value for __PIC__">,
- MarshallingInfoInt<LangOpts<"PICLevel">>;
-def pic_is_pie : Flag<["-"], "pic-is-pie">,
- HelpText<"File is for a position independent executable">,
- MarshallingInfoFlag<LangOpts<"PIE">>;
def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">,
HelpText<"Like -fno-semantic-interposition but don't use local aliases">,
MarshallingInfoFlag<LangOpts<"HalfNoSemanticInterposition">>;
@@ -6321,6 +6317,12 @@
CodeGenOpts<"DebugPassManager">, DefaultFalse,
PosFlag<SetTrue, [], "Prints debug information for the new pass manager">,
NegFlag<SetFalse, [], "Disables debug printing for the new pass manager">>;
+def pic_level : Separate<["-"], "pic-level">,
+ HelpText<"Value for __PIC__">,
+ MarshallingInfoInt<LangOpts<"PICLevel">>;
+def pic_is_pie : Flag<["-"], "pic-is-pie">,
+ HelpText<"File is for a position independent executable">,
+ MarshallingInfoFlag<LangOpts<"PIE">>;
} // let Flags = [CC1Option, FC1Option, NoDriverOption]
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits