Mercurial > hg > CbC > CbC_llvm
comparison 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 |
comparison
equal
deleted
inserted
replaced
134:3a76565eade5 | 147:c2174574ed3a |
---|---|
1 //===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// | 1 //===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 // | 8 // |
10 // CodeEmitterGen uses the descriptions of instructions and their fields to | 9 // CodeEmitterGen uses the descriptions of instructions and their fields to |
11 // construct an automated code emitter: a function that, given a MachineInstr, | 10 // construct an automated code emitter: a function that, given a MachineInstr, |
14 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
15 | 14 |
16 #include "CodeGenInstruction.h" | 15 #include "CodeGenInstruction.h" |
17 #include "CodeGenTarget.h" | 16 #include "CodeGenTarget.h" |
18 #include "SubtargetFeatureInfo.h" | 17 #include "SubtargetFeatureInfo.h" |
18 #include "Types.h" | |
19 #include "llvm/ADT/ArrayRef.h" | 19 #include "llvm/ADT/ArrayRef.h" |
20 #include "llvm/ADT/StringExtras.h" | 20 #include "llvm/ADT/StringExtras.h" |
21 #include "llvm/Support/Casting.h" | 21 #include "llvm/Support/Casting.h" |
22 #include "llvm/Support/raw_ostream.h" | 22 #include "llvm/Support/raw_ostream.h" |
23 #include "llvm/TableGen/Record.h" | 23 #include "llvm/TableGen/Record.h" |
227 } | 227 } |
228 | 228 |
229 return Case; | 229 return Case; |
230 } | 230 } |
231 | 231 |
232 static std::string | |
233 getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) { | |
234 std::string Name = "CEFBS"; | |
235 for (const auto &Feature : FeatureBitset) | |
236 Name += ("_" + Feature->getName()).str(); | |
237 return Name; | |
238 } | |
239 | |
232 void CodeEmitterGen::run(raw_ostream &o) { | 240 void CodeEmitterGen::run(raw_ostream &o) { |
233 CodeGenTarget Target(Records); | 241 CodeGenTarget Target(Records); |
234 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); | 242 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); |
235 | 243 |
236 // For little-endian instruction bit encodings, reverse the bit order | 244 // For little-endian instruction bit encodings, reverse the bit order |
325 o << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n" | 333 o << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n" |
326 << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n" | 334 << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n" |
327 << "#include <sstream>\n\n"; | 335 << "#include <sstream>\n\n"; |
328 | 336 |
329 // Emit the subtarget feature enumeration. | 337 // Emit the subtarget feature enumeration. |
330 SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(SubtargetFeatures, | 338 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures, |
331 o); | 339 o); |
332 | 340 |
333 // Emit the name table for error messages. | 341 // Emit the name table for error messages. |
334 o << "#ifndef NDEBUG\n"; | 342 o << "#ifndef NDEBUG\n"; |
335 SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, o); | 343 SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, o); |
336 o << "#endif // NDEBUG\n"; | 344 o << "#endif // NDEBUG\n"; |
338 // Emit the available features compute function. | 346 // Emit the available features compute function. |
339 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures( | 347 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures( |
340 Target.getName(), "MCCodeEmitter", "computeAvailableFeatures", | 348 Target.getName(), "MCCodeEmitter", "computeAvailableFeatures", |
341 SubtargetFeatures, o); | 349 SubtargetFeatures, o); |
342 | 350 |
351 std::vector<std::vector<Record *>> FeatureBitsets; | |
352 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { | |
353 FeatureBitsets.emplace_back(); | |
354 for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) { | |
355 const auto &I = SubtargetFeatures.find(Predicate); | |
356 if (I != SubtargetFeatures.end()) | |
357 FeatureBitsets.back().push_back(I->second.TheDef); | |
358 } | |
359 } | |
360 | |
361 llvm::sort(FeatureBitsets, [&](const std::vector<Record *> &A, | |
362 const std::vector<Record *> &B) { | |
363 if (A.size() < B.size()) | |
364 return true; | |
365 if (A.size() > B.size()) | |
366 return false; | |
367 for (const auto &Pair : zip(A, B)) { | |
368 if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName()) | |
369 return true; | |
370 if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName()) | |
371 return false; | |
372 } | |
373 return false; | |
374 }); | |
375 FeatureBitsets.erase( | |
376 std::unique(FeatureBitsets.begin(), FeatureBitsets.end()), | |
377 FeatureBitsets.end()); | |
378 o << "#ifndef NDEBUG\n" | |
379 << "// Feature bitsets.\n" | |
380 << "enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n" | |
381 << " CEFBS_None,\n"; | |
382 for (const auto &FeatureBitset : FeatureBitsets) { | |
383 if (FeatureBitset.empty()) | |
384 continue; | |
385 o << " " << getNameForFeatureBitset(FeatureBitset) << ",\n"; | |
386 } | |
387 o << "};\n\n" | |
388 << "const static FeatureBitset FeatureBitsets[] {\n" | |
389 << " {}, // CEFBS_None\n"; | |
390 for (const auto &FeatureBitset : FeatureBitsets) { | |
391 if (FeatureBitset.empty()) | |
392 continue; | |
393 o << " {"; | |
394 for (const auto &Feature : FeatureBitset) { | |
395 const auto &I = SubtargetFeatures.find(Feature); | |
396 assert(I != SubtargetFeatures.end() && "Didn't import predicate?"); | |
397 o << I->second.getEnumBitName() << ", "; | |
398 } | |
399 o << "},\n"; | |
400 } | |
401 o << "};\n" | |
402 << "#endif // NDEBUG\n\n"; | |
403 | |
404 | |
343 // Emit the predicate verifier. | 405 // Emit the predicate verifier. |
344 o << "void " << Target.getName() | 406 o << "void " << Target.getName() |
345 << "MCCodeEmitter::verifyInstructionPredicates(\n" | 407 << "MCCodeEmitter::verifyInstructionPredicates(\n" |
346 << " const MCInst &Inst, uint64_t AvailableFeatures) const {\n" | 408 << " const MCInst &Inst, const FeatureBitset &AvailableFeatures) const {\n" |
347 << "#ifndef NDEBUG\n" | 409 << "#ifndef NDEBUG\n" |
348 << " static uint64_t RequiredFeatures[] = {\n"; | 410 << " static " << getMinimalTypeForRange(FeatureBitsets.size()) |
411 << " RequiredFeaturesRefs[] = {\n"; | |
349 unsigned InstIdx = 0; | 412 unsigned InstIdx = 0; |
350 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { | 413 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { |
351 o << " "; | 414 o << " CEFBS"; |
415 unsigned NumPredicates = 0; | |
352 for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) { | 416 for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs("Predicates")) { |
353 const auto &I = SubtargetFeatures.find(Predicate); | 417 const auto &I = SubtargetFeatures.find(Predicate); |
354 if (I != SubtargetFeatures.end()) | 418 if (I != SubtargetFeatures.end()) { |
355 o << I->second.getEnumName() << " | "; | 419 o << '_' << I->second.TheDef->getName(); |
356 } | 420 NumPredicates++; |
357 o << "0, // " << Inst->TheDef->getName() << " = " << InstIdx << "\n"; | 421 } |
422 } | |
423 if (!NumPredicates) | |
424 o << "_None"; | |
425 o << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n"; | |
358 InstIdx++; | 426 InstIdx++; |
359 } | 427 } |
360 o << " };\n\n"; | 428 o << " };\n\n"; |
361 o << " assert(Inst.getOpcode() < " << InstIdx << ");\n"; | 429 o << " assert(Inst.getOpcode() < " << InstIdx << ");\n"; |
362 o << " uint64_t MissingFeatures =\n" | 430 o << " const FeatureBitset &RequiredFeatures = " |
363 << " (AvailableFeatures & RequiredFeatures[Inst.getOpcode()]) ^\n" | 431 "FeatureBitsets[RequiredFeaturesRefs[Inst.getOpcode()]];\n"; |
364 << " RequiredFeatures[Inst.getOpcode()];\n" | 432 o << " FeatureBitset MissingFeatures =\n" |
365 << " if (MissingFeatures) {\n" | 433 << " (AvailableFeatures & RequiredFeatures) ^\n" |
434 << " RequiredFeatures;\n" | |
435 << " if (MissingFeatures.any()) {\n" | |
366 << " std::ostringstream Msg;\n" | 436 << " std::ostringstream Msg;\n" |
367 << " Msg << \"Attempting to emit \" << " | 437 << " Msg << \"Attempting to emit \" << " |
368 "MCII.getName(Inst.getOpcode()).str()\n" | 438 "MCII.getName(Inst.getOpcode()).str()\n" |
369 << " << \" instruction but the \";\n" | 439 << " << \" instruction but the \";\n" |
370 << " for (unsigned i = 0; i < 8 * sizeof(MissingFeatures); ++i)\n" | 440 << " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n" |
371 << " if (MissingFeatures & (1ULL << i))\n" | 441 << " if (MissingFeatures.test(i))\n" |
372 << " Msg << SubtargetFeatureNames[i] << \" \";\n" | 442 << " Msg << SubtargetFeatureNames[i] << \" \";\n" |
373 << " Msg << \"predicate(s) are not met\";\n" | 443 << " Msg << \"predicate(s) are not met\";\n" |
374 << " report_fatal_error(Msg.str());\n" | 444 << " report_fatal_error(Msg.str());\n" |
375 << " }\n" | 445 << " }\n" |
376 << "#else\n" | 446 << "#else\n" |