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