[llvm] a8cfa4b - [SystemZ][z/OS] Initial code to generate assembly files on z/OS

Anirudh Prasad via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 27 08:29:23 PDT 2021


Author: Anirudh Prasad
Date: 2021-07-27T11:29:15-04:00
New Revision: a8cfa4b9bda3014a88e089cadcc6d366317aec5b

URL: https://github.com/llvm/llvm-project/commit/a8cfa4b9bda3014a88e089cadcc6d366317aec5b
DIFF: https://github.com/llvm/llvm-project/commit/a8cfa4b9bda3014a88e089cadcc6d366317aec5b.diff

LOG: [SystemZ][z/OS] Initial code to generate assembly files on z/OS

- This patch consists of the bare basic code needed in order to generate some assembly for the z/OS target.
- Only the .text and the .bss sections are added for now.
- The relevant MCSectionGOFF/Symbol interfaces have been added. This enables us to print out the GOFF machine code sections.
- This patch enables us to add simple lit tests wherever possible, and contribute to the testing coverage for the z/OS target
- Further improvements and additions will be made in future patches.

Reviewed By: tmatheson

Differential Revision: https://reviews.llvm.org/D106380

Added: 
    llvm/include/llvm/MC/MCSectionGOFF.h
    llvm/include/llvm/MC/MCSymbolGOFF.h
    llvm/test/CodeGen/SystemZ/zos-simple-test.ll

Modified: 
    llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
    llvm/include/llvm/MC/MCContext.h
    llvm/include/llvm/MC/MCObjectFileInfo.h
    llvm/include/llvm/MC/MCSection.h
    llvm/include/llvm/MC/MCSymbol.h
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/MC/MCContext.cpp
    llvm/lib/MC/MCObjectFileInfo.cpp
    llvm/lib/MC/MCParser/AsmParser.cpp
    llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 690a3f21114a0..2c8b17807f7ca 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -284,6 +284,17 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
                                         const TargetMachine &TM) const override;
 };
 
+class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
+public:
+  TargetLoweringObjectFileGOFF();
+  ~TargetLoweringObjectFileGOFF() override = default;
+
+  MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
+                                    const TargetMachine &TM) const override;
+  MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
+                                      const TargetMachine &TM) const override;
+};
+
 } // end namespace llvm
 
 #endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H

diff  --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index d0edad8f02c24..877b2dc4ac922 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -52,6 +52,7 @@ namespace llvm {
   class MCSection;
   class MCSectionCOFF;
   class MCSectionELF;
+  class MCSectionGOFF;
   class MCSectionMachO;
   class MCSectionWasm;
   class MCSectionXCOFF;
@@ -74,7 +75,7 @@ namespace llvm {
     using DiagHandlerTy =
         std::function<void(const SMDiagnostic &, bool, const SourceMgr &,
                            std::vector<const MDNode *> &)>;
-    enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF };
+    enum Environment { IsMachO, IsELF, IsGOFF, IsCOFF, IsWasm, IsXCOFF };
 
   private:
     Environment Env;
@@ -114,6 +115,7 @@ namespace llvm {
     SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator;
     SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
     SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
+    SpecificBumpPtrAllocator<MCSectionGOFF> GOFFAllocator;
     SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
     SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator;
     SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
@@ -323,6 +325,7 @@ namespace llvm {
     StringMap<MCSectionMachO *> MachOUniquingMap;
     std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
     std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
+    std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
     std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
     std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
     StringMap<bool> RelSecNames;
@@ -595,6 +598,8 @@ namespace llvm {
                                                 unsigned Flags,
                                                 unsigned EntrySize);
 
+    MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind);
+
     MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
                                   SectionKind Kind, StringRef COMDATSymName,
                                   int Selection,

diff  --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index a97cdc3970005..8ae86ef2a5746 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -426,6 +426,7 @@ class MCObjectFileInfo {
 
   void initMachOMCObjectFileInfo(const Triple &T);
   void initELFMCObjectFileInfo(const Triple &T, bool Large);
+  void initGOFFMCObjectFileInfo(const Triple &T);
   void initCOFFMCObjectFileInfo(const Triple &T);
   void initWasmMCObjectFileInfo(const Triple &T);
   void initXCOFFMCObjectFileInfo(const Triple &T);

diff  --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index a68e06e661bea..4335092f09205 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -40,7 +40,14 @@ class MCSection {
 public:
   static constexpr unsigned NonUniqueID = ~0U;
 
-  enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm, SV_XCOFF };
+  enum SectionVariant {
+    SV_COFF = 0,
+    SV_ELF,
+    SV_GOFF,
+    SV_MachO,
+    SV_Wasm,
+    SV_XCOFF
+  };
 
   /// Express the state of bundle locked groups while emitting code.
   enum BundleLockStateType {

diff  --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h
new file mode 100644
index 0000000000000..4ba7f79f9696e
--- /dev/null
+++ b/llvm/include/llvm/MC/MCSectionGOFF.h
@@ -0,0 +1,46 @@
+//===-- llvm/MC/MCSectionGOFF.h - GOFF Machine Code Sections ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file declares the MCSectionGOFF class, which contains all of the
+/// necessary machine code sections for the GOFF file format.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONGOFF_H
+#define LLVM_MC_MCSECTIONGOFF_H
+
+#include "llvm/MC/MCSection.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class MCExpr;
+
+class MCSectionGOFF final : public MCSection {
+private:
+  friend class MCContext;
+  MCSectionGOFF(StringRef Name, SectionKind K)
+      : MCSection(SV_GOFF, Name, K, nullptr) {}
+
+public:
+  void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+                            raw_ostream &OS,
+                            const MCExpr *Subsection) const override {
+    OS << "\t.section\t\"" << getName() << "\"\n";
+  }
+
+  bool UseCodeAlign() const override { return false; }
+
+  bool isVirtualSection() const override { return false; }
+
+  static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; }
+};
+} // end namespace llvm
+
+#endif

diff  --git a/llvm/include/llvm/MC/MCSymbol.h b/llvm/include/llvm/MC/MCSymbol.h
index a83781f5c5864..d8fc4505d4463 100644
--- a/llvm/include/llvm/MC/MCSymbol.h
+++ b/llvm/include/llvm/MC/MCSymbol.h
@@ -46,6 +46,7 @@ class MCSymbol {
     SymbolKindUnset,
     SymbolKindCOFF,
     SymbolKindELF,
+    SymbolKindGOFF,
     SymbolKindMachO,
     SymbolKindWasm,
     SymbolKindXCOFF,
@@ -276,6 +277,8 @@ class MCSymbol {
 
   bool isCOFF() const { return Kind == SymbolKindCOFF; }
 
+  bool isGOFF() const { return Kind == SymbolKindGOFF; }
+
   bool isMachO() const { return Kind == SymbolKindMachO; }
 
   bool isWasm() const { return Kind == SymbolKindWasm; }

diff  --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h
new file mode 100644
index 0000000000000..cc4e2bbe246e2
--- /dev/null
+++ b/llvm/include/llvm/MC/MCSymbolGOFF.h
@@ -0,0 +1,28 @@
+//===-- llvm/MC/MCSymbolGOFF.h - GOFF Machine Code Symbols ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the MCSymbolGOFF class
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_MC_MCSYMBOLGOFF_H
+#define LLVM_MC_MCSYMBOLGOFF_H
+
+#include "llvm/MC/MCSymbol.h"
+
+namespace llvm {
+
+class MCSymbolGOFF : public MCSymbol {
+public:
+  MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary)
+      : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
+  static bool classof(const MCSymbol *S) { return S->isGOFF(); }
+};
+} // end namespace llvm
+
+#endif

diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 8d8838f81c7ab..add34eccc1f37 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -48,6 +48,7 @@
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCSectionWasm.h"
 #include "llvm/MC/MCSectionXCOFF.h"
@@ -2521,3 +2522,24 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
           TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
           XCOFF::XTY_SD));
 }
+
+//===----------------------------------------------------------------------===//
+//                                  GOFF
+//===----------------------------------------------------------------------===//
+TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF()
+    : TargetLoweringObjectFile() {}
+
+MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
+    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
+  return SelectSectionForGlobal(GO, Kind, TM);
+}
+
+MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
+    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
+  auto *Symbol = TM.getSymbol(GO);
+  if (Kind.isBSS())
+    return getContext().getGOFFSection(Symbol->getName(),
+                                       SectionKind::getBSS());
+
+  return getContext().getObjectFileInfo()->getTextSection();
+}

diff  --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index af2546cb0a8b4..aa4051aa24005 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -25,6 +25,7 @@
 #include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCSectionWasm.h"
 #include "llvm/MC/MCSectionXCOFF.h"
@@ -32,6 +33,7 @@
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCSymbolCOFF.h"
 #include "llvm/MC/MCSymbolELF.h"
+#include "llvm/MC/MCSymbolGOFF.h"
 #include "llvm/MC/MCSymbolMachO.h"
 #include "llvm/MC/MCSymbolWasm.h"
 #include "llvm/MC/MCSymbolXCOFF.h"
@@ -99,7 +101,7 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
     Env = IsXCOFF;
     break;
   case Triple::GOFF:
-    report_fatal_error("Cannot initialize MC for GOFF object file format");
+    Env = IsGOFF;
     break;
   case Triple::UnknownObjectFormat:
     report_fatal_error("Cannot initialize MC for unknown object file format.");
@@ -133,6 +135,7 @@ void MCContext::reset() {
   // Call the destructors so the fragments are freed
   COFFAllocator.DestroyAll();
   ELFAllocator.DestroyAll();
+  GOFFAllocator.DestroyAll();
   MachOAllocator.DestroyAll();
   XCOFFAllocator.DestroyAll();
   MCInstAllocator.DestroyAll();
@@ -156,6 +159,7 @@ void MCContext::reset() {
 
   MachOUniquingMap.clear();
   ELFUniquingMap.clear();
+  GOFFUniquingMap.clear();
   COFFUniquingMap.clear();
   WasmUniquingMap.clear();
   XCOFFUniquingMap.clear();
@@ -231,6 +235,8 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
     return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
   case MCContext::IsELF:
     return new (Name, *this) MCSymbolELF(Name, IsTemporary);
+  case MCContext::IsGOFF:
+    return new (Name, *this) MCSymbolGOFF(Name, IsTemporary);
   case MCContext::IsMachO:
     return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
   case MCContext::IsWasm:
@@ -610,6 +616,15 @@ Optional<unsigned> MCContext::getELFUniqueIDForEntsize(StringRef SectionName,
   return (I != ELFEntrySizeMap.end()) ? Optional<unsigned>(I->second) : None;
 }
 
+MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind) {
+  // Do the lookup. If we don't have a hit, return a new section.
+  auto &GOFFSection = GOFFUniquingMap[Section.str()];
+  if (!GOFFSection)
+    GOFFSection = new (GOFFAllocator.Allocate()) MCSectionGOFF(Section, Kind);
+
+  return GOFFSection;
+}
+
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
                                          unsigned Characteristics,
                                          SectionKind Kind,

diff  --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 1a448f040b3b8..7ea1106068b74 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -17,6 +17,7 @@
 #include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionGOFF.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCSectionWasm.h"
 #include "llvm/MC/MCSectionXCOFF.h"
@@ -504,6 +505,11 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
       Ctx->getELFSection(".pseudo_probe_desc", DebugSecType, 0);
 }
 
+void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
+  TextSection = Ctx->getGOFFSection(".text", SectionKind::getText());
+  BSSSection = Ctx->getGOFFSection(".bss", SectionKind::getBSS());
+}
+
 void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
   EHFrameSection =
       Ctx->getCOFFSection(".eh_frame", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -995,6 +1001,9 @@ void MCObjectFileInfo::initMCObjectFileInfo(MCContext &MCCtx, bool PIC,
   case MCContext::IsELF:
     initELFMCObjectFileInfo(TheTriple, LargeCodeModel);
     break;
+  case MCContext::IsGOFF:
+    initGOFFMCObjectFileInfo(TheTriple);
+    break;
   case MCContext::IsWasm:
     initWasmMCObjectFileInfo(TheTriple);
     break;

diff  --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 45e6dfee4ca4b..d3cb5ca59bf3d 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -782,6 +782,8 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
   case MCContext::IsELF:
     PlatformParser.reset(createELFAsmParser());
     break;
+  case MCContext::IsGOFF:
+    report_fatal_error("GOFFAsmParser support not implemented yet");
   case MCContext::IsWasm:
     PlatformParser.reset(createWasmAsmParser());
     break;

diff  --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 1ddbe944ec085..e410fe0aeff28 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6369,6 +6369,7 @@ bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
   case MCContext::IsWasm:
     CurrentFormat = WASM;
     break;
+  case MCContext::IsGOFF:
   case MCContext::IsXCOFF:
     llvm_unreachable("unexpected object format");
     break;

diff  --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
index ebb8ed97bb592..a886f9b9d8149 100644
--- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp
@@ -97,6 +97,15 @@ static std::string computeDataLayout(const Triple &TT, StringRef CPU,
   return Ret;
 }
 
+static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
+  if (TT.isOSzOS())
+    return std::make_unique<TargetLoweringObjectFileGOFF>();
+
+  // Note: Some times run with -triple s390x-unknown.
+  // In this case, default to ELF unless z/OS specifically provided.
+  return std::make_unique<TargetLoweringObjectFileELF>();
+}
+
 static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
   // Static code is suitable for use in a dynamic executable; there is no
   // separate DynamicNoPIC model.
@@ -160,7 +169,7 @@ SystemZTargetMachine::SystemZTargetMachine(const Target &T, const Triple &TT,
           getEffectiveRelocModel(RM),
           getEffectiveSystemZCodeModel(CM, getEffectiveRelocModel(RM), JIT),
           OL),
-      TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
+      TLOF(createTLOF(getTargetTriple())) {
   initAsmInfo();
 }
 

diff  --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
new file mode 100644
index 0000000000000..a46079818b130
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll
@@ -0,0 +1,13 @@
+; A simple, barebones test to check whether assembly can be emitted
+; for the z/OS target
+; RUN: llc < %s -mtriple=s390x-ibm-zos | FileCheck %s
+
+ at a = global i32 0, align 4
+
+define signext i32 @main() {
+; CHECK: .section ".text"
+; CHECK: main:
+; CHECK: .section "a"
+entry:
+  ret i32 0
+}


        


More information about the llvm-commits mailing list