Age | Commit message (Collapse) | Author |
|
Document HiPE limitations
|
|
|
|
which don't seem to be true.
|
|
Fix hipe bug in binary <<X/utf32>> construction
|
|
by introducing new primop 'is_unicode'
with no exception (ab)use and no GC.
Replaces bs_validate_unicode which is kept for backward compat for now.
|
|
|
|
* lars/doc-cleanup/OTP-14475:
[edoc] Remove unused module otpsgml_layout.erl
Remove unused files from the documentation build
|
|
|
|
|
|
|
|
~tw and new string functions are new since OTP-20 (stdlib-3.4)
|
|
* hasse/dialyzer/map_fixes/OTP-14572:
dialyzer: Adjust a test case
dialyzer: Modify handling of singleton map key types
Dialyzer: Rewrite one map type invariant
Dialyzer: Rewrite some of the docs of map types
|
|
The implementation of OTP-14218 (commit 6d3b38a) has a weakness: only
a very limited part of the type form is checked. This is now fixed:
types not used by specs are checked equally well as types used by
specs.
The new function erl_types:t_from_form_check_remote() checks usage of
remote types. It does not expand used local types, and has (almost) no
limits on depth and size.
|
|
The test case loop.erl shows that there is a problem with certain
singleton key types. Here the internal representation toggles between
#{a | b => ...} and #{a => ..., b => ...}
The choice is to turn #{a | b => ...} into #{a => ..., b => ...} early
(t_from_form()). The aim is to keep as much info as possible (in
pairs). However, including complex singleton keys (tuples, maps) in
this scheme is potentially too costly, and a bit complicated. So one
more choice is made: let atoms and number (and nothing else) be
singleton types, and let complex keys go into the default key.
|
|
|
|
|
|
|
|
|
|
Substitute try/catch for an obsoletely used catch.
Thanks to Kostis for pointing it out.
|
|
|
|
|
|
|
|
This reverts commit eaf8ca41dfa4850437ad270d3897399c9358ced0.
|
|
|
|
As of commit 854ee8b (Erlang/OTP 18) warnings about using '_' as type
variable in parameterized types have not been output.
The code of erl_types:t_var_names() is corrected. The spec is also
corrected (thanks to Kostis for pointing out the bug).
|
|
This reverts commit dc57404252c47520f352834ad9be45ad684f96c9.
|
|
|
|
|
|
Due to a bug in Dialyzer, unknown types have been introduced.
|
|
* sverker/refactor:
erts: Introduce struct binary_internals
erts: Introduce erts_bin_release
erts: Init refc=1 in erts_bin_drv_alloc*
erts: Init refc=1 in erts_bin_nrml_alloc
erts: Remove deliberate leak of hipe fun entries
erts: Remove hipe_bifs:remove_refs_from/1
Refactor hipe specific code to use ErtsCodeInfo
erts: Refactor ErtsCodeInfo.native
|
|
|
|
which serves no purpose after all the
hipe load&purge fixes merged at
32729cab75325de58bf127e6e8836348071b8682
|
|
By having ErLLVM explicitly tell LLVM which architecture we're expecting
it to compile for we remove the risk of having LLVM generate amd64 code
for a x86 VM.
|
|
HiPE: Fix ERL-278: Fix range analysis miscompilation bug
|
|
|
|
hipe: Fix alignment of byte-sized constants
|
|
HiPE: Fix off-by-one bug in register allocators
Fix for PR-1380
|
|
HiPE's range analysis would not update the arguments of a callee when
the result of the call was ignored.
Fixes ERL-278.
|
|
erl_bif_types contains a fixed and improved copy-paste (obvious from the
dead Max_range2_leq_zero if branches) of hipe_icode_range:range_rem/2.
For now, delete the dead code and propagate back fixes and improvements
to hipe_icode_range.
|
|
|
|
hipe_regalloc_loop considers SpillLimit to be an inclusive lower bound,
the allocators considered it to be an exclusive lower bound. The
allocators are changed to also consider it an inclusive lower bound.
This caused the register allocators to occasionally spill the first
"unspillable" temporary. This caused a failure in a newly added
assertion when hipe-compiling dets_v9 on x86.
|
|
|
|
|
|
|
|
|
|
|
|
These pseudo instructions are added to all backends and allow spill slot
to spill slot move coalescing in a clean way.
They have regular move semantics, but contain an additional scratch
register to be used if both source and destination are spilled, and can
not be move coalesced.
Additionally, a register allocator callback
Target:is_spill_move(Instr, Context) is added which allows the spill
slot allocators to check for these instructions and try to coalesce the
spill slots the two temporaries are allocated to.
|
|
hipe_range_split is a complex live range splitter, more sophisticated
thatn hipe_restore_reuse, but still targeted specifically at temporaries
forced onto stack by being live over call instructions.
hipe_range_split partitions the control flow graph at call instructions,
like hipe_regalloc_prepass. Splitting decisions are made on a per
partition and per temporary basis.
There are three different ways in which hipe_range_split may choose to
split a temporary in a program partition:
* Mode1: Spill the temp before calls, and restore it after them
* Mode2: Spill the temp after definitions, restore it after calls
* Mode3: Spill the temp after definitions, restore it before uses
To pick which of these should be used for each temp×partiton pair,
hipe_range_split uses a cost function. The cost is simply the sum of the
cost of all expected stack accesses, and the cost for an individual
stack access is based on the probability weight of the basic block that
it resides in. This biases the range splitter so that it attempts moving
stack accesses from a functions hot path to the cold path.
hipe_bb_weights is used to compute the probability weights.
mode3 is effectively the same as what hipe_restore_reuse does. Because
of this, hipe_restore_reuse reuses the analysis pass of
hipe_restore_reuse in order to compute the minimal needed set of spills
and restores. The reason mode3 was introduced to hipe_range_split rather
than simply composing it with hipe_restore_reuse (by running both) is
that such a composition resulted in poor register allocation results due
to insufficiently strong move coalescing in the register allocator.
The cost function heuristic has a couple of tuning knobs:
* {range_split_min_gain, Gain} (default: 1.1, range: [0.0, inf))
The minimum proportional improvement that the cost of all stack
accesses to a temp must display in order for that temp to be split.
* {range_split_mode1_fudge, Factor} (default: 1.1, range: [0.0, inf))
Costs for mode1 are multiplied by this factor in order to discourage
it when it provides marginal benefits. The justification is that
mode1 causes temps to be live for longest, thus leading to higher
register pressure.
* {range_split_weight_power, Factor} (default: 2, range: (0.0, inf))
Adjusts how much effect the basic block weights have on the cost of a
stack access. A stack access in a block with weight 1.0 has cost 1.0,
a stack access in a block with weight 0.01 has cost 1/Factor.
Additionally, the option range_split_weights chooses whether the basic
block weights are used at all.
In the case that the input is very big, hipe_range_split automatically
falls back to hipe_restore_reuse only in order to keep compile times
under control. Note that this is not only because of hipe_range_split
being slow, but also due to the resulting program being slow to register
allocate, and is not as partitionable by hipe_regalloc_prepass.
hipe_restore_reuse, on the other hand, does not affect the programs
partitionability.
The hipe_range_split pass is controlled by a new option ra_range_split.
ra_range_split is added to o2, and ra_restore_reuse is disabled in o2.
|
|
hipe_bb_weights computes basic block weights by using the branch
probability predictions as the coefficients in a linear equation system.
This linear equation system is then solved using Gauss-Jordan
Elimination.
The equation system representation is picked to be efficient with highly
sparse data. During triangelisation, the remaining equations are
dynamically reordered in order to prevent the equations from growing in
the common case, preserving the benefit of the sparse equation
representation.
In the case that the input is very big, hipe_bb_weights automatically
falls back to a rough approximation in order to keep compile times under
control.
|
|
Adds a new register allocator callback
Target:branch_preds(Instr, Context) which, for a control flow
instruction Instr, returns a list of tuples {Target, Probability} for
each label name Target that Instr may branch to. Probability is a float
between 0.0 and 1.0 and corresponds to the predicted probability that
control flow branches to the corresponding target. The probabilities may
sum to at most 1.0 (rounding errors aside). Note that a sum less than
1.0 is valid.
|