[llvm] 4f9929a - [AIX][CodeGen] Storage Locations for Constant Pointers

Qiongsi Wu via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 23 06:46:16 PDT 2023


Author: Qiongsi Wu
Date: 2023-03-23T09:44:47-04:00
New Revision: 4f9929add5369490c9607fc9203761483d2bc916

URL: https://github.com/llvm/llvm-project/commit/4f9929add5369490c9607fc9203761483d2bc916
DIFF: https://github.com/llvm/llvm-project/commit/4f9929add5369490c9607fc9203761483d2bc916.diff

LOG: [AIX][CodeGen] Storage Locations for Constant Pointers

This patch adds an `llc` option `-mroptr` to specify storage locations for constant pointers on AIX.

When the `-mroptr` option is specified, constant pointers, virtual function tables, and virtual type tables are placed in read-only storage. Otherwise, by default, pointers, virtual function tables, and virtual type tables are placed are placed in read/write storage.

https://reviews.llvm.org/D144190 enables the `-mroptr` option for `clang`.

Reviewed By: hubert.reinterpretcast, stephenpeckham, myhsu, MaskRay, serge-sans-paille

Differential Revision: https://reviews.llvm.org/D144189

Added: 
    llvm/test/CodeGen/PowerPC/aix-xcoff-roptr.ll
    llvm/test/CodeGen/PowerPC/aix64-xcoff-roptr.ll

Modified: 
    llvm/docs/ReleaseNotes.rst
    llvm/include/llvm/CodeGen/CommandFlags.h
    llvm/include/llvm/Target/TargetOptions.h
    llvm/lib/CodeGen/CommandFlags.cpp
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/tools/llc/llc.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 525f57a90dfb0..6f78497644479 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -122,7 +122,11 @@ Changes to the MIPS Backend
 Changes to the PowerPC Backend
 ------------------------------
 
-* ...
+* A new option ``-mroptr`` is added to ``clang`` and ``llc``. When this option
+  is present, constant objects with relocatable address values are put into the
+  RO data section. This option should be used with the ``-fdata-sections``
+  option, and is not supported with ``-fno-data-sections``. The option is
+  only supported on AIX.
 
 Changes to the RISC-V Backend
 -----------------------------

diff  --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index 475d87bdd5b13..19b466629dbfc 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -143,6 +143,8 @@ unsigned getAlignLoops();
 
 bool getJMCInstrument();
 
+bool getXCOFFReadOnlyPointers();
+
 /// Create this object with static storage to register codegen-related command
 /// line options.
 struct RegisterCodeGenFlags {

diff  --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index 22e811653c6d4..76e4248088afd 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -130,13 +130,12 @@ namespace llvm {
           HonorSignDependentRoundingFPMathOption(false), NoZerosInBSS(false),
           GuaranteedTailCallOpt(false), StackSymbolOrdering(true),
           EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false),
-          DisableIntegratedAS(false),
-          RelaxELFRelocations(true), FunctionSections(false),
-          DataSections(false), IgnoreXCOFFVisibility(false),
-          XCOFFTracebackTable(true), UniqueSectionNames(true),
-          UniqueBasicBlockSectionNames(false), TrapUnreachable(false),
-          NoTrapAfterNoreturn(false), TLSSize(0), EmulatedTLS(false),
-          ExplicitEmulatedTLS(false), EnableIPRA(false),
+          DisableIntegratedAS(false), RelaxELFRelocations(true),
+          FunctionSections(false), DataSections(false),
+          IgnoreXCOFFVisibility(false), XCOFFTracebackTable(true),
+          UniqueSectionNames(true), UniqueBasicBlockSectionNames(false),
+          TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0),
+          EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false),
           EmitStackSizeSection(false), EnableMachineOutliner(false),
           EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
           EmitAddrsig(false), EmitCallSiteInfo(false),
