https://github.com/ysyeda updated https://github.com/llvm/llvm-project/pull/68926
>From 5ea8bea2bdf345e2baee07e0a94ac40bd0f109c4 Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Thu, 12 Oct 2023 16:56:27 -0400 Subject: [PATCH 1/8] This change adds support for the PPA2 section in zOS --- clang/include/clang/Basic/LangStandard.h | 1 + clang/lib/Basic/LangStandards.cpp | 39 ++++ clang/lib/CodeGen/CodeGenModule.cpp | 15 ++ clang/lib/Driver/ToolChains/Clang.cpp | 13 +- clang/lib/Driver/ToolChains/Clang.h | 3 +- clang/test/CodeGen/SystemZ/systemz-ppa2.c | 25 +++ llvm/include/llvm/BinaryFormat/GOFF.h | 1 + llvm/include/llvm/MC/MCObjectFileInfo.h | 4 + llvm/lib/MC/MCObjectFileInfo.cpp | 5 + llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 197 +++++++++++++++++- llvm/lib/Target/SystemZ/SystemZAsmPrinter.h | 7 +- llvm/test/CodeGen/SystemZ/zos-ppa2.ll | 26 +++ 12 files changed, 331 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGen/SystemZ/systemz-ppa2.c create mode 100644 llvm/test/CodeGen/SystemZ/zos-ppa2.ll diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h index 6356f16acc811e0..d94567adf2bfb99 100644 --- a/clang/include/clang/Basic/LangStandard.h +++ b/clang/include/clang/Basic/LangStandard.h @@ -43,6 +43,7 @@ enum class Language : uint8_t { HLSL, ///@} }; +const char *LanguageToString(Language L); enum LangFeatures { LineComment = (1 << 0), diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp index af9cf4f273920ee..e9b75d78e820a64 100644 --- a/clang/lib/Basic/LangStandards.cpp +++ b/clang/lib/Basic/LangStandards.cpp @@ -10,9 +10,48 @@ #include "clang/Config/config.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/TargetParser/Triple.h" using namespace clang; +const char *clang::LanguageToString(Language L) { + // I would like to make this function and the definition of Language + // in the .h file simply expand the contents of a .def file. + // However, in the .h the members of the enum have doxygen annotations + // and/or comments which would be lost. + switch (L) { + case Language::Unknown: + return "Unknown"; + case Language::Asm: + return "Asm"; + case Language::LLVM_IR: + return "LLVM_IR"; + case Language::C: + return "C"; + case Language::CXX: + return "CXX"; + case Language::ObjC: + return "ObjC"; + case Language::ObjCXX: + return "ObjCXX"; + case Language::OpenCL: + return "OpenCL"; + case Language::OpenCLCXX: + return "OpenCLCXX"; + case Language::CUDA: + return "CUDA"; + case Language::RenderScript: + return "RenderScript"; + case Language::HIP: + return "HIP"; + case Language::HLSL: + return "HLSL"; + } + + std::string msg = llvm::formatv("Unknown value ({0}) passed to LanguageToString", (unsigned int) L); + llvm_unreachable(msg.c_str()); +} + #define LANGSTANDARD(id, name, lang, desc, features) \ static const LangStandard Lang_##id = {name, desc, features, Language::lang}; #include "clang/Basic/LangStandards.def" diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 754377bed7f7eef..4fd5f8ad2d94c55 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -976,6 +976,21 @@ void CodeGenModule::Release() { Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity(); getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth); + if (getTriple().isOSzOS()) { + int32_t ProductVersion, ProductRelease, ProductPatch; + ProductVersion = LLVM_VERSION_MAJOR, + ProductRelease = LLVM_VERSION_MINOR, ProductPatch = LLVM_VERSION_PATCH; + getModule().addModuleFlag(llvm::Module::Warning, "Product Major Version", ProductVersion); + getModule().addModuleFlag(llvm::Module::Warning, "Product Minor Version", ProductRelease); + getModule().addModuleFlag(llvm::Module::Warning, "Product Patchlevel", ProductPatch); + + // Record the language because we need it for the PPA2. + const char *lang_str = LanguageToString( + LangStandard::getLangStandardForKind(LangOpts.LangStd).Language); + getModule().addModuleFlag(llvm::Module::Error, "zos_cu_language", + llvm::MDString::get(VMContext, lang_str)); + } + llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch(); if ( Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index b91126ebed0186c..4f02fa2fc3c788a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1738,7 +1738,7 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple, break; case llvm::Triple::systemz: - AddSystemZTargetArgs(Args, CmdArgs); + AddSystemZTargetArgs(EffectiveTriple, Args, CmdArgs); break; case llvm::Triple::x86: @@ -2235,7 +2235,8 @@ void Clang::AddSparcTargetArgs(const ArgList &Args, } } -void Clang::AddSystemZTargetArgs(const ArgList &Args, +void Clang::AddSystemZTargetArgs(const llvm::Triple &Triple, + const ArgList &Args, ArgStringList &CmdArgs) const { if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) { CmdArgs.push_back("-tune-cpu"); @@ -2267,6 +2268,14 @@ void Clang::AddSystemZTargetArgs(const ArgList &Args, CmdArgs.push_back("-mfloat-abi"); CmdArgs.push_back("soft"); } + + if (Triple.isOSzOS()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back( + Args.MakeArgString(llvm::Twine("-translation-time=") + .concat(llvm::Twine(std::time(nullptr))) + .str())); + } } void Clang::AddX86TargetArgs(const ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h index 0f503c4bd1c4fea..9f065f846b4cf34 100644 --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -69,7 +69,8 @@ class LLVM_LIBRARY_VISIBILITY Clang : public Tool { llvm::opt::ArgStringList &CmdArgs) const; void AddSparcTargetArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; - void AddSystemZTargetArgs(const llvm::opt::ArgList &Args, + void AddSystemZTargetArgs(const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; void AddX86TargetArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; diff --git a/clang/test/CodeGen/SystemZ/systemz-ppa2.c b/clang/test/CodeGen/SystemZ/systemz-ppa2.c new file mode 100644 index 000000000000000..8f396fc12c75fca --- /dev/null +++ b/clang/test/CodeGen/SystemZ/systemz-ppa2.c @@ -0,0 +1,25 @@ +// Please note the following: +// + we are checking that the first bytes of the PPA2 are 0x3 0x0 +// for C, and 0x3 0x1 for C++ +// + the label for the PPA2 seems to vary on different versions. +// We try to cover all cases, and use substitution blocks to +// help write the tests. The contents of the PPA2 itself should +// not be different. +// + the [[:space:]] combines the two .byte lines into one pattern. +// This is necessary because if the lines were separated, the first +// .byte (i.e., the one for the 3) would, it seems, also match +// the .byte line below for the 34. + +// RUN: %clang --target=s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C +// CHECK-C: [[PPA2:(.L)|(@@)PPA2]]: +// CHECK-C-NEXT: .byte 3{{[[:space:]]*}}.byte 0 +// CHECK-C-NEXT: .byte 34{{$}} +// CHECK-C-NEXT: .byte {{4}} +// CHECK-C-NEXT: .long {{(CELQSTRT)}}-[[PPA2]] + +// RUN: %clang --target=s390x-ibm-zos -xc++ -S -o - %s | FileCheck %s --check-prefix CHECK-CXX +// CHECK-CXX: [[PPA2:(.L)|(@@)PPA2]]: +// CHECK-CXX-NEXT: .byte 3{{[[:space:]]*}}.byte 1 +// CHECK-CXX-NEXT: .byte 34{{$}} +// CHECK-CXX-NEXT: .byte {{4}} +// CHECK-CXX-NEXT: .long {{(CELQSTRT)}}-[[PPA2]] diff --git a/llvm/include/llvm/BinaryFormat/GOFF.h b/llvm/include/llvm/BinaryFormat/GOFF.h index f1a30e41b736bda..443bcfc9479a8bc 100644 --- a/llvm/include/llvm/BinaryFormat/GOFF.h +++ b/llvm/include/llvm/BinaryFormat/GOFF.h @@ -167,6 +167,7 @@ enum ENDEntryPointRequest : uint8_t { // \brief Subsections of the primary C_CODE section in the object file. enum SubsectionKind : uint8_t { SK_PPA1 = 2, + SK_PPA2 = 4, }; } // end namespace GOFF diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h index 54f696cb795fbc1..2b2adf5012defae 100644 --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -227,7 +227,9 @@ class MCObjectFileInfo { // GOFF specific sections. MCSection *PPA1Section = nullptr; + MCSection *PPA2Section = nullptr; MCSection *ADASection = nullptr; + MCSection *IDRLSection = nullptr; // XCOFF specific sections MCSection *TOCBaseSection = nullptr; @@ -431,7 +433,9 @@ class MCObjectFileInfo { // GOFF specific sections. MCSection *getPPA1Section() const { return PPA1Section; } + MCSection *getPPA2Section() const { return PPA2Section; } MCSection *getADASection() const { return ADASection; } + MCSection *getIDRLSection() const { return IDRLSection; } // XCOFF specific sections MCSection *getTOCBaseSection() const { return TOCBaseSection; } diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 0b5109e41e71711..1b30645cea3c1ca 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -547,8 +547,13 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { PPA1Section = Ctx->getGOFFSection(".ppa1", SectionKind::getMetadata(), TextSection, MCConstantExpr::create(GOFF::SK_PPA1, *Ctx)); + PPA2Section = + Ctx->getGOFFSection(".ppa2", SectionKind::getMetadata(), TextSection, + MCConstantExpr::create(GOFF::SK_PPA2, *Ctx)); ADASection = Ctx->getGOFFSection(".ada", SectionKind::getData(), nullptr, nullptr); + IDRLSection = + Ctx->getGOFFSection("B_IDRL", SectionKind::getData(), nullptr, nullptr); } void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index b3075c150ebb36f..d963009c6c158f7 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -27,10 +27,20 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/Chrono.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertEBCDIC.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FormatProviders.h" +#include "llvm/Support/FormatVariadic.h" using namespace llvm; +cl::opt<uint64_t> TranslationTime( + "translation-time", + cl::desc("sets the time of compilation in seconds since epoch"), + cl::init(0)); + // Return an RI instruction like MI with opcode Opcode, but with the // GR64 register operands turned into GR32s. static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { @@ -953,6 +963,7 @@ void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) { auto TT = OutContext.getTargetTriple(); if (TT.isOSzOS()) { emitADASection(); + emitIDRLSection(M); } emitAttributes(M); } @@ -1026,6 +1037,68 @@ void SystemZAsmPrinter::emitADASection() { OutStreamer->popSection(); } +static uint32_t getProductVersion(Module &M) { + if (auto *VersionVal = cast_or_null<ConstantAsMetadata>( + M.getModuleFlag("Product Major Version"))) + return cast<ConstantInt>(VersionVal->getValue())->getZExtValue(); + return LLVM_VERSION_MAJOR; +} + +static uint32_t getProductRelease(Module &M) { + if (auto *ReleaseVal = cast_or_null<ConstantAsMetadata>( + M.getModuleFlag("Product Minor Version"))) + return cast<ConstantInt>(ReleaseVal->getValue())->getZExtValue(); + return LLVM_VERSION_MINOR; +} + +static uint32_t getProductPatch(Module &M) { + if (auto *PatchVal = cast_or_null<ConstantAsMetadata>( + M.getModuleFlag("Product Patchlevel"))) + return cast<ConstantInt>(PatchVal->getValue())->getZExtValue(); + return LLVM_VERSION_PATCH; +} + +void SystemZAsmPrinter::emitIDRLSection(Module &M) { + OutStreamer->pushSection(); + OutStreamer->switchSection(getObjFileLowering().getIDRLSection()); + constexpr unsigned IDRLDataLength = 30; + std::time_t Time = TranslationTime; + + uint32_t ProductVersion = getProductVersion(M); + uint32_t ProductRelease = getProductRelease(M); + + std::string ProductID; + if (auto *MD = M.getModuleFlag("Product Id")) + ProductID = cast<MDString>(MD)->getString().str(); + + if (ProductID.empty()) { + char ProductIDFormatted[11]; // 10 + null. + snprintf(ProductIDFormatted, sizeof(ProductIDFormatted), "LLVM %02d%02d", + ProductVersion, ProductRelease); + ProductID = ProductIDFormatted; + } + + // Remove - from Product Id, which makes it consistent with legacy. + // The binder expects alphanumeric characters only. + std::size_t DashFound = ProductID.find("-"); + if (DashFound != std::string::npos) + ProductID.erase(ProductID.begin() + DashFound); + + SmallString<IDRLDataLength + 1> TempStr; + raw_svector_ostream O(TempStr); + O << formatv("{0}{1,0-2:d}{2,0-2:d}{3:%Y-%m-%d %H:%M:%S}", ProductID.c_str(), + ProductVersion, ProductRelease, llvm::sys::toUtcTime(Time)); + SmallString<IDRLDataLength> Data; + + ConverterEBCDIC::convertToEBCDIC(TempStr, Data); + + OutStreamer->emitInt8(0); // Reserved. + OutStreamer->emitInt8(3); // Format. + OutStreamer->emitInt16(IDRLDataLength); // Length. + OutStreamer->emitBytes(Data.str()); + OutStreamer->popSection(); +} + void SystemZAsmPrinter::emitFunctionBodyEnd() { if (TM.getTargetTriple().isOSzOS()) { // Emit symbol for the end of function if the z/OS target streamer @@ -1150,6 +1223,8 @@ static void emitPPA1Name(std::unique_ptr<MCStreamer> &OutStreamer, } void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) { + assert(PPA2Sym != nullptr && "PPA2 Symbol not defined"); + const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo(); const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>(); const auto TargetHasVector = Subtarget.hasVector(); @@ -1239,6 +1314,8 @@ void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) { OutStreamer->emitInt8(0xCE); // CEL signature. OutStreamer->AddComment("Saved GPR Mask"); OutStreamer->emitInt16(SavedGPRMask); + OutStreamer->AddComment("Offset to PPA2"); + OutStreamer->emitAbsoluteSymbolDiff(PPA2Sym, CurrentFnPPA1Sym, 4); bool HasName = MF->getFunction().hasName() && MF->getFunction().getName().size() > 0; @@ -1296,6 +1373,124 @@ void SystemZAsmPrinter::emitPPA1(MCSymbol *FnEndSym) { 4); } +void SystemZAsmPrinter::emitStartOfAsmFile(Module &M) { + if (TM.getTargetTriple().isOSzOS()) + emitPPA2(M); + AsmPrinter::emitStartOfAsmFile(M); +} + +void SystemZAsmPrinter::emitPPA2(Module &M) { + OutStreamer->pushSection(); + OutStreamer->switchSection(getObjFileLowering().getPPA2Section()); + MCContext &OutContext = OutStreamer->getContext(); + // Make CELQSTRT symbol. + const char *StartSymbolName = "CELQSTRT"; + MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName); + + // Create symbol and assign to class field for use in PPA1. + PPA2Sym = OutContext.createTempSymbol("PPA2", false); + MCSymbol *DateVersionSym = OutContext.createTempSymbol("DVS", false); + + std::time_t Time = TranslationTime; + SmallString<15> CompilationTime; // 14 + null + raw_svector_ostream O(CompilationTime); + O << formatv("{0:%Y%m%d%H%M%S}", llvm::sys::toUtcTime(Time)); + + uint32_t ProductVersion = getProductVersion(M), + ProductRelease = getProductRelease(M), + ProductPatch = getProductPatch(M); + + SmallString<7> Version; // 6 + null + raw_svector_ostream ostr(Version); + ostr << formatv("{0,0-2:d}{1,0-2:d}{2,0-2:d}", ProductVersion, + ProductRelease, ProductPatch); + + // Drop 0 during conversion. + SmallString<sizeof(CompilationTime) - 1> CompilationTimeStr; + SmallString<sizeof(Version) - 1> VersionStr; + + ConverterEBCDIC::convertToEBCDIC(CompilationTime, CompilationTimeStr); + ConverterEBCDIC::convertToEBCDIC(Version, VersionStr); + + enum class PPA2MemberId : uint8_t { + // See z/OS Language Environment Vendor Interfaces v2r5, p.23, for + // complete list. Only the C runtime is supported by this backend. + LE_C_Runtime = 3, + }; + enum class PPA2MemberSubId : uint8_t { + // List of languages using the LE C runtime implementation. + C = 0x00, + CXX = 0x01, + Swift = 0x03, + Go = 0x60, + LLVMBasedLang = 0xe7, + }; + // PPA2 Flags + enum class PPA2Flags : uint8_t { + CompileForBinaryFloatingPoint = 0x80, + CompiledWithXPLink = 0x01, + CompiledUnitASCII = 0x04, + HasServiceInfo = 0x20, + }; + + PPA2MemberSubId MemberSubId = PPA2MemberSubId::LLVMBasedLang; + if (auto *MD = M.getModuleFlag("zos_cu_language")) { + StringRef Language = cast<MDString>(MD)->getString(); + MemberSubId = StringSwitch<PPA2MemberSubId>(Language) + .Case("C", PPA2MemberSubId::C) + .Case("CXX", PPA2MemberSubId::CXX) + .Case("Swift", PPA2MemberSubId::Swift) + .Case("Go", PPA2MemberSubId::Go) + .Default(PPA2MemberSubId::LLVMBasedLang); + } + + // Emit PPA2 section. + OutStreamer->emitLabel(PPA2Sym); + OutStreamer->emitInt8(static_cast<uint8_t>(PPA2MemberId::LE_C_Runtime)); + OutStreamer->emitInt8(static_cast<uint8_t>(MemberSubId)); + OutStreamer->emitInt8(0x22); // Member defined, c370_plist+c370_env + OutStreamer->emitInt8(0x04); // Control level 4 (XPLink) + OutStreamer->emitAbsoluteSymbolDiff(CELQSTRT, PPA2Sym, 4); + OutStreamer->emitInt32(0x00000000); + OutStreamer->emitAbsoluteSymbolDiff(DateVersionSym, PPA2Sym, 4); + OutStreamer->emitInt32( + 0x00000000); // Offset to main entry point, always 0 (so says TR). + uint8_t Flgs = static_cast<uint8_t>(PPA2Flags::CompileForBinaryFloatingPoint); + Flgs |= static_cast<uint8_t>(PPA2Flags::CompiledWithXPLink); + + if (auto *MD = M.getModuleFlag("zos_le_char_mode")) { + const StringRef &CharMode = cast<MDString>(MD)->getString(); + if (CharMode == "ascii") { + Flgs |= static_cast<uint8_t>( + PPA2Flags::CompiledUnitASCII); // Setting bit for ASCII char. mode. + } else if (CharMode != "ebcdic") { + report_fatal_error( + "Only ascii or ebcdic are valid values for zos_le_char_mode " + "metadata"); + } + } + + OutStreamer->emitInt8(Flgs); + OutStreamer->emitInt8(0x00); // Reserved. + // No MD5 signature before timestamp. + // No FLOAT(AFP(VOLATILE)). + // Remaining 5 flag bits reserved. + OutStreamer->emitInt16(0x0000); // 16 Reserved flag bits. + + // Emit date and version section. + OutStreamer->emitLabel(DateVersionSym); + OutStreamer->emitBytes(CompilationTimeStr.str()); + OutStreamer->emitBytes(VersionStr.str()); + + OutStreamer->emitInt16(0x0000); // Service level string length. + + // Emit 8 byte alignment. + // Emit pointer to PPA2 label. + OutStreamer->AddComment("A(PPA2-CELQSTRT)"); + OutStreamer->emitAbsoluteSymbolDiff(PPA2Sym, CELQSTRT, 8); + OutStreamer->popSection(); +} + void SystemZAsmPrinter::emitFunctionEntryLabel() { const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>(); @@ -1318,7 +1513,7 @@ void SystemZAsmPrinter::emitFunctionEntryLabel() { uint32_t DSASize = MFFrame.getStackSize(); bool IsLeaf = DSASize == 0 && MFFrame.getCalleeSavedInfo().empty(); - // Set Flags + // Set Flags. uint8_t Flags = 0; if (IsLeaf) Flags |= 0x08; diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h index c9dbbfd0b4c4335..303cce1a1b65818 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.h @@ -27,6 +27,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { private: MCSymbol *CurrentFnPPA1Sym; // PPA1 Symbol. MCSymbol *CurrentFnEPMarkerSym; // Entry Point Marker. + MCSymbol *PPA2Sym; SystemZTargetStreamer *getTargetStreamer() { MCTargetStreamer *TS = OutStreamer->getTargetStreamer(); @@ -90,12 +91,15 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { AssociatedDataAreaTable ADATable; void emitPPA1(MCSymbol *FnEndSym); + void emitPPA2(Module &M); void emitADASection(); + void emitIDRLSection(Module &M); public: SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) : AsmPrinter(TM, std::move(Streamer)), CurrentFnPPA1Sym(nullptr), - CurrentFnEPMarkerSym(nullptr), ADATable(TM.getPointerSize(0)) {} + CurrentFnEPMarkerSym(nullptr), PPA2Sym(nullptr), + ADATable(TM.getPointerSize(0)) {} // Override AsmPrinter. StringRef getPassName() const override { return "SystemZ Assembly Printer"; } @@ -113,6 +117,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter { } void emitFunctionEntryLabel() override; void emitFunctionBodyEnd() override; + void emitStartOfAsmFile(Module &M) override; private: void emitCallInformation(CallType CT); diff --git a/llvm/test/CodeGen/SystemZ/zos-ppa2.ll b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll new file mode 100644 index 000000000000000..aec45acf8befef4 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/zos-ppa2.ll @@ -0,0 +1,26 @@ +; RUN: llc -mtriple s390x-ibm-zos -mcpu=z15 -asm-verbose=true < %s | FileCheck %s +; REQUIRES: systemz-registered-target + +; CHECK: .section ".ppa2" +; CHECK: @@PPA2: +; CHECK: .byte 3 +; CHECK: .byte 231 +; CHECK: .byte 34 +; CHECK: .byte 4 +; CHECK: .long CELQSTRT-@@PPA2 +; CHECK: .long 0 +; CHECK: .long @@DVS-@@PPA2 +; CHECK: .long 0 +; CHECK: .byte 129 +; CHECK: .byte 0 +; CHECK: .short 0 +; CHECK: @@DVS: +; CHECK: .ascii "\361\371\367\360\360\361\360\361\360\360\360\360\360\360" +; CHECK: .short 0 +; CHECK: .quad @@PPA2-CELQSTRT * A(PPA2-CELQSTRT) +; CHECK: @@PPA1_void_test_0: +; CHECK: .long @@PPA2-@@PPA1_void_test_0 * Offset to PPA2 +define void @void_test() { +entry: + ret void +} >From e76100e044f87f9c53448ebab9623974074661f5 Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Thu, 12 Oct 2023 17:22:00 -0400 Subject: [PATCH 2/8] address comment --- clang/include/clang/Basic/LangStandard.h | 2 +- clang/lib/Basic/LangStandards.cpp | 4 ++-- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/test/CodeGen/SystemZ/systemz-ppa2.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h index d94567adf2bfb99..66b2ca0a8397136 100644 --- a/clang/include/clang/Basic/LangStandard.h +++ b/clang/include/clang/Basic/LangStandard.h @@ -43,7 +43,7 @@ enum class Language : uint8_t { HLSL, ///@} }; -const char *LanguageToString(Language L); +const char *languageToString(Language L); enum LangFeatures { LineComment = (1 << 0), diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp index e9b75d78e820a64..dbb84e412466c3d 100644 --- a/clang/lib/Basic/LangStandards.cpp +++ b/clang/lib/Basic/LangStandards.cpp @@ -14,7 +14,7 @@ #include "llvm/TargetParser/Triple.h" using namespace clang; -const char *clang::LanguageToString(Language L) { +const char *clang::languageToString(Language L) { // I would like to make this function and the definition of Language // in the .h file simply expand the contents of a .def file. // However, in the .h the members of the enum have doxygen annotations @@ -48,7 +48,7 @@ const char *clang::LanguageToString(Language L) { return "HLSL"; } - std::string msg = llvm::formatv("Unknown value ({0}) passed to LanguageToString", (unsigned int) L); + std::string msg = llvm::formatv("Unknown value ({0}) passed to languageToString", (unsigned int) L); llvm_unreachable(msg.c_str()); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4fd5f8ad2d94c55..cb67236b255a690 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -985,7 +985,7 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Warning, "Product Patchlevel", ProductPatch); // Record the language because we need it for the PPA2. - const char *lang_str = LanguageToString( + const char *lang_str = languageToString( LangStandard::getLangStandardForKind(LangOpts.LangStd).Language); getModule().addModuleFlag(llvm::Module::Error, "zos_cu_language", llvm::MDString::get(VMContext, lang_str)); diff --git a/clang/test/CodeGen/SystemZ/systemz-ppa2.c b/clang/test/CodeGen/SystemZ/systemz-ppa2.c index 8f396fc12c75fca..f143eea68b367fb 100644 --- a/clang/test/CodeGen/SystemZ/systemz-ppa2.c +++ b/clang/test/CodeGen/SystemZ/systemz-ppa2.c @@ -10,7 +10,7 @@ // .byte (i.e., the one for the 3) would, it seems, also match // the .byte line below for the 34. -// RUN: %clang --target=s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C +// RUN: %clang_cc1 --target=s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C // CHECK-C: [[PPA2:(.L)|(@@)PPA2]]: // CHECK-C-NEXT: .byte 3{{[[:space:]]*}}.byte 0 // CHECK-C-NEXT: .byte 34{{$}} >From 5247de3cc7a18db4f6decc9bcfb1288d8a1c5ffb Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Fri, 13 Oct 2023 10:53:28 -0400 Subject: [PATCH 3/8] fix lit test --- clang/test/CodeGen/SystemZ/systemz-ppa2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CodeGen/SystemZ/systemz-ppa2.c b/clang/test/CodeGen/SystemZ/systemz-ppa2.c index f143eea68b367fb..8f396fc12c75fca 100644 --- a/clang/test/CodeGen/SystemZ/systemz-ppa2.c +++ b/clang/test/CodeGen/SystemZ/systemz-ppa2.c @@ -10,7 +10,7 @@ // .byte (i.e., the one for the 3) would, it seems, also match // the .byte line below for the 34. -// RUN: %clang_cc1 --target=s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C +// RUN: %clang --target=s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C // CHECK-C: [[PPA2:(.L)|(@@)PPA2]]: // CHECK-C-NEXT: .byte 3{{[[:space:]]*}}.byte 0 // CHECK-C-NEXT: .byte 34{{$}} >From 9bf2cb91c103cd89be8827bebb6befb19d61ae70 Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Fri, 13 Oct 2023 11:03:54 -0400 Subject: [PATCH 4/8] fix formatting --- clang/lib/Basic/LangStandards.cpp | 3 ++- clang/lib/CodeGen/CodeGenModule.cpp | 13 ++++++++----- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 9 ++++----- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp index dbb84e412466c3d..2c894fdafa1cacb 100644 --- a/clang/lib/Basic/LangStandards.cpp +++ b/clang/lib/Basic/LangStandards.cpp @@ -48,7 +48,8 @@ const char *clang::languageToString(Language L) { return "HLSL"; } - std::string msg = llvm::formatv("Unknown value ({0}) passed to languageToString", (unsigned int) L); + std::string msg = llvm::formatv( + "Unknown value ({0}) passed to languageToString", (unsigned int)L); llvm_unreachable(msg.c_str()); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index cb67236b255a690..4b880404958749b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -978,11 +978,14 @@ void CodeGenModule::Release() { if (getTriple().isOSzOS()) { int32_t ProductVersion, ProductRelease, ProductPatch; - ProductVersion = LLVM_VERSION_MAJOR, - ProductRelease = LLVM_VERSION_MINOR, ProductPatch = LLVM_VERSION_PATCH; - getModule().addModuleFlag(llvm::Module::Warning, "Product Major Version", ProductVersion); - getModule().addModuleFlag(llvm::Module::Warning, "Product Minor Version", ProductRelease); - getModule().addModuleFlag(llvm::Module::Warning, "Product Patchlevel", ProductPatch); + ProductVersion = LLVM_VERSION_MAJOR, ProductRelease = LLVM_VERSION_MINOR, + ProductPatch = LLVM_VERSION_PATCH; + getModule().addModuleFlag(llvm::Module::Warning, "Product Major Version", + ProductVersion); + getModule().addModuleFlag(llvm::Module::Warning, "Product Minor Version", + ProductRelease); + getModule().addModuleFlag(llvm::Module::Warning, "Product Patchlevel", + ProductPatch); // Record the language because we need it for the PPA2. const char *lang_str = languageToString( diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index d963009c6c158f7..adf796ee12a6533 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -28,7 +28,6 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Chrono.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertEBCDIC.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormatProviders.h" @@ -1092,8 +1091,8 @@ void SystemZAsmPrinter::emitIDRLSection(Module &M) { ConverterEBCDIC::convertToEBCDIC(TempStr, Data); - OutStreamer->emitInt8(0); // Reserved. - OutStreamer->emitInt8(3); // Format. + OutStreamer->emitInt8(0); // Reserved. + OutStreamer->emitInt8(3); // Format. OutStreamer->emitInt16(IDRLDataLength); // Length. OutStreamer->emitBytes(Data.str()); OutStreamer->popSection(); @@ -1402,8 +1401,8 @@ void SystemZAsmPrinter::emitPPA2(Module &M) { SmallString<7> Version; // 6 + null raw_svector_ostream ostr(Version); - ostr << formatv("{0,0-2:d}{1,0-2:d}{2,0-2:d}", ProductVersion, - ProductRelease, ProductPatch); + ostr << formatv("{0,0-2:d}{1,0-2:d}{2,0-2:d}", ProductVersion, ProductRelease, + ProductPatch); // Drop 0 during conversion. SmallString<sizeof(CompilationTime) - 1> CompilationTimeStr; >From 1a52c031a9ba0bc0fb7305f466606d8acecdb29e Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Fri, 13 Oct 2023 12:01:53 -0400 Subject: [PATCH 5/8] change %clang to %clang_cc1 --- clang/test/CodeGen/SystemZ/systemz-ppa2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeGen/SystemZ/systemz-ppa2.c b/clang/test/CodeGen/SystemZ/systemz-ppa2.c index 8f396fc12c75fca..21ccd0d7b834c19 100644 --- a/clang/test/CodeGen/SystemZ/systemz-ppa2.c +++ b/clang/test/CodeGen/SystemZ/systemz-ppa2.c @@ -10,14 +10,14 @@ // .byte (i.e., the one for the 3) would, it seems, also match // the .byte line below for the 34. -// RUN: %clang --target=s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C +// RUN: %clang_cc1 -triple s390x-ibm-zos -xc -S -o - %s | FileCheck %s --check-prefix CHECK-C // CHECK-C: [[PPA2:(.L)|(@@)PPA2]]: // CHECK-C-NEXT: .byte 3{{[[:space:]]*}}.byte 0 // CHECK-C-NEXT: .byte 34{{$}} // CHECK-C-NEXT: .byte {{4}} // CHECK-C-NEXT: .long {{(CELQSTRT)}}-[[PPA2]] -// RUN: %clang --target=s390x-ibm-zos -xc++ -S -o - %s | FileCheck %s --check-prefix CHECK-CXX +// RUN: %clang_cc1 -triple s390x-ibm-zos -xc++ -S -o - %s | FileCheck %s --check-prefix CHECK-CXX // CHECK-CXX: [[PPA2:(.L)|(@@)PPA2]]: // CHECK-CXX-NEXT: .byte 3{{[[:space:]]*}}.byte 1 // CHECK-CXX-NEXT: .byte 34{{$}} >From f21b31b3d07fd70477ae8f3e60ba3d756ee79366 Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Fri, 13 Oct 2023 12:17:12 -0400 Subject: [PATCH 6/8] minor formatting --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index adf796ee12a6533..9d1a8d103e34d1b 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -28,8 +28,8 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Chrono.h" -#include "llvm/Support/ConvertEBCDIC.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ConvertEBCDIC.h" #include "llvm/Support/FormatProviders.h" #include "llvm/Support/FormatVariadic.h" >From 13034e091931a235a016c87c84c2fb53d24cdaac Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Tue, 17 Oct 2023 17:02:58 -0400 Subject: [PATCH 7/8] address review comments --- clang/include/clang/Basic/LangOptions.def | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 25 +++++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index c0ea4ecb9806a5b..690779dc76cce3d 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -90,6 +90,7 @@ LANGOPT(C23 , 1, 0, "C23") LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode") LANGOPT(Kernel , 1, 0, "Kernel mode") LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions") +LANGOPT(ASCIICharMode , 1, 1, "z/OS Language Environment Character mode") LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks") LANGOPT(Borland , 1, 0, "Borland extensions") LANGOPT(CPlusPlus , 1, 0, "C++") diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4b880404958749b..71edafe7e8e4f1f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -977,21 +977,34 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth); if (getTriple().isOSzOS()) { - int32_t ProductVersion, ProductRelease, ProductPatch; - ProductVersion = LLVM_VERSION_MAJOR, ProductRelease = LLVM_VERSION_MINOR, - ProductPatch = LLVM_VERSION_PATCH; getModule().addModuleFlag(llvm::Module::Warning, "Product Major Version", - ProductVersion); + uint32_t(CLANG_VERSION_MAJOR)); getModule().addModuleFlag(llvm::Module::Warning, "Product Minor Version", - ProductRelease); + uint32_t(CLANG_VERSION_MINOR)); getModule().addModuleFlag(llvm::Module::Warning, "Product Patchlevel", - ProductPatch); + uint32_t(CLANG_VERSION_PATCHLEVEL)); // Record the language because we need it for the PPA2. const char *lang_str = languageToString( LangStandard::getLangStandardForKind(LangOpts.LangStd).Language); getModule().addModuleFlag(llvm::Module::Error, "zos_cu_language", llvm::MDString::get(VMContext, lang_str)); + + std::string ProductId; +#ifdef CLANG_VENDOR + ProductId = #CLANG_VENDOR; +#else + ProductId = "clang"; +#endif + + getModule().addModuleFlag(llvm::Module::Error, "Product Id", + llvm::MDString::get(VMContext, ProductId)); + + getModule().addModuleFlag( + llvm::Module::Error, "zos_le_char_mode", + llvm::MDString::get(VMContext, Context.getLangOpts().ASCIICharMode + ? "ascii" + : "ebcdic")); } llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch(); >From 40da989125eb48d6675ad9733c109b99fda13d57 Mon Sep 17 00:00:00 2001 From: Yusra Syeda <yusra.sy...@ibm.com> Date: Mon, 23 Oct 2023 16:41:59 -0400 Subject: [PATCH 8/8] refactor translation time --- clang/lib/CodeGen/CodeGenModule.cpp | 3 +++ clang/lib/Driver/ToolChains/Clang.cpp | 8 -------- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 20 +++++++++++-------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 71edafe7e8e4f1f..b25c0e266de8dbe 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1000,6 +1000,9 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Error, "Product Id", llvm::MDString::get(VMContext, ProductId)); + getModule().addModuleFlag(llvm::Module::Error, "TranslationTime", + static_cast<uint64_t>(std::time(nullptr))); + getModule().addModuleFlag( llvm::Module::Error, "zos_le_char_mode", llvm::MDString::get(VMContext, Context.getLangOpts().ASCIICharMode diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 4f02fa2fc3c788a..d3280fa52e200e3 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2268,14 +2268,6 @@ void Clang::AddSystemZTargetArgs(const llvm::Triple &Triple, CmdArgs.push_back("-mfloat-abi"); CmdArgs.push_back("soft"); } - - if (Triple.isOSzOS()) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back( - Args.MakeArgString(llvm::Twine("-translation-time=") - .concat(llvm::Twine(std::time(nullptr))) - .str())); - } } void Clang::AddX86TargetArgs(const ArgList &Args, diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index 9d1a8d103e34d1b..bf4c7e9bd398166 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -28,18 +28,12 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Chrono.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertEBCDIC.h" #include "llvm/Support/FormatProviders.h" #include "llvm/Support/FormatVariadic.h" using namespace llvm; -cl::opt<uint64_t> TranslationTime( - "translation-time", - cl::desc("sets the time of compilation in seconds since epoch"), - cl::init(0)); - // Return an RI instruction like MI with opcode Opcode, but with the // GR64 register operands turned into GR32s. static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { @@ -1057,11 +1051,21 @@ static uint32_t getProductPatch(Module &M) { return LLVM_VERSION_PATCH; } +static time_t getTranslationTime(Module &M) { + std::time_t Time = 0; + if (auto *Val = cast_or_null<ConstantAsMetadata>( + M.getModuleFlag("TranslationTime"))) { + long SecondsSinceEpoch = cast<ConstantInt>(Val->getValue())->getSExtValue(); + Time = static_cast<time_t>(SecondsSinceEpoch); + } + return Time; +} + void SystemZAsmPrinter::emitIDRLSection(Module &M) { OutStreamer->pushSection(); OutStreamer->switchSection(getObjFileLowering().getIDRLSection()); constexpr unsigned IDRLDataLength = 30; - std::time_t Time = TranslationTime; + std::time_t Time = getTranslationTime(M); uint32_t ProductVersion = getProductVersion(M); uint32_t ProductRelease = getProductRelease(M); @@ -1390,7 +1394,7 @@ void SystemZAsmPrinter::emitPPA2(Module &M) { PPA2Sym = OutContext.createTempSymbol("PPA2", false); MCSymbol *DateVersionSym = OutContext.createTempSymbol("DVS", false); - std::time_t Time = TranslationTime; + std::time_t Time = getTranslationTime(M); SmallString<15> CompilationTime; // 14 + null raw_svector_ostream O(CompilationTime); O << formatv("{0:%Y%m%d%H%M%S}", llvm::sys::toUtcTime(Time)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits