Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hexagon] ELF attributes for Hexagon #85359

Merged
merged 3 commits into from
Mar 19, 2024
Merged

Conversation

quic-areg
Copy link
Contributor

Defines a subset of attributes and emits them to a section called .hexagon.attributes.

The current attributes recorded are the attributes needed by llvm-objdump to automatically determine target features and eliminate the need to manually pass features.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' mc Machine (object) code llvm:support objectyaml llvm:binary-utilities labels Mar 15, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 15, 2024

@llvm/pr-subscribers-llvm-support
@llvm/pr-subscribers-llvm-binary-utilities
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-objectyaml
@llvm/pr-subscribers-mc

@llvm/pr-subscribers-clang-driver

Author: None (quic-areg)

Changes

Defines a subset of attributes and emits them to a section called .hexagon.attributes.

The current attributes recorded are the attributes needed by llvm-objdump to automatically determine target features and eliminate the need to manually pass features.


Patch is 36.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85359.diff

24 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+8)
  • (added) clang/test/Driver/hexagon-default-build-attributes.s (+20)
  • (modified) llvm/include/llvm/BinaryFormat/ELF.h (+2)
  • (modified) llvm/include/llvm/Object/ELFObjectFile.h (+3-1)
  • (added) llvm/include/llvm/Support/HexagonAttributeParser.h (+36)
  • (added) llvm/include/llvm/Support/HexagonAttributes.h (+32)
  • (modified) llvm/lib/Object/ELF.cpp (+4-1)
  • (modified) llvm/lib/Object/ELFObjectFile.cpp (+78)
  • (modified) llvm/lib/ObjectYAML/ELFYAML.cpp (+1)
  • (modified) llvm/lib/Support/CMakeLists.txt (+2)
  • (added) llvm/lib/Support/HexagonAttributeParser.cpp (+55)
  • (added) llvm/lib/Support/HexagonAttributes.cpp (+27)
  • (modified) llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp (+62-1)
  • (modified) llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp (+20)
  • (modified) llvm/lib/Target/Hexagon/HexagonAsmPrinter.h (+4)
  • (modified) llvm/lib/Target/Hexagon/HexagonTargetStreamer.h (+9)
  • (modified) llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp (+61)
  • (modified) llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp (+66-6)
  • (modified) llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h (+5-1)
  • (added) llvm/test/CodeGen/Hexagon/build-attributes.ll (+16)
  • (added) llvm/test/MC/Hexagon/directive-attribute-err.s (+24)
  • (added) llvm/test/MC/Hexagon/directive-attribute.s (+41)
  • (added) llvm/test/MC/Hexagon/hexagon_attributes.s (+94)
  • (modified) llvm/tools/llvm-readobj/ELFDumper.cpp (+6)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3a7a1cf99c79ac..5628a6cd002b82 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8477,6 +8477,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
   case llvm::Triple::riscv64:
     AddRISCVTargetArgs(Args, CmdArgs);
     break;
+
+  case llvm::Triple::hexagon:
+    if (Args.hasFlag(options::OPT_mdefault_build_attributes,
+                     options::OPT_mno_default_build_attributes, true)) {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back("-hexagon-add-build-attributes");
+    }
+    break;
   }
 
   // Consume all the warning flags. Usually this would be handled more