@@ -144,7 +143,7 @@ namespace llvm {
           ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
           XRayOmitFunctionIndex(false), DebugStrictDwarf(false),
           Hotpatch(false), PPCGenScalarMASSEntries(false), JMCInstrument(false),
-          EnableCFIFixup(false), MisExpect(false),
+          EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
           FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
 
     /// DisableFramePointerElim - This returns true if frame pointer elimination
@@ -360,6 +359,10 @@ namespace llvm {
     /// By default, it is set to false
     unsigned MisExpect : 1;
 
+    /// When set to true, const objects with relocatable address values are put
+    /// into the RO data section.
+    unsigned XCOFFReadOnlyPointers : 1;
+
     /// Name of the stack usage file (i.e., .su file) if user passes
     /// -fstack-usage. If empty, it can be implied that -fstack-usage is not
     /// passed on the command line.

diff  --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 51d259cea41b8..5ef650787a585 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -103,6 +103,7 @@ CGOPT(bool, XRayOmitFunctionIndex)
 CGOPT(bool, DebugStrictDwarf)
 CGOPT(unsigned, AlignLoops)
 CGOPT(bool, JMCInstrument)
+CGOPT(bool, XCOFFReadOnlyPointers)
 
 codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
 #define CGBINDOPT(NAME)                                                        \
@@ -478,6 +479,13 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
       cl::init(false));
   CGBINDOPT(JMCInstrument);
 
+  static cl::opt<bool> XCOFFReadOnlyPointers(
+      "mroptr",
+      cl::desc("When set to true, const objects with relocatable address "
+               "values are put into the RO data section."),
+      cl::init(false));
+  CGBINDOPT(XCOFFReadOnlyPointers);
+
 #undef CGBINDOPT
 
   mc::RegisterMCTargetOptionsFlags();
@@ -554,6 +562,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
   Options.DebugStrictDwarf = getDebugStrictDwarf();
   Options.LoopAlignment = getAlignLoops();
   Options.JMCInstrument = getJMCInstrument();
+  Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();
 
   Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
 

diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index e2fbe027f15b0..c81b6bb623b96 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2343,8 +2343,11 @@ MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
   XCOFF::StorageMappingClass MappingClass;
   if (Kind.isText())
     MappingClass = XCOFF::XMC_PR;
-  else if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS())
+  else if (Kind.isData() || Kind.isBSS())
     MappingClass = XCOFF::XMC_RW;
+  else if (Kind.isReadOnlyWithRel())
+    MappingClass =
+        TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW;
   else if (Kind.isReadOnly())
     MappingClass = XCOFF::XMC_RO;
   else
@@ -2429,9 +2432,18 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
     return TextSection;
   }
 
-  // TODO: We may put Kind.isReadOnlyWithRel() under option control, because
-  // user may want to have read-only data with relocations placed into a
-  // read-only section by the compiler.
+  if (TM.Options.XCOFFReadOnlyPointers && Kind.isReadOnlyWithRel()) {
+    if (!TM.getDataSections())
+      report_fatal_error(
+          "ReadOnlyPointers is supported only if data sections is turned on");
+
+    SmallString<128> Name;
+    getNameWithPrefix(Name, GO, TM);
+    return getContext().getXCOFFSection(
+        Name, SectionKind::getReadOnly(),
+        XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));
+  }
+
   // For BSS kind, zero initialized data must be emitted to the .data section
   // because external linkage control sections that get mapped to the .bss
   // section will be linked as tentative defintions, which is only appropriate

diff  --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-roptr.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-roptr.ll
new file mode 100644
index 0000000000000..532d17e087e5b
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-roptr.ll
@@ -0,0 +1,30 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff -mroptr < %s | FileCheck %s
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff -mroptr -filetype=obj -o %t.o < %s
+; RUN: llvm-objdump -t --symbol-description %t.o | FileCheck %s --check-prefix=OBJ
+
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff -mroptr -data-sections=false \
+; RUN: < %s 2>&1 | FileCheck %s --check-prefix=DS_ERR
+
+; DS_ERR: -mroptr option must be used with -data-sections
+
+%union.U = type { %"struct.U::A" }
+%"struct.U::A" = type { ptr }
+
+ at _ZL1p = internal constant i32 ptrtoint (ptr @_ZL1p to i32), align 4
+; CHECK:         .csect _ZL1p[RO],2
+; CHECK-NEXT:    .lglobl	_ZL1p[RO]
+; CHECK-NEXT:    .align	2
+; CHECK-NEXT:    .vbyte	4, _ZL1p[RO]
+; OBJ-DAG: {{([[:xdigit:]]{8})}} l .text {{([[:xdigit:]]{8})}} (idx: [[#]]) _ZL1p[RO]
+ at q = thread_local constant ptr @_ZL1p, align 4
+; CHECK:         .csect q[TL],2
+; CHECK-NEXT:    .globl	q[TL]
+; CHECK-NEXT:    .align	2
+; CHECK-NEXT:    .vbyte	4, _ZL1p[RO]
+; OBJ-DAG: {{([[:xdigit:]]{8})}} g O .tdata {{([[:xdigit:]]{8})}} (idx: [[#]]) q[TL]
+ at u = local_unnamed_addr constant [1 x %union.U] [%union.U { %"struct.U::A" { ptr @_ZL1p } }], align 4
+; CHECK:         .csect u[RO],2
+; CHECK-NEXT:    .globl	u[RO]
+; CHECK-NEXT:    .align	2
+; CHECK-NEXT:    .vbyte	4, _ZL1p[RO]
+; OBJ-DAG: {{([[:xdigit:]]{8})}} g .text {{([[:xdigit:]]{8})}} (idx: [[#]]) u[RO]

diff  --git a/llvm/test/CodeGen/PowerPC/aix64-xcoff-roptr.ll b/llvm/test/CodeGen/PowerPC/aix64-xcoff-roptr.ll
new file mode 100644
index 0000000000000..aff753661b0e1
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix64-xcoff-roptr.ll
@@ -0,0 +1,33 @@
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -mroptr < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -mroptr -filetype=obj -o %t.o < %s
+; RUN: llvm-objdump -t --symbol-description %t.o | FileCheck %s --check-prefix=OBJ
+
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff -mroptr -data-sections=false \
+; RUN: < %s 2>&1 | FileCheck %s --check-prefix=DS_ERR
+; RUN: not llc -mtriple powerpc64le-unknown-linux-gnu -mroptr \
+; RUN: < %s 2>&1 | FileCheck %s --check-prefix=OS_ERR
+
+; DS_ERR: -mroptr option must be used with -data-sections
+; OS_ERR: -mroptr option is only supported on AIX
+
+%union.U = type { %"struct.U::A" }
+%"struct.U::A" = type { ptr }
+
+ at _ZL1p = internal constant i64 ptrtoint (ptr @_ZL1p to i64), align 8
+; CHECK:         .csect _ZL1p[RO],3
+; CHECK-NEXT:    .lglobl	_ZL1p[RO]
+; CHECK-NEXT:    .align	3
+; CHECK-NEXT:    .vbyte	8, _ZL1p[RO]
+; OBJ-DAG: {{([[:xdigit:]]{16})}} l .text {{([[:xdigit:]]{16})}} (idx: [[#]]) _ZL1p[RO]
+ at q = thread_local constant ptr @_ZL1p, align 8
+; CHECK:         .csect q[TL],3
+; CHECK-NEXT:    .globl	q[TL]
+; CHECK-NEXT:    .align	3
+; CHECK-NEXT:    .vbyte	8, _ZL1p[RO]
+; OBJ-DAG: {{([[:xdigit:]]{16})}} g O .tdata {{([[:xdigit:]]{16})}} (idx: [[#]]) q[TL]
+ at u = local_unnamed_addr constant [1 x %union.U] [%union.U { %"struct.U::A" { ptr @_ZL1p } }], align 8
+; CHECK:         .csect u[RO],3
+; CHECK-NEXT:    .globl	u[RO]
+; CHECK-NEXT:    .align	3
+; CHECK-NEXT:    .vbyte	8, _ZL1p[RO]
+; OBJ-DAG: {{([[:xdigit:]]{16})}} g .text {{([[:xdigit:]]{16})}} (idx: [[#]]) u[RO]

diff  --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index ed65b83487790..860fa39d57e8a 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -496,6 +496,24 @@ static int compileModule(char **argv, LLVMContext &Context) {
   TargetOptions Options;
   auto InitializeOptions = [&](const Triple &TheTriple) {
     Options = codegen::InitTargetOptionsFromCodeGenFlags(TheTriple);
+
+    if (Options.XCOFFReadOnlyPointers) {
+      if (!TheTriple.isOSAIX())
+        reportError("-mroptr option is only supported on AIX", InputFilename);
+
+      // Since the storage mapping class is specified per csect,
+      // without using data sections, it is less effective to use read-only
+      // pointers. Using read-only pointers may cause other RO variables in the
+      // same csect to become RW when the linker acts upon `-bforceimprw`;
+      // therefore, we require that separate data sections are used in the
+      // presence of ReadOnlyPointers. We respect the setting of data-sections
+      // since we have not found reasons to do otherwise that overcome the user
+      // surprise of not respecting the setting.
+      if (!Options.DataSections)
+        reportError("-mroptr option must be used with -data-sections",
+                    InputFilename);
+    }
+
     Options.BinutilsVersion =
         TargetMachine::parseBinutilsVersion(BinutilsVersion);
     Options.DisableIntegratedAS = NoIntegratedAssembler;


        


More information about the llvm-commits mailing list