1*0fca6ea1SDimitry Andric //===--- CodeGenHwModes.cpp -----------------------------------------------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric // Classes to parse and store HW mode information for instruction selection 9*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 10*0fca6ea1SDimitry Andric 11*0fca6ea1SDimitry Andric #include "CodeGenHwModes.h" 12*0fca6ea1SDimitry Andric #include "llvm/Support/Debug.h" 13*0fca6ea1SDimitry Andric #include "llvm/Support/raw_ostream.h" 14*0fca6ea1SDimitry Andric #include "llvm/TableGen/Error.h" 15*0fca6ea1SDimitry Andric #include "llvm/TableGen/Record.h" 16*0fca6ea1SDimitry Andric 17*0fca6ea1SDimitry Andric using namespace llvm; 18*0fca6ea1SDimitry Andric 19*0fca6ea1SDimitry Andric StringRef CodeGenHwModes::DefaultModeName = "DefaultMode"; 20*0fca6ea1SDimitry Andric 21*0fca6ea1SDimitry Andric HwMode::HwMode(Record *R) { 22*0fca6ea1SDimitry Andric Name = R->getName(); 23*0fca6ea1SDimitry Andric Features = std::string(R->getValueAsString("Features")); 24*0fca6ea1SDimitry Andric 25*0fca6ea1SDimitry Andric std::vector<Record *> PredicateRecs = R->getValueAsListOfDefs("Predicates"); 26*0fca6ea1SDimitry Andric SmallString<128> PredicateCheck; 27*0fca6ea1SDimitry Andric raw_svector_ostream OS(PredicateCheck); 28*0fca6ea1SDimitry Andric ListSeparator LS(" && "); 29*0fca6ea1SDimitry Andric for (Record *Pred : PredicateRecs) { 30*0fca6ea1SDimitry Andric StringRef CondString = Pred->getValueAsString("CondString"); 31*0fca6ea1SDimitry Andric if (CondString.empty()) 32*0fca6ea1SDimitry Andric continue; 33*0fca6ea1SDimitry Andric OS << LS << '(' << CondString << ')'; 34*0fca6ea1SDimitry Andric } 35*0fca6ea1SDimitry Andric 36*0fca6ea1SDimitry Andric Predicates = std::string(PredicateCheck); 37*0fca6ea1SDimitry Andric } 38*0fca6ea1SDimitry Andric 39*0fca6ea1SDimitry Andric LLVM_DUMP_METHOD 40*0fca6ea1SDimitry Andric void HwMode::dump() const { dbgs() << Name << ": " << Features << '\n'; } 41*0fca6ea1SDimitry Andric 42*0fca6ea1SDimitry Andric HwModeSelect::HwModeSelect(Record *R, CodeGenHwModes &CGH) { 43*0fca6ea1SDimitry Andric std::vector<Record *> Modes = R->getValueAsListOfDefs("Modes"); 44*0fca6ea1SDimitry Andric std::vector<Record *> Objects = R->getValueAsListOfDefs("Objects"); 45*0fca6ea1SDimitry Andric if (Modes.size() != Objects.size()) { 46*0fca6ea1SDimitry Andric PrintError( 47*0fca6ea1SDimitry Andric R->getLoc(), 48*0fca6ea1SDimitry Andric "in record " + R->getName() + 49*0fca6ea1SDimitry Andric " derived from HwModeSelect: the lists Modes and Objects should " 50*0fca6ea1SDimitry Andric "have the same size"); 51*0fca6ea1SDimitry Andric report_fatal_error("error in target description."); 52*0fca6ea1SDimitry Andric } 53*0fca6ea1SDimitry Andric for (unsigned i = 0, e = Modes.size(); i != e; ++i) { 54*0fca6ea1SDimitry Andric unsigned ModeId = CGH.getHwModeId(Modes[i]); 55*0fca6ea1SDimitry Andric Items.push_back(std::pair(ModeId, Objects[i])); 56*0fca6ea1SDimitry Andric } 57*0fca6ea1SDimitry Andric } 58*0fca6ea1SDimitry Andric 59*0fca6ea1SDimitry Andric LLVM_DUMP_METHOD 60*0fca6ea1SDimitry Andric void HwModeSelect::dump() const { 61*0fca6ea1SDimitry Andric dbgs() << '{'; 62*0fca6ea1SDimitry Andric for (const PairType &P : Items) 63*0fca6ea1SDimitry Andric dbgs() << " (" << P.first << ',' << P.second->getName() << ')'; 64*0fca6ea1SDimitry Andric dbgs() << " }\n"; 65*0fca6ea1SDimitry Andric } 66*0fca6ea1SDimitry Andric 67*0fca6ea1SDimitry Andric CodeGenHwModes::CodeGenHwModes(RecordKeeper &RK) : Records(RK) { 68*0fca6ea1SDimitry Andric for (Record *R : Records.getAllDerivedDefinitions("HwMode")) { 69*0fca6ea1SDimitry Andric // The default mode needs a definition in the .td sources for TableGen 70*0fca6ea1SDimitry Andric // to accept references to it. We need to ignore the definition here. 71*0fca6ea1SDimitry Andric if (R->getName() == DefaultModeName) 72*0fca6ea1SDimitry Andric continue; 73*0fca6ea1SDimitry Andric Modes.emplace_back(R); 74*0fca6ea1SDimitry Andric ModeIds.insert(std::pair(R, Modes.size())); 75*0fca6ea1SDimitry Andric } 76*0fca6ea1SDimitry Andric 77*0fca6ea1SDimitry Andric assert(Modes.size() <= 32 && "number of HwModes exceeds maximum of 32"); 78*0fca6ea1SDimitry Andric 79*0fca6ea1SDimitry Andric for (Record *R : Records.getAllDerivedDefinitions("HwModeSelect")) { 80*0fca6ea1SDimitry Andric auto P = ModeSelects.emplace(std::pair(R, HwModeSelect(R, *this))); 81*0fca6ea1SDimitry Andric assert(P.second); 82*0fca6ea1SDimitry Andric (void)P; 83*0fca6ea1SDimitry Andric } 84*0fca6ea1SDimitry Andric } 85*0fca6ea1SDimitry Andric 86*0fca6ea1SDimitry Andric unsigned CodeGenHwModes::getHwModeId(Record *R) const { 87*0fca6ea1SDimitry Andric if (R->getName() == DefaultModeName) 88*0fca6ea1SDimitry Andric return DefaultMode; 89*0fca6ea1SDimitry Andric auto F = ModeIds.find(R); 90*0fca6ea1SDimitry Andric assert(F != ModeIds.end() && "Unknown mode name"); 91*0fca6ea1SDimitry Andric return F->second; 92*0fca6ea1SDimitry Andric } 93*0fca6ea1SDimitry Andric 94*0fca6ea1SDimitry Andric const HwModeSelect &CodeGenHwModes::getHwModeSelect(Record *R) const { 95*0fca6ea1SDimitry Andric auto F = ModeSelects.find(R); 96*0fca6ea1SDimitry Andric assert(F != ModeSelects.end() && "Record is not a \"mode select\""); 97*0fca6ea1SDimitry Andric return F->second; 98*0fca6ea1SDimitry Andric } 99*0fca6ea1SDimitry Andric 100*0fca6ea1SDimitry Andric LLVM_DUMP_METHOD 101*0fca6ea1SDimitry Andric void CodeGenHwModes::dump() const { 102*0fca6ea1SDimitry Andric dbgs() << "Modes: {\n"; 103*0fca6ea1SDimitry Andric for (const HwMode &M : Modes) { 104*0fca6ea1SDimitry Andric dbgs() << " "; 105*0fca6ea1SDimitry Andric M.dump(); 106*0fca6ea1SDimitry Andric } 107*0fca6ea1SDimitry Andric dbgs() << "}\n"; 108*0fca6ea1SDimitry Andric 109*0fca6ea1SDimitry Andric dbgs() << "ModeIds: {\n"; 110*0fca6ea1SDimitry Andric for (const auto &P : ModeIds) 111*0fca6ea1SDimitry Andric dbgs() << " " << P.first->getName() << " -> " << P.second << '\n'; 112*0fca6ea1SDimitry Andric dbgs() << "}\n"; 113*0fca6ea1SDimitry Andric 114*0fca6ea1SDimitry Andric dbgs() << "ModeSelects: {\n"; 115*0fca6ea1SDimitry Andric for (const auto &P : ModeSelects) { 116*0fca6ea1SDimitry Andric dbgs() << " " << P.first->getName() << " -> "; 117*0fca6ea1SDimitry Andric P.second.dump(); 118*0fca6ea1SDimitry Andric } 119*0fca6ea1SDimitry Andric dbgs() << "}\n"; 120*0fca6ea1SDimitry Andric } 121