[TableGen] Add a way of getting the number of generic opcodes without including modular CodeGen headers.

This is a bit of a hack, but removes a cycle that broke modular builds
of LLVM. Of course the cycle is still there in form of a dependency
on the .def file.

llvm-svn: 323383
This commit is contained in:
Benjamin Kramer 2018-01-24 22:35:11 +00:00
parent 0c352b15d7
commit 4890a71f02
3 changed files with 18 additions and 9 deletions

View File

@ -19,7 +19,6 @@
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/Regex.h" #include "llvm/Support/Regex.h"
@ -104,9 +103,10 @@ struct InstRegexOp : public SetTheory::Operator {
RegexList.push_back(std::make_pair(Prefix, Regex(pat))); RegexList.push_back(std::make_pair(Prefix, Regex(pat)));
} }
for (auto &R : RegexList) { for (auto &R : RegexList) {
unsigned NumGeneric = Target.getNumFixedInstructions();
// The generic opcodes are unsorted, handle them manually. // The generic opcodes are unsorted, handle them manually.
for (auto *Inst : Target.getInstructionsByEnumValue().slice( for (auto *Inst :
0, TargetOpcode::GENERIC_OP_END + 1)) { Target.getInstructionsByEnumValue().slice(0, NumGeneric + 1)) {
if (Inst->TheDef->getName().startswith(R.first) && if (Inst->TheDef->getName().startswith(R.first) &&
(!R.second || (!R.second ||
R.second->match(Inst->TheDef->getName().substr(R.first.size())))) R.second->match(Inst->TheDef->getName().substr(R.first.size()))))
@ -114,8 +114,7 @@ struct InstRegexOp : public SetTheory::Operator {
} }
ArrayRef<const CodeGenInstruction *> Instructions = ArrayRef<const CodeGenInstruction *> Instructions =
Target.getInstructionsByEnumValue().slice( Target.getInstructionsByEnumValue().slice(NumGeneric + 1);
TargetOpcode::GENERIC_OP_END + 1);
// Target instructions are sorted. Find the range that starts with our // Target instructions are sorted. Find the range that starts with our
// prefix. // prefix.

View File

@ -345,13 +345,18 @@ GetInstByName(const char *Name,
return I->second.get(); return I->second.get();
} }
static const char *const FixedInstrs[] = {
#define HANDLE_TARGET_OPCODE(OPC) #OPC,
#include "llvm/CodeGen/TargetOpcodes.def"
nullptr};
unsigned CodeGenTarget::getNumFixedInstructions() {
return array_lengthof(FixedInstrs) - 1;
}
/// \brief Return all of the instructions defined by the target, ordered by /// \brief Return all of the instructions defined by the target, ordered by
/// their enum value. /// their enum value.
void CodeGenTarget::ComputeInstrsByEnum() const { void CodeGenTarget::ComputeInstrsByEnum() const {
static const char *const FixedInstrs[] = {
#define HANDLE_TARGET_OPCODE(OPC) #OPC,
#include "llvm/CodeGen/TargetOpcodes.def"
nullptr};
const auto &Insts = getInstructions(); const auto &Insts = getInstructions();
for (const char *const *p = FixedInstrs; *p; ++p) { for (const char *const *p = FixedInstrs; *p; ++p) {
const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records); const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
@ -360,6 +365,8 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
InstrsByEnum.push_back(Instr); InstrsByEnum.push_back(Instr);
} }
unsigned EndOfPredefines = InstrsByEnum.size(); unsigned EndOfPredefines = InstrsByEnum.size();
assert(EndOfPredefines == getNumFixedInstructions() &&
"Missing generic opcode");
for (const auto &I : Insts) { for (const auto &I : Insts) {
const CodeGenInstruction *CGI = I.second.get(); const CodeGenInstruction *CGI = I.second.get();

View File

@ -140,6 +140,9 @@ public:
return *I->second; return *I->second;
} }
/// Returns the number of predefined instructions.
static unsigned getNumFixedInstructions();
/// getInstructionsByEnumValue - Return all of the instructions defined by the /// getInstructionsByEnumValue - Return all of the instructions defined by the
/// target, ordered by their enum value. /// target, ordered by their enum value.
ArrayRef<const CodeGenInstruction *> ArrayRef<const CodeGenInstruction *>