Revision 146c2bab4fd9fb0c3ea6af47fe08c796a6407949 authored by Keno Fischer on 16 January 2018, 18:56:21 UTC, committed by Keno Fischer on 16 January 2018, 19:07:03 UTC
Consider the following example: ``` f() = (1, 1) f(s) = i == 1 ? (1, 2) : nothing function foo() next = f() while next !== nothing next = f(Core.getfield(next, 2)) end end ``` This was causing unnecessary allocations, because inference failed to inform codegen that the reference to next inside the loop was guaranteed not to be Nothing. Ironically if f() could also have returned nothing, inference was able to figure this out, thanks to pass the result of the comparison was inferred as Const(true), and on the second pass as Conditional(next, Tuple{Int, Int}, Const(nothing)), the tmerge of which is Bool. Fix that by implementing Jameson's suggestion in #25261, and instead infering the first pass as Conditional(next, Tuple{Int, Int}, Union{}). To make this work we also adjust the lattice relation to have Conditional(next, T, Union{}) ⊑ Const(true). The result is that the result of the comparison does not get widened to Bool as quickly, retaining the type information on next and allowing codegen to emit efficient code.
1 parent aea9155
File | Mode | Size |
---|---|---|
.circleci | ||
.github | ||
base | ||
contrib | ||
deps | ||
doc | ||
etc | ||
examples | ||
src | ||
stdlib | ||
test | ||
ui | ||
.gitignore | -rw-r--r-- | 213 bytes |
.mailmap | -rw-r--r-- | 9.5 KB |
.travis.yml | -rw-r--r-- | 6.5 KB |
CONTRIBUTING.md | -rw-r--r-- | 20.4 KB |
DISTRIBUTING.md | -rw-r--r-- | 23.6 KB |
HISTORY.md | -rw-r--r-- | 144.9 KB |
LICENSE.md | -rw-r--r-- | 5.5 KB |
Make.inc | -rw-r--r-- | 35.2 KB |
Makefile | -rw-r--r-- | 26.4 KB |
NEWS.md | -rw-r--r-- | 62.9 KB |
README.arm.md | -rw-r--r-- | 5.7 KB |
README.md | -rw-r--r-- | 28.1 KB |
README.windows.md | -rw-r--r-- | 13.0 KB |
VERSION | -rw-r--r-- | 10 bytes |
Windows.inc | -rw-r--r-- | 1.5 KB |
appveyor.yml | -rw-r--r-- | 2.2 KB |
Computing file changes ...