xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenHwModes.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
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
40*0fca6ea1SDimitry Andric void HwMode::dump() const { dbgs() << Name << ": " << Features << '\n'; }
41*0fca6ea1SDimitry Andric 
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
60*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 
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 
86*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 
94*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
101*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