xref: /src/contrib/llvm-project/llvm/utils/TableGen/Common/CodeGenHwModes.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1044eb2f6SDimitry Andric //===--- CodeGenHwModes.cpp -----------------------------------------------===//
2044eb2f6SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6044eb2f6SDimitry Andric //
7044eb2f6SDimitry Andric //===----------------------------------------------------------------------===//
8044eb2f6SDimitry Andric // Classes to parse and store HW mode information for instruction selection
9044eb2f6SDimitry Andric //===----------------------------------------------------------------------===//
10044eb2f6SDimitry Andric 
11044eb2f6SDimitry Andric #include "CodeGenHwModes.h"
12044eb2f6SDimitry Andric #include "llvm/Support/Debug.h"
13044eb2f6SDimitry Andric #include "llvm/Support/raw_ostream.h"
14044eb2f6SDimitry Andric #include "llvm/TableGen/Error.h"
15044eb2f6SDimitry Andric #include "llvm/TableGen/Record.h"
16044eb2f6SDimitry Andric 
17044eb2f6SDimitry Andric using namespace llvm;
18044eb2f6SDimitry Andric 
19044eb2f6SDimitry Andric StringRef CodeGenHwModes::DefaultModeName = "DefaultMode";
20044eb2f6SDimitry Andric 
HwMode(Record * R)21044eb2f6SDimitry Andric HwMode::HwMode(Record *R) {
22044eb2f6SDimitry Andric   Name = R->getName();
23cfca06d7SDimitry Andric   Features = std::string(R->getValueAsString("Features"));
247fa27ce4SDimitry Andric 
257fa27ce4SDimitry Andric   std::vector<Record *> PredicateRecs = R->getValueAsListOfDefs("Predicates");
267fa27ce4SDimitry Andric   SmallString<128> PredicateCheck;
277fa27ce4SDimitry Andric   raw_svector_ostream OS(PredicateCheck);
287fa27ce4SDimitry Andric   ListSeparator LS(" && ");
297fa27ce4SDimitry Andric   for (Record *Pred : PredicateRecs) {
307fa27ce4SDimitry Andric     StringRef CondString = Pred->getValueAsString("CondString");
317fa27ce4SDimitry Andric     if (CondString.empty())
327fa27ce4SDimitry Andric       continue;
337fa27ce4SDimitry Andric     OS << LS << '(' << CondString << ')';
347fa27ce4SDimitry Andric   }
357fa27ce4SDimitry Andric 
367fa27ce4SDimitry Andric   Predicates = std::string(PredicateCheck);
37044eb2f6SDimitry Andric }
38044eb2f6SDimitry Andric 
39044eb2f6SDimitry Andric LLVM_DUMP_METHOD
dump() const40ac9a064cSDimitry Andric void HwMode::dump() const { dbgs() << Name << ": " << Features << '\n'; }
41044eb2f6SDimitry Andric 
HwModeSelect(Record * R,CodeGenHwModes & CGH)42044eb2f6SDimitry Andric HwModeSelect::HwModeSelect(Record *R, CodeGenHwModes &CGH) {
43044eb2f6SDimitry Andric   std::vector<Record *> Modes = R->getValueAsListOfDefs("Modes");
44044eb2f6SDimitry Andric   std::vector<Record *> Objects = R->getValueAsListOfDefs("Objects");
45044eb2f6SDimitry Andric   if (Modes.size() != Objects.size()) {
46ac9a064cSDimitry Andric     PrintError(
47ac9a064cSDimitry Andric         R->getLoc(),
48ac9a064cSDimitry Andric         "in record " + R->getName() +
49044eb2f6SDimitry Andric             " derived from HwModeSelect: the lists Modes and Objects should "
50044eb2f6SDimitry Andric             "have the same size");
51044eb2f6SDimitry Andric     report_fatal_error("error in target description.");
52044eb2f6SDimitry Andric   }
53044eb2f6SDimitry Andric   for (unsigned i = 0, e = Modes.size(); i != e; ++i) {
547fa27ce4SDimitry Andric     unsigned ModeId = CGH.getHwModeId(Modes[i]);
55ac9a064cSDimitry Andric     Items.push_back(std::pair(ModeId, Objects[i]));
56044eb2f6SDimitry Andric   }
57044eb2f6SDimitry Andric }
58044eb2f6SDimitry Andric 
59044eb2f6SDimitry Andric LLVM_DUMP_METHOD
dump() const60044eb2f6SDimitry Andric void HwModeSelect::dump() const {
61044eb2f6SDimitry Andric   dbgs() << '{';
62044eb2f6SDimitry Andric   for (const PairType &P : Items)
63044eb2f6SDimitry Andric     dbgs() << " (" << P.first << ',' << P.second->getName() << ')';
64044eb2f6SDimitry Andric   dbgs() << " }\n";
65044eb2f6SDimitry Andric }
66044eb2f6SDimitry Andric 
CodeGenHwModes(RecordKeeper & RK)67044eb2f6SDimitry Andric CodeGenHwModes::CodeGenHwModes(RecordKeeper &RK) : Records(RK) {
687fa27ce4SDimitry Andric   for (Record *R : Records.getAllDerivedDefinitions("HwMode")) {
69044eb2f6SDimitry Andric     // The default mode needs a definition in the .td sources for TableGen
70044eb2f6SDimitry Andric     // to accept references to it. We need to ignore the definition here.
717fa27ce4SDimitry Andric     if (R->getName() == DefaultModeName)
72044eb2f6SDimitry Andric       continue;
73044eb2f6SDimitry Andric     Modes.emplace_back(R);
74ac9a064cSDimitry Andric     ModeIds.insert(std::pair(R, Modes.size()));
75044eb2f6SDimitry Andric   }
76044eb2f6SDimitry Andric 
77ac9a064cSDimitry Andric   assert(Modes.size() <= 32 && "number of HwModes exceeds maximum of 32");
78ac9a064cSDimitry Andric 
797fa27ce4SDimitry Andric   for (Record *R : Records.getAllDerivedDefinitions("HwModeSelect")) {
80ac9a064cSDimitry Andric     auto P = ModeSelects.emplace(std::pair(R, HwModeSelect(R, *this)));
81044eb2f6SDimitry Andric     assert(P.second);
82044eb2f6SDimitry Andric     (void)P;
83044eb2f6SDimitry Andric   }
84044eb2f6SDimitry Andric }
85044eb2f6SDimitry Andric 
getHwModeId(Record * R) const867fa27ce4SDimitry Andric unsigned CodeGenHwModes::getHwModeId(Record *R) const {
877fa27ce4SDimitry Andric   if (R->getName() == DefaultModeName)
88044eb2f6SDimitry Andric     return DefaultMode;
897fa27ce4SDimitry Andric   auto F = ModeIds.find(R);
90044eb2f6SDimitry Andric   assert(F != ModeIds.end() && "Unknown mode name");
91044eb2f6SDimitry Andric   return F->second;
92044eb2f6SDimitry Andric }
93044eb2f6SDimitry Andric 
getHwModeSelect(Record * R) const94044eb2f6SDimitry Andric const HwModeSelect &CodeGenHwModes::getHwModeSelect(Record *R) const {
95044eb2f6SDimitry Andric   auto F = ModeSelects.find(R);
96044eb2f6SDimitry Andric   assert(F != ModeSelects.end() && "Record is not a \"mode select\"");
97044eb2f6SDimitry Andric   return F->second;
98044eb2f6SDimitry Andric }
99044eb2f6SDimitry Andric 
100044eb2f6SDimitry Andric LLVM_DUMP_METHOD
dump() const101044eb2f6SDimitry Andric void CodeGenHwModes::dump() const {
102044eb2f6SDimitry Andric   dbgs() << "Modes: {\n";
103044eb2f6SDimitry Andric   for (const HwMode &M : Modes) {
104044eb2f6SDimitry Andric     dbgs() << "  ";
105044eb2f6SDimitry Andric     M.dump();
106044eb2f6SDimitry Andric   }
107044eb2f6SDimitry Andric   dbgs() << "}\n";
108044eb2f6SDimitry Andric 
109044eb2f6SDimitry Andric   dbgs() << "ModeIds: {\n";
110044eb2f6SDimitry Andric   for (const auto &P : ModeIds)
1117fa27ce4SDimitry Andric     dbgs() << "  " << P.first->getName() << " -> " << P.second << '\n';
112044eb2f6SDimitry Andric   dbgs() << "}\n";
113044eb2f6SDimitry Andric 
114044eb2f6SDimitry Andric   dbgs() << "ModeSelects: {\n";
115044eb2f6SDimitry Andric   for (const auto &P : ModeSelects) {
116044eb2f6SDimitry Andric     dbgs() << "  " << P.first->getName() << " -> ";
117044eb2f6SDimitry Andric     P.second.dump();
118044eb2f6SDimitry Andric   }
119044eb2f6SDimitry Andric   dbgs() << "}\n";
120044eb2f6SDimitry Andric }
121