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->getValueAsListOfDefs("Modes"); 43 std::vector<const Record *> Objects = R->getValueAsListOfDefs("Objects"); 44 for (auto [Mode, Object] : zip_equal(Modes, Objects)) { 45 unsigned ModeId = CGH.getHwModeId(Mode); 46 Items.emplace_back(ModeId, Object); 47 } 48 } 49 50 LLVM_DUMP_METHOD 51 void HwModeSelect::dump() const { 52 dbgs() << '{'; 53 for (const PairType &P : Items) 54 dbgs() << " (" << P.first << ',' << P.second->getName() << ')'; 55 dbgs() << " }\n"; 56 } 57 58 CodeGenHwModes::CodeGenHwModes(const RecordKeeper &RK) : Records(RK) { 59 for (const Record *R : Records.getAllDerivedDefinitions("HwMode")) { 60 // The default mode needs a definition in the .td sources for TableGen 61 // to accept references to it. We need to ignore the definition here. 62 if (R->getName() == DefaultModeName) 63 continue; 64 Modes.emplace_back(R); 65 ModeIds.try_emplace(R, Modes.size()); 66 } 67 68 assert(Modes.size() <= 32 && "number of HwModes exceeds maximum of 32"); 69 70 for (const Record *R : Records.getAllDerivedDefinitions("HwModeSelect")) { 71 auto P = ModeSelects.emplace(R, HwModeSelect(R, *this)); 72 assert(P.second); 73 (void)P; 74 } 75 } 76 77 unsigned CodeGenHwModes::getHwModeId(const Record *R) const { 78 if (R->getName() == DefaultModeName) 79 return DefaultMode; 80 auto F = ModeIds.find(R); 81 assert(F != ModeIds.end() && "Unknown mode name"); 82 return F->second; 83 } 84 85 const HwModeSelect &CodeGenHwModes::getHwModeSelect(const Record *R) const { 86 auto F = ModeSelects.find(R); 87 assert(F != ModeSelects.end() && "Record is not a \"mode select\""); 88 return F->second; 89 } 90 91 LLVM_DUMP_METHOD 92 void CodeGenHwModes::dump() const { 93 dbgs() << "Modes: {\n"; 94 for (const HwMode &M : Modes) { 95 dbgs() << " "; 96 M.dump(); 97 } 98 dbgs() << "}\n"; 99 100 dbgs() << "ModeIds: {\n"; 101 for (const auto &P : ModeIds) 102 dbgs() << " " << P.first->getName() << " -> " << P.second << '\n'; 103 dbgs() << "}\n"; 104 105 dbgs() << "ModeSelects: {\n"; 106 for (const auto &P : ModeSelects) { 107 dbgs() << " " << P.first->getName() << " -> "; 108 P.second.dump(); 109 } 110 dbgs() << "}\n"; 111 } 112