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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to