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