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 17 using namespace llvm; 18 19 StringRef CodeGenHwModes::DefaultModeName = "DefaultMode"; 20 21 HwMode::HwMode(const Record *R) { 22 Name = R->getName(); 23 Features = std::string(R->getValueAsString("Features")); 24 25 SmallString<128> PredicateCheck; 26 raw_svector_ostream OS(PredicateCheck); 27 ListSeparator LS(" && "); 28 for (const Record *Pred : R->getValueAsListOfDefs("Predicates")) { 29 StringRef CondString = Pred->getValueAsString("CondString"); 30 if (CondString.empty()) 31 continue; 32 OS << LS << '(' << CondString << ')'; 33 } 34 35 Predicates = std::string(PredicateCheck); 36 } 37 38 LLVM_DUMP_METHOD 39 void HwMode::dump() const { dbgs() << Name << ": " << Features << '\n'; } 40 41 HwModeSelect::HwModeSelect(const Record *R, CodeGenHwModes &CGH) { 42 std::vector<const Record *> Modes = R->getValueAsListOfConstDefs("Modes"); 43 std::vector<const Record *> Objects = R->getValueAsListOfConstDefs("Objects"); 44 if (Modes.size() != Objects.size()) { 45 PrintError( 46 R->getLoc(), 47 "in record " + R->getName() + 48 " derived from HwModeSelect: the lists Modes and Objects should " 49 "have the same size"); 50 report_fatal_error("error in target description."); 51 } 52 for (auto [Mode, Object] : zip_equal(Modes, Objects)) { 53 unsigned ModeId = CGH.getHwModeId(Mode); 54 Items.push_back(std::pair(ModeId, Object)); 55 } 56 } 57 58 LLVM_DUMP_METHOD 59 void HwModeSelect::dump() const { 60 dbgs() << '{'; 61 for (const PairType &P : Items) 62 dbgs() << " (" << P.first << ',' << P.second->getName() << ')'; 63 dbgs() << " }\n"; 64 } 65 66 CodeGenHwModes::CodeGenHwModes(const RecordKeeper &RK) : Records(RK) { 67 for (const Record *R : Records.getAllDerivedDefinitions("HwMode")) { 68 // The default mode needs a definition in the .td sources for TableGen 69 // to accept references to it. We need to ignore the definition here. 70 if (R->getName() == DefaultModeName) 71 continue; 72 Modes.emplace_back(R); 73 ModeIds.insert(std::pair(R, Modes.size())); 74 } 75 76 assert(Modes.size() <= 32 && "number of HwModes exceeds maximum of 32"); 77 78 for (const Record *R : Records.getAllDerivedDefinitions("HwModeSelect")) { 79 auto P = ModeSelects.emplace(std::pair(R, HwModeSelect(R, *this))); 80 assert(P.second); 81 (void)P; 82 } 83 } 84 85 unsigned CodeGenHwModes::getHwModeId(const Record *R) const { 86 if (R->getName() == DefaultModeName) 87 return DefaultMode; 88 auto F = ModeIds.find(R); 89 assert(F != ModeIds.end() && "Unknown mode name"); 90 return F->second; 91 } 92 93 const HwModeSelect &CodeGenHwModes::getHwModeSelect(const Record *R) const { 94 auto F = ModeSelects.find(R); 95 assert(F != ModeSelects.end() && "Record is not a \"mode select\""); 96 return F->second; 97 } 98 99 LLVM_DUMP_METHOD 100 void CodeGenHwModes::dump() const { 101 dbgs() << "Modes: {\n"; 102 for (const HwMode &M : Modes) { 103 dbgs() << " "; 104 M.dump(); 105 } 106 dbgs() << "}\n"; 107 108 dbgs() << "ModeIds: {\n"; 109 for (const auto &P : ModeIds) 110 dbgs() << " " << P.first->getName() << " -> " << P.second << '\n'; 111 dbgs() << "}\n"; 112 113 dbgs() << "ModeSelects: {\n"; 114 for (const auto &P : ModeSelects) { 115 dbgs() << " " << P.first->getName() << " -> "; 116 P.second.dump(); 117 } 118 dbgs() << "}\n"; 119 } 120