diff options
author | Rahul Joshi <rjoshi@nvidia.com> | 2025-07-02 12:49:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-02 12:49:27 -0700 |
commit | a880c8e670befc20dfb6e0789e8dfb93aa06173c (patch) | |
tree | 8ccecf33380c6bdbad07a055845a90e057c7cb72 /llvm | |
parent | d457621872528d27c8081cf147d41a6f46276d1d (diff) | |
download | llvm-a880c8e670befc20dfb6e0789e8dfb93aa06173c.zip llvm-a880c8e670befc20dfb6e0789e8dfb93aa06173c.tar.gz llvm-a880c8e670befc20dfb6e0789e8dfb93aa06173c.tar.bz2 |
[NFC][TableGen] Add accessors for various instruction subclasses (#146615)
- Add various instruction subclass/sub-slice accessors to
`CodeGenTarget`.
- Delete unused `inst_begin` and `inst_end` iterators.
- Rename `Instructions` to `InstructionMap` and `getInstructions` to
`getInstructionMap` to better represent their meaning.
- Use these new accessors in InstrInfoEmitter
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/utils/TableGen/Common/CodeGenSchedule.cpp | 16 | ||||
-rw-r--r-- | llvm/utils/TableGen/Common/CodeGenTarget.cpp | 26 | ||||
-rw-r--r-- | llvm/utils/TableGen/Common/CodeGenTarget.h | 48 | ||||
-rw-r--r-- | llvm/utils/TableGen/InstrInfoEmitter.cpp | 29 |
4 files changed, 63 insertions, 56 deletions
diff --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp index a93b5be..35c1ffb 100644 --- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp @@ -77,14 +77,12 @@ struct InstRegexOp : public SetTheory::Operator { void apply(SetTheory &ST, const DagInit *Expr, SetTheory::RecSet &Elts, ArrayRef<SMLoc> Loc) override { - ArrayRef<const CodeGenInstruction *> Instructions = - Target.getInstructionsByEnumValue(); - - unsigned NumGeneric = Target.getNumFixedInstructions(); - unsigned NumPseudos = Target.getNumPseudoInstructions(); - auto Generics = Instructions.slice(0, NumGeneric); - auto Pseudos = Instructions.slice(NumGeneric, NumPseudos); - auto NonPseudos = Instructions.slice(NumGeneric + NumPseudos); + ArrayRef<const CodeGenInstruction *> Generics = + Target.getGenericInstructionsByEnumValue(); + ArrayRef<const CodeGenInstruction *> Pseudos = + Target.getTargetPseudoInstructionsByEnumValue(); + ArrayRef<const CodeGenInstruction *> NonPseudos = + Target.getTargetNonPseudoInstructionsByEnumValue(); for (const Init *Arg : Expr->getArgs()) { const StringInit *SI = dyn_cast<StringInit>(Arg); @@ -145,7 +143,7 @@ struct InstRegexOp : public SetTheory::Operator { } // Target instructions are split into two ranges: pseudo instructions - // first, than non-pseudos. Each range is in lexicographical order + // first, then non-pseudos. Each range is in lexicographical order // sorted by name. Find the sub-ranges that start with our prefix. struct Comp { bool operator()(const CodeGenInstruction *LHS, StringRef RHS) { diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.cpp b/llvm/utils/TableGen/Common/CodeGenTarget.cpp index f519582..f8da985 100644 --- a/llvm/utils/TableGen/Common/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/Common/CodeGenTarget.cpp @@ -211,10 +211,9 @@ void CodeGenTarget::ReadInstructions() const { // Parse the instructions defined in the .td file. for (const Record *R : Insts) { - auto &Inst = Instructions[R]; - Inst = std::make_unique<CodeGenInstruction>(R); - if (Inst->isVariableLengthEncoding()) - HasVariableLengthEncodings = true; + auto [II, _] = + InstructionMap.try_emplace(R, std::make_unique<CodeGenInstruction>(R)); + HasVariableLengthEncodings |= II->second->isVariableLengthEncoding(); } } @@ -242,9 +241,9 @@ unsigned CodeGenTarget::getNumFixedInstructions() { /// Return all of the instructions defined by the target, ordered by /// their enum value. void CodeGenTarget::ComputeInstrsByEnum() const { - const auto &Insts = getInstructions(); + const auto &InstMap = getInstructionMap(); for (const char *Name : FixedInstrs) { - const CodeGenInstruction *Instr = GetInstByName(Name, Insts, Records); + const CodeGenInstruction *Instr = GetInstByName(Name, InstMap, Records); assert(Instr && "Missing target independent instruction"); assert(Instr->Namespace == "TargetOpcode" && "Bad namespace"); InstrsByEnum.push_back(Instr); @@ -253,23 +252,24 @@ void CodeGenTarget::ComputeInstrsByEnum() const { assert(EndOfPredefines == getNumFixedInstructions() && "Missing generic opcode"); - for (const auto &I : Insts) { - const CodeGenInstruction *CGI = I.second.get(); + for (const auto &[_, CGIUp] : InstMap) { + const CodeGenInstruction *CGI = CGIUp.get(); if (CGI->Namespace != "TargetOpcode") { InstrsByEnum.push_back(CGI); - if (CGI->TheDef->getValueAsBit("isPseudo")) - ++NumPseudoInstructions; + NumPseudoInstructions += CGI->TheDef->getValueAsBit("isPseudo"); } } - assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr"); + assert(InstrsByEnum.size() == InstMap.size() && "Missing predefined instr"); // All of the instructions are now in random order based on the map iteration. llvm::sort( InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(), [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) { - const auto &D1 = *Rec1->TheDef; - const auto &D2 = *Rec2->TheDef; + const Record &D1 = *Rec1->TheDef; + const Record &D2 = *Rec2->TheDef; + // Sort all pseudo instructions before non-pseudo ones, and sort by name + // within. return std::tuple(!D1.getValueAsBit("isPseudo"), D1.getName()) < std::tuple(!D2.getValueAsBit("isPseudo"), D2.getName()); }); diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.h b/llvm/utils/TableGen/Common/CodeGenTarget.h index 52871f3..191647c 100644 --- a/llvm/utils/TableGen/Common/CodeGenTarget.h +++ b/llvm/utils/TableGen/Common/CodeGenTarget.h @@ -59,7 +59,7 @@ class CodeGenTarget { const Record *TargetRec; mutable DenseMap<const Record *, std::unique_ptr<CodeGenInstruction>> - Instructions; + InstructionMap; mutable std::unique_ptr<CodeGenRegBank> RegBank; mutable ArrayRef<const Record *> RegAltNameIndices; mutable SmallVector<ValueTypeByHwMode, 8> LegalValueTypes; @@ -154,31 +154,22 @@ public: private: DenseMap<const Record *, std::unique_ptr<CodeGenInstruction>> & - getInstructions() const { - if (Instructions.empty()) + getInstructionMap() const { + if (InstructionMap.empty()) ReadInstructions(); - return Instructions; + return InstructionMap; } public: CodeGenInstruction &getInstruction(const Record *InstRec) const { - if (Instructions.empty()) - ReadInstructions(); - auto I = Instructions.find(InstRec); - assert(I != Instructions.end() && "Not an instruction"); + auto I = getInstructionMap().find(InstRec); + assert(I != InstructionMap.end() && "Not an instruction"); return *I->second; } /// Returns the number of predefined instructions. static unsigned getNumFixedInstructions(); - /// Returns the number of pseudo instructions. - unsigned getNumPseudoInstructions() const { - if (InstrsByEnum.empty()) - ComputeInstrsByEnum(); - return NumPseudoInstructions; - } - /// Return all of the instructions defined by the target, ordered by their /// enum value. /// The following order of instructions is also guaranteed: @@ -191,6 +182,27 @@ public: return InstrsByEnum; } + // Functions that return various slices of `getInstructionsByEnumValue`. + ArrayRef<const CodeGenInstruction *> + getGenericInstructionsByEnumValue() const { + return getInstructionsByEnumValue().take_front(getNumFixedInstructions()); + } + + ArrayRef<const CodeGenInstruction *> + getTargetInstructionsByEnumValue() const { + return getInstructionsByEnumValue().drop_front(getNumFixedInstructions()); + } + + ArrayRef<const CodeGenInstruction *> + getTargetPseudoInstructionsByEnumValue() const { + return getTargetInstructionsByEnumValue().take_front(NumPseudoInstructions); + } + + ArrayRef<const CodeGenInstruction *> + getTargetNonPseudoInstructionsByEnumValue() const { + return getTargetInstructionsByEnumValue().drop_front(NumPseudoInstructions); + } + /// Return the integer enum value corresponding to this instruction record. unsigned getInstrIntValue(const Record *R) const { if (InstrsByEnum.empty()) @@ -198,12 +210,6 @@ public: return getInstruction(R).EnumVal; } - typedef ArrayRef<const CodeGenInstruction *>::const_iterator inst_iterator; - inst_iterator inst_begin() const { - return getInstructionsByEnumValue().begin(); - } - inst_iterator inst_end() const { return getInstructionsByEnumValue().end(); } - /// Return whether instructions have variable length encodings on this target. bool hasVariableLengthEncodings() const { return HasVariableLengthEncodings; } diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index e72055b..d5b6692 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -91,10 +91,10 @@ private: ArrayRef<const CodeGenInstruction *> NumberedInstructions); void emitOperandNameMappings( raw_ostream &OS, const CodeGenTarget &Target, - ArrayRef<const CodeGenInstruction *> NumberedInstructions); + ArrayRef<const CodeGenInstruction *> TargetInstructions); void emitLogicalOperandSizeMappings( raw_ostream &OS, StringRef Namespace, - ArrayRef<const CodeGenInstruction *> NumberedInstructions); + ArrayRef<const CodeGenInstruction *> TargetInstructions); // Operand information. unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList, @@ -234,9 +234,12 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, /// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) /// for looking up the operand index for an instruction, given a value from /// OpName enum +/// +/// Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so +/// we can just skip them. Hence accept just the TargetInstructions. void InstrInfoEmitter::emitOperandNameMappings( raw_ostream &OS, const CodeGenTarget &Target, - ArrayRef<const CodeGenInstruction *> NumberedInstructions) { + ArrayRef<const CodeGenInstruction *> TargetInstructions) { StringRef Namespace = Target.getInstNamespace(); /// To facilitate assigning OpName enum values in the sorted alphabetical @@ -260,9 +263,7 @@ void InstrInfoEmitter::emitOperandNameMappings( // Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so // we can just skip them. - const unsigned NumFixedInsts = Target.getNumFixedInstructions(); - for (const CodeGenInstruction *Inst : - NumberedInstructions.drop_front(NumFixedInsts)) { + for (const CodeGenInstruction *Inst : TargetInstructions) { if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) continue; std::map<unsigned, unsigned> OpList; @@ -476,19 +477,18 @@ void InstrInfoEmitter::emitOperandTypeMappings( OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n"; } +// Fixed/Predefined instructions do not have UseLogicalOperandMappings +// enabled, so we can just skip them. Hence accept TargetInstructions. void InstrInfoEmitter::emitLogicalOperandSizeMappings( raw_ostream &OS, StringRef Namespace, - ArrayRef<const CodeGenInstruction *> NumberedInstructions) { + ArrayRef<const CodeGenInstruction *> TargetInstructions) { std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap; std::map<unsigned, std::vector<std::string>> InstMap; size_t LogicalOpListSize = 0U; std::vector<unsigned> LogicalOpList; - // Fixed/Predefined instructions do not have UseLogicalOperandMappings - // enabled, so we can just skip them. - const unsigned NumFixedInsts = CDP.getTargetInfo().getNumFixedInstructions(); - for (const auto *Inst : NumberedInstructions.drop_front(NumFixedInsts)) { + for (const auto *Inst : TargetInstructions) { if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings")) continue; @@ -1057,9 +1057,12 @@ void InstrInfoEmitter::run(raw_ostream &OS) { OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; + ArrayRef<const CodeGenInstruction *> TargetInstructions = + Target.getTargetInstructionsByEnumValue(); + if (HasUseNamedOperandTable) { Timer.startTimer("Emit operand name mappings"); - emitOperandNameMappings(OS, Target, NumberedInstructions); + emitOperandNameMappings(OS, Target, TargetInstructions); } Timer.startTimer("Emit operand type mappings"); @@ -1067,7 +1070,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) { if (HasUseLogicalOperandMappings) { Timer.startTimer("Emit logical operand size mappings"); - emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions); + emitLogicalOperandSizeMappings(OS, TargetName, TargetInstructions); } Timer.startTimer("Emit helper methods"); |