[llvm] [GlobalISel] Add iterative known-bits evaluation to GISelValueTracking (PR #221755)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 07:15:25 PDT 2026
================
@@ -1138,6 +1138,78 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
LLVM_DEBUG(dumpResult(MI, Known, Depth));
}
+static void genUnknown(MachineRegisterInfo &MRI, const Register &Reg,
+ KnownBits &Known) {
+ LLT Ty = MRI.getType(Reg);
+ if (!Ty.isValid()) {
+ Known = KnownBits();
+ return;
+ }
+ unsigned BitWidth = Ty.getScalarSizeInBits();
+ Known = KnownBits(BitWidth);
+}
+
+/// Evaluate a known-bits query with an explicit worklist instead of recursive
+/// descent.
+void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
+ const APInt &DemandedElts,
+ unsigned Depth) {
+ const bool TopLevel = Stack.empty();
+
+ // Nested queries only consult the per-query cache. If the result is not
+ // available yet, enqueue the request and return an unknown placeholder.
+ if (!TopLevel) {
+ if (!getKnownBitsResult(R, DemandedElts, Depth, Known)) {
+ Stack.push_back({R, DemandedElts, Depth});
+ genUnknown(MRI, R, Known);
+ }
+ return;
+ }
+
+ // Top-level queries drive evaluation iteratively until every queued item has
+ // either been computed or found in the cache.
+ Stack.push_back({R, DemandedElts, Depth});
+ while (!Stack.empty()) {
+ WorkItem Item = Stack.back();
+ size_t StackSize = Stack.size();
+ const Register &ItemReg = std::get<0>(Item);
+ const APInt &ItemDemandedElts = std::get<1>(Item);
+ const unsigned ItemDepth = std::get<2>(Item);
+ KnownBits ItemKnown;
+
+ if (getKnownBitsResult(ItemReg, ItemDemandedElts, ItemDepth, ItemKnown)) {
+ Stack.pop_back();
+ continue;
+ }
+
+ // Evaluate this item with the per-instruction known-bits logic. Dependent
+ // queries issued from there re-enter this worklist driver and take the
+ // `!TopLevel` path to enqueue more work.
+ computeKnownBits(ItemReg, ItemKnown, ItemDemandedElts, ItemDepth);
+
+ // If evaluating this item did not queue more work, its dependencies are
+ // resolved and the result can be memoized immediately.
+ if (Stack.size() == StackSize) {
+ assert((std::get<0>(Stack.back()) == ItemReg &&
+ std::get<1>(Stack.back()) == ItemDemandedElts &&
+ std::get<2>(Stack.back()) == ItemDepth) &&
+ "The item we just evaluated must still be the top one.");
+
+ setKnownBitsResult(ItemReg, ItemDemandedElts, ItemDepth, ItemKnown);
+ Stack.pop_back();
+ }
+ }
+
+ // The original query must have been computed by the time the worklist is
+ // drained.
+ [[maybe_unused]] bool Found =
+ getKnownBitsResult(R, DemandedElts, Depth, Known);
+ assert(Found &&
+ "Top level query must be in `results` after iteration is complete.");
----------------
daemonpilot wrote:
Yes, refined.
https://github.com/llvm/llvm-project/pull/221755
More information about the llvm-commits
mailing list