Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang][dataflow] Drop block-relative cap on worklist iterations. #80033

Merged
merged 1 commit into from
Jan 30, 2024

Conversation

ymand
Copy link
Collaborator

@ymand ymand commented Jan 30, 2024

As per the FIXME, this cap never really served its purpose. This patch
simplifies to a single, caller-specified, absolute cap.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:dataflow Clang Dataflow Analysis framework - https://clang.llvm.org/docs/DataFlowAnalysisIntro.html clang:analysis labels Jan 30, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 30, 2024

@llvm/pr-subscribers-clang-analysis

@llvm/pr-subscribers-clang

Author: Yitzhak Mandelbaum (ymand)

Changes

As per the FIXME, this cap never really served its purpose. This patch
simplifies to a single, caller-specified, absolute cap.


Full diff: https://github.com/llvm/llvm-project/pull/80033.diff

1 Files Affected:

  • (modified) clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp (-8)
diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index 49e425bde66aa..4c88c46142d64 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -540,14 +540,6 @@ runTypeErasedDataflowAnalysis(
   Worklist.enqueueSuccessors(&Entry);
 
   AnalysisContext AC(CFCtx, Analysis, StartingEnv, BlockStates);
-
-  // FIXME: remove relative cap. There isn't really any good setting for
-  // `MaxAverageVisitsPerBlock`, so it has no clear value over using
-  // `MaxBlockVisits` directly.
-  static constexpr std::int32_t MaxAverageVisitsPerBlock = 4;
-  const std::int32_t RelativeMaxBlockVisits =
-      MaxAverageVisitsPerBlock * BlockStates.size();
-  MaxBlockVisits = std::min(RelativeMaxBlockVisits, MaxBlockVisits);
   std::int32_t BlockVisits = 0;
   while (const CFGBlock *Block = Worklist.dequeue()) {
     LLVM_DEBUG(llvm::dbgs()

As per the FIXME, this cap never really served its purpose. This patch
simplifies to a single, caller-specified, absolute cap.
@ymand ymand merged commit a385c37 into llvm:main Jan 30, 2024
3 of 4 checks passed
@ymand ymand deleted the drop-block-cap branch January 30, 2024 21:05
copybara-service bot pushed a commit to google/crubit that referenced this pull request Jan 31, 2024
This expands to three nested for loops and led to "max blocks visited" errors
when ymand@ initially tried to change the order in which block successors are
visited in the dataflow framework
([#80030](llvm/llvm-project#80030)).

We now no longer see these "max blocks visited" errors with this test because
of
[other](3dfd35e)
[fixes](llvm/llvm-project#80033) that have landed in the
meantime. Nevertheless, it seems worthwhile to put this test in place to prevent
regressions.

PiperOrigin-RevId: 603020024
Change-Id: I7a8428a77a2f4252d012eec30e42ccb0c1b96bc5
copybara-service bot pushed a commit to google/crubit that referenced this pull request Jan 31, 2024
Our intent is to signal "perform the default behavior", i.e. keep the
`MergedVal` that has been produced by the framework. This would be done by
returning true (which is also what the [default
implementation](https://github.com/llvm/llvm-project/blob/d5c9d402f07e7448cd46870a59d981f582682548/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h#L105)
does).

However, we were returning false, which means that the framework should drop
the `MergedVal` and remove the corresponding entry from `LocToVal`.

This was initially causing "max blocks visited" errors on the
`TriplyNestedForLoopSingleIteration` test when ymand@ tried to
change the order in which the dataflow framework visits block successors
([#80030](llvm/llvm-project#80030)).

We now no longer see these errors because of
[other](3dfd35e)
[fixes](llvm/llvm-project#80033) that have landed in the
meantime. Nevertheless, it seems worthwhile to fix `merge()`, as this reduces
the number of block visits required to achieve convergence. On the
`TriplyNestedForLoopSingleIteration` test, we require 66 block visits before
this patch, and 53 block visits after.

The issue was that when performing the join at the loop head, our custom merge
logic was causing the merged value for the variable `int c` to be discarded from
`LocToVal`. This in turn was blocking convergence because widening
[considers](https://github.com/llvm/llvm-project/blob/d5c9d402f07e7448cd46870a59d981f582682548/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp#L626)
two environments to be different if the sizes of their `LocToVal` maps differ.

As an aside, widening is inconsistent in this respect with the convergence check
that we perform on blocks that don't get widened.
[`Environment::equivalentTo()`](https://github.com/llvm/llvm-project/blob/d5c9d402f07e7448cd46870a59d981f582682548/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp#L570),
which performs this check, uses `compareKeyToValueMaps()` to compare the
`LocToVal` maps of the two environments, and `compareKeyToValueMaps()` only
compares values for locations that are in both `LocToVal` maps and ignores
locations that only occur in one of the maps. We should probably fix this
inconsistency.

PiperOrigin-RevId: 603025629
Change-Id: Id02993e576023c44a335c8991020f7e233a75320
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:analysis clang:dataflow Clang Dataflow Analysis framework - https://clang.llvm.org/docs/DataFlowAnalysisIntro.html clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants