https://github.com/sujianIBM created https://github.com/llvm/llvm-project/pull/207416
This PR adds options -m[no-]zos-ppa1-name to remove the function name in PPA1 on z/OS. >From bec5141a9a339c59cf763e6695c36ba3f368f39b Mon Sep 17 00:00:00 2001 From: sujianIBM <[email protected]> Date: Fri, 3 Jul 2026 11:25:51 -0400 Subject: [PATCH] Add options -m[no-]zos-ppa1-name to remove the function name in PPA1 on z/OS. (#2) This PR adds options -m[no-]zos-ppa1-name to remove the function name in PPA1 on z/OS. --- clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/LangOptions.h | 10 ++++ clang/include/clang/Options/Options.td | 7 +++ clang/lib/CodeGen/Targets/SystemZ.cpp | 13 +++++ clang/lib/Driver/ToolChains/ZOS.cpp | 2 + clang/lib/Frontend/CompilerInvocation.cpp | 15 ++++++ clang/test/CodeGen/SystemZ/zos-ppa1-name.c | 19 +++++++ clang/test/Driver/zos-ppa1-name.c | 15 ++++++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 12 ++++- llvm/test/CodeGen/SystemZ/zos-ppa1.ll | 54 +++++++++++++++++++ 10 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGen/SystemZ/zos-ppa1-name.c create mode 100644 clang/test/Driver/zos-ppa1-name.c diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index b4d03a1a3e0b5..935c95846d4f6 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -295,6 +295,8 @@ LANGOPT(ConstantNSDictionaryLiterals , 1, 0, NotCompatible, "constant dictionary LANGOPT(InlineVisibilityHidden , 1, 0, Benign, "hidden visibility for inline C++ methods") ENUM_LANGOPT(DefaultVisibilityExportMapping, DefaultVisiblityExportMapping, 2, DefaultVisiblityExportMapping::None, Benign, "controls mapping of default visibility to dllexport") LANGOPT(IgnoreXCOFFVisibility, 1, 0, Benign, "All the visibility attributes that are specified in the source code are ignored in aix XCOFF.") +ENUM_LANGOPT(ZOSPPA1Name, ZOSPPA1NameKind, 2, ZOSPPA1NameKind::Default, Benign, + "Emit the function name in PPA1 on z/OS.") LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0, Benign, "hidden visibility for static local variables in inline C++ " "methods when -fvisibility-inlines hidden is enabled") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 6c86300fc5581..fceac5c2946f2 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -451,6 +451,16 @@ class LangOptionsBase { Microsoft = 2, }; + enum class ZOSPPA1NameKind { + /// Optimization for size level decides whether to emit the function name + /// in PPA1 on z/OS. + Default, + /// Emit the function name in PPA1 on z/OS. + Emit, + /// Do not emit the function name in PPA1 on z/OS. + NoEmit, + }; + // Define simple language options (with no accessors). #define LANGOPT(Name, Bits, Default, Compatibility, Description) \ unsigned Name : Bits; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 2f0e2b03fdb09..7e9dbb1a03dd8 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -6092,6 +6092,13 @@ defm backchain : BoolMOption<"backchain", PosFlag<SetTrue, [], [ClangOption], "Link stack frames through backchain on System Z">, NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>; +def mzos_ppa1_name : Flag<["-"], "mzos-ppa1-name">, Group<m_Group>, + Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Emit the function name in PPA1 on z/OS">; +def mno_zos_ppa1_name : Flag<["-"], "mno-zos-ppa1-name">, Group<m_Group>, + Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option]>, + HelpText<"Do not emit the function name in PPA1 on z/OS">; + def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>; def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>; def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>, diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index 37f6b3017f776..10f69ef379ba6 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -595,6 +595,19 @@ class ZOSXPLinkTargetCodeGenInfo : public TargetCodeGenInfo { SwiftInfo = std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override { + if (dyn_cast_or_null<FunctionDecl>(D)) { + if (auto *Fn = dyn_cast<llvm::Function>(GV)) { + auto ZOSPPA1Name = M.getLangOpts().getZOSPPA1Name(); + if (ZOSPPA1Name == clang::LangOptions::ZOSPPA1NameKind::Emit) + Fn->addFnAttr("zos-ppa1-name", "all"); + else if (ZOSPPA1Name == clang::LangOptions::ZOSPPA1NameKind::NoEmit) + Fn->addFnAttr("zos-ppa1-name", "none"); + } + } + } }; } // namespace diff --git a/clang/lib/Driver/ToolChains/ZOS.cpp b/clang/lib/Driver/ToolChains/ZOS.cpp index da4aaa28cd1da..bc4ff08e6e2c6 100644 --- a/clang/lib/Driver/ToolChains/ZOS.cpp +++ b/clang/lib/Driver/ToolChains/ZOS.cpp @@ -49,6 +49,8 @@ void ZOS::addClangTargetOptions(const ArgList &DriverArgs, if (!DriverArgs.hasArgNoClaim(options::OPT_fsized_deallocation, options::OPT_fno_sized_deallocation)) CC1Args.push_back("-fno-sized-deallocation"); + + DriverArgs.AddLastArg(CC1Args, options::OPT_mzos_ppa1_name, options::OPT_mno_zos_ppa1_name); } void zos::Assembler::ConstructJob(Compilation &C, const JobAction &JA, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 50a2359c0e986..5afe8487a9a21 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3822,6 +3822,11 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, if (Opts.IgnoreXCOFFVisibility) GenerateArg(Consumer, OPT_mignore_xcoff_visibility); + if (Opts.getZOSPPA1Name() == LangOptions::ZOSPPA1NameKind::Emit) + GenerateArg(Consumer, OPT_mzos_ppa1_name); + else if (Opts.getZOSPPA1Name() == LangOptions::ZOSPPA1NameKind::NoEmit) + GenerateArg(Consumer, OPT_mno_zos_ppa1_name); + if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) { GenerateArg(Consumer, OPT_ftrapv); GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler); @@ -4241,6 +4246,16 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility))) Opts.IgnoreXCOFFVisibility = 1; + if (T.isOSzOS()) { + if (const Arg *A = Args.getLastArg(OPT_mzos_ppa1_name, + OPT_mno_zos_ppa1_name)) { + if (A->getOption().matches(OPT_mzos_ppa1_name)) + Opts.setZOSPPA1Name(LangOptions::ZOSPPA1NameKind::Emit); + else + Opts.setZOSPPA1Name(LangOptions::ZOSPPA1NameKind::NoEmit); + } + } + if (Args.hasArg(OPT_ftrapv)) { Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); // Set the handler, if one is specified. diff --git a/clang/test/CodeGen/SystemZ/zos-ppa1-name.c b/clang/test/CodeGen/SystemZ/zos-ppa1-name.c new file mode 100644 index 0000000000000..e49c6ae7a20ca --- /dev/null +++ b/clang/test/CodeGen/SystemZ/zos-ppa1-name.c @@ -0,0 +1,19 @@ +// REQUIRES: systemz-registered-target + +// test default +// RUN: %clang_cc1 -triple s390x-ibm-zos -emit-llvm %s -o -\ +// RUN: | FileCheck %s -check-prefix=DEFAULT + +// test the positive and negative options +// RUN: %clang_cc1 -triple s390x-ibm-zos -mzos-ppa1-name -emit-llvm %s -o -\ +// RUN: | FileCheck %s -check-prefix=EMIT-NAME +// RUN: %clang_cc1 -triple s390x-ibm-zos -mno-zos-ppa1-name -emit-llvm %s -o -\ +// RUN: | FileCheck %s -check-prefix=NOT-EMIT-NAME + +// DEFAULT-NOT: attributes #0 = {{{.*}}"zos-ppa1-name"{{.*}}} +// EMIT-NAME: attributes #0 = {{{.*}}"zos-ppa1-name"="all"{{.*}}} +// NOT-EMIT-NAME: attributes #0 = {{{.*}}"zos-ppa1-name"="none"{{.*}}} + +int main() { + return 0; +} diff --git a/clang/test/Driver/zos-ppa1-name.c b/clang/test/Driver/zos-ppa1-name.c new file mode 100644 index 0000000000000..a5a1f9ca2486e --- /dev/null +++ b/clang/test/Driver/zos-ppa1-name.c @@ -0,0 +1,15 @@ +// REQUIRES: systemz-registered-target + +// RUN: %clang -### -target s390x-ibm-zos -mzos-ppa1-name -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=EMIT-NAME %s +// EMIT-NAME: "-mzos-ppa1-name" + +// RUN: %clang -### -target s390x-ibm-zos -mno-zos-ppa1-name -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=NOT-EMIT-NAME %s +// NOT-EMIT-NAME: "-mno-zos-ppa1-name" + +// RUN: not %clang -target systemz-unknown-elf -mzos-ppa1-name -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=ERR %s +// RUN: not %clang -target systemz-unknown-elf -mno-zos-ppa1-name -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=ERR %s +// ERR: error: unsupported option '-m{{.*}}zos-ppa1-name' for target 'systemz-unknown-elf' diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 5c755db5f7f5f..6dbe55b63b2a8 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -1756,7 +1756,17 @@ void SystemZAsmPrinter::calculatePPA1() { : ""); // Save the calculated values. - if (MF->getFunction().hasName()) + // Whether to emit the function name is decided by optimization level, + // unless it is explicitly required via -m[no-]zos-ppa1-name options. + bool IncludeFunctionName = !MF->getFunction().hasMinSize(); + if (MF->getFunction().hasFnAttribute("zos-ppa1-name")) { + auto ZOSPPA1Name = + MF->getFunction().getFnAttribute("zos-ppa1-name").getValueAsString(); + assert((ZOSPPA1Name == "all" || ZOSPPA1Name == "none") && + "Invalid value for attribute zos-ppa1-name."); + IncludeFunctionName = ZOSPPA1Name == "all"; + } + if (MF->getFunction().hasName() && IncludeFunctionName) Info.Name = MF->getFunction().getName(); Info.PPA1 = OutContext.createTempSymbol(Twine("PPA1_").concat(N), true); Info.EPMarker = OutContext.createTempSymbol(Twine("EPM_").concat(N), true); diff --git a/llvm/test/CodeGen/SystemZ/zos-ppa1.ll b/llvm/test/CodeGen/SystemZ/zos-ppa1.ll index 88790a9a45ddb..326de409bb2b3 100644 --- a/llvm/test/CodeGen/SystemZ/zos-ppa1.ll +++ b/llvm/test/CodeGen/SystemZ/zos-ppa1.ll @@ -50,3 +50,57 @@ define void @void_test() { entry: ret void } + +; Attribute "zos-ppa1-name"="none" removes the function name from PPA1. +; CHECK: * PPA1 +; CHECK-NEXT: L#PPA1_void_test_no_name_0 DS 0H +; CHECK: * PPA1 Flags 4 +; CHECK-NEXT: DC XL1'80' +; CHECK-NEXT: * Length/4 of Parms +; CHECK-NEXT: DC XL2'0000' +; CHECK-NEXT: * Length of Code +; CHECK-NEXT: DC AD(L#void_test_no_name_end_0-L#EPM_void_test_no_name_0) +; CHECK-NEXT: DC AD(L#EPM_void_test_no_name_0-L#PPA1_void_test_no_name_0) +define void @void_test_no_name() #0 { +entry: + ret void +} +attributes #0 = { "zos-ppa1-name"="none" } + +; Attribute minsize removes the function name from PPA1. +; CHECK: * PPA1 +; CHECK-NEXT: L#PPA1_void_test_minsize_0 DS 0H +; CHECK: * PPA1 Flags 4 +; CHECK-NEXT: DC XL1'80' +; CHECK-NEXT: * Length/4 of Parms +; CHECK-NEXT: DC XL2'0000' +; CHECK-NEXT: * Length of Code +; CHECK-NEXT: DC AD(L#void_test_minsize_end_0-L#EPM_void_test_minsize_0) +; CHECK-NEXT: DC AD(L#EPM_void_test_minsize_0-L#PPA1_void_test_minsize_0) +define void @void_test_minsize() #1 { +entry: + ret void +} +attributes #1 = { minsize } + +; Attribute "zos-ppa1-name"="all" takes precedence over minsize, +; and thus emits the function name in PPA1. +; CHECK: * PPA1 +; CHECK-NEXT: L#PPA1_void_test_name_0 DS 0H +; CHECK: * PPA1 Flags 4 +; CHECK-NEXT: * Bit 7: 1 = Name Length and Name +; CHECK-NEXT: DC XL1'81' +; CHECK-NEXT: * Length/4 of Parms +; CHECK-NEXT: DC XL2'0000' +; CHECK-NEXT: * Length of Code +; CHECK-NEXT: DC AD(L#void_test_name_end_0-L#EPM_void_test_name_0) +; CHECK-NEXT: * Length of Name +; CHECK-NEXT: DC XL2'000E' +; CHECK-NEXT: * Name of Function +; CHECK-NEXT: DC XL14'A59689846DA385A2A36D95819485' +; CHECK-NEXT: DC AD(L#EPM_void_test_name_0-L#PPA1_void_test_name_0) +define void @void_test_name() #2 { +entry: + ret void +} +attributes #2 = { "zos-ppa1-name"="all" minsize } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
