https://github.com/tltao created https://github.com/llvm/llvm-project/pull/169362
Add additional functionality required on z/OS for `lowerConstant`, `emitGlobalVariable`, and `emitGlobalAlias`. The main addition is to properly apply the attribute to the various `MCSymbols` and also emit the correct `MCExpr`. >From d565c7d8c772cf1c66d57bd1db0387ad90bb1d9b Mon Sep 17 00:00:00 2001 From: Tony Tao <[email protected]> Date: Wed, 19 Nov 2025 19:55:35 +0000 Subject: [PATCH 1/4] Implement emitGlobalVariable and lowerConstant --- clang/lib/Lex/HeaderMap.cpp | 1 + llvm/lib/Support/VirtualOutputBackends.cpp | 23 +++++--- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 56 +++++++++++++++++++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.h | 2 + 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp index a7b670f00ac6e..588b32ee9ca8e 100644 --- a/clang/lib/Lex/HeaderMap.cpp +++ b/clang/lib/Lex/HeaderMap.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SystemZ/zOSSupport.h" #include <cstring> #include <memory> #include <optional> diff --git a/llvm/lib/Support/VirtualOutputBackends.cpp b/llvm/lib/Support/VirtualOutputBackends.cpp index de59b8ab63a53..33a56c7f5f607 100644 --- a/llvm/lib/Support/VirtualOutputBackends.cpp +++ b/llvm/lib/Support/VirtualOutputBackends.cpp @@ -254,6 +254,18 @@ static Error createDirectoriesOnDemand(StringRef OutputPath, }); } +static sys::fs::OpenFlags generateFlagsFromConfig(OutputConfig Config) { + sys::fs::OpenFlags OF = sys::fs::OF_None; + if (Config.getTextWithCRLF()) + OF |= sys::fs::OF_TextWithCRLF; + else if (Config.getText()) + OF |= sys::fs::OF_Text; + if (Config.getAppend()) + OF |= sys::fs::OF_Append; + + return OF; +} + Error OnDiskOutputFile::tryToCreateTemporary(std::optional<int> &FD) { // Create a temporary file. // Insert -%%%%%%%% before the extension (if any), and because some tools @@ -268,9 +280,10 @@ Error OnDiskOutputFile::tryToCreateTemporary(std::optional<int> &FD) { return createDirectoriesOnDemand(OutputPath, Config, [&]() -> Error { int NewFD; + sys::fs::OpenFlags OF = generateFlagsFromConfig(Config); SmallString<128> UniquePath; if (std::error_code EC = - sys::fs::createUniqueFile(ModelPath, NewFD, UniquePath)) + sys::fs::createUniqueFile(ModelPath, NewFD, UniquePath, OF)) return make_error<TempFileOutputError>(ModelPath, OutputPath, EC); if (Config.getDiscardOnSignal()) @@ -312,13 +325,7 @@ Error OnDiskOutputFile::initializeFile(std::optional<int> &FD) { // Not using a temporary file. Open the final output file. return createDirectoriesOnDemand(OutputPath, Config, [&]() -> Error { int NewFD; - sys::fs::OpenFlags OF = sys::fs::OF_None; - if (Config.getTextWithCRLF()) - OF |= sys::fs::OF_TextWithCRLF; - else if (Config.getText()) - OF |= sys::fs::OF_Text; - if (Config.getAppend()) - OF |= sys::fs::OF_Append; + sys::fs::OpenFlags OF = generateFlagsFromConfig(Config); if (std::error_code EC = sys::fs::openFileForWrite( OutputPath, NewFD, sys::fs::CD_CreateAlways, OF)) return convertToOutputError(OutputPath, EC); diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 193e6ef6d1e64..151b59334cab1 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -1123,6 +1123,7 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { : MCSA_Global); OutStreamer->emitSymbolAttribute(Sym, isa<Function>(GO) ? MCSA_Code : MCSA_Data); + llvm::dbgs() << "TONY emitting " << Sym->getName() << "\n"; } } OutStreamer->switchSection( @@ -1699,6 +1700,61 @@ void SystemZAsmPrinter::emitPPA2(Module &M) { OutStreamer->popSection(); } +void SystemZAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { + if (TM.getTargetTriple().isOSzOS()) { + auto *Sym = getSymbol(GV); + OutStreamer->emitSymbolAttribute(Sym, MCSA_Data); + } + + AsmPrinter::emitGlobalVariable(GV); +} + +const MCExpr *SystemZAsmPrinter::lowerConstant(const Constant *CV, + const Constant *BaseCV, + uint64_t Offset) { + const Triple &TargetTriple = TM.getTargetTriple(); + + if (TargetTriple.isOSzOS()) { + const GlobalAlias *GA = dyn_cast<GlobalAlias>(CV); + const GlobalVariable *GV = dyn_cast<GlobalVariable>(CV); + const Function *FV = dyn_cast<Function>(CV); + bool IsFunc = !GV && (FV || (GA && isa<Function>(GA->getAliaseeObject()))); + + MCSymbol *Sym = NULL; + + if (GA) + Sym = getSymbol(GA); + else if (IsFunc) + Sym = getSymbol(FV); + else if (GV) + Sym = getSymbol(GV); + + if (IsFunc) { + OutStreamer->emitSymbolAttribute(Sym, MCSA_Code); + if (FV->hasExternalLinkage()) { + return MCSpecifierExpr::create(MCSymbolRefExpr::create(Sym, OutContext), + SystemZ::S_VCon, OutContext); + } + // Trigger creation of function descriptor in ADA for internal + // functions. + unsigned Disp = ADATable.insert(Sym, SystemZII::MO_ADA_DIRECT_FUNC_DESC); + return MCBinaryExpr::createAdd( + MCSpecifierExpr::create( + MCSymbolRefExpr::create( + getObjFileLowering().getADASection()->getBeginSymbol(), + OutContext), + SystemZ::S_None, OutContext), + MCConstantExpr::create(Disp, OutContext), OutContext); + } + if (Sym) { + OutStreamer->emitSymbolAttribute(Sym, MCSA_Data); + return MCSymbolRefExpr::create(Sym, OutContext); + } + } + + return AsmPrinter::lowerConstant(CV); +} + 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 cb101e472824f..5c7658dd3055b 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -130,6 +130,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { void emitFunctionEntryLabel() override; void emitFunctionBodyEnd() override; void emitStartOfAsmFile(Module &M) override; + void emitGlobalVariable(const GlobalVariable *GV) override; + const MCExpr *lowerConstant(const Constant *CV, const Constant *BaseCV = nullptr, uint64_t Offset = 0) override; private: void emitCallInformation(CallType CT); >From 7e735024caf847edbf916e22097c3470ecc7543f Mon Sep 17 00:00:00 2001 From: Tony Tao <[email protected]> Date: Wed, 19 Nov 2025 19:57:30 +0000 Subject: [PATCH 2/4] undo accdiental commit --- llvm/lib/Support/VirtualOutputBackends.cpp | 23 ++++++++-------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Support/VirtualOutputBackends.cpp b/llvm/lib/Support/VirtualOutputBackends.cpp index 33a56c7f5f607..de59b8ab63a53 100644 --- a/llvm/lib/Support/VirtualOutputBackends.cpp +++ b/llvm/lib/Support/VirtualOutputBackends.cpp @@ -254,18 +254,6 @@ static Error createDirectoriesOnDemand(StringRef OutputPath, }); } -static sys::fs::OpenFlags generateFlagsFromConfig(OutputConfig Config) { - sys::fs::OpenFlags OF = sys::fs::OF_None; - if (Config.getTextWithCRLF()) - OF |= sys::fs::OF_TextWithCRLF; - else if (Config.getText()) - OF |= sys::fs::OF_Text; - if (Config.getAppend()) - OF |= sys::fs::OF_Append; - - return OF; -} - Error OnDiskOutputFile::tryToCreateTemporary(std::optional<int> &FD) { // Create a temporary file. // Insert -%%%%%%%% before the extension (if any), and because some tools @@ -280,10 +268,9 @@ Error OnDiskOutputFile::tryToCreateTemporary(std::optional<int> &FD) { return createDirectoriesOnDemand(OutputPath, Config, [&]() -> Error { int NewFD; - sys::fs::OpenFlags OF = generateFlagsFromConfig(Config); SmallString<128> UniquePath; if (std::error_code EC = - sys::fs::createUniqueFile(ModelPath, NewFD, UniquePath, OF)) + sys::fs::createUniqueFile(ModelPath, NewFD, UniquePath)) return make_error<TempFileOutputError>(ModelPath, OutputPath, EC); if (Config.getDiscardOnSignal()) @@ -325,7 +312,13 @@ Error OnDiskOutputFile::initializeFile(std::optional<int> &FD) { // Not using a temporary file. Open the final output file. return createDirectoriesOnDemand(OutputPath, Config, [&]() -> Error { int NewFD; - sys::fs::OpenFlags OF = generateFlagsFromConfig(Config); + sys::fs::OpenFlags OF = sys::fs::OF_None; + if (Config.getTextWithCRLF()) + OF |= sys::fs::OF_TextWithCRLF; + else if (Config.getText()) + OF |= sys::fs::OF_Text; + if (Config.getAppend()) + OF |= sys::fs::OF_Append; if (std::error_code EC = sys::fs::openFileForWrite( OutputPath, NewFD, sys::fs::CD_CreateAlways, OF)) return convertToOutputError(OutputPath, EC); >From 3ba320b859221fbc6e44d1dfecfa559a2479db58 Mon Sep 17 00:00:00 2001 From: Tony Tao <[email protected]> Date: Fri, 14 Nov 2025 13:19:26 -0500 Subject: [PATCH 3/4] [Support] Prevent loss of file type flags when creating temporary (#167939) Non-binary output files from the compiler need the `OF_Text` flag set for encoding conversion to be performed correctly on z/OS. --------- Co-authored-by: Tony Tao <[email protected]> --- clang/test/CodeGen/SystemZ/encoding.c | 9 ++++++++ llvm/lib/Support/VirtualOutputBackends.cpp | 25 +++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/encoding.c diff --git a/clang/test/CodeGen/SystemZ/encoding.c b/clang/test/CodeGen/SystemZ/encoding.c new file mode 100644 index 0000000000000..d018a9c37852a --- /dev/null +++ b/clang/test/CodeGen/SystemZ/encoding.c @@ -0,0 +1,9 @@ +// Checks encoding of output file +// This is only required for z/OS. +// +// REQUIRES: system-zos, systemz-registered-target +// RUN: %clang_cc1 -triple s390x-ibm-zos -S %s -o %t.s +// RUN: ls -T %t.s | FileCheck %s + +// CHECK: t IBM-1047 T=on +void foo() { return; } diff --git a/llvm/lib/Support/VirtualOutputBackends.cpp b/llvm/lib/Support/VirtualOutputBackends.cpp index de59b8ab63a53..f9c8f1302e6c5 100644 --- a/llvm/lib/Support/VirtualOutputBackends.cpp +++ b/llvm/lib/Support/VirtualOutputBackends.cpp @@ -254,6 +254,20 @@ static Error createDirectoriesOnDemand(StringRef OutputPath, }); } +static sys::fs::OpenFlags generateFlagsFromConfig(OutputConfig Config) { + sys::fs::OpenFlags OF = sys::fs::OF_None; + if (Config.getTextWithCRLF()) + OF |= sys::fs::OF_TextWithCRLF; + else if (Config.getText()) + OF |= sys::fs::OF_Text; + // Don't pass OF_Append if writting to temporary since OF_Append is + // not Atomic Append + if (Config.getAppend() && !Config.getAtomicWrite()) + OF |= sys::fs::OF_Append; + + return OF; +} + Error OnDiskOutputFile::tryToCreateTemporary(std::optional<int> &FD) { // Create a temporary file. // Insert -%%%%%%%% before the extension (if any), and because some tools @@ -269,8 +283,9 @@ Error OnDiskOutputFile::tryToCreateTemporary(std::optional<int> &FD) { return createDirectoriesOnDemand(OutputPath, Config, [&]() -> Error { int NewFD; SmallString<128> UniquePath; + sys::fs::OpenFlags OF = generateFlagsFromConfig(Config); if (std::error_code EC = - sys::fs::createUniqueFile(ModelPath, NewFD, UniquePath)) + sys::fs::createUniqueFile(ModelPath, NewFD, UniquePath, OF)) return make_error<TempFileOutputError>(ModelPath, OutputPath, EC); if (Config.getDiscardOnSignal()) @@ -312,13 +327,7 @@ Error OnDiskOutputFile::initializeFile(std::optional<int> &FD) { // Not using a temporary file. Open the final output file. return createDirectoriesOnDemand(OutputPath, Config, [&]() -> Error { int NewFD; - sys::fs::OpenFlags OF = sys::fs::OF_None; - if (Config.getTextWithCRLF()) - OF |= sys::fs::OF_TextWithCRLF; - else if (Config.getText()) - OF |= sys::fs::OF_Text; - if (Config.getAppend()) - OF |= sys::fs::OF_Append; + sys::fs::OpenFlags OF = generateFlagsFromConfig(Config); if (std::error_code EC = sys::fs::openFileForWrite( OutputPath, NewFD, sys::fs::CD_CreateAlways, OF)) return convertToOutputError(OutputPath, EC); >From 903ea3977745b15ff8bcae99af61ddc2a8a9cfc3 Mon Sep 17 00:00:00 2001 From: Tony Tao <[email protected]> Date: Fri, 21 Nov 2025 13:58:15 -0500 Subject: [PATCH 4/4] implement more features --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 36 ++++++++++++++++++- llvm/lib/Target/SystemZ/SystemZAsmPrinter.h | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 151b59334cab1..17e71ec760095 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -347,7 +347,7 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { case SystemZ::ADA_ENTRY: { const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>(); const SystemZInstrInfo *TII = Subtarget.getInstrInfo(); - uint32_t Disp = ADATable.insert(MI->getOperand(1)); + uint32_t Disp = ADATable.insert(MI->getOperand(1)); Register TargetReg = MI->getOperand(0).getReg(); Register ADAReg = MI->getOperand(2).getReg(); @@ -373,6 +373,8 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { Disp = 0; Op = Op0; } + OutStreamer->AddComment(Twine("Loading from ADA at offset ") + .concat(utostr(Disp))); EmitToStreamer(*OutStreamer, MCInstBuilder(Op) .addReg(TargetReg) .addReg(ADAReg) @@ -1755,6 +1757,38 @@ const MCExpr *SystemZAsmPrinter::lowerConstant(const Constant *CV, return AsmPrinter::lowerConstant(CV); } +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 = MCSpecifierExpr::create(MCSymbolRefExpr::create(Sym, OutContext), + SystemZ::S_VCon, 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 5c7658dd3055b..003e9af7c2ca8 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -131,6 +131,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { void emitFunctionBodyEnd() override; void emitStartOfAsmFile(Module &M) override; void emitGlobalVariable(const GlobalVariable *GV) override; + void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override; const MCExpr *lowerConstant(const Constant *CV, const Constant *BaseCV = nullptr, uint64_t Offset = 0) override; private: _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
