Age | Commit message (Collapse) | Author |
|
|
|
|
|
Upstream this patch from FreeBSD Ports:
https://svnweb.freebsd.org/ports/head/lang/erlang-runtime21/files/patch-lib_hipe_llvm_hipe__llvm__main.erl?revision=473434&view=markup
|
|
* maint:
ErLLVM: Preserve precise BEAM tailcall semantics
observer: Fix change accum
Remove double calls
observer: Don't crash for late messages
observer: Optimize tv tab for many tables
|
|
The BEAM compiler chooses not to perform tailcall optimisations for some
calls in tail position, for example to some built-in functions. However,
when the ErLLVM HiPE backend is used, LLVM may choose to perform
tailcall optimisation on these calls, breaking the expected semantics.
To preserve the precise semantics exhibited by BEAM, the 'notail'
marker, present in LLVM since version 3.8, is added to call instructions
that BEAM has not turned into tail calls, which inhibits LLVM from
performing tail-call optimisation in turn.
|
|
Should probably be left for the HiPE team to fix
|
|
|
|
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 alignment of byte-sized constants
|
|
|
|
|
|
|
|
|
|
branch and alub overlap in their use cases, but the backends rely on
knowing that the result is unused in their lowering of branch. By
extending alub so that the destination is optional, it can fully replace
branch.
This simplifies rtl by reducing code duplication and the number of
instructions.
Also, in the x86 and arm backends, we can now use 'test' and
{'tst','mvn','teq'} to lower some alubs without destinations. This is
particularly good for x86, as sequences such as 'is_boxed' type tests
now get shorter (both from not needing a mov to copy the variable, but
also from the fact that 'testb' encodes shorter than 'andq').
|
|
# Conflicts:
# lib/hipe/llvm/hipe_rtl_to_llvm.erl
|
|
The constant ?WORD_WIDTH is renamed ?BITS_IN_WORD, and a new constant
?BITS_IN_BYTE is introduced.
Additionally, a bug in a currently unused case clause of
llvm_type_from_size/1 is fixed (the size of a word was hardcoded to 64
bits).
|
|
As of LLVM 3.9, the x86-call-frame-opt pass in LLVM's X86 backend causes
the stack descriptors to contain incorrect (or even negative) frame
sizes or root slot offsets.
This might cause LLVM-compiled modules to be rejected during loading
with a badarg exception in hipe_bifs:enter_sdecs/1 (which additionally
prints a "hipe_bifs_enter_sdesc_1: bad sdesc!" message to stderr), or it
might cause corruption or segmentation faults when walking stacks (f.ex.
during GC) containing frames compiled with ErLLVM.
As a workaround, we pass the -no-x86-call-frame-opt flag to llc when
the version is at least 3.9
|
|
ErLLVM was declaring atoms in the following manner:
@atom_ok = external constant i64
; Used inside a function like this
%var = ptrtoint i64* @atom_ok to i64
However, doing so makes LLVM think the `atom_ok` is 8-byte aligned,
since it refers to a i64 value. This resulted in LLVM occasionally
incorrectly optimising away type tests on atoms, causing incorrect
behaviour or even segfaults. One such case is in
bs_match_compiler:coverage_apply/2, in which an is_boxed test on a
literal atom was optimised away, causing the code to try and load the
"header" of an atom. This problem reproduces with LLVM versions 3.7
through 3.9.
By declaring atoms as i8 (byte) constants instead, LLVM no longer makes
these alignment assumptions, and the bug is fixed.
|
|
Seems to work either way, it just seem more correct
as all other 'bif' calls are 'not_remote'.
|
|
|
|
|
|
to not be transformed to local calls.
code_SUITE:uprade still fails if run with compile option
{hipe,to_llvm}
|
|
and correct the name of another, erroneously spelt, option in the process.
|
|
LLVM currently hard-codes these. Since it is desirable to be able to
change things like PCB layout without requiring a change to LLVM, we
export these as LLVM metadata, which can easily be used from LLVM to
make it independent of them.
|
|
Named types, except those for the records in the header files, have been
moved from elf*_format.hrl to elf_format.erl.
Also:
* Use lists instead of element/2-indexed tuples for ELF section and
symbol tables.
* Enable +warn_export_vars for hipe/llvm/ subdirectory and fix warning.
* Extract duplicated code in hipe_llvm module into help function
pp_dereference_type/3.
|
|
Since 3.7, LLVM sometimes generates SSE constants in a special constant
section with the requisite alignment (".rodata.cst16"). This broke
hipe_llvm since it assumed that all constants that were linked from the
text section were constants generated by hipe_llvm.
As this is the first time alignments larger than 8 have been required,
some small changes were required to hipe_consttab and
hipe_bifs:alloc_data/2. Note that hipe_bifs:alloc_data/2 still assumes
that erl_alloc will provide the requisite alignment.
|
|
This allows for much more robust interpretation of relocations, symbols
and sections in hipe_llvm_main, without the clunkiness of an abstract
interface between two internal modules that belong to the same subsystem
anyway.
|
|
|
|
|
|
The elf_format module was written in such a way that some of the
customisation to ELF-32 vs ELF-64 was made at compile-time and some of
it at run-time. As such it was not actually possible to read 32-bit
files with a module compiled for 64-bit support, or vice versa.
As the run-time selection uses some process dictionary ugliness, it was
removed, shifting all the customisation to be compile-time.
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
In case of function calls with arguments that are passed to the stack,
the frame size of corresponding stack descriptors needs to be reduced by
the number of stack arguments. This commit fixes a bug in this
adjustment which was caused by an incorrect check.
|
|
Do not rely on MFA name for the arity of functions, since closures have
an extra argument. Instead, just use the length of the arguments list.
|
|
|