Skip to content

Commit 200d770

Browse files
committed
concrete-eval: Use concrete eval information even if the result is too large
When we originally implemented concrete-eval, we decided not to create `Const` lattice elements for constants that are too large, on the fear that these would end up in the IR and blowing up the size. Now that we have some experience with this, I think that decision was incorrect for several reasons: 1. We've already performed the concrete evaluation (and allocated the big object), so we're just throwing away precision here that we could have otherwise used (Although if the call result is unused, we probably shouldn't do concrete eval at all - see #46774). 2. There's a number of other places in the compiler where we read large values into `Const`. Unless we add these kinds of check there too, we need to have appropriate guards in the optimizer and the cache anyway, to prevent the IR size blowup. 3. It turns out that throwing away this precision actually causes significant performance problems for code that is just over the line. Consider for example a lookup of a small struct inside a large, multi-level constant structure. The final result might be quite tiny, but if we refuse to propagate the intermediate levels, we might end up doing an (expensive) full-constprop when propagating the constant information could have given us a much cheaper concrete evaluation. This commit simply removes that check. If we see any regressions as a result of this, we should see if there are additional guards needed in the optimizer.
1 parent ca3cd8b commit 200d770

File tree

1 file changed

+1
-7
lines changed

1 file changed

+1
-7
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -841,13 +841,7 @@ function concrete_eval_call(interp::AbstractInterpreter,
841841
# The evaluation threw. By :consistent-cy, we're guaranteed this would have happened at runtime
842842
return ConstCallResults(Union{}, ConcreteResult(edge, result.effects), result.effects, edge)
843843
end
844-
if is_inlineable_constant(value) || call_result_unused(si)
845-
# If the constant is not inlineable, still do the const-prop, since the
846-
# code that led to the creation of the Const may be inlineable in the same
847-
# circumstance and may be optimizable.
848-
return ConstCallResults(Const(value), ConcreteResult(edge, EFFECTS_TOTAL, value), EFFECTS_TOTAL, edge)
849-
end
850-
return false
844+
return ConstCallResults(Const(value), ConcreteResult(edge, EFFECTS_TOTAL, value), EFFECTS_TOTAL, edge)
851845
else # eligible for semi-concrete evaluation
852846
return true
853847
end

0 commit comments

Comments
 (0)