diff --git a/clang/test/Driver/hexagon-default-build-attributes.s b/clang/test/Driver/hexagon-default-build-attributes.s
new file mode 100644
index 00000000000000..b83181d6d52e01
--- /dev/null
+++ b/clang/test/Driver/hexagon-default-build-attributes.s
@@ -0,0 +1,20 @@
+/// Enabled by default for assembly
+// RUN: %clang -target hexagon-unknown-elf -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-ENABLED
+
+/// Can be forced on or off for assembly.
+// RUN: %clang -target hexagon-unknown-elf -### %s 2>&1 -mno-default-build-attributes \
+// RUN:    | FileCheck %s -check-prefix CHECK-DISABLED
+// RUN: %clang -target hexagon-unknown-elf -### %s 2>&1 -mdefault-build-attributes \
+// RUN:    | FileCheck %s -check-prefix CHECK-ENABLED
+
+/// Option ignored C/C++ (since we always emit hardware and ABI build attributes
+/// during codegen).
+// RUN: %clang -target hexagon-unknown-elf -### -x c %s -mdefault-build-attributes 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-DISABLED
+// RUN: %clang -target hexagon-unknown-elf -### -x c++ %s -mdefault-build-attributes 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-DISABLED
+
+// CHECK-DISABLED-NOT: "-hexagon-add-build-attributes"
+// CHECK-ENABLED: "-hexagon-add-build-attributes"
+// expected-warning {{argument unused during compilation: '-mno-default-build-attributes'}}
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index bace3a92677a82..877f3f7862c8ba 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1141,6 +1141,8 @@ enum : unsigned {
 
   SHT_CSKY_ATTRIBUTES = 0x70000001U,
 
+  SHT_HEXAGON_ATTRIBUTES = 0x70000003U,
+
   SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
   SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
   SHT_HIUSER = 0xffffffff  // Highest type reserved for applications.
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index c9227da65708cc..7d04d8f8d54bf8 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -60,6 +60,7 @@ class ELFObjectFileBase : public ObjectFile {
 
   SubtargetFeatures getMIPSFeatures() const;
   SubtargetFeatures getARMFeatures() const;
+  SubtargetFeatures getHexagonFeatures() const;
   Expected<SubtargetFeatures> getRISCVFeatures() const;
   SubtargetFeatures getLoongArchFeatures() const;
 
@@ -395,7 +396,8 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
 
     for (const Elf_Shdr &Sec : *SectionsOrErr) {
       if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
-          Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
+          Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES ||
+          Sec.sh_type == ELF::SHT_HEXAGON_ATTRIBUTES) {
         auto ErrorOrContents = EF.getSectionContents(Sec);
         if (!ErrorOrContents)
           return ErrorOrContents.takeError();
diff --git a/llvm/include/llvm/Support/HexagonAttributeParser.h b/llvm/include/llvm/Support/HexagonAttributeParser.h
new file mode 100644
index 00000000000000..c7d866af08f5f7
--- /dev/null
+++ b/llvm/include/llvm/Support/HexagonAttributeParser.h
@@ -0,0 +1,36 @@
+//===-- HexagonAttributeParser.h - Hexagon Attribute Parser -----*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H
+#define LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H
+
+#include "llvm/Support/ELFAttributeParser.h"
+#include "llvm/Support/HexagonAttributes.h"
+
+namespace llvm {
+class HexagonAttributeParser : public ELFAttributeParser {
+  struct DisplayHandler {
+    HexagonAttrs::AttrType Attribute;
+    Error (HexagonAttributeParser::*Routine)(unsigned);
+  };
+
+  static const DisplayHandler DisplayRoutines[];
+
+  Error handler(uint64_t Tag, bool &Handled) override;
+
+public:
+  HexagonAttributeParser(ScopedPrinter *SP)
+      : ELFAttributeParser(SP, HexagonAttrs::getHexagonAttributeTags(),
+                           "hexagon") {}
+  HexagonAttributeParser()
+      : ELFAttributeParser(HexagonAttrs::getHexagonAttributeTags(), "hexagon") {}
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/Support/HexagonAttributes.h b/llvm/include/llvm/Support/HexagonAttributes.h
new file mode 100644
index 00000000000000..8a50d8993e633b
--- /dev/null
+++ b/llvm/include/llvm/Support/HexagonAttributes.h
@@ -0,0 +1,32 @@
+//===-- HexagonAttributes.h - Qualcomm Hexagon Attributes -----------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_HEXAGONATTRIBUTES_H
+#define LLVM_SUPPORT_HEXAGONATTRIBUTES_H
+
+#include "llvm/Support/ELFAttributes.h"
+
+namespace llvm {
+namespace HexagonAttrs {
+
+const TagNameMap &getHexagonAttributeTags();
+
+enum AttrType : unsigned {
+  ARCH = 4,
+  HVXARCH = 5,
+  HVXIEEEFP = 6,
+  HVXQFLOAT = 7,
+  ZREG = 8,
+  AUDIO = 9,
+  CABAC = 10
+};
+
+} // namespace HexagonAttrs
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index 137f606dd2d46b..55dd0c8e06c092 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -251,7 +251,10 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
     }
     break;
   case ELF::EM_HEXAGON:
-    switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
+    switch (Type) {
+      STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED);
+      STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES);
+    }
     break;
   case ELF::EM_X86_64:
     switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index 33be48196ae7d2..efec612957de33 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Support/ARMAttributeParser.h"
 #include "llvm/Support/ARMBuildAttributes.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/HexagonAttributeParser.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/RISCVAttributeParser.h"
 #include "llvm/Support/RISCVAttributes.h"
@@ -287,6 +288,81 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
   return Features;
 }
 
+static std::optional<std::string> hexagonAttrToFeatureString(unsigned Attr) {
+  switch (Attr) {
+  case 5:
+    return "v5";
+  case 55:
+    return "v55";
+  case 60:
+    return "v60";
+  case 62:
+    return "v62";
+  case 65:
+    return "v65";
+  case 67:
+    return "v67";
+  case 68:
+    return "v68";
+  case 69:
+    return "v69";
+  case 71:
+    return "v71";
+  case 73:
+    return "v73";
+  default:
+    return {};
+  }
+}
+
+SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const {
+  SubtargetFeatures Features;
+  HexagonAttributeParser Parser;
+  if (Error E = getBuildAttributes(Parser)) {
+    // Return no attributes if none can be read.
+    // This behavior is important for backwards compatibility.
+    consumeError(std::move(E));
+    return Features;
+  }
+  std::optional<unsigned> Attr;
+
+  if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH))) {
+    if (std::optional<std::string> FeatureString =
+            hexagonAttrToFeatureString(*Attr))
+      Features.AddFeature(*FeatureString);
+  }
+
+  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH))) {
+    std::optional<std::string> FeatureString =
+        hexagonAttrToFeatureString(*Attr);
+    // There is no corresponding hvx arch for v5 and v55.
+    if (FeatureString && *Attr >= 60)
+      Features.AddFeature("hvx" + *FeatureString);
+  }
+
+  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP)))
+    if (*Attr)
+      Features.AddFeature("hvx-ieee-fp");
+
+  if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT)))
+    if (*Attr)
+      Features.AddFeature("hvx-qfloat");
+
+  if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG)))
+    if (*Attr)
+      Features.AddFeature("zreg");
+
+  if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO)))
+    if (*Attr)
+      Features.AddFeature("audio");
+
+  if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC)))
+    if (*Attr)
+      Features.AddFeature("cabac");
+
+  return Features;
+}
+
 Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const {
   SubtargetFeatures Features;
   unsigned PlatformFlags = getPlatformFlags();
@@ -349,6 +425,8 @@ Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const {
     return getRISCVFeatures();
   case ELF::EM_LOONGARCH:
     return getLoongArchFeatures();
+  case ELF::EM_HEXAGON:
+    return getHexagonFeatures();
   default:
     return SubtargetFeatures();
   }
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 9c1a28db592a1c..045211c44b9079 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -716,6 +716,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
     break;
   case ELF::EM_HEXAGON:
     ECase(SHT_HEX_ORDERED);
+    ECase(SHT_HEXAGON_ATTRIBUTES);
     break;
   case ELF::EM_X86_64:
     ECase(SHT_X86_64_UNWIND);
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index b9c13c43e9a7c5..da2a4b4cdec568 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -188,6 +188,8 @@ add_llvm_component_library(LLVMSupport
   GlobPattern.cpp
   GraphWriter.cpp
   Hashing.cpp
+  HexagonAttributeParser.cpp
+  HexagonAttributes.cpp
   InitLLVM.cpp
   InstructionCost.cpp
   IntEqClasses.cpp
diff --git a/llvm/lib/Support/HexagonAttributeParser.cpp b/llvm/lib/Support/HexagonAttributeParser.cpp
new file mode 100644
index 00000000000000..2143162d11c79c
--- /dev/null
+++ b/llvm/lib/Support/HexagonAttributeParser.cpp
@@ -0,0 +1,55 @@
+//===-- HexagonAttributeParser.cpp - Hexagon Attribute Parser -------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/HexagonAttributeParser.h"
+
+using namespace llvm;
+
+const HexagonAttributeParser::DisplayHandler
+    HexagonAttributeParser::DisplayRoutines[] = {
+        {
+            HexagonAttrs::ARCH,
+            &ELFAttributeParser::integerAttribute,
+        },
+        {
+            HexagonAttrs::HVXARCH,
+            &ELFAttributeParser::integerAttribute,
+        },
+        {
+            HexagonAttrs::HVXIEEEFP,
+            &ELFAttributeParser::integerAttribute,
+        },
+        {
+            HexagonAttrs::HVXQFLOAT,
+            &ELFAttributeParser::integerAttribute,
+        },
+        {
+            HexagonAttrs::ZREG,
+            &ELFAttributeParser::integerAttribute,
+        },
+        {
+            HexagonAttrs::AUDIO,
+            &ELFAttributeParser::integerAttribute,
+        },
+        {
+            HexagonAttrs::CABAC,
+            &ELFAttributeParser::integerAttribute,
+        }};
+
+Error HexagonAttributeParser::handler(uint64_t Tag, bool &Handled) {
+  Handled = false;
+  for (const auto &R : DisplayRoutines) {
+    if (uint64_t(R.Attribute) == Tag) {
+      if (Error E = (this->*R.Routine)(Tag))
+        return E;
+      Handled = true;
+      break;
+    }
+  }
+  return Error::success();
+}
diff --git a/llvm/lib/Support/HexagonAttributes.cpp b/llvm/lib/Support/HexagonAttributes.cpp
new file mode 100644
index 00000000000000..165215c8fb676a
--- /dev/null
+++ b/llvm/lib/Support/HexagonAttributes.cpp
@@ -0,0 +1,27 @@
+//===-- HexagonAttributes.cpp - Qualcomm Hexagon Attributes ---------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/HexagonAttributes.h"
+
+using namespace llvm;
+using namespace llvm::HexagonAttrs;
+
+static constexpr TagNameItem TagData[] = {
+    {ARCH, "Tag_arch"},
+    {HVXARCH, "Tag_hvx_arch"},
+    {HVXIEEEFP, "Tag_hvx_ieeefp"},
+    {HVXQFLOAT, "Tag_hvx_qfloat"},
+    {ZREG, "Tag_zreg"},
+    {AUDIO, "Tag_audio"},
+    {CABAC, "Tag_cabac"},
+};
+
+constexpr TagNameMap HexagonAttributeTags{TagData};
+const TagNameMap &llvm::HexagonAttrs::getHexagonAttributeTags() {
+  return HexagonAttributeTags;
+}
diff --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
index fd7d25fa16d1da..d6d4a96b0d302f 100644
--- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
+++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
@@ -43,6 +43,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/HexagonAttributes.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/SMLoc.h"
 #include "llvm/Support/SourceMgr.h"
@@ -79,7 +80,8 @@ static cl::opt<bool> ErrorNoncontigiousRegister(
     "merror-noncontigious-register",
     cl::desc("Error for register names that aren't contigious"),
     cl::init(false));
-
+static cl::opt<bool> AddBuildAttributes("hexagon-add-build-attributes",
+                                        cl::init(false));
 namespace {
 
 struct HexagonOperand;
@@ -120,6 +122,9 @@ class HexagonAsmParser : public MCTargetAsmParser {
                                SMLoc &EndLoc) override;
   bool ParseDirectiveSubsection(SMLoc L);
   bool ParseDirectiveComm(bool IsLocal, SMLoc L);
+
+  bool parseDirectiveAttribute(SMLoc L);
+
   bool RegisterMatchesArch(unsigned MatchNum) const;
 
   bool matchBundleOptions();
@@ -164,6 +169,9 @@ class HexagonAsmParser : public MCTargetAsmParser {
     Parser.addAliasForDirective(".word", ".4byte");
 
     MCAsmParserExtension::Initialize(_Parser);
+
+    if (AddBuildAttributes)
+      getTargetStreamer().emitTargetAttributes(*STI);
   }
 
   bool splitIdentifier(OperandVector &Operands);
@@ -652,6 +660,57 @@ bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return finishBundle(IDLoc, Out);
   return false;
 }
+/// parseDirectiveAttribute
+///  ::= .attribute int, int
+///  ::= .attribute Tag_name, int
+bool HexagonAsmParser::parseDirectiveAttribute(SMLoc L) {
+  MCAsmParser &Parser = getParser();
+  int64_t Tag;
+  SMLoc TagLoc = Parser.getTok().getLoc();
+  if (Parser.getTok().is(AsmToken::Identifier)) {
+    StringRef Name = Parser.getTok().getIdentifier();
+    std::optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
+        Name, HexagonAttrs::getHexagonAttributeTags());
+    if (!Ret)
+      return Error(TagLoc, "attribute name not recognized: " + Name);
+    Tag = *Ret;
+    Parser.Lex();
+  } else {
+    const MCExpr *AttrExpr;
+
+    TagLoc = Parser.getTok().getLoc();
+    if (Parser.parseExpression(AttrExpr))
+      return true;
+
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
+    if (check(!CE, TagLoc, "expected numeric constant"))
+      return true;
+
+    Tag = CE->getValue();
+  }
+
+  if (Parser.parseComma())
+    return true;
+
+  // We currently only have integer values.
+  int64_t IntegerValue = 0;
+  SMLoc ValueExprLoc = Parser.getTok().getLoc();
+  const MCExpr *ValueExpr;
+  if (Parser.parseExpression(ValueExpr))
+    return true;
+
+  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
+  if (!CE)
+    return Error(ValueExprLoc, "expected numeric constant");
+  IntegerValue = CE->getValue();
+
+  if (Parser.parseEOL())
+    return true;
+
+  getTargetStreamer().emitAttribute(Tag, IntegerValue);
+
+  return false;
+}
 
 /// ParseDirective parses the Hexagon specific directives
 bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
@@ -664,6 +723,8 @@ bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
     return ParseDirectiveComm(false, DirectiveID.getLoc());
   if (IDVal.lower() == ".subsection")
     return ParseDirectiveSubsection(DirectiveID.getLoc());
+  if (IDVal == ".attribute")
+    return parseDirectiveAttribute(DirectiveID.getLoc());
 
   return true;
 }
diff --git a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp
index 4ee67cb05d4953..d2f64ac9e90b0b 100644
--- a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp
@@ -17,6 +17,7 @@
 #include "HexagonInstrInfo.h"
 #include "HexagonRegisterInfo.h"
 #include "HexagonSubtarget.h"
+#include "HexagonTargetStreamer.h"
 #include "MCTargetDesc/HexagonInstPrinter.h"
 #include "MCTargetDesc/HexagonMCExpr.h"
 #include "MCTargetDesc/HexagonMCInstrInfo.h"
@@ -46,6 +47,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
@@ -775,6 +777,24 @@ void HexagonAsmPrinter::emitInstruction(const MachineInstr *MI) {
   OutStreamer->emitInstruction(MCB, getSubtargetInfo());
 }
 
+void HexagonAsmPrinter::emitStartOfAsmFile(Module &M) {
+  if (TM.getTargetTriple().isOSBinFormatELF())
+    emitAttributes();
+}
+
+void HexagonAsmPrinter::emitEndOfAsmFile(Module &M) {
+  HexagonTargetStreamer &HTS =
+      static_cast<HexagonTargetStreamer &>(*OutStreamer->getTargetStreamer());
+  if (TM.getTargetTriple().isOSBinFormatELF())
+    HTS.finishAttributeSection();
+}
+
+void HexagonAsmPrinter::emitAttributes() {
+  HexagonTargetStreamer &HTS =
+      static_cast<HexagonTargetStreamer &>(*OutStreamer->getTargetStreamer());
+  HTS.emitTargetAttributes(*TM.getMCSubtargetInfo());
+}
+
 void HexagonAsmPrinter::EmitSled(const MachineInstr &MI, SledKind Kind) {
   static const int8_t NoopsInSledCount = 4;
   // We want to emit the following pattern:
diff --git a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h
index 5cb1edf54d1a76..b555c885965036 100644
--- a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h
+++ b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.h
@@ -29,6 +29,8 @@ class TargetMachine;
   class HexagonAsmPrinter : public AsmPrinter {
     const HexagonSubtarget *Subtarget = nullptr;
 
+    void emitAttributes();
+
   public:
     explicit HexagonAsmPrinter(TargetMachine &TM,
                                std::unique_ptr<MCStreamer> Streamer)
@@ -68,6 +70,8 @@ class TargetMachine;
                          const char *ExtraCode, raw_ostream &OS) override;
     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                                const char *ExtraCode, raw_ostream &OS) override;
+    void emitStartOfAsmFile(Module &M) override;
+    void emitEndOfAsmFile(Module &M) override;
   };
 
 } // end namespace llvm
diff --git a/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h b/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h
index ff84363106629f..a2f93d476bfe1b 100644
--- a/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h
+++ b/llvm/lib/Target/Hexagon/HexagonTargetStreamer.h
@@ -24,6 +2...
[truncated]

Copy link

github-actions bot commented Mar 15, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@quic-areg
Copy link
Contributor Author

@@ -0,0 +1,20 @@
/// Enabled by default for assembly
// RUN: %clang -target hexagon-unknown-elf -### %s 2>&1 \
Copy link
Member

Choose a reason for hiding this comment

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

--target= for new tests.
-target has been deprecated since Clang 3.4

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -79,7 +80,8 @@ static cl::opt<bool> ErrorNoncontigiousRegister(
"merror-noncontigious-register",
cl::desc("Error for register names that aren't contigious"),
cl::init(false));

static cl::opt<bool> AddBuildAttributes("hexagon-add-build-attributes",
cl::init(false));
Copy link
Member

Choose a reason for hiding this comment

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

omit init(false)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

return true;

getTargetStreamer().emitAttribute(Tag, IntegerValue);

Copy link
Member

Choose a reason for hiding this comment

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

