Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Options/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6068,6 +6068,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>,
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/CodeGen/Targets/SystemZ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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", "emit");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just a minor tweak on the attribute values.

Let's use all and none. I see these values are used for frame-pointer. This leaves us the ability to add behaviour like non-leaf down the road (i.e. don't add the name to ppa1 if this function doesn't call anything).

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, I have made the suggested change. Would you please take another look? Thanks!

else if (ZOSPPA1Name == clang::LangOptions::ZOSPPA1NameKind::NoEmit)
Fn->addFnAttr("zos-ppa1-name", "no-emit");
}
}
}
};

} // namespace
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/ZOS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3809,6 +3809,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);
Expand Down Expand Up @@ -4227,6 +4232,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.
Expand Down
19 changes: 19 additions & 0 deletions clang/test/CodeGen/SystemZ/zos-ppa1-name.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// REQUIRES: systemz-registered-target

// test default
Comment thread
sujianIBM marked this conversation as resolved.
// 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"="emit"{{.*}}}
// NOT-EMIT-NAME: attributes #0 = {{{.*}}"zos-ppa1-name"="no-emit"{{.*}}}

int main() {
return 0;
}
15 changes: 15 additions & 0 deletions clang/test/Driver/zos-ppa1-name.c
Original file line number Diff line number Diff line change
@@ -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'
12 changes: 11 additions & 1 deletion llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 == "emit" || ZOSPPA1Name == "no-emit") &&
"Invalid value for attribute zos-ppa1-name.");
IncludeFunctionName = ZOSPPA1Name == "emit";
}
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);
Expand Down
54 changes: 54 additions & 0 deletions llvm/test/CodeGen/SystemZ/zos-ppa1.ll
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,57 @@ define void @void_test() {
entry:
ret void
}

; Attribute "zos-ppa1-name"="no-emit" 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"="no-emit" }

; 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"="emit" 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"="emit" minsize }