Skip to content

Commit 31f4b32

Browse files
authored
[Hexagon] ELF attributes for Hexagon (#85359)
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.
1 parent e3030f1 commit 31f4b32

25 files changed

+681
-9
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8481,6 +8481,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
84818481
case llvm::Triple::riscv64:
84828482
AddRISCVTargetArgs(Args, CmdArgs);
84838483
break;
8484+
8485+
case llvm::Triple::hexagon:
8486+
if (Args.hasFlag(options::OPT_mdefault_build_attributes,
8487+
options::OPT_mno_default_build_attributes, true)) {
8488+
CmdArgs.push_back("-mllvm");
8489+
CmdArgs.push_back("-hexagon-add-build-attributes");
8490+
}
8491+
break;
84848492
}
84858493

84868494
// Consume all the warning flags. Usually this would be handled more
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// Enabled by default for assembly
2+
// RUN: %clang --target=hexagon-unknown-elf -### %s 2>&1 \
3+
// RUN: | FileCheck %s -check-prefix CHECK-ENABLED
4+
5+
/// Can be forced on or off for assembly.
6+
// RUN: %clang --target=hexagon-unknown-elf -### %s 2>&1 -mno-default-build-attributes \
7+
// RUN: | FileCheck %s -check-prefix CHECK-DISABLED
8+
// RUN: %clang --target=hexagon-unknown-elf -### %s 2>&1 -mdefault-build-attributes \
9+
// RUN: | FileCheck %s -check-prefix CHECK-ENABLED
10+
11+
/// Option ignored C/C++ (since we always emit hardware and ABI build attributes
12+
/// during codegen).
13+
// RUN: %clang --target=hexagon-unknown-elf -### -x c %s -mdefault-build-attributes 2>&1 \
14+
// RUN: | FileCheck %s -check-prefix CHECK-DISABLED-C
15+
// RUN: %clang --target=hexagon-unknown-elf -### -x c++ %s -mdefault-build-attributes 2>&1 \
16+
// RUN: | FileCheck %s -check-prefix CHECK-DISABLED-C
17+
18+
// CHECK-DISABLED-NOT: "-hexagon-add-build-attributes"
19+
// CHECK-DISABLED-C-NOT: "-hexagon-add-build-attributes"
20+
// CHECK-ENABLED: "-hexagon-add-build-attributes"
21+
// CHECK-DISABLED-C: argument unused during compilation: '-mdefault-build-attributes'

llvm/include/llvm/BinaryFormat/ELF.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,8 @@ enum : unsigned {
11411141

11421142
SHT_CSKY_ATTRIBUTES = 0x70000001U,
11431143

1144+
SHT_HEXAGON_ATTRIBUTES = 0x70000003U,
1145+
11441146
SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
11451147
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
11461148
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.

llvm/include/llvm/Object/ELFObjectFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class ELFObjectFileBase : public ObjectFile {
6060

6161
SubtargetFeatures getMIPSFeatures() const;
6262
SubtargetFeatures getARMFeatures() const;
63+
SubtargetFeatures getHexagonFeatures() const;
6364
Expected<SubtargetFeatures> getRISCVFeatures() const;
6465
SubtargetFeatures getLoongArchFeatures() const;
6566

@@ -397,6 +398,9 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
397398
case ELF::EM_RISCV:
398399
Type = ELF::SHT_RISCV_ATTRIBUTES;
399400
break;
401+
case ELF::EM_HEXAGON:
402+
Type = ELF::SHT_HEXAGON_ATTRIBUTES;
403+
break;
400404
default:
401405
return Error::success();
402406
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===-- HexagonAttributeParser.h - Hexagon Attribute Parser -----*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H
10+
#define LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H
11+
12+
#include "llvm/Support/ELFAttributeParser.h"
13+
#include "llvm/Support/HexagonAttributes.h"
14+
15+
namespace llvm {
16+
class HexagonAttributeParser : public ELFAttributeParser {
17+
struct DisplayHandler {
18+
HexagonAttrs::AttrType Attribute;
19+
Error (HexagonAttributeParser::*Routine)(unsigned);
20+
};
21+
22+
static const DisplayHandler DisplayRoutines[];
23+
24+
Error handler(uint64_t Tag, bool &Handled) override;
25+
26+
public:
27+
HexagonAttributeParser(ScopedPrinter *SP)
28+
: ELFAttributeParser(SP, HexagonAttrs::getHexagonAttributeTags(),
29+
"hexagon") {}
30+
HexagonAttributeParser()
31+
: ELFAttributeParser(HexagonAttrs::getHexagonAttributeTags(), "hexagon") {
32+
}
33+
};
34+
35+
} // namespace llvm
36+
37+
#endif
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===-- HexagonAttributes.h - Qualcomm Hexagon Attributes -----------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_SUPPORT_HEXAGONATTRIBUTES_H
10+
#define LLVM_SUPPORT_HEXAGONATTRIBUTES_H
11+
12+
#include "llvm/Support/ELFAttributes.h"
13+
14+
namespace llvm {
15+
namespace HexagonAttrs {
16+
17+
const TagNameMap &getHexagonAttributeTags();
18+
19+
enum AttrType : unsigned {
20+
ARCH = 4,
21+
HVXARCH = 5,
22+
HVXIEEEFP = 6,
23+
HVXQFLOAT = 7,
24+
ZREG = 8,
25+
AUDIO = 9,
26+
CABAC = 10
27+
};
28+
29+
} // namespace HexagonAttrs
30+
} // namespace llvm
31+
32+
#endif

llvm/lib/Object/ELF.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
251251
}
252252
break;
253253
case ELF::EM_HEXAGON:
254-
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
254+
switch (Type) {
255+
STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED);
256+
STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES);
257+
}
255258
break;
256259
case ELF::EM_X86_64:
257260
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }

llvm/lib/Object/ELFObjectFile.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/Support/ARMAttributeParser.h"
2121
#include "llvm/Support/ARMBuildAttributes.h"
2222
#include "llvm/Support/ErrorHandling.h"
23+
#include "llvm/Support/HexagonAttributeParser.h"
2324
#include "llvm/Support/MathExtras.h"
2425
#include "llvm/Support/RISCVAttributeParser.h"
2526
#include "llvm/Support/RISCVAttributes.h"
@@ -287,6 +288,81 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
287288
return Features;
288289
}
289290

