swh:1:snp:a72e953ecd624a7df6e6196bbdd05851996c5e40

sort by:
Revision Author Date Message Commit Date
a7cd4a3 [NewOptimizer] Make stmt_effect_free less aggressive Previously, the new optimizer used the pre-existing `effect_free` function to determine whether it is safe to remove an unreferenced statement. However, this function ignores many builtin's error cases, causing them to be removed when that is not legal to do (because that would potentially remove an exception that would otherwise be thrown). Start fixing this, by introducing a version of the function that is correct for a subset of intresting functions. We will likely need to expand this when we look at the benchmarks, but this should be correct for now. 01 May 2018, 19:45:17 UTC
4910e59 [NewOptimizer] Fix phi node codegen corner case Just a silly corner case where we forgot to check whether val.typ == Union{}, causing a crash in the cmdlineargs test. 01 May 2018, 17:09:02 UTC
7d3d636 Widen element type for processed array 01 May 2018, 15:51:01 UTC
6a6b96e [NewOptimizer] Union Split during Inlining This adds union splitting optimizations to the inliner. This works a bit differently from the old optimizer, which did union splitting on the bail out path. Instead, we try to run the full inliner on any union split case that's a dispatch tuple (and record what to do in that case). Doing that allows an effective resolution of #23338, though this PR doesn't quite do that yet, since some further (minor) fixes are needed. 01 May 2018, 15:25:09 UTC
23388ae Merge pull request #26918 from JuliaLang/kf/reverseaffinity [NewOptimizer] Backport reverse affinity changes from #26778 01 May 2018, 15:19:08 UTC
132a9f4 inference: first try to tmerge tuples to a single Vararg type (#22120) 01 May 2018, 03:19:27 UTC
8770821 Remove indirect dependency on system ZLIB (#26888) * Remove indirect dependency on system ZLIB - build LLVM without ZLIB support - use the bundled ZLIB for libgit * backport bundled zlib patch 30 April 2018, 21:25:44 UTC
509d6a1 Travis: download moreutils from the release tarball (#26902) * Update moreutils git repo location in .travis.yml The old `kitenet.net` domain is down. Checking on wayback, its pages had been throwing 302 redirects to this new domain. * Try downloading tarball from http.debian.net [av skip] 27 April 2018, 21:12:42 UTC
c9c2b5f Merge pull request #26901 from JuliaLang/kf/sroafix [NewOptimizer] Fix bug in getfield elim pass 27 April 2018, 18:24:21 UTC
99016fd [NewOptimizer] Backport reverse affinity changes from #26778 In #26778, I changed the way that the reverse affinity flag works in order to support node insertion during compaction. In particular, I had originally (for ease of implementation primarily) had that flag simply change which BB an inserted node belongs to (i.e. if that flag was set and there was a basic block boundary at the insertion site, the new node would belong to the previous BB). In #26778, I changed this to instead be a flag of whether to insert before or after a given instruction. As it turns out, this change is also required for correctness. Because domsorting can change the notion of "previous instruction" by moving basic blocks, we had (in rare circumstances) instructions end up in the wrong BB. Backporting those changes fixes that. 27 April 2018, 18:06:38 UTC
f93591d [NewOptimizer] Fix bug in getfield elim pass We were looking at the pre-compacted IR rather than the compacted one, causing errors. We need to clean all this up once we rip out the old optimizer code, but for now, let's get this correct. 27 April 2018, 15:02:44 UTC
1429744 fix pkg3 precompile (#26913) 26 April 2018, 20:58:09 UTC
ef76d9c Merge pull request #26891 from JuliaLang/mb-teh-jn-ajk/lazydotfuse Customizable lazy fused broadcasting in pure Julia 26 April 2018, 14:57:43 UTC
f4349c1 Merge pull request #26908 from JuliaLang/kc/bump_pkg3_7 Bump Pkg3 26 April 2018, 12:18:39 UTC
acb6cae fix adding and developing detached repos 26 April 2018, 10:04:15 UTC
88c342a Spelling 26 April 2018, 10:01:25 UTC
2620370 fix up on package with no manifest (#257) * fix up on package with no manifest * add debug stuff * wut * sigh * fixups 26 April 2018, 10:01:18 UTC
026bd86 give refspecs to the registry (#258) 26 April 2018, 10:01:11 UTC
67fc4fc Fix `comprod!` to use `mul_prod` instead of `add_sum` (#26905) 26 April 2018, 05:10:30 UTC
18ad6a8 Change lowering of `A .= x` to match fused RHS cases Now instead of lowering to `broadcast!(identity,A,x)`, it lowers to `Broadcast.materialize!(A, Broadcast.broadcasted(identity, x))`, with all names resolved in the top module. 25 April 2018, 15:43:40 UTC
edd4dcf Correct NEWS.md 25 April 2018, 14:07:15 UTC
75798f9 Remove the last of the base broadcast methods... by implementing a preprocessing step for chunked bitarray broadcast that converts boolean-only functions to ones that support chunk-wise operation. Also add a number of tests for this codepath 25 April 2018, 05:54:42 UTC
8a2d88a Remove hack that avoided materialize in fallback broadcast For reasons beyond my comprehensions, this previously failed to inline despite the at-inline. For reasons that are also beyond my comprehension, this hack is no longer necessary. 24 April 2018, 19:39:01 UTC
4cd10d3 Test and fix #26127 24 April 2018, 17:34:24 UTC
c9a0a41 Rename Broadcast.make to Broadcast.broadcasted 24 April 2018, 16:14:35 UTC
9f5351c Merge pull request #26893 from JuliaLang/sf/documenter Bump documenter version 24 April 2018, 14:26:44 UTC
a1450b3 Bump documenter version Documenter 0.17.0 contains the fix for https://github.com/JuliaDocs/Documenter.jl/pull/699, which allows doc builds inside of git worktrees to actually finish. 24 April 2018, 02:59:44 UTC
ef9168a fix a use of `isbitstype` in new optimizer (#26887) 24 April 2018, 02:56:14 UTC
dbe1ae0 Customizable lazy fused broadcasting in pure Julia This patch represents the combined efforts of four individuals, over 60 commits, and an iterated design over (at least) three pull requests that spanned nearly an entire year (closes #22063, #23692, #25377 by superceding them). This introduces a pure Julia data structure that represents a fused broadcast expression. For example, the expression `2 .* (x .+ 1)` lowers to: ```julia julia> Meta.@lower 2 .* (x .+ 1) :($(Expr(:thunk, CodeInfo(:(begin Core.SSAValue(0) = (Base.getproperty)(Base.Broadcast, :materialize) Core.SSAValue(1) = (Base.getproperty)(Base.Broadcast, :make) Core.SSAValue(2) = (Base.getproperty)(Base.Broadcast, :make) Core.SSAValue(3) = (Core.SSAValue(2))(+, x, 1) Core.SSAValue(4) = (Core.SSAValue(1))(*, 2, Core.SSAValue(3)) Core.SSAValue(5) = (Core.SSAValue(0))(Core.SSAValue(4)) return Core.SSAValue(5) end))))) ``` Or, slightly more readably as: ```julia using .Broadcast: materialize, make materialize(make(*, 2, make(+, x, 1))) ``` The `Broadcast.make` function serves two purposes. Its primary purpose is to construct the `Broadcast.Broadcasted` objects that hold onto the function, the tuple of arguments (potentially including nested `Broadcasted` arguments), and sometimes a set of `axes` to include knowledge of the outer shape. The secondary purpose, however, is to allow an "out" for objects that _don't_ want to participate in fusion. For example, if `x` is a range in the above `2 .* (x .+ 1)` expression, it needn't allocate an array and operate elementwise — it can just compute and return a new range. Thus custom structures are able to specialize `Broadcast.make(f, args...)` just as they'd specialize on `f` normally to return an immediate result. `Broadcast.materialize` is identity for everything _except_ `Broadcasted` objects for which it allocates an appropriate result and computes the broadcast. It does two things: it `initialize`s the outermost `Broadcasted` object to compute its axes and then `copy`s it. Similarly, an in-place fused broadcast like `y .= 2 .* (x .+ 1)` uses the exact same expression tree to compute the right-hand side of the expression as above, and then uses `materialize!(y, make(*, 2, make(+, x, 1)))` to `instantiate` the `Broadcasted` expression tree and then `copyto!` it into the given destination. All-together, this forms a complete API for custom types to extend and customize the behavior of broadcast (fixes #22060). It uses the existing `BroadcastStyle`s throughout to simplify dispatch on many arguments: * Custom types can opt-out of broadcast fusion by specializing `Broadcast.make(f, args...)` or `Broadcast.make(::BroadcastStyle, f, args...)`. * The `Broadcasted` object computes and stores the type of the combined `BroadcastStyle` of its arguments as its first type parameter, allowing for easy dispatch and specialization. * Custom Broadcast storage is still allocated via `broadcast_similar`, however instead of passing just a function as a first argument, the entire `Broadcasted` object is passed as a final argument. This potentially allows for much more runtime specialization dependent upon the exact expression given. * Custom broadcast implmentations for a `CustomStyle` are defined by specializing `copy(bc::Broadcasted{CustomStyle})` or `copyto!(dest::AbstractArray, bc::Broadcasted{CustomStyle})`. * Fallback broadcast specializations for a given output object of type `Dest` (for the `DefaultArrayStyle` or another such style that hasn't implemented assignments into such an object) are defined by specializing `copyto(dest::Dest, bc::Broadcasted{Nothing})`. As it fully supports range broadcasting, this now deprecates `(1:5) + 2` to `.+`, just as had been done for all `AbstractArray`s in general. As a first-mover proof of concept, LinearAlgebra uses this new system to improve broadcasting over structured arrays. Before, broadcasting over a structured matrix would result in a sparse array. Now, broadcasting over a structured matrix will _either_ return an appropriately structured matrix _or_ a dense array. This does incur a type instability (in the form of a discriminated union) in some situations, but thanks to type-based introspection of the `Broadcasted` wrapper commonly used functions can be special cased to be type stable. For example: ```julia julia> f(d) = round.(Int, d) f (generic function with 1 method) julia> @inferred f(Diagonal(rand(3))) 3×3 Diagonal{Int64,Array{Int64,1}}: 0 ⋅ ⋅ ⋅ 0 ⋅ ⋅ ⋅ 1 julia> @inferred Diagonal(rand(3)) .* 3 ERROR: return type Diagonal{Float64,Array{Float64,1}} does not match inferred return type Union{Array{Float64,2}, Diagonal{Float64,Array{Float64,1}}} Stacktrace: [1] error(::String) at ./error.jl:33 [2] top-level scope julia> @inferred Diagonal(1:4) .+ Bidiagonal(rand(4), rand(3), 'U') .* Tridiagonal(1:3, 1:4, 1:3) 4×4 Tridiagonal{Float64,Array{Float64,1}}: 1.30771 0.838589 ⋅ ⋅ 0.0 3.89109 0.0459757 ⋅ ⋅ 0.0 4.48033 2.51508 ⋅ ⋅ 0.0 6.23739 ``` In addition to the issues referenced above, it fixes: * Fixes #19313, #22053, #23445, and #24586: Literals are no longer treated specially in a fused broadcast; they're just arguments in a `Broadcasted` object like everything else. * Fixes #21094: Since broadcasting is now represented by a pure Julia datastructure it can be created within `@generated` functions and serialized. * Fixes #26097: The fallback destination-array specialization method of `copyto!` is specifically implemented as `Broadcasted{Nothing}` and will not be confused by `nothing` arguments. * Fixes the broadcast-specific element of #25499: The default base broadcast implementation no longer depends upon `Base._return_type` to allocate its array (except in the empty or concretely-type cases). Note that the sparse implementation (#19595) is still dependent upon inference and is _not_ fixed. * Fixes #25340: Functions are treated like normal values just like arguments and only evaluated once. * Fixes #22255, and is performant with 12+ fused broadcasts. Okay, that one was fixed on master already, but this fixes it now, too. * Fixes #25521. * The performance of this patch has been thoroughly tested through its iterative development process in #25377. There remain [two classes of performance regressions](#25377) that Nanosoldier flagged. * #25691: Propagation of constant literals sill lose their constant-ness upon going through the broadcast machinery. I believe quite a large number of functions would need to be marked as `@pure` to support this -- including functions that are intended to be specialized. (For bookkeeping, this is the squashed version of the [teh-jn/lazydotfuse](https://github.com/JuliaLang/julia/pull/25377) branch as of a1d4e7ec9756ada74fb48f2c514615b9d981cf5c. Squashed and separated out to make it easier to review and commit) Co-authored-by: Tim Holy <tim.holy@gmail.com> Co-authored-by: Jameson Nash <vtjnash@gmail.com> Co-authored-by: Andrew Keller <ajkeller34@users.noreply.github.com> 23 April 2018, 23:56:46 UTC
c0a278c Merge pull request #26839 from JuliaLang/jn/iddict-delete IdDict: support deletion, and support `nothing` used as a key 23 April 2018, 20:33:32 UTC
692408c fix deprecations of \cdot and \times (#26884) 23 April 2018, 18:23:43 UTC
43fe63c Support reshaping custom 0-dimensional arrays (#26870) Fixes #26163. 23 April 2018, 18:17:30 UTC
923cb6a fix some cases of dot syntax lowering (#26878) fix #26739, error for `sum.[1]` fix #26873, should have no error for `f."a"` 23 April 2018, 18:11:12 UTC
5e57c21 IdDict: support deletion, and support `nothing` used as a key previously, if we deleted one key or added `nothing` as a key, we might lose some of the other entries too (until rehash) fix #26833 23 April 2018, 16:23:06 UTC
55b3fc2 clang-format table.c 23 April 2018, 16:23:06 UTC
22ded18 Pkg3: deterministically close the LibGit2 repo in tests (#26883) 23 April 2018, 10:12:23 UTC
de705f3 Merge pull request #26854 from JuliaLang/kc/bump_pkg3_6 Bump Pkg3 22 April 2018, 20:14:39 UTC
114c1b6 code loading docs: add missing graph edge (#26874) 22 April 2018, 06:48:33 UTC
1c5ed70 add news for #26858 and #26859 [ci skip] (#26869) 20 April 2018, 22:02:48 UTC
23b08c5 Deprecate using && and || within at-dot expressions (#26792) Giving us space to allow lowering this to `.&&` and `.||` in the future. Ref #5187. 20 April 2018, 18:44:27 UTC
9aa32bd Merge pull request #26658 from JuliaLang/sb/accumulate2 Change accumulation promotion behaviour 20 April 2018, 18:43:40 UTC
367bc96 widen `Int8` and `Int16` to `Int` instead of `Int32` (#26859) This is consistent with `sum` and less arbitrary. 20 April 2018, 18:29:06 UTC
2953183 fix #26038, make `isequal` consistent with `hash` for `Ptr` (#26858) 20 April 2018, 18:28:34 UTC
8f46450 Deprecate variadic size(A, dim1, dim2, dims...) method (#26862) Resolves #26851. 20 April 2018, 15:45:30 UTC
45b2606 add using Random to example in manual (#26864) 20 April 2018, 13:54:10 UTC
5ba09d2 warn once instead of depwarn since we want to test it 20 April 2018, 12:28:14 UTC
8926889 Merge pull request #26860 from JuliaLang/tb/hotfix Fix compilation on LLVM 6.0 20 April 2018, 03:38:19 UTC
adab472 Merge pull request #26855 from JuliaLang/vc/ifconvt [LLVM 6] add patch to diamond if-conversion 20 April 2018, 02:30:44 UTC
153e72d Revert "reserve syntax that could be used for computed field types (#18466) (#26816)" (#26857) This reverts commit a6f6b5bd392ab87e21b5c0aa75e2f88e54038732. 20 April 2018, 02:07:21 UTC
5912b14 Merge pull request #26772 from JuliaLang/vc/ppc_interpreter_stacktrace [PPC] implement enter_interpreter_frame 19 April 2018, 21:08:51 UTC
0dbab6f Fix compilation on LLVM 6.0 19 April 2018, 20:01:57 UTC
82c8f45 change promotion behaviour of `cumsum` and `cumsum!` to match `sum` 19 April 2018, 19:36:31 UTC
5179455 Merge pull request #26790 from JuliaLang/jb/promotenum RFC: remove rule requiring Number types to implement specific promotions 19 April 2018, 18:32:44 UTC
2c369bf separate `isbitstype(::Type)` from `isbits` (#26850) 19 April 2018, 18:30:02 UTC
8dfe3fb [LLVM 6] add patch to diamond if-conversion 19 April 2018, 18:11:08 UTC
6e05a48 Merge pull request #26849 from JuliaLang/jn/new-inbounds [NewOptimizer] implement boundscheck elision 19 April 2018, 18:02:26 UTC
ac1c075 add a precompile command that can be used to precompile all dependencies (#254) 19 April 2018, 16:04:38 UTC
b1458d4 use registry if no version entry exist in project for developed pacakges 19 April 2018, 16:04:04 UTC
57fbbe9 make Pkg3 work as a drop in for the old CI scripts 19 April 2018, 16:03:57 UTC
78d4ed1 update registries when adding (#253) * update registries when adding * done error out if we fail to fetch repo 19 April 2018, 16:03:50 UTC
0a3a9ee make Pkg3 test itself (#251) 19 April 2018, 16:03:40 UTC
a8f356b Merge pull request #26844 from JuliaLang/tb/callinst_metadata Preserve CallInst metadata in LateLowerGCFrame pass. 19 April 2018, 05:56:33 UTC
aed8a84 bugfix for regex matches ending with non-ASCII (#26831) 19 April 2018, 05:07:58 UTC
e66e07e [NewOptimizer] track inbounds state as a per-statement flag 19 April 2018, 03:12:30 UTC
50413a4 change default LOAD_PATH and DEPOT_PATH (#26804, fix #25709) also: - rename "site" directory to "stdlib" since that's what it is now - use JULIA_LOAD_PATH as-is instead unconditionally appending the system package and stdlib directories to it - change default DEPOT_PATH to include system paths: one for arch-specific and one for arch-independent packages - delete comment about bundled code going in a versioned directory as it no longer applies since installed packages can and should be shared across different Julia versions - update Pkg3 and tests to work correctly when the stdlib directory isn't always included in LOAD_PATH 19 April 2018, 00:48:16 UTC
e98bc23 Change url scheme to https (#26835) Similarly to #26757, update the url scheme for this download to use https instead of http (which has started to 301 redirect) 19 April 2018, 00:40:18 UTC
e048e89 [NewOptimizer] inlining: Refactor todo object 18 April 2018, 22:23:16 UTC
69e559d inference: enable CodeInfo method_for_inference_limit_heuristics support (#26822) allow unbounded inference recursion, as long as the user-provided Method in method_for_inference_limit_heuristics does not match the target frame 18 April 2018, 22:02:54 UTC
8e7034e [NewOptimizer] Fix _apply elision (#26821) The old optimizer had an extra loop outside the inlining pass that would turn _apply's in to regular calls. When I wrote the new inliner we discussed that this wasn't actually necessary because we could just keep track of this information in the inliner (as we do for invoke). However, that of course also means that if we can't turn something into an :invoke, we should still at least turn it into a regular call. Do that. 18 April 2018, 16:21:27 UTC
8ab44ca add test case from issue #26607, cfunction with no args (#26838) 18 April 2018, 16:18:09 UTC
ab53067 add `do` in front-end deparser. fixes #17781 (#26840) 18 April 2018, 16:17:35 UTC
9c23f47 Preserve CallInst metadata in LateLowerGCFrame pass. 18 April 2018, 12:23:20 UTC
ca7e837 Improve differences from R documentation (#26810) Changes: * change of `.'` to `transpose` and `permutedims`; * explain that named tuple gives functionality similar to `list` in R; * fix example of creating a matrix using `A=[[1 2],[3 4]]` (which is wrong) and then using `sum(A, 1)` syntax (which is deprecated). 17 April 2018, 19:35:00 UTC
a6f6b5b reserve syntax that could be used for computed field types (#18466) (#26816) 17 April 2018, 19:28:03 UTC
033b722 Merge pull request #26757 from JuliaLang/sb/pcre-link change PCRE download link 17 April 2018, 19:01:42 UTC
c0e6b5b Add support for Atomic{Bool} (Fix #26542). (#26597) Adds `Bool` to list of types supported by `Atomic{T}`. Defines all `atomic_*!` for `Bool`, except `atomic_add!` and `atomic_sub!` since `add(::Bool, ::Bool)` returns an `Int`. Also adds tests for those methods to `test/threads.jl`. 16 April 2018, 19:19:56 UTC
9660a30 Merge pull request #26784 from JuliaLang/jn/accelerate-iterate ensure more iterators stay type-stable 16 April 2018, 16:39:20 UTC
3180efa Remove argument restriction on dims2string and inds2string (#26799) (#26817) 16 April 2018, 16:23:52 UTC
890239f remove some unnecessary `eltype` methods (#26791) 15 April 2018, 17:04:27 UTC
8e37e1b optimize: ensure merge_value_ssa doesn't drop PiNodes 14 April 2018, 03:20:59 UTC
55cee67 inference: improve tmerge for Conditional and Const 14 April 2018, 03:20:59 UTC
ee50eee ensure more iterators stay type-stable This is a frequent performance trap. Perhaps because Tuple/NamedTuple/Pair/default-constructor usage is so much easier than `@nospecialize`. Dunno what else to do but fix them manually. 14 April 2018, 03:20:59 UTC
b6d81e3 code loading docs (#26787) 13 April 2018, 22:09:58 UTC
2eb9048 Merge pull request #26785 from JuliaLang/jn/newir-performance [newir] fix major performance issues 13 April 2018, 19:14:01 UTC
85c341c Rework replace and replace! (#26206) Introduce a new _replace!(new::Callable, res::T, A::T, count::Int) method which custom types can implement to support all replace and replace! methods automatically, instead of the current replace!(new::Callable, A::T, count::Int). This offers several advantages: - For arrays, instead of copying the input and then replace elements, we can do the copy and replace operations at the same time, which is quite faster for arrays when count=nothing. - For dicts and sets, copying up-front is still faster as long as most original elements are preserved, but for replace(), we can apply replacements directly instead of storing a them in a temporary vector. - When the LHS of a pair contains a singleton type, we can subtract it from the element type of the result, e.g. Union{T,Missing} becomes T. Also simplify the dispatch logic by introducing the replace_pairs! function. 13 April 2018, 17:48:30 UTC
cb49bef Improve documentation of const (#26749) * Improve documentation of const Current description of `const` in the manual gave an impression that `const` ensures that variable binding may not change, e.g.: > A common use of variables is giving names to specific, unchanging values. Such variables are only assigned once. This intent can be conveyed to the compiler using the `const` keyword and > Note that `const` only affects the variable binding. The proposed change describes the actual current behavior of `const`. * additional example of const 13 April 2018, 16:59:22 UTC
c149d57 Fix optional argument description (#26048) * Fix optional argument description The `parse` example used keyword argument not optional argument. * change base to Date 13 April 2018, 16:58:28 UTC
100666b [NewOptimizer] manually optimize UseRefIterator allocations eventually, we want stack-allocations to do this automatically 13 April 2018, 16:17:55 UTC
f09fb93 [NewOptimizer] backport improve inlining apply 49f70adf2022f007b93d90cbe7c0da31996a83bc to new inliner 13 April 2018, 16:17:55 UTC
af65e71 [NewOptimizer] avoid common performance traps and fix construct_domtree performance bugs 13 April 2018, 16:17:55 UTC
2233ec4 Deprecate similar(f, …) in favor of just dispatching directly on f(…) (#26733) Remove AbstractArray constructors; just use dispatch on functions Make compiler test use a local function that has the known properties that we want to test. The important thing is not necessarily zeros -- it is a relatively complex function. The `Base.zeros` method tree temporarily breaks this test due to its numerous deprecations, but this will be resolved in the future. 13 April 2018, 15:28:08 UTC
f82eb5b Merge pull request #26800 from bkamins/indexing_error Distinguish getindex/setindex! error message 13 April 2018, 14:33:48 UTC
8d8655d Distinguish getindex/setindex! error message 13 April 2018, 10:06:12 UTC
d63b203 fix #26777, echo server example in manual (#26794) 13 April 2018, 02:20:07 UTC
c45bbde Fix signif deprecation (#26780) 12 April 2018, 23:46:22 UTC
52f27a7 add StringIndexError documentation (#26747) 12 April 2018, 23:44:41 UTC
a3bf547 Fix sentence style in docs (#26746) 12 April 2018, 23:43:30 UTC
f995cea Update Strings section of the documentation (#26736) Changes: * correct description of `b"..."` construct; * correct the fact that now Julia allows invalid string literals; * add reference to `ncodeunits` and `codeunit` function; 12 April 2018, 23:42:49 UTC
e3e5097 add keys for SimpleVector (#26711) 12 April 2018, 23:30:56 UTC
6fe64fe check process type while getting bind address (#26704) fixes #26699 12 April 2018, 23:29:33 UTC
back to top