1*0b57cec5SDimitry Andric //===--- CodeGenHwModes.cpp -----------------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric // Classes to parse and store HW mode information for instruction selection
9*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10*0b57cec5SDimitry Andric
11*0b57cec5SDimitry Andric #include "CodeGenHwModes.h"
12*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
13*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
14*0b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
15*0b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
16*0b57cec5SDimitry Andric
17*0b57cec5SDimitry Andric using namespace llvm;
18*0b57cec5SDimitry Andric
19*0b57cec5SDimitry Andric StringRef CodeGenHwModes::DefaultModeName = "DefaultMode";
20*0b57cec5SDimitry Andric
HwMode(Record * R)21*0b57cec5SDimitry Andric HwMode::HwMode(Record *R) {
22*0b57cec5SDimitry Andric Name = R->getName();
23*0b57cec5SDimitry Andric Features = std::string(R->getValueAsString("Features"));
24*0b57cec5SDimitry Andric }
25*0b57cec5SDimitry Andric
26*0b57cec5SDimitry Andric LLVM_DUMP_METHOD
dump() const27*0b57cec5SDimitry Andric void HwMode::dump() const {
28*0b57cec5SDimitry Andric dbgs() << Name << ": " << Features << '\n';
29*0b57cec5SDimitry Andric }
30*0b57cec5SDimitry Andric
HwModeSelect(Record * R,CodeGenHwModes & CGH)31*0b57cec5SDimitry Andric HwModeSelect::HwModeSelect(Record *R, CodeGenHwModes &CGH) {
32*0b57cec5SDimitry Andric std::vector<Record*> Modes = R->getValueAsListOfDefs("Modes");
33*0b57cec5SDimitry Andric std::vector<Record*> Objects = R->getValueAsListOfDefs("Objects");
34*0b57cec5SDimitry Andric if (Modes.size() != Objects.size()) {
35*0b57cec5SDimitry Andric PrintError(R->getLoc(), "in record " + R->getName() +
36*0b57cec5SDimitry Andric " derived from HwModeSelect: the lists Modes and Objects should "
37*0b57cec5SDimitry Andric "have the same size");
38*0b57cec5SDimitry Andric report_fatal_error("error in target description.");
39*0b57cec5SDimitry Andric }
40*0b57cec5SDimitry Andric for (unsigned i = 0, e = Modes.size(); i != e; ++i) {
41*0b57cec5SDimitry Andric unsigned ModeId = CGH.getHwModeId(Modes[i]->getName());
42*0b57cec5SDimitry Andric Items.push_back(std::make_pair(ModeId, Objects[i]));
43*0b57cec5SDimitry Andric }
44*0b57cec5SDimitry Andric }
45*0b57cec5SDimitry Andric
46*0b57cec5SDimitry Andric LLVM_DUMP_METHOD
dump() const47*0b57cec5SDimitry Andric void HwModeSelect::dump() const {
48*0b57cec5SDimitry Andric dbgs() << '{';
49*0b57cec5SDimitry Andric for (const PairType &P : Items)
50*0b57cec5SDimitry Andric dbgs() << " (" << P.first << ',' << P.second->getName() << ')';
51*0b57cec5SDimitry Andric dbgs() << " }\n";
52*0b57cec5SDimitry Andric }
53*0b57cec5SDimitry Andric
CodeGenHwModes(RecordKeeper & RK)54*0b57cec5SDimitry Andric CodeGenHwModes::CodeGenHwModes(RecordKeeper &RK) : Records(RK) {
55*0b57cec5SDimitry Andric std::vector<Record*> MRs = Records.getAllDerivedDefinitions("HwMode");
56*0b57cec5SDimitry Andric // The default mode needs a definition in the .td sources for TableGen
57*0b57cec5SDimitry Andric // to accept references to it. We need to ignore the definition here.
58*0b57cec5SDimitry Andric for (auto I = MRs.begin(), E = MRs.end(); I != E; ++I) {
59*0b57cec5SDimitry Andric if ((*I)->getName() != DefaultModeName)
60*0b57cec5SDimitry Andric continue;
61*0b57cec5SDimitry Andric MRs.erase(I);
62*0b57cec5SDimitry Andric break;
63*0b57cec5SDimitry Andric }
64*0b57cec5SDimitry Andric
65*0b57cec5SDimitry Andric for (Record *R : MRs) {
66*0b57cec5SDimitry Andric Modes.emplace_back(R);
67*0b57cec5SDimitry Andric unsigned NewId = Modes.size();
68*0b57cec5SDimitry Andric ModeIds.insert(std::make_pair(Modes[NewId-1].Name, NewId));
69*0b57cec5SDimitry Andric }
70*0b57cec5SDimitry Andric
71*0b57cec5SDimitry Andric std::vector<Record*> MSs = Records.getAllDerivedDefinitions("HwModeSelect");
72*0b57cec5SDimitry Andric for (Record *R : MSs) {
73*0b57cec5SDimitry Andric auto P = ModeSelects.emplace(std::make_pair(R, HwModeSelect(R, *this)));
74*0b57cec5SDimitry Andric assert(P.second);
75*0b57cec5SDimitry Andric (void)P;
76*0b57cec5SDimitry Andric }
77*0b57cec5SDimitry Andric }
78*0b57cec5SDimitry Andric
getHwModeId(StringRef Name) const79*0b57cec5SDimitry Andric unsigned CodeGenHwModes::getHwModeId(StringRef Name) const {
80*0b57cec5SDimitry Andric if (Name == DefaultModeName)
81*0b57cec5SDimitry Andric return DefaultMode;
82*0b57cec5SDimitry Andric auto F = ModeIds.find(Name);
83*0b57cec5SDimitry Andric assert(F != ModeIds.end() && "Unknown mode name");
84*0b57cec5SDimitry Andric return F->second;
85*0b57cec5SDimitry Andric }
86*0b57cec5SDimitry Andric
getHwModeSelect(Record * R) const87*0b57cec5SDimitry Andric const HwModeSelect &CodeGenHwModes::getHwModeSelect(Record *R) const {
88*0b57cec5SDimitry Andric auto F = ModeSelects.find(R);
89*0b57cec5SDimitry Andric assert(F != ModeSelects.end() && "Record is not a \"mode select\"");
90*0b57cec5SDimitry Andric return F->second;
91*0b57cec5SDimitry Andric }
92*0b57cec5SDimitry Andric
93*0b57cec5SDimitry Andric LLVM_DUMP_METHOD
dump() const94*0b57cec5SDimitry Andric void CodeGenHwModes::dump() const {
95*0b57cec5SDimitry Andric dbgs() << "Modes: {\n";
96*0b57cec5SDimitry Andric for (const HwMode &M : Modes) {
97*0b57cec5SDimitry Andric dbgs() << " ";
98*0b57cec5SDimitry Andric M.dump();
99*0b57cec5SDimitry Andric }
100*0b57cec5SDimitry Andric dbgs() << "}\n";
101*0b57cec5SDimitry Andric
102*0b57cec5SDimitry Andric dbgs() << "ModeIds: {\n";
103*0b57cec5SDimitry Andric for (const auto &P : ModeIds)
104*0b57cec5SDimitry Andric dbgs() << " " << P.first() << " -> " << P.second << '\n';
105*0b57cec5SDimitry Andric dbgs() << "}\n";
106*0b57cec5SDimitry Andric
107*0b57cec5SDimitry Andric dbgs() << "ModeSelects: {\n";
108*0b57cec5SDimitry Andric for (const auto &P : ModeSelects) {
109*0b57cec5SDimitry Andric dbgs() << " " << P.first->getName() << " -> ";
110*0b57cec5SDimitry Andric P.second.dump();
111*0b57cec5SDimitry Andric }
112*0b57cec5SDimitry Andric dbgs() << "}\n";
113*0b57cec5SDimitry Andric }
114