[llvm] [TableGen] Use bitwise operations to access HwMode ID. (PR #88377)
Jason Eckhardt via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 17 20:43:51 PDT 2024
================
@@ -1781,13 +1781,68 @@ void SubtargetEmitter::EmitHwModeCheck(const std::string &ClassName,
if (CGH.getNumModeIds() == 1)
return;
- OS << "unsigned " << ClassName << "::getHwMode() const {\n";
+ // Collect all HwModes and related features defined in the TD files,
+ // and store them in bit format.
+ unsigned ValueTypeModes = 0;
+ unsigned RegInfoModes = 0;
+ unsigned EncodingInfoModes = 0;
+ for (const auto &MS : CGH.getHwModeSelects()) {
+ for (const HwModeSelect::PairType &P : MS.second.Items) {
+ if (P.first == DefaultMode)
+ continue;
+ if (P.second->isSubClassOf("ValueType")) {
+ ValueTypeModes |= (1 << (P.first - 1));
+ } else if (P.second->isSubClassOf("RegInfo") ||
+ P.second->isSubClassOf("SubRegRange")) {
+ RegInfoModes |= (1 << (P.first - 1));
+ } else if (P.second->isSubClassOf("InstructionEncoding")) {
+ EncodingInfoModes |= (1 << (P.first - 1));
+ }
+ }
+ }
+
+ // Start emitting for getHwModeSet().
+ OS << "unsigned " << ClassName << "::getHwModeSet() const {\n";
+ OS << " // Collect HwModes and store them in bits\n";
+ OS << " unsigned Modes = 0;\n";
for (unsigned M = 1, NumModes = CGH.getNumModeIds(); M != NumModes; ++M) {
const HwMode &HM = CGH.getMode(M);
- OS << " if (checkFeatures(\"" << HM.Features << "\")) return " << M
- << ";\n";
+ OS << " if (checkFeatures(\"" << HM.Features << "\")) Modes |= (1 << "
+ << (M - 1) << ");\n";
}
- OS << " return 0;\n}\n";
+ OS << " return Modes;\n}\n";
+ // End emitting for getHwModeSet().
+
+ // Start emitting for getHwMode().
+ OS << "unsigned " << ClassName
+ << "::getHwMode(enum HwModeType type) const {\n";
+ OS << " unsigned Modes = getHwModeSet();\n";
+ OS << "\n if(!Modes)\n return Modes;\n\n";
+ OS << " switch (type) {\n";
+ OS << " case HwMode_Default:\n return llvm::countr_zero(Modes) + 1;\n"
+ << " break;\n";
+ OS << " case HwMode_ValueType: {\n Modes &= " << ValueTypeModes << ";\n"
+ << " if (!Modes)\n return Modes;\n"
+ << " if (!llvm::has_single_bit<unsigned>(Modes))\n"
+ << " llvm_unreachable(\"Two or more HwModes for ValueType were "
+ "found!\");\n"
+ << " return llvm::countr_zero(Modes) + 1;\n }\n";
+ OS << " case HwMode_RegInfo: {\n Modes &= " << RegInfoModes << ";\n"
+ << " if (!Modes)\n return Modes;\n"
+ << " if (!llvm::has_single_bit<unsigned>(Modes))\n"
+ << " llvm_unreachable(\"Two or more HwModes for RegInfo were "
+ "found!\");\n"
+ << " return llvm::countr_zero(Modes) + 1;\n }\n";
+ OS << " case HwMode_EncodingInfo: {\n Modes &= " << EncodingInfoModes
+ << ";\n"
+ << " if (!Modes)\n return Modes;\n"
+ << " if (!llvm::has_single_bit<unsigned>(Modes))\n"
+ << " llvm_unreachable(\"Two or more HwModes for Encoding were "
+ "found!\");\n"
+ << " return llvm::countr_zero(Modes) + 1;\n }\n";
----------------
nvjle wrote:
All three of the non-Default cases are essentially identical other than the mask value. We should collapse this into ~1/3 the code.
https://github.com/llvm/llvm-project/pull/88377
More information about the llvm-commits
mailing list