[llvm] [clang] [SystemZ][z/OS] This change adds support for the PPA2 section in zOS (PR #68926)

Yusra Syeda via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 1 07:37:37 PDT 2023


https://github.com/ysyeda updated https://github.com/llvm/llvm-project/pull/68926

>From 78f82bcf33998de0663f4684a64a240f2e97f8a9 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Thu, 12 Oct 2023 16:56:27 -0400
Subject: [PATCH 01/13] This change adds support for the PPA2 section in zOS

---
 clang/lib/Basic/LangStandards.cpp             |   6 +
 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 +++
 11 files changed, 297 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/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp
index ab09c7221dda92f..cfe79ec90f3796b 100644
--- a/clang/lib/Basic/LangStandards.cpp
+++ b/clang/lib/Basic/LangStandards.cpp
@@ -10,10 +10,16 @@
 #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;
 
 StringRef 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
+  // and/or comments which would be lost.
   switch (L) {
   case Language::Unknown:
     return "Unknown";
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b1a6683a66bd052..9a4763413ea3fbc 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 43a92adbef64ba8..109699f2ea4a62a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1765,7 +1765,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:
@@ -2262,7 +2262,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");
@@ -2294,6 +2295,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 5abb1d8fb7a662be3b49e34bf61774a6cfedb038 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Thu, 12 Oct 2023 17:22:00 -0400
Subject: [PATCH 02/13] address comment

---
 clang/lib/Basic/LangStandards.cpp         | 5 -----
 clang/lib/CodeGen/CodeGenModule.cpp       | 2 +-
 clang/test/CodeGen/SystemZ/systemz-ppa2.c | 2 +-
 3 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp
index cfe79ec90f3796b..488559231767859 100644
--- a/clang/lib/Basic/LangStandards.cpp
+++ b/clang/lib/Basic/LangStandards.cpp
@@ -15,11 +15,6 @@
 using namespace clang;
 
 StringRef 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
-  // and/or comments which would be lost.
   switch (L) {
   case Language::Unknown:
     return "Unknown";
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 9a4763413ea3fbc..b365cdc860b9907 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 7fcf8f6acc5e19857d2275dc30664129ba660bd9 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Fri, 13 Oct 2023 10:53:28 -0400
Subject: [PATCH 03/13] 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 df7b6f9d018753231f3e99e629521e5f2a6ddf79 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Fri, 13 Oct 2023 11:03:54 -0400
Subject: [PATCH 04/13] fix formatting

---
 clang/lib/CodeGen/CodeGenModule.cpp           | 13 ++++++++-----
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp |  9 ++++-----
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b365cdc860b9907..0e335362df502d5 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 28034918baadecf3ba96ed85fa19ecc36b4f384f Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Fri, 13 Oct 2023 12:01:53 -0400
Subject: [PATCH 05/13] 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 3b03227818a93b3a7992a4e8c1ab5812f247b707 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Fri, 13 Oct 2023 12:17:12 -0400
Subject: [PATCH 06/13] 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 4a13aa660a04172e2f49d41950d344335c40c0ae Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Tue, 17 Oct 2023 17:02:58 -0400
Subject: [PATCH 07/13] 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 0e335362df502d5..9a60d72a1e90cc7 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 c0b35d5cbfa1557f6f64ea490897f22a6ea7bfb3 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Mon, 23 Oct 2023 16:41:59 -0400
Subject: [PATCH 08/13] 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 9a60d72a1e90cc7..cc31f8d1f0e36e6 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 109699f2ea4a62a..196e9848673cb6f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2295,14 +2295,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));

>From 1768151d746473d255d0ac77dc216f9500779caa Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Mon, 30 Oct 2023 13:31:53 -0400
Subject: [PATCH 09/13] fix build error after rebase

---
 clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index cc31f8d1f0e36e6..1fc60c7e0f512e5 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -985,7 +985,7 @@ void CodeGenModule::Release() {
                               uint32_t(CLANG_VERSION_PATCHLEVEL));
 
     // Record the language because we need it for the PPA2.
-    const char *lang_str = languageToString(
+    StringRef lang_str = languageToString(
         LangStandard::getLangStandardForKind(LangOpts.LangStd).Language);
     getModule().addModuleFlag(llvm::Module::Error, "zos_cu_language",
                               llvm::MDString::get(VMContext, lang_str));

>From e4346d39819b6508f978c39e525ed05e99418319 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Mon, 30 Oct 2023 13:32:54 -0400
Subject: [PATCH 10/13] small fix

---
 clang/lib/Basic/LangStandards.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp
index 488559231767859..ab09c7221dda92f 100644
--- a/clang/lib/Basic/LangStandards.cpp
+++ b/clang/lib/Basic/LangStandards.cpp
@@ -10,7 +10,6 @@
 #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;
 

>From ae6a160490e30b6001892a7f38ec90c9741bd1e5 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Mon, 30 Oct 2023 14:55:04 -0400
Subject: [PATCH 11/13] 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 21ccd0d7b834c19..7b56ec9d2188a7d 100644
--- a/clang/test/CodeGen/SystemZ/systemz-ppa2.c
+++ b/clang/test/CodeGen/SystemZ/systemz-ppa2.c
@@ -19,7 +19,7 @@
 
 // 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      3{{[[:space:]]*}}.byte 231
 // CHECK-CXX-NEXT:   .byte      34{{$}}
 // CHECK-CXX-NEXT:   .byte      {{4}}
 // CHECK-CXX-NEXT:   .long      {{(CELQSTRT)}}-[[PPA2]]

>From e3d3ed1b0b6ceb95ebc8aed73839e922d232b0f9 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Tue, 31 Oct 2023 11:59:19 -0400
Subject: [PATCH 12/13] address review comments

---
 clang/include/clang/Basic/LangOptions.def |  1 -
 clang/lib/CodeGen/CodeGenModule.cpp       | 23 +++++++++--------------
 clang/lib/Driver/ToolChains/Clang.cpp     |  5 ++---
 clang/lib/Driver/ToolChains/Clang.h       |  3 +--
 4 files changed, 12 insertions(+), 20 deletions(-)

diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 690779dc76cce3d..c0ea4ecb9806a5b 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -90,7 +90,6 @@ 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 1fc60c7e0f512e5..9215cdc37d8f6b2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -983,31 +983,26 @@ void CodeGenModule::Release() {
                               uint32_t(CLANG_VERSION_MINOR));
     getModule().addModuleFlag(llvm::Module::Warning, "Product Patchlevel",
                               uint32_t(CLANG_VERSION_PATCHLEVEL));
-
-    // Record the language because we need it for the PPA2.
-    StringRef 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, "TranslationTime",
+    // Record the language because we need it for the PPA2.
+    StringRef lang_str = languageToString(
+        LangStandard::getLangStandardForKind(LangOpts.LangStd).Language);
+    getModule().addModuleFlag(llvm::Module::Error, "zos_cu_language",
+                              llvm::MDString::get(VMContext, lang_str));
+
+    getModule().addModuleFlag(llvm::Module::Max, "TranslationTime",
                               static_cast<uint64_t>(std::time(nullptr)));
 
-    getModule().addModuleFlag(
-        llvm::Module::Error, "zos_le_char_mode",
-        llvm::MDString::get(VMContext, Context.getLangOpts().ASCIICharMode
-                                           ? "ascii"
-                                           : "ebcdic"));
+    getModule().addModuleFlag(llvm::Module::Error, "zos_le_char_mode",
+                              llvm::MDString::get(VMContext, "ascii"));
   }
 
   llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 196e9848673cb6f..43a92adbef64ba8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1765,7 +1765,7 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
     break;
 
   case llvm::Triple::systemz:
-    AddSystemZTargetArgs(EffectiveTriple, Args, CmdArgs);
+    AddSystemZTargetArgs(Args, CmdArgs);
     break;
 
   case llvm::Triple::x86:
@@ -2262,8 +2262,7 @@ void Clang::AddSparcTargetArgs(const ArgList &Args,
   }
 }
 
