Vendor import of llvm trunk r242221:
https://llvm.org/svn/llvm-project/llvm/trunk@242221
This commit is contained in:
parent
1a82d4c088
commit
ee8648bdac
4
.gitignore
vendored
4
.gitignore
vendored
@ -43,7 +43,9 @@ autoconf/autom4te.cache
|
||||
# Directories to ignore (do not add trailing '/'s, they skip symlinks).
|
||||
#==============================================================================#
|
||||
# External projects that are tracked independently.
|
||||
projects/*/
|
||||
projects/*
|
||||
!projects/*.*
|
||||
!projects/Makefile
|
||||
# Clang, which is tracked independently.
|
||||
tools/clang
|
||||
# LLDB, which is tracked independently.
|
||||
|
3
autoconf/config.guess
vendored
3
autoconf/config.guess
vendored
@ -810,6 +810,9 @@ EOF
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
*:MSYS*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msys
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
|
@ -371,14 +371,6 @@ def __init__(self, ptr):
|
||||
|
||||
self.expired = False
|
||||
|
||||
@CachedProperty
|
||||
def address(self):
|
||||
"""The address of this relocation, in long bytes."""
|
||||
if self.expired:
|
||||
raise Exception('Relocation instance has expired.')
|
||||
|
||||
return lib.LLVMGetRelocationAddress(self)
|
||||
|
||||
@CachedProperty
|
||||
def offset(self):
|
||||
"""The offset of this relocation, in long bytes."""
|
||||
@ -498,9 +490,6 @@ def register_library(library):
|
||||
library.LLVMGetSymbolSize.argtypes = [Symbol]
|
||||
library.LLVMGetSymbolSize.restype = c_uint64
|
||||
|
||||
library.LLVMGetRelocationAddress.argtypes = [c_object_p]
|
||||
library.LLVMGetRelocationAddress.restype = c_uint64
|
||||
|
||||
library.LLVMGetRelocationOffset.argtypes = [c_object_p]
|
||||
library.LLVMGetRelocationOffset.restype = c_uint64
|
||||
|
||||
|
@ -93,20 +93,9 @@ function(add_llvm_symbol_exports target_name export_file)
|
||||
else()
|
||||
set(native_export_file "${target_name}.def")
|
||||
|
||||
set(CAT "cat")
|
||||
set(export_file_nativeslashes ${export_file})
|
||||
if(WIN32 AND NOT CYGWIN AND NOT MSYS)
|
||||
set(CAT "type")
|
||||
# Convert ${export_file} to native format (backslashes) for "type"
|
||||
# Does not use file(TO_NATIVE_PATH) as it doesn't create a native
|
||||
# path but a build-system specific format (see CMake bug
|
||||
# http://public.kitware.com/Bug/print_bug_page.php?bug_id=5939 )
|
||||
string(REPLACE / \\ export_file_nativeslashes ${export_file})
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${native_export_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "EXPORTS" > ${native_export_file}
|
||||
COMMAND ${CAT} ${export_file_nativeslashes} >> ${native_export_file}
|
||||
COMMAND ${PYTHON_EXECUTABLE} -c "import sys;print(''.join(['EXPORTS\\n']+sys.stdin.readlines(),))"
|
||||
< ${export_file} > ${native_export_file}
|
||||
DEPENDS ${export_file}
|
||||
VERBATIM
|
||||
COMMENT "Creating export file for ${target_name}")
|
||||
@ -700,10 +689,18 @@ macro(add_llvm_external_project name)
|
||||
list(APPEND LLVM_IMPLICIT_PROJECT_IGNORE "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
|
||||
string(REPLACE "-" "_" nameUNDERSCORE ${name})
|
||||
string(TOUPPER ${nameUNDERSCORE} nameUPPER)
|
||||
set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}"
|
||||
CACHE PATH "Path to ${name} source directory")
|
||||
if (NOT ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR} STREQUAL ""
|
||||
AND EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}/CMakeLists.txt)
|
||||
#TODO: Remove this check in a few days once it has circulated through
|
||||
# buildbots and people's checkouts (cbieneman - July 14, 2015)
|
||||
if("${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
|
||||
unset(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR CACHE)
|
||||
endif()
|
||||
if(NOT LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR)
|
||||
set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${add_llvm_external_dir}")
|
||||
else()
|
||||
set(LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR
|
||||
CACHE PATH "Path to ${name} source directory")
|
||||
endif()
|
||||
if (EXISTS ${LLVM_EXTERNAL_${nameUPPER}_SOURCE_DIR}/CMakeLists.txt)
|
||||
option(LLVM_EXTERNAL_${nameUPPER}_BUILD
|
||||
"Whether to build ${name} as part of LLVM" ON)
|
||||
if (LLVM_EXTERNAL_${nameUPPER}_BUILD)
|
||||
|
@ -339,11 +339,11 @@ original context before code generation.
|
||||
|
||||
Catch handlers are called with a pointer to the handler itself as the first
|
||||
argument and a pointer to the parent function's stack frame as the second
|
||||
argument. The catch handler uses the `llvm.recoverframe
|
||||
<LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ to get a
|
||||
argument. The catch handler uses the `llvm.localrecover
|
||||
<LangRef.html#llvm-localescape-and-llvm-localrecover-intrinsics>`_ to get a
|
||||
pointer to a frame allocation block that is created in the parent frame using
|
||||
the `llvm.allocateframe
|
||||
<LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ intrinsic.
|
||||
the `llvm.localescape
|
||||
<LangRef.html#llvm-localescape-and-llvm-localrecover-intrinsics>`_ intrinsic.
|
||||
The ``WinEHPrepare`` pass will have created a structure definition for the
|
||||
contents of this block. The first two members of the structure will always be
|
||||
(1) a 32-bit integer that the runtime uses to track the exception state of the
|
||||
@ -520,12 +520,12 @@ action.
|
||||
A code of ``i32 1`` indicates a catch action, which expects three additional
|
||||
arguments. Different EH schemes give different meanings to the three arguments,
|
||||
but the first argument indicates whether the catch should fire, the second is
|
||||
the frameescape index of the exception object, and the third is the code to run
|
||||
the localescape index of the exception object, and the third is the code to run
|
||||
to catch the exception.
|
||||
|
||||
For Windows C++ exception handling, the first argument for a catch handler is a
|
||||
pointer to the RTTI type descriptor for the object to catch. The second
|
||||
argument is an index into the argument list of the ``llvm.frameescape`` call in
|
||||
argument is an index into the argument list of the ``llvm.localescape`` call in
|
||||
the main function. The exception object will be copied into the provided stack
|
||||
object. If the exception object is not required, this argument should be -1.
|
||||
The third argument is a pointer to a function implementing the catch. This
|
||||
|
827
docs/LangRef.rst
827
docs/LangRef.rst
@ -1326,6 +1326,14 @@ example:
|
||||
On an argument, this attribute indicates that the function does not write
|
||||
through this pointer argument, even though it may write to the memory that
|
||||
the pointer points to.
|
||||
``argmemonly``
|
||||
This attribute indicates that the only memory accesses inside function are
|
||||
loads and stores from objects pointed to by its pointer-typed arguments,
|
||||
with arbitrary offsets. Or in other words, all memory operations in the
|
||||
function can refer to memory only using pointers based on its function
|
||||
arguments.
|
||||
Note that ``argmemonly`` can be used together with ``readonly`` attribute
|
||||
in order to specify that function reads only from its arguments.
|
||||
``returns_twice``
|
||||
This attribute indicates that this function can return twice. The C
|
||||
``setjmp`` is an example of such a function. The compiler disables
|
||||
@ -1446,8 +1454,8 @@ The strings can contain any character by escaping non-printable
|
||||
characters. The escape sequence used is simply "\\xx" where "xx" is the
|
||||
two digit hex code for the number.
|
||||
|
||||
The inline asm code is simply printed to the machine code .s file when
|
||||
assembly code is generated.
|
||||
Note that the assembly string *must* be parseable by LLVM's integrated assembler
|
||||
(unless it is disabled), even when emitting a ``.s`` file.
|
||||
|
||||
.. _langref_datalayout:
|
||||
|
||||
@ -1837,8 +1845,8 @@ Fast-Math Flags
|
||||
|
||||
LLVM IR floating-point binary ops (:ref:`fadd <i_fadd>`,
|
||||
:ref:`fsub <i_fsub>`, :ref:`fmul <i_fmul>`, :ref:`fdiv <i_fdiv>`,
|
||||
:ref:`frem <i_frem>`) have the following flags that can be set to enable
|
||||
otherwise unsafe floating point operations
|
||||
:ref:`frem <i_frem>`, :ref:`fcmp <i_fcmp>`) have the following flags that can
|
||||
be set to enable otherwise unsafe floating point operations
|
||||
|
||||
``nnan``
|
||||
No NaNs - Allow optimizations to assume the arguments and result are not
|
||||
@ -2800,13 +2808,36 @@ Inline Assembler Expressions
|
||||
----------------------------
|
||||
|
||||
LLVM supports inline assembler expressions (as opposed to :ref:`Module-Level
|
||||
Inline Assembly <moduleasm>`) through the use of a special value. This
|
||||
value represents the inline assembler as a string (containing the
|
||||
instructions to emit), a list of operand constraints (stored as a
|
||||
string), a flag that indicates whether or not the inline asm expression
|
||||
has side effects, and a flag indicating whether the function containing
|
||||
the asm needs to align its stack conservatively. An example inline
|
||||
assembler expression is:
|
||||
Inline Assembly <moduleasm>`) through the use of a special value. This value
|
||||
represents the inline assembler as a template string (containing the
|
||||
instructions to emit), a list of operand constraints (stored as a string), a
|
||||
flag that indicates whether or not the inline asm expression has side effects,
|
||||
and a flag indicating whether the function containing the asm needs to align its
|
||||
stack conservatively.
|
||||
|
||||
The template string supports argument substitution of the operands using "``$``"
|
||||
followed by a number, to indicate substitution of the given register/memory
|
||||
location, as specified by the constraint string. "``${NUM:MODIFIER}``" may also
|
||||
be used, where ``MODIFIER`` is a target-specific annotation for how to print the
|
||||
operand (See :ref:`inline-asm-modifiers`).
|
||||
|
||||
A literal "``$``" may be included by using "``$$``" in the template. To include
|
||||
other special characters into the output, the usual "``\XX``" escapes may be
|
||||
used, just as in other strings. Note that after template substitution, the
|
||||
resulting assembly string is parsed by LLVM's integrated assembler unless it is
|
||||
disabled -- even when emitting a ``.s`` file -- and thus must contain assembly
|
||||
syntax known to LLVM.
|
||||
|
||||
LLVM's support for inline asm is modeled closely on the requirements of Clang's
|
||||
GCC-compatible inline-asm support. Thus, the feature-set and the constraint and
|
||||
modifier codes listed here are similar or identical to those in GCC's inline asm
|
||||
support. However, to be clear, the syntax of the template and constraint strings
|
||||
described here is *not* the same as the syntax accepted by GCC and Clang, and,
|
||||
while most constraint letters are passed through as-is by Clang, some get
|
||||
translated to other codes when converting from the C source to the LLVM
|
||||
assembly.
|
||||
|
||||
An example inline assembler expression is:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
@ -2852,6 +2883,596 @@ If multiple keywords appear the '``sideeffect``' keyword must come
|
||||
first, the '``alignstack``' keyword second and the '``inteldialect``'
|
||||
keyword last.
|
||||
|
||||
Inline Asm Constraint String
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The constraint list is a comma-separated string, each element containing one or
|
||||
more constraint codes.
|
||||
|
||||
For each element in the constraint list an appropriate register or memory
|
||||
operand will be chosen, and it will be made available to assembly template
|
||||
string expansion as ``$0`` for the first constraint in the list, ``$1`` for the
|
||||
second, etc.
|
||||
|
||||
There are three different types of constraints, which are distinguished by a
|
||||
prefix symbol in front of the constraint code: Output, Input, and Clobber. The
|
||||
constraints must always be given in that order: outputs first, then inputs, then
|
||||
clobbers. They cannot be intermingled.
|
||||
|
||||
There are also three different categories of constraint codes:
|
||||
|
||||
- Register constraint. This is either a register class, or a fixed physical
|
||||
register. This kind of constraint will allocate a register, and if necessary,
|
||||
bitcast the argument or result to the appropriate type.
|
||||
- Memory constraint. This kind of constraint is for use with an instruction
|
||||
taking a memory operand. Different constraints allow for different addressing
|
||||
modes used by the target.
|
||||
- Immediate value constraint. This kind of constraint is for an integer or other
|
||||
immediate value which can be rendered directly into an instruction. The
|
||||
various target-specific constraints allow the selection of a value in the
|
||||
proper range for the instruction you wish to use it with.
|
||||
|
||||
Output constraints
|
||||
""""""""""""""""""
|
||||
|
||||
Output constraints are specified by an "``=``" prefix (e.g. "``=r``"). This
|
||||
indicates that the assembly will write to this operand, and the operand will
|
||||
then be made available as a return value of the ``asm`` expression. Output
|
||||
constraints do not consume an argument from the call instruction. (Except, see
|
||||
below about indirect outputs).
|
||||
|
||||
Normally, it is expected that no output locations are written to by the assembly
|
||||
expression until *all* of the inputs have been read. As such, LLVM may assign
|
||||
the same register to an output and an input. If this is not safe (e.g. if the
|
||||
assembly contains two instructions, where the first writes to one output, and
|
||||
the second reads an input and writes to a second output), then the "``&``"
|
||||
modifier must be used (e.g. "``=&r``") to specify that the output is an
|
||||
"early-clobber" output. Marking an ouput as "early-clobber" ensures that LLVM
|
||||
will not use the same register for any inputs (other than an input tied to this
|
||||
output).
|
||||
|
||||
Input constraints
|
||||
"""""""""""""""""
|
||||
|
||||
Input constraints do not have a prefix -- just the constraint codes. Each input
|
||||
constraint will consume one argument from the call instruction. It is not
|
||||
permitted for the asm to write to any input register or memory location (unless
|
||||
that input is tied to an output). Note also that multiple inputs may all be
|
||||
assigned to the same register, if LLVM can determine that they necessarily all
|
||||
contain the same value.
|
||||
|
||||
Instead of providing a Constraint Code, input constraints may also "tie"
|
||||
themselves to an output constraint, by providing an integer as the constraint
|
||||
string. Tied inputs still consume an argument from the call instruction, and
|
||||
take up a position in the asm template numbering as is usual -- they will simply
|
||||
be constrained to always use the same register as the output they've been tied
|
||||
to. For example, a constraint string of "``=r,0``" says to assign a register for
|
||||
output, and use that register as an input as well (it being the 0'th
|
||||
constraint).
|
||||
|
||||
It is permitted to tie an input to an "early-clobber" output. In that case, no
|
||||
*other* input may share the same register as the input tied to the early-clobber
|
||||
(even when the other input has the same value).
|
||||
|
||||
You may only tie an input to an output which has a register constraint, not a
|
||||
memory constraint. Only a single input may be tied to an output.
|
||||
|
||||
There is also an "interesting" feature which deserves a bit of explanation: if a
|
||||
register class constraint allocates a register which is too small for the value
|
||||
type operand provided as input, the input value will be split into multiple
|
||||
registers, and all of them passed to the inline asm.
|
||||
|
||||
However, this feature is often not as useful as you might think.
|
||||
|
||||
Firstly, the registers are *not* guaranteed to be consecutive. So, on those
|
||||
architectures that have instructions which operate on multiple consecutive
|
||||
instructions, this is not an appropriate way to support them. (e.g. the 32-bit
|
||||
SparcV8 has a 64-bit load, which instruction takes a single 32-bit register. The
|
||||
hardware then loads into both the named register, and the next register. This
|
||||
feature of inline asm would not be useful to support that.)
|
||||
|
||||
A few of the targets provide a template string modifier allowing explicit access
|
||||
to the second register of a two-register operand (e.g. MIPS ``L``, ``M``, and
|
||||
``D``). On such an architecture, you can actually access the second allocated
|
||||
register (yet, still, not any subsequent ones). But, in that case, you're still
|
||||
probably better off simply splitting the value into two separate operands, for
|
||||
clarity. (e.g. see the description of the ``A`` constraint on X86, which,
|
||||
despite existing only for use with this feature, is not really a good idea to
|
||||
use)
|
||||
|
||||
Indirect inputs and outputs
|
||||
"""""""""""""""""""""""""""
|
||||
|
||||
Indirect output or input constraints can be specified by the "``*``" modifier
|
||||
(which goes after the "``=``" in case of an output). This indicates that the asm
|
||||
will write to or read from the contents of an *address* provided as an input
|
||||
argument. (Note that in this way, indirect outputs act more like an *input* than
|
||||
an output: just like an input, they consume an argument of the call expression,
|
||||
rather than producing a return value. An indirect output constraint is an
|
||||
"output" only in that the asm is expected to write to the contents of the input
|
||||
memory location, instead of just read from it).
|
||||
|
||||
This is most typically used for memory constraint, e.g. "``=*m``", to pass the
|
||||
address of a variable as a value.
|
||||
|
||||
It is also possible to use an indirect *register* constraint, but only on output
|
||||
(e.g. "``=*r``"). This will cause LLVM to allocate a register for an output
|
||||
value normally, and then, separately emit a store to the address provided as
|
||||
input, after the provided inline asm. (It's not clear what value this
|
||||
functionality provides, compared to writing the store explicitly after the asm
|
||||
statement, and it can only produce worse code, since it bypasses many
|
||||
optimization passes. I would recommend not using it.)
|
||||
|
||||
|
||||
Clobber constraints
|
||||
"""""""""""""""""""
|
||||
|
||||
A clobber constraint is indicated by a "``~``" prefix. A clobber does not
|
||||
consume an input operand, nor generate an output. Clobbers cannot use any of the
|
||||
general constraint code letters -- they may use only explicit register
|
||||
constraints, e.g. "``~{eax}``". The one exception is that a clobber string of
|
||||
"``~{memory}``" indicates that the assembly writes to arbitrary undeclared
|
||||
memory locations -- not only the memory pointed to by a declared indirect
|
||||
output.
|
||||
|
||||
|
||||
Constraint Codes
|
||||
""""""""""""""""
|
||||
After a potential prefix comes constraint code, or codes.
|
||||
|
||||
A Constraint Code is either a single letter (e.g. "``r``"), a "``^``" character
|
||||
followed by two letters (e.g. "``^wc``"), or "``{``" register-name "``}``"
|
||||
(e.g. "``{eax}``").
|
||||
|
||||
The one and two letter constraint codes are typically chosen to be the same as
|
||||
GCC's constraint codes.
|
||||
|
||||
A single constraint may include one or more than constraint code in it, leaving
|
||||
it up to LLVM to choose which one to use. This is included mainly for
|
||||
compatibility with the translation of GCC inline asm coming from clang.
|
||||
|
||||
There are two ways to specify alternatives, and either or both may be used in an
|
||||
inline asm constraint list:
|
||||
|
||||
1) Append the codes to each other, making a constraint code set. E.g. "``im``"
|
||||
or "``{eax}m``". This means "choose any of the options in the set". The
|
||||
choice of constraint is made independently for each constraint in the
|
||||
constraint list.
|
||||
|
||||
2) Use "``|``" between constraint code sets, creating alternatives. Every
|
||||
constraint in the constraint list must have the same number of alternative
|
||||
sets. With this syntax, the same alternative in *all* of the items in the
|
||||
constraint list will be chosen together.
|
||||
|
||||
Putting those together, you might have a two operand constraint string like
|
||||
``"rm|r,ri|rm"``. This indicates that if operand 0 is ``r`` or ``m``, then
|
||||
operand 1 may be one of ``r`` or ``i``. If operand 0 is ``r``, then operand 1
|
||||
may be one of ``r`` or ``m``. But, operand 0 and 1 cannot both be of type m.
|
||||
|
||||
However, the use of either of the alternatives features is *NOT* recommended, as
|
||||
LLVM is not able to make an intelligent choice about which one to use. (At the
|
||||
point it currently needs to choose, not enough information is available to do so
|
||||
in a smart way.) Thus, it simply tries to make a choice that's most likely to
|
||||
compile, not one that will be optimal performance. (e.g., given "``rm``", it'll
|
||||
always choose to use memory, not registers). And, if given multiple registers,
|
||||
or multiple register classes, it will simply choose the first one. (In fact, it
|
||||
doesn't currently even ensure explicitly specified physical registers are
|
||||
unique, so specifying multiple physical registers as alternatives, like
|
||||
``{r11}{r12},{r11}{r12}``, will assign r11 to both operands, not at all what was
|
||||
intended.)
|
||||
|
||||
Supported Constraint Code List
|
||||
""""""""""""""""""""""""""""""
|
||||
|
||||
The constraint codes are, in general, expected to behave the same way they do in
|
||||
GCC. LLVM's support is often implemented on an 'as-needed' basis, to support C
|
||||
inline asm code which was supported by GCC. A mismatch in behavior between LLVM
|
||||
and GCC likely indicates a bug in LLVM.
|
||||
|
||||
Some constraint codes are typically supported by all targets:
|
||||
|
||||
- ``r``: A register in the target's general purpose register class.
|
||||
- ``m``: A memory address operand. It is target-specific what addressing modes
|
||||
are supported, typical examples are register, or register + register offset,
|
||||
or register + immediate offset (of some target-specific size).
|
||||
- ``i``: An integer constant (of target-specific width). Allows either a simple
|
||||
immediate, or a relocatable value.
|
||||
- ``n``: An integer constant -- *not* including relocatable values.
|
||||
- ``s``: An integer constant, but allowing *only* relocatable values.
|
||||
- ``X``: Allows an operand of any kind, no constraint whatsoever. Typically
|
||||
useful to pass a label for an asm branch or call.
|
||||
|
||||
.. FIXME: but that surely isn't actually okay to jump out of an asm
|
||||
block without telling llvm about the control transfer???)
|
||||
|
||||
- ``{register-name}``: Requires exactly the named physical register.
|
||||
|
||||
Other constraints are target-specific:
|
||||
|
||||
AArch64:
|
||||
|
||||
- ``z``: An immediate integer 0. Outputs ``WZR`` or ``XZR``, as appropriate.
|
||||
- ``I``: An immediate integer valid for an ``ADD`` or ``SUB`` instruction,
|
||||
i.e. 0 to 4095 with optional shift by 12.
|
||||
- ``J``: An immediate integer that, when negated, is valid for an ``ADD`` or
|
||||
``SUB`` instruction, i.e. -1 to -4095 with optional left shift by 12.
|
||||
- ``K``: An immediate integer that is valid for the 'bitmask immediate 32' of a
|
||||
logical instruction like ``AND``, ``EOR``, or ``ORR`` with a 32-bit register.
|
||||
- ``L``: An immediate integer that is valid for the 'bitmask immediate 64' of a
|
||||
logical instruction like ``AND``, ``EOR``, or ``ORR`` with a 64-bit register.
|
||||
- ``M``: An immediate integer for use with the ``MOV`` assembly alias on a
|
||||
32-bit register. This is a superset of ``K``: in addition to the bitmask
|
||||
immediate, also allows immediate integers which can be loaded with a single
|
||||
``MOVZ`` or ``MOVL`` instruction.
|
||||
- ``N``: An immediate integer for use with the ``MOV`` assembly alias on a
|
||||
64-bit register. This is a superset of ``L``.
|
||||
- ``Q``: Memory address operand must be in a single register (no
|
||||
offsets). (However, LLVM currently does this for the ``m`` constraint as
|
||||
well.)
|
||||
- ``r``: A 32 or 64-bit integer register (W* or X*).
|
||||
- ``w``: A 32, 64, or 128-bit floating-point/SIMD register.
|
||||
- ``x``: A lower 128-bit floating-point/SIMD register (``V0`` to ``V15``).
|
||||
|
||||
AMDGPU:
|
||||
|
||||
- ``r``: A 32 or 64-bit integer register.
|
||||
- ``[0-9]v``: The 32-bit VGPR register, number 0-9.
|
||||
- ``[0-9]s``: The 32-bit SGPR register, number 0-9.
|
||||
|
||||
|
||||
All ARM modes:
|
||||
|
||||
- ``Q``, ``Um``, ``Un``, ``Uq``, ``Us``, ``Ut``, ``Uv``, ``Uy``: Memory address
|
||||
operand. Treated the same as operand ``m``, at the moment.
|
||||
|
||||
ARM and ARM's Thumb2 mode:
|
||||
|
||||
- ``j``: An immediate integer between 0 and 65535 (valid for ``MOVW``)
|
||||
- ``I``: An immediate integer valid for a data-processing instruction.
|
||||
- ``J``: An immediate integer between -4095 and 4095.
|
||||
- ``K``: An immediate integer whose bitwise inverse is valid for a
|
||||
data-processing instruction. (Can be used with template modifier "``B``" to
|
||||
print the inverted value).
|
||||
- ``L``: An immediate integer whose negation is valid for a data-processing
|
||||
instruction. (Can be used with template modifier "``n``" to print the negated
|
||||
value).
|
||||
- ``M``: A power of two or a integer between 0 and 32.
|
||||
- ``N``: Invalid immediate constraint.
|
||||
- ``O``: Invalid immediate constraint.
|
||||
- ``r``: A general-purpose 32-bit integer register (``r0-r15``).
|
||||
- ``l``: In Thumb2 mode, low 32-bit GPR registers (``r0-r7``). In ARM mode, same
|
||||
as ``r``.
|
||||
- ``h``: In Thumb2 mode, a high 32-bit GPR register (``r8-r15``). In ARM mode,
|
||||
invalid.
|
||||
- ``w``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s31``,
|
||||
``d0-d31``, or ``q0-q15``.
|
||||
- ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``,
|
||||
``d0-d7``, or ``q0-q3``.
|
||||
- ``t``: A floating-point/SIMD register, only supports 32-bit values:
|
||||
``s0-s31``.
|
||||
|
||||
ARM's Thumb1 mode:
|
||||
|
||||
- ``I``: An immediate integer between 0 and 255.
|
||||
- ``J``: An immediate integer between -255 and -1.
|
||||
- ``K``: An immediate integer between 0 and 255, with optional left-shift by
|
||||
some amount.
|
||||
- ``L``: An immediate integer between -7 and 7.
|
||||
- ``M``: An immediate integer which is a multiple of 4 between 0 and 1020.
|
||||
- ``N``: An immediate integer between 0 and 31.
|
||||
- ``O``: An immediate integer which is a multiple of 4 between -508 and 508.
|
||||
- ``r``: A low 32-bit GPR register (``r0-r7``).
|
||||
- ``l``: A low 32-bit GPR register (``r0-r7``).
|
||||
- ``h``: A high GPR register (``r0-r7``).
|
||||
- ``w``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s31``,
|
||||
``d0-d31``, or ``q0-q15``.
|
||||
- ``x``: A 32, 64, or 128-bit floating-point/SIMD register: ``s0-s15``,
|
||||
``d0-d7``, or ``q0-q3``.
|
||||
- ``t``: A floating-point/SIMD register, only supports 32-bit values:
|
||||
``s0-s31``.
|
||||
|
||||
|
||||
Hexagon:
|
||||
|
||||
- ``o``, ``v``: A memory address operand, treated the same as constraint ``m``,
|
||||
at the moment.
|
||||
- ``r``: A 32 or 64-bit register.
|
||||
|
||||
MSP430:
|
||||
|
||||
- ``r``: An 8 or 16-bit register.
|
||||
|
||||
MIPS:
|
||||
|
||||
- ``I``: An immediate signed 16-bit integer.
|
||||
- ``J``: An immediate integer zero.
|
||||
- ``K``: An immediate unsigned 16-bit integer.
|
||||
- ``L``: An immediate 32-bit integer, where the lower 16 bits are 0.
|
||||
- ``N``: An immediate integer between -65535 and -1.
|
||||
- ``O``: An immediate signed 15-bit integer.
|
||||
- ``P``: An immediate integer between 1 and 65535.
|
||||
- ``m``: A memory address operand. In MIPS-SE mode, allows a base address
|
||||
register plus 16-bit immediate offset. In MIPS mode, just a base register.
|
||||
- ``R``: A memory address operand. In MIPS-SE mode, allows a base address
|
||||
register plus a 9-bit signed offset. In MIPS mode, the same as constraint
|
||||
``m``.
|
||||
- ``ZC``: A memory address operand, suitable for use in a ``pref``, ``ll``, or
|
||||
``sc`` instruction on the given subtarget (details vary).
|
||||
- ``r``, ``d``, ``y``: A 32 or 64-bit GPR register.
|
||||
- ``f``: A 32 or 64-bit FPU register (``F0-F31``), or a 128-bit MSA register
|
||||
(``W0-W31``). In the case of MSA registers, it is recommended to use the ``w``
|
||||
argument modifier for compatibility with GCC.
|
||||
- ``c``: A 32-bit or 64-bit GPR register suitable for indirect jump (always
|
||||
``25``).
|
||||
- ``l``: The ``lo`` register, 32 or 64-bit.
|
||||
- ``x``: Invalid.
|
||||
|
||||
NVPTX:
|
||||
|
||||
- ``b``: A 1-bit integer register.
|
||||
- ``c`` or ``h``: A 16-bit integer register.
|
||||
- ``r``: A 32-bit integer register.
|
||||
- ``l`` or ``N``: A 64-bit integer register.
|
||||
- ``f``: A 32-bit float register.
|
||||
- ``d``: A 64-bit float register.
|
||||
|
||||
|
||||
PowerPC:
|
||||
|
||||
- ``I``: An immediate signed 16-bit integer.
|
||||
- ``J``: An immediate unsigned 16-bit integer, shifted left 16 bits.
|
||||
- ``K``: An immediate unsigned 16-bit integer.
|
||||
- ``L``: An immediate signed 16-bit integer, shifted left 16 bits.
|
||||
- ``M``: An immediate integer greater than 31.
|
||||
- ``N``: An immediate integer that is an exact power of 2.
|
||||
- ``O``: The immediate integer constant 0.
|
||||
- ``P``: An immediate integer constant whose negation is a signed 16-bit
|
||||
constant.
|
||||
- ``es``, ``o``, ``Q``, ``Z``, ``Zy``: A memory address operand, currently
|
||||
treated the same as ``m``.
|
||||
- ``r``: A 32 or 64-bit integer register.
|
||||
- ``b``: A 32 or 64-bit integer register, excluding ``R0`` (that is:
|
||||
``R1-R31``).
|
||||
- ``f``: A 32 or 64-bit float register (``F0-F31``), or when QPX is enabled, a
|
||||
128 or 256-bit QPX register (``Q0-Q31``; aliases the ``F`` registers).
|
||||
- ``v``: For ``4 x f32`` or ``4 x f64`` types, when QPX is enabled, a
|
||||
128 or 256-bit QPX register (``Q0-Q31``), otherwise a 128-bit
|
||||
altivec vector register (``V0-V31``).
|
||||
|
||||
.. FIXME: is this a bug that v accepts QPX registers? I think this
|
||||
is supposed to only use the altivec vector registers?
|
||||
|
||||
- ``y``: Condition register (``CR0-CR7``).
|
||||
- ``wc``: An individual CR bit in a CR register.
|
||||
- ``wa``, ``wd``, ``wf``: Any 128-bit VSX vector register, from the full VSX
|
||||
register set (overlapping both the floating-point and vector register files).
|
||||
- ``ws``: A 32 or 64-bit floating point register, from the full VSX register
|
||||
set.
|
||||
|
||||
Sparc:
|
||||
|
||||
- ``I``: An immediate 13-bit signed integer.
|
||||
- ``r``: A 32-bit integer register.
|
||||
|
||||
SystemZ:
|
||||
|
||||
- ``I``: An immediate unsigned 8-bit integer.
|
||||
- ``J``: An immediate unsigned 12-bit integer.
|
||||
- ``K``: An immediate signed 16-bit integer.
|
||||
- ``L``: An immediate signed 20-bit integer.
|
||||
- ``M``: An immediate integer 0x7fffffff.
|
||||
- ``Q``, ``R``, ``S``, ``T``: A memory address operand, treated the same as
|
||||
``m``, at the moment.
|
||||
- ``r`` or ``d``: A 32, 64, or 128-bit integer register.
|
||||
- ``a``: A 32, 64, or 128-bit integer address register (excludes R0, which in an
|
||||
address context evaluates as zero).
|
||||
- ``h``: A 32-bit value in the high part of a 64bit data register
|
||||
(LLVM-specific)
|
||||
- ``f``: A 32, 64, or 128-bit floating point register.
|
||||
|
||||
X86:
|
||||
|
||||
- ``I``: An immediate integer between 0 and 31.
|
||||
- ``J``: An immediate integer between 0 and 64.
|
||||
- ``K``: An immediate signed 8-bit integer.
|
||||
- ``L``: An immediate integer, 0xff or 0xffff or (in 64-bit mode only)
|
||||
0xffffffff.
|
||||
- ``M``: An immediate integer between 0 and 3.
|
||||
- ``N``: An immediate unsigned 8-bit integer.
|
||||
- ``O``: An immediate integer between 0 and 127.
|
||||
- ``e``: An immediate 32-bit signed integer.
|
||||
- ``Z``: An immediate 32-bit unsigned integer.
|
||||
- ``o``, ``v``: Treated the same as ``m``, at the moment.
|
||||
- ``q``: An 8, 16, 32, or 64-bit register which can be accessed as an 8-bit
|
||||
``l`` integer register. On X86-32, this is the ``a``, ``b``, ``c``, and ``d``
|
||||
registers, and on X86-64, it is all of the integer registers.
|
||||
- ``Q``: An 8, 16, 32, or 64-bit register which can be accessed as an 8-bit
|
||||
``h`` integer register. This is the ``a``, ``b``, ``c``, and ``d`` registers.
|
||||
- ``r`` or ``l``: An 8, 16, 32, or 64-bit integer register.
|
||||
- ``R``: An 8, 16, 32, or 64-bit "legacy" integer register -- one which has
|
||||
existed since i386, and can be accessed without the REX prefix.
|
||||
- ``f``: A 32, 64, or 80-bit '387 FPU stack pseudo-register.
|
||||
- ``y``: A 64-bit MMX register, if MMX is enabled.
|
||||
- ``x``: If SSE is enabled: a 32 or 64-bit scalar operand, or 128-bit vector
|
||||
operand in a SSE register. If AVX is also enabled, can also be a 256-bit
|
||||
vector operand in an AVX register. If AVX-512 is also enabled, can also be a
|
||||
512-bit vector operand in an AVX512 register, Otherwise, an error.
|
||||
- ``Y``: The same as ``x``, if *SSE2* is enabled, otherwise an error.
|
||||
- ``A``: Special case: allocates EAX first, then EDX, for a single operand (in
|
||||
32-bit mode, a 64-bit integer operand will get split into two registers). It
|
||||
is not recommended to use this constraint, as in 64-bit mode, the 64-bit
|
||||
operand will get allocated only to RAX -- if two 32-bit operands are needed,
|
||||
you're better off splitting it yourself, before passing it to the asm
|
||||
statement.
|
||||
|
||||
XCore:
|
||||
|
||||
- ``r``: A 32-bit integer register.
|
||||
|
||||
|
||||
.. _inline-asm-modifiers:
|
||||
|
||||
Asm template argument modifiers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In the asm template string, modifiers can be used on the operand reference, like
|
||||
"``${0:n}``".
|
||||
|
||||
The modifiers are, in general, expected to behave the same way they do in
|
||||
GCC. LLVM's support is often implemented on an 'as-needed' basis, to support C
|
||||
inline asm code which was supported by GCC. A mismatch in behavior between LLVM
|
||||
and GCC likely indicates a bug in LLVM.
|
||||
|
||||
Target-independent:
|
||||
|
||||
- ``c``: Print an immediate integer constant unadorned, without
|
||||
the target-specific immediate punctuation (e.g. no ``$`` prefix).
|
||||
- ``n``: Negate and print immediate integer constant unadorned, without the
|
||||
target-specific immediate punctuation (e.g. no ``$`` prefix).
|
||||
- ``l``: Print as an unadorned label, without the target-specific label
|
||||
punctuation (e.g. no ``$`` prefix).
|
||||
|
||||
AArch64:
|
||||
|
||||
- ``w``: Print a GPR register with a ``w*`` name instead of ``x*`` name. E.g.,
|
||||
instead of ``x30``, print ``w30``.
|
||||
- ``x``: Print a GPR register with a ``x*`` name. (this is the default, anyhow).
|
||||
- ``b``, ``h``, ``s``, ``d``, ``q``: Print a floating-point/SIMD register with a
|
||||
``b*``, ``h*``, ``s*``, ``d*``, or ``q*`` name, rather than the default of
|
||||
``v*``.
|
||||
|
||||
AMDGPU:
|
||||
|
||||
- ``r``: No effect.
|
||||
|
||||
ARM:
|
||||
|
||||
- ``a``: Print an operand as an address (with ``[`` and ``]`` surrounding a
|
||||
register).
|
||||
- ``P``: No effect.
|
||||
- ``q``: No effect.
|
||||
- ``y``: Print a VFP single-precision register as an indexed double (e.g. print
|
||||
as ``d4[1]`` instead of ``s9``)
|
||||
- ``B``: Bitwise invert and print an immediate integer constant without ``#``
|
||||
prefix.
|
||||
- ``L``: Print the low 16-bits of an immediate integer constant.
|
||||
- ``M``: Print as a register set suitable for ldm/stm. Also prints *all*
|
||||
register operands subsequent to the specified one (!), so use carefully.
|
||||
- ``Q``: Print the low-order register of a register-pair, or the low-order
|
||||
register of a two-register operand.
|
||||
- ``R``: Print the high-order register of a register-pair, or the high-order
|
||||
register of a two-register operand.
|
||||
- ``H``: Print the second register of a register-pair. (On a big-endian system,
|
||||
``H`` is equivalent to ``Q``, and on little-endian system, ``H`` is equivalent
|
||||
to ``R``.)
|
||||
|
||||
.. FIXME: H doesn't currently support printing the second register
|
||||
of a two-register operand.
|
||||
|
||||
- ``e``: Print the low doubleword register of a NEON quad register.
|
||||
- ``f``: Print the high doubleword register of a NEON quad register.
|
||||
- ``m``: Print the base register of a memory operand without the ``[`` and ``]``
|
||||
adornment.
|
||||
|
||||
Hexagon:
|
||||
|
||||
- ``L``: Print the second register of a two-register operand. Requires that it
|
||||
has been allocated consecutively to the first.
|
||||
|
||||
.. FIXME: why is it restricted to consecutive ones? And there's
|
||||
nothing that ensures that happens, is there?
|
||||
|
||||
- ``I``: Print the letter 'i' if the operand is an integer constant, otherwise
|
||||
nothing. Used to print 'addi' vs 'add' instructions.
|
||||
|
||||
MSP430:
|
||||
|
||||
No additional modifiers.
|
||||
|
||||
MIPS:
|
||||
|
||||
- ``X``: Print an immediate integer as hexadecimal
|
||||
- ``x``: Print the low 16 bits of an immediate integer as hexadecimal.
|
||||
- ``d``: Print an immediate integer as decimal.
|
||||
- ``m``: Subtract one and print an immediate integer as decimal.
|
||||
- ``z``: Print $0 if an immediate zero, otherwise print normally.
|
||||
- ``L``: Print the low-order register of a two-register operand, or prints the
|
||||
address of the low-order word of a double-word memory operand.
|
||||
|
||||
.. FIXME: L seems to be missing memory operand support.
|
||||
|
||||
- ``M``: Print the high-order register of a two-register operand, or prints the
|
||||
address of the high-order word of a double-word memory operand.
|
||||
|
||||
.. FIXME: M seems to be missing memory operand support.
|
||||
|
||||
- ``D``: Print the second register of a two-register operand, or prints the
|
||||
second word of a double-word memory operand. (On a big-endian system, ``D`` is
|
||||
equivalent to ``L``, and on little-endian system, ``D`` is equivalent to
|
||||
``M``.)
|
||||
- ``w``: No effect. Provided for compatibility with GCC which requires this
|
||||
modifier in order to print MSA registers (``W0-W31``) with the ``f``
|
||||
constraint.
|
||||
|
||||
NVPTX:
|
||||
|
||||
- ``r``: No effect.
|
||||
|
||||
PowerPC:
|
||||
|
||||
- ``L``: Print the second register of a two-register operand. Requires that it
|
||||
has been allocated consecutively to the first.
|
||||
|
||||
.. FIXME: why is it restricted to consecutive ones? And there's
|
||||
nothing that ensures that happens, is there?
|
||||
|
||||
- ``I``: Print the letter 'i' if the operand is an integer constant, otherwise
|
||||
nothing. Used to print 'addi' vs 'add' instructions.
|
||||
- ``y``: For a memory operand, prints formatter for a two-register X-form
|
||||
instruction. (Currently always prints ``r0,OPERAND``).
|
||||
- ``U``: Prints 'u' if the memory operand is an update form, and nothing
|
||||
otherwise. (NOTE: LLVM does not support update form, so this will currently
|
||||
always print nothing)
|
||||
- ``X``: Prints 'x' if the memory operand is an indexed form. (NOTE: LLVM does
|
||||
not support indexed form, so this will currently always print nothing)
|
||||
|
||||
Sparc:
|
||||
|
||||
- ``r``: No effect.
|
||||
|
||||
SystemZ:
|
||||
|
||||
SystemZ implements only ``n``, and does *not* support any of the other
|
||||
target-independent modifiers.
|
||||
|
||||
X86:
|
||||
|
||||
- ``c``: Print an unadorned integer or symbol name. (The latter is
|
||||
target-specific behavior for this typically target-independent modifier).
|
||||
- ``A``: Print a register name with a '``*``' before it.
|
||||
- ``b``: Print an 8-bit register name (e.g. ``al``); do nothing on a memory
|
||||
operand.
|
||||
- ``h``: Print the upper 8-bit register name (e.g. ``ah``); do nothing on a
|
||||
memory operand.
|
||||
- ``w``: Print the 16-bit register name (e.g. ``ax``); do nothing on a memory
|
||||
operand.
|
||||
- ``k``: Print the 32-bit register name (e.g. ``eax``); do nothing on a memory
|
||||
operand.
|
||||
- ``q``: Print the 64-bit register name (e.g. ``rax``), if 64-bit registers are
|
||||
available, otherwise the 32-bit register name; do nothing on a memory operand.
|
||||
- ``n``: Negate and print an unadorned integer, or, for operands other than an
|
||||
immediate integer (e.g. a relocatable symbol expression), print a '-' before
|
||||
the operand. (The behavior for relocatable symbol expressions is a
|
||||
target-specific behavior for this typically target-independent modifier)
|
||||
- ``H``: Print a memory reference with additional offset +8.
|
||||
- ``P``: Print a memory reference or operand for use as the argument of a call
|
||||
instruction. (E.g. omit ``(rip)``, even though it's PC-relative.)
|
||||
|
||||
XCore:
|
||||
|
||||
No additional modifiers.
|
||||
|
||||
|
||||
Inline Asm Metadata
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -6108,7 +6729,8 @@ Overview:
|
||||
|
||||
The '``getelementptr``' instruction is used to get the address of a
|
||||
subelement of an :ref:`aggregate <t_aggregate>` data structure. It performs
|
||||
address calculation only and does not access memory.
|
||||
address calculation only and does not access memory. The instruction can also
|
||||
be used to calculate a vector of such addresses.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
@ -6234,12 +6856,61 @@ Example:
|
||||
; yields i32*:iptr
|
||||
%iptr = getelementptr [10 x i32], [10 x i32]* @arr, i16 0, i16 0
|
||||
|
||||
In cases where the pointer argument is a vector of pointers, each index
|
||||
must be a vector with the same number of elements. For example:
|
||||
Vector of pointers:
|
||||
"""""""""""""""""""
|
||||
|
||||
The ``getelementptr`` returns a vector of pointers, instead of a single address,
|
||||
when one or more of its arguments is a vector. In such cases, all vector
|
||||
arguments should have the same number of elements, and every scalar argument
|
||||
will be effectively broadcast into a vector during address calculation.
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
%A = getelementptr i8, <4 x i8*> %ptrs, <4 x i64> %offsets,
|
||||
; All arguments are vectors:
|
||||
; A[i] = ptrs[i] + offsets[i]*sizeof(i8)
|
||||
%A = getelementptr i8, <4 x i8*> %ptrs, <4 x i64> %offsets
|
||||
|
||||
; Add the same scalar offset to each pointer of a vector:
|
||||
; A[i] = ptrs[i] + offset*sizeof(i8)
|
||||
%A = getelementptr i8, <4 x i8*> %ptrs, i64 %offset
|
||||
|
||||
; Add distinct offsets to the same pointer:
|
||||
; A[i] = ptr + offsets[i]*sizeof(i8)
|
||||
%A = getelementptr i8, i8* %ptr, <4 x i64> %offsets
|
||||
|
||||
; In all cases described above the type of the result is <4 x i8*>
|
||||
|
||||
The two following instructions are equivalent:
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
getelementptr %struct.ST, <4 x %struct.ST*> %s, <4 x i64> %ind1,
|
||||
<4 x i32> <i32 2, i32 2, i32 2, i32 2>,
|
||||
<4 x i32> <i32 1, i32 1, i32 1, i32 1>,
|
||||
<4 x i32> %ind4,
|
||||
<4 x i64> <i64 13, i64 13, i64 13, i64 13>
|
||||
|
||||
getelementptr %struct.ST, <4 x %struct.ST*> %s, <4 x i64> %ind1,
|
||||
i32 2, i32 1, <4 x i32> %ind4, i64 13
|
||||
|
||||
Let's look at the C code, where the vector version of ``getelementptr``
|
||||
makes sense:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Let's assume that we vectorize the following loop:
|
||||
double *A, B; int *C;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
A[i] = B[C[i]];
|
||||
}
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
; get pointers for 8 elements from array B
|
||||
%ptrs = getelementptr double, double* %B, <8 x i32> %C
|
||||
; load 8 elements from array B into A
|
||||
%A = call <8 x double> @llvm.masked.gather.v8f64(<8 x double*> %ptrs,
|
||||
i32 8, <8 x i1> %mask, <8 x double> %passthru)
|
||||
|
||||
Conversion Operations
|
||||
---------------------
|
||||
@ -6913,7 +7584,7 @@ Syntax:
|
||||
|
||||
::
|
||||
|
||||
<result> = fcmp <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
|
||||
<result> = fcmp [fast-math flags]* <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
@ -6996,6 +7667,15 @@ always yields an :ref:`i1 <t_integer>` result, as follows:
|
||||
#. ``uno``: yields ``true`` if either operand is a QNAN.
|
||||
#. ``true``: always yields ``true``, regardless of operands.
|
||||
|
||||
The ``fcmp`` instruction can also optionally take any number of
|
||||
:ref:`fast-math flags <fastmath>`, which are optimization hints to enable
|
||||
otherwise unsafe floating point optimizations.
|
||||
|
||||
Any set of fast-math flags are legal on an ``fcmp`` instruction, but the
|
||||
only flags that have any effect on its semantics are those that allow
|
||||
assumptions to be made about the values of input arguments; namely
|
||||
``nnan``, ``ninf``, and ``nsz``. See :ref:`fastmath` for more information.
|
||||
|
||||
Example:
|
||||
""""""""
|
||||
|
||||
@ -7780,7 +8460,7 @@ Note that calling this intrinsic does not prevent function inlining or
|
||||
other aggressive transformations, so the value returned may not be that
|
||||
of the obvious source-language caller.
|
||||
|
||||
'``llvm.frameescape``' and '``llvm.framerecover``' Intrinsics
|
||||
'``llvm.localescape``' and '``llvm.localrecover``' Intrinsics
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
@ -7788,49 +8468,47 @@ Syntax:
|
||||
|
||||
::
|
||||
|
||||
declare void @llvm.frameescape(...)
|
||||
declare i8* @llvm.framerecover(i8* %func, i8* %fp, i32 %idx)
|
||||
declare void @llvm.localescape(...)
|
||||
declare i8* @llvm.localrecover(i8* %func, i8* %fp, i32 %idx)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.frameescape``' intrinsic escapes offsets of a collection of static
|
||||
allocas, and the '``llvm.framerecover``' intrinsic applies those offsets to a
|
||||
The '``llvm.localescape``' intrinsic escapes offsets of a collection of static
|
||||
allocas, and the '``llvm.localrecover``' intrinsic applies those offsets to a
|
||||
live frame pointer to recover the address of the allocation. The offset is
|
||||
computed during frame layout of the caller of ``llvm.frameescape``.
|
||||
computed during frame layout of the caller of ``llvm.localescape``.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
|
||||
All arguments to '``llvm.frameescape``' must be pointers to static allocas or
|
||||
casts of static allocas. Each function can only call '``llvm.frameescape``'
|
||||
All arguments to '``llvm.localescape``' must be pointers to static allocas or
|
||||
casts of static allocas. Each function can only call '``llvm.localescape``'
|
||||
once, and it can only do so from the entry block.
|
||||
|
||||
The ``func`` argument to '``llvm.framerecover``' must be a constant
|
||||
The ``func`` argument to '``llvm.localrecover``' must be a constant
|
||||
bitcasted pointer to a function defined in the current module. The code
|
||||
generator cannot determine the frame allocation offset of functions defined in
|
||||
other modules.
|
||||
|
||||
The ``fp`` argument to '``llvm.framerecover``' must be a frame
|
||||
pointer of a call frame that is currently live. The return value of
|
||||
'``llvm.frameaddress``' is one way to produce such a value, but most platforms
|
||||
also expose the frame pointer through stack unwinding mechanisms.
|
||||
The ``fp`` argument to '``llvm.localrecover``' must be a frame pointer of a
|
||||
call frame that is currently live. The return value of '``llvm.localaddress``'
|
||||
is one way to produce such a value, but various runtimes also expose a suitable
|
||||
pointer in platform-specific ways.
|
||||
|
||||
The ``idx`` argument to '``llvm.framerecover``' indicates which alloca passed to
|
||||
'``llvm.frameescape``' to recover. It is zero-indexed.
|
||||
The ``idx`` argument to '``llvm.localrecover``' indicates which alloca passed to
|
||||
'``llvm.localescape``' to recover. It is zero-indexed.
|
||||
|
||||
Semantics:
|
||||
""""""""""
|
||||
|
||||
These intrinsics allow a group of functions to access one stack memory
|
||||
allocation in an ancestor stack frame. The memory returned from
|
||||
'``llvm.frameallocate``' may be allocated prior to stack realignment, so the
|
||||
memory is only aligned to the ABI-required stack alignment. Each function may
|
||||
only call '``llvm.frameallocate``' one or zero times from the function entry
|
||||
block. The frame allocation intrinsic inhibits inlining, as any frame
|
||||
allocations in the inlined function frame are likely to be at a different
|
||||
offset from the one used by '``llvm.framerecover``' called with the
|
||||
uninlined function.
|
||||
These intrinsics allow a group of functions to share access to a set of local
|
||||
stack allocations of a one parent function. The parent function may call the
|
||||
'``llvm.localescape``' intrinsic once from the function entry block, and the
|
||||
child functions can use '``llvm.localrecover``' to access the escaped allocas.
|
||||
The '``llvm.localescape``' intrinsic blocks inlining, as inlining changes where
|
||||
the escaped allocas are allocated, which would break attempts to use
|
||||
'``llvm.localrecover``'.
|
||||
|
||||
.. _int_read_register:
|
||||
.. _int_write_register:
|
||||
@ -9532,6 +10210,75 @@ Examples:
|
||||
Specialised Arithmetic Intrinsics
|
||||
---------------------------------
|
||||
|
||||
'``llvm.canonicalize.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare float @llvm.canonicalize.f32(float %a)
|
||||
declare double @llvm.canonicalize.f64(double %b)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.canonicalize.*``' intrinsic returns the platform specific canonical
|
||||
encoding of a floating point number. This canonicalization is useful for
|
||||
implementing certain numeric primitives such as frexp. The canonical encoding is
|
||||
defined by IEEE-754-2008 to be:
|
||||
|
||||
::
|
||||
|
||||
2.1.8 canonical encoding: The preferred encoding of a floating-point
|
||||
representation in a format. Applied to declets, significands of finite
|
||||
numbers, infinities, and NaNs, especially in decimal formats.
|
||||
|
||||
This operation can also be considered equivalent to the IEEE-754-2008
|
||||
conversion of a floating-point value to the same format. NaNs are handled
|
||||
according to section 6.2.
|
||||
|
||||
Examples of non-canonical encodings:
|
||||
|
||||
- x87 pseudo denormals, pseudo NaNs, pseudo Infinity, Unnormals. These are
|
||||
converted to a canonical representation per hardware-specific protocol.
|
||||
- Many normal decimal floating point numbers have non-canonical alternative
|
||||
encodings.
|
||||
- Some machines, like GPUs or ARMv7 NEON, do not support subnormal values.
|
||||
These are treated as non-canonical encodings of zero and with be flushed to
|
||||
a zero of the same sign by this operation.
|
||||
|
||||
Note that per IEEE-754-2008 6.2, systems that support signaling NaNs with
|
||||
default exception handling must signal an invalid exception, and produce a
|
||||
quiet NaN result.
|
||||
|
||||
This function should always be implementable as multiplication by 1.0, provided
|
||||
that the compiler does not constant fold the operation. Likewise, division by
|
||||
1.0 and ``llvm.minnum(x, x)`` are possible implementations. Addition with
|
||||
-0.0 is also sufficient provided that the rounding mode is not -Infinity.
|
||||
|
||||
``@llvm.canonicalize`` must preserve the equality relation. That is:
|
||||
|
||||
- ``(@llvm.canonicalize(x) == x)`` is equivalent to ``(x == x)``
|
||||
- ``(@llvm.canonicalize(x) == @llvm.canonicalize(y))`` is equivalent to
|
||||
to ``(x == y)``
|
||||
|
||||
Additionally, the sign of zero must be conserved:
|
||||
``@llvm.canonicalize(-0.0) = -0.0`` and ``@llvm.canonicalize(+0.0) = +0.0``
|
||||
|
||||
The payload bits of a NaN must be conserved, with two exceptions.
|
||||
First, environments which use only a single canonical representation of NaN
|
||||
must perform said canonicalization. Second, SNaNs must be quieted per the
|
||||
usual methods.
|
||||
|
||||
The canonicalization operation may be optimized away if:
|
||||
|
||||
- The input is known to be canonical. For example, it was produced by a
|
||||
floating-point operation that is required by the standard to be canonical.
|
||||
- The result is consumed only by (or fused with) other floating-point
|
||||
operations. That is, the bits of the floating point value are not examined.
|
||||
|
||||
'``llvm.fmuladd.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -1868,7 +1868,7 @@ Iterating over predecessors & successors of blocks
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Iterating over the predecessors and successors of a block is quite easy with the
|
||||
routines defined in ``"llvm/Support/CFG.h"``. Just use code like this to
|
||||
routines defined in ``"llvm/IR/CFG.h"``. Just use code like this to
|
||||
iterate over all predecessors of BB:
|
||||
|
||||
.. code-block:: c++
|
||||
|
@ -221,12 +221,10 @@ lowered according to the calling convention specified at the
|
||||
intrinsic's callsite. Variants of the intrinsic with non-void return
|
||||
type also return a value according to calling convention.
|
||||
|
||||
On PowerPC, note that ``<target>`` must be the actual intended target of
|
||||
the indirect call. Specifically, even when compiling for the ELF V1 ABI,
|
||||
``<target>`` is not the function-descriptor address normally used as the C/C++
|
||||
function-pointer representation. As a result, the call target must be local
|
||||
because no adjustment or restoration of the TOC pointer (in register r2) will
|
||||
be performed.
|
||||
On PowerPC, note that ``<target>`` must be the ABI function pointer for the
|
||||
intended target of the indirect call. Specifically, when compiling for the
|
||||
ELF V1 ABI, ``<target>`` is the function-descriptor address normally used as
|
||||
the C/C++ function-pointer representation.
|
||||
|
||||
Requesting zero patch point arguments is valid. In this case, all
|
||||
variable operands are handled just like
|
||||
|
@ -1887,6 +1887,20 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
|
||||
*/
|
||||
void LLVMDeleteFunction(LLVMValueRef Fn);
|
||||
|
||||
/**
|
||||
* Obtain the personality function attached to the function.
|
||||
*
|
||||
* @see llvm::Function::getPersonalityFn()
|
||||
*/
|
||||
LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn);
|
||||
|
||||
/**
|
||||
* Set the personality function attached to the function.
|
||||
*
|
||||
* @see llvm::Function::setPersonalityFn()
|
||||
*/
|
||||
void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn);
|
||||
|
||||
/**
|
||||
* Obtain the ID number from a function instance.
|
||||
*
|
||||
|
@ -81,7 +81,6 @@ uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI);
|
||||
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI);
|
||||
|
||||
// RelocationRef accessors
|
||||
uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI);
|
||||
uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI);
|
||||
LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI);
|
||||
uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI);
|
||||
|
@ -40,7 +40,7 @@ typedef bool lto_bool_t;
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define LTO_API_VERSION 16
|
||||
#define LTO_API_VERSION 17
|
||||
|
||||
/**
|
||||
* \since prior to LTO_API_VERSION=3
|
||||
@ -63,7 +63,8 @@ typedef enum {
|
||||
LTO_SYMBOL_SCOPE_PROTECTED = 0x00002000,
|
||||
LTO_SYMBOL_SCOPE_DEFAULT = 0x00001800,
|
||||
LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN = 0x00002800,
|
||||
LTO_SYMBOL_COMDAT = 0x00004000
|
||||
LTO_SYMBOL_COMDAT = 0x00004000,
|
||||
LTO_SYMBOL_ALIAS = 0x00008000
|
||||
} lto_symbol_attributes;
|
||||
|
||||
/**
|
||||
|
@ -276,6 +276,10 @@ class APFloat {
|
||||
/// \param isIEEE - If 128 bit number, select between PPC and IEEE
|
||||
static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
|
||||
|
||||
/// Returns the size of the floating point number (in bits) in the given
|
||||
/// semantics.
|
||||
static unsigned getSizeInBits(const fltSemantics &Sem);
|
||||
|
||||
/// @}
|
||||
|
||||
/// Used to insert APFloat objects, or objects that contain APFloat objects,
|
||||
|
@ -569,6 +569,22 @@ class Triple {
|
||||
/// architecture if no such variant can be found.
|
||||
llvm::Triple get64BitArchVariant() const;
|
||||
|
||||
/// Form a triple with a big endian variant of the current architecture.
|
||||
///
|
||||
/// This can be used to move across "families" of architectures where useful.
|
||||
///
|
||||
/// \returns A new triple with a big endian architecture or an unknown
|
||||
/// architecture if no such variant can be found.
|
||||
llvm::Triple getBigEndianArchVariant() const;
|
||||
|
||||
/// Form a triple with a little endian variant of the current architecture.
|
||||
///
|
||||
/// This can be used to move across "families" of architectures where useful.
|
||||
///
|
||||
/// \returns A new triple with a little endian architecture or an unknown
|
||||
/// architecture if no such variant can be found.
|
||||
llvm::Triple getLittleEndianArchVariant() const;
|
||||
|
||||
/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
|
||||
///
|
||||
/// \param Arch the architecture name (e.g., "armv7s"). If it is an empty
|
||||
|
@ -50,50 +50,51 @@ unsigned ComputeEditDistance(ArrayRef<T> FromArray, ArrayRef<T> ToArray,
|
||||
// http://en.wikipedia.org/wiki/Levenshtein_distance
|
||||
//
|
||||
// Although the algorithm is typically described using an m x n
|
||||
// array, only two rows are used at a time, so this implementation
|
||||
// just keeps two separate vectors for those two rows.
|
||||
// array, only one row plus one element are used at a time, so this
|
||||
// implementation just keeps one vector for the row. To update one entry,
|
||||
// only the entries to the left, top, and top-left are needed. The left
|
||||
// entry is in Row[x-1], the top entry is what's in Row[x] from the last
|
||||
// iteration, and the top-left entry is stored in Previous.
|
||||
typename ArrayRef<T>::size_type m = FromArray.size();
|
||||
typename ArrayRef<T>::size_type n = ToArray.size();
|
||||
|
||||
const unsigned SmallBufferSize = 64;
|
||||
unsigned SmallBuffer[SmallBufferSize];
|
||||
std::unique_ptr<unsigned[]> Allocated;
|
||||
unsigned *Previous = SmallBuffer;
|
||||
if (2*(n + 1) > SmallBufferSize) {
|
||||
Previous = new unsigned [2*(n+1)];
|
||||
Allocated.reset(Previous);
|
||||
unsigned *Row = SmallBuffer;
|
||||
if (n + 1 > SmallBufferSize) {
|
||||
Row = new unsigned[n + 1];
|
||||
Allocated.reset(Row);
|
||||
}
|
||||
unsigned *Current = Previous + (n + 1);
|
||||
|
||||
for (unsigned i = 0; i <= n; ++i)
|
||||
Previous[i] = i;
|
||||
for (unsigned i = 1; i <= n; ++i)
|
||||
Row[i] = i;
|
||||
|
||||
for (typename ArrayRef<T>::size_type y = 1; y <= m; ++y) {
|
||||
Current[0] = y;
|
||||
unsigned BestThisRow = Current[0];
|
||||
Row[0] = y;
|
||||
unsigned BestThisRow = Row[0];
|
||||
|
||||
unsigned Previous = y - 1;
|
||||
for (typename ArrayRef<T>::size_type x = 1; x <= n; ++x) {
|
||||
int OldRow = Row[x];
|
||||
if (AllowReplacements) {
|
||||
Current[x] = std::min(
|
||||
Previous[x-1] + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
|
||||
std::min(Current[x-1], Previous[x])+1);
|
||||
Row[x] = std::min(
|
||||
Previous + (FromArray[y-1] == ToArray[x-1] ? 0u : 1u),
|
||||
std::min(Row[x-1], Row[x])+1);
|
||||
}
|
||||
else {
|
||||
if (FromArray[y-1] == ToArray[x-1]) Current[x] = Previous[x-1];
|
||||
else Current[x] = std::min(Current[x-1], Previous[x]) + 1;
|
||||
if (FromArray[y-1] == ToArray[x-1]) Row[x] = Previous;
|
||||
else Row[x] = std::min(Row[x-1], Row[x]) + 1;
|
||||
}
|
||||
BestThisRow = std::min(BestThisRow, Current[x]);
|
||||
Previous = OldRow;
|
||||
BestThisRow = std::min(BestThisRow, Row[x]);
|
||||
}
|
||||
|
||||
if (MaxEditDistance && BestThisRow > MaxEditDistance)
|
||||
return MaxEditDistance + 1;
|
||||
|
||||
unsigned *tmp = Current;
|
||||
Current = Previous;
|
||||
Previous = tmp;
|
||||
}
|
||||
|
||||
unsigned Result = Previous[n];
|
||||
unsigned Result = Row[n];
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -211,6 +211,8 @@ class AliasAnalysis {
|
||||
/// (if it has any) are non-volatile loads from objects pointed to by its
|
||||
/// pointer-typed arguments, with arbitrary offsets.
|
||||
///
|
||||
/// This property corresponds to the LLVM IR 'argmemonly' attribute combined
|
||||
/// with 'readonly' attribute.
|
||||
/// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
|
||||
OnlyReadsArgumentPointees = ArgumentPointees | Ref,
|
||||
|
||||
@ -218,6 +220,7 @@ class AliasAnalysis {
|
||||
/// function (if it has any) are non-volatile loads and stores from objects
|
||||
/// pointed to by its pointer-typed arguments, with arbitrary offsets.
|
||||
///
|
||||
/// This property corresponds to the LLVM IR 'argmemonly' attribute.
|
||||
/// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
|
||||
OnlyAccessesArgumentPointees = ArgumentPointees | ModRef,
|
||||
|
||||
@ -518,14 +521,6 @@ class AliasAnalysis {
|
||||
///
|
||||
virtual void deleteValue(Value *V);
|
||||
|
||||
/// copyValue - This method should be used whenever a preexisting value in the
|
||||
/// program is copied or cloned, introducing a new value. Note that analysis
|
||||
/// implementations should tolerate clients that use this method to introduce
|
||||
/// the same value multiple times: if the analysis already knows about a
|
||||
/// value, it should ignore the request.
|
||||
///
|
||||
virtual void copyValue(Value *From, Value *To);
|
||||
|
||||
/// addEscapingUse - This method should be used whenever an escaping use is
|
||||
/// added to a pointer value. Analysis implementations may either return
|
||||
/// conservative responses for that value in the future, or may recompute
|
||||
@ -541,7 +536,6 @@ class AliasAnalysis {
|
||||
/// above, and it provided as a helper to simplify client code.
|
||||
///
|
||||
void replaceWithNewValue(Value *Old, Value *New) {
|
||||
copyValue(Old, New);
|
||||
deleteValue(Old);
|
||||
}
|
||||
};
|
||||
|
@ -72,6 +72,17 @@ namespace llvm {
|
||||
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
|
||||
ArrayRef<unsigned> Idxs);
|
||||
|
||||
/// \brief Attempt to constant fold an extractvalue instruction with the
|
||||
/// specified operands and indices. The constant result is returned if
|
||||
/// successful; if not, null is returned.
|
||||
Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
|
||||
ArrayRef<unsigned> Idxs);
|
||||
|
||||
/// \brief Attempt to constant fold an extractelement instruction with the
|
||||
/// specified operands and indices. The constant result is returned if
|
||||
/// successful; if not, null is returned.
|
||||
Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx);
|
||||
|
||||
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
|
||||
/// produce if it is constant and determinable. If this is not determinable,
|
||||
/// return null.
|
||||
|
@ -202,8 +202,8 @@ class DominanceFrontier : public FunctionPass {
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase<BasicBlock>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase<BasicBlock>);
|
||||
extern template class DominanceFrontierBase<BasicBlock>;
|
||||
extern template class ForwardDominanceFrontierBase<BasicBlock>;
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class Value;
|
||||
@ -119,15 +120,19 @@ template<> struct ilist_traits<IVStrideUse>
|
||||
class IVUsers : public LoopPass {
|
||||
friend class IVStrideUse;
|
||||
Loop *L;
|
||||
AssumptionCache *AC;
|
||||
LoopInfo *LI;
|
||||
DominatorTree *DT;
|
||||
ScalarEvolution *SE;
|
||||
SmallPtrSet<Instruction*,16> Processed;
|
||||
SmallPtrSet<Instruction*, 16> Processed;
|
||||
|
||||
/// IVUses - A list of all tracked IV uses of induction variable expressions
|
||||
/// we are interested in.
|
||||
ilist<IVStrideUse> IVUses;
|
||||
|
||||
// Ephemeral values used by @llvm.assume in this function.
|
||||
SmallPtrSet<const Value *, 32> EphValues;
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
|
||||
|
@ -212,7 +212,7 @@ namespace llvm {
|
||||
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout &DL,
|
||||
FastMathFlags FMF, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
@ -244,6 +244,24 @@ namespace llvm {
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// \brief Given operands for an ExtractValueInst, see if we can fold the
|
||||
/// result. If not, this returns null.
|
||||
Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// \brief Given operands for an ExtractElementInst, see if we can fold the
|
||||
/// result. If not, this returns null.
|
||||
Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
|
||||
/// the result. If not, this returns null.
|
||||
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
|
||||
|
@ -1,71 +0,0 @@
|
||||
//===-- JumpInstrTableInfo.h: Info for Jump-Instruction Tables --*- C++ -*-===//
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Information about jump-instruction tables that have been created by
|
||||
/// JumpInstrTables pass.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
|
||||
#define LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class Function;
|
||||
class FunctionType;
|
||||
|
||||
/// This class stores information about jump-instruction tables created by the
|
||||
/// JumpInstrTables pass (in lib/CodeGen/JumpInstrTables.cpp). Each table is a
|
||||
/// map from a function type to a vector of pairs. The first element of each
|
||||
/// pair is the function that has the jumptable annotation. The second element
|
||||
/// is a function that was declared by JumpInstrTables and used to replace all
|
||||
/// address-taking sites for the original function.
|
||||
///
|
||||
/// The information in this pass is used in AsmPrinter
|
||||
/// (lib/CodeGen/AsmPrinter/AsmPrinter.cpp) to generate the required assembly
|
||||
/// for the jump-instruction tables.
|
||||
class JumpInstrTableInfo : public ImmutablePass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
/// The default byte alignment for jump tables is 16, which is large but
|
||||
/// usually safe.
|
||||
JumpInstrTableInfo(uint64_t ByteAlign = 16);
|
||||
~JumpInstrTableInfo() override;
|
||||
const char *getPassName() const override {
|
||||
return "Jump-Instruction Table Info";
|
||||
}
|
||||
|
||||
typedef std::pair<Function *, Function *> JumpPair;
|
||||
typedef DenseMap<FunctionType *, std::vector<JumpPair> > JumpTables;
|
||||
|
||||
/// Inserts an entry in a table, adding the table if it doesn't exist.
|
||||
void insertEntry(FunctionType *TableFunTy, Function *Target, Function *Jump);
|
||||
|
||||
/// Gets the tables.
|
||||
const JumpTables &getTables() const { return Tables; }
|
||||
|
||||
/// Gets the alignment in bytes of a jumptable entry.
|
||||
uint64_t entryByteAlignment() const { return ByteAlignment; }
|
||||
private:
|
||||
JumpTables Tables;
|
||||
|
||||
/// A power-of-two alignment of a jumptable entry.
|
||||
uint64_t ByteAlignment;
|
||||
};
|
||||
|
||||
/// Creates a JumpInstrTableInfo pass with the given bound on entry size. This
|
||||
/// bound specifies the maximum number of bytes needed to represent an
|
||||
/// unconditional jump or a trap instruction in the back end currently in use.
|
||||
ModulePass *createJumpInstrTableInfoPass(unsigned Bound);
|
||||
}
|
||||
|
||||
#endif /* LLVM_ANALYSIS_JUMPINSTRTABLEINFO_H */
|
@ -206,6 +206,18 @@ class InvokeInst;
|
||||
llvm_unreachable("invalid enum");
|
||||
}
|
||||
|
||||
/// \brief Return true if this personality may be safely removed if there
|
||||
/// are no invoke instructions remaining in the current function.
|
||||
inline bool isNoOpWithoutInvoke(EHPersonality Pers) {
|
||||
switch (Pers) {
|
||||
case EHPersonality::Unknown:
|
||||
return false;
|
||||
// All known personalities currently have this behavior
|
||||
default: return true;
|
||||
}
|
||||
llvm_unreachable("invalid enum");
|
||||
}
|
||||
|
||||
bool canSimplifyInvokeNoUnwind(const Function *F);
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -292,6 +292,133 @@ class MemoryDepChecker {
|
||||
bool couldPreventStoreLoadForward(unsigned Distance, unsigned TypeByteSize);
|
||||
};
|
||||
|
||||
/// \brief Holds information about the memory runtime legality checks to verify
|
||||
/// that a group of pointers do not overlap.
|
||||
class RuntimePointerChecking {
|
||||
public:
|
||||
struct PointerInfo {
|
||||
/// Holds the pointer value that we need to check.
|
||||
TrackingVH<Value> PointerValue;
|
||||
/// Holds the pointer value at the beginning of the loop.
|
||||
const SCEV *Start;
|
||||
/// Holds the pointer value at the end of the loop.
|
||||
const SCEV *End;
|
||||
/// Holds the information if this pointer is used for writing to memory.
|
||||
bool IsWritePtr;
|
||||
/// Holds the id of the set of pointers that could be dependent because of a
|
||||
/// shared underlying object.
|
||||
unsigned DependencySetId;
|
||||
/// Holds the id of the disjoint alias set to which this pointer belongs.
|
||||
unsigned AliasSetId;
|
||||
/// SCEV for the access.
|
||||
const SCEV *Expr;
|
||||
|
||||
PointerInfo(Value *PointerValue, const SCEV *Start, const SCEV *End,
|
||||
bool IsWritePtr, unsigned DependencySetId, unsigned AliasSetId,
|
||||
const SCEV *Expr)
|
||||
: PointerValue(PointerValue), Start(Start), End(End),
|
||||
IsWritePtr(IsWritePtr), DependencySetId(DependencySetId),
|
||||
AliasSetId(AliasSetId), Expr(Expr) {}
|
||||
};
|
||||
|
||||
RuntimePointerChecking(ScalarEvolution *SE) : Need(false), SE(SE) {}
|
||||
|
||||
/// Reset the state of the pointer runtime information.
|
||||
void reset() {
|
||||
Need = false;
|
||||
Pointers.clear();
|
||||
}
|
||||
|
||||
/// Insert a pointer and calculate the start and end SCEVs.
|
||||
void insert(Loop *Lp, Value *Ptr, bool WritePtr, unsigned DepSetId,
|
||||
unsigned ASId, const ValueToValueMap &Strides);
|
||||
|
||||
/// \brief No run-time memory checking is necessary.
|
||||
bool empty() const { return Pointers.empty(); }
|
||||
|
||||
/// A grouping of pointers. A single memcheck is required between
|
||||
/// two groups.
|
||||
struct CheckingPtrGroup {
|
||||
/// \brief Create a new pointer checking group containing a single
|
||||
/// pointer, with index \p Index in RtCheck.
|
||||
CheckingPtrGroup(unsigned Index, RuntimePointerChecking &RtCheck)
|
||||
: RtCheck(RtCheck), High(RtCheck.Pointers[Index].End),
|
||||
Low(RtCheck.Pointers[Index].Start) {
|
||||
Members.push_back(Index);
|
||||
}
|
||||
|
||||
/// \brief Tries to add the pointer recorded in RtCheck at index
|
||||
/// \p Index to this pointer checking group. We can only add a pointer
|
||||
/// to a checking group if we will still be able to get
|
||||
/// the upper and lower bounds of the check. Returns true in case
|
||||
/// of success, false otherwise.
|
||||
bool addPointer(unsigned Index);
|
||||
|
||||
/// Constitutes the context of this pointer checking group. For each
|
||||
/// pointer that is a member of this group we will retain the index
|
||||
/// at which it appears in RtCheck.
|
||||
RuntimePointerChecking &RtCheck;
|
||||
/// The SCEV expression which represents the upper bound of all the
|
||||
/// pointers in this group.
|
||||
const SCEV *High;
|
||||
/// The SCEV expression which represents the lower bound of all the
|
||||
/// pointers in this group.
|
||||
const SCEV *Low;
|
||||
/// Indices of all the pointers that constitute this grouping.
|
||||
SmallVector<unsigned, 2> Members;
|
||||
};
|
||||
|
||||
/// \brief Groups pointers such that a single memcheck is required
|
||||
/// between two different groups. This will clear the CheckingGroups vector
|
||||
/// and re-compute it. We will only group dependecies if \p UseDependencies
|
||||
/// is true, otherwise we will create a separate group for each pointer.
|
||||
void groupChecks(MemoryDepChecker::DepCandidates &DepCands,
|
||||
bool UseDependencies);
|
||||
|
||||
/// \brief Decide if we need to add a check between two groups of pointers,
|
||||
/// according to needsChecking.
|
||||
bool needsChecking(const CheckingPtrGroup &M, const CheckingPtrGroup &N,
|
||||
const SmallVectorImpl<int> *PtrPartition) const;
|
||||
|
||||
/// \brief Return true if any pointer requires run-time checking according
|
||||
/// to needsChecking.
|
||||
bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const;
|
||||
|
||||
/// \brief Returns the number of run-time checks required according to
|
||||
/// needsChecking.
|
||||
unsigned getNumberOfChecks(const SmallVectorImpl<int> *PtrPartition) const;
|
||||
|
||||
/// \brief Print the list run-time memory checks necessary.
|
||||
///
|
||||
/// If \p PtrPartition is set, it contains the partition number for
|
||||
/// pointers (-1 if the pointer belongs to multiple partitions). In this
|
||||
/// case omit checks between pointers belonging to the same partition.
|
||||
void print(raw_ostream &OS, unsigned Depth = 0,
|
||||
const SmallVectorImpl<int> *PtrPartition = nullptr) const;
|
||||
|
||||
/// This flag indicates if we need to add the runtime check.
|
||||
bool Need;
|
||||
|
||||
/// Information about the pointers that may require checking.
|
||||
SmallVector<PointerInfo, 2> Pointers;
|
||||
|
||||
/// Holds a partitioning of pointers into "check groups".
|
||||
SmallVector<CheckingPtrGroup, 2> CheckingGroups;
|
||||
|
||||
private:
|
||||
/// \brief Decide whether we need to issue a run-time check for pointer at
|
||||
/// index \p I and \p J to prove their independence.
|
||||
///
|
||||
/// If \p PtrPartition is set, it contains the partition number for
|
||||
/// pointers (-1 if the pointer belongs to multiple partitions). In this
|
||||
/// case omit checks between pointers belonging to the same partition.
|
||||
bool needsChecking(unsigned I, unsigned J,
|
||||
const SmallVectorImpl<int> *PtrPartition) const;
|
||||
|
||||
/// Holds a pointer to the ScalarEvolution analysis.
|
||||
ScalarEvolution *SE;
|
||||
};
|
||||
|
||||
/// \brief Drive the analysis of memory accesses in the loop
|
||||
///
|
||||
/// This class is responsible for analyzing the memory accesses of a loop. It
|
||||
@ -308,72 +435,6 @@ class MemoryDepChecker {
|
||||
/// RuntimePointerCheck class.
|
||||
class LoopAccessInfo {
|
||||
public:
|
||||
/// This struct holds information about the memory runtime legality check that
|
||||
/// a group of pointers do not overlap.
|
||||
struct RuntimePointerCheck {
|
||||
RuntimePointerCheck() : Need(false) {}
|
||||
|
||||
/// Reset the state of the pointer runtime information.
|
||||
void reset() {
|
||||
Need = false;
|
||||
Pointers.clear();
|
||||
Starts.clear();
|
||||
Ends.clear();
|
||||
IsWritePtr.clear();
|
||||
DependencySetId.clear();
|
||||
AliasSetId.clear();
|
||||
}
|
||||
|
||||
/// Insert a pointer and calculate the start and end SCEVs.
|
||||
void insert(ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr,
|
||||
unsigned DepSetId, unsigned ASId,
|
||||
const ValueToValueMap &Strides);
|
||||
|
||||
/// \brief No run-time memory checking is necessary.
|
||||
bool empty() const { return Pointers.empty(); }
|
||||
|
||||
/// \brief Decide whether we need to issue a run-time check for pointer at
|
||||
/// index \p I and \p J to prove their independence.
|
||||
///
|
||||
/// If \p PtrPartition is set, it contains the partition number for
|
||||
/// pointers (-1 if the pointer belongs to multiple partitions). In this
|
||||
/// case omit checks between pointers belonging to the same partition.
|
||||
bool needsChecking(unsigned I, unsigned J,
|
||||
const SmallVectorImpl<int> *PtrPartition) const;
|
||||
|
||||
/// \brief Return true if any pointer requires run-time checking according
|
||||
/// to needsChecking.
|
||||
bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const;
|
||||
|
||||
/// \brief Returns the number of run-time checks required according to
|
||||
/// needsChecking.
|
||||
unsigned getNumberOfChecks(const SmallVectorImpl<int> *PtrPartition) const;
|
||||
|
||||
/// \brief Print the list run-time memory checks necessary.
|
||||
///
|
||||
/// If \p PtrPartition is set, it contains the partition number for
|
||||
/// pointers (-1 if the pointer belongs to multiple partitions). In this
|
||||
/// case omit checks between pointers belonging to the same partition.
|
||||
void print(raw_ostream &OS, unsigned Depth = 0,
|
||||
const SmallVectorImpl<int> *PtrPartition = nullptr) const;
|
||||
|
||||
/// This flag indicates if we need to add the runtime check.
|
||||
bool Need;
|
||||
/// Holds the pointers that we need to check.
|
||||
SmallVector<TrackingVH<Value>, 2> Pointers;
|
||||
/// Holds the pointer value at the beginning of the loop.
|
||||
SmallVector<const SCEV*, 2> Starts;
|
||||
/// Holds the pointer value at the end of the loop.
|
||||
SmallVector<const SCEV*, 2> Ends;
|
||||
/// Holds the information if this pointer is used for writing to memory.
|
||||
SmallVector<bool, 2> IsWritePtr;
|
||||
/// Holds the id of the set of pointers that could be dependent because of a
|
||||
/// shared underlying object.
|
||||
SmallVector<unsigned, 2> DependencySetId;
|
||||
/// Holds the id of the disjoint alias set to which this pointer belongs.
|
||||
SmallVector<unsigned, 2> AliasSetId;
|
||||
};
|
||||
|
||||
LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
|
||||
DominatorTree *DT, LoopInfo *LI,
|
||||
@ -383,15 +444,15 @@ class LoopAccessInfo {
|
||||
/// no memory dependence cycles.
|
||||
bool canVectorizeMemory() const { return CanVecMem; }
|
||||
|
||||
const RuntimePointerCheck *getRuntimePointerCheck() const {
|
||||
return &PtrRtCheck;
|
||||
const RuntimePointerChecking *getRuntimePointerChecking() const {
|
||||
return &PtrRtChecking;
|
||||
}
|
||||
|
||||
/// \brief Number of memchecks required to prove independence of otherwise
|
||||
/// may-alias pointers.
|
||||
unsigned getNumRuntimePointerChecks(
|
||||
const SmallVectorImpl<int> *PtrPartition = nullptr) const {
|
||||
return PtrRtCheck.getNumberOfChecks(PtrPartition);
|
||||
return PtrRtChecking.getNumberOfChecks(PtrPartition);
|
||||
}
|
||||
|
||||
/// Return true if the block BB needs to be predicated in order for the loop
|
||||
@ -461,7 +522,7 @@ class LoopAccessInfo {
|
||||
|
||||
/// We need to check that all of the pointers in this list are disjoint
|
||||
/// at runtime.
|
||||
RuntimePointerCheck PtrRtCheck;
|
||||
RuntimePointerChecking PtrRtChecking;
|
||||
|
||||
/// \brief the Memory Dependence Checker which can determine the
|
||||
/// loop-independent and loop-carried dependences between memory accesses.
|
||||
|
@ -347,9 +347,7 @@ raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) {
|
||||
}
|
||||
|
||||
// Implementation in LoopInfoImpl.h
|
||||
#ifdef __GNUC__
|
||||
__extension__ extern template class LoopBase<BasicBlock, Loop>;
|
||||
#endif
|
||||
extern template class LoopBase<BasicBlock, Loop>;
|
||||
|
||||
class Loop : public LoopBase<BasicBlock, Loop> {
|
||||
public:
|
||||
@ -633,9 +631,7 @@ class LoopInfoBase {
|
||||
};
|
||||
|
||||
// Implementation in LoopInfoImpl.h
|
||||
#ifdef __GNUC__
|
||||
__extension__ extern template class LoopInfoBase<BasicBlock, Loop>;
|
||||
#endif
|
||||
extern template class LoopInfoBase<BasicBlock, Loop>;
|
||||
|
||||
class LoopInfo : public LoopInfoBase<BasicBlock, Loop> {
|
||||
typedef LoopInfoBase<BasicBlock, Loop> BaseT;
|
||||
|
@ -902,9 +902,9 @@ inline raw_ostream &operator<<(raw_ostream &OS,
|
||||
return OS << Node.template getNodeAs<BlockT>()->getName();
|
||||
}
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<Function>>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<Function>>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<Function>>);
|
||||
extern template class RegionBase<RegionTraits<Function>>;
|
||||
extern template class RegionNodeBase<RegionTraits<Function>>;
|
||||
extern template class RegionInfoBase<RegionTraits<Function>>;
|
||||
|
||||
} // End llvm namespace
|
||||
#endif
|
||||
|
@ -69,7 +69,7 @@ class TargetTransformInfo {
|
||||
///
|
||||
/// The TTI implementation will reflect the information in the DataLayout
|
||||
/// provided if non-null.
|
||||
explicit TargetTransformInfo(const DataLayout *DL);
|
||||
explicit TargetTransformInfo(const DataLayout &DL);
|
||||
|
||||
// Provide move semantics.
|
||||
TargetTransformInfo(TargetTransformInfo &&Arg);
|
||||
@ -541,7 +541,7 @@ class TargetTransformInfo {
|
||||
class TargetTransformInfo::Concept {
|
||||
public:
|
||||
virtual ~Concept() = 0;
|
||||
|
||||
virtual const DataLayout &getDataLayout() const = 0;
|
||||
virtual unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0;
|
||||
virtual unsigned getGEPCost(const Value *Ptr,
|
||||
ArrayRef<const Value *> Operands) = 0;
|
||||
@ -636,6 +636,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
|
||||
Model(T Impl) : Impl(std::move(Impl)) {}
|
||||
~Model() override {}
|
||||
|
||||
const DataLayout &getDataLayout() const override {
|
||||
return Impl.getDataLayout();
|
||||
}
|
||||
|
||||
unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override {
|
||||
return Impl.getOperationCost(Opcode, Ty, OpTy);
|
||||
}
|
||||
|
@ -30,26 +30,17 @@ class TargetTransformInfoImplBase {
|
||||
protected:
|
||||
typedef TargetTransformInfo TTI;
|
||||
|
||||
const DataLayout *DL;
|
||||
const DataLayout &DL;
|
||||
|
||||
explicit TargetTransformInfoImplBase(const DataLayout *DL)
|
||||
: DL(DL) {}
|
||||
explicit TargetTransformInfoImplBase(const DataLayout &DL) : DL(DL) {}
|
||||
|
||||
public:
|
||||
// Provide value semantics. MSVC requires that we spell all of these out.
|
||||
TargetTransformInfoImplBase(const TargetTransformInfoImplBase &Arg)
|
||||
: DL(Arg.DL) {}
|
||||
TargetTransformInfoImplBase(TargetTransformInfoImplBase &&Arg)
|
||||
: DL(std::move(Arg.DL)) {}
|
||||
TargetTransformInfoImplBase &
|
||||
operator=(const TargetTransformInfoImplBase &RHS) {
|
||||
DL = RHS.DL;
|
||||
return *this;
|
||||
}
|
||||
TargetTransformInfoImplBase &operator=(TargetTransformInfoImplBase &&RHS) {
|
||||
DL = std::move(RHS.DL);
|
||||
return *this;
|
||||
}
|
||||
TargetTransformInfoImplBase(TargetTransformInfoImplBase &&Arg) : DL(Arg.DL) {}
|
||||
|
||||
const DataLayout &getDataLayout() const { return DL; }
|
||||
|
||||
unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) {
|
||||
switch (Opcode) {
|
||||
@ -70,28 +61,22 @@ class TargetTransformInfoImplBase {
|
||||
return TTI::TCC_Basic;
|
||||
|
||||
case Instruction::IntToPtr: {
|
||||
if (!DL)
|
||||
return TTI::TCC_Basic;
|
||||
|
||||
// An inttoptr cast is free so long as the input is a legal integer type
|
||||
// which doesn't contain values outside the range of a pointer.
|
||||
unsigned OpSize = OpTy->getScalarSizeInBits();
|
||||
if (DL->isLegalInteger(OpSize) &&
|
||||
OpSize <= DL->getPointerTypeSizeInBits(Ty))
|
||||
if (DL.isLegalInteger(OpSize) &&
|
||||
OpSize <= DL.getPointerTypeSizeInBits(Ty))
|
||||
return TTI::TCC_Free;
|
||||
|
||||
// Otherwise it's not a no-op.
|
||||
return TTI::TCC_Basic;
|
||||
}
|
||||
case Instruction::PtrToInt: {
|
||||
if (!DL)
|
||||
return TTI::TCC_Basic;
|
||||
|
||||
// A ptrtoint cast is free so long as the result is large enough to store
|
||||
// the pointer, and a legal integer type.
|
||||
unsigned DestSize = Ty->getScalarSizeInBits();
|
||||
if (DL->isLegalInteger(DestSize) &&
|
||||
DestSize >= DL->getPointerTypeSizeInBits(OpTy))
|
||||
if (DL.isLegalInteger(DestSize) &&
|
||||
DestSize >= DL.getPointerTypeSizeInBits(OpTy))
|
||||
return TTI::TCC_Free;
|
||||
|
||||
// Otherwise it's not a no-op.
|
||||
@ -100,7 +85,7 @@ class TargetTransformInfoImplBase {
|
||||
case Instruction::Trunc:
|
||||
// trunc to a native type is free (assuming the target has compare and
|
||||
// shift-right of the same width).
|
||||
if (DL && DL->isLegalInteger(DL->getTypeSizeInBits(Ty)))
|
||||
if (DL.isLegalInteger(DL.getTypeSizeInBits(Ty)))
|
||||
return TTI::TCC_Free;
|
||||
|
||||
return TTI::TCC_Basic;
|
||||
@ -353,8 +338,7 @@ class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {
|
||||
typedef TargetTransformInfoImplBase BaseT;
|
||||
|
||||
protected:
|
||||
explicit TargetTransformInfoImplCRTPBase(const DataLayout *DL)
|
||||
: BaseT(DL) {}
|
||||
explicit TargetTransformInfoImplCRTPBase(const DataLayout &DL) : BaseT(DL) {}
|
||||
|
||||
public:
|
||||
// Provide value semantics. MSVC requires that we spell all of these out.
|
||||
@ -362,16 +346,6 @@ class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {
|
||||
: BaseT(static_cast<const BaseT &>(Arg)) {}
|
||||
TargetTransformInfoImplCRTPBase(TargetTransformInfoImplCRTPBase &&Arg)
|
||||
: BaseT(std::move(static_cast<BaseT &>(Arg))) {}
|
||||
TargetTransformInfoImplCRTPBase &
|
||||
operator=(const TargetTransformInfoImplCRTPBase &RHS) {
|
||||
BaseT::operator=(static_cast<const BaseT &>(RHS));
|
||||
return *this;
|
||||
}
|
||||
TargetTransformInfoImplCRTPBase &
|
||||
operator=(TargetTransformInfoImplCRTPBase &&RHS) {
|
||||
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
using BaseT::getCallCost;
|
||||
|
||||
|
@ -20,6 +20,12 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class GetElementPtrInst;
|
||||
class Loop;
|
||||
class ScalarEvolution;
|
||||
class Type;
|
||||
class Value;
|
||||
|
||||
/// \brief Identify if the intrinsic is trivially vectorizable.
|
||||
/// This method returns true if the intrinsic's argument types are all
|
||||
/// scalars for the scalar form of the intrinsic and all vectors for
|
||||
@ -51,6 +57,28 @@ Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
|
||||
/// its intrinsic ID, in case it does not found it return not_intrinsic.
|
||||
Intrinsic::ID getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// \brief Find the operand of the GEP that should be checked for consecutive
|
||||
/// stores. This ignores trailing indices that have no effect on the final
|
||||
/// pointer.
|
||||
unsigned getGEPInductionOperand(const GetElementPtrInst *Gep);
|
||||
|
||||
/// \brief If the argument is a GEP, then returns the operand identified by
|
||||
/// getGEPInductionOperand. However, if there is some other non-loop-invariant
|
||||
/// operand, it returns that instead.
|
||||
Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp);
|
||||
|
||||
/// \brief If a value has only one user that is a CastInst, return it.
|
||||
Value *getUniqueCastUse(Value *Ptr, Loop *Lp, Type *Ty);
|
||||
|
||||
/// \brief Get the stride of a pointer access in a loop. Looks for symbolic
|
||||
/// strides "a[i*stride]". Returns the symbolic stride, or null otherwise.
|
||||
Value *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp);
|
||||
|
||||
/// \brief Given a vector and an element number, see if the scalar value is
|
||||
/// already around as a register, for example if it were inserted then extracted
|
||||
/// from the vector.
|
||||
Value *findScalarElement(Value *V, unsigned EltNo);
|
||||
|
||||
} // llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -407,6 +407,7 @@ namespace bitc {
|
||||
ATTR_KIND_DEREFERENCEABLE_OR_NULL = 42,
|
||||
ATTR_KIND_CONVERGENT = 43,
|
||||
ATTR_KIND_SAFESTACK = 44,
|
||||
ATTR_KIND_ARGMEMONLY = 45
|
||||
};
|
||||
|
||||
enum ComdatSelectionKindCodes {
|
||||
|
@ -146,7 +146,7 @@ namespace llvm {
|
||||
}
|
||||
|
||||
const std::error_category &BitcodeErrorCategory();
|
||||
enum class BitcodeError { InvalidBitcodeSignature, CorruptedBitcode };
|
||||
enum class BitcodeError { InvalidBitcodeSignature = 1, CorruptedBitcode };
|
||||
inline std::error_code make_error_code(BitcodeError E) {
|
||||
return std::error_code(static_cast<int>(E), BitcodeErrorCategory());
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ inline unsigned ComputeLinearIndex(Type *Ty,
|
||||
/// If Offsets is non-null, it points to a vector to be filled in
|
||||
/// with the in-memory offsets of each of the individual values.
|
||||
///
|
||||
void ComputeValueVTs(const TargetLowering &TLI, Type *Ty,
|
||||
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty,
|
||||
SmallVectorImpl<EVT> &ValueVTs,
|
||||
SmallVectorImpl<uint64_t> *Offsets = nullptr,
|
||||
uint64_t StartingOffset = 0);
|
||||
|
@ -91,8 +91,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit BasicTTIImplBase(const TargetMachine *TM)
|
||||
: BaseT(TM->getDataLayout()) {}
|
||||
explicit BasicTTIImplBase(const TargetMachine *TM, const DataLayout &DL)
|
||||
: BaseT(DL) {}
|
||||
|
||||
using TargetTransformInfoImplBase::DL;
|
||||
|
||||
public:
|
||||
// Provide value semantics. MSVC requires that we spell all of these out.
|
||||
@ -100,14 +102,6 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
: BaseT(static_cast<const BaseT &>(Arg)) {}
|
||||
BasicTTIImplBase(BasicTTIImplBase &&Arg)
|
||||
: BaseT(std::move(static_cast<BaseT &>(Arg))) {}
|
||||
BasicTTIImplBase &operator=(const BasicTTIImplBase &RHS) {
|
||||
BaseT::operator=(static_cast<const BaseT &>(RHS));
|
||||
return *this;
|
||||
}
|
||||
BasicTTIImplBase &operator=(BasicTTIImplBase &&RHS) {
|
||||
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \name Scalar TTI Implementations
|
||||
/// @{
|
||||
@ -132,7 +126,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
AM.BaseOffs = BaseOffset;
|
||||
AM.HasBaseReg = HasBaseReg;
|
||||
AM.Scale = Scale;
|
||||
return getTLI()->isLegalAddressingMode(AM, Ty, AddrSpace);
|
||||
return getTLI()->isLegalAddressingMode(DL, AM, Ty, AddrSpace);
|
||||
}
|
||||
|
||||
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
|
||||
@ -142,7 +136,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
AM.BaseOffs = BaseOffset;
|
||||
AM.HasBaseReg = HasBaseReg;
|
||||
AM.Scale = Scale;
|
||||
return getTLI()->getScalingFactorCost(AM, Ty, AddrSpace);
|
||||
return getTLI()->getScalingFactorCost(DL, AM, Ty, AddrSpace);
|
||||
}
|
||||
|
||||
bool isTruncateFree(Type *Ty1, Type *Ty2) {
|
||||
@ -154,7 +148,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
}
|
||||
|
||||
bool isTypeLegal(Type *Ty) {
|
||||
EVT VT = getTLI()->getValueType(Ty);
|
||||
EVT VT = getTLI()->getValueType(DL, Ty);
|
||||
return getTLI()->isTypeLegal(VT);
|
||||
}
|
||||
|
||||
@ -192,7 +186,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
|
||||
bool haveFastSqrt(Type *Ty) {
|
||||
const TargetLoweringBase *TLI = getTLI();
|
||||
EVT VT = TLI->getValueType(Ty);
|
||||
EVT VT = TLI->getValueType(DL, Ty);
|
||||
return TLI->isTypeLegal(VT) &&
|
||||
TLI->isOperationLegalOrCustom(ISD::FSQRT, VT);
|
||||
}
|
||||
@ -282,7 +276,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
/// \name Vector TTI Implementations
|
||||
/// @{
|
||||
|
||||
unsigned getNumberOfRegisters(bool Vector) { return 1; }
|
||||
unsigned getNumberOfRegisters(bool Vector) { return Vector ? 0 : 1; }
|
||||
|
||||
unsigned getRegisterBitWidth(bool Vector) { return 32; }
|
||||
|
||||
@ -299,7 +293,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
int ISD = TLI->InstructionOpcodeToISD(Opcode);
|
||||
assert(ISD && "Invalid opcode");
|
||||
|
||||
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty);
|
||||
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty);
|
||||
|
||||
bool IsFloat = Ty->getScalarType()->isFloatingPointTy();
|
||||
// Assume that floating point arithmetic operations cost twice as much as
|
||||
@ -349,9 +343,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
const TargetLoweringBase *TLI = getTLI();
|
||||
int ISD = TLI->InstructionOpcodeToISD(Opcode);
|
||||
assert(ISD && "Invalid opcode");
|
||||
|
||||
std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(Src);
|
||||
std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(Dst);
|
||||
std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(DL, Src);
|
||||
std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(DL, Dst);
|
||||
|
||||
// Check for NOOP conversions.
|
||||
if (SrcLT.first == DstLT.first &&
|
||||
@ -455,8 +448,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
if (CondTy->isVectorTy())
|
||||
ISD = ISD::VSELECT;
|
||||
}
|
||||
|
||||
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(ValTy);
|
||||
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, ValTy);
|
||||
|
||||
if (!(ValTy->isVectorTy() && !LT.second.isVector()) &&
|
||||
!TLI->isOperationExpand(ISD, LT.second)) {
|
||||
@ -485,7 +477,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
|
||||
unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) {
|
||||
std::pair<unsigned, MVT> LT =
|
||||
getTLI()->getTypeLegalizationCost(Val->getScalarType());
|
||||
getTLI()->getTypeLegalizationCost(DL, Val->getScalarType());
|
||||
|
||||
return LT.first;
|
||||
}
|
||||
@ -493,7 +485,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
|
||||
unsigned AddressSpace) {
|
||||
assert(!Src->isVoidTy() && "Invalid type");
|
||||
std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Src);
|
||||
std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Src);
|
||||
|
||||
// Assuming that all loads of legal types cost 1.
|
||||
unsigned Cost = LT.first;
|
||||
@ -504,7 +496,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
// itself. Unless the corresponding extending load or truncating store is
|
||||
// legal, then this will scalarize.
|
||||
TargetLowering::LegalizeAction LA = TargetLowering::Expand;
|
||||
EVT MemVT = getTLI()->getValueType(Src, true);
|
||||
EVT MemVT = getTLI()->getValueType(DL, Src, true);
|
||||
if (MemVT.isSimple() && MemVT != MVT::Other) {
|
||||
if (Opcode == Instruction::Store)
|
||||
LA = getTLI()->getTruncStoreAction(LT.second, MemVT.getSimpleVT());
|
||||
@ -700,7 +692,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
}
|
||||
|
||||
const TargetLoweringBase *TLI = getTLI();
|
||||
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(RetTy);
|
||||
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, RetTy);
|
||||
|
||||
if (TLI->isOperationLegalOrPromote(ISD, LT.second)) {
|
||||
// The operation is legal. Assume it costs 1.
|
||||
@ -771,7 +763,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
|
||||
}
|
||||
|
||||
unsigned getNumberOfParts(Type *Tp) {
|
||||
std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Tp);
|
||||
std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Tp);
|
||||
return LT.first;
|
||||
}
|
||||
|
||||
@ -816,18 +808,6 @@ class BasicTTIImpl : public BasicTTIImplBase<BasicTTIImpl> {
|
||||
BasicTTIImpl(BasicTTIImpl &&Arg)
|
||||
: BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
|
||||
TLI(std::move(Arg.TLI)) {}
|
||||
BasicTTIImpl &operator=(const BasicTTIImpl &RHS) {
|
||||
BaseT::operator=(static_cast<const BaseT &>(RHS));
|
||||
ST = RHS.ST;
|
||||
TLI = RHS.TLI;
|
||||
return *this;
|
||||
}
|
||||
BasicTTIImpl &operator=(BasicTTIImpl &&RHS) {
|
||||
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
|
||||
ST = std::move(RHS.ST);
|
||||
TLI = std::move(RHS.TLI);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -206,6 +206,10 @@ cl::opt<std::string> StartAfter("start-after",
|
||||
cl::value_desc("pass-name"),
|
||||
cl::init(""));
|
||||
|
||||
cl::opt<std::string>
|
||||
RunPass("run-pass", cl::desc("Run compiler only for one specific pass"),
|
||||
cl::value_desc("pass-name"), cl::init(""));
|
||||
|
||||
cl::opt<bool> DataSections("data-sections",
|
||||
cl::desc("Emit data into separate sections"),
|
||||
cl::init(false));
|
||||
|
@ -72,10 +72,13 @@ namespace ISD {
|
||||
/// the parent's frame or return address, and so on.
|
||||
FRAMEADDR, RETURNADDR,
|
||||
|
||||
/// FRAME_ALLOC_RECOVER - Represents the llvm.framerecover
|
||||
/// intrinsic. Materializes the offset from the frame pointer of another
|
||||
/// function to the result of llvm.frameallocate.
|
||||
FRAME_ALLOC_RECOVER,
|
||||
/// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
|
||||
/// Materializes the offset from the local object pointer of another
|
||||
/// function to a particular local object passed to llvm.localescape. The
|
||||
/// operand is the MCSymbol label used to represent this offset, since
|
||||
/// typically the offset is not known until after code generation of the
|
||||
/// parent.
|
||||
LOCAL_RECOVER,
|
||||
|
||||
/// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on
|
||||
/// the DAG, which implements the named register global variables extension.
|
||||
@ -725,7 +728,7 @@ namespace ISD {
|
||||
/// which do not reference a specific memory location should be less than
|
||||
/// this value. Those that do must not be less than this value, and can
|
||||
/// be used with SelectionDAG::getMemIntrinsicNode.
|
||||
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+200;
|
||||
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+300;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// MemIndexedMode enum - This enum defines the load / store indexed
|
||||
|
@ -203,6 +203,11 @@ class LiveIntervalUnion {
|
||||
assert(idx < Size && "idx out of bounds");
|
||||
return LIUs[idx];
|
||||
}
|
||||
|
||||
const LiveIntervalUnion& operator[](unsigned Idx) const {
|
||||
assert(Idx < Size && "Idx out of bounds");
|
||||
return LIUs[Idx];
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -32,13 +32,11 @@ namespace llvm {
|
||||
|
||||
class LiveInterval;
|
||||
class LiveIntervalAnalysis;
|
||||
class MachineRegisterInfo;
|
||||
class TargetRegisterInfo;
|
||||
class VirtRegMap;
|
||||
|
||||
class LiveRegMatrix : public MachineFunctionPass {
|
||||
const TargetRegisterInfo *TRI;
|
||||
MachineRegisterInfo *MRI;
|
||||
LiveIntervals *LIS;
|
||||
VirtRegMap *VRM;
|
||||
|
||||
@ -114,6 +112,9 @@ class LiveRegMatrix : public MachineFunctionPass {
|
||||
/// the assignment and updates VirtRegMap accordingly.
|
||||
void unassign(LiveInterval &VirtReg);
|
||||
|
||||
/// Returns true if the given \p PhysReg has any live intervals assigned.
|
||||
bool isPhysRegUsed(unsigned PhysReg) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Low-level interface.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -81,15 +81,30 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::FlowStringValue)
|
||||
namespace llvm {
|
||||
namespace yaml {
|
||||
|
||||
struct VirtualRegisterDefinition {
|
||||
unsigned ID;
|
||||
StringValue Class;
|
||||
// TODO: Serialize the virtual register hints.
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<VirtualRegisterDefinition> {
|
||||
static void mapping(IO &YamlIO, VirtualRegisterDefinition &Reg) {
|
||||
YamlIO.mapRequired("id", Reg.ID);
|
||||
YamlIO.mapRequired("class", Reg.Class);
|
||||
}
|
||||
|
||||
static const bool flow = true;
|
||||
};
|
||||
|
||||
struct MachineBasicBlock {
|
||||
unsigned ID;
|
||||
std::string Name;
|
||||
StringValue Name;
|
||||
unsigned Alignment = 0;
|
||||
bool IsLandingPad = false;
|
||||
bool AddressTaken = false;
|
||||
// TODO: Serialize the successor weights and liveins.
|
||||
// TODO: Serialize the successor weights.
|
||||
std::vector<FlowStringValue> Successors;
|
||||
|
||||
std::vector<FlowStringValue> LiveIns;
|
||||
std::vector<StringValue> Instructions;
|
||||
};
|
||||
|
||||
@ -97,23 +112,153 @@ template <> struct MappingTraits<MachineBasicBlock> {
|
||||
static void mapping(IO &YamlIO, MachineBasicBlock &MBB) {
|
||||
YamlIO.mapRequired("id", MBB.ID);
|
||||
YamlIO.mapOptional("name", MBB.Name,
|
||||
std::string()); // Don't print out an empty name.
|
||||
StringValue()); // Don't print out an empty name.
|
||||
YamlIO.mapOptional("alignment", MBB.Alignment);
|
||||
YamlIO.mapOptional("isLandingPad", MBB.IsLandingPad);
|
||||
YamlIO.mapOptional("addressTaken", MBB.AddressTaken);
|
||||
YamlIO.mapOptional("successors", MBB.Successors);
|
||||
YamlIO.mapOptional("liveins", MBB.LiveIns);
|
||||
YamlIO.mapOptional("instructions", MBB.Instructions);
|
||||
}
|
||||
};
|
||||
|
||||
/// Serializable representation of stack object from the MachineFrameInfo class.
|
||||
///
|
||||
/// The flags 'isImmutable' and 'isAliased' aren't serialized, as they are
|
||||
/// determined by the object's type and frame information flags.
|
||||
/// Dead stack objects aren't serialized.
|
||||
///
|
||||
/// TODO: Determine isPreallocated flag by mapping between objects and local
|
||||
/// objects (Serialize local objects).
|
||||
struct MachineStackObject {
|
||||
enum ObjectType { DefaultType, SpillSlot, VariableSized };
|
||||
// TODO: Serialize LLVM alloca reference.
|
||||
unsigned ID;
|
||||
ObjectType Type = DefaultType;
|
||||
int64_t Offset = 0;
|
||||
uint64_t Size = 0;
|
||||
unsigned Alignment = 0;
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<MachineStackObject::ObjectType> {
|
||||
static void enumeration(yaml::IO &IO, MachineStackObject::ObjectType &Type) {
|
||||
IO.enumCase(Type, "default", MachineStackObject::DefaultType);
|
||||
IO.enumCase(Type, "spill-slot", MachineStackObject::SpillSlot);
|
||||
IO.enumCase(Type, "variable-sized", MachineStackObject::VariableSized);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<MachineStackObject> {
|
||||
static void mapping(yaml::IO &YamlIO, MachineStackObject &Object) {
|
||||
YamlIO.mapRequired("id", Object.ID);
|
||||
YamlIO.mapOptional(
|
||||
"type", Object.Type,
|
||||
MachineStackObject::DefaultType); // Don't print the default type.
|
||||
YamlIO.mapOptional("offset", Object.Offset);
|
||||
if (Object.Type != MachineStackObject::VariableSized)
|
||||
YamlIO.mapRequired("size", Object.Size);
|
||||
YamlIO.mapOptional("alignment", Object.Alignment);
|
||||
}
|
||||
|
||||
static const bool flow = true;
|
||||
};
|
||||
|
||||
/// Serializable representation of the fixed stack object from the
|
||||
/// MachineFrameInfo class.
|
||||
struct FixedMachineStackObject {
|
||||
enum ObjectType { DefaultType, SpillSlot };
|
||||
unsigned ID;
|
||||
ObjectType Type = DefaultType;
|
||||
int64_t Offset = 0;
|
||||
uint64_t Size = 0;
|
||||
unsigned Alignment = 0;
|
||||
bool IsImmutable = false;
|
||||
bool IsAliased = false;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<FixedMachineStackObject::ObjectType> {
|
||||
static void enumeration(yaml::IO &IO,
|
||||
FixedMachineStackObject::ObjectType &Type) {
|
||||
IO.enumCase(Type, "default", FixedMachineStackObject::DefaultType);
|
||||
IO.enumCase(Type, "spill-slot", FixedMachineStackObject::SpillSlot);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<FixedMachineStackObject> {
|
||||
static void mapping(yaml::IO &YamlIO, FixedMachineStackObject &Object) {
|
||||
YamlIO.mapRequired("id", Object.ID);
|
||||
YamlIO.mapOptional(
|
||||
"type", Object.Type,
|
||||
FixedMachineStackObject::DefaultType); // Don't print the default type.
|
||||
YamlIO.mapOptional("offset", Object.Offset);
|
||||
YamlIO.mapOptional("size", Object.Size);
|
||||
YamlIO.mapOptional("alignment", Object.Alignment);
|
||||
if (Object.Type != FixedMachineStackObject::SpillSlot) {
|
||||
YamlIO.mapOptional("isImmutable", Object.IsImmutable);
|
||||
YamlIO.mapOptional("isAliased", Object.IsAliased);
|
||||
}
|
||||
}
|
||||
|
||||
static const bool flow = true;
|
||||
};
|
||||
|
||||
} // end namespace yaml
|
||||
} // end namespace llvm
|
||||
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::VirtualRegisterDefinition)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineBasicBlock)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::MachineStackObject)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::FixedMachineStackObject)
|
||||
|
||||
namespace llvm {
|
||||
namespace yaml {
|
||||
|
||||
/// Serializable representation of MachineFrameInfo.
|
||||
///
|
||||
/// Doesn't serialize attributes like 'StackAlignment', 'IsStackRealignable' and
|
||||
/// 'RealignOption' as they are determined by the target and LLVM function
|
||||
/// attributes.
|
||||
/// It also doesn't serialize attributes like 'NumFixedObject' and
|
||||
/// 'HasVarSizedObjects' as they are determined by the frame objects themselves.
|
||||
struct MachineFrameInfo {
|
||||
bool IsFrameAddressTaken = false;
|
||||
bool IsReturnAddressTaken = false;
|
||||
bool HasStackMap = false;
|
||||
bool HasPatchPoint = false;
|
||||
uint64_t StackSize = 0;
|
||||
int OffsetAdjustment = 0;
|
||||
unsigned MaxAlignment = 0;
|
||||
bool AdjustsStack = false;
|
||||
bool HasCalls = false;
|
||||
// TODO: Serialize StackProtectorIdx and FunctionContextIdx
|
||||
unsigned MaxCallFrameSize = 0;
|
||||
// TODO: Serialize callee saved info.
|
||||
// TODO: Serialize local frame objects.
|
||||
bool HasOpaqueSPAdjustment = false;
|
||||
bool HasVAStart = false;
|
||||
bool HasMustTailInVarArgFunc = false;
|
||||
// TODO: Serialize save and restore MBB references.
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<MachineFrameInfo> {
|
||||
static void mapping(IO &YamlIO, MachineFrameInfo &MFI) {
|
||||
YamlIO.mapOptional("isFrameAddressTaken", MFI.IsFrameAddressTaken);
|
||||
YamlIO.mapOptional("isReturnAddressTaken", MFI.IsReturnAddressTaken);
|
||||
YamlIO.mapOptional("hasStackMap", MFI.HasStackMap);
|
||||
YamlIO.mapOptional("hasPatchPoint", MFI.HasPatchPoint);
|
||||
YamlIO.mapOptional("stackSize", MFI.StackSize);
|
||||
YamlIO.mapOptional("offsetAdjustment", MFI.OffsetAdjustment);
|
||||
YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
|
||||
YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
|
||||
YamlIO.mapOptional("hasCalls", MFI.HasCalls);
|
||||
YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
|
||||
YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
|
||||
YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
|
||||
YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
|
||||
}
|
||||
};
|
||||
|
||||
struct MachineFunction {
|
||||
StringRef Name;
|
||||
unsigned Alignment = 0;
|
||||
@ -123,9 +268,13 @@ struct MachineFunction {
|
||||
bool IsSSA = false;
|
||||
bool TracksRegLiveness = false;
|
||||
bool TracksSubRegLiveness = false;
|
||||
// TODO: Serialize virtual register definitions.
|
||||
std::vector<VirtualRegisterDefinition> VirtualRegisters;
|
||||
// TODO: Serialize the various register masks.
|
||||
// TODO: Serialize live in registers.
|
||||
// Frame information
|
||||
MachineFrameInfo FrameInfo;
|
||||
std::vector<FixedMachineStackObject> FixedStackObjects;
|
||||
std::vector<MachineStackObject> StackObjects;
|
||||
|
||||
std::vector<MachineBasicBlock> BasicBlocks;
|
||||
};
|
||||
@ -139,6 +288,10 @@ template <> struct MappingTraits<MachineFunction> {
|
||||
YamlIO.mapOptional("isSSA", MF.IsSSA);
|
||||
YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness);
|
||||
YamlIO.mapOptional("tracksSubRegLiveness", MF.TracksSubRegLiveness);
|
||||
YamlIO.mapOptional("registers", MF.VirtualRegisters);
|
||||
YamlIO.mapOptional("frameInfo", MF.FrameInfo);
|
||||
YamlIO.mapOptional("fixedStack", MF.FixedStackObjects);
|
||||
YamlIO.mapOptional("stack", MF.StackObjects);
|
||||
YamlIO.mapOptional("body", MF.BasicBlocks);
|
||||
}
|
||||
};
|
||||
|
@ -135,17 +135,18 @@ class MachineConstantPoolEntry {
|
||||
/// address of the function constant pool values.
|
||||
/// @brief The machine constant pool.
|
||||
class MachineConstantPool {
|
||||
const TargetMachine &TM; ///< The target machine.
|
||||
unsigned PoolAlignment; ///< The alignment for the pool.
|
||||
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
|
||||
/// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
|
||||
DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
|
||||
const DataLayout &DL;
|
||||
|
||||
const DataLayout &getDataLayout() const { return DL; }
|
||||
|
||||
const DataLayout *getDataLayout() const;
|
||||
public:
|
||||
/// @brief The only constructor.
|
||||
explicit MachineConstantPool(const TargetMachine &TM)
|
||||
: TM(TM), PoolAlignment(1) {}
|
||||
explicit MachineConstantPool(const DataLayout &DL)
|
||||
: PoolAlignment(1), DL(DL) {}
|
||||
~MachineConstantPool();
|
||||
|
||||
/// getConstantPoolAlignment - Return the alignment required by
|
||||
|
@ -29,8 +29,8 @@ inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB
|
||||
this->Roots.push_back(MBB);
|
||||
}
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>);
|
||||
extern template class DomTreeNodeBase<MachineBasicBlock>;
|
||||
extern template class DominatorTreeBase<MachineBasicBlock>;
|
||||
|
||||
typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
|
||||
|
||||
|
@ -229,9 +229,9 @@ class MachineFrameInfo {
|
||||
/// Whether the "realign-stack" option is on.
|
||||
bool RealignOption;
|
||||
|
||||
/// True if the function includes inline assembly that adjusts the stack
|
||||
/// pointer.
|
||||
bool HasInlineAsmWithSPAdjust;
|
||||
/// True if the function dynamically adjusts the stack pointer through some
|
||||
/// opaque mechanism like inline assembly or Win32 EH.
|
||||
bool HasOpaqueSPAdjustment;
|
||||
|
||||
/// True if the function contains a call to the llvm.vastart intrinsic.
|
||||
bool HasVAStart;
|
||||
@ -269,7 +269,7 @@ class MachineFrameInfo {
|
||||
LocalFrameSize = 0;
|
||||
LocalFrameMaxAlign = 0;
|
||||
UseLocalStackAllocationBlock = false;
|
||||
HasInlineAsmWithSPAdjust = false;
|
||||
HasOpaqueSPAdjustment = false;
|
||||
HasVAStart = false;
|
||||
HasMustTailInVarArgFunc = false;
|
||||
Save = nullptr;
|
||||
@ -468,9 +468,9 @@ class MachineFrameInfo {
|
||||
bool hasCalls() const { return HasCalls; }
|
||||
void setHasCalls(bool V) { HasCalls = V; }
|
||||
|
||||
/// Returns true if the function contains any stack-adjusting inline assembly.
|
||||
bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
|
||||
void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
|
||||
/// Returns true if the function contains opaque dynamic stack adjustments.
|
||||
bool hasOpaqueSPAdjustment() const { return HasOpaqueSPAdjustment; }
|
||||
void setHasOpaqueSPAdjustment(bool B) { HasOpaqueSPAdjustment = B; }
|
||||
|
||||
/// Returns true if the function calls the llvm.va_start intrinsic.
|
||||
bool hasVAStart() const { return HasVAStart; }
|
||||
@ -541,6 +541,14 @@ class MachineFrameInfo {
|
||||
return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
|
||||
}
|
||||
|
||||
/// Returns true if the specified index corresponds to a variable sized
|
||||
/// object.
|
||||
bool isVariableSizedObjectIndex(int ObjectIdx) const {
|
||||
assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
|
||||
"Invalid Object Idx!");
|
||||
return Objects[ObjectIdx + NumFixedObjects].Size == 0;
|
||||
}
|
||||
|
||||
/// Create a new statically sized stack object, returning
|
||||
/// a nonnegative identifier to represent it.
|
||||
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
|
||||
|
@ -155,6 +155,9 @@ class MachineFunction {
|
||||
MachineModuleInfo &getMMI() const { return MMI; }
|
||||
MCContext &getContext() const { return Ctx; }
|
||||
|
||||
/// Return the DataLayout attached to the Module associated to this MF.
|
||||
const DataLayout &getDataLayout() const;
|
||||
|
||||
/// getFunction - Return the LLVM function that this machine code represents
|
||||
///
|
||||
const Function *getFunction() const { return Fn; }
|
||||
|
@ -37,10 +37,8 @@
|
||||
namespace llvm {
|
||||
|
||||
// Implementation in LoopInfoImpl.h
|
||||
#ifdef __GNUC__
|
||||
class MachineLoop;
|
||||
__extension__ extern template class LoopBase<MachineBasicBlock, MachineLoop>;
|
||||
#endif
|
||||
extern template class LoopBase<MachineBasicBlock, MachineLoop>;
|
||||
|
||||
class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
|
||||
public:
|
||||
@ -65,10 +63,7 @@ class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
|
||||
};
|
||||
|
||||
// Implementation in LoopInfoImpl.h
|
||||
#ifdef __GNUC__
|
||||
__extension__ extern template
|
||||
class LoopInfoBase<MachineBasicBlock, MachineLoop>;
|
||||
#endif
|
||||
extern template class LoopInfoBase<MachineBasicBlock, MachineLoop>;
|
||||
|
||||
class MachineLoopInfo : public MachineFunctionPass {
|
||||
LoopInfoBase<MachineBasicBlock, MachineLoop> LI;
|
||||
|
@ -320,6 +320,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
/// information.
|
||||
void addPersonality(MachineBasicBlock *LandingPad,
|
||||
const Function *Personality);
|
||||
void addPersonality(const Function *Personality);
|
||||
|
||||
void addWinEHState(MachineBasicBlock *LandingPad, int State);
|
||||
|
||||
|
@ -172,10 +172,9 @@ template <> struct GraphTraits<MachineRegionInfoPass*>
|
||||
}
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>);
|
||||
|
||||
extern template class RegionBase<RegionTraits<MachineFunction>>;
|
||||
extern template class RegionNodeBase<RegionTraits<MachineFunction>>;
|
||||
extern template class RegionInfoBase<RegionTraits<MachineFunction>>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -95,20 +95,8 @@ class MachineRegisterInfo {
|
||||
return MO->Contents.Reg.Next;
|
||||
}
|
||||
|
||||
/// UsedRegUnits - This is a bit vector that is computed and set by the
|
||||
/// register allocator, and must be kept up to date by passes that run after
|
||||
/// register allocation (though most don't modify this). This is used
|
||||
/// so that the code generator knows which callee save registers to save and
|
||||
/// for other target specific uses.
|
||||
/// This vector has bits set for register units that are modified in the
|
||||
/// current function. It doesn't include registers clobbered by function
|
||||
/// calls with register mask operands.
|
||||
BitVector UsedRegUnits;
|
||||
|
||||
/// UsedPhysRegMask - Additional used physregs including aliases.
|
||||
/// This bit vector represents all the registers clobbered by function calls.
|
||||
/// It can model things that UsedRegUnits can't, such as function calls that
|
||||
/// clobber ymm7 but preserve the low half in xmm7.
|
||||
BitVector UsedPhysRegMask;
|
||||
|
||||
/// ReservedRegs - This is a bit vector of reserved registers. The target
|
||||
@ -647,40 +635,11 @@ class MachineRegisterInfo {
|
||||
/// deleted during LiveDebugVariables analysis.
|
||||
void markUsesInDebugValueAsUndef(unsigned Reg) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Physical Register Use Info
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// isPhysRegUsed - Return true if the specified register is used in this
|
||||
/// function. Also check for clobbered aliases and registers clobbered by
|
||||
/// function calls with register mask operands.
|
||||
///
|
||||
/// This only works after register allocation. It is primarily used by
|
||||
/// PrologEpilogInserter to determine which callee-saved registers need
|
||||
/// spilling.
|
||||
bool isPhysRegUsed(unsigned Reg) const {
|
||||
if (UsedPhysRegMask.test(Reg))
|
||||
return true;
|
||||
for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
|
||||
Units.isValid(); ++Units)
|
||||
if (UsedRegUnits.test(*Units))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Mark the specified register unit as used in this function.
|
||||
/// This should only be called during and after register allocation.
|
||||
void setRegUnitUsed(unsigned RegUnit) {
|
||||
UsedRegUnits.set(RegUnit);
|
||||
}
|
||||
|
||||
/// setPhysRegUsed - Mark the specified register used in this function.
|
||||
/// This should only be called during and after register allocation.
|
||||
void setPhysRegUsed(unsigned Reg) {
|
||||
for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
|
||||
Units.isValid(); ++Units)
|
||||
UsedRegUnits.set(*Units);
|
||||
}
|
||||
/// Return true if the specified register is modified in this function.
|
||||
/// This checks that no defining machine operands exist for the register or
|
||||
/// any of its aliases. Definitions found on functions marked noreturn are
|
||||
/// ignored.
|
||||
bool isPhysRegModified(unsigned PhysReg) const;
|
||||
|
||||
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
|
||||
/// This corresponds to the bit mask attached to register mask operands.
|
||||
@ -688,16 +647,6 @@ class MachineRegisterInfo {
|
||||
UsedPhysRegMask.setBitsNotInMask(RegMask);
|
||||
}
|
||||
|
||||
/// setPhysRegUnused - Mark the specified register unused in this function.
|
||||
/// This should only be called during and after register allocation.
|
||||
void setPhysRegUnused(unsigned Reg) {
|
||||
UsedPhysRegMask.reset(Reg);
|
||||
for (MCRegUnitIterator Units(Reg, getTargetRegisterInfo());
|
||||
Units.isValid(); ++Units)
|
||||
UsedRegUnits.reset(*Units);
|
||||
}
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Reserved Register Info
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -101,7 +101,7 @@ class TargetPassConfig : public ImmutablePass {
|
||||
|
||||
private:
|
||||
PassManagerBase *PM;
|
||||
AnalysisID StartAfter;
|
||||
AnalysisID StartBefore, StartAfter;
|
||||
AnalysisID StopAfter;
|
||||
bool Started;
|
||||
bool Stopped;
|
||||
@ -142,16 +142,24 @@ class TargetPassConfig : public ImmutablePass {
|
||||
|
||||
CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
|
||||
|
||||
/// setStartStopPasses - Set the StartAfter and StopAfter passes to allow
|
||||
/// running only a portion of the normal code-gen pass sequence. If the
|
||||
/// Start pass ID is zero, then compilation will begin at the normal point;
|
||||
/// otherwise, clear the Started flag to indicate that passes should not be
|
||||
/// added until the starting pass is seen. If the Stop pass ID is zero,
|
||||
/// then compilation will continue to the end.
|
||||
void setStartStopPasses(AnalysisID Start, AnalysisID Stop) {
|
||||
StartAfter = Start;
|
||||
StopAfter = Stop;
|
||||
Started = (StartAfter == nullptr);
|
||||
/// Set the StartAfter, StartBefore and StopAfter passes to allow running only
|
||||
/// a portion of the normal code-gen pass sequence.
|
||||
///
|
||||
/// If the StartAfter and StartBefore pass ID is zero, then compilation will
|
||||
/// begin at the normal point; otherwise, clear the Started flag to indicate
|
||||
/// that passes should not be added until the starting pass is seen. If the
|
||||
/// Stop pass ID is zero, then compilation will continue to the end.
|
||||
///
|
||||
/// This function expects that at least one of the StartAfter or the
|
||||
/// StartBefore pass IDs is null.
|
||||
void setStartStopPasses(AnalysisID StartBefore, AnalysisID StartAfter,
|
||||
AnalysisID StopAfter) {
|
||||
if (StartAfter)
|
||||
assert(!StartBefore && "Start after and start before passes are given");
|
||||
this->StartBefore = StartBefore;
|
||||
this->StartAfter = StartAfter;
|
||||
this->StopAfter = StopAfter;
|
||||
Started = (StartAfter == nullptr) && (StartBefore == nullptr);
|
||||
}
|
||||
|
||||
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
|
||||
@ -597,7 +605,7 @@ namespace llvm {
|
||||
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
|
||||
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
|
||||
///
|
||||
FunctionPass *createSjLjEHPreparePass(const TargetMachine *TM);
|
||||
FunctionPass *createSjLjEHPreparePass();
|
||||
|
||||
/// LocalStackSlotAllocation - This pass assigns local frame indices to stack
|
||||
/// slots relative to one another and allocates base registers to access them
|
||||
|
@ -135,6 +135,8 @@ class PressureDiff {
|
||||
|
||||
void addPressureChange(unsigned RegUnit, bool IsDec,
|
||||
const MachineRegisterInfo *MRI);
|
||||
|
||||
LLVM_DUMP_METHOD void dump(const TargetRegisterInfo &TRI) const;
|
||||
};
|
||||
|
||||
/// Array of PressureDiffs.
|
||||
|
@ -281,6 +281,7 @@ class SelectionDAG {
|
||||
void clear();
|
||||
|
||||
MachineFunction &getMachineFunction() const { return *MF; }
|
||||
const DataLayout &getDataLayout() const { return MF->getDataLayout(); }
|
||||
const TargetMachine &getTarget() const { return TM; }
|
||||
const TargetSubtargetInfo &getSubtarget() const { return MF->getSubtarget(); }
|
||||
const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
|
||||
@ -322,6 +323,14 @@ class SelectionDAG {
|
||||
return AllNodes.size();
|
||||
}
|
||||
|
||||
iterator_range<allnodes_iterator> allnodes() {
|
||||
return iterator_range<allnodes_iterator>(allnodes_begin(), allnodes_end());
|
||||
}
|
||||
iterator_range<allnodes_const_iterator> allnodes() const {
|
||||
return iterator_range<allnodes_const_iterator>(allnodes_begin(),
|
||||
allnodes_end());
|
||||
}
|
||||
|
||||
/// Return the root tag of the SelectionDAG.
|
||||
const SDValue &getRoot() const { return Root; }
|
||||
|
||||
|
@ -140,7 +140,7 @@ class SDValue {
|
||||
}
|
||||
|
||||
// Return true if this node is an operand of N.
|
||||
bool isOperandOf(SDNode *N) const;
|
||||
bool isOperandOf(const SDNode *N) const;
|
||||
|
||||
/// Return the ValueType of the referenced return value.
|
||||
inline EVT getValueType() const;
|
||||
@ -357,9 +357,6 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
|
||||
/// The number of entries in the Operand/Value list.
|
||||
unsigned short NumOperands, NumValues;
|
||||
|
||||
/// Source line information.
|
||||
DebugLoc debugLoc;
|
||||
|
||||
// The ordering of the SDNodes. It roughly corresponds to the ordering of the
|
||||
// original LLVM instructions.
|
||||
// This is used for turning off scheduling, because we'll forgo
|
||||
@ -367,6 +364,9 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
|
||||
// this ordering.
|
||||
unsigned IROrder;
|
||||
|
||||
/// Source line information.
|
||||
DebugLoc debugLoc;
|
||||
|
||||
/// Return a pointer to the specified value type.
|
||||
static const EVT *getValueTypeList(EVT VT);
|
||||
|
||||
@ -532,10 +532,10 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
|
||||
bool hasAnyUseOfValue(unsigned Value) const;
|
||||
|
||||
/// Return true if this node is the only use of N.
|
||||
bool isOnlyUserOf(SDNode *N) const;
|
||||
bool isOnlyUserOf(const SDNode *N) const;
|
||||
|
||||
/// Return true if this node is an operand of N.
|
||||
bool isOperandOf(SDNode *N) const;
|
||||
bool isOperandOf(const SDNode *N) const;
|
||||
|
||||
/// Return true if this node is a predecessor of N.
|
||||
/// NOTE: Implemented on top of hasPredecessor and every bit as
|
||||
@ -732,7 +732,7 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
|
||||
SubclassData(0), NodeId(-1),
|
||||
OperandList(Ops.size() ? new SDUse[Ops.size()] : nullptr),
|
||||
ValueList(VTs.VTs), UseList(nullptr), NumOperands(Ops.size()),
|
||||
NumValues(VTs.NumVTs), debugLoc(std::move(dl)), IROrder(Order) {
|
||||
NumValues(VTs.NumVTs), IROrder(Order), debugLoc(std::move(dl)) {
|
||||
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
|
||||
assert(NumOperands == Ops.size() &&
|
||||
"NumOperands wasn't wide enough for its operands!");
|
||||
@ -752,7 +752,7 @@ class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
|
||||
: NodeType(Opc), OperandsNeedDelete(false), HasDebugValue(false),
|
||||
SubclassData(0), NodeId(-1), OperandList(nullptr), ValueList(VTs.VTs),
|
||||
UseList(nullptr), NumOperands(0), NumValues(VTs.NumVTs),
|
||||
debugLoc(std::move(dl)), IROrder(Order) {
|
||||
IROrder(Order), debugLoc(std::move(dl)) {
|
||||
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
|
||||
assert(NumValues == VTs.NumVTs &&
|
||||
"NumValues wasn't wide enough for its operands!");
|
||||
|
@ -1,5 +1,4 @@
|
||||
//===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===//
|
||||
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -42,10 +41,12 @@ class PatchPointOpers {
|
||||
public:
|
||||
/// Enumerate the meta operands.
|
||||
enum { IDPos, NBytesPos, TargetPos, NArgPos, CCPos, MetaEnd };
|
||||
|
||||
private:
|
||||
const MachineInstr *MI;
|
||||
bool HasDef;
|
||||
bool IsAnyReg;
|
||||
|
||||
public:
|
||||
explicit PatchPointOpers(const MachineInstr *MI);
|
||||
|
||||
@ -66,8 +67,8 @@ class PatchPointOpers {
|
||||
/// Get the operand index of the variable list of non-argument operands.
|
||||
/// These hold the "live state".
|
||||
unsigned getVarIdx() const {
|
||||
return getMetaIdx() + MetaEnd
|
||||
+ MI->getOperand(getMetaIdx(NArgPos)).getImm();
|
||||
return getMetaIdx() + MetaEnd +
|
||||
MI->getOperand(getMetaIdx(NArgPos)).getImm();
|
||||
}
|
||||
|
||||
/// Get the index at which stack map locations will be recorded.
|
||||
@ -98,15 +99,10 @@ class StatepointOpers {
|
||||
|
||||
// These values are relative offests from the start of the statepoint meta
|
||||
// arguments (i.e. the end of the call arguments).
|
||||
enum {
|
||||
CCOffset = 1,
|
||||
FlagsOffset = 3,
|
||||
NumVMSArgsOffset = 5
|
||||
};
|
||||
enum { CCOffset = 1, FlagsOffset = 3, NumVMSArgsOffset = 5 };
|
||||
|
||||
public:
|
||||
explicit StatepointOpers(const MachineInstr *MI):
|
||||
MI(MI) { }
|
||||
explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
|
||||
|
||||
/// Get starting index of non call related arguments
|
||||
/// (calling convention, statepoint flags, vm state and gc state).
|
||||
@ -134,31 +130,32 @@ class StatepointOpers {
|
||||
class StackMaps {
|
||||
public:
|
||||
struct Location {
|
||||
enum LocationType { Unprocessed, Register, Direct, Indirect, Constant,
|
||||
ConstantIndex };
|
||||
LocationType LocType;
|
||||
enum LocationType {
|
||||
Unprocessed,
|
||||
Register,
|
||||
Direct,
|
||||
Indirect,
|
||||
Constant,
|
||||
ConstantIndex
|
||||
};
|
||||
LocationType Type;
|
||||
unsigned Size;
|
||||
unsigned Reg;
|
||||
int64_t Offset;
|
||||
Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0) {}
|
||||
Location(LocationType LocType, unsigned Size, unsigned Reg, int64_t Offset)
|
||||
: LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
|
||||
Location() : Type(Unprocessed), Size(0), Reg(0), Offset(0) {}
|
||||
Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset)
|
||||
: Type(Type), Size(Size), Reg(Reg), Offset(Offset) {}
|
||||
};
|
||||
|
||||
struct LiveOutReg {
|
||||
unsigned short Reg;
|
||||
unsigned short RegNo;
|
||||
unsigned short DwarfRegNum;
|
||||
unsigned short Size;
|
||||
|
||||
LiveOutReg() : Reg(0), RegNo(0), Size(0) {}
|
||||
LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size)
|
||||
: Reg(Reg), RegNo(RegNo), Size(Size) {}
|
||||
|
||||
void MarkInvalid() { Reg = 0; }
|
||||
|
||||
// Only sort by the dwarf register number.
|
||||
bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; }
|
||||
static bool IsInvalid(const LiveOutReg &LO) { return LO.Reg == 0; }
|
||||
LiveOutReg() : Reg(0), DwarfRegNum(0), Size(0) {}
|
||||
LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum,
|
||||
unsigned short Size)
|
||||
: Reg(Reg), DwarfRegNum(DwarfRegNum), Size(Size) {}
|
||||
};
|
||||
|
||||
// OpTypes are used to encode information about the following logical
|
||||
@ -205,8 +202,8 @@ class StackMaps {
|
||||
CallsiteInfo() : CSOffsetExpr(nullptr), ID(0) {}
|
||||
CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
|
||||
LocationVec &&Locations, LiveOutVec &&LiveOuts)
|
||||
: CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
|
||||
LiveOuts(std::move(LiveOuts)) {}
|
||||
: CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
|
||||
LiveOuts(std::move(LiveOuts)) {}
|
||||
};
|
||||
|
||||
typedef std::vector<CallsiteInfo> CallsiteInfoList;
|
||||
@ -218,8 +215,8 @@ class StackMaps {
|
||||
|
||||
MachineInstr::const_mop_iterator
|
||||
parseOperand(MachineInstr::const_mop_iterator MOI,
|
||||
MachineInstr::const_mop_iterator MOE,
|
||||
LocationVec &Locs, LiveOutVec &LiveOuts) const;
|
||||
MachineInstr::const_mop_iterator MOE, LocationVec &Locs,
|
||||
LiveOutVec &LiveOuts) const;
|
||||
|
||||
/// \brief Create a live-out register record for the given register @p Reg.
|
||||
LiveOutReg createLiveOutReg(unsigned Reg,
|
||||
@ -254,7 +251,6 @@ class StackMaps {
|
||||
void print(raw_ostream &OS);
|
||||
void debug() { print(dbgs()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -91,7 +91,7 @@ class CatchHandler : public ActionHandler {
|
||||
// When the parseEHActions function is called to populate a vector of
|
||||
// instances of this class, the ExceptionObjectVar field will be nullptr
|
||||
// and the ExceptionObjectIndex will be the index of the exception object in
|
||||
// the parent function's frameescape block.
|
||||
// the parent function's localescape block.
|
||||
const Value *ExceptionObjectVar;
|
||||
int ExceptionObjectIndex;
|
||||
TinyPtrVector<BasicBlock *> ReturnTargets;
|
||||
@ -148,7 +148,7 @@ struct WinEHFuncInfo {
|
||||
int UnwindHelpFrameOffset = -1;
|
||||
unsigned NumIPToStateFuncsVisited = 0;
|
||||
|
||||
/// frameescape index of the 32-bit EH registration node. Set by
|
||||
/// localescape index of the 32-bit EH registration node. Set by
|
||||
/// WinEHStatePass and used indirectly by SEH filter functions of the parent.
|
||||
int EHRegNodeEscapeIndex = INT_MAX;
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -89,6 +90,8 @@ class ExecutionEngineState {
|
||||
uint64_t RemoveMapping(StringRef Name);
|
||||
};
|
||||
|
||||
using FunctionCreator = std::function<void *(const std::string &)>;
|
||||
|
||||
/// \brief Abstract interface for implementation execution of LLVM modules,
|
||||
/// designed to support both interpreter and just-in-time (JIT) compiler
|
||||
/// implementations.
|
||||
@ -147,7 +150,7 @@ class ExecutionEngine {
|
||||
/// LazyFunctionCreator - If an unknown function is needed, this function
|
||||
/// pointer is invoked to create it. If this returns null, the JIT will
|
||||
/// abort.
|
||||
void *(*LazyFunctionCreator)(const std::string &);
|
||||
FunctionCreator LazyFunctionCreator;
|
||||
|
||||
/// getMangledName - Get mangled name.
|
||||
std::string getMangledName(const GlobalValue *GV);
|
||||
@ -470,8 +473,8 @@ class ExecutionEngine {
|
||||
/// InstallLazyFunctionCreator - If an unknown function is needed, the
|
||||
/// specified function pointer is invoked to create it. If it returns null,
|
||||
/// the JIT will abort.
|
||||
void InstallLazyFunctionCreator(void* (*P)(const std::string &)) {
|
||||
LazyFunctionCreator = P;
|
||||
void InstallLazyFunctionCreator(FunctionCreator C) {
|
||||
LazyFunctionCreator = C;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -153,6 +153,10 @@ class RuntimeDyld {
|
||||
|
||||
/// This method returns the address of the specified function or variable.
|
||||
/// It is used to resolve symbols during module linking.
|
||||
///
|
||||
/// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
|
||||
/// skip all relocations for that symbol, and the client will be responsible
|
||||
/// for handling them manually.
|
||||
virtual SymbolInfo findSymbol(const std::string &Name) = 0;
|
||||
|
||||
/// This method returns the address of the specified symbol if it exists
|
||||
|
@ -98,6 +98,8 @@ class Attribute {
|
||||
OptimizeNone, ///< Function must not be optimized.
|
||||
ReadNone, ///< Function does not access memory
|
||||
ReadOnly, ///< Function only reads from memory
|
||||
ArgMemOnly, ///< Funciton can access memory only using pointers
|
||||
///< based on its arguments.
|
||||
Returned, ///< Return value is always equal to this argument
|
||||
ReturnsTwice, ///< Function can return twice
|
||||
SExt, ///< Sign extended before/after call
|
||||
|
@ -290,6 +290,15 @@ class CallSiteBase {
|
||||
CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
|
||||
}
|
||||
|
||||
/// @brief Determine if the call can access memmory only using pointers based
|
||||
/// on its arguments.
|
||||
bool onlyAccessesArgMemory() const {
|
||||
CALLSITE_DELEGATE_GETTER(onlyAccessesArgMemory());
|
||||
}
|
||||
void setOnlyAccessesArgMemory() {
|
||||
CALLSITE_DELEGATE_SETTER(setOnlyAccessesArgMemory());
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const {
|
||||
CALLSITE_DELEGATE_GETTER(doesNotReturn());
|
||||
|
@ -47,7 +47,7 @@ namespace llvm {
|
||||
SmallVector<Metadata *, 4> AllGVs;
|
||||
SmallVector<TrackingMDNodeRef, 4> AllImportedModules;
|
||||
|
||||
/// \brief Track nodes that may be unresolved.
|
||||
/// Track nodes that may be unresolved.
|
||||
SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;
|
||||
bool AllowUnresolvedNodes;
|
||||
|
||||
@ -57,49 +57,52 @@ namespace llvm {
|
||||
DIBuilder(const DIBuilder &) = delete;
|
||||
void operator=(const DIBuilder &) = delete;
|
||||
|
||||
/// \brief Create a temporary.
|
||||
/// Create a temporary.
|
||||
///
|
||||
/// Create an \a temporary node and track it in \a UnresolvedNodes.
|
||||
void trackIfUnresolved(MDNode *N);
|
||||
|
||||
public:
|
||||
/// \brief Construct a builder for a module.
|
||||
/// Construct a builder for a module.
|
||||
///
|
||||
/// If \c AllowUnresolved, collect unresolved nodes attached to the module
|
||||
/// in order to resolve cycles during \a finalize().
|
||||
explicit DIBuilder(Module &M, bool AllowUnresolved = true);
|
||||
enum DebugEmissionKind { FullDebug=1, LineTablesOnly };
|
||||
|
||||
/// finalize - Construct any deferred debug info descriptors.
|
||||
/// Construct any deferred debug info descriptors.
|
||||
void finalize();
|
||||
|
||||
/// createCompileUnit - A CompileUnit provides an anchor for all debugging
|
||||
/// A CompileUnit provides an anchor for all debugging
|
||||
/// information generated during this instance of compilation.
|
||||
/// @param Lang Source programming language, eg. dwarf::DW_LANG_C99
|
||||
/// @param File File name
|
||||
/// @param Dir Directory
|
||||
/// @param Producer Identify the producer of debugging information and code.
|
||||
/// Usually this is a compiler version string.
|
||||
/// @param isOptimized A boolean flag which indicates whether optimization
|
||||
/// is ON or not.
|
||||
/// @param Flags This string lists command line options. This string is
|
||||
/// directly embedded in debug info output which may be used
|
||||
/// by a tool analyzing generated debugging information.
|
||||
/// @param RV This indicates runtime version for languages like
|
||||
/// Objective-C.
|
||||
/// @param SplitName The name of the file that we'll split debug info out
|
||||
/// into.
|
||||
/// @param Kind The kind of debug information to generate.
|
||||
/// @param DWOId The DWOId if this is a split skeleton compile unit.
|
||||
/// @param EmitDebugInfo A boolean flag which indicates whether debug
|
||||
/// information should be written to the final
|
||||
/// output or not. When this is false, debug
|
||||
/// information annotations will be present in
|
||||
/// the IL but they are not written to the final
|
||||
/// assembly or object file. This supports tracking
|
||||
/// source location information in the back end
|
||||
/// without actually changing the output (e.g.,
|
||||
/// when using optimization remarks).
|
||||
/// \param Lang Source programming language, eg. dwarf::DW_LANG_C99
|
||||
/// \param File File name
|
||||
/// \param Dir Directory
|
||||
/// \param Producer Identify the producer of debugging information
|
||||
/// and code. Usually this is a compiler
|
||||
/// version string.
|
||||
/// \param isOptimized A boolean flag which indicates whether optimization
|
||||
/// is enabled or not.
|
||||
/// \param Flags This string lists command line options. This
|
||||
/// string is directly embedded in debug info
|
||||
/// output which may be used by a tool
|
||||
/// analyzing generated debugging information.
|
||||
/// \param RV This indicates runtime version for languages like
|
||||
/// Objective-C.
|
||||
/// \param SplitName The name of the file that we'll split debug info
|
||||
/// out into.
|
||||
/// \param Kind The kind of debug information to generate.
|
||||
/// \param DWOId The DWOId if this is a split skeleton compile unit.
|
||||
/// \param EmitDebugInfo A boolean flag which indicates whether
|
||||
/// debug information should be written to
|
||||
/// the final output or not. When this is
|
||||
/// false, debug information annotations will
|
||||
/// be present in the IL but they are not
|
||||
/// written to the final assembly or object
|
||||
/// file. This supports tracking source
|
||||
/// location information in the back end
|
||||
/// without actually changing the output
|
||||
/// (e.g., when using optimization remarks).
|
||||
DICompileUnit *
|
||||
createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
|
||||
StringRef Producer, bool isOptimized, StringRef Flags,
|
||||
@ -107,155 +110,155 @@ namespace llvm {
|
||||
DebugEmissionKind Kind = FullDebug, uint64_t DWOId = 0,
|
||||
bool EmitDebugInfo = true);
|
||||
|
||||
/// createFile - Create a file descriptor to hold debugging information
|
||||
/// Create a file descriptor to hold debugging information
|
||||
/// for a file.
|
||||
DIFile *createFile(StringRef Filename, StringRef Directory);
|
||||
|
||||
/// createEnumerator - Create a single enumerator value.
|
||||
/// Create a single enumerator value.
|
||||
DIEnumerator *createEnumerator(StringRef Name, int64_t Val);
|
||||
|
||||
/// \brief Create a DWARF unspecified type.
|
||||
/// Create a DWARF unspecified type.
|
||||
DIBasicType *createUnspecifiedType(StringRef Name);
|
||||
|
||||
/// \brief Create C++11 nullptr type.
|
||||
/// Create C++11 nullptr type.
|
||||
DIBasicType *createNullPtrType();
|
||||
|
||||
/// createBasicType - Create debugging information entry for a basic
|
||||
/// Create debugging information entry for a basic
|
||||
/// type.
|
||||
/// @param Name Type name.
|
||||
/// @param SizeInBits Size of the type.
|
||||
/// @param AlignInBits Type alignment.
|
||||
/// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
|
||||
/// \param Name Type name.
|
||||
/// \param SizeInBits Size of the type.
|
||||
/// \param AlignInBits Type alignment.
|
||||
/// \param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
|
||||
DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
|
||||
uint64_t AlignInBits, unsigned Encoding);
|
||||
|
||||
/// createQualifiedType - Create debugging information entry for a qualified
|
||||
/// Create debugging information entry for a qualified
|
||||
/// type, e.g. 'const int'.
|
||||
/// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
|
||||
/// @param FromTy Base Type.
|
||||
/// \param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
|
||||
/// \param FromTy Base Type.
|
||||
DIDerivedType *createQualifiedType(unsigned Tag, DIType *FromTy);
|
||||
|
||||
/// createPointerType - Create debugging information entry for a pointer.
|
||||
/// @param PointeeTy Type pointed by this pointer.
|
||||
/// @param SizeInBits Size.
|
||||
/// @param AlignInBits Alignment. (optional)
|
||||
/// @param Name Pointer type name. (optional)
|
||||
/// Create debugging information entry for a pointer.
|
||||
/// \param PointeeTy Type pointed by this pointer.
|
||||
/// \param SizeInBits Size.
|
||||
/// \param AlignInBits Alignment. (optional)
|
||||
/// \param Name Pointer type name. (optional)
|
||||
DIDerivedType *createPointerType(DIType *PointeeTy, uint64_t SizeInBits,
|
||||
uint64_t AlignInBits = 0,
|
||||
StringRef Name = "");
|
||||
|
||||
/// \brief Create debugging information entry for a pointer to member.
|
||||
/// @param PointeeTy Type pointed to by this pointer.
|
||||
/// @param SizeInBits Size.
|
||||
/// @param AlignInBits Alignment. (optional)
|
||||
/// @param Class Type for which this pointer points to members of.
|
||||
/// Create debugging information entry for a pointer to member.
|
||||
/// \param PointeeTy Type pointed to by this pointer.
|
||||
/// \param SizeInBits Size.
|
||||
/// \param AlignInBits Alignment. (optional)
|
||||
/// \param Class Type for which this pointer points to members of.
|
||||
DIDerivedType *createMemberPointerType(DIType *PointeeTy, DIType *Class,
|
||||
uint64_t SizeInBits,
|
||||
uint64_t AlignInBits = 0);
|
||||
|
||||
/// createReferenceType - Create debugging information entry for a c++
|
||||
/// Create debugging information entry for a c++
|
||||
/// style reference or rvalue reference type.
|
||||
DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy);
|
||||
|
||||
/// createTypedef - Create debugging information entry for a typedef.
|
||||
/// @param Ty Original type.
|
||||
/// @param Name Typedef name.
|
||||
/// @param File File where this type is defined.
|
||||
/// @param LineNo Line number.
|
||||
/// @param Context The surrounding context for the typedef.
|
||||
/// Create debugging information entry for a typedef.
|
||||
/// \param Ty Original type.
|
||||
/// \param Name Typedef name.
|
||||
/// \param File File where this type is defined.
|
||||
/// \param LineNo Line number.
|
||||
/// \param Context The surrounding context for the typedef.
|
||||
DIDerivedType *createTypedef(DIType *Ty, StringRef Name, DIFile *File,
|
||||
unsigned LineNo, DIScope *Context);
|
||||
|
||||
/// createFriend - Create debugging information entry for a 'friend'.
|
||||
/// Create debugging information entry for a 'friend'.
|
||||
DIDerivedType *createFriend(DIType *Ty, DIType *FriendTy);
|
||||
|
||||
/// createInheritance - Create debugging information entry to establish
|
||||
/// Create debugging information entry to establish
|
||||
/// inheritance relationship between two types.
|
||||
/// @param Ty Original type.
|
||||
/// @param BaseTy Base type. Ty is inherits from base.
|
||||
/// @param BaseOffset Base offset.
|
||||
/// @param Flags Flags to describe inheritance attribute,
|
||||
/// \param Ty Original type.
|
||||
/// \param BaseTy Base type. Ty is inherits from base.
|
||||
/// \param BaseOffset Base offset.
|
||||
/// \param Flags Flags to describe inheritance attribute,
|
||||
/// e.g. private
|
||||
DIDerivedType *createInheritance(DIType *Ty, DIType *BaseTy,
|
||||
uint64_t BaseOffset, unsigned Flags);
|
||||
|
||||
/// createMemberType - Create debugging information entry for a member.
|
||||
/// @param Scope Member scope.
|
||||
/// @param Name Member name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNo Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param OffsetInBits Member offset.
|
||||
/// @param Flags Flags to encode member attribute, e.g. private
|
||||
/// @param Ty Parent type.
|
||||
/// Create debugging information entry for a member.
|
||||
/// \param Scope Member scope.
|
||||
/// \param Name Member name.
|
||||
/// \param File File where this member is defined.
|
||||
/// \param LineNo Line number.
|
||||
/// \param SizeInBits Member size.
|
||||
/// \param AlignInBits Member alignment.
|
||||
/// \param OffsetInBits Member offset.
|
||||
/// \param Flags Flags to encode member attribute, e.g. private
|
||||
/// \param Ty Parent type.
|
||||
DIDerivedType *createMemberType(DIScope *Scope, StringRef Name,
|
||||
DIFile *File, unsigned LineNo,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits,
|
||||
uint64_t OffsetInBits, unsigned Flags,
|
||||
DIType *Ty);
|
||||
|
||||
/// createStaticMemberType - Create debugging information entry for a
|
||||
/// Create debugging information entry for a
|
||||
/// C++ static data member.
|
||||
/// @param Scope Member scope.
|
||||
/// @param Name Member name.
|
||||
/// @param File File where this member is declared.
|
||||
/// @param LineNo Line number.
|
||||
/// @param Ty Type of the static member.
|
||||
/// @param Flags Flags to encode member attribute, e.g. private.
|
||||
/// @param Val Const initializer of the member.
|
||||
/// \param Scope Member scope.
|
||||
/// \param Name Member name.
|
||||
/// \param File File where this member is declared.
|
||||
/// \param LineNo Line number.
|
||||
/// \param Ty Type of the static member.
|
||||
/// \param Flags Flags to encode member attribute, e.g. private.
|
||||
/// \param Val Const initializer of the member.
|
||||
DIDerivedType *createStaticMemberType(DIScope *Scope, StringRef Name,
|
||||
DIFile *File, unsigned LineNo,
|
||||
DIType *Ty, unsigned Flags,
|
||||
llvm::Constant *Val);
|
||||
|
||||
/// createObjCIVar - Create debugging information entry for Objective-C
|
||||
/// Create debugging information entry for Objective-C
|
||||
/// instance variable.
|
||||
/// @param Name Member name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNo Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param OffsetInBits Member offset.
|
||||
/// @param Flags Flags to encode member attribute, e.g. private
|
||||
/// @param Ty Parent type.
|
||||
/// @param PropertyNode Property associated with this ivar.
|
||||
/// \param Name Member name.
|
||||
/// \param File File where this member is defined.
|
||||
/// \param LineNo Line number.
|
||||
/// \param SizeInBits Member size.
|
||||
/// \param AlignInBits Member alignment.
|
||||
/// \param OffsetInBits Member offset.
|
||||
/// \param Flags Flags to encode member attribute, e.g. private
|
||||
/// \param Ty Parent type.
|
||||
/// \param PropertyNode Property associated with this ivar.
|
||||
DIDerivedType *createObjCIVar(StringRef Name, DIFile *File, unsigned LineNo,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits,
|
||||
uint64_t OffsetInBits, unsigned Flags,
|
||||
DIType *Ty, MDNode *PropertyNode);
|
||||
|
||||
/// createObjCProperty - Create debugging information entry for Objective-C
|
||||
/// Create debugging information entry for Objective-C
|
||||
/// property.
|
||||
/// @param Name Property name.
|
||||
/// @param File File where this property is defined.
|
||||
/// @param LineNumber Line number.
|
||||
/// @param GetterName Name of the Objective C property getter selector.
|
||||
/// @param SetterName Name of the Objective C property setter selector.
|
||||
/// @param PropertyAttributes Objective C property attributes.
|
||||
/// @param Ty Type.
|
||||
/// \param Name Property name.
|
||||
/// \param File File where this property is defined.
|
||||
/// \param LineNumber Line number.
|
||||
/// \param GetterName Name of the Objective C property getter selector.
|
||||
/// \param SetterName Name of the Objective C property setter selector.
|
||||
/// \param PropertyAttributes Objective C property attributes.
|
||||
/// \param Ty Type.
|
||||
DIObjCProperty *createObjCProperty(StringRef Name, DIFile *File,
|
||||
unsigned LineNumber,
|
||||
StringRef GetterName,
|
||||
StringRef SetterName,
|
||||
unsigned PropertyAttributes, DIType *Ty);
|
||||
|
||||
/// createClassType - Create debugging information entry for a class.
|
||||
/// @param Scope Scope in which this class is defined.
|
||||
/// @param Name class name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNumber Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param OffsetInBits Member offset.
|
||||
/// @param Flags Flags to encode member attribute, e.g. private
|
||||
/// @param Elements class members.
|
||||
/// @param VTableHolder Debug info of the base class that contains vtable
|
||||
/// Create debugging information entry for a class.
|
||||
/// \param Scope Scope in which this class is defined.
|
||||
/// \param Name class name.
|
||||
/// \param File File where this member is defined.
|
||||
/// \param LineNumber Line number.
|
||||
/// \param SizeInBits Member size.
|
||||
/// \param AlignInBits Member alignment.
|
||||
/// \param OffsetInBits Member offset.
|
||||
/// \param Flags Flags to encode member attribute, e.g. private
|
||||
/// \param Elements class members.
|
||||
/// \param VTableHolder Debug info of the base class that contains vtable
|
||||
/// for this type. This is used in
|
||||
/// DW_AT_containing_type. See DWARF documentation
|
||||
/// for more info.
|
||||
/// @param TemplateParms Template type parameters.
|
||||
/// @param UniqueIdentifier A unique identifier for the class.
|
||||
/// \param TemplateParms Template type parameters.
|
||||
/// \param UniqueIdentifier A unique identifier for the class.
|
||||
DICompositeType *createClassType(DIScope *Scope, StringRef Name,
|
||||
DIFile *File, unsigned LineNumber,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits,
|
||||
@ -265,34 +268,34 @@ namespace llvm {
|
||||
MDNode *TemplateParms = nullptr,
|
||||
StringRef UniqueIdentifier = "");
|
||||
|
||||
/// createStructType - Create debugging information entry for a struct.
|
||||
/// @param Scope Scope in which this struct is defined.
|
||||
/// @param Name Struct name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNumber Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param Flags Flags to encode member attribute, e.g. private
|
||||
/// @param Elements Struct elements.
|
||||
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
|
||||
/// @param UniqueIdentifier A unique identifier for the struct.
|
||||
/// Create debugging information entry for a struct.
|
||||
/// \param Scope Scope in which this struct is defined.
|
||||
/// \param Name Struct name.
|
||||
/// \param File File where this member is defined.
|
||||
/// \param LineNumber Line number.
|
||||
/// \param SizeInBits Member size.
|
||||
/// \param AlignInBits Member alignment.
|
||||
/// \param Flags Flags to encode member attribute, e.g. private
|
||||
/// \param Elements Struct elements.
|
||||
/// \param RunTimeLang Optional parameter, Objective-C runtime version.
|
||||
/// \param UniqueIdentifier A unique identifier for the struct.
|
||||
DICompositeType *createStructType(
|
||||
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
|
||||
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
|
||||
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "");
|
||||
|
||||
/// createUnionType - Create debugging information entry for an union.
|
||||
/// @param Scope Scope in which this union is defined.
|
||||
/// @param Name Union name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNumber Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param Flags Flags to encode member attribute, e.g. private
|
||||
/// @param Elements Union elements.
|
||||
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
|
||||
/// @param UniqueIdentifier A unique identifier for the union.
|
||||
/// Create debugging information entry for an union.
|
||||
/// \param Scope Scope in which this union is defined.
|
||||
/// \param Name Union name.
|
||||
/// \param File File where this member is defined.
|
||||
/// \param LineNumber Line number.
|
||||
/// \param SizeInBits Member size.
|
||||
/// \param AlignInBits Member alignment.
|
||||
/// \param Flags Flags to encode member attribute, e.g. private
|
||||
/// \param Elements Union elements.
|
||||
/// \param RunTimeLang Optional parameter, Objective-C runtime version.
|
||||
/// \param UniqueIdentifier A unique identifier for the union.
|
||||
DICompositeType *createUnionType(DIScope *Scope, StringRef Name,
|
||||
DIFile *File, unsigned LineNumber,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits,
|
||||
@ -300,95 +303,95 @@ namespace llvm {
|
||||
unsigned RunTimeLang = 0,
|
||||
StringRef UniqueIdentifier = "");
|
||||
|
||||
/// createTemplateTypeParameter - Create debugging information for template
|
||||
/// Create debugging information for template
|
||||
/// type parameter.
|
||||
/// @param Scope Scope in which this type is defined.
|
||||
/// @param Name Type parameter name.
|
||||
/// @param Ty Parameter type.
|
||||
/// \param Scope Scope in which this type is defined.
|
||||
/// \param Name Type parameter name.
|
||||
/// \param Ty Parameter type.
|
||||
DITemplateTypeParameter *
|
||||
createTemplateTypeParameter(DIScope *Scope, StringRef Name, DIType *Ty);
|
||||
|
||||
/// createTemplateValueParameter - Create debugging information for template
|
||||
/// Create debugging information for template
|
||||
/// value parameter.
|
||||
/// @param Scope Scope in which this type is defined.
|
||||
/// @param Name Value parameter name.
|
||||
/// @param Ty Parameter type.
|
||||
/// @param Val Constant parameter value.
|
||||
/// \param Scope Scope in which this type is defined.
|
||||
/// \param Name Value parameter name.
|
||||
/// \param Ty Parameter type.
|
||||
/// \param Val Constant parameter value.
|
||||
DITemplateValueParameter *createTemplateValueParameter(DIScope *Scope,
|
||||
StringRef Name,
|
||||
DIType *Ty,
|
||||
Constant *Val);
|
||||
|
||||
/// \brief Create debugging information for a template template parameter.
|
||||
/// @param Scope Scope in which this type is defined.
|
||||
/// @param Name Value parameter name.
|
||||
/// @param Ty Parameter type.
|
||||
/// @param Val The fully qualified name of the template.
|
||||
/// Create debugging information for a template template parameter.
|
||||
/// \param Scope Scope in which this type is defined.
|
||||
/// \param Name Value parameter name.
|
||||
/// \param Ty Parameter type.
|
||||
/// \param Val The fully qualified name of the template.
|
||||
DITemplateValueParameter *createTemplateTemplateParameter(DIScope *Scope,
|
||||
StringRef Name,
|
||||
DIType *Ty,
|
||||
StringRef Val);
|
||||
|
||||
/// \brief Create debugging information for a template parameter pack.
|
||||
/// @param Scope Scope in which this type is defined.
|
||||
/// @param Name Value parameter name.
|
||||
/// @param Ty Parameter type.
|
||||
/// @param Val An array of types in the pack.
|
||||
/// Create debugging information for a template parameter pack.
|
||||
/// \param Scope Scope in which this type is defined.
|
||||
/// \param Name Value parameter name.
|
||||
/// \param Ty Parameter type.
|
||||
/// \param Val An array of types in the pack.
|
||||
DITemplateValueParameter *createTemplateParameterPack(DIScope *Scope,
|
||||
StringRef Name,
|
||||
DIType *Ty,
|
||||
DINodeArray Val);
|
||||
|
||||
/// createArrayType - Create debugging information entry for an array.
|
||||
/// @param Size Array size.
|
||||
/// @param AlignInBits Alignment.
|
||||
/// @param Ty Element type.
|
||||
/// @param Subscripts Subscripts.
|
||||
/// Create debugging information entry for an array.
|
||||
/// \param Size Array size.
|
||||
/// \param AlignInBits Alignment.
|
||||
/// \param Ty Element type.
|
||||
/// \param Subscripts Subscripts.
|
||||
DICompositeType *createArrayType(uint64_t Size, uint64_t AlignInBits,
|
||||
DIType *Ty, DINodeArray Subscripts);
|
||||
|
||||
/// createVectorType - Create debugging information entry for a vector type.
|
||||
/// @param Size Array size.
|
||||
/// @param AlignInBits Alignment.
|
||||
/// @param Ty Element type.
|
||||
/// @param Subscripts Subscripts.
|
||||
/// Create debugging information entry for a vector type.
|
||||
/// \param Size Array size.
|
||||
/// \param AlignInBits Alignment.
|
||||
/// \param Ty Element type.
|
||||
/// \param Subscripts Subscripts.
|
||||
DICompositeType *createVectorType(uint64_t Size, uint64_t AlignInBits,
|
||||
DIType *Ty, DINodeArray Subscripts);
|
||||
|
||||
/// createEnumerationType - Create debugging information entry for an
|
||||
/// Create debugging information entry for an
|
||||
/// enumeration.
|
||||
/// @param Scope Scope in which this enumeration is defined.
|
||||
/// @param Name Union name.
|
||||
/// @param File File where this member is defined.
|
||||
/// @param LineNumber Line number.
|
||||
/// @param SizeInBits Member size.
|
||||
/// @param AlignInBits Member alignment.
|
||||
/// @param Elements Enumeration elements.
|
||||
/// @param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
|
||||
/// @param UniqueIdentifier A unique identifier for the enum.
|
||||
/// \param Scope Scope in which this enumeration is defined.
|
||||
/// \param Name Union name.
|
||||
/// \param File File where this member is defined.
|
||||
/// \param LineNumber Line number.
|
||||
/// \param SizeInBits Member size.
|
||||
/// \param AlignInBits Member alignment.
|
||||
/// \param Elements Enumeration elements.
|
||||
/// \param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
|
||||
/// \param UniqueIdentifier A unique identifier for the enum.
|
||||
DICompositeType *createEnumerationType(
|
||||
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
|
||||
uint64_t SizeInBits, uint64_t AlignInBits, DINodeArray Elements,
|
||||
DIType *UnderlyingType, StringRef UniqueIdentifier = "");
|
||||
|
||||
/// createSubroutineType - Create subroutine type.
|
||||
/// @param File File in which this subroutine is defined.
|
||||
/// @param ParameterTypes An array of subroutine parameter types. This
|
||||
/// Create subroutine type.
|
||||
/// \param File File in which this subroutine is defined.
|
||||
/// \param ParameterTypes An array of subroutine parameter types. This
|
||||
/// includes return type at 0th index.
|
||||
/// @param Flags E.g.: LValueReference.
|
||||
/// \param Flags E.g.: LValueReference.
|
||||
/// These flags are used to emit dwarf attributes.
|
||||
DISubroutineType *createSubroutineType(DIFile *File,
|
||||
DITypeRefArray ParameterTypes,
|
||||
unsigned Flags = 0);
|
||||
|
||||
/// createArtificialType - Create a new DIType* with "artificial" flag set.
|
||||
/// Create a new DIType* with "artificial" flag set.
|
||||
DIType *createArtificialType(DIType *Ty);
|
||||
|
||||
/// createObjectPointerType - Create a new DIType* with the "object pointer"
|
||||
/// Create a new DIType* with the "object pointer"
|
||||
/// flag set.
|
||||
DIType *createObjectPointerType(DIType *Ty);
|
||||
|
||||
/// \brief Create a permanent forward-declared type.
|
||||
/// Create a permanent forward-declared type.
|
||||
DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,
|
||||
DIScope *Scope, DIFile *F, unsigned Line,
|
||||
unsigned RuntimeLang = 0,
|
||||
@ -396,43 +399,43 @@ namespace llvm {
|
||||
uint64_t AlignInBits = 0,
|
||||
StringRef UniqueIdentifier = "");
|
||||
|
||||
/// \brief Create a temporary forward-declared type.
|
||||
/// Create a temporary forward-declared type.
|
||||
DICompositeType *createReplaceableCompositeType(
|
||||
unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,
|
||||
unsigned RuntimeLang = 0, uint64_t SizeInBits = 0,
|
||||
uint64_t AlignInBits = 0, unsigned Flags = DINode::FlagFwdDecl,
|
||||
StringRef UniqueIdentifier = "");
|
||||
|
||||
/// retainType - Retain DIType* in a module even if it is not referenced
|
||||
/// Retain DIType* in a module even if it is not referenced
|
||||
/// through debug info anchors.
|
||||
void retainType(DIType *T);
|
||||
|
||||
/// createUnspecifiedParameter - Create unspecified parameter type
|
||||
/// Create unspecified parameter type
|
||||
/// for a subroutine type.
|
||||
DIBasicType *createUnspecifiedParameter();
|
||||
|
||||
/// getOrCreateArray - Get a DINodeArray, create one if required.
|
||||
/// Get a DINodeArray, create one if required.
|
||||
DINodeArray getOrCreateArray(ArrayRef<Metadata *> Elements);
|
||||
|
||||
/// getOrCreateTypeArray - Get a DITypeRefArray, create one if required.
|
||||
/// Get a DITypeRefArray, create one if required.
|
||||
DITypeRefArray getOrCreateTypeArray(ArrayRef<Metadata *> Elements);
|
||||
|
||||
/// getOrCreateSubrange - Create a descriptor for a value range. This
|
||||
/// Create a descriptor for a value range. This
|
||||
/// implicitly uniques the values returned.
|
||||
DISubrange *getOrCreateSubrange(int64_t Lo, int64_t Count);
|
||||
|
||||
/// createGlobalVariable - Create a new descriptor for the specified
|
||||
/// Create a new descriptor for the specified
|
||||
/// variable.
|
||||
/// @param Context Variable scope.
|
||||
/// @param Name Name of the variable.
|
||||
/// @param LinkageName Mangled name of the variable.
|
||||
/// @param File File where this variable is defined.
|
||||
/// @param LineNo Line number.
|
||||
/// @param Ty Variable Type.
|
||||
/// @param isLocalToUnit Boolean flag indicate whether this variable is
|
||||
/// \param Context Variable scope.
|
||||
/// \param Name Name of the variable.
|
||||
/// \param LinkageName Mangled name of the variable.
|
||||
/// \param File File where this variable is defined.
|
||||
/// \param LineNo Line number.
|
||||
/// \param Ty Variable Type.
|
||||
/// \param isLocalToUnit Boolean flag indicate whether this variable is
|
||||
/// externally visible or not.
|
||||
/// @param Val llvm::Value of the variable.
|
||||
/// @param Decl Reference to the corresponding declaration.
|
||||
/// \param Val llvm::Value of the variable.
|
||||
/// \param Decl Reference to the corresponding declaration.
|
||||
DIGlobalVariable *createGlobalVariable(DIScope *Context, StringRef Name,
|
||||
StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DIType *Ty,
|
||||
@ -440,26 +443,26 @@ namespace llvm {
|
||||
llvm::Constant *Val,
|
||||
MDNode *Decl = nullptr);
|
||||
|
||||
/// createTempGlobalVariableFwdDecl - Identical to createGlobalVariable
|
||||
/// Identical to createGlobalVariable
|
||||
/// except that the resulting DbgNode is temporary and meant to be RAUWed.
|
||||
DIGlobalVariable *createTempGlobalVariableFwdDecl(
|
||||
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val,
|
||||
MDNode *Decl = nullptr);
|
||||
|
||||
/// createLocalVariable - Create a new descriptor for the specified
|
||||
/// Create a new descriptor for the specified
|
||||
/// local variable.
|
||||
/// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
|
||||
/// \param Tag Dwarf TAG. Usually DW_TAG_auto_variable or
|
||||
/// DW_TAG_arg_variable.
|
||||
/// @param Scope Variable scope.
|
||||
/// @param Name Variable name.
|
||||
/// @param File File where this variable is defined.
|
||||
/// @param LineNo Line number.
|
||||
/// @param Ty Variable Type
|
||||
/// @param AlwaysPreserve Boolean. Set to true if debug info for this
|
||||
/// \param Scope Variable scope.
|
||||
/// \param Name Variable name.
|
||||
/// \param File File where this variable is defined.
|
||||
/// \param LineNo Line number.
|
||||
/// \param Ty Variable Type
|
||||
/// \param AlwaysPreserve Boolean. Set to true if debug info for this
|
||||
/// variable should be preserved in optimized build.
|
||||
/// @param Flags Flags, e.g. artificial variable.
|
||||
/// @param ArgNo If this variable is an argument then this argument's
|
||||
/// \param Flags Flags, e.g. artificial variable.
|
||||
/// \param ArgNo If this variable is an argument then this argument's
|
||||
/// number. 1 indicates 1st argument.
|
||||
DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope,
|
||||
StringRef Name, DIFile *File,
|
||||
@ -468,36 +471,36 @@ namespace llvm {
|
||||
unsigned Flags = 0,
|
||||
unsigned ArgNo = 0);
|
||||
|
||||
/// createExpression - Create a new descriptor for the specified
|
||||
/// Create a new descriptor for the specified
|
||||
/// variable which has a complex address expression for its address.
|
||||
/// @param Addr An array of complex address operations.
|
||||
/// \param Addr An array of complex address operations.
|
||||
DIExpression *createExpression(ArrayRef<uint64_t> Addr = None);
|
||||
DIExpression *createExpression(ArrayRef<int64_t> Addr);
|
||||
|
||||
/// createBitPieceExpression - Create a descriptor to describe one part
|
||||
/// Create a descriptor to describe one part
|
||||
/// of aggregate variable that is fragmented across multiple Values.
|
||||
///
|
||||
/// @param OffsetInBits Offset of the piece in bits.
|
||||
/// @param SizeInBits Size of the piece in bits.
|
||||
/// \param OffsetInBits Offset of the piece in bits.
|
||||
/// \param SizeInBits Size of the piece in bits.
|
||||
DIExpression *createBitPieceExpression(unsigned OffsetInBits,
|
||||
unsigned SizeInBits);
|
||||
|
||||
/// createFunction - Create a new descriptor for the specified subprogram.
|
||||
/// Create a new descriptor for the specified subprogram.
|
||||
/// See comments in DISubprogram* for descriptions of these fields.
|
||||
/// @param Scope Function scope.
|
||||
/// @param Name Function name.
|
||||
/// @param LinkageName Mangled function name.
|
||||
/// @param File File where this variable is defined.
|
||||
/// @param LineNo Line number.
|
||||
/// @param Ty Function type.
|
||||
/// @param isLocalToUnit True if this function is not externally visible.
|
||||
/// @param isDefinition True if this is a function definition.
|
||||
/// @param ScopeLine Set to the beginning of the scope this starts
|
||||
/// @param Flags e.g. is this function prototyped or not.
|
||||
/// \param Scope Function scope.
|
||||
/// \param Name Function name.
|
||||
/// \param LinkageName Mangled function name.
|
||||
/// \param File File where this variable is defined.
|
||||
/// \param LineNo Line number.
|
||||
/// \param Ty Function type.
|
||||
/// \param isLocalToUnit True if this function is not externally visible.
|
||||
/// \param isDefinition True if this is a function definition.
|
||||
/// \param ScopeLine Set to the beginning of the scope this starts
|
||||
/// \param Flags e.g. is this function prototyped or not.
|
||||
/// These flags are used to emit dwarf attributes.
|
||||
/// @param isOptimized True if optimization is ON.
|
||||
/// @param Fn llvm::Function pointer.
|
||||
/// @param TParam Function template parameters.
|
||||
/// \param isOptimized True if optimization is ON.
|
||||
/// \param Fn llvm::Function pointer.
|
||||
/// \param TParam Function template parameters.
|
||||
DISubprogram *
|
||||
createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName,
|
||||
DIFile *File, unsigned LineNo, DISubroutineType *Ty,
|
||||
@ -506,7 +509,7 @@ namespace llvm {
|
||||
Function *Fn = nullptr, MDNode *TParam = nullptr,
|
||||
MDNode *Decl = nullptr);
|
||||
|
||||
/// createTempFunctionFwdDecl - Identical to createFunction,
|
||||
/// Identical to createFunction,
|
||||
/// except that the resulting DbgNode is meant to be RAUWed.
|
||||
DISubprogram *createTempFunctionFwdDecl(
|
||||
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
@ -525,25 +528,25 @@ namespace llvm {
|
||||
Function *Fn = nullptr, MDNode *TParam = nullptr,
|
||||
MDNode *Decl = nullptr);
|
||||
|
||||
/// createMethod - Create a new descriptor for the specified C++ method.
|
||||
/// See comments in DISubprogram* for descriptions of these fields.
|
||||
/// @param Scope Function scope.
|
||||
/// @param Name Function name.
|
||||
/// @param LinkageName Mangled function name.
|
||||
/// @param File File where this variable is defined.
|
||||
/// @param LineNo Line number.
|
||||
/// @param Ty Function type.
|
||||
/// @param isLocalToUnit True if this function is not externally visible..
|
||||
/// @param isDefinition True if this is a function definition.
|
||||
/// @param Virtuality Attributes describing virtualness. e.g. pure
|
||||
/// Create a new descriptor for the specified C++ method.
|
||||
/// See comments in \a DISubprogram* for descriptions of these fields.
|
||||
/// \param Scope Function scope.
|
||||
/// \param Name Function name.
|
||||
/// \param LinkageName Mangled function name.
|
||||
/// \param File File where this variable is defined.
|
||||
/// \param LineNo Line number.
|
||||
/// \param Ty Function type.
|
||||
/// \param isLocalToUnit True if this function is not externally visible..
|
||||
/// \param isDefinition True if this is a function definition.
|
||||
/// \param Virtuality Attributes describing virtualness. e.g. pure
|
||||
/// virtual function.
|
||||
/// @param VTableIndex Index no of this method in virtual table.
|
||||
/// @param VTableHolder Type that holds vtable.
|
||||
/// @param Flags e.g. is this function prototyped or not.
|
||||
/// \param VTableIndex Index no of this method in virtual table.
|
||||
/// \param VTableHolder Type that holds vtable.
|
||||
/// \param Flags e.g. is this function prototyped or not.
|
||||
/// This flags are used to emit dwarf attributes.
|
||||
/// @param isOptimized True if optimization is ON.
|
||||
/// @param Fn llvm::Function pointer.
|
||||
/// @param TParam Function template parameters.
|
||||
/// \param isOptimized True if optimization is ON.
|
||||
/// \param Fn llvm::Function pointer.
|
||||
/// \param TParam Function template parameters.
|
||||
DISubprogram *
|
||||
createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName,
|
||||
DIFile *File, unsigned LineNo, DISubroutineType *Ty,
|
||||
@ -552,131 +555,131 @@ namespace llvm {
|
||||
unsigned Flags = 0, bool isOptimized = false,
|
||||
Function *Fn = nullptr, MDNode *TParam = nullptr);
|
||||
|
||||
/// createNameSpace - This creates new descriptor for a namespace
|
||||
/// with the specified parent scope.
|
||||
/// @param Scope Namespace scope
|
||||
/// @param Name Name of this namespace
|
||||
/// @param File Source file
|
||||
/// @param LineNo Line number
|
||||
/// This creates new descriptor for a namespace with the specified
|
||||
/// parent scope.
|
||||
/// \param Scope Namespace scope
|
||||
/// \param Name Name of this namespace
|
||||
/// \param File Source file
|
||||
/// \param LineNo Line number
|
||||
DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File,
|
||||
unsigned LineNo);
|
||||
|
||||
/// createModule - This creates new descriptor for a module
|
||||
/// with the specified parent scope.
|
||||
/// @param Scope Parent scope
|
||||
/// @param Name Name of this module
|
||||
/// @param ConfigurationMacros
|
||||
/// This creates new descriptor for a module with the specified
|
||||
/// parent scope.
|
||||
/// \param Scope Parent scope
|
||||
/// \param Name Name of this module
|
||||
/// \param ConfigurationMacros
|
||||
/// A space-separated shell-quoted list of -D macro
|
||||
/// definitions as they would appear on a command line.
|
||||
/// @param IncludePath The path to the module map file.
|
||||
/// @param ISysRoot The clang system root (value of -isysroot).
|
||||
/// \param IncludePath The path to the module map file.
|
||||
/// \param ISysRoot The clang system root (value of -isysroot).
|
||||
DIModule *createModule(DIScope *Scope, StringRef Name,
|
||||
StringRef ConfigurationMacros,
|
||||
StringRef IncludePath,
|
||||
StringRef ISysRoot);
|
||||
|
||||
/// createLexicalBlockFile - This creates a descriptor for a lexical
|
||||
/// block with a new file attached. This merely extends the existing
|
||||
/// This creates a descriptor for a lexical block with a new file
|
||||
/// attached. This merely extends the existing
|
||||
/// lexical block as it crosses a file.
|
||||
/// @param Scope Lexical block.
|
||||
/// @param File Source file.
|
||||
/// @param Discriminator DWARF path discriminator value.
|
||||
/// \param Scope Lexical block.
|
||||
/// \param File Source file.
|
||||
/// \param Discriminator DWARF path discriminator value.
|
||||
DILexicalBlockFile *createLexicalBlockFile(DIScope *Scope, DIFile *File,
|
||||
unsigned Discriminator = 0);
|
||||
|
||||
/// createLexicalBlock - This creates a descriptor for a lexical block
|
||||
/// with the specified parent context.
|
||||
/// @param Scope Parent lexical scope.
|
||||
/// @param File Source file.
|
||||
/// @param Line Line number.
|
||||
/// @param Col Column number.
|
||||
/// This creates a descriptor for a lexical block with the
|
||||
/// specified parent context.
|
||||
/// \param Scope Parent lexical scope.
|
||||
/// \param File Source file.
|
||||
/// \param Line Line number.
|
||||
/// \param Col Column number.
|
||||
DILexicalBlock *createLexicalBlock(DIScope *Scope, DIFile *File,
|
||||
unsigned Line, unsigned Col);
|
||||
|
||||
/// \brief Create a descriptor for an imported module.
|
||||
/// @param Context The scope this module is imported into
|
||||
/// @param NS The namespace being imported here
|
||||
/// @param Line Line number
|
||||
/// Create a descriptor for an imported module.
|
||||
/// \param Context The scope this module is imported into
|
||||
/// \param NS The namespace being imported here
|
||||
/// \param Line Line number
|
||||
DIImportedEntity *createImportedModule(DIScope *Context, DINamespace *NS,
|
||||
unsigned Line);
|
||||
|
||||
/// \brief Create a descriptor for an imported module.
|
||||
/// @param Context The scope this module is imported into
|
||||
/// @param NS An aliased namespace
|
||||
/// @param Line Line number
|
||||
/// Create a descriptor for an imported module.
|
||||
/// \param Context The scope this module is imported into
|
||||
/// \param NS An aliased namespace
|
||||
/// \param Line Line number
|
||||
DIImportedEntity *createImportedModule(DIScope *Context,
|
||||
DIImportedEntity *NS, unsigned Line);
|
||||
|
||||
/// \brief Create a descriptor for an imported module.
|
||||
/// @param Context The scope this module is imported into
|
||||
/// @param M The module being imported here
|
||||
/// @param Line Line number
|
||||
/// Create a descriptor for an imported module.
|
||||
/// \param Context The scope this module is imported into
|
||||
/// \param M The module being imported here
|
||||
/// \param Line Line number
|
||||
DIImportedEntity *createImportedModule(DIScope *Context, DIModule *M,
|
||||
unsigned Line);
|
||||
|
||||
/// \brief Create a descriptor for an imported function.
|
||||
/// @param Context The scope this module is imported into
|
||||
/// @param Decl The declaration (or definition) of a function, type, or
|
||||
/// Create a descriptor for an imported function.
|
||||
/// \param Context The scope this module is imported into
|
||||
/// \param Decl The declaration (or definition) of a function, type, or
|
||||
/// variable
|
||||
/// @param Line Line number
|
||||
/// \param Line Line number
|
||||
DIImportedEntity *createImportedDeclaration(DIScope *Context, DINode *Decl,
|
||||
unsigned Line,
|
||||
StringRef Name = "");
|
||||
|
||||
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
|
||||
/// @param Storage llvm::Value of the variable
|
||||
/// @param VarInfo Variable's debug info descriptor.
|
||||
/// @param Expr A complex location expression.
|
||||
/// @param DL Debug info location.
|
||||
/// @param InsertAtEnd Location for the new intrinsic.
|
||||
/// Insert a new llvm.dbg.declare intrinsic call.
|
||||
/// \param Storage llvm::Value of the variable
|
||||
/// \param VarInfo Variable's debug info descriptor.
|
||||
/// \param Expr A complex location expression.
|
||||
/// \param DL Debug info location.
|
||||
/// \param InsertAtEnd Location for the new intrinsic.
|
||||
Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo,
|
||||
DIExpression *Expr, const DILocation *DL,
|
||||
BasicBlock *InsertAtEnd);
|
||||
|
||||
/// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.
|
||||
/// @param Storage llvm::Value of the variable
|
||||
/// @param VarInfo Variable's debug info descriptor.
|
||||
/// @param Expr A complex location expression.
|
||||
/// @param DL Debug info location.
|
||||
/// @param InsertBefore Location for the new intrinsic.
|
||||
/// Insert a new llvm.dbg.declare intrinsic call.
|
||||
/// \param Storage llvm::Value of the variable
|
||||
/// \param VarInfo Variable's debug info descriptor.
|
||||
/// \param Expr A complex location expression.
|
||||
/// \param DL Debug info location.
|
||||
/// \param InsertBefore Location for the new intrinsic.
|
||||
Instruction *insertDeclare(llvm::Value *Storage, DILocalVariable *VarInfo,
|
||||
DIExpression *Expr, const DILocation *DL,
|
||||
Instruction *InsertBefore);
|
||||
|
||||
/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
|
||||
/// @param Val llvm::Value of the variable
|
||||
/// @param Offset Offset
|
||||
/// @param VarInfo Variable's debug info descriptor.
|
||||
/// @param Expr A complex location expression.
|
||||
/// @param DL Debug info location.
|
||||
/// @param InsertAtEnd Location for the new intrinsic.
|
||||
/// Insert a new llvm.dbg.value intrinsic call.
|
||||
/// \param Val llvm::Value of the variable
|
||||
/// \param Offset Offset
|
||||
/// \param VarInfo Variable's debug info descriptor.
|
||||
/// \param Expr A complex location expression.
|
||||
/// \param DL Debug info location.
|
||||
/// \param InsertAtEnd Location for the new intrinsic.
|
||||
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
|
||||
DILocalVariable *VarInfo,
|
||||
DIExpression *Expr,
|
||||
const DILocation *DL,
|
||||
BasicBlock *InsertAtEnd);
|
||||
|
||||
/// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.
|
||||
/// @param Val llvm::Value of the variable
|
||||
/// @param Offset Offset
|
||||
/// @param VarInfo Variable's debug info descriptor.
|
||||
/// @param Expr A complex location expression.
|
||||
/// @param DL Debug info location.
|
||||
/// @param InsertBefore Location for the new intrinsic.
|
||||
/// Insert a new llvm.dbg.value intrinsic call.
|
||||
/// \param Val llvm::Value of the variable
|
||||
/// \param Offset Offset
|
||||
/// \param VarInfo Variable's debug info descriptor.
|
||||
/// \param Expr A complex location expression.
|
||||
/// \param DL Debug info location.
|
||||
/// \param InsertBefore Location for the new intrinsic.
|
||||
Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
|
||||
DILocalVariable *VarInfo,
|
||||
DIExpression *Expr,
|
||||
const DILocation *DL,
|
||||
Instruction *InsertBefore);
|
||||
|
||||
/// \brief Replace the vtable holder in the given composite type.
|
||||
/// Replace the vtable holder in the given composite type.
|
||||
///
|
||||
/// If this creates a self reference, it may orphan some unresolved cycles
|
||||
/// in the operands of \c T, so \a DIBuilder needs to track that.
|
||||
void replaceVTableHolder(DICompositeType *&T,
|
||||
DICompositeType *VTableHolder);
|
||||
|
||||
/// \brief Replace arrays on a composite type.
|
||||
/// Replace arrays on a composite type.
|
||||
///
|
||||
/// If \c T is resolved, but the arrays aren't -- which can happen if \c T
|
||||
/// has a self-reference -- \a DIBuilder needs to track the array to
|
||||
@ -684,7 +687,7 @@ namespace llvm {
|
||||
void replaceArrays(DICompositeType *&T, DINodeArray Elements,
|
||||
DINodeArray TParems = DINodeArray());
|
||||
|
||||
/// \brief Replace a temporary node.
|
||||
/// Replace a temporary node.
|
||||
///
|
||||
/// Call \a MDNode::replaceAllUsesWith() on \c N, replacing it with \c
|
||||
/// Replacement.
|
||||
|
@ -1085,10 +1085,10 @@ class DICompileUnit : public DIScope {
|
||||
/// deleted on a uniquing collision. In practice, uniquing collisions on \a
|
||||
/// DICompileUnit should be fairly rare.
|
||||
/// @{
|
||||
void replaceEnumTypes(DISubprogramArray N) {
|
||||
void replaceEnumTypes(DICompositeTypeArray N) {
|
||||
replaceOperandWith(4, N.get());
|
||||
}
|
||||
void replaceRetainedTypes(DISubprogramArray N) {
|
||||
void replaceRetainedTypes(DITypeArray N) {
|
||||
replaceOperandWith(5, N.get());
|
||||
}
|
||||
void replaceSubprograms(DISubprogramArray N) {
|
||||
@ -1097,7 +1097,7 @@ class DICompileUnit : public DIScope {
|
||||
void replaceGlobalVariables(DIGlobalVariableArray N) {
|
||||
replaceOperandWith(7, N.get());
|
||||
}
|
||||
void replaceImportedEntities(DIGlobalVariableArray N) {
|
||||
void replaceImportedEntities(DIImportedEntityArray N) {
|
||||
replaceOperandWith(8, N.get());
|
||||
}
|
||||
/// @}
|
||||
@ -1650,14 +1650,14 @@ class DIModule : public DIScope {
|
||||
StorageType Storage, bool ShouldCreate = true) {
|
||||
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
|
||||
getCanonicalMDString(Context, ConfigurationMacros),
|
||||
getCanonicalMDString(Context, IncludePath),
|
||||
getCanonicalMDString(Context, ISysRoot),
|
||||
getCanonicalMDString(Context, IncludePath),
|
||||
getCanonicalMDString(Context, ISysRoot),
|
||||
Storage, ShouldCreate);
|
||||
}
|
||||
static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
|
||||
MDString *Name, MDString *ConfigurationMacros,
|
||||
MDString *IncludePath, MDString *ISysRoot,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
MDString *IncludePath, MDString *ISysRoot,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
|
||||
TempDIModule cloneImpl() const {
|
||||
return getTemporary(getContext(), getScope(), getName(),
|
||||
@ -1667,12 +1667,12 @@ class DIModule : public DIScope {
|
||||
|
||||
public:
|
||||
DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
|
||||
StringRef ConfigurationMacros, StringRef IncludePath,
|
||||
StringRef ISysRoot),
|
||||
StringRef ConfigurationMacros, StringRef IncludePath,
|
||||
StringRef ISysRoot),
|
||||
(Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
|
||||
DEFINE_MDNODE_GET(DIModule,
|
||||
(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
|
||||
MDString *IncludePath, MDString *ISysRoot),
|
||||
MDString *IncludePath, MDString *ISysRoot),
|
||||
(Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
|
||||
|
||||
TempDIModule clone() const { return cloneImpl(); }
|
||||
|
@ -36,18 +36,14 @@ namespace llvm {
|
||||
template <typename IRUnitT> class AnalysisManager;
|
||||
class PreservedAnalyses;
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
|
||||
extern template class DomTreeNodeBase<BasicBlock>;
|
||||
extern template class DominatorTreeBase<BasicBlock>;
|
||||
|
||||
#define LLVM_COMMA ,
|
||||
EXTERN_TEMPLATE_INSTANTIATION(void Calculate<Function LLVM_COMMA BasicBlock *>(
|
||||
DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT LLVM_COMMA
|
||||
Function &F));
|
||||
EXTERN_TEMPLATE_INSTANTIATION(
|
||||
void Calculate<Function LLVM_COMMA Inverse<BasicBlock *> >(
|
||||
DominatorTreeBase<GraphTraits<Inverse<BasicBlock *> >::NodeType> &DT
|
||||
LLVM_COMMA Function &F));
|
||||
#undef LLVM_COMMA
|
||||
extern template void Calculate<Function, BasicBlock *>(
|
||||
DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F);
|
||||
extern template void Calculate<Function, Inverse<BasicBlock *>>(
|
||||
DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT,
|
||||
Function &F);
|
||||
|
||||
typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
|
||||
|
||||
|
@ -293,6 +293,16 @@ class Function : public GlobalObject, public ilist_node<Function> {
|
||||
addFnAttr(Attribute::ReadOnly);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call can access memmory only using pointers based
|
||||
/// on its arguments.
|
||||
bool onlyAccessesArgMemory() const {
|
||||
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
|
||||
Attribute::ArgMemOnly);
|
||||
}
|
||||
void setOnlyAccessesArgMemory() {
|
||||
addFnAttr(Attribute::ArgMemOnly);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function cannot return.
|
||||
bool doesNotReturn() const {
|
||||
return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
|
||||
|
@ -252,10 +252,9 @@ class GlobalValue : public Constant {
|
||||
/// mistake: when working at the IR level use mayBeOverridden instead as it
|
||||
/// knows about ODR semantics.
|
||||
static bool isWeakForLinker(LinkageTypes Linkage) {
|
||||
return Linkage == AvailableExternallyLinkage || Linkage == WeakAnyLinkage ||
|
||||
Linkage == WeakODRLinkage || Linkage == LinkOnceAnyLinkage ||
|
||||
Linkage == LinkOnceODRLinkage || Linkage == CommonLinkage ||
|
||||
Linkage == ExternalWeakLinkage;
|
||||
return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage ||
|
||||
Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage ||
|
||||
Linkage == CommonLinkage || Linkage == ExternalWeakLinkage;
|
||||
}
|
||||
|
||||
bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
|
||||
@ -349,6 +348,12 @@ class GlobalValue : public Constant {
|
||||
return isDeclaration();
|
||||
}
|
||||
|
||||
/// Returns true if this global's definition will be the one chosen by the
|
||||
/// linker.
|
||||
bool isStrongDefinitionForLinker() const {
|
||||
return !(isDeclarationForLinker() || isWeakForLinker());
|
||||
}
|
||||
|
||||
/// This method unlinks 'this' from the containing module, but does not delete
|
||||
/// it.
|
||||
virtual void removeFromParent() = 0;
|
||||
|
@ -1382,47 +1382,61 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
|
||||
}
|
||||
|
||||
Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
|
||||
Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
|
||||
Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
|
||||
Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
|
||||
Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
|
||||
Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
|
||||
Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
|
||||
Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
|
||||
Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
|
||||
Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
|
||||
Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
|
||||
Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
|
||||
Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
|
||||
Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
|
||||
Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "",
|
||||
MDNode *FPMathTag = nullptr) {
|
||||
return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name, FPMathTag);
|
||||
}
|
||||
|
||||
Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
|
||||
@ -1433,11 +1447,12 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
return Insert(new ICmpInst(P, LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
|
||||
const Twine &Name = "") {
|
||||
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS))
|
||||
return Insert(Folder.CreateFCmp(P, LC, RC), Name);
|
||||
return Insert(new FCmpInst(P, LHS, RHS), Name);
|
||||
return Insert(AddFPMathAttributes(new FCmpInst(P, LHS, RHS),
|
||||
FPMathTag, FMF), Name);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
@ -1449,7 +1464,7 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
return Insert(PHINode::Create(Ty, NumReservedValues), Name);
|
||||
}
|
||||
|
||||
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
|
||||
CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None,
|
||||
const Twine &Name = "") {
|
||||
return Insert(CallInst::Create(Callee, Args), Name);
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ class Instruction : public User, public ilist_node<Instruction> {
|
||||
///
|
||||
/// Note that this does not consider malloc and alloca to have side
|
||||
/// effects because the newly allocated memory is completely invisible to
|
||||
/// instructions which don't used the returned value. For cases where this
|
||||
/// instructions which don't use the returned value. For cases where this
|
||||
/// matters, isSafeToSpeculativelyExecute may be more appropriate.
|
||||
bool mayHaveSideEffects() const {
|
||||
return mayWriteToMemory() || mayThrow() || !mayReturn();
|
||||
|
@ -990,10 +990,14 @@ class GetElementPtrInst : public Instruction {
|
||||
Ptr->getType()->getPointerAddressSpace());
|
||||
// Vector GEP
|
||||
if (Ptr->getType()->isVectorTy()) {
|
||||
unsigned NumElem = cast<VectorType>(Ptr->getType())->getNumElements();
|
||||
unsigned NumElem = Ptr->getType()->getVectorNumElements();
|
||||
return VectorType::get(PtrTy, NumElem);
|
||||
}
|
||||
|
||||
for (Value *Index : IdxList)
|
||||
if (Index->getType()->isVectorTy()) {
|
||||
unsigned NumElem = Index->getType()->getVectorNumElements();
|
||||
return VectorType::get(PtrTy, NumElem);
|
||||
}
|
||||
// Scalar GEP
|
||||
return PtrTy;
|
||||
}
|
||||
@ -1591,6 +1595,15 @@ class CallInst : public Instruction {
|
||||
addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call can access memmory only using pointers based
|
||||
/// on its arguments.
|
||||
bool onlyAccessesArgMemory() const {
|
||||
return hasFnAttr(Attribute::ArgMemOnly);
|
||||
}
|
||||
void setOnlyAccessesArgMemory() {
|
||||
addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
|
||||
}
|
||||
|
||||
/// \brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
|
||||
void setDoesNotReturn() {
|
||||
@ -3360,6 +3373,15 @@ class InvokeInst : public TerminatorInst {
|
||||
addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call access memmory only using it's pointer
|
||||
/// arguments.
|
||||
bool onlyAccessesArgMemory() const {
|
||||
return hasFnAttr(Attribute::ArgMemOnly);
|
||||
}
|
||||
void setOnlyAccessesArgMemory() {
|
||||
addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
|
||||
}
|
||||
|
||||
/// \brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
|
||||
void setDoesNotReturn() {
|
||||
|
@ -268,15 +268,23 @@ def int_gcwrite : Intrinsic<[],
|
||||
//
|
||||
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
|
||||
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
|
||||
def int_frameescape : Intrinsic<[], [llvm_vararg_ty]>;
|
||||
def int_framerecover : Intrinsic<[llvm_ptr_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
|
||||
[IntrReadMem], "llvm.read_register">;
|
||||
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
|
||||
[], "llvm.write_register">;
|
||||
|
||||
// Gets the address of the local variable area. This is typically a copy of the
|
||||
// stack, frame, or base pointer depending on the type of prologue.
|
||||
def int_localaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
|
||||
|
||||
// Escapes local variables to allow access from other functions.
|
||||
def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
|
||||
|
||||
// Given a function and the localaddress of a parent frame, returns a pointer
|
||||
// to an escaped allocation indicated by the index.
|
||||
def int_localrecover : Intrinsic<[llvm_ptr_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
// Note: we treat stacksave/stackrestore as writemem because we don't otherwise
|
||||
// model their dependencies on allocas.
|
||||
def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
|
||||
@ -362,6 +370,8 @@ let Properties = [IntrNoMem] in {
|
||||
def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
|
||||
def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>],
|
||||
[IntrNoMem]>;
|
||||
}
|
||||
|
||||
// NOTE: these are internal interfaces.
|
||||
@ -638,3 +648,4 @@ include "llvm/IR/IntrinsicsMips.td"
|
||||
include "llvm/IR/IntrinsicsAMDGPU.td"
|
||||
include "llvm/IR/IntrinsicsBPF.td"
|
||||
include "llvm/IR/IntrinsicsSystemZ.td"
|
||||
include "llvm/IR/IntrinsicsWebAssembly.td"
|
||||
|
@ -694,6 +694,18 @@ def int_ppc_vsx_xvrspip :
|
||||
def int_ppc_vsx_xvrdpip :
|
||||
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
|
||||
|
||||
// Vector reciprocal estimate
|
||||
def int_ppc_vsx_xvresp : GCCBuiltin<"__builtin_vsx_xvresp">,
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
|
||||
def int_ppc_vsx_xvredp : GCCBuiltin<"__builtin_vsx_xvredp">,
|
||||
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
|
||||
|
||||
// Vector rsqrte
|
||||
def int_ppc_vsx_xvrsqrtesp : GCCBuiltin<"__builtin_vsx_xvrsqrtesp">,
|
||||
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
|
||||
def int_ppc_vsx_xvrsqrtedp : GCCBuiltin<"__builtin_vsx_xvrsqrtedp">,
|
||||
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
|
||||
|
||||
// Vector compare
|
||||
def int_ppc_vsx_xvcmpeqdp :
|
||||
PowerPC_VSX_Intrinsic<"xvcmpeqdp", [llvm_v2i64_ty],
|
||||
@ -713,6 +725,9 @@ def int_ppc_vsx_xvcmpgtdp :
|
||||
def int_ppc_vsx_xvcmpgtsp :
|
||||
PowerPC_VSX_Intrinsic<"xvcmpgtsp", [llvm_v4i32_ty],
|
||||
[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
|
||||
def int_ppc_vsx_xxleqv :
|
||||
PowerPC_VSX_Intrinsic<"xxleqv", [llvm_v4i32_ty],
|
||||
[llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
16
include/llvm/IR/IntrinsicsWebAssembly.td
Normal file
16
include/llvm/IR/IntrinsicsWebAssembly.td
Normal file
@ -0,0 +1,16 @@
|
||||
//===- IntrinsicsWebAssembly.td - Defines wasm intrinsics --*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file defines all of the WebAssembly-specific intrinsics.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let TargetPrefix = "wasm" in { // All intrinsics start with "llvm.wasm.".
|
||||
}
|
@ -28,7 +28,7 @@ let TargetPrefix = "x86" in {
|
||||
def int_x86_seh_restoreframe : Intrinsic<[], [], []>;
|
||||
|
||||
// Given a pointer to the end of an EH registration object, returns the true
|
||||
// parent frame address that can be used with llvm.framerecover.
|
||||
// parent frame address that can be used with llvm.localrecover.
|
||||
def int_x86_seh_recoverfp : Intrinsic<[llvm_ptr_ty],
|
||||
[llvm_ptr_ty, llvm_ptr_ty],
|
||||
[IntrNoMem]>;
|
||||
@ -2107,6 +2107,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
|
||||
def int_x86_avx2_pmul_hr_sw : GCCBuiltin<"__builtin_ia32_pmulhrsw256">,
|
||||
Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty,
|
||||
llvm_v16i16_ty], [IntrNoMem, Commutative]>;
|
||||
def int_x86_avx512_mask_pmul_hr_sw_128 : GCCBuiltin<"__builtin_ia32_pmulhrsw128_mask">,
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmul_hr_sw_256 : GCCBuiltin<"__builtin_ia32_pmulhrsw256_mask">,
|
||||
Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
|
||||
llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmul_hr_sw_512 : GCCBuiltin<"__builtin_ia32_pmulhrsw512_mask">,
|
||||
Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
|
||||
llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
// Vector sign and zero extend
|
||||
@ -4466,6 +4475,24 @@ let TargetPrefix = "x86" in {
|
||||
def int_x86_avx512_mask_pmull_q_512 : GCCBuiltin<"__builtin_ia32_pmullq512_mask">,
|
||||
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty,
|
||||
llvm_v8i64_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmulhu_w_512 : GCCBuiltin<"__builtin_ia32_pmulhuw512_mask">,
|
||||
Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
|
||||
llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmulh_w_512 : GCCBuiltin<"__builtin_ia32_pmulhw512_mask">,
|
||||
Intrinsic<[llvm_v32i16_ty], [llvm_v32i16_ty, llvm_v32i16_ty,
|
||||
llvm_v32i16_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmulhu_w_128 : GCCBuiltin<"__builtin_ia32_pmulhuw128_mask">,
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmulhu_w_256 : GCCBuiltin<"__builtin_ia32_pmulhuw256_mask">,
|
||||
Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
|
||||
llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmulh_w_128 : GCCBuiltin<"__builtin_ia32_pmulhw128_mask">,
|
||||
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
|
||||
llvm_v8i16_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pmulh_w_256 : GCCBuiltin<"__builtin_ia32_pmulhw256_mask">,
|
||||
Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
|
||||
llvm_v16i16_ty, llvm_i16_ty], [IntrNoMem]>;
|
||||
def int_x86_avx512_mask_pavg_b_512 : GCCBuiltin<"__builtin_ia32_pavgb512_mask">,
|
||||
Intrinsic<[llvm_v64i8_ty], [llvm_v64i8_ty, llvm_v64i8_ty,
|
||||
llvm_v64i8_ty, llvm_i64_ty], [IntrNoMem]>;
|
||||
|
@ -305,7 +305,8 @@ class FPMathOperator : public Operator {
|
||||
float getFPAccuracy() const;
|
||||
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getType()->isFPOrFPVectorTy();
|
||||
return I->getType()->isFPOrFPVectorTy() ||
|
||||
I->getOpcode() == Instruction::FCmp;
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<Instruction>(V) && classof(cast<Instruction>(V));
|
||||
|
@ -104,8 +104,8 @@ class Value {
|
||||
///
|
||||
/// Note, this should *NOT* be used directly by any class other than User.
|
||||
/// User uses this value to find the Use list.
|
||||
static const unsigned NumUserOperandsBits = 29;
|
||||
unsigned NumUserOperands : 29;
|
||||
enum : unsigned { NumUserOperandsBits = 29 };
|
||||
unsigned NumUserOperands : NumUserOperandsBits;
|
||||
|
||||
bool IsUsedByMD : 1;
|
||||
bool HasName : 1;
|
||||
|
@ -130,6 +130,7 @@ void initializeSanitizerCoverageModulePass(PassRegistry&);
|
||||
void initializeDataFlowSanitizerPass(PassRegistry&);
|
||||
void initializeScalarizerPass(PassRegistry&);
|
||||
void initializeEarlyCSELegacyPassPass(PassRegistry &);
|
||||
void initializeEliminateAvailableExternallyPass(PassRegistry&);
|
||||
void initializeExpandISelPseudosPass(PassRegistry&);
|
||||
void initializeFunctionAttrsPass(PassRegistry&);
|
||||
void initializeGCMachineCodeAnalysisPass(PassRegistry&);
|
||||
@ -302,6 +303,7 @@ void initializePlaceSafepointsPass(PassRegistry&);
|
||||
void initializeDwarfEHPreparePass(PassRegistry&);
|
||||
void initializeFloat2IntPass(PassRegistry&);
|
||||
void initializeLoopDistributePass(PassRegistry&);
|
||||
void initializeSjLjEHPreparePass(PassRegistry&);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -176,6 +176,7 @@ namespace {
|
||||
(void) llvm::createStraightLineStrengthReducePass();
|
||||
(void) llvm::createMemDerefPrinter();
|
||||
(void) llvm::createFloat2IntPass();
|
||||
(void) llvm::createEliminateAvailableExternallyPass();
|
||||
|
||||
(void)new llvm::IntervalPartition();
|
||||
(void)new llvm::ScalarEvolution();
|
||||
|
@ -273,7 +273,7 @@ namespace llvm {
|
||||
/// Gets a symbol that will be defined to the final stack offset of a local
|
||||
/// variable after codegen.
|
||||
///
|
||||
/// \param Idx - The index of a local variable passed to @llvm.frameescape.
|
||||
/// \param Idx - The index of a local variable passed to @llvm.localescape.
|
||||
MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
|
||||
|
||||
MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
|
||||
|
@ -54,13 +54,13 @@ struct MCDwarfFile {
|
||||
/// \brief Instances of this class represent the information from a
|
||||
/// dwarf .loc directive.
|
||||
class MCDwarfLoc {
|
||||
unsigned FileNum;
|
||||
unsigned Line;
|
||||
unsigned Column;
|
||||
uint32_t FileNum;
|
||||
uint32_t Line;
|
||||
uint16_t Column;
|
||||
// Flags (see #define's below)
|
||||
unsigned Flags;
|
||||
unsigned Isa;
|
||||
unsigned Discriminator;
|
||||
uint8_t Flags;
|
||||
uint8_t Isa;
|
||||
uint32_t Discriminator;
|
||||
|
||||
// Flag that indicates the initial value of the is_stmt_start flag.
|
||||
#define DWARF2_LINE_DEFAULT_IS_STMT 1
|
||||
@ -107,13 +107,22 @@ class MCDwarfLoc {
|
||||
void setLine(unsigned line) { Line = line; }
|
||||
|
||||
/// \brief Set the Column of this MCDwarfLoc.
|
||||
void setColumn(unsigned column) { Column = column; }
|
||||
void setColumn(unsigned column) {
|
||||
assert(column <= UINT16_MAX);
|
||||
Column = column;
|
||||
}
|
||||
|
||||
/// \brief Set the Flags of this MCDwarfLoc.
|
||||
void setFlags(unsigned flags) { Flags = flags; }
|
||||
void setFlags(unsigned flags) {
|
||||
assert(flags <= UINT8_MAX);
|
||||
Flags = flags;
|
||||
}
|
||||
|
||||
/// \brief Set the Isa of this MCDwarfLoc.
|
||||
void setIsa(unsigned isa) { Isa = isa; }
|
||||
void setIsa(unsigned isa) {
|
||||
assert(isa <= UINT8_MAX);
|
||||
Isa = isa;
|
||||
}
|
||||
|
||||
/// \brief Set the Discriminator of this MCDwarfLoc.
|
||||
void setDiscriminator(unsigned discriminator) {
|
||||
|
@ -154,7 +154,8 @@ class MCInstrDesc {
|
||||
|
||||
// A complex method to determine is a certain is deprecated or not, and return
|
||||
// the reason for deprecation.
|
||||
bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &);
|
||||
bool (*ComplexDeprecationInfo)(MCInst &, const MCSubtargetInfo &,
|
||||
std::string &);
|
||||
|
||||
/// \brief Returns the value of the specific constraint if
|
||||
/// it is set. Returns -1 if it is not set.
|
||||
@ -170,7 +171,7 @@ class MCInstrDesc {
|
||||
|
||||
/// \brief Returns true if a certain instruction is deprecated and if so
|
||||
/// returns the reason in \p Info.
|
||||
bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI,
|
||||
bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI,
|
||||
std::string &Info) const;
|
||||
|
||||
/// \brief Return the opcode number for this descriptor.
|
||||
|
@ -224,25 +224,9 @@ struct MCSchedModel {
|
||||
return &SchedClassTable[SchedClassIdx];
|
||||
}
|
||||
|
||||
// /\brief Returns a default initialized model. Used for unknown processors.
|
||||
static MCSchedModel GetDefaultSchedModel() {
|
||||
MCSchedModel Ret = { DefaultIssueWidth,
|
||||
DefaultMicroOpBufferSize,
|
||||
DefaultLoopMicroOpBufferSize,
|
||||
DefaultLoadLatency,
|
||||
DefaultHighLatency,
|
||||
DefaultMispredictPenalty,
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
0,
|
||||
nullptr
|
||||
};
|
||||
return Ret;
|
||||
}
|
||||
/// Returns the default initialized model.
|
||||
static const MCSchedModel &GetDefaultSchedModel() { return Default; }
|
||||
static const MCSchedModel Default;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -37,22 +37,26 @@ class MCSubtargetInfo {
|
||||
const MCWriteProcResEntry *WriteProcResTable;
|
||||
const MCWriteLatencyEntry *WriteLatencyTable;
|
||||
const MCReadAdvanceEntry *ReadAdvanceTable;
|
||||
MCSchedModel CPUSchedModel;
|
||||
const MCSchedModel *CPUSchedModel;
|
||||
|
||||
const InstrStage *Stages; // Instruction itinerary stages
|
||||
const unsigned *OperandCycles; // Itinerary operand cycles
|
||||
const unsigned *ForwardingPaths; // Forwarding paths
|
||||
FeatureBitset FeatureBits; // Feature bits for current CPU + FS
|
||||
|
||||
MCSubtargetInfo() = delete;
|
||||
MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
|
||||
MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
|
||||
|
||||
public:
|
||||
void InitMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
|
||||
ArrayRef<SubtargetFeatureKV> PF,
|
||||
ArrayRef<SubtargetFeatureKV> PD,
|
||||
const SubtargetInfoKV *ProcSched,
|
||||
const MCWriteProcResEntry *WPR,
|
||||
const MCWriteLatencyEntry *WL,
|
||||
const MCReadAdvanceEntry *RA, const InstrStage *IS,
|
||||
const unsigned *OC, const unsigned *FP);
|
||||
MCSubtargetInfo(const MCSubtargetInfo &) = default;
|
||||
MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
|
||||
ArrayRef<SubtargetFeatureKV> PF,
|
||||
ArrayRef<SubtargetFeatureKV> PD,
|
||||
const SubtargetInfoKV *ProcSched,
|
||||
const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
|
||||
const MCReadAdvanceEntry *RA, const InstrStage *IS,
|
||||
const unsigned *OC, const unsigned *FP);
|
||||
|
||||
/// getTargetTriple - Return the target triple string.
|
||||
const Triple &getTargetTriple() const { return TargetTriple; }
|
||||
@ -74,12 +78,16 @@ class MCSubtargetInfo {
|
||||
FeatureBits = FeatureBits_;
|
||||
}
|
||||
|
||||
/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
|
||||
/// feature string). Recompute feature bits and scheduling model.
|
||||
protected:
|
||||
/// Initialize the scheduling model and feature bits.
|
||||
///
|
||||
/// FIXME: Find a way to stick this in the constructor, since it should only
|
||||
/// be called during initialization.
|
||||
void InitMCProcessorInfo(StringRef CPU, StringRef FS);
|
||||
|
||||
/// InitCPUSchedModel - Recompute scheduling model based on CPU.
|
||||
void InitCPUSchedModel(StringRef CPU);
|
||||
public:
|
||||
/// Set the features to the default for the given CPU.
|
||||
void setDefaultFeatures(StringRef CPU);
|
||||
|
||||
/// ToggleFeature - Toggle a feature and returns the re-computed feature
|
||||
/// bits. This version does not change the implied bits.
|
||||
@ -99,11 +107,10 @@ class MCSubtargetInfo {
|
||||
|
||||
/// getSchedModelForCPU - Get the machine model of a CPU.
|
||||
///
|
||||
MCSchedModel getSchedModelForCPU(StringRef CPU) const;
|
||||
const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
|
||||
|
||||
/// getSchedModel - Get the machine model for this subtarget's CPU.
|
||||
///
|
||||
const MCSchedModel &getSchedModel() const { return CPUSchedModel; }
|
||||
/// Get the machine model for this subtarget's CPU.
|
||||
const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
|
||||
|
||||
/// Return an iterator at the first process resource consumed by the given
|
||||
/// scheduling class.
|
||||
@ -151,7 +158,7 @@ class MCSubtargetInfo {
|
||||
void initInstrItins(InstrItineraryData &InstrItins) const;
|
||||
|
||||
/// Check whether the CPU string is valid.
|
||||
bool isCPUStringValid(StringRef CPU) {
|
||||
bool isCPUStringValid(StringRef CPU) const {
|
||||
auto Found = std::find_if(ProcDesc.begin(), ProcDesc.end(),
|
||||
[=](const SubtargetFeatureKV &KV) {
|
||||
return CPU == KV.Key;
|
||||
|
@ -114,12 +114,12 @@ class MCSymbol {
|
||||
/// The alignment is stored as log2(align) + 1. This allows all values from
|
||||
/// 0 to 2^31 to be stored which is every power of 2 representable by an
|
||||
/// unsigned.
|
||||
static const unsigned NumCommonAlignmentBits = 5;
|
||||
enum : unsigned { NumCommonAlignmentBits = 5 };
|
||||
unsigned CommonAlignLog2 : NumCommonAlignmentBits;
|
||||
|
||||
/// The Flags field is used by object file implementations to store
|
||||
/// additional per symbol information which is not easily classified.
|
||||
static const unsigned NumFlagsBits = 16;
|
||||
enum : unsigned { NumFlagsBits = 16 };
|
||||
mutable uint32_t Flags : NumFlagsBits;
|
||||
|
||||
/// Index field, for use by the object file implementation.
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_MC_MCSYMBOLMACHO_H
|
||||
#define setIsWeakExternal
|
||||
#define LLVM_MC_MCSYMBOLMACHO_H
|
||||
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
|
||||
|
@ -55,7 +55,7 @@ inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
|
||||
ARE_EQUAL(ShowMCInst) &&
|
||||
ARE_EQUAL(AsmVerbose) &&
|
||||
ARE_EQUAL(DwarfVersion) &&
|
||||
ARE_EQUAL(ABIName));
|
||||
ARE_EQUAL(ABIName));
|
||||
#undef ARE_EQUAL
|
||||
}
|
||||
|
||||
|
@ -94,9 +94,7 @@ class Archive : public Binary {
|
||||
/// \return the size in the archive header for this member.
|
||||
uint64_t getRawSize() const;
|
||||
|
||||
StringRef getBuffer() const {
|
||||
return StringRef(Data.data() + StartOfFile, getSize());
|
||||
}
|
||||
ErrorOr<StringRef> getBuffer() const;
|
||||
uint64_t getChildOffset() const;
|
||||
|
||||
ErrorOr<MemoryBufferRef> getMemoryBufferRef() const;
|
||||
@ -183,6 +181,7 @@ class Archive : public Binary {
|
||||
};
|
||||
|
||||
Kind kind() const { return (Kind)Format; }
|
||||
bool isThin() const { return IsThin; }
|
||||
|
||||
child_iterator child_begin(bool SkipInternal = true) const;
|
||||
child_iterator child_end() const;
|
||||
@ -207,6 +206,11 @@ class Archive : public Binary {
|
||||
|
||||
bool hasSymbolTable() const;
|
||||
child_iterator getSymbolTableChild() const { return SymbolTable; }
|
||||
StringRef getSymbolTable() const {
|
||||
// We know that the symbol table is not an external file,
|
||||
// so we just assert there is no error.
|
||||
return *SymbolTable->getBuffer();
|
||||
}
|
||||
uint32_t getNumberOfSymbols() const;
|
||||
|
||||
private:
|
||||
@ -215,6 +219,7 @@ class Archive : public Binary {
|
||||
child_iterator FirstRegular;
|
||||
unsigned Format : 2;
|
||||
unsigned IsThin : 1;
|
||||
mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ class NewArchiveIterator {
|
||||
public:
|
||||
NewArchiveIterator(object::Archive::child_iterator I, StringRef Name);
|
||||
NewArchiveIterator(StringRef I, StringRef Name);
|
||||
NewArchiveIterator();
|
||||
bool isNewMember() const;
|
||||
StringRef getName() const;
|
||||
|
||||
@ -44,8 +43,7 @@ class NewArchiveIterator {
|
||||
|
||||
std::pair<StringRef, std::error_code>
|
||||
writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
|
||||
bool WriteSymtab);
|
||||
|
||||
bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -474,7 +474,7 @@ struct coff_import_header {
|
||||
support::ulittle16_t OrdinalHint;
|
||||
support::ulittle16_t TypeInfo;
|
||||
int getType() const { return TypeInfo & 0x3; }
|
||||
int getNameType() const { return (TypeInfo & 0x7) >> 2; }
|
||||
int getNameType() const { return (TypeInfo >> 2) & 0x7; }
|
||||
};
|
||||
|
||||
struct coff_import_directory_table_entry {
|
||||
@ -648,9 +648,8 @@ class COFFObjectFile : public ObjectFile {
|
||||
protected:
|
||||
void moveSymbolNext(DataRefImpl &Symb) const override;
|
||||
ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
|
||||
std::error_code getSymbolAddress(DataRefImpl Symb,
|
||||
uint64_t &Res) const override;
|
||||
uint64_t getSymbolValue(DataRefImpl Symb) const override;
|
||||
ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
|
||||
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
|
||||
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
|
||||
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
|
||||
SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
|
||||
@ -672,7 +671,6 @@ class COFFObjectFile : public ObjectFile {
|
||||
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
|
||||
|
||||
void moveRelocationNext(DataRefImpl &Rel) const override;
|
||||
ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override;
|
||||
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
|
||||
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
|
||||
uint64_t getRelocationType(DataRefImpl Rel) const override;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/IntervalMap.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
@ -139,6 +140,7 @@ class ELFFile {
|
||||
typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
|
||||
typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
|
||||
typedef Elf_Versym_Impl<ELFT> Elf_Versym;
|
||||
typedef Elf_Hash_Impl<ELFT> Elf_Hash;
|
||||
typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_Iter;
|
||||
typedef iterator_range<Elf_Dyn_Iter> Elf_Dyn_Range;
|
||||
typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
|
||||
@ -174,8 +176,8 @@ class ELFFile {
|
||||
StringRef DotShstrtab; // Section header string table.
|
||||
StringRef DotStrtab; // Symbol header string table.
|
||||
const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section.
|
||||
StringRef DynSymStrTab; // Dynnamic symbol string table.
|
||||
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
|
||||
const Elf_Hash *HashTable = nullptr;
|
||||
|
||||
const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr;
|
||||
DenseMap<const Elf_Sym *, ELF::Elf64_Word> ExtendedSymbolTable;
|
||||
@ -197,6 +199,7 @@ class ELFFile {
|
||||
|
||||
DynRegionInfo DynamicRegion;
|
||||
DynRegionInfo DynHashRegion;
|
||||
DynRegionInfo DynStrRegion;
|
||||
DynRegionInfo DynRelaRegion;
|
||||
|
||||
// Pointer to SONAME entry in dynamic string table
|
||||
@ -229,6 +232,8 @@ class ELFFile {
|
||||
void LoadVersionNeeds(const Elf_Shdr *ec) const;
|
||||
void LoadVersionMap() const;
|
||||
|
||||
void scanDynamicTable();
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
const T *getEntry(uint32_t Section, uint32_t Entry) const;
|
||||
@ -237,6 +242,7 @@ class ELFFile {
|
||||
|
||||
const Elf_Shdr *getDotSymtabSec() const { return dot_symtab_sec; }
|
||||
const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; }
|
||||
const Elf_Hash *getHashTable() const { return HashTable; }
|
||||
|
||||
ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const;
|
||||
const char *getDynamicString(uintX_t Offset) const;
|
||||
@ -578,8 +584,10 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
|
||||
|
||||
Header = reinterpret_cast<const Elf_Ehdr *>(base());
|
||||
|
||||
if (Header->e_shoff == 0)
|
||||
if (Header->e_shoff == 0) {
|
||||
scanDynamicTable();
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t SectionTableOffset = Header->e_shoff;
|
||||
|
||||
@ -604,6 +612,13 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
|
||||
|
||||
for (const Elf_Shdr &Sec : sections()) {
|
||||
switch (Sec.sh_type) {
|
||||
case ELF::SHT_HASH:
|
||||
if (HashTable) {
|
||||
EC = object_error::parse_failed;
|
||||
return;
|
||||
}
|
||||
HashTable = reinterpret_cast<const Elf_Hash *>(base() + Sec.sh_offset);
|
||||
break;
|
||||
case ELF::SHT_SYMTAB_SHNDX:
|
||||
if (SymbolTableSectionHeaderIndex) {
|
||||
// More than one .symtab_shndx!
|
||||
@ -640,7 +655,9 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
|
||||
ErrorOr<StringRef> SymtabOrErr = getStringTable(*SectionOrErr);
|
||||
if ((EC = SymtabOrErr.getError()))
|
||||
return;
|
||||
DynSymStrTab = *SymtabOrErr;
|
||||
DynStrRegion.Addr = SymtabOrErr->data();
|
||||
DynStrRegion.Size = SymtabOrErr->size();
|
||||
DynStrRegion.EntSize = 1;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_DYNAMIC:
|
||||
@ -701,7 +718,23 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
|
||||
}
|
||||
}
|
||||
|
||||
// Scan program headers.
|
||||
scanDynamicTable();
|
||||
|
||||
EC = std::error_code();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ELFFile<ELFT>::scanDynamicTable() {
|
||||
// Build load-address to file-offset map.
|
||||
typedef IntervalMap<
|
||||
uintX_t, uintptr_t,
|
||||
IntervalMapImpl::NodeSizer<uintX_t, uintptr_t>::LeafSize,
|
||||
IntervalMapHalfOpenInfo<uintX_t>> LoadMapT;
|
||||
typename LoadMapT::Allocator Alloc;
|
||||
// Allocate the IntervalMap on the heap to work around MSVC bug where the
|
||||
// stack doesn't get realigned despite LoadMap having alignment 8 (PR24113).
|
||||
std::unique_ptr<LoadMapT> LoadMap(new LoadMapT(Alloc));
|
||||
|
||||
for (Elf_Phdr_Iter PhdrI = program_header_begin(),
|
||||
PhdrE = program_header_end();
|
||||
PhdrI != PhdrE; ++PhdrI) {
|
||||
@ -709,34 +742,44 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
|
||||
DynamicRegion.Addr = base() + PhdrI->p_offset;
|
||||
DynamicRegion.Size = PhdrI->p_filesz;
|
||||
DynamicRegion.EntSize = sizeof(Elf_Dyn);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (PhdrI->p_type != ELF::PT_LOAD)
|
||||
continue;
|
||||
if (PhdrI->p_filesz == 0)
|
||||
continue;
|
||||
LoadMap->insert(PhdrI->p_vaddr, PhdrI->p_vaddr + PhdrI->p_filesz,
|
||||
PhdrI->p_offset);
|
||||
}
|
||||
|
||||
// Scan dynamic table.
|
||||
auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * {
|
||||
auto I = LoadMap->find(VAddr);
|
||||
if (I == LoadMap->end())
|
||||
return nullptr;
|
||||
return this->base() + I.value() + (VAddr - I.start());
|
||||
};
|
||||
|
||||
for (Elf_Dyn_Iter DynI = dynamic_table_begin(), DynE = dynamic_table_end();
|
||||
DynI != DynE; ++DynI) {
|
||||
switch (DynI->d_tag) {
|
||||
case ELF::DT_RELA: {
|
||||
uint64_t VBase = 0;
|
||||
const uint8_t *FBase = nullptr;
|
||||
for (Elf_Phdr_Iter PhdrI = program_header_begin(),
|
||||
PhdrE = program_header_end();
|
||||
PhdrI != PhdrE; ++PhdrI) {
|
||||
if (PhdrI->p_type != ELF::PT_LOAD)
|
||||
continue;
|
||||
if (DynI->getPtr() >= PhdrI->p_vaddr &&
|
||||
DynI->getPtr() < PhdrI->p_vaddr + PhdrI->p_memsz) {
|
||||
VBase = PhdrI->p_vaddr;
|
||||
FBase = base() + PhdrI->p_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!VBase)
|
||||
return;
|
||||
DynRelaRegion.Addr = FBase + DynI->getPtr() - VBase;
|
||||
case ELF::DT_HASH:
|
||||
if (HashTable)
|
||||
continue;
|
||||
HashTable =
|
||||
reinterpret_cast<const Elf_Hash *>(toMappedAddr(DynI->getPtr()));
|
||||
break;
|
||||
case ELF::DT_STRTAB:
|
||||
if (!DynStrRegion.Addr)
|
||||
DynStrRegion.Addr = toMappedAddr(DynI->getPtr());
|
||||
break;
|
||||
case ELF::DT_STRSZ:
|
||||
if (!DynStrRegion.Size)
|
||||
DynStrRegion.Size = DynI->getVal();
|
||||
break;
|
||||
case ELF::DT_RELA:
|
||||
if (!DynRelaRegion.Addr)
|
||||
DynRelaRegion.Addr = toMappedAddr(DynI->getPtr());
|
||||
break;
|
||||
}
|
||||
case ELF::DT_RELASZ:
|
||||
DynRelaRegion.Size = DynI->getVal();
|
||||
break;
|
||||
@ -744,8 +787,6 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC)
|
||||
DynRelaRegion.EntSize = DynI->getVal();
|
||||
}
|
||||
}
|
||||
|
||||
EC = std::error_code();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
@ -868,9 +909,9 @@ ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
|
||||
|
||||
template <class ELFT>
|
||||
const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const {
|
||||
if (!DotDynSymSec || Offset >= DynSymStrTab.size())
|
||||
if (Offset >= DynStrRegion.Size)
|
||||
return nullptr;
|
||||
return (const char *)DynSymStrTab.begin() + Offset;
|
||||
return (const char *)DynStrRegion.Addr + Offset;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
@ -983,7 +1024,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
|
||||
IsDefault = false;
|
||||
}
|
||||
|
||||
if (name_offset >= DynSymStrTab.size())
|
||||
if (name_offset >= DynStrRegion.Size)
|
||||
return object_error::parse_failed;
|
||||
return StringRef(getDynamicString(name_offset));
|
||||
}
|
||||
|
@ -196,9 +196,8 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
|
||||
|
||||
void moveSymbolNext(DataRefImpl &Symb) const override;
|
||||
ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
|
||||
std::error_code getSymbolAddress(DataRefImpl Symb,
|
||||
uint64_t &Res) const override;
|
||||
uint64_t getSymbolValue(DataRefImpl Symb) const override;
|
||||
ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
|
||||
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
|
||||
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
|
||||
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
|
||||
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
|
||||
@ -226,7 +225,6 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
|
||||
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
|
||||
|
||||
void moveRelocationNext(DataRefImpl &Rel) const override;
|
||||
ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override;
|
||||
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
|
||||
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
|
||||
uint64_t getRelocationType(DataRefImpl Rel) const override;
|
||||
@ -235,7 +233,6 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
|
||||
|
||||
uint32_t getSectionType(DataRefImpl Sec) const override;
|
||||
uint64_t getSectionFlags(DataRefImpl Sec) const override;
|
||||
uint64_t getROffset(DataRefImpl Rel) const;
|
||||
StringRef getRelocationTypeName(uint32_t Type) const;
|
||||
|
||||
/// \brief Get the relocation section that contains \a Rel.
|
||||
@ -276,11 +273,6 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
|
||||
return DRI;
|
||||
}
|
||||
|
||||
Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const {
|
||||
return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(),
|
||||
reinterpret_cast<const char *>(Dyn.p));
|
||||
}
|
||||
|
||||
DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const {
|
||||
DataRefImpl DRI;
|
||||
DRI.p = reinterpret_cast<uintptr_t>(Dyn.get());
|
||||
@ -378,19 +370,13 @@ uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const {
|
||||
uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
|
||||
const Elf_Sym *ESym = getSymbol(Symb);
|
||||
switch (ESym->st_shndx) {
|
||||
case ELF::SHN_COMMON:
|
||||
case ELF::SHN_UNDEF:
|
||||
return UnknownAddress;
|
||||
case ELF::SHN_ABS:
|
||||
return ESym->st_value;
|
||||
}
|
||||
uint64_t Ret = ESym->st_value;
|
||||
if (ESym->st_shndx == ELF::SHN_ABS)
|
||||
return Ret;
|
||||
|
||||
const Elf_Ehdr *Header = EF.getHeader();
|
||||
uint64_t Ret = ESym->st_value;
|
||||
|
||||
// Clear the ARM/Thumb or microMIPS indicator flag.
|
||||
if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
|
||||
ESym->getType() == ELF::STT_FUNC)
|
||||
@ -400,15 +386,15 @@ uint64_t ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb) const {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
|
||||
uint64_t &Result) const {
|
||||
Result = getSymbolValue(Symb);
|
||||
ErrorOr<uint64_t>
|
||||
ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
|
||||
uint64_t Result = getSymbolValue(Symb);
|
||||
const Elf_Sym *ESym = getSymbol(Symb);
|
||||
switch (ESym->st_shndx) {
|
||||
case ELF::SHN_COMMON:
|
||||
case ELF::SHN_UNDEF:
|
||||
case ELF::SHN_ABS:
|
||||
return std::error_code();
|
||||
return Result;
|
||||
}
|
||||
|
||||
const Elf_Ehdr *Header = EF.getHeader();
|
||||
@ -422,7 +408,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
|
||||
Result += Section->sh_addr;
|
||||
}
|
||||
|
||||
return std::error_code();
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
@ -688,32 +674,10 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
|
||||
return symbol_iterator(SymbolRef(SymbolData, this));
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<uint64_t>
|
||||
ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel) const {
|
||||
uint64_t ROffset = getROffset(Rel);
|
||||
const Elf_Ehdr *Header = EF.getHeader();
|
||||
|
||||
if (Header->e_type == ELF::ET_REL) {
|
||||
const Elf_Shdr *RelocationSec = getRelSection(Rel);
|
||||
ErrorOr<const Elf_Shdr *> RelocatedSec =
|
||||
EF.getSection(RelocationSec->sh_info);
|
||||
if (std::error_code EC = RelocatedSec.getError())
|
||||
return EC;
|
||||
return ROffset + (*RelocatedSec)->sh_addr;
|
||||
}
|
||||
return ROffset;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
|
||||
assert(EF.getHeader()->e_type == ELF::ET_REL &&
|
||||
"Only relocatable object files have relocation offsets");
|
||||
return getROffset(Rel);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
|
||||
const Elf_Shdr *sec = getRelSection(Rel);
|
||||
if (sec->sh_type == ELF::SHT_REL)
|
||||
return getRel(Rel)->r_offset;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_OBJECT_ELFTYPES_H
|
||||
#define LLVM_OBJECT_ELFTYPES_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Object/Error.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
@ -463,6 +464,23 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
|
||||
Elf_Xword p_align; // Segment alignment constraint
|
||||
};
|
||||
|
||||
// ELFT needed for endianess.
|
||||
template <class ELFT>
|
||||
struct Elf_Hash_Impl {
|
||||
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
|
||||
Elf_Word nbucket;
|
||||
Elf_Word nchain;
|
||||
|
||||
ArrayRef<Elf_Word> buckets() const {
|
||||
return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
|
||||
}
|
||||
|
||||
ArrayRef<Elf_Word> chains() const {
|
||||
return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
|
||||
&nbucket + 2 + nbucket + nchain);
|
||||
}
|
||||
};
|
||||
|
||||
// MIPS .reginfo section
|
||||
template <class ELFT>
|
||||
struct Elf_Mips_RegInfo;
|
||||
|
@ -85,7 +85,13 @@ struct SectionOrType {
|
||||
};
|
||||
|
||||
struct Section {
|
||||
enum class SectionKind { Group, RawContent, Relocation, MipsABIFlags };
|
||||
enum class SectionKind {
|
||||
Group,
|
||||
RawContent,
|
||||
Relocation,
|
||||
NoBits,
|
||||
MipsABIFlags
|
||||
};
|
||||
SectionKind Kind;
|
||||
StringRef Name;
|
||||
ELF_SHT Type;
|
||||
@ -106,6 +112,14 @@ struct RawContentSection : Section {
|
||||
}
|
||||
};
|
||||
|
||||
struct NoBitsSection : Section {
|
||||
llvm::yaml::Hex64 Size;
|
||||
NoBitsSection() : Section(SectionKind::NoBits) {}
|
||||
static bool classof(const Section *S) {
|
||||
return S->Kind == SectionKind::NoBits;
|
||||
}
|
||||
};
|
||||
|
||||
struct Group : Section {
|
||||
// Members of a group contain a flag and a list of section indices
|
||||
// that are part of the group.
|
||||
|
@ -205,9 +205,7 @@ class MachOObjectFile : public ObjectFile {
|
||||
std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
|
||||
unsigned getSectionType(SectionRef Sec) const;
|
||||
|
||||
std::error_code getSymbolAddress(DataRefImpl Symb,
|
||||
uint64_t &Res) const override;
|
||||
uint64_t getSymbolValue(DataRefImpl Symb) const override;
|
||||
ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
|
||||
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
|
||||
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
|
||||
SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
|
||||
@ -233,7 +231,6 @@ class MachOObjectFile : public ObjectFile {
|
||||
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
|
||||
|
||||
void moveRelocationNext(DataRefImpl &Rel) const override;
|
||||
ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const override;
|
||||
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
|
||||
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
|
||||
section_iterator getRelocationSection(DataRefImpl Rel) const;
|
||||
@ -245,6 +242,8 @@ class MachOObjectFile : public ObjectFile {
|
||||
// MachO specific.
|
||||
std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
|
||||
|
||||
section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
|
||||
|
||||
// TODO: Would be useful to have an iterator based version
|
||||
// of the load command interface too.
|
||||
|
||||
@ -425,6 +424,8 @@ class MachOObjectFile : public ObjectFile {
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
|
||||
|
||||
union {
|
||||
MachO::mach_header_64 Header64;
|
||||
MachO::mach_header Header;
|
||||
|
@ -50,7 +50,6 @@ class RelocationRef {
|
||||
|
||||
void moveNext();
|
||||
|
||||
ErrorOr<uint64_t> getAddress() const;
|
||||
uint64_t getOffset() const;
|
||||
symbol_iterator getSymbol() const;
|
||||
uint64_t getType() const;
|
||||
@ -135,7 +134,7 @@ class SymbolRef : public BasicSymbolRef {
|
||||
ErrorOr<StringRef> getName() const;
|
||||
/// Returns the symbol virtual address (i.e. address at which it will be
|
||||
/// mapped).
|
||||
std::error_code getAddress(uint64_t &Result) const;
|
||||
ErrorOr<uint64_t> getAddress() const;
|
||||
|
||||
/// Return the value of the symbol depending on the object this can be an
|
||||
/// offset or a virtual address.
|
||||
@ -198,9 +197,8 @@ class ObjectFile : public SymbolicFile {
|
||||
virtual ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
|
||||
std::error_code printSymbolName(raw_ostream &OS,
|
||||
DataRefImpl Symb) const override;
|
||||
virtual std::error_code getSymbolAddress(DataRefImpl Symb,
|
||||
uint64_t &Res) const = 0;
|
||||
virtual uint64_t getSymbolValue(DataRefImpl Symb) const = 0;
|
||||
virtual ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
|
||||
virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
|
||||
virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
|
||||
virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
|
||||
virtual SymbolRef::Type getSymbolType(DataRefImpl Symb) const = 0;
|
||||
@ -229,13 +227,14 @@ class ObjectFile : public SymbolicFile {
|
||||
// Same as above for RelocationRef.
|
||||
friend class RelocationRef;
|
||||
virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
|
||||
virtual ErrorOr<uint64_t> getRelocationAddress(DataRefImpl Rel) const = 0;
|
||||
virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
|
||||
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
|
||||
virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
|
||||
virtual void getRelocationTypeName(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const = 0;
|
||||
|
||||
uint64_t getSymbolValue(DataRefImpl Symb) const;
|
||||
|
||||
public:
|
||||
uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
|
||||
assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
|
||||
@ -308,8 +307,8 @@ inline ErrorOr<StringRef> SymbolRef::getName() const {
|
||||
return getObject()->getSymbolName(getRawDataRefImpl());
|
||||
}
|
||||
|
||||
inline std::error_code SymbolRef::getAddress(uint64_t &Result) const {
|
||||
return getObject()->getSymbolAddress(getRawDataRefImpl(), Result);
|
||||
inline ErrorOr<uint64_t> SymbolRef::getAddress() const {
|
||||
return getObject()->getSymbolAddress(getRawDataRefImpl());
|
||||
}
|
||||
|
||||
inline uint64_t SymbolRef::getValue() const {
|
||||
@ -430,10 +429,6 @@ inline void RelocationRef::moveNext() {
|
||||
return OwningObject->moveRelocationNext(RelocationPimpl);
|
||||
}
|
||||
|
||||
inline ErrorOr<uint64_t> RelocationRef::getAddress() const {
|
||||
return OwningObject->getRelocationAddress(RelocationPimpl);
|
||||
}
|
||||
|
||||
inline uint64_t RelocationRef::getOffset() const {
|
||||
return OwningObject->getRelocationOffset(RelocationPimpl);
|
||||
}
|
||||
|
@ -100,9 +100,9 @@ class RelocVisitor {
|
||||
case Triple::mips64:
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_MIPS_32:
|
||||
return visitELF_MIPS_32(R, Value);
|
||||
return visitELF_MIPS64_32(R, Value);
|
||||
case llvm::ELF::R_MIPS_64:
|
||||
return visitELF_MIPS_64(R, Value);
|
||||
return visitELF_MIPS64_64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
@ -313,11 +313,18 @@ class RelocVisitor {
|
||||
|
||||
/// MIPS ELF
|
||||
RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) {
|
||||
uint32_t Res = (Value)&0xFFFFFFFF;
|
||||
uint32_t Res = Value & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_MIPS_64(RelocationRef R, uint64_t Value) {
|
||||
/// MIPS64 ELF
|
||||
RelocToApply visitELF_MIPS64_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getELFAddend(R);
|
||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_MIPS64_64(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend = getELFAddend(R);
|
||||
uint64_t Res = (Value + Addend);
|
||||
return RelocToApply(Res, 8);
|
||||
|
@ -115,8 +115,6 @@ class BasicSymbolRef {
|
||||
|
||||
typedef content_iterator<BasicSymbolRef> basic_symbol_iterator;
|
||||
|
||||
const uint64_t UnknownAddress = ~0ULL;
|
||||
|
||||
class SymbolicFile : public Binary {
|
||||
public:
|
||||
~SymbolicFile() override;
|
||||
|
@ -655,6 +655,7 @@ namespace COFF {
|
||||
};
|
||||
|
||||
enum CodeViewIdentifiers {
|
||||
DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS = 0x1,
|
||||
DEBUG_SECTION_MAGIC = 0x4,
|
||||
DEBUG_SYMBOL_SUBSECTION = 0xF1,
|
||||
DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
|
||||
|
@ -790,7 +790,7 @@ template <> class parser<bool> final : public basic_parser<bool> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
|
||||
extern template class basic_parser<bool>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<boolOrDefault>
|
||||
@ -816,7 +816,7 @@ class parser<boolOrDefault> final : public basic_parser<boolOrDefault> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
|
||||
extern template class basic_parser<boolOrDefault>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<int>
|
||||
@ -838,7 +838,7 @@ template <> class parser<int> final : public basic_parser<int> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
|
||||
extern template class basic_parser<int>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<unsigned>
|
||||
@ -860,7 +860,7 @@ template <> class parser<unsigned> final : public basic_parser<unsigned> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
|
||||
extern template class basic_parser<unsigned>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<unsigned long long>
|
||||
@ -885,7 +885,7 @@ class parser<unsigned long long> final
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
|
||||
extern template class basic_parser<unsigned long long>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<double>
|
||||
@ -907,7 +907,7 @@ template <> class parser<double> final : public basic_parser<double> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
|
||||
extern template class basic_parser<double>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<float>
|
||||
@ -929,7 +929,7 @@ template <> class parser<float> final : public basic_parser<float> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
|
||||
extern template class basic_parser<float>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<std::string>
|
||||
@ -954,7 +954,7 @@ template <> class parser<std::string> final : public basic_parser<std::string> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
|
||||
extern template class basic_parser<std::string>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// parser<char>
|
||||
@ -979,7 +979,7 @@ template <> class parser<char> final : public basic_parser<char> {
|
||||
void anchor() override;
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
|
||||
extern template class basic_parser<char>;
|
||||
|
||||
//--------------------------------------------------
|
||||
// PrintOptionDiff
|
||||
@ -1254,11 +1254,11 @@ class opt : public Option,
|
||||
}
|
||||
};
|
||||
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class opt<char>);
|
||||
EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
|
||||
extern template class opt<unsigned>;
|
||||
extern template class opt<int>;
|
||||
extern template class opt<std::string>;
|
||||
extern template class opt<char>;
|
||||
extern template class opt<bool>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// list_storage class
|
||||
|
@ -174,19 +174,6 @@
|
||||
#define LLVM_UNLIKELY(EXPR) (EXPR)
|
||||
#endif
|
||||
|
||||
// C++ doesn't support 'extern template' of template specializations. GCC does,
|
||||
// but requires __extension__ before it. In the header, use this:
|
||||
// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
|
||||
// in the .cpp file, use this:
|
||||
// TEMPLATE_INSTANTIATION(class foo<bar>);
|
||||
#ifdef __GNUC__
|
||||
#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
|
||||
#define TEMPLATE_INSTANTIATION(X) template X
|
||||
#else
|
||||
#define EXTERN_TEMPLATE_INSTANTIATION(X)
|
||||
#define TEMPLATE_INSTANTIATION(X)
|
||||
#endif
|
||||
|
||||
/// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
|
||||
/// mark a method "not for inlining".
|
||||
#if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0)
|
||||
|
@ -280,13 +280,19 @@ template <typename Info> class OnDiskChainedHashTable {
|
||||
};
|
||||
|
||||
/// \brief Look up the stored data for a particular key.
|
||||
iterator find(const external_key_type &EKey, Info *InfoPtr = 0) {
|
||||
if (!InfoPtr)
|
||||
InfoPtr = &InfoObj;
|
||||
|
||||
using namespace llvm::support;
|
||||
iterator find(const external_key_type &EKey, Info *InfoPtr = nullptr) {
|
||||
const internal_key_type &IKey = InfoObj.GetInternalKey(EKey);
|
||||
hash_value_type KeyHash = InfoObj.ComputeHash(IKey);
|
||||
return find_hashed(IKey, KeyHash, InfoPtr);
|
||||
}
|
||||
|
||||
/// \brief Look up the stored data for a particular key with a known hash.
|
||||
iterator find_hashed(const internal_key_type &IKey, hash_value_type KeyHash,
|
||||
Info *InfoPtr = nullptr) {
|
||||
using namespace llvm::support;
|
||||
|
||||
if (!InfoPtr)
|
||||
InfoPtr = &InfoObj;
|
||||
|
||||
// Each bucket is just an offset into the hash table file.
|
||||
offset_type Idx = KeyHash & (NumBuckets - 1);
|
||||
|
@ -71,7 +71,7 @@ MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
|
||||
|
||||
MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
|
||||
|
||||
MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
|
||||
MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
|
||||
LLVMSymbolLookupCallback SymbolLookUp,
|
||||
void *DisInfo, MCContext *Ctx,
|
||||
std::unique_ptr<MCRelocationInfo> &&RelInfo);
|
||||
@ -92,17 +92,18 @@ class Target {
|
||||
|
||||
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
|
||||
const Triple &TT);
|
||||
typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model RM,
|
||||
typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(const Triple &TT,
|
||||
Reloc::Model RM,
|
||||
CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL);
|
||||
typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
|
||||
typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo *Info);
|
||||
typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
|
||||
typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(const Triple &TT);
|
||||
typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(const Triple &TT,
|
||||
StringRef CPU,
|
||||
StringRef Features);
|
||||
typedef TargetMachine *(*TargetMachineCtorTy)(
|
||||
const Target &T, StringRef TT, StringRef CPU, StringRef Features,
|
||||
const Target &T, const Triple &TT, StringRef CPU, StringRef Features,
|
||||
const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL);
|
||||
// If it weren't for layering issues (this header is in llvm/Support, but
|
||||
@ -150,7 +151,7 @@ class Target {
|
||||
typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(const Triple &TT,
|
||||
MCContext &Ctx);
|
||||
typedef MCSymbolizer *(*MCSymbolizerCtorTy)(
|
||||
StringRef TT, LLVMOpInfoCallback GetOpInfo,
|
||||
const Triple &TT, LLVMOpInfoCallback GetOpInfo,
|
||||
LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
|
||||
std::unique_ptr<MCRelocationInfo> &&RelInfo);
|
||||
|
||||
@ -300,12 +301,12 @@ class Target {
|
||||
|
||||
/// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
|
||||
///
|
||||
MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
|
||||
MCCodeGenInfo *createMCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL) const {
|
||||
if (!MCCodeGenInfoCtorFn)
|
||||
return nullptr;
|
||||
return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
|
||||
return MCCodeGenInfoCtorFn(Triple(TT), RM, CM, OL);
|
||||
}
|
||||
|
||||
/// createMCInstrInfo - Create a MCInstrInfo implementation.
|
||||
@ -326,10 +327,10 @@ class Target {
|
||||
|
||||
/// createMCRegInfo - Create a MCRegisterInfo implementation.
|
||||
///
|
||||
MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
|
||||
MCRegisterInfo *createMCRegInfo(StringRef TT) const {
|
||||
if (!MCRegInfoCtorFn)
|
||||
return nullptr;
|
||||
return MCRegInfoCtorFn(Triple);
|
||||
return MCRegInfoCtorFn(Triple(TT));
|
||||
}
|
||||
|
||||
/// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
|
||||
@ -351,20 +352,20 @@ class Target {
|
||||
/// createTargetMachine - Create a target specific machine implementation
|
||||
/// for the specified \p Triple.
|
||||
///
|
||||
/// \param Triple This argument is used to determine the target machine
|
||||
/// \param TT This argument is used to determine the target machine
|
||||
/// feature set; it should always be provided. Generally this should be
|
||||
/// either the target triple from the module, or the target triple of the
|
||||
/// host if that does not exist.
|
||||
TargetMachine *
|
||||
createTargetMachine(StringRef Triple, StringRef CPU, StringRef Features,
|
||||
createTargetMachine(StringRef TT, StringRef CPU, StringRef Features,
|
||||
const TargetOptions &Options,
|
||||
Reloc::Model RM = Reloc::Default,
|
||||
CodeModel::Model CM = CodeModel::Default,
|
||||
CodeGenOpt::Level OL = CodeGenOpt::Default) const {
|
||||
if (!TargetMachineCtorFn)
|
||||
return nullptr;
|
||||
return TargetMachineCtorFn(*this, Triple, CPU, Features, Options, RM, CM,
|
||||
OL);
|
||||
return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM,
|
||||
CM, OL);
|
||||
}
|
||||
|
||||
/// createMCAsmBackend - Create a target specific assembly parser.
|
||||
@ -529,7 +530,8 @@ class Target {
|
||||
std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
|
||||
MCSymbolizerCtorTy Fn =
|
||||
MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
|
||||
return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo));
|
||||
return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx,
|
||||
std::move(RelInfo));
|
||||
}
|
||||
|
||||
/// @}
|
||||
@ -924,7 +926,7 @@ template <class MCCodeGenInfoImpl> struct RegisterMCCodeGenInfo {
|
||||
}
|
||||
|
||||
private:
|
||||
static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
|
||||
static MCCodeGenInfo *Allocator(const Triple & /*TT*/, Reloc::Model /*RM*/,
|
||||
CodeModel::Model /*CM*/,
|
||||
CodeGenOpt::Level /*OL*/) {
|
||||
return new MCCodeGenInfoImpl();
|
||||
@ -1023,7 +1025,7 @@ template <class MCRegisterInfoImpl> struct RegisterMCRegInfo {
|
||||
}
|
||||
|
||||
private:
|
||||
static MCRegisterInfo *Allocator(StringRef /*TT*/) {
|
||||
static MCRegisterInfo *Allocator(const Triple & /*TT*/) {
|
||||
return new MCRegisterInfoImpl();
|
||||
}
|
||||
};
|
||||
@ -1090,11 +1092,11 @@ template <class TargetMachineImpl> struct RegisterTargetMachine {
|
||||
}
|
||||
|
||||
private:
|
||||
static TargetMachine *Allocator(const Target &T, StringRef TT, StringRef CPU,
|
||||
StringRef FS, const TargetOptions &Options,
|
||||
Reloc::Model RM, CodeModel::Model CM,
|
||||
CodeGenOpt::Level OL) {
|
||||
return new TargetMachineImpl(T, Triple(TT), CPU, FS, Options, RM, CM, OL);
|
||||
static TargetMachine *Allocator(const Target &T, const Triple &TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
const TargetOptions &Options, Reloc::Model RM,
|
||||
CodeModel::Model CM, CodeGenOpt::Level OL) {
|
||||
return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -165,8 +165,10 @@ class raw_ostream {
|
||||
if (Size > (size_t)(OutBufEnd - OutBufCur))
|
||||
return write(Str.data(), Size);
|
||||
|
||||
memcpy(OutBufCur, Str.data(), Size);
|
||||
OutBufCur += Size;
|
||||
if (Size) {
|
||||
memcpy(OutBufCur, Str.data(), Size);
|
||||
OutBufCur += Size;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1222,11 +1222,11 @@ class Record {
|
||||
/// get the corresponding DefInit.
|
||||
DefInit *getDefInit();
|
||||
|
||||
const std::vector<Init *> &getTemplateArgs() const {
|
||||
ArrayRef<Init *> getTemplateArgs() const {
|
||||
return TemplateArgs;
|
||||
}
|
||||
const std::vector<RecordVal> &getValues() const { return Values; }
|
||||
const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
|
||||
ArrayRef<RecordVal> getValues() const { return Values; }
|
||||
ArrayRef<Record *> getSuperClasses() const { return SuperClasses; }
|
||||
ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
|
||||
|
||||
bool isTemplateArg(Init *Name) const {
|
||||
|
@ -872,7 +872,7 @@ def LOAD_STACK_GUARD : Instruction {
|
||||
let hasSideEffects = 0;
|
||||
bit isPseudo = 1;
|
||||
}
|
||||
def FRAME_ALLOC : Instruction {
|
||||
def LOCAL_ESCAPE : Instruction {
|
||||
// This instruction is really just a label. It has to be part of the chain so
|
||||
// that it doesn't get dropped from the DAG, but it produces nothing and has
|
||||
// no side effects.
|
||||
@ -1014,7 +1014,7 @@ class InstAlias<string Asm, dag Result, int Emit = 1> {
|
||||
// Predicates - Predicates that must be true for this to match.
|
||||
list<Predicate> Predicates = [];
|
||||
|
||||
// If the instruction specified in Result has defined an AsmMatchConverter
|
||||
// If the instruction specified in Result has defined an AsmMatchConverter
|
||||
// then setting this to 1 will cause the alias to use the AsmMatchConverter
|
||||
// function when converting the OperandVector into an MCInst instead of the
|
||||
// function that is generated by the dag Result.
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class BitVector;
|
||||
class CalleeSavedInfo;
|
||||
class MachineFunction;
|
||||
class RegScavenger;
|
||||
@ -226,13 +227,15 @@ class TargetFrameLowering {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// processFunctionBeforeCalleeSavedScan - This method is called immediately
|
||||
/// before PrologEpilogInserter scans the physical registers used to determine
|
||||
/// what callee saved registers should be spilled. This method is optional.
|
||||
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS = nullptr) const {
|
||||
|
||||
}
|
||||
/// This method determines which of the registers reported by
|
||||
/// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved.
|
||||
/// The default implementation checks populates the \p SavedRegs bitset with
|
||||
/// all registers which are modified in the function, targets may override
|
||||
/// this function to save additional registers.
|
||||
/// This method also sets up the register scavenger ensuring there is a free
|
||||
/// register or a frameindex available.
|
||||
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
||||
RegScavenger *RS = nullptr) const;
|
||||
|
||||
/// processFunctionBeforeFrameFinalized - This method is called immediately
|
||||
/// before the specified function's frame layout (MF.getFrameInfo()) is
|
||||
|
@ -161,27 +161,27 @@ class TargetLoweringBase {
|
||||
|
||||
public:
|
||||
const TargetMachine &getTargetMachine() const { return TM; }
|
||||
const DataLayout *getDataLayout() const { return TM.getDataLayout(); }
|
||||
|
||||
bool isBigEndian() const { return !IsLittleEndian; }
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
virtual bool useSoftFloat() const { return false; }
|
||||
|
||||
/// Return the pointer type for the given address space, defaults to
|
||||
/// the pointer type from the data layout.
|
||||
/// FIXME: The default needs to be removed once all the code is updated.
|
||||
virtual MVT getPointerTy(uint32_t /*AS*/ = 0) const;
|
||||
unsigned getPointerSizeInBits(uint32_t AS = 0) const;
|
||||
unsigned getPointerTypeSizeInBits(Type *Ty) const;
|
||||
virtual MVT getScalarShiftAmountTy(EVT LHSTy) const;
|
||||
MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const {
|
||||
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
|
||||
}
|
||||
|
||||
EVT getShiftAmountTy(EVT LHSTy) const;
|
||||
/// EVT is not used in-tree, but is used by out-of-tree target.
|
||||
/// A documentation for this function would be nice...
|
||||
virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const;
|
||||
|
||||
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const;
|
||||
|
||||
/// Returns the type to be used for the index operand of:
|
||||
/// ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT,
|
||||
/// ISD::INSERT_SUBVECTOR, and ISD::EXTRACT_SUBVECTOR
|
||||
virtual MVT getVectorIdxTy() const {
|
||||
return getPointerTy();
|
||||
virtual MVT getVectorIdxTy(const DataLayout &DL) const {
|
||||
return getPointerTy(DL);
|
||||
}
|
||||
|
||||
/// Return true if the select operation is expensive for this target.
|
||||
@ -327,7 +327,8 @@ class TargetLoweringBase {
|
||||
}
|
||||
|
||||
/// Return the ValueType of the result of SETCC operations.
|
||||
virtual EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
|
||||
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
|
||||
EVT VT) const;
|
||||
|
||||
/// Return the ValueType for comparison libcalls. Comparions libcalls include
|
||||
/// floating point comparion calls, and Ordered/Unordered check calls on
|
||||
@ -715,17 +716,18 @@ class TargetLoweringBase {
|
||||
/// operations except for the pointer size. If AllowUnknown is true, this
|
||||
/// will return MVT::Other for types with no EVT counterpart (e.g. structs),
|
||||
/// otherwise it will assert.
|
||||
EVT getValueType(Type *Ty, bool AllowUnknown = false) const {
|
||||
EVT getValueType(const DataLayout &DL, Type *Ty,
|
||||
bool AllowUnknown = false) const {
|
||||
// Lower scalar pointers to native pointer types.
|
||||
if (PointerType *PTy = dyn_cast<PointerType>(Ty))
|
||||
return getPointerTy(PTy->getAddressSpace());
|
||||
return getPointerTy(DL, PTy->getAddressSpace());
|
||||
|
||||
if (Ty->isVectorTy()) {
|
||||
VectorType *VTy = cast<VectorType>(Ty);
|
||||
Type *Elm = VTy->getElementType();
|
||||
// Lower vectors of pointers to native pointer types.
|
||||
if (PointerType *PT = dyn_cast<PointerType>(Elm)) {
|
||||
EVT PointerTy(getPointerTy(PT->getAddressSpace()));
|
||||
EVT PointerTy(getPointerTy(DL, PT->getAddressSpace()));
|
||||
Elm = PointerTy.getTypeForEVT(Ty->getContext());
|
||||
}
|
||||
|
||||
@ -736,14 +738,15 @@ class TargetLoweringBase {
|
||||
}
|
||||
|
||||
/// Return the MVT corresponding to this LLVM type. See getValueType.
|
||||
MVT getSimpleValueType(Type *Ty, bool AllowUnknown = false) const {
|
||||
return getValueType(Ty, AllowUnknown).getSimpleVT();
|
||||
MVT getSimpleValueType(const DataLayout &DL, Type *Ty,
|
||||
bool AllowUnknown = false) const {
|
||||
return getValueType(DL, Ty, AllowUnknown).getSimpleVT();
|
||||
}
|
||||
|
||||
/// Return the desired alignment for ByVal or InAlloca aggregate function
|
||||
/// arguments in the caller parameter area. This is the actual alignment, not
|
||||
/// its logarithm.
|
||||
virtual unsigned getByValTypeAlignment(Type *Ty) const;
|
||||
virtual unsigned getByValTypeAlignment(Type *Ty, const DataLayout &DL) const;
|
||||
|
||||
/// Return the type of registers that this ValueType will eventually require.
|
||||
MVT getRegisterType(MVT VT) const {
|
||||
@ -818,8 +821,8 @@ class TargetLoweringBase {
|
||||
/// When splitting a value of the specified type into parts, does the Lo
|
||||
/// or Hi part come first? This usually follows the endianness, except
|
||||
/// for ppcf128, where the Hi part always comes first.
|
||||
bool hasBigEndianPartOrdering(EVT VT) const {
|
||||
return isBigEndian() || VT == MVT::ppcf128;
|
||||
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const {
|
||||
return DL.isBigEndian() || VT == MVT::ppcf128;
|
||||
}
|
||||
|
||||
/// If true, the target has custom DAG combine transformations that it can
|
||||
@ -1006,7 +1009,8 @@ class TargetLoweringBase {
|
||||
int InstructionOpcodeToISD(unsigned Opcode) const;
|
||||
|
||||
/// Estimate the cost of type-legalization and the legalized type.
|
||||
std::pair<unsigned, MVT> getTypeLegalizationCost(Type *Ty) const;
|
||||
std::pair<unsigned, MVT> getTypeLegalizationCost(const DataLayout &DL,
|
||||
Type *Ty) const;
|
||||
|
||||
/// @}
|
||||
|
||||
@ -1460,8 +1464,8 @@ class TargetLoweringBase {
|
||||
/// If the address space cannot be determined, it will be -1.
|
||||
///
|
||||
/// TODO: Remove default argument
|
||||
virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty,
|
||||
unsigned AddrSpace) const;
|
||||
virtual bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
|
||||
Type *Ty, unsigned AddrSpace) const;
|
||||
|
||||
/// \brief Return the cost of the scaling factor used in the addressing mode
|
||||
/// represented by AM for this target, for a load/store of the specified type.
|
||||
@ -1470,10 +1474,10 @@ class TargetLoweringBase {
|
||||
/// If the AM is not supported, it returns a negative value.
|
||||
/// TODO: Handle pre/postinc as well.
|
||||
/// TODO: Remove default argument
|
||||
virtual int getScalingFactorCost(const AddrMode &AM, Type *Ty,
|
||||
unsigned AS = 0) const {
|
||||
virtual int getScalingFactorCost(const DataLayout &DL, const AddrMode &AM,
|
||||
Type *Ty, unsigned AS = 0) const {
|
||||
// Default: assume that any scaling factor used in a legal AM is free.
|
||||
if (isLegalAddressingMode(AM, Ty, AS))
|
||||
if (isLegalAddressingMode(DL, AM, Ty, AS))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
@ -1734,9 +1738,6 @@ class TargetLoweringBase {
|
||||
private:
|
||||
const TargetMachine &TM;
|
||||
|
||||
/// True if this is a little endian target.
|
||||
bool IsLittleEndian;
|
||||
|
||||
/// Tells the code generator not to expand operations into sequences that use
|
||||
/// the select operations if possible.
|
||||
bool SelectIsExpensive;
|
||||
@ -2414,6 +2415,7 @@ class TargetLowering : public TargetLoweringBase {
|
||||
ArgListTy &getArgs() {
|
||||
return Args;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// This function lowers an abstract call to a function into an actual call.
|
||||
@ -2485,7 +2487,8 @@ class TargetLowering : public TargetLoweringBase {
|
||||
/// Return the register ID of the name passed in. Used by named register
|
||||
/// global variables extension. There is no target-independent behaviour
|
||||
/// so the default action is to bail.
|
||||
virtual unsigned getRegisterByName(const char* RegName, EVT VT) const {
|
||||
virtual unsigned getRegisterByName(const char* RegName, EVT VT,
|
||||
SelectionDAG &DAG) const {
|
||||
report_fatal_error("Named registers not implemented for this target");
|
||||
}
|
||||
|
||||
@ -2657,7 +2660,8 @@ class TargetLowering : public TargetLoweringBase {
|
||||
/// specific constraints and their prefixes, and also tie in the associated
|
||||
/// operand values. If this returns an empty vector, and if the constraint
|
||||
/// string itself isn't empty, there was an error parsing.
|
||||
virtual AsmOperandInfoVector ParseConstraints(const TargetRegisterInfo *TRI,
|
||||
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL,
|
||||
const TargetRegisterInfo *TRI,
|
||||
ImmutableCallSite CS) const;
|
||||
|
||||
/// Examine constraint type and operand type and determine a weight value.
|
||||
@ -2679,7 +2683,7 @@ class TargetLowering : public TargetLoweringBase {
|
||||
SelectionDAG *DAG = nullptr) const;
|
||||
|
||||
/// Given a constraint, return the type of constraint it is for this target.
|
||||
virtual ConstraintType getConstraintType(const std::string &Constraint) const;
|
||||
virtual ConstraintType getConstraintType(StringRef Constraint) const;
|
||||
|
||||
/// Given a physical register constraint (e.g. {edx}), return the register
|
||||
/// number and the register class for the register.
|
||||
@ -2692,10 +2696,9 @@ class TargetLowering : public TargetLoweringBase {
|
||||
/// returns a register number of 0 and a null register class pointer.
|
||||
virtual std::pair<unsigned, const TargetRegisterClass *>
|
||||
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
|
||||
const std::string &Constraint, MVT VT) const;
|
||||
StringRef Constraint, MVT VT) const;
|
||||
|
||||
virtual unsigned
|
||||
getInlineAsmMemConstraint(const std::string &ConstraintCode) const {
|
||||
virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const {
|
||||
if (ConstraintCode == "i")
|
||||
return InlineAsm::Constraint_i;
|
||||
else if (ConstraintCode == "m")
|
||||
@ -2823,9 +2826,9 @@ class TargetLowering : public TargetLoweringBase {
|
||||
/// Given an LLVM IR type and return type attributes, compute the return value
|
||||
/// EVTs and flags, and optionally also the offsets, if the return value is
|
||||
/// being lowered to memory.
|
||||
void GetReturnInfo(Type* ReturnType, AttributeSet attr,
|
||||
void GetReturnInfo(Type *ReturnType, AttributeSet attr,
|
||||
SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const TargetLowering &TLI);
|
||||
const TargetLowering &TLI, const DataLayout &DL);
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
|
@ -212,8 +212,8 @@ class TargetMachine {
|
||||
/// supported, or false on success.
|
||||
virtual bool addPassesToEmitFile(
|
||||
PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
|
||||
bool /*DisableVerify*/ = true, AnalysisID /*StartAfter*/ = nullptr,
|
||||
AnalysisID /*StopAfter*/ = nullptr,
|
||||
bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,
|
||||
AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopAfter*/ = nullptr,
|
||||
MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
|
||||
return true;
|
||||
}
|
||||
@ -260,8 +260,8 @@ class LLVMTargetMachine : public TargetMachine {
|
||||
/// emitted. Typically this will involve several steps of code generation.
|
||||
bool addPassesToEmitFile(
|
||||
PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
|
||||
bool DisableVerify = true, AnalysisID StartAfter = nullptr,
|
||||
AnalysisID StopAfter = nullptr,
|
||||
bool DisableVerify = true, AnalysisID StartBefore = nullptr,
|
||||
AnalysisID StartAfter = nullptr, AnalysisID StopAfter = nullptr,
|
||||
MachineFunctionInitializer *MFInitializer = nullptr) override;
|
||||
|
||||
/// Add passes to the specified pass manager to get machine code emitted with
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user