unneeded blank line

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

@@ -395,7 +396,8 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {

for (const Elf_Shdr &Sec : *SectionsOrErr) {
if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES ||
Copy link
Member

Choose a reason for hiding this comment

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

These values are all equal. However, we should check getEMachine() == EM_HEXAGON before testing a processor-specific section type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


// CHECK-DISABLED-NOT: "-hexagon-add-build-attributes"
// CHECK-ENABLED: "-hexagon-add-build-attributes"
// expected-warning {{argument unused during compilation: '-mno-default-build-attributes'}}
Copy link
Member

Choose a reason for hiding this comment

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

expected directive is for -verify. Driver tests use -### instead of cc1 -verify

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed

@@ -251,7 +251,10 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
}
break;
case ELF::EM_HEXAGON:
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
switch (Type) {
STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED);
Copy link
Member

Choose a reason for hiding this comment

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

Add a test to llvm/test/tools/llvm-readobj/ELF/machine-specific-section-types.test

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added

// RUN: | FileCheck %s

.attribute Tag_unknown_name, 0
// CHECK: error: attribute name not recognized: Tag_unknown_name
Copy link
Member

Choose a reason for hiding this comment

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

Newer MC tests try to test the error line/column information like: [[#@LINE-1]]:4: error:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Defines a subset of attributes and emits them to a section called
.hexagon.attributes.

The current attributes recorded are the attributes needed by
llvm-objdump to automatically determine target features and eliminate
the need to manually pass features.
@quic-areg
Copy link
Contributor Author

Can this be merged? I don't have write access @androm3da @SundeepKushwaha

@androm3da androm3da merged commit 31f4b32 into llvm:main Mar 19, 2024
4 checks passed
chencha3 pushed a commit to chencha3/llvm-project that referenced this pull request Mar 23, 2024
Defines a subset of attributes and emits them to a section called
.hexagon.attributes.

The current attributes recorded are the attributes needed by
llvm-objdump to automatically determine target features and eliminate
the need to manually pass features.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category llvm:binary-utilities llvm:support mc Machine (object) code objectyaml
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants