Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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", "all");
else if (ZOSPPA1Name == clang::LangOptions::ZOSPPA1NameKind::NoEmit)
Fn->addFnAttr("zos-ppa1-name", "none");
}
}
}
};

} // 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"="all"{{.*}}}
// NOT-EMIT-NAME: attributes #0 = {{{.*}}"zos-ppa1-name"="none"{{.*}}}

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