[llvm] [TableGen][DecoderEmitter] Add extractBits() overloads (PR #159405)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 17 10:15:06 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-mc
Author: Sergei Barannikov (s-barannikov)
<details>
<summary>Changes</summary>
These differ from `fieldFromInstruction()` in that StartBit and NumBits are the template parameters.
Using them in the generated code significantly speeds up compilation in release builds (up to 4 times faster, depending on the used compiler).
---
Full diff: https://github.com/llvm/llvm-project/pull/159405.diff
2 Files Affected:
- (modified) llvm/include/llvm/MC/MCDecoder.h (+18)
- (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+3-4)
``````````diff
diff --git a/llvm/include/llvm/MC/MCDecoder.h b/llvm/include/llvm/MC/MCDecoder.h
index 175f6a9591558..770941da5f31c 100644
--- a/llvm/include/llvm/MC/MCDecoder.h
+++ b/llvm/include/llvm/MC/MCDecoder.h
@@ -58,6 +58,24 @@ uint64_t fieldFromInstruction(const std::bitset<N> &Insn, unsigned StartBit,
return ((Insn >> StartBit) & Mask).to_ullong();
}
+template <unsigned StartBit, unsigned NumBits, typename T>
+inline std::enable_if_t<std::is_unsigned_v<T>, T> extractBits(T Val) {
+ static_assert(StartBit + NumBits <= std::numeric_limits<T>::digits);
+ return (Val >> StartBit) & maskTrailingOnes<T>(NumBits);
+}
+
+template <unsigned StartBit, unsigned NumBits, size_t N>
+uint64_t extractBits(const std::bitset<N> &Val) {
+ static_assert(StartBit + NumBits <= N);
+ std::bitset<N> Mask = maskTrailingOnes<uint64_t>(NumBits);
+ return ((Val >> StartBit) & Mask).to_ullong();
+}
+
+template <unsigned StartBit, unsigned NumBits>
+uint64_t extractBits(const APInt &Val) {
+ return Val.extractBitsAsZExtValue(NumBits, StartBit);
+}
+
} // namespace llvm::MCD
#endif // LLVM_MC_MCDECODER_H
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 3a464e01042dc..5a087eefaaf8d 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -1031,8 +1031,7 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent,
// One variable part and no/zero constant part. Initialize `tmp` with the
// variable part.
auto [Base, Width, Offset] = OpInfo.fields().front();
- OS << Indent << "tmp = fieldFromInstruction(insn, " << Base << ", " << Width
- << ')';
+ OS << Indent << "tmp = extractBits<" << Base << ", " << Width << ">(insn)";
if (Offset)
OS << " << " << Offset;
OS << ";\n";
@@ -1042,8 +1041,8 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent,
OS << Indent << "tmp = " << format_hex(OpInfo.InitValue.value_or(0), 0)
<< ";\n";
for (auto [Base, Width, Offset] : OpInfo.fields()) {
- OS << Indent << "tmp |= fieldFromInstruction(insn, " << Base << ", "
- << Width << ')';
+ OS << Indent << "tmp |= extractBits<" << Base << ", " << Width
+ << ">(insn)";
if (Offset)
OS << " << " << Offset;
OS << ";\n";
``````````
</details>
https://github.com/llvm/llvm-project/pull/159405
More information about the llvm-commits
mailing list