brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · e2b5241 Raw
173 lines · cpp
1//===- TargetFeaturesEmitter.cpp - Generate CPU Target feature ----===//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-exception6//7//===----------------------------------------------------------------------===//8//9//  This tablegen backend exports cpu target features10//  and cpu sub-type.11//12//===----------------------------------------------------------------------===//13 14#include "TargetFeaturesEmitter.h"15#include "llvm/TableGen/CodeGenHelpers.h"16#include "llvm/TableGen/Error.h"17#include "llvm/TableGen/TableGenBackend.h"18#include "llvm/TargetParser/SubtargetFeature.h"19 20using namespace llvm;21 22using FeatureMapTy = DenseMap<const Record *, unsigned>;23using ConstRecVec = std::vector<const Record *>;24 25TargetFeaturesEmitter::TargetFeaturesEmitter(const RecordKeeper &R)26    : Records(R) {27  ArrayRef<const Record *> Targets = Records.getAllDerivedDefinitions("Target");28  if (Targets.size() == 0)29    PrintFatalError("No 'Target' subclasses defined!");30  if (Targets.size() != 1)31    PrintFatalError("Multiple subclasses of Target defined!");32  Target = Targets[0]->getName();33}34 35FeatureMapTy TargetFeaturesEmitter::enumeration(raw_ostream &OS) {36  ArrayRef<const Record *> DefList =37      Records.getAllDerivedDefinitions("SubtargetFeature");38 39  unsigned N = DefList.size();40  if (N == 0)41    return FeatureMapTy();42 43  if (N + 1 > MAX_SUBTARGET_FEATURES)44    PrintFatalError(45        "Too many subtarget features! Bump MAX_SUBTARGET_FEATURES.");46 47  NamespaceEmitter NS(OS, Target);48 49  OS << "enum {\n";50 51  FeatureMapTy FeatureMap;52  for (unsigned I = 0; I < N; ++I) {53    const Record *Def = DefList[I];54    // Print the Feature Name.55    OS << "  " << Def->getName() << " = " << I << ",\n";56 57    FeatureMap[Def] = I;58  }59 60  OS << "  " << "NumSubtargetFeatures = " << N << "\n";61 62  // Close enumeration.63  OS << "};\n";64  return FeatureMap;65}66 67void TargetFeaturesEmitter::printFeatureMask(68    raw_ostream &OS, ArrayRef<const Record *> FeatureList,69    const FeatureMapTy &FeatureMap) {70  std::array<uint64_t, MAX_SUBTARGET_WORDS> Mask = {};71  for (const Record *Feature : FeatureList) {72    unsigned Bit = FeatureMap.lookup(Feature);73    Mask[Bit / 64] |= 1ULL << (Bit % 64);74  }75 76  OS << "{ { { ";77  for (unsigned I = 0; I != Mask.size(); ++I) {78    OS << "0x";79    OS.write_hex(Mask[I]);80    OS << "ULL, ";81  }82  OS << "} } }";83}84 85void TargetFeaturesEmitter::printFeatureKeyValues(86    raw_ostream &OS, const FeatureMapTy &FeatureMap) {87  std::vector<const Record *> FeatureList =88      Records.getAllDerivedDefinitions("SubtargetFeature");89 90  // Remove features with empty name.91  llvm::erase_if(FeatureList, [](const Record *Rec) {92    return Rec->getValueAsString("Name").empty();93  });94 95  if (FeatureList.empty())96    return;97 98  llvm::sort(FeatureList, LessRecordFieldName());99 100  // Begin feature table.101  OS << "// Sorted (by key) array of values for CPU features.\n"102     << "extern const llvm::BasicSubtargetFeatureKV " << "Basic" << Target103     << "FeatureKV[] = {\n";104 105  for (const Record *Feature : FeatureList) {106    StringRef Name = Feature->getName();107    StringRef ValueName = Feature->getValueAsString("Name");108 109    OS << "  { " << "\"" << ValueName << "\", " << Target << "::" << Name110       << ", ";111 112    ConstRecVec ImpliesList = Feature->getValueAsListOfDefs("Implies");113 114    printFeatureMask(OS, ImpliesList, FeatureMap);115 116    OS << " },\n";117  }118 119  // End feature table.120  OS << "};\n";121}122 123void TargetFeaturesEmitter::printCPUKeyValues(raw_ostream &OS,124                                              const FeatureMapTy &FeatureMap) {125  // Gather and sort processor information126  std::vector<const Record *> ProcessorList =127      Records.getAllDerivedDefinitions("Processor");128  llvm::sort(ProcessorList, LessRecordFieldName());129 130  // Begin processor table.131  OS << "// Sorted (by key) array of values for CPU subtype.\n"132     << "extern const llvm::BasicSubtargetSubTypeKV " << "Basic" << Target133     << "SubTypeKV[] = {\n";134 135  for (const Record *Processor : ProcessorList) {136    StringRef Name = Processor->getValueAsString("Name");137    ConstRecVec FeatureList = Processor->getValueAsListOfDefs("Features");138 139    OS << " { " << "\"" << Name << "\", ";140 141    printFeatureMask(OS, FeatureList, FeatureMap);142    OS << " },\n";143  }144 145  // End processor table.146  OS << "};\n";147}148 149void TargetFeaturesEmitter::run(raw_ostream &OS) {150  OS << "// Autogenerated by TargetFeatureEmitter.cpp\n\n";151 152  FeatureMapTy FeatureMap;153  {154    IfDefEmitter IfDef(OS, "GET_SUBTARGETFEATURES_ENUM");155    NamespaceEmitter NS(OS, "llvm");156    FeatureMap = enumeration(OS);157  }158 159  {160    IfDefEmitter IfDef(OS, "GET_SUBTARGETFEATURES_KV");161    NamespaceEmitter NS(OS, "llvm");162 163    printFeatureKeyValues(OS, FeatureMap);164    OS << "\n";165 166    printCPUKeyValues(OS, FeatureMap);167    OS << "\n";168  }169}170 171static TableGen::Emitter::OptClass<TargetFeaturesEmitter>172    X("gen-target-features", "Generate subtarget enumerations");173