-void Clang::AddSystemZTargetArgs(const llvm::Triple &Triple,
-                                 const ArgList &Args,
+void Clang::AddSystemZTargetArgs(const ArgList &Args,
                                  ArgStringList &CmdArgs) const {
   if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
     CmdArgs.push_back("-tune-cpu");
diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h
index 9f065f846b4cf34..0f503c4bd1c4fea 100644
--- a/clang/lib/Driver/ToolChains/Clang.h
+++ b/clang/lib/Driver/ToolChains/Clang.h
@@ -69,8 +69,7 @@ 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::Triple &Triple,
-                            const llvm::opt::ArgList &Args,
+  void AddSystemZTargetArgs(const llvm::opt::ArgList &Args,
                             llvm::opt::ArgStringList &CmdArgs) const;
   void AddX86TargetArgs(const llvm::opt::ArgList &Args,
                         llvm::opt::ArgStringList &CmdArgs) const;

>From c1b9af787e9a92d62ae6752694b49eec0e2231f4 Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Wed, 1 Nov 2023 10:37:14 -0400
Subject: [PATCH 13/13] renaming of module flags

---
 clang/lib/CodeGen/CodeGenModule.cpp           | 10 +++++-----
 llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 9215cdc37d8f6b2..e719c448f34bc9b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -977,11 +977,11 @@ void CodeGenModule::Release() {
   getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth);
 
   if (getTriple().isOSzOS()) {
-    getModule().addModuleFlag(llvm::Module::Warning, "Product Major Version",
+    getModule().addModuleFlag(llvm::Module::Warning, "zos_product_major_version",
                               uint32_t(CLANG_VERSION_MAJOR));
-    getModule().addModuleFlag(llvm::Module::Warning, "Product Minor Version",
+    getModule().addModuleFlag(llvm::Module::Warning, "zos_product_minor_version",
                               uint32_t(CLANG_VERSION_MINOR));
-    getModule().addModuleFlag(llvm::Module::Warning, "Product Patchlevel",
+    getModule().addModuleFlag(llvm::Module::Warning, "zos_product_patchlevel",
                               uint32_t(CLANG_VERSION_PATCHLEVEL));
     std::string ProductId;
 #ifdef CLANG_VENDOR
@@ -989,7 +989,7 @@ void CodeGenModule::Release() {
 #else
     ProductId = "clang";
 #endif
-    getModule().addModuleFlag(llvm::Module::Error, "Product Id",
+    getModule().addModuleFlag(llvm::Module::Error, "zos_product_id",
                               llvm::MDString::get(VMContext, ProductId));
 
     // Record the language because we need it for the PPA2.
@@ -998,7 +998,7 @@ void CodeGenModule::Release() {
     getModule().addModuleFlag(llvm::Module::Error, "zos_cu_language",
                               llvm::MDString::get(VMContext, lang_str));
 
-    getModule().addModuleFlag(llvm::Module::Max, "TranslationTime",
+    getModule().addModuleFlag(llvm::Module::Max, "zos_translation_time",
                               static_cast<uint64_t>(std::time(nullptr)));
 
     getModule().addModuleFlag(llvm::Module::Error, "zos_le_char_mode",
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index bf4c7e9bd398166..65893881f6eead0 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -1032,21 +1032,21 @@ void SystemZAsmPrinter::emitADASection() {
 
 static uint32_t getProductVersion(Module &M) {
   if (auto *VersionVal = cast_or_null<ConstantAsMetadata>(
-          M.getModuleFlag("Product Major Version")))
+          M.getModuleFlag("zos_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")))
+          M.getModuleFlag("zos_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")))
+          M.getModuleFlag("zos_product_patchlevel")))
     return cast<ConstantInt>(PatchVal->getValue())->getZExtValue();
   return LLVM_VERSION_PATCH;
 }
@@ -1054,7 +1054,7 @@ static uint32_t getProductPatch(Module &M) {
 static time_t getTranslationTime(Module &M) {
   std::time_t Time = 0;
   if (auto *Val = cast_or_null<ConstantAsMetadata>(
-          M.getModuleFlag("TranslationTime"))) {
+          M.getModuleFlag("zos_translation_time"))) {
     long SecondsSinceEpoch = cast<ConstantInt>(Val->getValue())->getSExtValue();
     Time = static_cast<time_t>(SecondsSinceEpoch);
   }
@@ -1071,7 +1071,7 @@ void SystemZAsmPrinter::emitIDRLSection(Module &M) {
   uint32_t ProductRelease = getProductRelease(M);
 
   std::string ProductID;
-  if (auto *MD = M.getModuleFlag("Product Id"))
+  if (auto *MD = M.getModuleFlag("zos_product_id"))
     ProductID = cast<MDString>(MD)->getString().str();
 
   if (ProductID.empty()) {



More information about the cfe-commits mailing list