1//===--- CodeGenHwModes.cpp -----------------------------------------------===//
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// Classes to parse and store HW mode information for instruction selection
9//===----------------------------------------------------------------------===//
10
11#include "CodeGenHwModes.h"
12#include "llvm/Support/Debug.h"
13#include "llvm/Support/raw_ostream.h"
14#include "llvm/TableGen/Error.h"
15#include "llvm/TableGen/Record.h"
16
17using namespace llvm;
18
19StringRef CodeGenHwModes::DefaultModeName = "DefaultMode";
20
21HwMode::HwMode(const Record *R) {
22 Name = R->getName();
23 Predicates = R->getValueAsListOfDefs(FieldName: "Predicates");
24}
25
26LLVM_DUMP_METHOD
27void HwMode::dump() const {
28 dbgs() << Name << ": ";
29 ListSeparator LS;
30 for (const Record *R : Predicates)
31 dbgs() << LS << R->getName();
32 dbgs() << '\n';
33}
34
35HwModeSelect::HwModeSelect(const Record *R, CodeGenHwModes &CGH) {
36 std::vector<const Record *> Modes = R->getValueAsListOfDefs(FieldName: "Modes");
37 std::vector<const Record *> Objects = R->getValueAsListOfDefs(FieldName: "Objects");
38 for (auto [Mode, Object] : zip_equal(t&: Modes, u&: Objects)) {
39 unsigned ModeId = CGH.getHwModeId(R: Mode);
40 Items.emplace_back(args&: ModeId, args&: Object);
41 }
42}
43
44LLVM_DUMP_METHOD
45void HwModeSelect::dump() const {
46 dbgs() << '{';
47 for (const PairType &P : Items)
48 dbgs() << " (" << P.first << ',' << P.second->getName() << ')';
49 dbgs() << " }\n";
50}
51
52CodeGenHwModes::CodeGenHwModes(const RecordKeeper &RK) : Records(RK) {
53 for (const Record *R : Records.getAllDerivedDefinitions(ClassName: "HwMode")) {
54 // The default mode needs a definition in the .td sources for TableGen
55 // to accept references to it. We need to ignore the definition here.
56 if (R->getName() == DefaultModeName)
57 continue;
58 Modes.emplace_back(args&: R);
59 ModeIds.try_emplace(Key: R, Args: Modes.size());
60 }
61
62 assert(Modes.size() <= 32 && "number of HwModes exceeds maximum of 32");
63
64 for (const Record *R : Records.getAllDerivedDefinitions(ClassName: "HwModeSelect")) {
65 auto P = ModeSelects.emplace(args&: R, args: HwModeSelect(R, *this));
66 assert(P.second);
67 (void)P;
68 }
69}
70
71unsigned CodeGenHwModes::getHwModeId(const Record *R) const {
72 if (R->getName() == DefaultModeName)
73 return DefaultMode;
74 auto F = ModeIds.find(Val: R);
75 assert(F != ModeIds.end() && "Unknown mode name");
76 return F->second;
77}
78
79const HwModeSelect &CodeGenHwModes::getHwModeSelect(const Record *R) const {
80 auto F = ModeSelects.find(x: R);
81 assert(F != ModeSelects.end() && "Record is not a \"mode select\"");
82 return F->second;
83}
84
85LLVM_DUMP_METHOD
86void CodeGenHwModes::dump() const {
87 dbgs() << "Modes: {\n";
88 for (const HwMode &M : Modes) {
89 dbgs() << " ";
90 M.dump();
91 }
92 dbgs() << "}\n";
93
94 dbgs() << "ModeIds: {\n";
95 for (const auto &P : ModeIds)
96 dbgs() << " " << P.first->getName() << " -> " << P.second << '\n';
97 dbgs() << "}\n";
98
99 dbgs() << "ModeSelects: {\n";
100 for (const auto &P : ModeSelects) {
101 dbgs() << " " << P.first->getName() << " -> ";
102 P.second.dump();
103 }
104 dbgs() << "}\n";
105}
106