• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37606

31 Aug 2023 03:12AM UTC coverage: 86.167% (-0.03%) from 86.2%
#37606

push

local

web-flow
Refine effects based on optimizer-derived information (#50805)

The optimizer may be able to derive information that is not available to
inference. For example, it may SROA a mutable value to derive additional
constant information. Additionally, some effects, like :consistent are
path-dependent and should ideally be scanned once all optimizations are
done. Now, there is a bit of a complication that we have generally so
far taken the position that the optimizer may do non-IPO-safe
optimizations, although in practice we never actually implemented any.
This was a sensible choice, because we weren't really doing anything
with the post-optimized IR other than feeding it into codegen anyway.
However, with irinterp and this change, there's now two consumers of
IPO-safely optimized IR. I do still think we may at some point want to
run passes that allow IPO-unsafe optimizations, but we can always add
them at the end of the pipeline.

With these changes, the effect analysis is a lot more precise. For
example, we can now derive :consistent for these functions:
```
function f1(b)
    if Base.inferencebarrier(b)
        error()
    end
    return b
end

function f3(x)
    @fastmath sqrt(x)
    return x
end
```
and we can derive `:nothrow` for this function:
```
function f2()
    if Ref(false)[]
        error()
    end
    return true
end
```

414 of 414 new or added lines in 13 files covered. (100.0%)

73383 of 85164 relevant lines covered (86.17%)

12690106.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.03
/stdlib/Dates/src/arithmetic.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
# Instant arithmetic
4
(+)(x::Instant) = x
×
5
(-)(x::T, y::T) where {T<:Instant} = x.periods - y.periods
988,306✔
6

7
# TimeType arithmetic
8
(+)(x::TimeType) = x
×
9
(-)(x::T, y::T) where {T<:TimeType} = x.instant - y.instant
1,025,306✔
10
(-)(x::TimeType, y::TimeType) = -(promote(x, y)...)
×
11

12
# Date-Time arithmetic
13
"""
14
    dt::Date + t::Time -> DateTime
15

16
The addition of a `Date` with a `Time` produces a `DateTime`. The hour, minute, second, and millisecond parts of
17
the `Time` are used along with the year, month, and day of the `Date` to create the new `DateTime`.
18
Non-zero microseconds or nanoseconds in the `Time` type will result in an `InexactError` being thrown.
19
"""
20
(+)(dt::Date, t::Time) = DateTime(dt ,t)
×
21
(+)(t::Time, dt::Date) = DateTime(dt, t)
×
22

23
# TimeType-Year arithmetic
24
function (+)(dt::DateTime, y::Year)
169,599✔
25
    oy, m, d = yearmonthday(dt); ny = oy + value(y); ld = daysinmonth(ny, m)
508,797✔
26
    return DateTime(ny, m, d <= ld ? d : ld, hour(dt), minute(dt), second(dt), millisecond(dt))
169,599✔
27
end
28
function (+)(dt::Date,y::Year)
919,738✔
29
    oy, m, d = yearmonthday(dt); ny = oy + value(y); ld = daysinmonth(ny, m)
2,759,214✔
30
    return Date(ny, m, d <= ld ? d : ld)
919,738✔
31
end
32
function (-)(dt::DateTime,y::Year)
10✔
33
    oy, m, d = yearmonthday(dt); ny = oy - value(y); ld = daysinmonth(ny, m)
30✔
34
    return DateTime(ny, m, d <= ld ? d : ld, hour(dt), minute(dt), second(dt), millisecond(dt))
10✔
35
end
36
function (-)(dt::Date,y::Year)
10✔
37
    oy, m, d = yearmonthday(dt); ny = oy - value(y); ld = daysinmonth(ny, m)
30✔
38
    return Date(ny, m, d <= ld ? d : ld)
10✔
39
end
40

41
# TimeType-Month arithmetic
42
# monthwrap adds two months with wraparound behavior (i.e. 12 + 1 == 1)
43
monthwrap(m1, m2) = (v = mod1(m1 + m2, 12); return v < 0 ? 12 + v : v)
3,862,216✔
44
# yearwrap takes a starting year/month and a month to add and returns
45
# the resulting year with wraparound behavior (i.e. 2000-12 + 1 == 2001)
46
yearwrap(y, m1, m2) = y + fld(m1 + m2 - 1, 12)
1,294,072✔
47

48
function (+)(dt::DateTime, z::Month)
223,586✔
49
    y,m,d = yearmonthday(dt)
223,586✔
50
    ny = yearwrap(y, m, value(z))
223,586✔
51
    mm = monthwrap(m, value(z)); ld = daysinmonth(ny, mm)
650,758✔
52
    return DateTime(ny, mm, d <= ld ? d : ld, hour(dt), minute(dt), second(dt), millisecond(dt))
223,586✔
53
end
54

55
function (+)(dt::Date, z::Month)
1,070,446✔
56
    y,m,d = yearmonthday(dt)
1,070,446✔
57
    ny = yearwrap(y, m, value(z))
1,070,446✔
58
    mm = monthwrap(m, value(z)); ld = daysinmonth(ny, mm)
3,211,338✔
59
    return Date(ny, mm, d <= ld ? d : ld)
1,070,446✔
60
end
61
function (-)(dt::DateTime, z::Month)
20✔
62
    y,m,d = yearmonthday(dt)
20✔
63
    ny = yearwrap(y, m, -value(z))
20✔
64
    mm = monthwrap(m, -value(z)); ld = daysinmonth(ny, mm)
60✔
65
    return DateTime(ny, mm, d <= ld ? d : ld, hour(dt), minute(dt), second(dt), millisecond(dt))
20✔
66
end
67
function (-)(dt::Date, z::Month)
20✔
68
    y,m,d = yearmonthday(dt)
20✔
69
    ny = yearwrap(y, m, -value(z))
20✔
70
    mm = monthwrap(m, -value(z)); ld = daysinmonth(ny, mm)
60✔
71
    return Date(ny, mm, d <= ld ? d : ld)
20✔
72
end
73

74
(+)(x::Date, y::Quarter) = x + Month(y)
151,529✔
75
(-)(x::Date, y::Quarter) = x - Month(y)
10✔
76
(+)(x::DateTime, y::Quarter) = x + Month(y)
135,465✔
77
(-)(x::DateTime, y::Quarter) = x - Month(y)
10✔
78
(+)(x::Date, y::Week) = return Date(UTD(value(x) + 7 * value(y)))
71,521✔
79
(-)(x::Date, y::Week) = return Date(UTD(value(x) - 7 * value(y)))
10✔
80
(+)(x::Date, y::Day)  = return Date(UTD(value(x) + value(y)))
260,912✔
81
(-)(x::Date, y::Day)  = return Date(UTD(value(x) - value(y)))
220,672✔
82
(+)(x::DateTime, y::Period) = return DateTime(UTM(value(x) + toms(y)))
526,206,212✔
83
(-)(x::DateTime, y::Period) = return DateTime(UTM(value(x) - toms(y)))
20,844✔
84
(+)(x::Time, y::TimePeriod) = return Time(Nanosecond(value(x) + tons(y)))
36,984✔
85
(-)(x::Time, y::TimePeriod) = return Time(Nanosecond(value(x) - tons(y)))
62✔
86
(+)(y::Period, x::TimeType) = x + y
2✔
87

88
# Missing support
89
(+)(x::AbstractTime, y::Missing) = missing
×
90
(+)(x::Missing, y::AbstractTime) = missing
×
91
(-)(x::AbstractTime, y::Missing) = missing
×
92
(-)(x::Missing, y::AbstractTime) = missing
×
93

94
# AbstractArray{TimeType}, AbstractArray{TimeType}
95
(-)(x::OrdinalRange{T}, y::OrdinalRange{T}) where {T<:TimeType} = Vector(x) - Vector(y)
×
96
(-)(x::AbstractRange{T}, y::AbstractRange{T}) where {T<:TimeType} = Vector(x) - Vector(y)
×
97

98
# Allow dates, times, and time zones to broadcast as unwrapped scalars
99
Base.Broadcast.broadcastable(x::AbstractTime) = Ref(x)
×
100
Base.Broadcast.broadcastable(x::TimeZone) = Ref(x)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc