diff utils/TableGen/CodeEmitterGen.cpp @ 147:c2174574ed3a

LLVM 10
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 16:55:33 +0900
parents 803732b1fca8
children
line wrap: on
line diff
--- a/utils/TableGen/CodeEmitterGen.cpp	Sat Feb 17 09:57:20 2018 +0900
+++ b/utils/TableGen/CodeEmitterGen.cpp	Wed Aug 14 16:55:33 2019 +0900
@@ -1,9 +1,8 @@
 //===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -16,6 +15,7 @@
 #include "CodeGenInstruction.h"
 #include "CodeGenTarget.h"
 #include "SubtargetFeatureInfo.h"
+#include "Types.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Casting.h"
@@ -229,6 +229,14 @@
   return Case;
 }
 
+static std::string
+getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
+  std::string Name = "CEFBS";
+  for (const auto &Feature : FeatureBitset)
+    Name += ("_" + Feature->getName()).str();
+  return Name;
+}
+
 void CodeEmitterGen::run(raw_ostream &o) {
   CodeGenTarget Target(Records);
   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
@@ -327,8 +335,8 @@
     << "#include <sstream>\n\n";
 
   // Emit the subtarget feature enumeration.
-  SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(SubtargetFeatures,
-                                                            o);
+  SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
+                                                           o);
 
   // Emit the name table for error messages.
   o << "#ifndef NDEBUG\n";
@@ -340,35 +348,97 @@
       Target.getName(), "MCCodeEmitter", "computeAvailableFeatures",
       SubtargetFeatures, o);
 
+  std::vector<std::vector<Record *>> FeatureBitsets;
+  for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
+    FeatureBitsets.emplace_back();
+    for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
+      const auto &I = SubtargetFeatures.find(Predicate);
+      if (I != SubtargetFeatures.end())
+        FeatureBitsets.back().push_back(I->second.TheDef);
+    }
+  }
+
+  llvm::sort(FeatureBitsets, [&](const std::vector<Record *> &A,
+                                 const std::vector<Record *> &B) {
+    if (A.size() < B.size())
+      return true;
+    if (A.size() > B.size())
+      return false;
+    for (const auto &Pair : zip(A, B)) {
+      if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
+        return true;
+      if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
+        return false;
+    }
+    return false;
+  });
+  FeatureBitsets.erase(
+      std::unique(FeatureBitsets.begin(), FeatureBitsets.end()),
+      FeatureBitsets.end());
+  o << "#ifndef NDEBUG\n"
+    << "// Feature bitsets.\n"
+    << "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
+    << "  CEFBS_None,\n";
+  for (const auto &FeatureBitset : FeatureBitsets) {
+    if (FeatureBitset.empty())
+      continue;
+    o << "  " << getNameForFeatureBitset(FeatureBitset) << ",\n";
+  }
+  o << "};\n\n"
+     << "const static FeatureBitset FeatureBitsets[] {\n"
+     << "  {}, // CEFBS_None\n";
+  for (const auto &FeatureBitset : FeatureBitsets) {
+    if (FeatureBitset.empty())
+      continue;
+    o << "  {";
+    for (const auto &Feature : FeatureBitset) {
+      const auto &I = SubtargetFeatures.find(Feature);
+      assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
+      o << I->second.getEnumBitName() << ", ";
+    }
+    o << "},\n";
+  }
+  o << "};\n"
+    << "#endif // NDEBUG\n\n";
+
+
   // Emit the predicate verifier.
   o << "void " << Target.getName()
     << "MCCodeEmitter::verifyInstructionPredicates(\n"
-    << "    const MCInst &Inst, uint64_t AvailableFeatures) const {\n"
+    << "    const MCInst &Inst, const FeatureBitset &AvailableFeatures) const {\n"
     << "#ifndef NDEBUG\n"
-    << "  static uint64_t RequiredFeatures[] = {\n";
+    << "  static " << getMinimalTypeForRange(FeatureBitsets.size())
+    << " RequiredFeaturesRefs[] = {\n";
   unsigned InstIdx = 0;
   for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
-    o << "    ";
+    o << "    CEFBS";
+    unsigned NumPredicates = 0;
     for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) {
       const auto &I = SubtargetFeatures.find(Predicate);
-      if (I != SubtargetFeatures.end())
-        o << I->second.getEnumName() << " | ";
+      if (I != SubtargetFeatures.end()) {
+        o << '_' << I->second.TheDef->getName();
+        NumPredicates++;
+      }
     }
-    o << "0, // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
+    if (!NumPredicates)
+      o << "_None";
+    o << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
     InstIdx++;
   }
   o << "  };\n\n";
   o << "  assert(Inst.getOpcode() < " << InstIdx << ");\n";
-  o << "  uint64_t MissingFeatures =\n"
-    << "      (AvailableFeatures & RequiredFeatures[Inst.getOpcode()]) ^\n"
-    << "      RequiredFeatures[Inst.getOpcode()];\n"
-    << "  if (MissingFeatures) {\n"
+  o << "  const FeatureBitset &RequiredFeatures = "
+       "FeatureBitsets[RequiredFeaturesRefs[Inst.getOpcode()]];\n";
+  o << "  FeatureBitset MissingFeatures =\n"
+    << "      (AvailableFeatures & RequiredFeatures) ^\n"
+    << "      RequiredFeatures;\n"
+    << "  if (MissingFeatures.any()) {\n"
     << "    std::ostringstream Msg;\n"
     << "    Msg << \"Attempting to emit \" << "
        "MCII.getName(Inst.getOpcode()).str()\n"
     << "        << \" instruction but the \";\n"
-    << "    for (unsigned i = 0; i < 8 * sizeof(MissingFeatures); ++i)\n"
-    << "      if (MissingFeatures & (1ULL << i))\n"
+    << "    for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
+    << "      if (MissingFeatures.test(i))\n"
     << "        Msg << SubtargetFeatureNames[i] << \" \";\n"
     << "    Msg << \"predicate(s) are not met\";\n"
     << "    report_fatal_error(Msg.str());\n"