Vendor import of llvm trunk r242221:

https://llvm.org/svn/llvm-project/llvm/trunk@242221
This commit is contained in:
Dimitry Andric 2015-08-07 23:01:33 +00:00
parent 1a82d4c088
commit ee8648bdac
860 changed files with 32350 additions and 11242 deletions

4
.gitignore vendored
View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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++

View File

@ -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

View File

@ -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.
*

View File

@ -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);

View File

@ -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;
/**

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}
};

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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 */

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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());
}

View File

@ -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);

View File

@ -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;
}
};
}

View File

@ -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));

View File

@ -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

View File

@ -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];
}
};
};

View File

@ -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.
//===--------------------------------------------------------------------===//

View File

@ -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);
}
};

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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; }

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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
//===--------------------------------------------------------------------===//

View File

@ -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

View File

@ -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.

View File

@ -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; }

View File

@ -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!");

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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());

View File

@ -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.

View File

@ -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(); }

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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);
}

View File

@ -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();

View File

@ -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() {

View File

@ -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"

View File

@ -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]>;
}
//===----------------------------------------------------------------------===//

View 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.".
}

View File

@ -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]>;

View File

@ -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));

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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) {

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSYMBOLMACHO_H
#define setIsWeakExternal
#define LLVM_MC_MCSYMBOLMACHO_H
#include "llvm/MC/MCSymbol.h"

View File

@ -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
}

View File

@ -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;
};
}

View File

@ -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

View File

@ -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;

View File

@ -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));
}

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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);
}
};

View File

@ -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;
}

View File

@ -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 {

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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