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 { dbgs() << Name << ": " << Features << '\n'; } 41 42 HwModeSelect::HwModeSelect(Record *R, CodeGenHwModes &CGH) { 43 std::vector<Record *> Modes = R->getValueAsListOfDefs("Modes"); 44 std::vector<Record *> Objects = R->getValueAsListOfDefs("Objects"); 45 if (Modes.size() != Objects.size()) { 46 PrintError( 47 R->getLoc(), 48 "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::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::pair(R, Modes.size())); 75 } 76 77 assert(Modes.size() <= 32 && "number of HwModes exceeds maximum of 32"); 78 79 for (Record *R : Records.getAllDerivedDefinitions("HwModeSelect")) { 80 auto P = ModeSelects.emplace(std::pair(R, HwModeSelect(R, *this))); 81 assert(P.second); 82 (void)P; 83 } 84 } 85 86 unsigned CodeGenHwModes::getHwModeId(Record *R) const { 87 if (R->getName() == DefaultModeName) 88 return DefaultMode; 89 auto F = ModeIds.find(R); 90 assert(F != ModeIds.end() && "Unknown mode name"); 91 return F->second; 92 } 93 94 const HwModeSelect &CodeGenHwModes::getHwModeSelect(Record *R) const { 95 auto F = ModeSelects.find(R); 96 assert(F != ModeSelects.end() && "Record is not a \"mode select\""); 97 return F->second; 98 } 99 100 LLVM_DUMP_METHOD 101 void CodeGenHwModes::dump() const { 102 dbgs() << "Modes: {\n"; 103 for (const HwMode &M : Modes) { 104 dbgs() << " "; 105 M.dump(); 106 } 107 dbgs() << "}\n"; 108 109 dbgs() << "ModeIds: {\n"; 110 for (const auto &P : ModeIds) 111 dbgs() << " " << P.first->getName() << " -> " << P.second << '\n'; 112 dbgs() << "}\n"; 113 114 dbgs() << "ModeSelects: {\n"; 115 for (const auto &P : ModeSelects) { 116 dbgs() << " " << P.first->getName() << " -> "; 117 P.second.dump(); 118 } 119 dbgs() << "}\n"; 120 } 121