Age | Commit message (Collapse) | Author |
|
hipe: Cleanup and fix specs of the hipe module
|
|
HiPE: Fix check for when ErLLVM is available
|
|
There was a lot of confusion between file vs. module names in the
function specification of the hipe module (as also discovered by #1992)
and this PR cleans up and fixes them.
|
|
|
|
The previous check whether ErLLVM could be enabled and/or tested simply
checked whether a suitable version of the LLVM tool chain was present
in the path. Obviously this is not enough: there should also be a check
that we are running in an architecture on which the ErLLVM compiler
has been ported. Fix the function that provides this functionality and
also rename it in order to more appropriately describe what it does.
In principle, this change introduces a backwards incompatibility as the
function is one of those exported by the `hipe' module, but this
function was not documented and the chances that it has been used
somewhere else that the test suite are pretty low (if not zero).
|
|
|
|
|
|
|
|
HiPE has had metadata for gc safety on it's temporaries for a while, but
it has never been enforced or even checked, so naturally several
gc-safety violations has slipped through.
A new pass, hipe_rtl_verify_gcsafe verifies gcsafety on optimised RTL
and is used when running the testsuite, and can be manually enabled with
+{hipe,[verify_gcsafe]}.
|
|
Should probably be left for the HiPE team to fix
|
|
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_restore_reuse is a simplistic range splitter that splits temps that
are forced onto the stack by being live over call instructions. In
particular, it attempts to avoid cases where there are several accesses
to such stack allocated temps in straight-line code, uninterrupted by
any calls. In order to achieve this it splits temps between just before
the first access(es) and just after the last access(es) in such
straight-line code groups.
The hipe_restore_reuse pass is controlled by a new option
ra_restore_reuse.
ra_restore_reuse is added to o1.
|
|
|
|
|
|
* richarl/fix-license-headers/PR-788:
Make use of the Header feature in yecc
Remove Emacs timestamp markers
Remove obsolete CVS keyword markup
Update obsolete author e-mails
Replace broken example URL
Add missing entries to COPYRIGHT file
Correct copyright on stdlib files
Add license headers to hipe files in kernel
Correct copyright info on typer files
Correct copyright and license on dialyzer files
Correct copyright on remaining hipe files
Correct copyright info on hipe cerl files
Correct copyright info on cerl-related files
Correct the copyright info in docgen_edoc_xml_cb
Update Syntax Tools license headers
Remove some obsolete files
Update EDoc license headers to dual Apache2/LGPL
Update EUnit license headers to dual Apache2/LGPL
|
|
|
|
|
|
Print the MFA/module being compiled, and pretty-print the backtrace with
lib:format_stacktrace/4.
Additionally, make the error_msg/2 macro in hipe.hrl respect the
HIPE_LOGGING define, since messages produced by this macro just before
runtime shutdown were sometimes lost (since code_server:error_msg/2 is
asynchronous).
|
|
ra_partitioned significantly speeds up register allocation of larger
functions without affecting allocation quality negatively. This is the
final change needed to make o1 suitable for compiling really large
functions without choking.
|
|
|
|
These options would not do anything, because they would not supress the
'o2' in ?COMPILE_DEFAULTS. Such behaviour is added to expand_options/2.
|
|
Now that x86 is no longer broken with these optimisation levels, we add
them to the test suite to ensure they do not break again.
Bump timeout to 6min since tests are run twice as many times.
The option set of o1 was changed to all optimisations that run fast on
both big and small programs, incurring only a slight compile time
increase compared to the old set, but with a, presumably, significant
improvement to speed of compiled code.
Change o0 register allocator to linear_scan.
|
|
* Rewrite matching statements in ?when_option macro to form that silences
dialyzer's unmatched_return warnings
* Treat compiler warnings as errors when compiling files in main
|
|
|
|
|
|
* Implemented removal of maps:is_key/2 calls of which the result is
known in a new pass during the typed phase, called
hipe_icode_call_elim.
* Added the option icode_call_elim that enables the
hipe_icode_call_elim pass, and made it default for o2.
|
|
A bug in LLVM miscompiles x86 functions that have floats are spilled to
stack. We work around it by disabling (inlined) floats when using llvm
on x86. Once a LLVM version in which the bug is fixed is released, we
can make the workaround conditional depending on the version.
|
|
|
|
The bulk of the changes concerns cleanups and code refactorings concerning
record constructions that assigned 'undefined' to record fields whose type
did not contain this value. See commit 8ce35b2.
While at it, some new type definitions were introduced and type names were
used instead of record type notation. Minor code cleaups were also done.
|
|
Main problem:
A faulty HIPE_LITERAL_CRC was not detected by the loader.
Strangeness #1:
Dialyzer should ask the hipe compiler about the target checksum,
not an internal bif.
Strangeness #2:
The HIPE_SYSTEM_CRC checksum was based on the HIPE_LITERALS_CRC
checksum.
Solution:
New HIPE_ERTS_CHECKSUM which is an bxor of the two (now independent)
HIPE_LITERALS_CRC and HIPE_SYSTEM_CRC.
HIPE_LITERALS_CRC represents values that are assumed to stay constant
for different VM configurations of the same arch, and are therefor
hard coded into the hipe compiler.
HIPE_SYSTEM_CRC represents values that may differ between VM variants.
By default the hipe compiler asks the running VM for this checksum,
in order to create beam files for the same running VM.
The hipe compiler can be configured (with "make XCOMP=yes ...") to
create beam files for another VM variant, in which case HIPE_SYSTEM_CRC
is also hard coded.
ToDo:
Treat all erts properties the same. Either ask the running VM or hard
coded into hipe (if XCOMP=yes). This will simplify and reduce the risk
of dangerous mismatches. One concern might be the added overhead
from more frequent calls to hipe_bifs:get_rts_param.
|
|
OTP-12845
* bruce/change-license:
fix errors caused by changed line numbers
Change license text to APLv2
|
|
|
|
A recent rewrite of some code in this file (commit 355f4b5)
exposed some dialyzer warnings of some code which is unreachable.
Indeed, checking whether one executes on an unsupported architecture
when expanding the 'o2' and 'o3' hipe compiler options is unnecessary
because that check is performed in the expansion of the 'o1' option
anyway. While at it, simplified the code a bit not to have a very
long case clause.
|
|
|
|
This checks that a required LLVM version (i.e. 3.4 or greater) appears in $PATH
when 'to_llvm' flag is used; in case of failure, abort compilation with an
error.
|
|
Add flags to enable and use the LLVM backend:
* to_llvm: use the LLVM pipeline for compilation (default optimization level
is O3),
* llvm_save_temps: save the intermediate files in current directory in order
to be able to debug or optimize the LLVM assembly,
* {to_llvm, O}: set the optimization level of LLVM opt and llc tools.
Add some debug support to the loader; no semantic change intented.
|
|
The HiPE compiler implicitly relied on the assumption that a function
will never appear as both exported and also used as function closure.
This was true because the BEAM compiler prior to R16B created module
local anonymous functions for each closure. A proposed change to the
BEAM compiler invalidates this invariant, so in order to accommodate
for this change there needs to be a change of how the set of possibly
escaping functions is computed.
While doing this, the code was simplified by taking out a boolean()
tag that indicated whether a function is a closure or exported and
also slightly cleaned up the affected modules.
|
|
|
|
The hybrid heap emulator was last working in the non-SMP R11B
run-time system. When the constant pools were introduced in R12B,
the hybrid heap emulator was not updated to handle them.
At this point, the harm from reduced readability of the code is
greater than any potential usefulness of keeping the code.
|
|
|
|
The BEAM disassembler used the atom 'none' to signify the absence
of a compile_info chunk in a .beam file. This clashes with the type
declaration of the compile_info field of a #beam_file{} record as
containing a list. Use [] to signify the absence of this chunk.
This simplifies the code and avoids a dialyzer warning.
For fixing a similar problem and for consistency, changed also the
return type of the attributes field of the #beam_file{} record.
This required a change in the beam_disasm test suite.
|
|
|
|
* bjorn/compiler/options/OTP-9752:
filename documentation: Recommend against using filename:find_src/1,2
Teach filename:find_src/1,2 to handle slim or stripped BEAM files
filename: Eliminate failing call to Mod:module_info(source_file)
filename.erl:filter_options/1: Remove handling of dead options
compiler: Don't include {cwd,_} in module_info(compile)
compiler: Don't include source code options in module_info(compile)
hipe: Teach hipe to handle slim or stripped BEAM files
|
|
Compiling single functions (as opposed to whole modules) to native
code complicates code management in HiPE. It would also vastly
complicate whole-module optimizations, such as returning multiple
return values instead of tuples within a module.
As a first step, remove the external interface for the single
compilation feature. In the future, there are many things that
could be restructured and simplified.
|
|
|
|
|
|
hipe:load/1 (and unexported hipe:load/2) just did not work. Calling it
would fail with a badmatch because only the hipe chunk was passed to
do_load/3's third parameter called WholeModule. Since this parameter is
then passed to beam_lib:all_chunks/1 which accepts the whole module as a
binary as well as a path to the beam file, and since a path is exactly
what we have in load/2, the fix consists in letting do_load/3 accept a
path and passing it from load/2.
|
|
|