Skip to content

Commit

Permalink
RFC: lower x^literal as x^Val{literal} for integer literals (#20530)
Browse files Browse the repository at this point in the history
lower x^literal as x^Val{literal} for integer literals (closes #20527)
  • Loading branch information
stevengj committed Feb 16, 2017
1 parent 7ab6428 commit 3222749
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 0 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ Language changes
* The `typealias` keyword is deprecated, and should be replaced with
`Vector{T} = Array{T,1}` or a `const` assignment.

* Experimental feature: `x^n` for integer literals `n` (e.g. `x^3`
or `x^-3`) is now lowered to `x^Val{n}`, to enable compile-time
specialization for literal integer exponents ([#20530]).

Breaking changes
----------------

Expand Down
5 changes: 5 additions & 0 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ end
^(x::Number, p::Integer) = power_by_squaring(x,p)
^(x, p::Integer) = power_by_squaring(x,p)

# x^p for any literal integer p is lowered to x^Val{p},
# to enable compile-time optimizations specialized to p.
# However, we still need a fallback that calls the general ^:
^{p}(x, ::Type{Val{p}}) = x^p

# b^p mod m

"""
Expand Down
5 changes: 5 additions & 0 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ end
Exponentiation operator. If `x` is a matrix, computes matrix exponentiation.
If `y` is an `Int` literal (e.g. `2` in `x^2` or `-3` in `x^-3`), the Julia code
`x^y` is transformed by the compiler to `x^Val{y}`, to enable compile-time
specialization on the value of the exponent. (As a default fallback,
however, `x^Val{y}` simply calls the `^(x,y)` function.)
```jldoctest
julia> 3^5
243
Expand Down
4 changes: 4 additions & 0 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -2057,6 +2057,10 @@
(expand-forms
`(call (core _apply) ,f ,@(tuple-wrap argl '())))))

((and (eq? f '^) (length= e 4) (integer? (cadddr e)))
(expand-forms
`(call ^ ,(caddr e) (call (core apply_type) (top Val) ,(cadddr e)))))

((and (eq? f '*) (length= e 4))
(expand-transposed-op
e
Expand Down
12 changes: 12 additions & 0 deletions test/numbers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2902,6 +2902,18 @@ end
@test rem2pi(T(-4), RoundUp) == -4
end

import Base.^
immutable PR20530; end
^(::PR20530, p::Int) = 1
^{p}(::PR20530, ::Type{Val{p}}) = 2
@testset "literal powers" begin
x = PR20530()
p = 2
@test x^p == 1
@test x^2 == 2
@test [x,x,x].^2 == [2,2,2]
end

@testset "iszero" begin
# Numeric scalars
for T in [Float16, Float32, Float64, BigFloat,
Expand Down

1 comment on commit 3222749

@pabloferz
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this affect broadcast dot fusion? 3958491#commitcomment-20926124

Please sign in to comment.