[llvm] [SystemZ][zOS] Override emitGlobalAlias for ADA (PR #84829)

Yusra Syeda via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 13 14:02:48 PDT 2024


https://github.com/ysyeda updated https://github.com/llvm/llvm-project/pull/84829

>From 8418f1498540cf106f1cfefaa7d22f80fba2e329 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Mon, 11 Mar 2024 16:13:32 -0400
Subject: [PATCH 1/3] update indirect handling

---
 llvm/include/llvm/CodeGen/AsmPrinter.h        |  4 +-
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 49 ++++++++++++++++---
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.h   |  1 +
 .../CodeGen/SystemZ/zos-ada-relocations.ll    |  4 +-
 4 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index a7fbf4aeb74494..857a39a6b71ce6 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -897,12 +897,14 @@ class AsmPrinter : public MachineFunctionPass {
   virtual void emitModuleCommandLines(Module &M);
 
   GCMetadataPrinter *getOrCreateGCPrinter(GCStrategy &S);
+
+protected:
   virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA);
-  void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
 
 private:
   /// This method decides whether the specified basic block requires a label.
   bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
+  void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
 
 protected:
   virtual bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const {
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 5696ae117d69f0..b69dfad5227dc9 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -26,6 +26,7 @@
 #include "llvm/MC/MCInstBuilder.h"
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbolGOFF.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/Chrono.h"
 #include "llvm/Support/ConvertEBCDIC.h"
@@ -1026,17 +1027,15 @@ void SystemZAsmPrinter::emitADASection() {
       EmittedBytes += PointerSize;
       break;
     case SystemZII::MO_ADA_INDIRECT_FUNC_DESC: {
-      MCSymbol *Alias = OutContext.createTempSymbol(
-          Twine(Sym->getName()).concat("@indirect"));
-      OutStreamer->emitAssignment(Alias,
-                                  MCSymbolRefExpr::create(Sym, OutContext));
-      OutStreamer->emitSymbolAttribute(Alias, MCSA_IndirectSymbol);
+      MCSymbolGOFF *IndirectSym =
+          static_cast<MCSymbolGOFF *>(OutContext.getOrCreateSymbol(
+              Twine(Sym->getName()).concat("@indirect")));
 
       EMIT_COMMENT("pointer to function descriptor");
       OutStreamer->emitValue(
-          SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
-                                MCSymbolRefExpr::create(Alias, OutContext),
-                                OutContext),
+          SystemZMCExpr::create(
+              SystemZMCExpr::VK_SystemZ_VCon,
+              MCSymbolRefExpr::create(IndirectSym, OutContext), OutContext),
           PointerSize);
       EmittedBytes += PointerSize;
       break;
@@ -1541,6 +1540,40 @@ void SystemZAsmPrinter::emitPPA2(Module &M) {
   OutStreamer->popSection();
 }
 
+void SystemZAsmPrinter::emitGlobalAlias(const Module &M,
+                                        const GlobalAlias &GA) {
+  if (!TM.getTargetTriple().isOSzOS()) {
+    AsmPrinter::emitGlobalAlias(M, GA);
+    return;
+  }
+
+  MCSymbol *Name = getSymbol(&GA);
+  bool IsFunc = isa<Function>(GA.getAliasee()->stripPointerCasts());
+
+  if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective())
+    OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
+  else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage())
+    OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
+  else
+    assert(GA.hasLocalLinkage() && "Invalid alias linkage");
+
+  emitVisibility(Name, GA.getVisibility());
+
+  const MCExpr *Expr;
+
+  // For XPLINK, create a VCON relocation in case of a function, and
+  // a direct reference else.
+  MCSymbol *Sym = getSymbol(GA.getAliaseeObject());
+  if (IsFunc)
+    Expr = SystemZMCExpr::create(SystemZMCExpr::VK_SystemZ_VCon,
+                                 MCSymbolRefExpr::create(Sym, OutContext),
+                                 OutContext);
+
+  else
+    Expr = MCSymbolRefExpr::create(Sym, OutContext);
+  OutStreamer->emitAssignment(Name, Expr);
+}
+
 void SystemZAsmPrinter::emitFunctionEntryLabel() {
   const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
 
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
index 303cce1a1b6581..4d9605725321cd 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h
@@ -118,6 +118,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
   void emitFunctionEntryLabel() override;
   void emitFunctionBodyEnd() override;
   void emitStartOfAsmFile(Module &M) override;
+  void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override;
 
 private:
   void emitCallInformation(CallType CT);
diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
index e25246917ec099..6bdd42a9bd0a58 100644
--- a/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll
@@ -56,9 +56,7 @@ entry:
 declare signext i32 @callout(i32 signext)
 
 ; CHECK:     .section    ".ada"
-; CHECK:  .set @@DoFunc at indirect0, DoFunc
-; CHECK:      .indirect_symbol   @@DoFunc at indirect0
-; CHECK:  .quad V(@@DoFunc at indirect0)          * Offset 0 pointer to function descriptor DoFunc
+; CHECK:  .quad V(DoFunc at indirect)             * Offset 0 pointer to function descriptor DoFunc
 ; CHECK:  .quad R(Caller)                      * Offset 8 function descriptor of Caller
 ; CHECK:  .quad V(Caller)
 ; CHECK:  .quad A(i2)                           * Offset 24 pointer to data symbol i2

>From e1da0442117ce961b380fc3b1c09bf9f91b11a19 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Tue, 12 Mar 2024 16:45:52 -0400
Subject: [PATCH 2/3] add set/getAliasName & set/getIndirect functions to
 MCSymbolGOFF

---
 llvm/include/llvm/MC/MCSymbolGOFF.h           | 18 +++++++++++++++++-
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp |  3 +++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
index cc4e2bbe246e2d..2ebb78c97df1da 100644
--- a/llvm/include/llvm/MC/MCSymbolGOFF.h
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -18,10 +18,26 @@
 namespace llvm {
 
 class MCSymbolGOFF : public MCSymbol {
+  mutable StringRef AliasName; // ADA indirect
+
+  enum SymbolFlags : uint16_t {
+    SF_Alias = 0x02,     // Symbol is alias.
+    SF_Indirect = 0x200, // Symbol referenced indirectly.
+  };
+
 public:
   MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary)
-      : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
+      : MCSymbol(SymbolKindGOFF, Name, IsTemporary), AliasName() {}
   static bool classof(const MCSymbol *S) { return S->isGOFF(); }
+
+  bool hasAliasName() const { return !AliasName.empty(); }
+  void setAliasName(StringRef Name) { AliasName = Name; }
+  StringRef getAliasName() const { return AliasName; }
+
+  void setIndirect(bool Value = true) {
+    modifyFlags(Value ? SF_Indirect : 0, SF_Indirect);
+  }
+  bool isIndirect() const { return getFlags() & SF_Indirect; }
 };
 } // end namespace llvm
 
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index b69dfad5227dc9..171aea7808a387 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1030,6 +1030,9 @@ void SystemZAsmPrinter::emitADASection() {
       MCSymbolGOFF *IndirectSym =
           static_cast<MCSymbolGOFF *>(OutContext.getOrCreateSymbol(
               Twine(Sym->getName()).concat("@indirect")));
+      IndirectSym->setExternal(Sym->isExternal());
+      IndirectSym->setAliasName(Sym->getName());
+      IndirectSym->setIndirect(true);
 
       EMIT_COMMENT("pointer to function descriptor");
       OutStreamer->emitValue(

>From 53d03a490b1f8b7c2a6aa77c79fb50a36896e31e Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Wed, 13 Mar 2024 17:02:08 -0400
Subject: [PATCH 3/3] add test case for global alias

---
 .../CodeGen/SystemZ/zos-ada-globalalias.ll    | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 llvm/test/CodeGen/SystemZ/zos-ada-globalalias.ll

diff --git a/llvm/test/CodeGen/SystemZ/zos-ada-globalalias.ll b/llvm/test/CodeGen/SystemZ/zos-ada-globalalias.ll
new file mode 100644
index 00000000000000..afb3cd2a76b5c7
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-ada-globalalias.ll
@@ -0,0 +1,35 @@
+; RUN: llc -mtriple s390x-ibm-zos < %s | FileCheck %s
+
+; C test case:
+; typedef void (*voidfunc)();
+; void func(){}
+; voidfunc ptr = &func;
+
+; CHECK: ptr:
+; CHECK:        .quad   func
+
+ at ptr = hidden global void (...)* bitcast (void ()* @func to void (...)*), align 8
+  
+define hidden void @func() {
+entry:
+  ret void
+}
+
+; C test case for global alias
+; void __f() {}
+; void f() __attribute__ ((alias ("__f")));
+; void (*fp)() = &f;
+
+; CHECK:        .quad   f
+
+; CHECK:        .globl  f
+; CHECK:        .hidden f
+; CHECK: .set f, V(__f)
+
+ at fp = hidden global void (...)* @f, align 8
+ at f = hidden alias void (...), bitcast (void ()* @__f to void (...)*)
+
+define hidden void @__f() #0 {
+entry:
+  ret void
+}



More information about the llvm-commits mailing list