291+
static std::optional<std::string> hexagonAttrToFeatureString(unsigned Attr) {
292+
switch (Attr) {
293+
case 5:
294+
return "v5";
295+
case 55:
296+
return "v55";
297+
case 60:
298+
return "v60";
299+
case 62:
300+
return "v62";
301+
case 65:
302+
return "v65";
303+
case 67:
304+
return "v67";
305+
case 68:
306+
return "v68";
307+
case 69:
308+
return "v69";
309+
case 71:
310+
return "v71";
311+
case 73:
312+
return "v73";
313+
default:
314+
return {};
315+
}
316+
}
317+
318+
SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const {
319+
SubtargetFeatures Features;
320+
HexagonAttributeParser Parser;
321+
if (Error E = getBuildAttributes(Parser)) {
322+
// Return no attributes if none can be read.
323+
// This behavior is important for backwards compatibility.
324+
consumeError(std::move(E));
325+
return Features;
326+
}
327+
std::optional<unsigned> Attr;
328+
329+
if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH))) {
330+
if (std::optional<std::string> FeatureString =
331+
hexagonAttrToFeatureString(*Attr))
332+
Features.AddFeature(*FeatureString);
333+
}
334+
335+
if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH))) {
336+
std::optional<std::string> FeatureString =
337+
hexagonAttrToFeatureString(*Attr);
338+
// There is no corresponding hvx arch for v5 and v55.
339+
if (FeatureString && *Attr >= 60)
340+
Features.AddFeature("hvx" + *FeatureString);
341+
}
342+
343+
if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP)))
344+
if (*Attr)
345+
Features.AddFeature("hvx-ieee-fp");
346+
347+
if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT)))
348+
if (*Attr)
349+
Features.AddFeature("hvx-qfloat");
350+
351+
if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG)))
352+
if (*Attr)
353+
Features.AddFeature("zreg");
354+
355+
if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO)))
356+
if (*Attr)
357+
Features.AddFeature("audio");
358+
359+
if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC)))
360+
if (*Attr)
361+
Features.AddFeature("cabac");
362+
363+
return Features;
364+
}
365+
290366
Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const {
291367
SubtargetFeatures Features;
292368
unsigned PlatformFlags = getPlatformFlags();
@@ -349,6 +425,8 @@ Expected<SubtargetFeatures> ELFObjectFileBase::getFeatures() const {
349425
return getRISCVFeatures();
350426
case ELF::EM_LOONGARCH:
351427
return getLoongArchFeatures();
428+
case ELF::EM_HEXAGON:
429+
return getHexagonFeatures();
352430
default:
353431
return SubtargetFeatures();
354432
}

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
716716
break;
717717
case ELF::EM_HEXAGON:
718718
ECase(SHT_HEX_ORDERED);
719+
ECase(SHT_HEXAGON_ATTRIBUTES);
719720
break;
720721
case ELF::EM_X86_64:
721722
ECase(SHT_X86_64_UNWIND);

llvm/lib/Support/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ add_llvm_component_library(LLVMSupport
188188
GlobPattern.cpp
189189
GraphWriter.cpp
190190
Hashing.cpp
191+
HexagonAttributeParser.cpp
192+
HexagonAttributes.cpp
191193
InitLLVM.cpp
192194
InstructionCost.cpp
193195
IntEqClasses.cpp
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===-- HexagonAttributeParser.cpp - Hexagon Attribute Parser -------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/Support/HexagonAttributeParser.h"
10+
11+
using namespace llvm;
12+
13+
const HexagonAttributeParser::DisplayHandler
14+
HexagonAttributeParser::DisplayRoutines[] = {
15+
{
16+
HexagonAttrs::ARCH,
17+
&ELFAttributeParser::integerAttribute,
18+
},
19+
{
20+
HexagonAttrs::HVXARCH,
21+
&ELFAttributeParser::integerAttribute,
22+
},
23+
{
24+
HexagonAttrs::HVXIEEEFP,
25+
&ELFAttributeParser::integerAttribute,
26+
},
27+
{
28+
HexagonAttrs::HVXQFLOAT,
29+
&ELFAttributeParser::integerAttribute,
30+
},
31+
{
32+
HexagonAttrs::ZREG,
33+
&ELFAttributeParser::integerAttribute,
34+
},
35+
{
36+
HexagonAttrs::AUDIO,
37+
&ELFAttributeParser::integerAttribute,
38+
},
39+
{
40+
HexagonAttrs::CABAC,
41+
&ELFAttributeParser::integerAttribute,
42+
}};
43+
44+
Error HexagonAttributeParser::handler(uint64_t Tag, bool &Handled) {
45+
Handled = false;
46+
for (const auto &R : DisplayRoutines) {
47+
if (uint64_t(R.Attribute) == Tag) {
48+
if (Error E = (this->*R.Routine)(Tag))
49+
return E;
50+
Handled = true;
51+
break;
52+
}
53+
}
54+
return Error::success();
55+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===-- HexagonAttributes.cpp - Qualcomm Hexagon Attributes ---------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/Support/HexagonAttributes.h"
10+
11+
using namespace llvm;
12+
using namespace llvm::HexagonAttrs;
13+
14+
static constexpr TagNameItem TagData[] = {
15+
{ARCH, "Tag_arch"},
16+
{HVXARCH, "Tag_hvx_arch"},
17+
{HVXIEEEFP, "Tag_hvx_ieeefp"},
18+
{HVXQFLOAT, "Tag_hvx_qfloat"},
19+
{ZREG, "Tag_zreg"},
20+
{AUDIO, "Tag_audio"},
21+
{CABAC, "Tag_cabac"},
22+
};
23+
24+
constexpr TagNameMap HexagonAttributeTags{TagData};
25+
const TagNameMap &llvm::HexagonAttrs::getHexagonAttributeTags() {
26+
return HexagonAttributeTags;
27+
}

0 commit comments

Comments
 (0)