Vendor import of llvm trunk r303197:
https://llvm.org/svn/llvm-project/llvm/trunk@303197
This commit is contained in:
parent
7577e511db
commit
d8101ca407
@ -265,7 +265,7 @@ D: Release manager (1.7+)
|
||||
N: Sylvestre Ledru
|
||||
E: sylvestre@debian.org
|
||||
W: http://sylvestre.ledru.info/
|
||||
W: http://llvm.org/apt/
|
||||
W: http://apt.llvm.org/
|
||||
D: Debian and Ubuntu packaging
|
||||
D: Continuous integration with jenkins
|
||||
|
||||
|
@ -530,16 +530,6 @@ else()
|
||||
message(STATUS "Doxygen disabled.")
|
||||
endif()
|
||||
|
||||
if (LLVM_ENABLE_SPHINX)
|
||||
message(STATUS "Sphinx enabled.")
|
||||
find_package(Sphinx REQUIRED)
|
||||
if (LLVM_BUILD_DOCS)
|
||||
add_custom_target(sphinx ALL)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Sphinx disabled.")
|
||||
endif()
|
||||
|
||||
set(LLVM_BINDINGS "")
|
||||
if(WIN32)
|
||||
message(STATUS "Go bindings disabled.")
|
||||
|
@ -1,3 +1,16 @@
|
||||
|
||||
# Create sphinx target
|
||||
if (LLVM_ENABLE_SPHINX)
|
||||
message(STATUS "Sphinx enabled.")
|
||||
find_package(Sphinx REQUIRED)
|
||||
if (LLVM_BUILD_DOCS AND NOT TARGET sphinx)
|
||||
add_custom_target(sphinx ALL)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Sphinx disabled.")
|
||||
endif()
|
||||
|
||||
|
||||
# Handy function for creating the different Sphinx targets.
|
||||
#
|
||||
# ``builder`` should be one of the supported builders used by
|
||||
|
@ -103,8 +103,8 @@ endif()
|
||||
endif()
|
||||
|
||||
if (LLVM_ENABLE_SPHINX)
|
||||
include(AddSphinxTarget)
|
||||
if (SPHINX_FOUND)
|
||||
include(AddSphinxTarget)
|
||||
if (${SPHINX_OUTPUT_HTML})
|
||||
add_sphinx_target(html llvm)
|
||||
endif()
|
||||
|
@ -699,14 +699,14 @@ For developers to work with a git monorepo
|
||||
|
||||
.. note::
|
||||
|
||||
This set-up is using unofficial mirror hosted on GitHub, use with caution.
|
||||
This set-up is using an unofficial mirror hosted on GitHub, use with caution.
|
||||
|
||||
To set up a clone of all the llvm projects using a unified repository:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
% export TOP_LEVEL_DIR=`pwd`
|
||||
% git clone https://github.com/llvm-project/llvm-project/
|
||||
% git clone https://github.com/llvm-project/llvm-project-20170507/ llvm-project
|
||||
% cd llvm-project
|
||||
% git config branch.master.rebase true
|
||||
|
||||
|
348
docs/LangRef.rst
348
docs/LangRef.rst
@ -641,8 +641,9 @@ assume that the globals are densely packed in their section and try to
|
||||
iterate over them as an array, alignment padding would break this
|
||||
iteration. The maximum alignment is ``1 << 29``.
|
||||
|
||||
Globals can also have a :ref:`DLL storage class <dllstorageclass>` and
|
||||
an optional list of attached :ref:`metadata <metadata>`,
|
||||
Globals can also have a :ref:`DLL storage class <dllstorageclass>`,
|
||||
an optional :ref:`global attributes <glattrs>` and
|
||||
an optional list of attached :ref:`metadata <metadata>`.
|
||||
|
||||
Variables and aliases can have a
|
||||
:ref:`Thread Local Storage Model <tls_model>`.
|
||||
@ -1624,6 +1625,14 @@ example:
|
||||
the ELF x86-64 abi, but it can be disabled for some compilation
|
||||
units.
|
||||
|
||||
.. _glattrs:
|
||||
|
||||
Global Attributes
|
||||
-----------------
|
||||
|
||||
Attributes may be set to communicate additional information about a global variable.
|
||||
Unlike :ref:`function attributes <fnattrs>`, attributes on a global variable
|
||||
are grouped into a single :ref:`attribute group <attrgrp>`.
|
||||
|
||||
.. _opbundles:
|
||||
|
||||
@ -3664,6 +3673,9 @@ Sparc:
|
||||
|
||||
- ``I``: An immediate 13-bit signed integer.
|
||||
- ``r``: A 32-bit integer register.
|
||||
- ``f``: Any floating-point register on SparcV8, or a floating point
|
||||
register in the "low" half of the registers on SparcV9.
|
||||
- ``e``: Any floating point register. (Same as ``f`` on SparcV8.)
|
||||
|
||||
SystemZ:
|
||||
|
||||
@ -11687,6 +11699,338 @@ Examples:
|
||||
|
||||
%r2 = call float @llvm.fmuladd.f32(float %a, float %b, float %c) ; yields float:r2 = (a * b) + c
|
||||
|
||||
|
||||
Experimental Vector Reduction Intrinsics
|
||||
----------------------------------------
|
||||
|
||||
Horizontal reductions of vectors can be expressed using the following
|
||||
intrinsics. Each one takes a vector operand as an input and applies its
|
||||
respective operation across all elements of the vector, returning a single
|
||||
scalar result of the same element type.
|
||||
|
||||
|
||||
'``llvm.experimental.vector.reduce.add.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.add.i32.v4i32(<4 x i32> %a)
|
||||
declare i64 @llvm.experimental.vector.reduce.add.i64.v2i64(<2 x i64> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.add.*``' intrinsics do an integer ``ADD``
|
||||
reduction of a vector, returning the result as a scalar. The return type matches
|
||||
the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.fadd.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare float @llvm.experimental.vector.reduce.fadd.f32.v4f32(float %acc, <4 x float> %a)
|
||||
declare double @llvm.experimental.vector.reduce.fadd.f64.v2f64(double %acc, <2 x double> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.fadd.*``' intrinsics do a floating point
|
||||
``ADD`` reduction of a vector, returning the result as a scalar. The return type
|
||||
matches the element-type of the vector input.
|
||||
|
||||
If the intrinsic call has fast-math flags, then the reduction will not preserve
|
||||
the associativity of an equivalent scalarized counterpart. If it does not have
|
||||
fast-math flags, then the reduction will be *ordered*, implying that the
|
||||
operation respects the associativity of a scalarized reduction.
|
||||
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The first argument to this intrinsic is a scalar accumulator value, which is
|
||||
only used when there are no fast-math flags attached. This argument may be undef
|
||||
when fast-math flags are used.
|
||||
|
||||
The second argument must be a vector of floating point values.
|
||||
|
||||
Examples:
|
||||
"""""""""
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
%fast = call fast float @llvm.experimental.vector.reduce.fadd.f32.v4f32(float undef, <4 x float> %input) ; fast reduction
|
||||
%ord = call float @llvm.experimental.vector.reduce.fadd.f32.v4f32(float %acc, <4 x float> %input) ; ordered reduction
|
||||
|
||||
|
||||
'``llvm.experimental.vector.reduce.mul.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.mul.i32.v4i32(<4 x i32> %a)
|
||||
declare i64 @llvm.experimental.vector.reduce.mul.i64.v2i64(<2 x i64> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.mul.*``' intrinsics do an integer ``MUL``
|
||||
reduction of a vector, returning the result as a scalar. The return type matches
|
||||
the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.fmul.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare float @llvm.experimental.vector.reduce.fmul.f32.v4f32(float %acc, <4 x float> %a)
|
||||
declare double @llvm.experimental.vector.reduce.fmul.f64.v2f64(double %acc, <2 x double> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.fmul.*``' intrinsics do a floating point
|
||||
``MUL`` reduction of a vector, returning the result as a scalar. The return type
|
||||
matches the element-type of the vector input.
|
||||
|
||||
If the intrinsic call has fast-math flags, then the reduction will not preserve
|
||||
the associativity of an equivalent scalarized counterpart. If it does not have
|
||||
fast-math flags, then the reduction will be *ordered*, implying that the
|
||||
operation respects the associativity of a scalarized reduction.
|
||||
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The first argument to this intrinsic is a scalar accumulator value, which is
|
||||
only used when there are no fast-math flags attached. This argument may be undef
|
||||
when fast-math flags are used.
|
||||
|
||||
The second argument must be a vector of floating point values.
|
||||
|
||||
Examples:
|
||||
"""""""""
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
%fast = call fast float @llvm.experimental.vector.reduce.fmul.f32.v4f32(float undef, <4 x float> %input) ; fast reduction
|
||||
%ord = call float @llvm.experimental.vector.reduce.fmul.f32.v4f32(float %acc, <4 x float> %input) ; ordered reduction
|
||||
|
||||
'``llvm.experimental.vector.reduce.and.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.and.i32.v4i32(<4 x i32> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.and.*``' intrinsics do a bitwise ``AND``
|
||||
reduction of a vector, returning the result as a scalar. The return type matches
|
||||
the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.or.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.or.i32.v4i32(<4 x i32> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.or.*``' intrinsics do a bitwise ``OR`` reduction
|
||||
of a vector, returning the result as a scalar. The return type matches the
|
||||
element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.xor.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.xor.i32.v4i32(<4 x i32> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.xor.*``' intrinsics do a bitwise ``XOR``
|
||||
reduction of a vector, returning the result as a scalar. The return type matches
|
||||
the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.smax.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.smax.i32.v4i32(<4 x i32> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.smax.*``' intrinsics do a signed integer
|
||||
``MAX`` reduction of a vector, returning the result as a scalar. The return type
|
||||
matches the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.smin.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.smin.i32.v4i32(<4 x i32> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.smin.*``' intrinsics do a signed integer
|
||||
``MIN`` reduction of a vector, returning the result as a scalar. The return type
|
||||
matches the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.umax.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.umax.i32.v4i32(<4 x i32> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.umax.*``' intrinsics do an unsigned
|
||||
integer ``MAX`` reduction of a vector, returning the result as a scalar. The
|
||||
return type matches the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.umin.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare i32 @llvm.experimental.vector.reduce.umin.i32.v4i32(<4 x i32> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.umin.*``' intrinsics do an unsigned
|
||||
integer ``MIN`` reduction of a vector, returning the result as a scalar. The
|
||||
return type matches the element-type of the vector input.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of integer values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.fmax.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare float @llvm.experimental.vector.reduce.fmax.f32.v4f32(<4 x float> %a)
|
||||
declare double @llvm.experimental.vector.reduce.fmax.f64.v2f64(<2 x double> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.fmax.*``' intrinsics do a floating point
|
||||
``MAX`` reduction of a vector, returning the result as a scalar. The return type
|
||||
matches the element-type of the vector input.
|
||||
|
||||
If the intrinsic call has the ``nnan`` fast-math flag then the operation can
|
||||
assume that NaNs are not present in the input vector.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of floating point values.
|
||||
|
||||
'``llvm.experimental.vector.reduce.fmin.*``' Intrinsic
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Syntax:
|
||||
"""""""
|
||||
|
||||
::
|
||||
|
||||
declare float @llvm.experimental.vector.reduce.fmin.f32.v4f32(<4 x float> %a)
|
||||
declare double @llvm.experimental.vector.reduce.fmin.f64.v2f64(<2 x double> %a)
|
||||
|
||||
Overview:
|
||||
"""""""""
|
||||
|
||||
The '``llvm.experimental.vector.reduce.fmin.*``' intrinsics do a floating point
|
||||
``MIN`` reduction of a vector, returning the result as a scalar. The return type
|
||||
matches the element-type of the vector input.
|
||||
|
||||
If the intrinsic call has the ``nnan`` fast-math flag then the operation can
|
||||
assume that NaNs are not present in the input vector.
|
||||
|
||||
Arguments:
|
||||
""""""""""
|
||||
The argument to this intrinsic must be a vector of floating point values.
|
||||
|
||||
Half Precision Floating Point Intrinsics
|
||||
----------------------------------------
|
||||
|
||||
|
@ -249,6 +249,14 @@ S
|
||||
Superword-Level Parallelism, same as :ref:`Basic-Block Vectorization
|
||||
<lexicon-bb-vectorization>`.
|
||||
|
||||
**Splat**
|
||||
Splat refers to a vector of identical scalar elements.
|
||||
|
||||
The term is based on the PowerPC Altivec instructions that provided
|
||||
this functionality in hardware. For example, "vsplth" and the corresponding
|
||||
software intrinsic "vec_splat()". Examples of other hardware names for this
|
||||
action include "duplicate" (ARM) and "broadcast" (x86).
|
||||
|
||||
**SRoA**
|
||||
Scalar Replacement of Aggregates
|
||||
|
||||
|
@ -305,6 +305,10 @@ The most important command line options are:
|
||||
- 1 : close ``stdout``
|
||||
- 2 : close ``stderr``
|
||||
- 3 : close both ``stdout`` and ``stderr``.
|
||||
``-print_coverage``
|
||||
If 1, print coverage information as text at exit.
|
||||
``-dump_coverage``
|
||||
If 1, dump coverage information as a .sancov file at exit.
|
||||
|
||||
For the full list of flags run the fuzzer binary with ``-help=1``.
|
||||
|
||||
@ -543,12 +547,19 @@ You can get the coverage for your corpus like this:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
ASAN_OPTIONS=coverage=1 ./fuzzer CORPUS_DIR -runs=0
|
||||
./fuzzer CORPUS_DIR -runs=0 -print_coverage=1
|
||||
|
||||
This will run all tests in the CORPUS_DIR but will not perform any fuzzing.
|
||||
At the end of the process it will dump a single ``.sancov`` file with coverage
|
||||
information. See SanitizerCoverage_ for details on querying the file using the
|
||||
``sancov`` tool.
|
||||
At the end of the process it will print text describing what code has been covered and what hasn't.
|
||||
|
||||
Alternatively, use
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./fuzzer CORPUS_DIR -runs=0 -dump_coverage=1
|
||||
|
||||
which will dump a ``.sancov`` file with coverage information.
|
||||
See SanitizerCoverage_ for details on querying the file using the ``sancov`` tool.
|
||||
|
||||
You may also use other ways to visualize coverage,
|
||||
e.g. using `Clang coverage <http://clang.llvm.org/docs/SourceBasedCodeCoverage.html>`_,
|
||||
|
@ -40,6 +40,10 @@ Non-comprehensive list of changes in this release
|
||||
functionality, or simply have a lot to talk about), see the `NOTE` below
|
||||
for adding a new subsection.
|
||||
|
||||
* LLVM's ``WeakVH`` has been renamed to ``WeakTrackingVH`` and a new ``WeakVH``
|
||||
has been introduced. The new ``WeakVH`` nulls itself out on deletion, but
|
||||
does not track values across RAUW.
|
||||
|
||||
* ... next change ...
|
||||
|
||||
.. NOTE
|
||||
|
@ -157,6 +157,11 @@ private:
|
||||
return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
|
||||
}
|
||||
|
||||
/// Utility method to change the bit width of this APInt to new bit width,
|
||||
/// allocating and/or deallocating as necessary. There is no guarantee on the
|
||||
/// value of any bits upon return. Caller should populate the bits after.
|
||||
void reallocate(unsigned NewBitWidth);
|
||||
|
||||
/// \brief Convert a char array into an APInt
|
||||
///
|
||||
/// \param radix 2, 8, 10, 16, or 36
|
||||
@ -1437,6 +1442,12 @@ public:
|
||||
/// as "bitPosition".
|
||||
void flipBit(unsigned bitPosition);
|
||||
|
||||
/// Negate this APInt in place.
|
||||
void negate() {
|
||||
flipAllBits();
|
||||
++(*this);
|
||||
}
|
||||
|
||||
/// Insert the bits from a smaller APInt starting at bitPosition.
|
||||
void insertBits(const APInt &SubBits, unsigned bitPosition);
|
||||
|
||||
@ -1646,12 +1657,7 @@ public:
|
||||
/// re-interprets the bits as a double. Note that it is valid to do this on
|
||||
/// any bit width. Exactly 64 bits will be translated.
|
||||
double bitsToDouble() const {
|
||||
union {
|
||||
uint64_t I;
|
||||
double D;
|
||||
} T;
|
||||
T.I = (isSingleWord() ? U.VAL : U.pVal[0]);
|
||||
return T.D;
|
||||
return BitsToDouble(getWord(0));
|
||||
}
|
||||
|
||||
/// \brief Converts APInt bits to a double
|
||||
@ -1660,12 +1666,7 @@ public:
|
||||
/// re-interprets the bits as a float. Note that it is valid to do this on
|
||||
/// any bit width. Exactly 32 bits will be translated.
|
||||
float bitsToFloat() const {
|
||||
union {
|
||||
unsigned I;
|
||||
float F;
|
||||
} T;
|
||||
T.I = unsigned((isSingleWord() ? U.VAL : U.pVal[0]));
|
||||
return T.F;
|
||||
return BitsToFloat(getWord(0));
|
||||
}
|
||||
|
||||
/// \brief Converts a double to APInt bits.
|
||||
@ -1673,12 +1674,7 @@ public:
|
||||
/// The conversion does not do a translation from double to integer, it just
|
||||
/// re-interprets the bits of the double.
|
||||
static APInt doubleToBits(double V) {
|
||||
union {
|
||||
uint64_t I;
|
||||
double D;
|
||||
} T;
|
||||
T.D = V;
|
||||
return APInt(sizeof T * CHAR_BIT, T.I);
|
||||
return APInt(sizeof(double) * CHAR_BIT, DoubleToBits(V));
|
||||
}
|
||||
|
||||
/// \brief Converts a float to APInt bits.
|
||||
@ -1686,12 +1682,7 @@ public:
|
||||
/// The conversion does not do a translation from float to integer, it just
|
||||
/// re-interprets the bits of the float.
|
||||
static APInt floatToBits(float V) {
|
||||
union {
|
||||
unsigned I;
|
||||
float F;
|
||||
} T;
|
||||
T.F = V;
|
||||
return APInt(sizeof T * CHAR_BIT, T.I);
|
||||
return APInt(sizeof(float) * CHAR_BIT, FloatToBits(V));
|
||||
}
|
||||
|
||||
/// @}
|
||||
@ -1852,10 +1843,9 @@ public:
|
||||
unsigned);
|
||||
|
||||
/// DST = LHS * RHS, where DST has width the sum of the widths of the
|
||||
/// operands. No overflow occurs. DST must be disjoint from both
|
||||
/// operands. Returns the number of parts required to hold the result.
|
||||
static unsigned tcFullMultiply(WordType *, const WordType *,
|
||||
const WordType *, unsigned, unsigned);
|
||||
/// operands. No overflow occurs. DST must be disjoint from both operands.
|
||||
static void tcFullMultiply(WordType *, const WordType *,
|
||||
const WordType *, unsigned, unsigned);
|
||||
|
||||
/// If RHS is zero LHS and REMAINDER are left unchanged, return one.
|
||||
/// Otherwise set LHS to LHS / RHS with the fractional part discarded, set
|
||||
@ -1997,8 +1987,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
|
||||
}
|
||||
|
||||
inline APInt operator-(APInt v) {
|
||||
v.flipAllBits();
|
||||
++v;
|
||||
v.negate();
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ public:
|
||||
|
||||
/// find_prev - Returns the index of the first set bit that precedes the
|
||||
/// the bit at \p PriorTo. Returns -1 if all previous bits are unset.
|
||||
int find_prev(unsigned PriorTo) {
|
||||
int find_prev(unsigned PriorTo) const {
|
||||
if (PriorTo == 0)
|
||||
return -1;
|
||||
|
||||
|
@ -706,6 +706,18 @@ struct is_one_of<T, U, Ts...> {
|
||||
std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
|
||||
};
|
||||
|
||||
/// \brief traits class for checking whether type T is a base class for all
|
||||
/// the given types in the variadic list.
|
||||
template <typename T, typename... Ts> struct are_base_of {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <typename T, typename U, typename... Ts>
|
||||
struct are_base_of<T, U, Ts...> {
|
||||
static const bool value =
|
||||
std::is_base_of<T, U>::value && are_base_of<T, Ts...>::value;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Extra additions for arrays
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1079,7 +1091,7 @@ private:
|
||||
///
|
||||
/// std::vector<char> Items = {'A', 'B', 'C', 'D'};
|
||||
/// for (auto X : enumerate(Items)) {
|
||||
/// printf("Item %d - %c\n", X.Index, X.Value);
|
||||
/// printf("Item %d - %c\n", X.index(), X.value());
|
||||
/// }
|
||||
///
|
||||
/// Output:
|
||||
|
@ -106,6 +106,13 @@ static inline std::string fromHex(StringRef Input) {
|
||||
return Output;
|
||||
}
|
||||
|
||||
/// \brief Convert the string \p S to an integer of the specified type using
|
||||
/// the radix \p Base. If \p Base is 0, auto-detects the radix.
|
||||
/// Returns true if the number was successfully converted, false otherwise.
|
||||
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
|
||||
return !S.getAsInteger(Base, Num);
|
||||
}
|
||||
|
||||
static inline std::string utostr(uint64_t X, bool isNeg = false) {
|
||||
char Buffer[21];
|
||||
char *BufPtr = std::end(Buffer);
|
||||
|
@ -41,12 +41,6 @@
|
||||
/// of all of the caller-callee relationships, which is useful for
|
||||
/// transformations.
|
||||
///
|
||||
/// The CallGraph class also attempts to figure out what the root of the
|
||||
/// CallGraph is, which it currently does by looking for a function named
|
||||
/// 'main'. If no function named 'main' is found, the external node is used as
|
||||
/// the entry node, reflecting the fact that any function without internal
|
||||
/// linkage could be called into (which is common for libraries).
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
|
||||
@ -82,10 +76,6 @@ class CallGraph {
|
||||
/// \brief A map from \c Function* to \c CallGraphNode*.
|
||||
FunctionMapTy FunctionMap;
|
||||
|
||||
/// \brief Root is root of the call graph, or the external node if a 'main'
|
||||
/// function couldn't be found.
|
||||
CallGraphNode *Root;
|
||||
|
||||
/// \brief This node has edges to all external functions and those internal
|
||||
/// functions that have their address taken.
|
||||
CallGraphNode *ExternalCallingNode;
|
||||
|
@ -67,8 +67,8 @@ public:
|
||||
}
|
||||
|
||||
/// Returns the profile count for \p CallInst.
|
||||
static Optional<uint64_t> getProfileCount(const Instruction *CallInst,
|
||||
BlockFrequencyInfo *BFI);
|
||||
Optional<uint64_t> getProfileCount(const Instruction *CallInst,
|
||||
BlockFrequencyInfo *BFI);
|
||||
/// \brief Returns true if \p F has hot function entry.
|
||||
bool isFunctionEntryHot(const Function *F);
|
||||
/// Returns true if \p F has hot function entry or hot call edge.
|
||||
|
@ -568,27 +568,16 @@ private:
|
||||
Predicates.insert(P);
|
||||
}
|
||||
|
||||
/*implicit*/ ExitLimit(const SCEV *E)
|
||||
: ExactNotTaken(E), MaxNotTaken(E), MaxOrZero(false) {}
|
||||
/*implicit*/ ExitLimit(const SCEV *E);
|
||||
|
||||
ExitLimit(
|
||||
const SCEV *E, const SCEV *M, bool MaxOrZero,
|
||||
ArrayRef<const SmallPtrSetImpl<const SCEVPredicate *> *> PredSetList)
|
||||
: ExactNotTaken(E), MaxNotTaken(M), MaxOrZero(MaxOrZero) {
|
||||
assert((isa<SCEVCouldNotCompute>(ExactNotTaken) ||
|
||||
!isa<SCEVCouldNotCompute>(MaxNotTaken)) &&
|
||||
"Exact is not allowed to be less precise than Max");
|
||||
for (auto *PredSet : PredSetList)
|
||||
for (auto *P : *PredSet)
|
||||
addPredicate(P);
|
||||
}
|
||||
ArrayRef<const SmallPtrSetImpl<const SCEVPredicate *> *> PredSetList);
|
||||
|
||||
ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero,
|
||||
const SmallPtrSetImpl<const SCEVPredicate *> &PredSet)
|
||||
: ExitLimit(E, M, MaxOrZero, {&PredSet}) {}
|
||||
const SmallPtrSetImpl<const SCEVPredicate *> &PredSet);
|
||||
|
||||
ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero)
|
||||
: ExitLimit(E, M, MaxOrZero, None) {}
|
||||
ExitLimit(const SCEV *E, const SCEV *M, bool MaxOrZero);
|
||||
|
||||
/// Test whether this ExitLimit contains any computed information, or
|
||||
/// whether it's all SCEVCouldNotCompute values.
|
||||
@ -782,7 +771,7 @@ private:
|
||||
|
||||
/// Set the memoized range for the given SCEV.
|
||||
const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint,
|
||||
ConstantRange &&CR) {
|
||||
ConstantRange CR) {
|
||||
DenseMap<const SCEV *, ConstantRange> &Cache =
|
||||
Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges;
|
||||
|
||||
|
@ -161,6 +161,60 @@ TLI_DEFINE_STRING_INTERNAL("_Znwm")
|
||||
/// void *new(unsigned long, nothrow);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t")
|
||||
/// double __acos_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(acos_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__acos_finite")
|
||||
/// float __acosf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(acosf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__acosf_finite")
|
||||
/// double __acosh_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(acosh_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__acosh_finite")
|
||||
/// float __acoshf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(acoshf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__acoshf_finite")
|
||||
/// long double __acoshl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(acoshl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__acoshl_finite")
|
||||
/// long double __acosl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(acosl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__acosl_finite")
|
||||
/// double __asin_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(asin_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__asin_finite")
|
||||
/// float __asinf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(asinf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__asinf_finite")
|
||||
/// long double __asinl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(asinl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__asinl_finite")
|
||||
/// double atan2_finite(double y, double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(atan2_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__atan2_finite")
|
||||
/// float atan2f_finite(float y, float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(atan2f_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__atan2f_finite")
|
||||
/// long double atan2l_finite(long double y, long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(atan2l_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__atan2l_finite")
|
||||
/// double __atanh_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(atanh_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__atanh_finite")
|
||||
/// float __atanhf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(atanhf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__atanhf_finite")
|
||||
/// long double __atanhl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(atanhl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__atanhl_finite")
|
||||
/// double __cosh_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(cosh_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__cosh_finite")
|
||||
/// float __coshf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(coshf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__coshf_finite")
|
||||
/// long double __coshl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(coshl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__coshl_finite")
|
||||
/// double __cospi(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(cospi)
|
||||
TLI_DEFINE_STRING_INTERNAL("__cospi")
|
||||
@ -180,12 +234,66 @@ TLI_DEFINE_STRING_INTERNAL("__cxa_guard_acquire")
|
||||
/// void __cxa_guard_release(guard_t *guard);
|
||||
TLI_DEFINE_ENUM_INTERNAL(cxa_guard_release)
|
||||
TLI_DEFINE_STRING_INTERNAL("__cxa_guard_release")
|
||||
/// double __exp10_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(exp10_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__exp10_finite")
|
||||
/// float __exp10f_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(exp10f_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__exp10f_finite")
|
||||
/// long double __exp10l_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(exp10l_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__exp10l_finite")
|
||||
/// double __exp2_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(exp2_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__exp2_finite")
|
||||
/// float __exp2f_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(exp2f_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__exp2f_finite")
|
||||
/// long double __exp2l_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(exp2l_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__exp2l_finite")
|
||||
/// double __exp_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(exp_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__exp_finite")
|
||||
/// float __expf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(expf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__expf_finite")
|
||||
/// long double __expl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(expl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__expl_finite")
|
||||
/// int __isoc99_scanf (const char *format, ...)
|
||||
TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_scanf)
|
||||
TLI_DEFINE_STRING_INTERNAL("__isoc99_scanf")
|
||||
/// int __isoc99_sscanf(const char *s, const char *format, ...)
|
||||
TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_sscanf)
|
||||
TLI_DEFINE_STRING_INTERNAL("__isoc99_sscanf")
|
||||
/// double __log10_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(log10_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__log10_finite")
|
||||
/// float __log10f_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(log10f_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__log10f_finite")
|
||||
/// long double __log10l_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(log10l_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__log10l_finite")
|
||||
/// double __log2_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(log2_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__log2_finite")
|
||||
/// float __log2f_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(log2f_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__log2f_finite")
|
||||
/// long double __log2l_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(log2l_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__log2l_finite")
|
||||
/// double __log_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(log_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__log_finite")
|
||||
/// float __logf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(logf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__logf_finite")
|
||||
/// long double __logl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(logl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__logl_finite")
|
||||
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
|
||||
TLI_DEFINE_ENUM_INTERNAL(memcpy_chk)
|
||||
TLI_DEFINE_STRING_INTERNAL("__memcpy_chk")
|
||||
@ -199,13 +307,30 @@ TLI_DEFINE_STRING_INTERNAL("__memset_chk")
|
||||
// int __nvvm_reflect(const char *)
|
||||
TLI_DEFINE_ENUM_INTERNAL(nvvm_reflect)
|
||||
TLI_DEFINE_STRING_INTERNAL("__nvvm_reflect")
|
||||
|
||||
/// double __pow_finite(double x, double y);
|
||||
TLI_DEFINE_ENUM_INTERNAL(pow_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__pow_finite")
|
||||
/// float _powf_finite(float x, float y);
|
||||
TLI_DEFINE_ENUM_INTERNAL(powf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__powf_finite")
|
||||
/// long double __powl_finite(long double x, long double y);
|
||||
TLI_DEFINE_ENUM_INTERNAL(powl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__powl_finite")
|
||||
/// double __sincospi_stret(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(sincospi_stret)
|
||||
TLI_DEFINE_STRING_INTERNAL("__sincospi_stret")
|
||||
/// float __sincospif_stret(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(sincospif_stret)
|
||||
TLI_DEFINE_STRING_INTERNAL("__sincospif_stret")
|
||||
/// double __sinh_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(sinh_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__sinh_finite")
|
||||
/// float _sinhf_finite(float x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(sinhf_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__sinhf_finite")
|
||||
/// long double __sinhl_finite(long double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(sinhl_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__sinhl_finite")
|
||||
/// double __sinpi(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(sinpi)
|
||||
TLI_DEFINE_STRING_INTERNAL("__sinpi")
|
||||
|
@ -537,6 +537,9 @@ public:
|
||||
/// \return The width of the largest scalar or vector register type.
|
||||
unsigned getRegisterBitWidth(bool Vector) const;
|
||||
|
||||
/// \return The width of the smallest vector register type.
|
||||
unsigned getMinVectorRegisterBitWidth() const;
|
||||
|
||||
/// \return True if it should be considered for address type promotion.
|
||||
/// \p AllowPromotionWithoutCommonHeader Set true if promoting \p I is
|
||||
/// profitable without finding other extensions fed by the same input.
|
||||
@ -740,6 +743,22 @@ public:
|
||||
unsigned ChainSizeInBytes,
|
||||
VectorType *VecTy) const;
|
||||
|
||||
/// Flags describing the kind of vector reduction.
|
||||
struct ReductionFlags {
|
||||
ReductionFlags() : IsMaxOp(false), IsSigned(false), NoNaN(false) {}
|
||||
bool IsMaxOp; ///< If the op a min/max kind, true if it's a max operation.
|
||||
bool IsSigned; ///< Whether the operation is a signed int reduction.
|
||||
bool NoNaN; ///< If op is an fp min/max, whether NaNs may be present.
|
||||
};
|
||||
|
||||
/// \returns True if the target wants to handle the given reduction idiom in
|
||||
/// the intrinsics form instead of the shuffle form.
|
||||
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
|
||||
ReductionFlags Flags) const;
|
||||
|
||||
/// \returns True if the target wants to expand the given reduction intrinsic
|
||||
/// into a shuffle sequence.
|
||||
bool shouldExpandReduction(const IntrinsicInst *II) const;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
@ -824,6 +843,7 @@ public:
|
||||
Type *Ty) = 0;
|
||||
virtual unsigned getNumberOfRegisters(bool Vector) = 0;
|
||||
virtual unsigned getRegisterBitWidth(bool Vector) = 0;
|
||||
virtual unsigned getMinVectorRegisterBitWidth() = 0;
|
||||
virtual bool shouldConsiderAddressTypePromotion(
|
||||
const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0;
|
||||
virtual unsigned getCacheLineSize() = 0;
|
||||
@ -895,6 +915,9 @@ public:
|
||||
virtual unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize,
|
||||
unsigned ChainSizeInBytes,
|
||||
VectorType *VecTy) const = 0;
|
||||
virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
|
||||
ReductionFlags) const = 0;
|
||||
virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -1057,6 +1080,9 @@ public:
|
||||
unsigned getRegisterBitWidth(bool Vector) override {
|
||||
return Impl.getRegisterBitWidth(Vector);
|
||||
}
|
||||
unsigned getMinVectorRegisterBitWidth() override {
|
||||
return Impl.getMinVectorRegisterBitWidth();
|
||||
}
|
||||
bool shouldConsiderAddressTypePromotion(
|
||||
const Instruction &I, bool &AllowPromotionWithoutCommonHeader) override {
|
||||
return Impl.shouldConsiderAddressTypePromotion(
|
||||
@ -1200,6 +1226,13 @@ public:
|
||||
VectorType *VecTy) const override {
|
||||
return Impl.getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
|
||||
}
|
||||
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
|
||||
ReductionFlags Flags) const override {
|
||||
return Impl.useReductionIntrinsic(Opcode, Ty, Flags);
|
||||
}
|
||||
bool shouldExpandReduction(const IntrinsicInst *II) const override {
|
||||
return Impl.shouldExpandReduction(II);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -311,6 +311,8 @@ public:
|
||||
|
||||
unsigned getRegisterBitWidth(bool Vector) { return 32; }
|
||||
|
||||
unsigned getMinVectorRegisterBitWidth() { return 128; }
|
||||
|
||||
bool
|
||||
shouldConsiderAddressTypePromotion(const Instruction &I,
|
||||
bool &AllowPromotionWithoutCommonHeader) {
|
||||
@ -456,6 +458,16 @@ public:
|
||||
VectorType *VecTy) const {
|
||||
return VF;
|
||||
}
|
||||
|
||||
bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
|
||||
TTI::ReductionFlags Flags) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shouldExpandReduction(const IntrinsicInst *II) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Obtain the minimum required size to hold the value (without the sign)
|
||||
// In case of a vector it returns the min required size for one element.
|
||||
|
@ -56,6 +56,11 @@ template <typename T> class ArrayRef;
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
OptimizationRemarkEmitter *ORE = nullptr);
|
||||
/// Returns the known bits rather than passing by reference.
|
||||
KnownBits computeKnownBits(const Value *V, const DataLayout &DL,
|
||||
unsigned Depth = 0, AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
/// Compute known bits from the range metadata.
|
||||
/// \p KnownZero the set of bits that are known to be zero
|
||||
/// \p KnownOne the set of bits that are known to be one
|
||||
@ -68,14 +73,6 @@ template <typename T> class ArrayRef;
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Determine whether the sign bit is known to be zero or one. Convenience
|
||||
/// wrapper around computeKnownBits.
|
||||
void ComputeSignBit(const Value *V, bool &KnownZero, bool &KnownOne,
|
||||
const DataLayout &DL, unsigned Depth = 0,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// Return true if the given value is known to have exactly one bit set when
|
||||
/// defined. For vectors return true if every element is known to be a power
|
||||
/// of two when defined. Supports values with integer or pointer type and
|
||||
|
@ -152,10 +152,11 @@ namespace llvm {
|
||||
|
||||
/// Parse the module summary index out of an IR file and return the module
|
||||
/// summary index object if found, or an empty summary if not. If Path refers
|
||||
/// to an empty file and the -ignore-empty-index-file cl::opt flag is passed
|
||||
/// to an empty file and IgnoreEmptyThinLTOIndexFile is true, then
|
||||
/// this function will return nullptr.
|
||||
Expected<std::unique_ptr<ModuleSummaryIndex>>
|
||||
getModuleSummaryIndexForFile(StringRef Path);
|
||||
getModuleSummaryIndexForFile(StringRef Path,
|
||||
bool IgnoreEmptyThinLTOIndexFile = false);
|
||||
|
||||
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
|
||||
/// for an LLVM IR bitcode wrapper.
|
||||
|
24
include/llvm/CodeGen/ExpandReductions.h
Normal file
24
include/llvm/CodeGen/ExpandReductions.h
Normal file
@ -0,0 +1,24 @@
|
||||
//===----- ExpandReductions.h - Expand experimental reduction intrinsics --===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_EXPANDREDUCTIONS_H
|
||||
#define LLVM_CODEGEN_EXPANDREDUCTIONS_H
|
||||
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ExpandReductionsPass
|
||||
: public PassInfoMixin<ExpandReductionsPass> {
|
||||
public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_CODEGEN_EXPANDREDUCTIONS_H
|
@ -145,7 +145,7 @@ public:
|
||||
|
||||
/// Iterate the given function (typically something like doubling the width)
|
||||
/// on Ty until we find a legal type for this operation.
|
||||
LLT findLegalType(const InstrAspect &Aspect,
|
||||
Optional<LLT> findLegalType(const InstrAspect &Aspect,
|
||||
function_ref<LLT(LLT)> NextType) const {
|
||||
LegalizeAction Action;
|
||||
const TypeMap &Map = Actions[Aspect.Opcode - FirstOp][Aspect.Idx];
|
||||
@ -153,8 +153,12 @@ public:
|
||||
do {
|
||||
Ty = NextType(Ty);
|
||||
auto ActionIt = Map.find(Ty);
|
||||
if (ActionIt == Map.end())
|
||||
Action = DefaultActions.find(Aspect.Opcode)->second;
|
||||
if (ActionIt == Map.end()) {
|
||||
auto DefaultIt = DefaultActions.find(Aspect.Opcode);
|
||||
if (DefaultIt == DefaultActions.end())
|
||||
return None;
|
||||
Action = DefaultIt->second;
|
||||
}
|
||||
else
|
||||
Action = ActionIt->second;
|
||||
} while(Action != Legal);
|
||||
@ -163,11 +167,14 @@ public:
|
||||
|
||||
/// Find what type it's actually OK to perform the given operation on, given
|
||||
/// the general approach we've decided to take.
|
||||
LLT findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const;
|
||||
Optional<LLT> findLegalType(const InstrAspect &Aspect, LegalizeAction Action) const;
|
||||
|
||||
std::pair<LegalizeAction, LLT> findLegalAction(const InstrAspect &Aspect,
|
||||
LegalizeAction Action) const {
|
||||
return std::make_pair(Action, findLegalType(Aspect, Action));
|
||||
auto LegalType = findLegalType(Aspect, Action);
|
||||
if (!LegalType)
|
||||
return std::make_pair(LegalizeAction::Unsupported, LLT());
|
||||
return std::make_pair(Action, *LegalType);
|
||||
}
|
||||
|
||||
/// Find the specified \p Aspect in the primary (explicitly set) Actions
|
||||
|
@ -30,6 +30,7 @@ class TargetInstrInfo;
|
||||
class TargetPassConfig;
|
||||
class TargetRegisterInfo;
|
||||
class Twine;
|
||||
class ConstantFP;
|
||||
|
||||
/// Try to constrain Reg so that it is usable by argument OpIdx of the
|
||||
/// provided MCInstrDesc \p II. If this fails, create a new virtual
|
||||
@ -62,6 +63,8 @@ void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
|
||||
|
||||
Optional<int64_t> getConstantVRegVal(unsigned VReg,
|
||||
const MachineRegisterInfo &MRI);
|
||||
const ConstantFP* getConstantFPVRegVal(unsigned VReg,
|
||||
const MachineRegisterInfo &MRI);
|
||||
|
||||
} // End namespace llvm.
|
||||
#endif
|
||||
|
@ -644,6 +644,13 @@ namespace ISD {
|
||||
/// of a call sequence, and carry arbitrary information that target might
|
||||
/// want to know. The first operand is a chain, the rest are specified by
|
||||
/// the target and not touched by the DAG optimizers.
|
||||
/// Targets that may use stack to pass call arguments define additional
|
||||
/// operands:
|
||||
/// - size of the call frame part that must be set up within the
|
||||
/// CALLSEQ_START..CALLSEQ_END pair,
|
||||
/// - part of the call frame prepared prior to CALLSEQ_START.
|
||||
/// Both these parameters must be constants, their sum is the total call
|
||||
/// frame size.
|
||||
/// CALLSEQ_START..CALLSEQ_END pairs may not be nested.
|
||||
CALLSEQ_START, // Beginning of a call sequence
|
||||
CALLSEQ_END, // End of a call sequence
|
||||
@ -783,6 +790,20 @@ namespace ISD {
|
||||
/// known nonzero constant. The only operand here is the chain.
|
||||
GET_DYNAMIC_AREA_OFFSET,
|
||||
|
||||
/// Generic reduction nodes. These nodes represent horizontal vector
|
||||
/// reduction operations, producing a scalar result.
|
||||
/// The STRICT variants perform reductions in sequential order. The first
|
||||
/// operand is an initial scalar accumulator value, and the second operand
|
||||
/// is the vector to reduce.
|
||||
VECREDUCE_STRICT_FADD, VECREDUCE_STRICT_FMUL,
|
||||
/// These reductions are non-strict, and have a single vector operand.
|
||||
VECREDUCE_FADD, VECREDUCE_FMUL,
|
||||
VECREDUCE_ADD, VECREDUCE_MUL,
|
||||
VECREDUCE_AND, VECREDUCE_OR, VECREDUCE_XOR,
|
||||
VECREDUCE_SMAX, VECREDUCE_SMIN, VECREDUCE_UMAX, VECREDUCE_UMIN,
|
||||
/// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
|
||||
VECREDUCE_FMAX, VECREDUCE_FMIN,
|
||||
|
||||
/// BUILTIN_OP_END - This must be the last enum value in this list.
|
||||
/// The target-specific pre-isel opcode values start here.
|
||||
BUILTIN_OP_END
|
||||
|
@ -48,6 +48,8 @@ enum class MachineCombinerPattern {
|
||||
FMULADDD_OP2,
|
||||
FMULSUBD_OP1,
|
||||
FMULSUBD_OP2,
|
||||
FNMULSUBS_OP1,
|
||||
FNMULSUBD_OP1,
|
||||
FMLAv1i32_indexed_OP1,
|
||||
FMLAv1i32_indexed_OP2,
|
||||
FMLAv1i64_indexed_OP1,
|
||||
|
@ -68,6 +68,10 @@ namespace llvm {
|
||||
/// matching during instruction selection.
|
||||
FunctionPass *createCodeGenPreparePass(const TargetMachine *TM = nullptr);
|
||||
|
||||
/// createScalarizeMaskedMemIntrinPass - Replace masked load, store, gather
|
||||
/// and scatter intrinsics with scalar code when target doesn't support them.
|
||||
FunctionPass *createScalarizeMaskedMemIntrinPass();
|
||||
|
||||
/// AtomicExpandID -- Lowers atomic operations in terms of either cmpxchg
|
||||
/// load-linked/store-conditional loops.
|
||||
extern char &AtomicExpandID;
|
||||
@ -129,6 +133,10 @@ namespace llvm {
|
||||
// instruction and update the MachineFunctionInfo with that information.
|
||||
extern char &ShrinkWrapID;
|
||||
|
||||
/// LiveRangeShrink pass. Move instruction close to its definition to shrink
|
||||
/// the definition's live range.
|
||||
extern char &LiveRangeShrinkID;
|
||||
|
||||
/// Greedy register allocator.
|
||||
extern char &RAGreedyID;
|
||||
|
||||
@ -405,6 +413,10 @@ namespace llvm {
|
||||
/// printing assembly.
|
||||
ModulePass *createMachineOutlinerPass();
|
||||
|
||||
/// This pass expands the experimental reduction intrinsics into sequences of
|
||||
/// shuffles.
|
||||
FunctionPass *createExpandReductionsPass();
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
/// Target machine pass initializer for passes with dependencies. Use with
|
||||
|
@ -406,7 +406,7 @@ public:
|
||||
/// certain types of nodes together, or eliminating superfluous nodes. The
|
||||
/// Level argument controls whether Combine is allowed to produce nodes and
|
||||
/// types that are illegal on the target.
|
||||
void Combine(CombineLevel Level, AliasAnalysis &AA,
|
||||
void Combine(CombineLevel Level, AliasAnalysis *AA,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
|
||||
/// This transforms the SelectionDAG into a SelectionDAG that
|
||||
@ -737,11 +737,15 @@ public:
|
||||
/// \brief Create a logical NOT operation as (XOR Val, BooleanOne).
|
||||
SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT);
|
||||
|
||||
/// Return a new CALLSEQ_START node, which always must have a glue result
|
||||
/// (to ensure it's not CSE'd). CALLSEQ_START does not have a useful SDLoc.
|
||||
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, const SDLoc &DL) {
|
||||
/// Return a new CALLSEQ_START node, that starts new call frame, in which
|
||||
/// InSize bytes are set up inside CALLSEQ_START..CALLSEQ_END sequence and
|
||||
/// OutSize specifies part of the frame set up prior to the sequence.
|
||||
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize,
|
||||
const SDLoc &DL) {
|
||||
SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
|
||||
SDValue Ops[] = { Chain, Op };
|
||||
SDValue Ops[] = { Chain,
|
||||
getIntPtrConstant(InSize, DL, true),
|
||||
getIntPtrConstant(OutSize, DL, true) };
|
||||
return getNode(ISD::CALLSEQ_START, DL, VTs, Ops);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
|
||||
void addTypeServerHandler(TypeServerHandler &Handler);
|
||||
|
||||
Error visitTypeRecord(CVType &Record, TypeIndex Index);
|
||||
Error visitTypeRecord(CVType &Record);
|
||||
Error visitMemberRecord(CVMemberRecord &Record);
|
||||
|
||||
@ -37,6 +38,9 @@ public:
|
||||
Error visitFieldListMemberStream(BinaryStreamReader Reader);
|
||||
|
||||
private:
|
||||
Expected<bool> handleTypeServer(CVType &Record);
|
||||
Error finishVisitation(CVType &Record);
|
||||
|
||||
/// The interface to the class that gets notified of each visitation.
|
||||
TypeVisitorCallbacks &Callbacks;
|
||||
|
||||
|
103
include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h
Normal file
103
include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h
Normal file
@ -0,0 +1,103 @@
|
||||
//===- RandomAccessTypeVisitor.h ------------------------------ *- C++ --*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H
|
||||
|
||||
#include "llvm/ADT/TinyPtrVector.h"
|
||||
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
class TypeDatabase;
|
||||
class TypeServerHandler;
|
||||
class TypeVisitorCallbacks;
|
||||
|
||||
/// \brief Provides amortized O(1) random access to a CodeView type stream.
|
||||
/// Normally to access a type from a type stream, you must know its byte
|
||||
/// offset into the type stream, because type records are variable-lengthed.
|
||||
/// However, this is not the way we prefer to access them. For example, given
|
||||
/// a symbol record one of the fields may be the TypeIndex of the symbol's
|
||||
/// type record. Or given a type record such as an array type, there might
|
||||
/// be a TypeIndex for the element type. Sequential access is perfect when
|
||||
/// we're just dumping every entry, but it's very poor for real world usage.
|
||||
///
|
||||
/// Type streams in PDBs contain an additional field which is a list of pairs
|
||||
/// containing indices and their corresponding offsets, roughly every ~8KB of
|
||||
/// record data. This general idea need not be confined to PDBs though. By
|
||||
/// supplying such an array, the producer of a type stream can allow the
|
||||
/// consumer much better access time, because the consumer can find the nearest
|
||||
/// index in this array, and do a linear scan forward only from there.
|
||||
///
|
||||
/// RandomAccessTypeVisitor implements this algorithm, but additionally goes one
|
||||
/// step further by caching offsets of every record that has been visited at
|
||||
/// least once. This way, even repeated visits of the same record will never
|
||||
/// require more than one linear scan. For a type stream of N elements divided
|
||||
/// into M chunks of roughly equal size, this yields a worst case lookup time
|
||||
/// of O(N/M) and an amortized time of O(1).
|
||||
class RandomAccessTypeVisitor {
|
||||
typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray;
|
||||
|
||||
public:
|
||||
RandomAccessTypeVisitor(const CVTypeArray &Types, uint32_t NumRecords,
|
||||
PartialOffsetArray PartialOffsets);
|
||||
|
||||
Error visitTypeIndex(TypeIndex Index, TypeVisitorCallbacks &Callbacks);
|
||||
|
||||
const TypeDatabase &database() const { return Database; }
|
||||
|
||||
private:
|
||||
Error visitRangeForType(TypeIndex TI);
|
||||
Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
|
||||
|
||||
/// Visited records get automatically added to the type database.
|
||||
TypeDatabase Database;
|
||||
|
||||
/// The type array to allow random access visitation of.
|
||||
const CVTypeArray &Types;
|
||||
|
||||
/// The database visitor which adds new records to the database.
|
||||
TypeDatabaseVisitor DatabaseVisitor;
|
||||
|
||||
/// The deserializer which deserializes new records.
|
||||
TypeDeserializer Deserializer;
|
||||
|
||||
/// The visitation callback pipeline to use. By default this contains a
|
||||
/// deserializer and a type database visitor. But the callback specified
|
||||
/// in the constructor is also added.
|
||||
TypeVisitorCallbackPipeline Pipeline;
|
||||
|
||||
/// The visitor used to visit the internal pipeline for deserialization and
|
||||
/// database maintenance.
|
||||
CVTypeVisitor InternalVisitor;
|
||||
|
||||
/// A vector mapping type indices to type offset. For every record that has
|
||||
/// been visited, contains the absolute offset of that record in the record
|
||||
/// array.
|
||||
std::vector<uint32_t> KnownOffsets;
|
||||
|
||||
/// An array of index offsets for the given type stream, allowing log(N)
|
||||
/// lookups of a type record by index. Similar to KnownOffsets but only
|
||||
/// contains offsets for some type indices, some of which may not have
|
||||
/// ever been visited.
|
||||
PartialOffsetArray PartialOffsets;
|
||||
};
|
||||
|
||||
} // end namespace codeview
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H
|
@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||
@ -20,14 +21,16 @@
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
class TypeDatabase {
|
||||
public:
|
||||
explicit TypeDatabase(uint32_t ExpectedSize);
|
||||
friend class RandomAccessTypeVisitor;
|
||||
|
||||
/// Gets the type index for the next type record.
|
||||
TypeIndex getNextTypeIndex() const;
|
||||
public:
|
||||
explicit TypeDatabase(uint32_t Capacity);
|
||||
|
||||
/// Records the name of a type, and reserves its type index.
|
||||
void recordType(StringRef Name, const CVType &Data);
|
||||
TypeIndex appendType(StringRef Name, const CVType &Data);
|
||||
|
||||
/// Records the name of a type, and reserves its type index.
|
||||
void recordType(StringRef Name, TypeIndex Index, const CVType &Data);
|
||||
|
||||
/// Saves the name in a StringSet and creates a stable StringRef.
|
||||
StringRef saveTypeName(StringRef TypeName);
|
||||
@ -37,13 +40,21 @@ public:
|
||||
const CVType &getTypeRecord(TypeIndex Index) const;
|
||||
CVType &getTypeRecord(TypeIndex Index);
|
||||
|
||||
bool containsTypeIndex(TypeIndex Index) const;
|
||||
bool contains(TypeIndex Index) const;
|
||||
|
||||
uint32_t size() const;
|
||||
uint32_t capacity() const;
|
||||
bool empty() const;
|
||||
|
||||
TypeIndex getAppendIndex() const;
|
||||
|
||||
private:
|
||||
void grow();
|
||||
|
||||
BumpPtrAllocator Allocator;
|
||||
|
||||
uint32_t Count = 0;
|
||||
|
||||
/// All user defined type records in .debug$T live in here. Type indices
|
||||
/// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
|
||||
/// index into this vector.
|
||||
@ -51,6 +62,8 @@ private:
|
||||
SmallVector<CVType, 10> TypeRecords;
|
||||
|
||||
StringSaver TypeNameStorage;
|
||||
|
||||
BitVector ValidRecords;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
|
||||
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||
@ -21,11 +23,12 @@ namespace codeview {
|
||||
/// Dumper for CodeView type streams found in COFF object files and PDB files.
|
||||
class TypeDatabaseVisitor : public TypeVisitorCallbacks {
|
||||
public:
|
||||
explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(TypeDB) {}
|
||||
explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(&TypeDB) {}
|
||||
|
||||
/// Paired begin/end actions for all types. Receives all record data,
|
||||
/// including the fixed-length record prefix.
|
||||
Error visitTypeBegin(CVType &Record) override;
|
||||
Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
|
||||
Error visitTypeEnd(CVType &Record) override;
|
||||
Error visitMemberBegin(CVMemberRecord &Record) override;
|
||||
Error visitMemberEnd(CVMemberRecord &Record) override;
|
||||
@ -39,12 +42,18 @@ public:
|
||||
#include "TypeRecords.def"
|
||||
|
||||
private:
|
||||
StringRef getTypeName(TypeIndex Index) const;
|
||||
StringRef saveTypeName(StringRef Name);
|
||||
|
||||
bool IsInFieldList = false;
|
||||
|
||||
/// Name of the current type. Only valid before visitTypeEnd.
|
||||
StringRef Name;
|
||||
/// Current type index. Only valid before visitTypeEnd, and if we are
|
||||
/// visiting a random access type database.
|
||||
Optional<TypeIndex> CurrentTypeIndex;
|
||||
|
||||
TypeDatabase &TypeDB;
|
||||
TypeDatabase *TypeDB;
|
||||
};
|
||||
|
||||
} // end namespace codeview
|
||||
|
@ -46,6 +46,10 @@ public:
|
||||
return Mapping->Mapping.visitTypeBegin(Record);
|
||||
}
|
||||
|
||||
Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
|
||||
return visitTypeBegin(Record);
|
||||
}
|
||||
|
||||
Error visitTypeEnd(CVType &Record) override {
|
||||
assert(Mapping && "Not in a type mapping!");
|
||||
auto EC = Mapping->Mapping.visitTypeEnd(Record);
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
/// Paired begin/end actions for all types. Receives all record data,
|
||||
/// including the fixed-length record prefix.
|
||||
Error visitTypeBegin(CVType &Record) override;
|
||||
Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
|
||||
Error visitTypeEnd(CVType &Record) override;
|
||||
Error visitMemberBegin(CVMemberRecord &Record) override;
|
||||
Error visitMemberEnd(CVMemberRecord &Record) override;
|
||||
|
@ -106,6 +106,15 @@ public:
|
||||
|
||||
bool isNoneType() const { return *this == None(); }
|
||||
|
||||
uint32_t toArrayIndex() const {
|
||||
assert(!isSimple());
|
||||
return getIndex() - FirstNonSimpleIndex;
|
||||
}
|
||||
|
||||
static TypeIndex fromArrayIndex(uint32_t Index) {
|
||||
return TypeIndex(Index + FirstNonSimpleIndex);
|
||||
}
|
||||
|
||||
SimpleTypeKind getSimpleKind() const {
|
||||
assert(isSimple());
|
||||
return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
|
||||
@ -159,6 +168,39 @@ public:
|
||||
static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); }
|
||||
static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
|
||||
|
||||
TypeIndex &operator+=(unsigned N) {
|
||||
Index += N;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeIndex &operator++() {
|
||||
Index += 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeIndex operator++(int) {
|
||||
TypeIndex Copy = *this;
|
||||
operator++();
|
||||
return Copy;
|
||||
}
|
||||
|
||||
TypeIndex &operator-=(unsigned N) {
|
||||
assert(Index >= N);
|
||||
Index -= N;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeIndex &operator--() {
|
||||
Index -= 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeIndex operator--(int) {
|
||||
TypeIndex Copy = *this;
|
||||
operator--();
|
||||
return Copy;
|
||||
}
|
||||
|
||||
friend inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
|
||||
return A.getIndex() == B.getIndex();
|
||||
}
|
||||
@ -183,10 +225,30 @@ public:
|
||||
return A.getIndex() >= B.getIndex();
|
||||
}
|
||||
|
||||
friend inline TypeIndex operator+(const TypeIndex &A, uint32_t N) {
|
||||
TypeIndex Result(A);
|
||||
Result += N;
|
||||
return Result;
|
||||
}
|
||||
|
||||
friend inline TypeIndex operator-(const TypeIndex &A, uint32_t N) {
|
||||
assert(A.getIndex() >= N);
|
||||
TypeIndex Result(A);
|
||||
Result -= N;
|
||||
return Result;
|
||||
}
|
||||
|
||||
private:
|
||||
support::ulittle32_t Index;
|
||||
};
|
||||
|
||||
// Used for pseudo-indexing an array of type records. An array of such records
|
||||
// sorted by TypeIndex can allow log(N) lookups even though such a type record
|
||||
// stream does not provide random access.
|
||||
struct TypeIndexOffset {
|
||||
TypeIndex Type;
|
||||
support::ulittle32_t Offset;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,14 @@ public:
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error visitTypeBegin(CVType &Record, TypeIndex Index) override {
|
||||
for (auto Visitor : Pipeline) {
|
||||
if (auto EC = Visitor->visitTypeBegin(Record, Index))
|
||||
return EC;
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error visitTypeEnd(CVType &Record) override {
|
||||
for (auto Visitor : Pipeline) {
|
||||
if (auto EC = Visitor->visitTypeEnd(Record))
|
||||
|
@ -26,8 +26,15 @@ public:
|
||||
virtual Error visitUnknownType(CVType &Record) { return Error::success(); }
|
||||
/// Paired begin/end actions for all types. Receives all record data,
|
||||
/// including the fixed-length record prefix. visitTypeBegin() should return
|
||||
/// the type of the Record, or an error if it cannot be determined.
|
||||
/// the type of the Record, or an error if it cannot be determined. Exactly
|
||||
/// one of the two visitTypeBegin methods will be called, depending on whether
|
||||
/// records are being visited sequentially or randomly. An implementation
|
||||
/// should be prepared to handle both (or assert if it can't handle random
|
||||
/// access visitation).
|
||||
virtual Error visitTypeBegin(CVType &Record) { return Error::success(); }
|
||||
virtual Error visitTypeBegin(CVType &Record, TypeIndex Index) {
|
||||
return Error::success();
|
||||
}
|
||||
virtual Error visitTypeEnd(CVType &Record) { return Error::success(); }
|
||||
|
||||
virtual Error visitUnknownMember(CVMemberRecord &Record) {
|
||||
|
@ -43,13 +43,6 @@ namespace llvm {
|
||||
class MemoryBuffer;
|
||||
class raw_ostream;
|
||||
|
||||
// In place of applying the relocations to the data we've read from disk we use
|
||||
// a separate mapping table to the side and checking that at locations in the
|
||||
// dwarf where we expect relocated values. This adds a bit of complexity to the
|
||||
// dwarf parsing/extraction at the benefit of not allocating memory for the
|
||||
// entire size of the debug info sections.
|
||||
typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap;
|
||||
|
||||
/// Reads a value from data extractor and applies a relocation to the result if
|
||||
/// one exists for the given offset.
|
||||
uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size,
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
struct FileNameEntry {
|
||||
FileNameEntry() = default;
|
||||
|
||||
StringRef Name = StringRef();
|
||||
StringRef Name;
|
||||
uint64_t DirIdx = 0;
|
||||
uint64_t ModTime = 0;
|
||||
uint64_t Length = 0;
|
||||
|
@ -22,8 +22,13 @@ namespace llvm {
|
||||
|
||||
class raw_ostream;
|
||||
|
||||
struct DWARFAddressRange {
|
||||
uint64_t LowPC;
|
||||
uint64_t HighPC;
|
||||
};
|
||||
|
||||
/// DWARFAddressRangesVector - represents a set of absolute address ranges.
|
||||
typedef std::vector<std::pair<uint64_t, uint64_t>> DWARFAddressRangesVector;
|
||||
typedef std::vector<DWARFAddressRange> DWARFAddressRangesVector;
|
||||
|
||||
class DWARFDebugRangeList {
|
||||
public:
|
||||
|
@ -16,7 +16,17 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t>> RelocAddrMap;
|
||||
struct RelocAddrEntry {
|
||||
uint8_t Width;
|
||||
int64_t Value;
|
||||
};
|
||||
|
||||
// In place of applying the relocations to the data we've read from disk we use
|
||||
// a separate mapping table to the side and checking that at locations in the
|
||||
// dwarf where we expect relocated values. This adds a bit of complexity to the
|
||||
// dwarf parsing/extraction at the benefit of not allocating memory for the
|
||||
// entire size of the debug info sections.
|
||||
typedef DenseMap<uint64_t, RelocAddrEntry> RelocAddrMap;
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -40,7 +40,7 @@ class DWARFVerifier {
|
||||
///
|
||||
/// @param Die The DWARF DIE that owns the attribute value
|
||||
/// @param AttrValue The DWARF attribute value to check
|
||||
void verifyDebugInfoAttribute(DWARFDie &Die, DWARFAttribute &AttrValue);
|
||||
void verifyDebugInfoAttribute(const DWARFDie &Die, DWARFAttribute &AttrValue);
|
||||
|
||||
/// Verifies the attribute's DWARF form.
|
||||
///
|
||||
@ -51,7 +51,7 @@ class DWARFVerifier {
|
||||
///
|
||||
/// @param Die The DWARF DIE that owns the attribute value
|
||||
/// @param AttrValue The DWARF attribute value to check
|
||||
void verifyDebugInfoForm(DWARFDie &Die, DWARFAttribute &AttrValue);
|
||||
void verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue);
|
||||
|
||||
/// Verifies the all valid references that were found when iterating through
|
||||
/// all of the DIE attributes.
|
||||
@ -60,7 +60,7 @@ class DWARFVerifier {
|
||||
/// offset matches. This helps to ensure if a DWARF link phase moved things
|
||||
/// around, that it doesn't create invalid references by failing to relocate
|
||||
/// CU relative and absolute references.
|
||||
void veifyDebugInfoReferences();
|
||||
void verifyDebugInfoReferences();
|
||||
|
||||
/// Verify the the DW_AT_stmt_list encoding and value and ensure that no
|
||||
/// compile units that have the same DW_AT_stmt_list value.
|
||||
|
@ -73,13 +73,6 @@ struct SecMapEntry {
|
||||
support::ulittle32_t SecByteLength; // Byte count of the segment or group.
|
||||
};
|
||||
|
||||
// Used for serialized hash table in TPI stream.
|
||||
// In the reference, it is an array of TI and cbOff pair.
|
||||
struct TypeIndexOffset {
|
||||
codeview::TypeIndex Type;
|
||||
support::ulittle32_t Offset;
|
||||
};
|
||||
|
||||
/// Some of the values are stored in bitfields. Since this needs to be portable
|
||||
/// across compilers and architectures (big / little endian in particular) we
|
||||
/// can't use the actual structures below, but must instead do the shifting
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
uint32_t getHashKeySize() const;
|
||||
uint32_t getNumHashBuckets() const;
|
||||
FixedStreamArray<support::ulittle32_t> getHashValues() const;
|
||||
FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const;
|
||||
FixedStreamArray<codeview::TypeIndexOffset> getTypeIndexOffsets() const;
|
||||
HashTable &getHashAdjusters();
|
||||
|
||||
codeview::CVTypeRange types(bool *HadError) const;
|
||||
@ -62,7 +62,7 @@ private:
|
||||
|
||||
std::unique_ptr<BinaryStream> HashStream;
|
||||
FixedStreamArray<support::ulittle32_t> HashValues;
|
||||
FixedStreamArray<TypeIndexOffset> TypeIndexOffsets;
|
||||
FixedStreamArray<codeview::TypeIndexOffset> TypeIndexOffsets;
|
||||
HashTable HashAdjusters;
|
||||
|
||||
const TpiStreamHeader *Header;
|
||||
|
@ -75,7 +75,7 @@ private:
|
||||
Optional<PdbRaw_TpiVer> VerHeader;
|
||||
std::vector<ArrayRef<uint8_t>> TypeRecords;
|
||||
std::vector<uint32_t> TypeHashes;
|
||||
std::vector<TypeIndexOffset> TypeIndexOffsets;
|
||||
std::vector<codeview::TypeIndexOffset> TypeIndexOffsets;
|
||||
uint32_t HashStreamIndex = kInvalidStreamIndex;
|
||||
std::unique_ptr<BinaryByteStream> HashValueStream;
|
||||
|
||||
|
@ -172,6 +172,11 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
|
||||
for (auto &BLH : BaseLayerHandles)
|
||||
BaseLayer.removeModuleSet(BLH);
|
||||
}
|
||||
|
||||
std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver;
|
||||
std::unique_ptr<ResourceOwner<RuntimeDyld::MemoryManager>> MemMgr;
|
||||
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
|
||||
@ -204,6 +209,11 @@ public:
|
||||
CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
|
||||
CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
|
||||
|
||||
~CompileOnDemandLayer() {
|
||||
while (!LogicalDylibs.empty())
|
||||
removeModuleSet(LogicalDylibs.begin());
|
||||
}
|
||||
|
||||
/// @brief Add a module to the compile-on-demand layer.
|
||||
template <typename ModuleSetT, typename MemoryManagerPtrT,
|
||||
typename SymbolResolverPtrT>
|
||||
@ -239,6 +249,7 @@ public:
|
||||
/// This will remove all modules in the layers below that were derived from
|
||||
/// the module represented by H.
|
||||
void removeModuleSet(ModuleSetHandleT H) {
|
||||
H->removeModulesFromBaseLayer(BaseLayer);
|
||||
LogicalDylibs.erase(H);
|
||||
}
|
||||
|
||||
@ -478,6 +489,8 @@ private:
|
||||
return 0;
|
||||
}
|
||||
|
||||
LD.BaseLayerHandles.push_back(PartH);
|
||||
|
||||
return CalledAddr;
|
||||
}
|
||||
|
||||
|
@ -144,16 +144,16 @@ public:
|
||||
|
||||
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
|
||||
size_t Size) override {
|
||||
UnfinalizedEHFrames.push_back(
|
||||
std::make_pair(LoadAddr, static_cast<uint32_t>(Size)));
|
||||
UnfinalizedEHFrames.push_back({LoadAddr, Size});
|
||||
}
|
||||
|
||||
void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
|
||||
size_t Size) override {
|
||||
auto Err = Client.deregisterEHFrames(LoadAddr, Size);
|
||||
// FIXME: Add error poll.
|
||||
assert(!Err && "Failed to register remote EH frames.");
|
||||
(void)Err;
|
||||
void deregisterEHFrames() override {
|
||||
for (auto &Frame : RegisteredEHFrames) {
|
||||
auto Err = Client.deregisterEHFrames(Frame.Addr, Frame.Size);
|
||||
// FIXME: Add error poll.
|
||||
assert(!Err && "Failed to register remote EH frames.");
|
||||
(void)Err;
|
||||
}
|
||||
}
|
||||
|
||||
void notifyObjectLoaded(RuntimeDyld &Dyld,
|
||||
@ -320,7 +320,7 @@ public:
|
||||
Unfinalized.clear();
|
||||
|
||||
for (auto &EHFrame : UnfinalizedEHFrames) {
|
||||
if (auto Err = Client.registerEHFrames(EHFrame.first, EHFrame.second)) {
|
||||
if (auto Err = Client.registerEHFrames(EHFrame.Addr, EHFrame.Size)) {
|
||||
// FIXME: Replace this once finalizeMemory can return an Error.
|
||||
handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) {
|
||||
if (ErrMsg) {
|
||||
@ -331,7 +331,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UnfinalizedEHFrames.clear();
|
||||
RegisteredEHFrames = std::move(UnfinalizedEHFrames);
|
||||
UnfinalizedEHFrames = {};
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -387,7 +388,13 @@ public:
|
||||
ResourceIdMgr::ResourceId Id;
|
||||
std::vector<ObjectAllocs> Unmapped;
|
||||
std::vector<ObjectAllocs> Unfinalized;
|
||||
std::vector<std::pair<uint64_t, uint32_t>> UnfinalizedEHFrames;
|
||||
|
||||
struct EHFrame {
|
||||
JITTargetAddress Addr;
|
||||
uint64_t Size;
|
||||
};
|
||||
std::vector<EHFrame> UnfinalizedEHFrames;
|
||||
std::vector<EHFrame> RegisteredEHFrames;
|
||||
};
|
||||
|
||||
/// Remote indirect stubs manager.
|
||||
|
@ -120,6 +120,10 @@ private:
|
||||
buildInitialSymbolTable(PFC->Objects);
|
||||
}
|
||||
|
||||
~ConcreteLinkedObjectSet() override {
|
||||
MemMgr->deregisterEHFrames();
|
||||
}
|
||||
|
||||
void setHandle(ObjSetHandleT H) {
|
||||
PFC->Handle = H;
|
||||
}
|
||||
|
@ -69,13 +69,8 @@ public:
|
||||
/// Deregister EH frames in the current proces.
|
||||
static void deregisterEHFramesInProcess(uint8_t *Addr, size_t Size);
|
||||
|
||||
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
|
||||
registerEHFramesInProcess(Addr, Size);
|
||||
}
|
||||
|
||||
void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override {
|
||||
deregisterEHFramesInProcess(Addr, Size);
|
||||
}
|
||||
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
|
||||
void deregisterEHFrames() override;
|
||||
|
||||
/// This method returns the address of the specified function or variable in
|
||||
/// the current process.
|
||||
@ -139,6 +134,13 @@ public:
|
||||
/// MCJIT or RuntimeDyld. Use getSymbolAddress instead.
|
||||
virtual void *getPointerToNamedFunction(const std::string &Name,
|
||||
bool AbortOnFailure = true);
|
||||
|
||||
private:
|
||||
struct EHFrame {
|
||||
uint8_t *Addr;
|
||||
size_t Size;
|
||||
};
|
||||
std::vector<EHFrame> EHFrames;
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
|
@ -150,8 +150,7 @@ public:
|
||||
/// be the case for local execution) these two values will be the same.
|
||||
virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
|
||||
size_t Size) = 0;
|
||||
virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr,
|
||||
size_t Size) = 0;
|
||||
virtual void deregisterEHFrames() = 0;
|
||||
|
||||
/// This method is called when object loading is complete and section page
|
||||
/// permissions can be applied. It is up to the memory manager implementation
|
||||
|
@ -35,6 +35,7 @@ namespace llvm {
|
||||
class AttrBuilder;
|
||||
class AttributeImpl;
|
||||
class AttributeListImpl;
|
||||
class AttributeList;
|
||||
class AttributeSetNode;
|
||||
template<typename T> struct DenseMapInfo;
|
||||
class Function;
|
||||
@ -227,14 +228,51 @@ public:
|
||||
bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; }
|
||||
bool operator!=(const AttributeSet &O) { return !(*this == O); }
|
||||
|
||||
/// Add an argument attribute. Because
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet addAttribute(LLVMContext &C,
|
||||
Attribute::AttrKind Kind) const;
|
||||
|
||||
/// Add a target-dependent attribute. Because
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet addAttribute(LLVMContext &C, StringRef Kind,
|
||||
StringRef Value = StringRef()) const;
|
||||
|
||||
/// Add attributes to the attribute set. Because
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const;
|
||||
|
||||
/// Remove the specified attribute from this set. Because
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet removeAttribute(LLVMContext &C,
|
||||
Attribute::AttrKind Kind) const;
|
||||
|
||||
/// Remove the specified attribute from this set. Because
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet removeAttribute(LLVMContext &C,
|
||||
StringRef Kind) const;
|
||||
|
||||
/// Remove the specified attributes from this set. Because
|
||||
/// attribute sets are immutable, this returns a new set.
|
||||
AttributeSet removeAttributes(LLVMContext &C,
|
||||
const AttrBuilder &AttrsToRemove) const;
|
||||
|
||||
/// Return the number of attributes in this set.
|
||||
unsigned getNumAttributes() const;
|
||||
|
||||
/// Return true if attributes exists in this set.
|
||||
bool hasAttributes() const { return SetNode != nullptr; }
|
||||
|
||||
/// Return true if the attribute exists in this set.
|
||||
bool hasAttribute(Attribute::AttrKind Kind) const;
|
||||
|
||||
/// Return true if the attribute exists in this set.
|
||||
bool hasAttribute(StringRef Kind) const;
|
||||
|
||||
/// Return the attribute object.
|
||||
Attribute getAttribute(Attribute::AttrKind Kind) const;
|
||||
|
||||
/// Return the target-dependent attribute object.
|
||||
Attribute getAttribute(StringRef Kind) const;
|
||||
|
||||
unsigned getAlignment() const;
|
||||
@ -248,6 +286,9 @@ public:
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
void dump() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -201,6 +201,10 @@ namespace CallingConv {
|
||||
/// shaders)
|
||||
AMDGPU_HS = 93,
|
||||
|
||||
/// Calling convention used for special MSP430 rtlib functions
|
||||
/// which have an "optimized" convention using additional registers.
|
||||
MSP430_BUILTIN = 94,
|
||||
|
||||
/// The highest possible calling convention ID. Must be some 2^k - 1.
|
||||
MaxID = 1023
|
||||
};
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
@ -452,7 +453,14 @@ class ConstantStruct final : public ConstantAggregate {
|
||||
public:
|
||||
// ConstantStruct accessors
|
||||
static Constant *get(StructType *T, ArrayRef<Constant*> V);
|
||||
static Constant *get(StructType *T, ...) LLVM_END_WITH_NULL;
|
||||
|
||||
template <typename... Csts>
|
||||
static typename std::enable_if<are_base_of<Constant, Csts...>::value,
|
||||
Constant *>::type
|
||||
get(StructType *T, Csts *... Vs) {
|
||||
SmallVector<Constant *, 8> Values({Vs...});
|
||||
return get(T, Values);
|
||||
}
|
||||
|
||||
/// Return an anonymous struct that has the specified elements.
|
||||
/// If the struct is possibly empty, then you must specify a context.
|
||||
|
@ -16,8 +16,11 @@
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/BitmaskEnum.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
@ -56,10 +59,6 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class DIBuilder;
|
||||
|
||||
template <typename T> class Optional;
|
||||
|
||||
/// Holds a subclass of DINode.
|
||||
///
|
||||
/// FIXME: This class doesn't currently make much sense. Previously it was a
|
||||
@ -94,9 +93,9 @@ public:
|
||||
bool operator!=(const TypedDINodeRef<T> &X) const { return MD != X.MD; }
|
||||
};
|
||||
|
||||
typedef TypedDINodeRef<DINode> DINodeRef;
|
||||
typedef TypedDINodeRef<DIScope> DIScopeRef;
|
||||
typedef TypedDINodeRef<DIType> DITypeRef;
|
||||
using DINodeRef = TypedDINodeRef<DINode>;
|
||||
using DIScopeRef = TypedDINodeRef<DIScope>;
|
||||
using DITypeRef = TypedDINodeRef<DIType>;
|
||||
|
||||
class DITypeRefArray {
|
||||
const MDTuple *N = nullptr;
|
||||
@ -240,7 +239,8 @@ public:
|
||||
};
|
||||
|
||||
template <class T> struct simplify_type<const TypedDINodeRef<T>> {
|
||||
typedef Metadata *SimpleType;
|
||||
using SimpleType = Metadata *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const TypedDINodeRef<T> &MD) {
|
||||
return MD;
|
||||
}
|
||||
@ -799,15 +799,18 @@ public:
|
||||
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
|
||||
return DITypeRef(getExtraData());
|
||||
}
|
||||
|
||||
DIObjCProperty *getObjCProperty() const {
|
||||
return dyn_cast_or_null<DIObjCProperty>(getExtraData());
|
||||
}
|
||||
|
||||
Constant *getStorageOffsetInBits() const {
|
||||
assert(getTag() == dwarf::DW_TAG_member && isBitField());
|
||||
if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
|
||||
return C->getValue();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Constant *getConstant() const {
|
||||
assert(getTag() == dwarf::DW_TAG_member && isStaticMember());
|
||||
if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
|
||||
@ -970,9 +973,11 @@ public:
|
||||
#endif
|
||||
replaceOperandWith(4, Elements.get());
|
||||
}
|
||||
|
||||
void replaceVTableHolder(DITypeRef VTableHolder) {
|
||||
replaceOperandWith(5, VTableHolder);
|
||||
}
|
||||
|
||||
void replaceTemplateParams(DITemplateParameterArray TemplateParams) {
|
||||
replaceOperandWith(6, TemplateParams.get());
|
||||
}
|
||||
@ -1031,6 +1036,7 @@ public:
|
||||
DITypeRefArray getTypeArray() const {
|
||||
return cast_or_null<MDTuple>(getRawTypeArray());
|
||||
}
|
||||
|
||||
Metadata *getRawTypeArray() const { return getOperand(3); }
|
||||
|
||||
static bool classof(const Metadata *MD) {
|
||||
@ -1319,6 +1325,7 @@ public:
|
||||
unsigned getLine() const { return SubclassData32; }
|
||||
unsigned getColumn() const { return SubclassData16; }
|
||||
DILocalScope *getScope() const { return cast<DILocalScope>(getRawScope()); }
|
||||
|
||||
DILocation *getInlinedAt() const {
|
||||
return cast_or_null<DILocation>(getRawInlinedAt());
|
||||
}
|
||||
@ -1452,7 +1459,6 @@ public:
|
||||
static bool classof(const Metadata *MD) {
|
||||
return MD->getMetadataID() == DILocationKind;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Subprogram description.
|
||||
@ -2087,6 +2093,7 @@ public:
|
||||
return F->getFilename();
|
||||
return "";
|
||||
}
|
||||
|
||||
StringRef getDirectory() const {
|
||||
if (auto *F = getFile())
|
||||
return F->getDirectory();
|
||||
@ -2143,6 +2150,7 @@ public:
|
||||
ArrayRef<uint64_t> getElements() const { return Elements; }
|
||||
|
||||
unsigned getNumElements() const { return Elements.size(); }
|
||||
|
||||
uint64_t getElement(unsigned I) const {
|
||||
assert(I < Elements.size() && "Index out of range");
|
||||
return Elements[I];
|
||||
@ -2151,7 +2159,8 @@ public:
|
||||
/// Determine whether this represents a standalone constant value.
|
||||
bool isConstant() const;
|
||||
|
||||
typedef ArrayRef<uint64_t>::iterator element_iterator;
|
||||
using element_iterator = ArrayRef<uint64_t>::iterator;
|
||||
|
||||
element_iterator elements_begin() const { return getElements().begin(); }
|
||||
element_iterator elements_end() const { return getElements().end(); }
|
||||
|
||||
@ -2276,6 +2285,10 @@ public:
|
||||
/// Append \p Ops with operations to apply the \p Offset.
|
||||
static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
|
||||
|
||||
/// If this is a constant offset, extract it. If there is no expression,
|
||||
/// return true with an offset of zero.
|
||||
bool extractIfOffset(int64_t &Offset) const;
|
||||
|
||||
/// Constants for DIExpression::prepend.
|
||||
enum { NoDeref = false, WithDeref = true, WithStackValue = true };
|
||||
|
||||
@ -2509,6 +2522,7 @@ public:
|
||||
return F->getFilename();
|
||||
return "";
|
||||
}
|
||||
|
||||
StringRef getDirectory() const {
|
||||
if (auto *F = getFile())
|
||||
return F->getDirectory();
|
||||
@ -2609,10 +2623,13 @@ public:
|
||||
TempDIGlobalVariableExpression clone() const { return cloneImpl(); }
|
||||
|
||||
Metadata *getRawVariable() const { return getOperand(0); }
|
||||
|
||||
DIGlobalVariable *getVariable() const {
|
||||
return cast_or_null<DIGlobalVariable>(getRawVariable());
|
||||
}
|
||||
|
||||
Metadata *getRawExpression() const { return getOperand(1); }
|
||||
|
||||
DIExpression *getExpression() const {
|
||||
return cast_or_null<DIExpression>(getRawExpression());
|
||||
}
|
||||
|
@ -80,6 +80,22 @@ namespace llvm {
|
||||
static DebugLoc get(unsigned Line, unsigned Col, const MDNode *Scope,
|
||||
const MDNode *InlinedAt = nullptr);
|
||||
|
||||
enum { ReplaceLastInlinedAt = true };
|
||||
/// Rebuild the entire inlined-at chain for this instruction so that the top of
|
||||
/// the chain now is inlined-at the new call site.
|
||||
/// \param InlinedAt The new outermost inlined-at in the chain.
|
||||
/// \param ReplaceLast Replace the last location in the inlined-at chain.
|
||||
static DebugLoc appendInlinedAt(DebugLoc DL, DILocation *InlinedAt,
|
||||
LLVMContext &Ctx,
|
||||
DenseMap<const MDNode *, MDNode *> &Cache,
|
||||
bool ReplaceLast = false);
|
||||
|
||||
/// Reparent all debug locations referenced by \c I that belong to \c OrigSP
|
||||
/// to become (possibly indirect) children of \c NewSP.
|
||||
static void reparentDebugInfo(Instruction &I, DISubprogram *OrigSP,
|
||||
DISubprogram *NewSP,
|
||||
DenseMap<const MDNode *, MDNode *> &Cache);
|
||||
|
||||
unsigned getLine() const;
|
||||
unsigned getCol() const;
|
||||
MDNode *getScope() const;
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
|
||||
//===- llvm/DerivedTypes.h - Classes for handling data types ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -19,6 +19,7 @@
|
||||
#define LLVM_IR_DERIVEDTYPES_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
@ -122,7 +123,8 @@ public:
|
||||
bool isVarArg() const { return getSubclassData()!=0; }
|
||||
Type *getReturnType() const { return ContainedTys[0]; }
|
||||
|
||||
typedef Type::subtype_iterator param_iterator;
|
||||
using param_iterator = Type::subtype_iterator;
|
||||
|
||||
param_iterator param_begin() const { return ContainedTys + 1; }
|
||||
param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
|
||||
ArrayRef<Type *> params() const {
|
||||
@ -197,8 +199,7 @@ public:
|
||||
/// generator for a target expects).
|
||||
///
|
||||
class StructType : public CompositeType {
|
||||
StructType(LLVMContext &C)
|
||||
: CompositeType(C, StructTyID), SymbolTableEntry(nullptr) {}
|
||||
StructType(LLVMContext &C) : CompositeType(C, StructTyID) {}
|
||||
|
||||
enum {
|
||||
/// This is the contents of the SubClassData field.
|
||||
@ -212,7 +213,7 @@ class StructType : public CompositeType {
|
||||
/// symbol table entry (maintained by LLVMContext) for the struct.
|
||||
/// This is null if the type is an literal struct or if it is a identified
|
||||
/// type that has an empty name.
|
||||
void *SymbolTableEntry;
|
||||
void *SymbolTableEntry = nullptr;
|
||||
|
||||
public:
|
||||
StructType(const StructType &) = delete;
|
||||
@ -228,7 +229,14 @@ public:
|
||||
static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements,
|
||||
StringRef Name, bool isPacked = false);
|
||||
static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements);
|
||||
static StructType *create(StringRef Name, Type *elt1, ...) LLVM_END_WITH_NULL;
|
||||
template <class... Tys>
|
||||
static typename std::enable_if<are_base_of<Type, Tys...>::value,
|
||||
StructType *>::type
|
||||
create(StringRef Name, Type *elt1, Tys *... elts) {
|
||||
assert(elt1 && "Cannot create a struct type with no elements with this");
|
||||
SmallVector<llvm::Type *, 8> StructFields({elt1, elts...});
|
||||
return create(StructFields, Name);
|
||||
}
|
||||
|
||||
/// This static method is the primary way to create a literal StructType.
|
||||
static StructType *get(LLVMContext &Context, ArrayRef<Type*> Elements,
|
||||
@ -240,7 +248,15 @@ public:
|
||||
/// This static method is a convenience method for creating structure types by
|
||||
/// specifying the elements as arguments. Note that this method always returns
|
||||
/// a non-packed struct, and requires at least one element type.
|
||||
static StructType *get(Type *elt1, ...) LLVM_END_WITH_NULL;
|
||||
template <class... Tys>
|
||||
static typename std::enable_if<are_base_of<Type, Tys...>::value,
|
||||
StructType *>::type
|
||||
get(Type *elt1, Tys *... elts) {
|
||||
assert(elt1 && "Cannot create a struct type with no elements with this");
|
||||
LLVMContext &Ctx = elt1->getContext();
|
||||
SmallVector<llvm::Type *, 8> StructFields({elt1, elts...});
|
||||
return llvm::StructType::get(Ctx, StructFields);
|
||||
}
|
||||
|
||||
bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; }
|
||||
|
||||
@ -269,13 +285,21 @@ public:
|
||||
|
||||
/// Specify a body for an opaque identified type.
|
||||
void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
|
||||
void setBody(Type *elt1, ...) LLVM_END_WITH_NULL;
|
||||
|
||||
template <typename... Tys>
|
||||
typename std::enable_if<are_base_of<Type, Tys...>::value, void>::type
|
||||
setBody(Type *elt1, Tys *... elts) {
|
||||
assert(elt1 && "Cannot create a struct type with no elements with this");
|
||||
SmallVector<llvm::Type *, 8> StructFields({elt1, elts...});
|
||||
setBody(StructFields);
|
||||
}
|
||||
|
||||
/// Return true if the specified type is valid as a element type.
|
||||
static bool isValidElementType(Type *ElemTy);
|
||||
|
||||
// Iterator access to the elements.
|
||||
typedef Type::subtype_iterator element_iterator;
|
||||
using element_iterator = Type::subtype_iterator;
|
||||
|
||||
element_iterator element_begin() const { return ContainedTys; }
|
||||
element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
|
||||
ArrayRef<Type *> const elements() const {
|
||||
|
@ -15,7 +15,6 @@
|
||||
#ifndef LLVM_IR_DIAGNOSTICINFO_H
|
||||
#define LLVM_IR_DIAGNOSTICINFO_H
|
||||
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
@ -120,18 +119,18 @@ public:
|
||||
virtual void print(DiagnosticPrinter &DP) const = 0;
|
||||
};
|
||||
|
||||
typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
|
||||
using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
|
||||
|
||||
/// Diagnostic information for inline asm reporting.
|
||||
/// This is basically a message and an optional location.
|
||||
class DiagnosticInfoInlineAsm : public DiagnosticInfo {
|
||||
private:
|
||||
/// Optional line information. 0 if not set.
|
||||
unsigned LocCookie;
|
||||
unsigned LocCookie = 0;
|
||||
/// Message to be reported.
|
||||
const Twine &MsgStr;
|
||||
/// Optional origin of the problem.
|
||||
const Instruction *Instr;
|
||||
const Instruction *Instr = nullptr;
|
||||
|
||||
public:
|
||||
/// \p MsgStr is the message to be reported to the frontend.
|
||||
@ -139,8 +138,7 @@ public:
|
||||
/// for the whole life time of the Diagnostic.
|
||||
DiagnosticInfoInlineAsm(const Twine &MsgStr,
|
||||
DiagnosticSeverity Severity = DS_Error)
|
||||
: DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
|
||||
Instr(nullptr) {}
|
||||
: DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
|
||||
|
||||
/// \p LocCookie if non-zero gives the line number for this report.
|
||||
/// \p MsgStr gives the message.
|
||||
@ -149,7 +147,7 @@ public:
|
||||
DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
|
||||
DiagnosticSeverity Severity = DS_Error)
|
||||
: DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
|
||||
MsgStr(MsgStr), Instr(nullptr) {}
|
||||
MsgStr(MsgStr) {}
|
||||
|
||||
/// \p Instr gives the original instruction that triggered the diagnostic.
|
||||
/// \p MsgStr gives the message.
|
||||
@ -294,10 +292,10 @@ public:
|
||||
DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
|
||||
DiagnosticSeverity Severity = DS_Error)
|
||||
: DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
|
||||
LineNum(0), Msg(Msg) {}
|
||||
Msg(Msg) {}
|
||||
DiagnosticInfoSampleProfile(const Twine &Msg,
|
||||
DiagnosticSeverity Severity = DS_Error)
|
||||
: DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {}
|
||||
: DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
|
||||
|
||||
/// \see DiagnosticInfo::print.
|
||||
void print(DiagnosticPrinter &DP) const override;
|
||||
@ -316,7 +314,7 @@ private:
|
||||
|
||||
/// Line number where the diagnostic occurred. If 0, no line number will
|
||||
/// be emitted in the message.
|
||||
unsigned LineNum;
|
||||
unsigned LineNum = 0;
|
||||
|
||||
/// Message to report.
|
||||
const Twine &Msg;
|
||||
@ -351,8 +349,9 @@ class DiagnosticLocation {
|
||||
StringRef Filename;
|
||||
unsigned Line = 0;
|
||||
unsigned Column = 0;
|
||||
|
||||
public:
|
||||
DiagnosticLocation() {}
|
||||
DiagnosticLocation() = default;
|
||||
DiagnosticLocation(const DebugLoc &DL);
|
||||
DiagnosticLocation(const DISubprogram *SP);
|
||||
|
||||
@ -796,6 +795,7 @@ private:
|
||||
const Twine &Msg)
|
||||
: OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
|
||||
PassName, Fn, Loc, Msg) {}
|
||||
|
||||
friend void emitOptimizationRemarkAnalysisFPCommute(
|
||||
LLVMContext &Ctx, const char *PassName, const Function &Fn,
|
||||
const DiagnosticLocation &Loc, const Twine &Msg);
|
||||
@ -1012,6 +1012,7 @@ public:
|
||||
|
||||
void print(DiagnosticPrinter &DP) const override;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_IR_DIAGNOSTICINFO_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Function.h - Class to represent a single function --*- C++ -*-===//
|
||||
//===- llvm/Function.h - Class to represent a single function ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -22,15 +22,19 @@
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/IR/Argument.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/GlobalObject.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/OperandTraits.h"
|
||||
#include "llvm/IR/SymbolTableListTraits.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
@ -40,27 +44,31 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <typename T> class Optional;
|
||||
class AssemblyAnnotationWriter;
|
||||
class FunctionType;
|
||||
class LLVMContext;
|
||||
class Constant;
|
||||
class DISubprogram;
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
template <typename T> class Optional;
|
||||
class raw_ostream;
|
||||
class Type;
|
||||
class User;
|
||||
|
||||
class Function : public GlobalObject, public ilist_node<Function> {
|
||||
public:
|
||||
typedef SymbolTableList<BasicBlock> BasicBlockListType;
|
||||
using BasicBlockListType = SymbolTableList<BasicBlock>;
|
||||
|
||||
// BasicBlock iterators...
|
||||
typedef BasicBlockListType::iterator iterator;
|
||||
typedef BasicBlockListType::const_iterator const_iterator;
|
||||
using iterator = BasicBlockListType::iterator;
|
||||
using const_iterator = BasicBlockListType::const_iterator;
|
||||
|
||||
typedef Argument *arg_iterator;
|
||||
typedef const Argument *const_arg_iterator;
|
||||
using arg_iterator = Argument *;
|
||||
using const_arg_iterator = const Argument *;
|
||||
|
||||
private:
|
||||
// Important things that make up a function!
|
||||
BasicBlockListType BasicBlocks; ///< The basic blocks
|
||||
mutable Argument *Arguments; ///< The formal arguments
|
||||
BasicBlockListType BasicBlocks; ///< The basic blocks
|
||||
mutable Argument *Arguments = nullptr; ///< The formal arguments
|
||||
size_t NumArgs;
|
||||
std::unique_ptr<ValueSymbolTable>
|
||||
SymTab; ///< Symbol table of args/instructions
|
||||
@ -124,10 +132,12 @@ public:
|
||||
|
||||
// Provide fast operand accessors.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
/// Returns the FunctionType for me.
|
||||
FunctionType *getFunctionType() const {
|
||||
return cast<FunctionType>(getValueType());
|
||||
}
|
||||
|
||||
/// Returns the type of the ret val.
|
||||
Type *getReturnType() const { return getFunctionType()->getReturnType(); }
|
||||
|
||||
@ -484,7 +494,7 @@ public:
|
||||
|
||||
/// copyAttributesFrom - copy all additional attributes (those not needed to
|
||||
/// create a Function) from the Function Src to this one.
|
||||
void copyAttributesFrom(const GlobalValue *Src) override;
|
||||
void copyAttributesFrom(const Function *Src);
|
||||
|
||||
/// deleteBody - This method deletes the body of the function, and converts
|
||||
/// the linkage to external.
|
||||
@ -497,12 +507,12 @@ public:
|
||||
/// removeFromParent - This method unlinks 'this' from the containing module,
|
||||
/// but does not delete it.
|
||||
///
|
||||
void removeFromParent() override;
|
||||
void removeFromParent();
|
||||
|
||||
/// eraseFromParent - This method unlinks 'this' from the containing module
|
||||
/// and deletes it.
|
||||
///
|
||||
void eraseFromParent() override;
|
||||
void eraseFromParent();
|
||||
|
||||
/// Steal arguments from another function.
|
||||
///
|
||||
|
@ -21,7 +21,9 @@
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
namespace llvm {
|
||||
@ -29,13 +31,13 @@ namespace llvm {
|
||||
template<typename ItTy = User::const_op_iterator>
|
||||
class generic_gep_type_iterator
|
||||
: public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
|
||||
typedef std::iterator<std::forward_iterator_tag,
|
||||
Type *, ptrdiff_t> super;
|
||||
using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>;
|
||||
|
||||
ItTy OpIt;
|
||||
PointerUnion<StructType *, Type *> CurTy;
|
||||
enum : uint64_t { Unbounded = -1ull };
|
||||
uint64_t NumElements = Unbounded;
|
||||
|
||||
generic_gep_type_iterator() = default;
|
||||
|
||||
public:
|
||||
@ -121,7 +123,7 @@ namespace llvm {
|
||||
}
|
||||
};
|
||||
|
||||
typedef generic_gep_type_iterator<> gep_type_iterator;
|
||||
using gep_type_iterator = generic_gep_type_iterator<>;
|
||||
|
||||
inline gep_type_iterator gep_type_begin(const User *GEP) {
|
||||
auto *GEPOp = cast<GEPOperator>(GEP);
|
||||
|
@ -59,15 +59,19 @@ public:
|
||||
// Linkage, Type, Parent and AddressSpace taken from the Aliasee.
|
||||
static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
|
||||
|
||||
void copyAttributesFrom(const GlobalValue *Src) {
|
||||
GlobalValue::copyAttributesFrom(Src);
|
||||
}
|
||||
|
||||
/// removeFromParent - This method unlinks 'this' from the containing module,
|
||||
/// but does not delete it.
|
||||
///
|
||||
void removeFromParent() override;
|
||||
void removeFromParent();
|
||||
|
||||
/// eraseFromParent - This method unlinks 'this' from the containing module
|
||||
/// and deletes it.
|
||||
///
|
||||
void eraseFromParent() override;
|
||||
void eraseFromParent();
|
||||
|
||||
/// These methods retrieve and set alias target.
|
||||
void setAliasee(Constant *Aliasee);
|
||||
|
@ -47,12 +47,16 @@ public:
|
||||
LinkageTypes Linkage, const Twine &Name,
|
||||
Constant *Resolver, Module *Parent);
|
||||
|
||||
void copyAttributesFrom(const GlobalIFunc *Src) {
|
||||
GlobalValue::copyAttributesFrom(Src);
|
||||
}
|
||||
|
||||
/// This method unlinks 'this' from the containing module, but does not
|
||||
/// delete it.
|
||||
void removeFromParent() final;
|
||||
void removeFromParent();
|
||||
|
||||
/// This method unlinks 'this' from the containing module and deletes it.
|
||||
void eraseFromParent() final;
|
||||
void eraseFromParent();
|
||||
|
||||
/// These methods retrieve and set ifunc resolver function.
|
||||
void setResolver(Constant *Resolver) {
|
||||
|
@ -150,8 +150,10 @@ public:
|
||||
|
||||
void addTypeMetadata(unsigned Offset, Metadata *TypeID);
|
||||
|
||||
void copyAttributesFrom(const GlobalValue *Src) override;
|
||||
protected:
|
||||
void copyAttributesFrom(const GlobalObject *Src);
|
||||
|
||||
public:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const Value *V) {
|
||||
return V->getValueID() == Value::FunctionVal ||
|
||||
|
@ -435,14 +435,20 @@ public:
|
||||
|
||||
bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); }
|
||||
|
||||
protected:
|
||||
/// Copy all additional attributes (those not needed to create a GlobalValue)
|
||||
/// from the GlobalValue Src to this one.
|
||||
virtual void copyAttributesFrom(const GlobalValue *Src);
|
||||
void copyAttributesFrom(const GlobalValue *Src);
|
||||
|
||||
/// If special LLVM prefix that is used to inform the asm printer to not emit
|
||||
/// usual symbol prefix before the symbol name is used then return linkage
|
||||
/// name after skipping this special LLVM prefix.
|
||||
static StringRef getRealLinkageName(StringRef Name) {
|
||||
public:
|
||||
/// If the given string begins with the GlobalValue name mangling escape
|
||||
/// character '\1', drop it.
|
||||
///
|
||||
/// This function applies a specific mangling that is used in PGO profiles,
|
||||
/// among other things. If you're trying to get a symbol name for an
|
||||
/// arbitrary GlobalValue, this is not the function you're looking for; see
|
||||
/// Mangler.h.
|
||||
static StringRef dropLLVMManglingEscape(StringRef Name) {
|
||||
if (!Name.empty() && Name[0] == '\1')
|
||||
return Name.substr(1);
|
||||
return Name;
|
||||
@ -530,10 +536,10 @@ public:
|
||||
|
||||
/// This method unlinks 'this' from the containing module, but does not delete
|
||||
/// it.
|
||||
virtual void removeFromParent() = 0;
|
||||
void removeFromParent();
|
||||
|
||||
/// This method unlinks 'this' from the containing module and deletes it.
|
||||
virtual void eraseFromParent() = 0;
|
||||
void eraseFromParent();
|
||||
|
||||
/// Get the module that this global value is contained inside of...
|
||||
Module *getParent() { return Parent; }
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/IR/GlobalObject.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/OperandTraits.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include <cassert>
|
||||
@ -41,6 +42,7 @@ class DIGlobalVariableExpression;
|
||||
class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
|
||||
friend class SymbolTableListTraits<GlobalVariable>;
|
||||
|
||||
AttributeSet Attrs;
|
||||
bool isConstantGlobal : 1; // Is this a global constant?
|
||||
bool isExternallyInitializedConstant : 1; // Is this a global whose value
|
||||
// can change from its initial
|
||||
@ -156,17 +158,17 @@ public:
|
||||
|
||||
/// copyAttributesFrom - copy all additional attributes (those not needed to
|
||||
/// create a GlobalVariable) from the GlobalVariable Src to this one.
|
||||
void copyAttributesFrom(const GlobalValue *Src) override;
|
||||
void copyAttributesFrom(const GlobalVariable *Src);
|
||||
|
||||
/// removeFromParent - This method unlinks 'this' from the containing module,
|
||||
/// but does not delete it.
|
||||
///
|
||||
void removeFromParent() override;
|
||||
void removeFromParent();
|
||||
|
||||
/// eraseFromParent - This method unlinks 'this' from the containing module
|
||||
/// and deletes it.
|
||||
///
|
||||
void eraseFromParent() override;
|
||||
void eraseFromParent();
|
||||
|
||||
/// Drop all references in preparation to destroy the GlobalVariable. This
|
||||
/// drops not only the reference to the initializer but also to any metadata.
|
||||
@ -178,6 +180,61 @@ public:
|
||||
/// Fill the vector with all debug info attachements.
|
||||
void getDebugInfo(SmallVectorImpl<DIGlobalVariableExpression *> &GVs) const;
|
||||
|
||||
/// Add attribute to this global.
|
||||
void addAttribute(Attribute::AttrKind Kind) {
|
||||
Attrs = Attrs.addAttribute(getContext(), Kind);
|
||||
}
|
||||
|
||||
/// Add attribute to this global.
|
||||
void addAttribute(StringRef Kind, StringRef Val = StringRef()) {
|
||||
Attrs = Attrs.addAttribute(getContext(), Kind, Val);
|
||||
}
|
||||
|
||||
/// Return true if the attribute exists.
|
||||
bool hasAttribute(Attribute::AttrKind Kind) const {
|
||||
return Attrs.hasAttribute(Kind);
|
||||
}
|
||||
|
||||
/// Return true if the attribute exists.
|
||||
bool hasAttribute(StringRef Kind) const {
|
||||
return Attrs.hasAttribute(Kind);
|
||||
}
|
||||
|
||||
/// Return true if any attributes exist.
|
||||
bool hasAttributes() const {
|
||||
return Attrs.hasAttributes();
|
||||
}
|
||||
|
||||
/// Return the attribute object.
|
||||
Attribute getAttribute(Attribute::AttrKind Kind) const {
|
||||
return Attrs.getAttribute(Kind);
|
||||
}
|
||||
|
||||
/// Return the attribute object.
|
||||
Attribute getAttribute(StringRef Kind) const {
|
||||
return Attrs.getAttribute(Kind);
|
||||
}
|
||||
|
||||
/// Return the attribute set for this global
|
||||
AttributeSet getAttributes() const {
|
||||
return Attrs;
|
||||
}
|
||||
|
||||
/// Return attribute set as list with index.
|
||||
/// FIXME: This may not be required once ValueEnumerators
|
||||
/// in bitcode-writer can enumerate attribute-set.
|
||||
AttributeList getAttributesAsList(unsigned index) const {
|
||||
if (!hasAttributes())
|
||||
return AttributeList();
|
||||
std::pair<unsigned, AttributeSet> AS[1] = {{index, Attrs}};
|
||||
return AttributeList::get(getContext(), AS);
|
||||
}
|
||||
|
||||
/// Set attribute list for this global
|
||||
void setAttributes(AttributeSet A) {
|
||||
Attrs = A;
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const Value *V) {
|
||||
return V->getValueID() == Value::GlobalVariableVal;
|
||||
|
@ -454,6 +454,45 @@ public:
|
||||
MDNode *ScopeTag = nullptr,
|
||||
MDNode *NoAliasTag = nullptr);
|
||||
|
||||
/// \brief Create a vector fadd reduction intrinsic of the source vector.
|
||||
/// The first parameter is a scalar accumulator value for ordered reductions.
|
||||
CallInst *CreateFAddReduce(Value *Acc, Value *Src);
|
||||
|
||||
/// \brief Create a vector fmul reduction intrinsic of the source vector.
|
||||
/// The first parameter is a scalar accumulator value for ordered reductions.
|
||||
CallInst *CreateFMulReduce(Value *Acc, Value *Src);
|
||||
|
||||
/// \brief Create a vector int add reduction intrinsic of the source vector.
|
||||
CallInst *CreateAddReduce(Value *Src);
|
||||
|
||||
/// \brief Create a vector int mul reduction intrinsic of the source vector.
|
||||
CallInst *CreateMulReduce(Value *Src);
|
||||
|
||||
/// \brief Create a vector int AND reduction intrinsic of the source vector.
|
||||
CallInst *CreateAndReduce(Value *Src);
|
||||
|
||||
/// \brief Create a vector int OR reduction intrinsic of the source vector.
|
||||
CallInst *CreateOrReduce(Value *Src);
|
||||
|
||||
/// \brief Create a vector int XOR reduction intrinsic of the source vector.
|
||||
CallInst *CreateXorReduce(Value *Src);
|
||||
|
||||
/// \brief Create a vector integer max reduction intrinsic of the source
|
||||
/// vector.
|
||||
CallInst *CreateIntMaxReduce(Value *Src, bool IsSigned = false);
|
||||
|
||||
/// \brief Create a vector integer min reduction intrinsic of the source
|
||||
/// vector.
|
||||
CallInst *CreateIntMinReduce(Value *Src, bool IsSigned = false);
|
||||
|
||||
/// \brief Create a vector float max reduction intrinsic of the source
|
||||
/// vector.
|
||||
CallInst *CreateFPMaxReduce(Value *Src, bool NoNaN = false);
|
||||
|
||||
/// \brief Create a vector float min reduction intrinsic of the source
|
||||
/// vector.
|
||||
CallInst *CreateFPMinReduce(Value *Src, bool NoNaN = false);
|
||||
|
||||
/// \brief Create a lifetime.start intrinsic.
|
||||
///
|
||||
/// If the pointer isn't i8* it will be converted.
|
||||
|
@ -65,27 +65,15 @@ protected:
|
||||
// Out of line virtual method, so the vtable, etc has a home.
|
||||
~TerminatorInst() override;
|
||||
|
||||
/// Virtual methods - Terminators should overload these and provide inline
|
||||
/// overrides of non-V methods.
|
||||
virtual BasicBlock *getSuccessorV(unsigned idx) const = 0;
|
||||
virtual unsigned getNumSuccessorsV() const = 0;
|
||||
virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0;
|
||||
|
||||
public:
|
||||
/// Return the number of successors that this terminator has.
|
||||
unsigned getNumSuccessors() const {
|
||||
return getNumSuccessorsV();
|
||||
}
|
||||
unsigned getNumSuccessors() const;
|
||||
|
||||
/// Return the specified successor.
|
||||
BasicBlock *getSuccessor(unsigned idx) const {
|
||||
return getSuccessorV(idx);
|
||||
}
|
||||
BasicBlock *getSuccessor(unsigned idx) const;
|
||||
|
||||
/// Update the specified successor to point at the provided block.
|
||||
void setSuccessor(unsigned idx, BasicBlock *B) {
|
||||
setSuccessorV(idx, B);
|
||||
}
|
||||
void setSuccessor(unsigned idx, BasicBlock *B);
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const Instruction *I) {
|
||||
|
@ -456,6 +456,12 @@ public:
|
||||
/// higher.
|
||||
bool isAtomic() const;
|
||||
|
||||
/// Return true if this atomic instruction loads from memory.
|
||||
bool hasAtomicLoad() const;
|
||||
|
||||
/// Return true if this atomic instruction stores to memory.
|
||||
bool hasAtomicStore() const;
|
||||
|
||||
/// Return true if this instruction may throw an exception.
|
||||
bool mayThrow() const;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Instructions.h - Instruction subclass definitions --*- C++ -*-===//
|
||||
//===- llvm/Instructions.h - Instruction subclass definitions ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -17,6 +17,7 @@
|
||||
#define LLVM_IR_INSTRUCTIONS_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@ -24,21 +25,25 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CallingConv.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/OperandTraits.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/Use.h"
|
||||
#include "llvm/IR/User.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Support/AtomicOrdering.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -264,6 +269,7 @@ public:
|
||||
}
|
||||
|
||||
bool isSimple() const { return !isAtomic() && !isVolatile(); }
|
||||
|
||||
bool isUnordered() const {
|
||||
return (getOrdering() == AtomicOrdering::NotAtomic ||
|
||||
getOrdering() == AtomicOrdering::Unordered) &&
|
||||
@ -386,6 +392,7 @@ public:
|
||||
}
|
||||
|
||||
bool isSimple() const { return !isAtomic() && !isVolatile(); }
|
||||
|
||||
bool isUnordered() const {
|
||||
return (getOrdering() == AtomicOrdering::NotAtomic ||
|
||||
getOrdering() == AtomicOrdering::Unordered) &&
|
||||
@ -836,10 +843,7 @@ class GetElementPtrInst : public Instruction {
|
||||
Type *SourceElementType;
|
||||
Type *ResultElementType;
|
||||
|
||||
void anchor() override;
|
||||
|
||||
GetElementPtrInst(const GetElementPtrInst &GEPI);
|
||||
void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
|
||||
|
||||
/// Constructors - Create a getelementptr instruction with a base pointer an
|
||||
/// list of indices. The first ctor can optionally insert before an existing
|
||||
@ -852,6 +856,9 @@ class GetElementPtrInst : public Instruction {
|
||||
ArrayRef<Value *> IdxList, unsigned Values,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
|
||||
void anchor() override;
|
||||
void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
|
||||
|
||||
protected:
|
||||
// Note: Instruction needs to be a friend here to call cloneImpl.
|
||||
friend class Instruction;
|
||||
@ -2261,6 +2268,19 @@ public:
|
||||
return Mask;
|
||||
}
|
||||
|
||||
/// Change values in a shuffle permute mask assuming the two vector operands
|
||||
/// of length InVecNumElts have swapped position.
|
||||
static void commuteShuffleMask(MutableArrayRef<int> Mask,
|
||||
unsigned InVecNumElts) {
|
||||
for (int &Idx : Mask) {
|
||||
if (Idx == -1)
|
||||
continue;
|
||||
Idx = Idx < (int)InVecNumElts ? Idx + InVecNumElts : Idx - InVecNumElts;
|
||||
assert(Idx >= 0 && Idx < (int)InVecNumElts * 2 &&
|
||||
"shufflevector mask index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return I->getOpcode() == Instruction::ShuffleVector;
|
||||
@ -2288,6 +2308,7 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
|
||||
ExtractValueInst(const ExtractValueInst &EVI);
|
||||
|
||||
/// Constructors - Create a extractvalue instruction with a base aggregate
|
||||
/// value and a list of indices. The first ctor can optionally insert before
|
||||
/// an existing instruction, the second appends the new instruction to the
|
||||
@ -2333,7 +2354,8 @@ public:
|
||||
/// Null is returned if the indices are invalid for the specified type.
|
||||
static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs);
|
||||
|
||||
typedef const unsigned* idx_iterator;
|
||||
using idx_iterator = const unsigned*;
|
||||
|
||||
inline idx_iterator idx_begin() const { return Indices.begin(); }
|
||||
inline idx_iterator idx_end() const { return Indices.end(); }
|
||||
inline iterator_range<idx_iterator> indices() const {
|
||||
@ -2455,7 +2477,8 @@ public:
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
|
||||
typedef const unsigned* idx_iterator;
|
||||
using idx_iterator = const unsigned*;
|
||||
|
||||
inline idx_iterator idx_begin() const { return Indices.begin(); }
|
||||
inline idx_iterator idx_end() const { return Indices.end(); }
|
||||
inline iterator_range<idx_iterator> indices() const {
|
||||
@ -2606,8 +2629,8 @@ public:
|
||||
// Block iterator interface. This provides access to the list of incoming
|
||||
// basic blocks, which parallels the list of incoming values.
|
||||
|
||||
typedef BasicBlock **block_iterator;
|
||||
typedef BasicBlock * const *const_block_iterator;
|
||||
using block_iterator = BasicBlock **;
|
||||
using const_block_iterator = BasicBlock * const *;
|
||||
|
||||
block_iterator block_begin() {
|
||||
Use::UserRef *ref =
|
||||
@ -2656,9 +2679,11 @@ public:
|
||||
"All operands to PHI node must be the same type as the PHI node!");
|
||||
setOperand(i, V);
|
||||
}
|
||||
|
||||
static unsigned getOperandNumForIncomingValue(unsigned i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned getIncomingValueNumForOperand(unsigned i) {
|
||||
return i;
|
||||
}
|
||||
@ -2937,9 +2962,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -3047,9 +3074,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -3123,7 +3152,7 @@ public:
|
||||
|
||||
protected:
|
||||
// Expose the switch type we're parameterized with to the iterator.
|
||||
typedef SwitchInstT SwitchInstType;
|
||||
using SwitchInstType = SwitchInstT;
|
||||
|
||||
SwitchInstT *SI;
|
||||
ptrdiff_t Index;
|
||||
@ -3164,8 +3193,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef CaseHandleImpl<const SwitchInst, const ConstantInt, const BasicBlock>
|
||||
ConstCaseHandle;
|
||||
using ConstCaseHandle =
|
||||
CaseHandleImpl<const SwitchInst, const ConstantInt, const BasicBlock>;
|
||||
|
||||
class CaseHandle
|
||||
: public CaseHandleImpl<SwitchInst, ConstantInt, BasicBlock> {
|
||||
@ -3192,7 +3221,7 @@ public:
|
||||
: public iterator_facade_base<CaseIteratorImpl<CaseHandleT>,
|
||||
std::random_access_iterator_tag,
|
||||
CaseHandleT> {
|
||||
typedef typename CaseHandleT::SwitchInstType SwitchInstT;
|
||||
using SwitchInstT = typename CaseHandleT::SwitchInstType;
|
||||
|
||||
CaseHandleT Case;
|
||||
|
||||
@ -3254,8 +3283,8 @@ public:
|
||||
const CaseHandleT &operator*() const { return Case; }
|
||||
};
|
||||
|
||||
typedef CaseIteratorImpl<CaseHandle> CaseIt;
|
||||
typedef CaseIteratorImpl<ConstCaseHandle> ConstCaseIt;
|
||||
using CaseIt = CaseIteratorImpl<CaseHandle>;
|
||||
using ConstCaseIt = CaseIteratorImpl<ConstCaseHandle>;
|
||||
|
||||
static SwitchInst *Create(Value *Value, BasicBlock *Default,
|
||||
unsigned NumCases,
|
||||
@ -3411,9 +3440,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -3516,9 +3547,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -3639,6 +3672,7 @@ public:
|
||||
return new (Values) InvokeInst(Func, IfNormal, IfException, Args, None,
|
||||
Values, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
static InvokeInst *Create(Value *Func, BasicBlock *IfNormal,
|
||||
BasicBlock *IfException, ArrayRef<Value *> Args,
|
||||
ArrayRef<OperandBundleDef> Bundles,
|
||||
@ -3996,9 +4030,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
|
||||
template <typename AttrKind> bool hasFnAttrImpl(AttrKind Kind) const {
|
||||
if (Attrs.hasAttribute(AttributeList::FunctionIndex, Kind))
|
||||
@ -4095,9 +4131,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -4202,13 +4240,14 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
typedef std::pointer_to_unary_function<Value *, BasicBlock *> DerefFnTy;
|
||||
typedef mapped_iterator<op_iterator, DerefFnTy> handler_iterator;
|
||||
typedef iterator_range<handler_iterator> handler_range;
|
||||
typedef std::pointer_to_unary_function<const Value *, const BasicBlock *>
|
||||
ConstDerefFnTy;
|
||||
typedef mapped_iterator<const_op_iterator, ConstDerefFnTy> const_handler_iterator;
|
||||
typedef iterator_range<const_handler_iterator> const_handler_range;
|
||||
using DerefFnTy = std::pointer_to_unary_function<Value *, BasicBlock *>;
|
||||
using handler_iterator = mapped_iterator<op_iterator, DerefFnTy>;
|
||||
using handler_range = iterator_range<handler_iterator>;
|
||||
using ConstDerefFnTy =
|
||||
std::pointer_to_unary_function<const Value *, const BasicBlock *>;
|
||||
using const_handler_iterator =
|
||||
mapped_iterator<const_op_iterator, ConstDerefFnTy>;
|
||||
using const_handler_range = iterator_range<const_handler_iterator>;
|
||||
|
||||
/// Returns an iterator that points to the first handler in CatchSwitchInst.
|
||||
handler_iterator handler_begin() {
|
||||
@ -4278,9 +4317,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned Idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned Idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned Idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned Idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -4443,9 +4484,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned Idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned Idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned Idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned Idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -4531,9 +4574,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned Idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned Idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned Idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned Idx, BasicBlock *B);
|
||||
|
||||
// Shadow Instruction::setInstructionSubclassData with a private forwarding
|
||||
// method so that subclasses cannot accidentally use it.
|
||||
@ -4586,9 +4631,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
BasicBlock *getSuccessorV(unsigned idx) const override;
|
||||
unsigned getNumSuccessorsV() const override;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B) override;
|
||||
friend TerminatorInst;
|
||||
|
||||
BasicBlock *getSuccessorV(unsigned idx) const;
|
||||
unsigned getNumSuccessorsV() const;
|
||||
void setSuccessorV(unsigned idx, BasicBlock *B);
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -812,6 +812,50 @@ def int_memcpy_element_atomic : Intrinsic<[],
|
||||
[IntrArgMemOnly, NoCapture<0>, NoCapture<1>,
|
||||
WriteOnly<0>, ReadOnly<1>]>;
|
||||
|
||||
//===------------------------ Reduction Intrinsics ------------------------===//
|
||||
//
|
||||
def int_experimental_vector_reduce_fadd : Intrinsic<[llvm_anyfloat_ty],
|
||||
[llvm_anyfloat_ty,
|
||||
llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_fmul : Intrinsic<[llvm_anyfloat_ty],
|
||||
[llvm_anyfloat_ty,
|
||||
llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_add : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_mul : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_and : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_or : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_xor : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_smax : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_smin : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_umax : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_umin : Intrinsic<[llvm_anyint_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_fmax : Intrinsic<[llvm_anyfloat_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
def int_experimental_vector_reduce_fmin : Intrinsic<[llvm_anyfloat_ty],
|
||||
[llvm_anyvector_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
//===----- Intrinsics that are used to provide predicate information -----===//
|
||||
|
||||
def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>],
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/LLVMContext.h - Class for managing "global" state --*- C++ -*-===//
|
||||
//===- llvm/LLVMContext.h - Class for managing "global" state ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -37,7 +37,9 @@ class StringRef;
|
||||
class Twine;
|
||||
|
||||
namespace yaml {
|
||||
|
||||
class Output;
|
||||
|
||||
} // end namespace yaml
|
||||
|
||||
/// This is an important class for using LLVM in a threaded context. It
|
||||
@ -134,17 +136,17 @@ public:
|
||||
void enableDebugTypeODRUniquing();
|
||||
void disableDebugTypeODRUniquing();
|
||||
|
||||
typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
|
||||
unsigned LocCookie);
|
||||
using InlineAsmDiagHandlerTy = void (*)(const SMDiagnostic&, void *Context,
|
||||
unsigned LocCookie);
|
||||
|
||||
/// Defines the type of a diagnostic handler.
|
||||
/// \see LLVMContext::setDiagnosticHandler.
|
||||
/// \see LLVMContext::diagnose.
|
||||
typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context);
|
||||
using DiagnosticHandlerTy = void (*)(const DiagnosticInfo &DI, void *Context);
|
||||
|
||||
/// Defines the type of a yield callback.
|
||||
/// \see LLVMContext::setYieldCallback.
|
||||
typedef void (*YieldCallbackTy)(LLVMContext *Context, void *OpaqueHandle);
|
||||
using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle);
|
||||
|
||||
/// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
|
||||
/// when problems with inline asm are detected by the backend. The first
|
||||
|
@ -98,6 +98,9 @@ private:
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_STDCXX_CONVERSION_FUNCTIONS(legacy::PassManagerBase, LLVMPassManagerRef)
|
||||
|
||||
/// If -time-passes has been specified, report the timings immediately and then
|
||||
/// reset the timers to zero.
|
||||
void reportAndResetTimings();
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Module.h - C++ class to represent a VM module ------*- C++ -*-===//
|
||||
//===- llvm/Module.h - C++ class to represent a VM module -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,6 +16,10 @@
|
||||
#define LLVM_IR_MODULE_H
|
||||
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/Comdat.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
@ -23,20 +27,27 @@
|
||||
#include "llvm/IR/GlobalIFunc.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/SymbolTableListTraits.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm-c/Types.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
template <typename T> class Optional;
|
||||
|
||||
class Error;
|
||||
class FunctionType;
|
||||
class GVMaterializer;
|
||||
class LLVMContext;
|
||||
class MemoryBuffer;
|
||||
class RandomNumberGenerator;
|
||||
class StructType;
|
||||
template <class PtrType> class SmallPtrSetImpl;
|
||||
class StructType;
|
||||
|
||||
/// A Module instance is used to store all the information related to an
|
||||
/// LLVM module. Modules are the top level container of all other LLVM
|
||||
@ -54,47 +65,47 @@ class Module {
|
||||
/// @{
|
||||
public:
|
||||
/// The type for the list of global variables.
|
||||
typedef SymbolTableList<GlobalVariable> GlobalListType;
|
||||
using GlobalListType = SymbolTableList<GlobalVariable>;
|
||||
/// The type for the list of functions.
|
||||
typedef SymbolTableList<Function> FunctionListType;
|
||||
using FunctionListType = SymbolTableList<Function>;
|
||||
/// The type for the list of aliases.
|
||||
typedef SymbolTableList<GlobalAlias> AliasListType;
|
||||
using AliasListType = SymbolTableList<GlobalAlias>;
|
||||
/// The type for the list of ifuncs.
|
||||
typedef SymbolTableList<GlobalIFunc> IFuncListType;
|
||||
using IFuncListType = SymbolTableList<GlobalIFunc>;
|
||||
/// The type for the list of named metadata.
|
||||
typedef ilist<NamedMDNode> NamedMDListType;
|
||||
using NamedMDListType = ilist<NamedMDNode>;
|
||||
/// The type of the comdat "symbol" table.
|
||||
typedef StringMap<Comdat> ComdatSymTabType;
|
||||
using ComdatSymTabType = StringMap<Comdat>;
|
||||
|
||||
/// The Global Variable iterator.
|
||||
typedef GlobalListType::iterator global_iterator;
|
||||
using global_iterator = GlobalListType::iterator;
|
||||
/// The Global Variable constant iterator.
|
||||
typedef GlobalListType::const_iterator const_global_iterator;
|
||||
using const_global_iterator = GlobalListType::const_iterator;
|
||||
|
||||
/// The Function iterators.
|
||||
typedef FunctionListType::iterator iterator;
|
||||
using iterator = FunctionListType::iterator;
|
||||
/// The Function constant iterator
|
||||
typedef FunctionListType::const_iterator const_iterator;
|
||||
using const_iterator = FunctionListType::const_iterator;
|
||||
|
||||
/// The Function reverse iterator.
|
||||
typedef FunctionListType::reverse_iterator reverse_iterator;
|
||||
using reverse_iterator = FunctionListType::reverse_iterator;
|
||||
/// The Function constant reverse iterator.
|
||||
typedef FunctionListType::const_reverse_iterator const_reverse_iterator;
|
||||
using const_reverse_iterator = FunctionListType::const_reverse_iterator;
|
||||
|
||||
/// The Global Alias iterators.
|
||||
typedef AliasListType::iterator alias_iterator;
|
||||
using alias_iterator = AliasListType::iterator;
|
||||
/// The Global Alias constant iterator
|
||||
typedef AliasListType::const_iterator const_alias_iterator;
|
||||
using const_alias_iterator = AliasListType::const_iterator;
|
||||
|
||||
/// The Global IFunc iterators.
|
||||
typedef IFuncListType::iterator ifunc_iterator;
|
||||
using ifunc_iterator = IFuncListType::iterator;
|
||||
/// The Global IFunc constant iterator
|
||||
typedef IFuncListType::const_iterator const_ifunc_iterator;
|
||||
using const_ifunc_iterator = IFuncListType::const_iterator;
|
||||
|
||||
/// The named metadata iterators.
|
||||
typedef NamedMDListType::iterator named_metadata_iterator;
|
||||
using named_metadata_iterator = NamedMDListType::iterator;
|
||||
/// The named metadata constant iterators.
|
||||
typedef NamedMDListType::const_iterator const_named_metadata_iterator;
|
||||
using const_named_metadata_iterator = NamedMDListType::const_iterator;
|
||||
|
||||
/// This enumeration defines the supported behaviors of module flags.
|
||||
enum ModFlagBehavior {
|
||||
@ -141,6 +152,7 @@ public:
|
||||
ModFlagBehavior Behavior;
|
||||
MDString *Key;
|
||||
Metadata *Val;
|
||||
|
||||
ModuleFlagEntry(ModFlagBehavior B, MDString *K, Metadata *V)
|
||||
: Behavior(B), Key(K), Val(V) {}
|
||||
};
|
||||
@ -483,9 +495,11 @@ public:
|
||||
const GlobalListType &getGlobalList() const { return GlobalList; }
|
||||
/// Get the Module's list of global variables.
|
||||
GlobalListType &getGlobalList() { return GlobalList; }
|
||||
|
||||
static GlobalListType Module::*getSublistAccess(GlobalVariable*) {
|
||||
return &Module::GlobalList;
|
||||
}
|
||||
|
||||
/// Get the Module's list of functions (constant).
|
||||
const FunctionListType &getFunctionList() const { return FunctionList; }
|
||||
/// Get the Module's list of functions.
|
||||
@ -493,31 +507,39 @@ public:
|
||||
static FunctionListType Module::*getSublistAccess(Function*) {
|
||||
return &Module::FunctionList;
|
||||
}
|
||||
|
||||
/// Get the Module's list of aliases (constant).
|
||||
const AliasListType &getAliasList() const { return AliasList; }
|
||||
/// Get the Module's list of aliases.
|
||||
AliasListType &getAliasList() { return AliasList; }
|
||||
|
||||
static AliasListType Module::*getSublistAccess(GlobalAlias*) {
|
||||
return &Module::AliasList;
|
||||
}
|
||||
|
||||
/// Get the Module's list of ifuncs (constant).
|
||||
const IFuncListType &getIFuncList() const { return IFuncList; }
|
||||
/// Get the Module's list of ifuncs.
|
||||
IFuncListType &getIFuncList() { return IFuncList; }
|
||||
|
||||
static IFuncListType Module::*getSublistAccess(GlobalIFunc*) {
|
||||
return &Module::IFuncList;
|
||||
}
|
||||
|
||||
/// Get the Module's list of named metadata (constant).
|
||||
const NamedMDListType &getNamedMDList() const { return NamedMDList; }
|
||||
/// Get the Module's list of named metadata.
|
||||
NamedMDListType &getNamedMDList() { return NamedMDList; }
|
||||
|
||||
static NamedMDListType Module::*getSublistAccess(NamedMDNode*) {
|
||||
return &Module::NamedMDList;
|
||||
}
|
||||
|
||||
/// Get the symbol table of global variable and function identifiers
|
||||
const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
|
||||
/// Get the Module's symbol table of global variable and function identifiers.
|
||||
ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
|
||||
|
||||
/// Get the Module's symbol table for COMDATs (constant).
|
||||
const ComdatSymTabType &getComdatSymbolTable() const { return ComdatSymTab; }
|
||||
/// Get the Module's symbol table for COMDATs.
|
||||
@ -602,11 +624,11 @@ public:
|
||||
/// @name Convenience iterators
|
||||
/// @{
|
||||
|
||||
typedef concat_iterator<GlobalObject, iterator, global_iterator>
|
||||
global_object_iterator;
|
||||
typedef concat_iterator<const GlobalObject, const_iterator,
|
||||
const_global_iterator>
|
||||
const_global_object_iterator;
|
||||
using global_object_iterator =
|
||||
concat_iterator<GlobalObject, iterator, global_iterator>;
|
||||
using const_global_object_iterator =
|
||||
concat_iterator<const GlobalObject, const_iterator,
|
||||
const_global_iterator>;
|
||||
|
||||
iterator_range<global_object_iterator> global_objects() {
|
||||
return concat<GlobalObject>(functions(), globals());
|
||||
@ -627,13 +649,12 @@ public:
|
||||
return global_objects().end();
|
||||
}
|
||||
|
||||
typedef concat_iterator<GlobalValue, iterator, global_iterator,
|
||||
alias_iterator, ifunc_iterator>
|
||||
global_value_iterator;
|
||||
typedef concat_iterator<const GlobalValue, const_iterator,
|
||||
const_global_iterator, const_alias_iterator,
|
||||
const_ifunc_iterator>
|
||||
const_global_value_iterator;
|
||||
using global_value_iterator =
|
||||
concat_iterator<GlobalValue, iterator, global_iterator, alias_iterator,
|
||||
ifunc_iterator>;
|
||||
using const_global_value_iterator =
|
||||
concat_iterator<const GlobalValue, const_iterator, const_global_iterator,
|
||||
const_alias_iterator, const_ifunc_iterator>;
|
||||
|
||||
iterator_range<global_value_iterator> global_values() {
|
||||
return concat<GlobalValue>(functions(), globals(), aliases(), ifuncs());
|
||||
@ -682,28 +703,35 @@ public:
|
||||
: public std::iterator<std::input_iterator_tag, DICompileUnit *> {
|
||||
NamedMDNode *CUs;
|
||||
unsigned Idx;
|
||||
|
||||
void SkipNoDebugCUs();
|
||||
|
||||
public:
|
||||
explicit debug_compile_units_iterator(NamedMDNode *CUs, unsigned Idx)
|
||||
: CUs(CUs), Idx(Idx) {
|
||||
SkipNoDebugCUs();
|
||||
}
|
||||
|
||||
debug_compile_units_iterator &operator++() {
|
||||
++Idx;
|
||||
SkipNoDebugCUs();
|
||||
return *this;
|
||||
}
|
||||
|
||||
debug_compile_units_iterator operator++(int) {
|
||||
debug_compile_units_iterator T(*this);
|
||||
++Idx;
|
||||
return T;
|
||||
}
|
||||
|
||||
bool operator==(const debug_compile_units_iterator &I) const {
|
||||
return Idx == I.Idx;
|
||||
}
|
||||
|
||||
bool operator!=(const debug_compile_units_iterator &I) const {
|
||||
return Idx != I.Idx;
|
||||
}
|
||||
|
||||
DICompileUnit *operator*() const;
|
||||
DICompileUnit *operator->() const;
|
||||
};
|
||||
@ -833,6 +861,6 @@ inline Module *unwrap(LLVMModuleProviderRef MP) {
|
||||
return reinterpret_cast<Module*>(MP);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_IR_MODULE_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/ModuleSummaryIndex.h - Module Summary Index --------*- C++ -*-===//
|
||||
//===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,21 +16,33 @@
|
||||
#ifndef LLVM_IR_MODULESUMMARYINDEX_H
|
||||
#define LLVM_IR_MODULESUMMARYINDEX_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace yaml {
|
||||
|
||||
template <typename T> struct MappingTraits;
|
||||
}
|
||||
|
||||
} // end namespace yaml
|
||||
|
||||
/// \brief Class to accumulate and hold information about a callee.
|
||||
struct CalleeInfo {
|
||||
@ -47,7 +59,7 @@ struct CalleeInfo {
|
||||
|
||||
class GlobalValueSummary;
|
||||
|
||||
typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList;
|
||||
using GlobalValueSummaryList = std::vector<std::unique_ptr<GlobalValueSummary>>;
|
||||
|
||||
struct GlobalValueSummaryInfo {
|
||||
/// The GlobalValue corresponding to this summary. This is only used in
|
||||
@ -66,19 +78,22 @@ struct GlobalValueSummaryInfo {
|
||||
/// likely incur less overhead, as the value type is not very small and the size
|
||||
/// of the map is unknown, resulting in inefficiencies due to repeated
|
||||
/// insertions and resizing.
|
||||
typedef std::map<GlobalValue::GUID, GlobalValueSummaryInfo>
|
||||
GlobalValueSummaryMapTy;
|
||||
using GlobalValueSummaryMapTy =
|
||||
std::map<GlobalValue::GUID, GlobalValueSummaryInfo>;
|
||||
|
||||
/// Struct that holds a reference to a particular GUID in a global value
|
||||
/// summary.
|
||||
struct ValueInfo {
|
||||
const GlobalValueSummaryMapTy::value_type *Ref = nullptr;
|
||||
|
||||
ValueInfo() = default;
|
||||
ValueInfo(const GlobalValueSummaryMapTy::value_type *Ref) : Ref(Ref) {}
|
||||
|
||||
operator bool() const { return Ref; }
|
||||
|
||||
GlobalValue::GUID getGUID() const { return Ref->first; }
|
||||
const GlobalValue *getValue() const { return Ref->second.GV; }
|
||||
|
||||
ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const {
|
||||
return Ref->second.SummaryList;
|
||||
}
|
||||
@ -88,9 +103,11 @@ template <> struct DenseMapInfo<ValueInfo> {
|
||||
static inline ValueInfo getEmptyKey() {
|
||||
return ValueInfo((GlobalValueSummaryMapTy::value_type *)-1);
|
||||
}
|
||||
|
||||
static inline ValueInfo getTombstoneKey() {
|
||||
return ValueInfo((GlobalValueSummaryMapTy::value_type *)-2);
|
||||
}
|
||||
|
||||
static bool isEqual(ValueInfo L, ValueInfo R) { return L.Ref == R.Ref; }
|
||||
static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.Ref; }
|
||||
};
|
||||
@ -138,7 +155,7 @@ private:
|
||||
/// This is the hash of the name of the symbol in the original file. It is
|
||||
/// identical to the GUID for global symbols, but differs for local since the
|
||||
/// GUID includes the module level id in the hash.
|
||||
GlobalValue::GUID OriginalName;
|
||||
GlobalValue::GUID OriginalName = 0;
|
||||
|
||||
/// \brief Path of module IR containing value's definition, used to locate
|
||||
/// module during importing.
|
||||
@ -157,7 +174,7 @@ private:
|
||||
|
||||
protected:
|
||||
GlobalValueSummary(SummaryKind K, GVFlags Flags, std::vector<ValueInfo> Refs)
|
||||
: Kind(K), Flags(Flags), OriginalName(0), RefEdgeList(std::move(Refs)) {}
|
||||
: Kind(K), Flags(Flags), RefEdgeList(std::move(Refs)) {}
|
||||
|
||||
public:
|
||||
virtual ~GlobalValueSummary() = default;
|
||||
@ -242,7 +259,7 @@ public:
|
||||
class FunctionSummary : public GlobalValueSummary {
|
||||
public:
|
||||
/// <CalleeValueInfo, CalleeInfo> call edge pair.
|
||||
typedef std::pair<ValueInfo, CalleeInfo> EdgeTy;
|
||||
using EdgeTy = std::pair<ValueInfo, CalleeInfo>;
|
||||
|
||||
/// An "identifier" for a virtual function. This contains the type identifier
|
||||
/// represented as a GUID and the offset from the address point to the virtual
|
||||
@ -376,12 +393,15 @@ public:
|
||||
|
||||
template <> struct DenseMapInfo<FunctionSummary::VFuncId> {
|
||||
static FunctionSummary::VFuncId getEmptyKey() { return {0, uint64_t(-1)}; }
|
||||
|
||||
static FunctionSummary::VFuncId getTombstoneKey() {
|
||||
return {0, uint64_t(-2)};
|
||||
}
|
||||
|
||||
static bool isEqual(FunctionSummary::VFuncId L, FunctionSummary::VFuncId R) {
|
||||
return L.GUID == R.GUID && L.Offset == R.Offset;
|
||||
}
|
||||
|
||||
static unsigned getHashValue(FunctionSummary::VFuncId I) { return I.GUID; }
|
||||
};
|
||||
|
||||
@ -389,14 +409,17 @@ template <> struct DenseMapInfo<FunctionSummary::ConstVCall> {
|
||||
static FunctionSummary::ConstVCall getEmptyKey() {
|
||||
return {{0, uint64_t(-1)}, {}};
|
||||
}
|
||||
|
||||
static FunctionSummary::ConstVCall getTombstoneKey() {
|
||||
return {{0, uint64_t(-2)}, {}};
|
||||
}
|
||||
|
||||
static bool isEqual(FunctionSummary::ConstVCall L,
|
||||
FunctionSummary::ConstVCall R) {
|
||||
return DenseMapInfo<FunctionSummary::VFuncId>::isEqual(L.VFunc, R.VFunc) &&
|
||||
L.Args == R.Args;
|
||||
}
|
||||
|
||||
static unsigned getHashValue(FunctionSummary::ConstVCall I) {
|
||||
return I.VFunc.GUID;
|
||||
}
|
||||
@ -477,20 +500,20 @@ struct TypeIdSummary {
|
||||
};
|
||||
|
||||
/// 160 bits SHA1
|
||||
typedef std::array<uint32_t, 5> ModuleHash;
|
||||
using ModuleHash = std::array<uint32_t, 5>;
|
||||
|
||||
/// Type used for iterating through the global value summary map.
|
||||
typedef GlobalValueSummaryMapTy::const_iterator const_gvsummary_iterator;
|
||||
typedef GlobalValueSummaryMapTy::iterator gvsummary_iterator;
|
||||
using const_gvsummary_iterator = GlobalValueSummaryMapTy::const_iterator;
|
||||
using gvsummary_iterator = GlobalValueSummaryMapTy::iterator;
|
||||
|
||||
/// String table to hold/own module path strings, which additionally holds the
|
||||
/// module ID assigned to each module during the plugin step, as well as a hash
|
||||
/// of the module. The StringMap makes a copy of and owns inserted strings.
|
||||
typedef StringMap<std::pair<uint64_t, ModuleHash>> ModulePathStringTableTy;
|
||||
using ModulePathStringTableTy = StringMap<std::pair<uint64_t, ModuleHash>>;
|
||||
|
||||
/// Map of global value GUID to its summary, used to identify values defined in
|
||||
/// a particular module, and provide efficient access to their summary.
|
||||
typedef std::map<GlobalValue::GUID, GlobalValueSummary *> GVSummaryMapTy;
|
||||
using GVSummaryMapTy = std::map<GlobalValue::GUID, GlobalValueSummary *>;
|
||||
|
||||
/// Class to hold module path string table and global value map,
|
||||
/// and encapsulate methods for operating on them.
|
||||
@ -697,6 +720,6 @@ public:
|
||||
StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_IR_MODULESUMMARYINDEX_H
|
||||
|
@ -39,8 +39,8 @@
|
||||
#define LLVM_IR_PASSMANAGER_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/TinyPtrVector.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
@ -48,9 +48,15 @@
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/TypeName.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
@ -469,15 +475,16 @@ public:
|
||||
}
|
||||
|
||||
template <typename PassT> void addPass(PassT Pass) {
|
||||
typedef detail::PassModel<IRUnitT, PassT, PreservedAnalyses,
|
||||
AnalysisManagerT, ExtraArgTs...>
|
||||
PassModelT;
|
||||
using PassModelT =
|
||||
detail::PassModel<IRUnitT, PassT, PreservedAnalyses, AnalysisManagerT,
|
||||
ExtraArgTs...>;
|
||||
|
||||
Passes.emplace_back(new PassModelT(std::move(Pass)));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>
|
||||
PassConceptT;
|
||||
using PassConceptT =
|
||||
detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
|
||||
|
||||
std::vector<std::unique_ptr<PassConceptT>> Passes;
|
||||
|
||||
@ -486,12 +493,14 @@ private:
|
||||
};
|
||||
|
||||
extern template class PassManager<Module>;
|
||||
|
||||
/// \brief Convenience typedef for a pass manager over modules.
|
||||
typedef PassManager<Module> ModulePassManager;
|
||||
using ModulePassManager = PassManager<Module>;
|
||||
|
||||
extern template class PassManager<Function>;
|
||||
|
||||
/// \brief Convenience typedef for a pass manager over functions.
|
||||
typedef PassManager<Function> FunctionPassManager;
|
||||
using FunctionPassManager = PassManager<Function>;
|
||||
|
||||
/// \brief A container for analyses that lazily runs them and caches their
|
||||
/// results.
|
||||
@ -504,11 +513,11 @@ public:
|
||||
|
||||
private:
|
||||
// Now that we've defined our invalidator, we can define the concept types.
|
||||
typedef detail::AnalysisResultConcept<IRUnitT, PreservedAnalyses, Invalidator>
|
||||
ResultConceptT;
|
||||
typedef detail::AnalysisPassConcept<IRUnitT, PreservedAnalyses, Invalidator,
|
||||
ExtraArgTs...>
|
||||
PassConceptT;
|
||||
using ResultConceptT =
|
||||
detail::AnalysisResultConcept<IRUnitT, PreservedAnalyses, Invalidator>;
|
||||
using PassConceptT =
|
||||
detail::AnalysisPassConcept<IRUnitT, PreservedAnalyses, Invalidator,
|
||||
ExtraArgTs...>;
|
||||
|
||||
/// \brief List of analysis pass IDs and associated concept pointers.
|
||||
///
|
||||
@ -516,18 +525,18 @@ private:
|
||||
/// erases. Provides the analysis ID to enable finding iterators to a given
|
||||
/// entry in maps below, and provides the storage for the actual result
|
||||
/// concept.
|
||||
typedef std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>
|
||||
AnalysisResultListT;
|
||||
using AnalysisResultListT =
|
||||
std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
|
||||
|
||||
/// \brief Map type from IRUnitT pointer to our custom list type.
|
||||
typedef DenseMap<IRUnitT *, AnalysisResultListT> AnalysisResultListMapT;
|
||||
using AnalysisResultListMapT = DenseMap<IRUnitT *, AnalysisResultListT>;
|
||||
|
||||
/// \brief Map type from a pair of analysis ID and IRUnitT pointer to an
|
||||
/// iterator into a particular result list (which is where the actual analysis
|
||||
/// result is stored).
|
||||
typedef DenseMap<std::pair<AnalysisKey *, IRUnitT *>,
|
||||
typename AnalysisResultListT::iterator>
|
||||
AnalysisResultMapT;
|
||||
using AnalysisResultMapT =
|
||||
DenseMap<std::pair<AnalysisKey *, IRUnitT *>,
|
||||
typename AnalysisResultListT::iterator>;
|
||||
|
||||
public:
|
||||
/// API to communicate dependencies between analyses during invalidation.
|
||||
@ -558,10 +567,10 @@ public:
|
||||
/// dependecies on it will become invalid as a result.
|
||||
template <typename PassT>
|
||||
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
|
||||
typedef detail::AnalysisResultModel<IRUnitT, PassT,
|
||||
typename PassT::Result,
|
||||
PreservedAnalyses, Invalidator>
|
||||
ResultModelT;
|
||||
using ResultModelT =
|
||||
detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
|
||||
PreservedAnalyses, Invalidator>;
|
||||
|
||||
return invalidateImpl<ResultModelT>(PassT::ID(), IR, PA);
|
||||
}
|
||||
|
||||
@ -672,9 +681,11 @@ public:
|
||||
"This analysis pass was not registered prior to being queried");
|
||||
ResultConceptT &ResultConcept =
|
||||
getResultImpl(PassT::ID(), IR, ExtraArgs...);
|
||||
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
|
||||
PreservedAnalyses, Invalidator>
|
||||
ResultModelT;
|
||||
|
||||
using ResultModelT =
|
||||
detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
|
||||
PreservedAnalyses, Invalidator>;
|
||||
|
||||
return static_cast<ResultModelT &>(ResultConcept).Result;
|
||||
}
|
||||
|
||||
@ -692,9 +703,10 @@ public:
|
||||
if (!ResultConcept)
|
||||
return nullptr;
|
||||
|
||||
typedef detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
|
||||
PreservedAnalyses, Invalidator>
|
||||
ResultModelT;
|
||||
using ResultModelT =
|
||||
detail::AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
|
||||
PreservedAnalyses, Invalidator>;
|
||||
|
||||
return &static_cast<ResultModelT *>(ResultConcept)->Result;
|
||||
}
|
||||
|
||||
@ -717,10 +729,10 @@ public:
|
||||
/// hashtable.)
|
||||
template <typename PassBuilderT>
|
||||
bool registerPass(PassBuilderT &&PassBuilder) {
|
||||
typedef decltype(PassBuilder()) PassT;
|
||||
typedef detail::AnalysisPassModel<IRUnitT, PassT, PreservedAnalyses,
|
||||
Invalidator, ExtraArgTs...>
|
||||
PassModelT;
|
||||
using PassT = decltype(PassBuilder());
|
||||
using PassModelT =
|
||||
detail::AnalysisPassModel<IRUnitT, PassT, PreservedAnalyses,
|
||||
Invalidator, ExtraArgTs...>;
|
||||
|
||||
auto &PassPtr = AnalysisPasses[PassT::ID()];
|
||||
if (PassPtr)
|
||||
@ -876,7 +888,8 @@ private:
|
||||
}
|
||||
|
||||
/// \brief Map type from module analysis pass ID to pass concept pointer.
|
||||
typedef DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>> AnalysisPassMapT;
|
||||
using AnalysisPassMapT =
|
||||
DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
|
||||
|
||||
/// \brief Collection of module analysis passes, indexed by ID.
|
||||
AnalysisPassMapT AnalysisPasses;
|
||||
@ -896,12 +909,14 @@ private:
|
||||
};
|
||||
|
||||
extern template class AnalysisManager<Module>;
|
||||
|
||||
/// \brief Convenience typedef for the Module analysis manager.
|
||||
typedef AnalysisManager<Module> ModuleAnalysisManager;
|
||||
using ModuleAnalysisManager = AnalysisManager<Module>;
|
||||
|
||||
extern template class AnalysisManager<Function>;
|
||||
|
||||
/// \brief Convenience typedef for the Function analysis manager.
|
||||
typedef AnalysisManager<Function> FunctionAnalysisManager;
|
||||
using FunctionAnalysisManager = AnalysisManager<Function>;
|
||||
|
||||
/// \brief An analysis over an "outer" IR unit that provides access to an
|
||||
/// analysis manager over an "inner" IR unit. The inner unit must be contained
|
||||
@ -927,20 +942,14 @@ public:
|
||||
class Result {
|
||||
public:
|
||||
explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
|
||||
|
||||
Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)) {
|
||||
// We have to null out the analysis manager in the moved-from state
|
||||
// because we are taking ownership of the responsibilty to clear the
|
||||
// analysis state.
|
||||
Arg.InnerAM = nullptr;
|
||||
}
|
||||
Result &operator=(Result &&RHS) {
|
||||
InnerAM = RHS.InnerAM;
|
||||
// We have to null out the analysis manager in the moved-from state
|
||||
// because we are taking ownership of the responsibilty to clear the
|
||||
// analysis state.
|
||||
RHS.InnerAM = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Result() {
|
||||
// InnerAM is cleared in a moved from state where there is nothing to do.
|
||||
if (!InnerAM)
|
||||
@ -951,6 +960,15 @@ public:
|
||||
InnerAM->clear();
|
||||
}
|
||||
|
||||
Result &operator=(Result &&RHS) {
|
||||
InnerAM = RHS.InnerAM;
|
||||
// We have to null out the analysis manager in the moved-from state
|
||||
// because we are taking ownership of the responsibilty to clear the
|
||||
// analysis state.
|
||||
RHS.InnerAM = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Accessor for the analysis manager.
|
||||
AnalysisManagerT &getManager() { return *InnerAM; }
|
||||
|
||||
@ -988,6 +1006,7 @@ public:
|
||||
private:
|
||||
friend AnalysisInfoMixin<
|
||||
InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>>;
|
||||
|
||||
static AnalysisKey Key;
|
||||
|
||||
AnalysisManagerT *InnerAM;
|
||||
@ -998,8 +1017,8 @@ AnalysisKey
|
||||
InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
|
||||
|
||||
/// Provide the \c FunctionAnalysisManager to \c Module proxy.
|
||||
typedef InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>
|
||||
FunctionAnalysisManagerModuleProxy;
|
||||
using FunctionAnalysisManagerModuleProxy =
|
||||
InnerAnalysisManagerProxy<FunctionAnalysisManager, Module>;
|
||||
|
||||
/// Specialization of the invalidate method for the \c
|
||||
/// FunctionAnalysisManagerModuleProxy's result.
|
||||
@ -1097,6 +1116,7 @@ public:
|
||||
private:
|
||||
friend AnalysisInfoMixin<
|
||||
OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>>;
|
||||
|
||||
static AnalysisKey Key;
|
||||
|
||||
const AnalysisManagerT *AM;
|
||||
@ -1109,8 +1129,8 @@ AnalysisKey
|
||||
extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
|
||||
Function>;
|
||||
/// Provide the \c ModuleAnalysisManager to \c Function proxy.
|
||||
typedef OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>
|
||||
ModuleAnalysisManagerFunctionProxy;
|
||||
using ModuleAnalysisManagerFunctionProxy =
|
||||
OuterAnalysisManagerProxy<ModuleAnalysisManager, Function>;
|
||||
|
||||
/// \brief Trivial adaptor that maps from a module to its functions.
|
||||
///
|
||||
@ -1274,6 +1294,6 @@ RepeatedPass<PassT> createRepeatedPass(int Count, PassT P) {
|
||||
return RepeatedPass<PassT>(Count, std::move(P));
|
||||
}
|
||||
|
||||
}
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_IR_PASSMANAGER_H
|
||||
|
@ -27,7 +27,6 @@ namespace llvm {
|
||||
|
||||
template <typename IRUnitT> class AllAnalysesOn;
|
||||
template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
|
||||
class Invalidator;
|
||||
class PreservedAnalyses;
|
||||
|
||||
/// \brief Implementation details of the pass manager interfaces.
|
||||
@ -116,7 +115,7 @@ struct AnalysisResultConcept {
|
||||
/// \brief SFINAE metafunction for computing whether \c ResultT provides an
|
||||
/// \c invalidate member function.
|
||||
template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
|
||||
typedef char EnabledType;
|
||||
using EnabledType = char;
|
||||
struct DisabledType {
|
||||
char a, b;
|
||||
};
|
||||
@ -124,7 +123,7 @@ template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
|
||||
// Purely to help out MSVC which fails to disable the below specialization,
|
||||
// explicitly enable using the result type's invalidate routine if we can
|
||||
// successfully call that routine.
|
||||
template <typename T> struct Nonce { typedef EnabledType Type; };
|
||||
template <typename T> struct Nonce { using Type = EnabledType; };
|
||||
template <typename T>
|
||||
static typename Nonce<decltype(std::declval<T>().invalidate(
|
||||
std::declval<IRUnitT &>(), std::declval<PreservedAnalyses>()))>::Type
|
||||
@ -280,9 +279,9 @@ struct AnalysisPassModel : AnalysisPassConcept<IRUnitT, PreservedAnalysesT,
|
||||
}
|
||||
|
||||
// FIXME: Replace PassT::Result with type traits when we use C++11.
|
||||
typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
|
||||
PreservedAnalysesT, InvalidatorT>
|
||||
ResultModelT;
|
||||
using ResultModelT =
|
||||
AnalysisResultModel<IRUnitT, PassT, typename PassT::Result,
|
||||
PreservedAnalysesT, InvalidatorT>;
|
||||
|
||||
/// \brief The model delegates to the \c PassT::run method.
|
||||
///
|
||||
|
@ -29,11 +29,19 @@
|
||||
#ifndef LLVM_IR_PATTERNMATCH_H
|
||||
#define LLVM_IR_PATTERNMATCH_H
|
||||
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Constant.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/InstrTypes.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
namespace PatternMatch {
|
||||
@ -172,7 +180,9 @@ inline match_nan m_NaN() { return match_nan(); }
|
||||
|
||||
struct apint_match {
|
||||
const APInt *&Res;
|
||||
|
||||
apint_match(const APInt *&R) : Res(R) {}
|
||||
|
||||
template <typename ITy> bool match(ITy *V) {
|
||||
if (auto *CI = dyn_cast<ConstantInt>(V)) {
|
||||
Res = &CI->getValue();
|
||||
@ -230,7 +240,9 @@ template <typename Predicate> struct cst_pred_ty : public Predicate {
|
||||
/// satisfy a specified predicate, and bind them to an APInt.
|
||||
template <typename Predicate> struct api_pred_ty : public Predicate {
|
||||
const APInt *&Res;
|
||||
|
||||
api_pred_ty(const APInt *&R) : Res(R) {}
|
||||
|
||||
template <typename ITy> bool match(ITy *V) {
|
||||
if (const auto *CI = dyn_cast<ConstantInt>(V))
|
||||
if (this->isValue(CI->getValue())) {
|
||||
@ -294,6 +306,7 @@ inline api_pred_ty<is_maxsignedvalue> m_MaxSignedValue(const APInt *&V) { return
|
||||
|
||||
template <typename Class> struct bind_ty {
|
||||
Class *&VR;
|
||||
|
||||
bind_ty(Class *&V) : VR(V) {}
|
||||
|
||||
template <typename ITy> bool match(ITy *V) {
|
||||
@ -326,6 +339,7 @@ inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; }
|
||||
/// \brief Match a specified Value*.
|
||||
struct specificval_ty {
|
||||
const Value *Val;
|
||||
|
||||
specificval_ty(const Value *V) : Val(V) {}
|
||||
|
||||
template <typename ITy> bool match(ITy *V) { return V == Val; }
|
||||
@ -338,6 +352,7 @@ inline specificval_ty m_Specific(const Value *V) { return V; }
|
||||
/// that value.
|
||||
struct specific_fpval {
|
||||
double Val;
|
||||
|
||||
specific_fpval(double V) : Val(V) {}
|
||||
|
||||
template <typename ITy> bool match(ITy *V) {
|
||||
@ -360,6 +375,7 @@ inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); }
|
||||
|
||||
struct bind_const_intval_ty {
|
||||
uint64_t &VR;
|
||||
|
||||
bind_const_intval_ty(uint64_t &V) : VR(V) {}
|
||||
|
||||
template <typename ITy> bool match(ITy *V) {
|
||||
@ -376,6 +392,7 @@ struct bind_const_intval_ty {
|
||||
// value.
|
||||
struct specific_intval {
|
||||
uint64_t Val;
|
||||
|
||||
specific_intval(uint64_t V) : Val(V) {}
|
||||
|
||||
template <typename ITy> bool match(ITy *V) {
|
||||
@ -939,6 +956,7 @@ template <typename LHS> inline fneg_match<LHS> m_FNeg(const LHS &L) {
|
||||
|
||||
struct br_match {
|
||||
BasicBlock *&Succ;
|
||||
|
||||
br_match(BasicBlock *&Succ) : Succ(Succ) {}
|
||||
|
||||
template <typename OpTy> bool match(OpTy *V) {
|
||||
@ -956,6 +974,7 @@ inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); }
|
||||
template <typename Cond_t> struct brc_match {
|
||||
Cond_t Cond;
|
||||
BasicBlock *&T, *&F;
|
||||
|
||||
brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
|
||||
: Cond(C), T(t), F(f) {}
|
||||
|
||||
@ -1202,6 +1221,7 @@ m_UnordFMin(const LHS &L, const RHS &R) {
|
||||
template <typename Opnd_t> struct Argument_match {
|
||||
unsigned OpI;
|
||||
Opnd_t Val;
|
||||
|
||||
Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) {}
|
||||
|
||||
template <typename OpTy> bool match(OpTy *V) {
|
||||
@ -1219,6 +1239,7 @@ inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) {
|
||||
/// \brief Intrinsic matchers.
|
||||
struct IntrinsicID_match {
|
||||
unsigned ID;
|
||||
|
||||
IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) {}
|
||||
|
||||
template <typename OpTy> bool match(OpTy *V) {
|
||||
@ -1239,21 +1260,23 @@ template <typename T0 = void, typename T1 = void, typename T2 = void,
|
||||
typename T9 = void, typename T10 = void>
|
||||
struct m_Intrinsic_Ty;
|
||||
template <typename T0> struct m_Intrinsic_Ty<T0> {
|
||||
typedef match_combine_and<IntrinsicID_match, Argument_match<T0>> Ty;
|
||||
using Ty = match_combine_and<IntrinsicID_match, Argument_match<T0>>;
|
||||
};
|
||||
template <typename T0, typename T1> struct m_Intrinsic_Ty<T0, T1> {
|
||||
typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>>
|
||||
Ty;
|
||||
using Ty =
|
||||
match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, Argument_match<T1>>;
|
||||
};
|
||||
template <typename T0, typename T1, typename T2>
|
||||
struct m_Intrinsic_Ty<T0, T1, T2> {
|
||||
typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
|
||||
Argument_match<T2>> Ty;
|
||||
using Ty =
|
||||
match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty,
|
||||
Argument_match<T2>>;
|
||||
};
|
||||
template <typename T0, typename T1, typename T2, typename T3>
|
||||
struct m_Intrinsic_Ty<T0, T1, T2, T3> {
|
||||
typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
|
||||
Argument_match<T3>> Ty;
|
||||
using Ty =
|
||||
match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty,
|
||||
Argument_match<T3>>;
|
||||
};
|
||||
|
||||
/// \brief Match intrinsic calls like this:
|
||||
@ -1437,4 +1460,4 @@ m_c_UMax(const LHS &L, const RHS &R) {
|
||||
} // end namespace PatternMatch
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_IR_PATTERNMATCH_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- ProfileSummary.h - Profile summary data structure. ------*- C++ -*-===//
|
||||
//===- ProfileSummary.h - Profile summary data structure. -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,21 +11,17 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PROFILE_SUMMARY_H
|
||||
#define LLVM_SUPPORT_PROFILE_SUMMARY_H
|
||||
#ifndef LLVM_IR_PROFILESUMMARY_H
|
||||
#define LLVM_IR_PROFILESUMMARY_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LLVMContext;
|
||||
class Metadata;
|
||||
class MDTuple;
|
||||
class MDNode;
|
||||
|
||||
// The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.
|
||||
// The semantics of counts depend on the type of profile. For instrumentation
|
||||
@ -37,12 +33,13 @@ struct ProfileSummaryEntry {
|
||||
uint32_t Cutoff; ///< The required percentile of counts.
|
||||
uint64_t MinCount; ///< The minimum count for this percentile.
|
||||
uint64_t NumCounts; ///< Number of counts >= the minimum count.
|
||||
|
||||
ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount,
|
||||
uint64_t TheNumCounts)
|
||||
: Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {}
|
||||
};
|
||||
|
||||
typedef std::vector<ProfileSummaryEntry> SummaryEntryVector;
|
||||
using SummaryEntryVector = std::vector<ProfileSummaryEntry>;
|
||||
|
||||
class ProfileSummary {
|
||||
public:
|
||||
@ -59,6 +56,7 @@ private:
|
||||
|
||||
public:
|
||||
static const int Scale = 1000000;
|
||||
|
||||
ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
|
||||
uint64_t TotalCount, uint64_t MaxCount,
|
||||
uint64_t MaxInternalCount, uint64_t MaxFunctionCount,
|
||||
@ -67,6 +65,7 @@ public:
|
||||
TotalCount(TotalCount), MaxCount(MaxCount),
|
||||
MaxInternalCount(MaxInternalCount), MaxFunctionCount(MaxFunctionCount),
|
||||
NumCounts(NumCounts), NumFunctions(NumFunctions) {}
|
||||
|
||||
Kind getKind() const { return PSK; }
|
||||
/// \brief Return summary information as metadata.
|
||||
Metadata *getMD(LLVMContext &Context);
|
||||
@ -82,4 +81,5 @@ public:
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
#endif
|
||||
|
||||
#endif // LLVM_IR_PROFILESUMMARY_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/IR/Statepoint.h - gc.statepoint utilities ----------*- C++ -*-===//
|
||||
//===- llvm/IR/Statepoint.h - gc.statepoint utilities -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -24,10 +24,12 @@
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Instruction.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@ -87,7 +89,7 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
typedef typename CallSiteTy::arg_iterator arg_iterator;
|
||||
using arg_iterator = typename CallSiteTy::arg_iterator;
|
||||
|
||||
enum {
|
||||
IDPos = 0,
|
||||
@ -300,8 +302,9 @@ public:
|
||||
class ImmutableStatepoint
|
||||
: public StatepointBase<const Function, const Instruction, const Value,
|
||||
ImmutableCallSite> {
|
||||
typedef StatepointBase<const Function, const Instruction, const Value,
|
||||
ImmutableCallSite> Base;
|
||||
using Base =
|
||||
StatepointBase<const Function, const Instruction, const Value,
|
||||
ImmutableCallSite>;
|
||||
|
||||
public:
|
||||
explicit ImmutableStatepoint(const Instruction *I) : Base(I) {}
|
||||
@ -312,7 +315,7 @@ public:
|
||||
/// to a gc.statepoint.
|
||||
class Statepoint
|
||||
: public StatepointBase<Function, Instruction, Value, CallSite> {
|
||||
typedef StatepointBase<Function, Instruction, Value, CallSite> Base;
|
||||
using Base = StatepointBase<Function, Instruction, Value, CallSite>;
|
||||
|
||||
public:
|
||||
explicit Statepoint(Instruction *I) : Base(I) {}
|
||||
@ -327,6 +330,7 @@ public:
|
||||
return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate ||
|
||||
I->getIntrinsicID() == Intrinsic::experimental_gc_result;
|
||||
}
|
||||
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
@ -369,6 +373,7 @@ public:
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
|
||||
}
|
||||
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
@ -403,6 +408,7 @@ public:
|
||||
static inline bool classof(const IntrinsicInst *I) {
|
||||
return I->getIntrinsicID() == Intrinsic::experimental_gc_result;
|
||||
}
|
||||
|
||||
static inline bool classof(const Value *V) {
|
||||
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class ValueSymbolTable;
|
||||
template <typename NodeTy> struct SymbolTableListParentType {};
|
||||
|
||||
#define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \
|
||||
template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; };
|
||||
template <> struct SymbolTableListParentType<NODE> { using type = PARENT; };
|
||||
DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
|
||||
DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
|
||||
DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
|
||||
@ -65,10 +65,10 @@ template <typename NodeTy> class SymbolTableList;
|
||||
//
|
||||
template <typename ValueSubClass>
|
||||
class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> {
|
||||
typedef SymbolTableList<ValueSubClass> ListTy;
|
||||
typedef typename simple_ilist<ValueSubClass>::iterator iterator;
|
||||
typedef
|
||||
typename SymbolTableListParentType<ValueSubClass>::type ItemParentClass;
|
||||
using ListTy = SymbolTableList<ValueSubClass>;
|
||||
using iterator = typename simple_ilist<ValueSubClass>::iterator;
|
||||
using ItemParentClass =
|
||||
typename SymbolTableListParentType<ValueSubClass>::type;
|
||||
|
||||
public:
|
||||
SymbolTableListTraits() = default;
|
||||
|
@ -139,31 +139,35 @@ public:
|
||||
bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); }
|
||||
};
|
||||
|
||||
typedef TypedTrackingMDRef<MDNode> TrackingMDNodeRef;
|
||||
typedef TypedTrackingMDRef<ValueAsMetadata> TrackingValueAsMetadataRef;
|
||||
using TrackingMDNodeRef = TypedTrackingMDRef<MDNode>;
|
||||
using TrackingValueAsMetadataRef = TypedTrackingMDRef<ValueAsMetadata>;
|
||||
|
||||
// Expose the underlying metadata to casting.
|
||||
template <> struct simplify_type<TrackingMDRef> {
|
||||
typedef Metadata *SimpleType;
|
||||
using SimpleType = Metadata *;
|
||||
|
||||
static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); }
|
||||
};
|
||||
|
||||
template <> struct simplify_type<const TrackingMDRef> {
|
||||
typedef Metadata *SimpleType;
|
||||
using SimpleType = Metadata *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const TrackingMDRef &MD) {
|
||||
return MD.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct simplify_type<TypedTrackingMDRef<T>> {
|
||||
typedef T *SimpleType;
|
||||
using SimpleType = T *;
|
||||
|
||||
static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) {
|
||||
return MD.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> struct simplify_type<const TypedTrackingMDRef<T>> {
|
||||
typedef T *SimpleType;
|
||||
using SimpleType = T *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) {
|
||||
return MD.get();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
|
||||
//===- llvm/Type.h - Classes for handling data types ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -18,21 +18,22 @@
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class PointerType;
|
||||
class IntegerType;
|
||||
class raw_ostream;
|
||||
class Module;
|
||||
class LLVMContext;
|
||||
class LLVMContextImpl;
|
||||
class StringRef;
|
||||
template<class GraphType> struct GraphTraits;
|
||||
class IntegerType;
|
||||
class LLVMContext;
|
||||
class PointerType;
|
||||
class raw_ostream;
|
||||
class StringRef;
|
||||
|
||||
/// The instances of the Type class are immutable: once they are created,
|
||||
/// they are never changed. Also note that only one instance of a particular
|
||||
@ -86,9 +87,9 @@ private:
|
||||
|
||||
protected:
|
||||
friend class LLVMContextImpl;
|
||||
|
||||
explicit Type(LLVMContext &C, TypeID tid)
|
||||
: Context(C), ID(tid), SubclassData(0),
|
||||
NumContainedTys(0), ContainedTys(nullptr) {}
|
||||
: Context(C), ID(tid), SubclassData(0) {}
|
||||
~Type() = default;
|
||||
|
||||
unsigned getSubclassData() const { return SubclassData; }
|
||||
@ -100,14 +101,14 @@ protected:
|
||||
}
|
||||
|
||||
/// Keeps track of how many Type*'s there are in the ContainedTys list.
|
||||
unsigned NumContainedTys;
|
||||
unsigned NumContainedTys = 0;
|
||||
|
||||
/// A pointer to the array of Types contained by this Type. For example, this
|
||||
/// includes the arguments of a function type, the elements of a structure,
|
||||
/// the pointee of a pointer, the element type of an array, etc. This pointer
|
||||
/// may be 0 for types that don't contain other types (Integer, Double,
|
||||
/// Float).
|
||||
Type * const *ContainedTys;
|
||||
Type * const *ContainedTys = nullptr;
|
||||
|
||||
static bool isSequentialType(TypeID TyID) {
|
||||
return TyID == ArrayTyID || TyID == VectorTyID;
|
||||
@ -122,6 +123,7 @@ public:
|
||||
/// inlined with the operands when printing an instruction.
|
||||
void print(raw_ostream &O, bool IsForDebug = false,
|
||||
bool NoDetails = false) const;
|
||||
|
||||
void dump() const;
|
||||
|
||||
/// Return the LLVMContext in which this type was uniqued.
|
||||
@ -299,14 +301,16 @@ public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Iteration support.
|
||||
//
|
||||
typedef Type * const *subtype_iterator;
|
||||
using subtype_iterator = Type * const *;
|
||||
|
||||
subtype_iterator subtype_begin() const { return ContainedTys; }
|
||||
subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
|
||||
ArrayRef<Type*> subtypes() const {
|
||||
return makeArrayRef(subtype_begin(), subtype_end());
|
||||
}
|
||||
|
||||
typedef std::reverse_iterator<subtype_iterator> subtype_reverse_iterator;
|
||||
using subtype_reverse_iterator = std::reverse_iterator<subtype_iterator>;
|
||||
|
||||
subtype_reverse_iterator subtype_rbegin() const {
|
||||
return subtype_reverse_iterator(subtype_end());
|
||||
}
|
||||
@ -348,6 +352,7 @@ public:
|
||||
}
|
||||
|
||||
inline uint64_t getArrayNumElements() const;
|
||||
|
||||
Type *getArrayElementType() const {
|
||||
assert(getTypeID() == ArrayTyID);
|
||||
return ContainedTys[0];
|
||||
@ -444,8 +449,8 @@ template <> struct isa_impl<PointerType, Type> {
|
||||
// graph of sub types.
|
||||
|
||||
template <> struct GraphTraits<Type *> {
|
||||
typedef Type *NodeRef;
|
||||
typedef Type::subtype_iterator ChildIteratorType;
|
||||
using NodeRef = Type *;
|
||||
using ChildIteratorType = Type::subtype_iterator;
|
||||
|
||||
static NodeRef getEntryNode(Type *T) { return T; }
|
||||
static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); }
|
||||
@ -453,8 +458,8 @@ template <> struct GraphTraits<Type *> {
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<const Type*> {
|
||||
typedef const Type *NodeRef;
|
||||
typedef Type::subtype_iterator ChildIteratorType;
|
||||
using NodeRef = const Type *;
|
||||
using ChildIteratorType = Type::subtype_iterator;
|
||||
|
||||
static NodeRef getEntryNode(NodeRef T) { return T; }
|
||||
static ChildIteratorType child_begin(NodeRef N) { return N->subtype_begin(); }
|
||||
@ -474,6 +479,6 @@ inline LLVMTypeRef *wrap(Type **Tys) {
|
||||
return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_IR_TYPE_H
|
||||
|
@ -44,8 +44,8 @@ public:
|
||||
void run(const Module &M, bool onlyNamed);
|
||||
void clear();
|
||||
|
||||
typedef std::vector<StructType*>::iterator iterator;
|
||||
typedef std::vector<StructType*>::const_iterator const_iterator;
|
||||
using iterator = std::vector<StructType*>::iterator;
|
||||
using const_iterator = std::vector<StructType*>::const_iterator;
|
||||
|
||||
iterator begin() { return StructTypes.begin(); }
|
||||
iterator end() { return StructTypes.end(); }
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Use.h - Definition of the Use class ----------------*- C++ -*-===//
|
||||
//===- llvm/Use.h - Definition of the Use class -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -27,14 +27,14 @@
|
||||
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/CBindingWrapping.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm-c/Types.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Value;
|
||||
class User;
|
||||
class Use;
|
||||
template <typename> struct simplify_type;
|
||||
class User;
|
||||
class Value;
|
||||
|
||||
/// \brief A Use represents the edge between a Value definition and its users.
|
||||
///
|
||||
@ -65,23 +65,27 @@ public:
|
||||
/// use the LSB regardless of pointer alignment on different targets.
|
||||
struct UserRefPointerTraits {
|
||||
static inline void *getAsVoidPointer(User *P) { return P; }
|
||||
|
||||
static inline User *getFromVoidPointer(void *P) {
|
||||
return (User *)P;
|
||||
}
|
||||
|
||||
enum { NumLowBitsAvailable = 1 };
|
||||
};
|
||||
|
||||
// A type for the word following an array of hung-off Uses in memory, which is
|
||||
// a pointer back to their User with the bottom bit set.
|
||||
typedef PointerIntPair<User *, 1, unsigned, UserRefPointerTraits> UserRef;
|
||||
using UserRef = PointerIntPair<User *, 1, unsigned, UserRefPointerTraits>;
|
||||
|
||||
/// Pointer traits for the Prev PointerIntPair. This ensures we always use
|
||||
/// the two LSBs regardless of pointer alignment on different targets.
|
||||
struct PrevPointerTraits {
|
||||
static inline void *getAsVoidPointer(Use **P) { return P; }
|
||||
|
||||
static inline Use **getFromVoidPointer(void *P) {
|
||||
return (Use **)P;
|
||||
}
|
||||
|
||||
enum { NumLowBitsAvailable = 2 };
|
||||
};
|
||||
|
||||
@ -95,9 +99,11 @@ private:
|
||||
enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag };
|
||||
|
||||
/// Constructor
|
||||
Use(PrevPtrTag tag) : Val(nullptr) { Prev.setInt(tag); }
|
||||
Use(PrevPtrTag tag) { Prev.setInt(tag); }
|
||||
|
||||
public:
|
||||
friend class Value;
|
||||
|
||||
operator Value *() const { return Val; }
|
||||
Value *get() const { return Val; }
|
||||
|
||||
@ -133,7 +139,7 @@ public:
|
||||
private:
|
||||
const Use *getImpliedUser() const LLVM_READONLY;
|
||||
|
||||
Value *Val;
|
||||
Value *Val = nullptr;
|
||||
Use *Next;
|
||||
PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev;
|
||||
|
||||
@ -153,18 +159,18 @@ private:
|
||||
if (Next)
|
||||
Next->setPrev(StrippedPrev);
|
||||
}
|
||||
|
||||
friend class Value;
|
||||
};
|
||||
|
||||
/// \brief Allow clients to treat uses just like values when using
|
||||
/// casting operators.
|
||||
template <> struct simplify_type<Use> {
|
||||
typedef Value *SimpleType;
|
||||
using SimpleType = Value *;
|
||||
|
||||
static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); }
|
||||
};
|
||||
template <> struct simplify_type<const Use> {
|
||||
typedef /*const*/ Value *SimpleType;
|
||||
using SimpleType = /*const*/ Value *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); }
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@ struct UseListOrder {
|
||||
UseListOrder &operator=(UseListOrder &&) = default;
|
||||
};
|
||||
|
||||
typedef std::vector<UseListOrder> UseListOrderStack;
|
||||
using UseListOrderStack = std::vector<UseListOrder>;
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/User.h - User class definition ---------------------*- C++ -*-===//
|
||||
//===- llvm/User.h - User class definition ----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -114,6 +114,7 @@ protected:
|
||||
? OperandTraits<U>::op_end(const_cast<U*>(that))[Idx]
|
||||
: OperandTraits<U>::op_begin(const_cast<U*>(that))[Idx];
|
||||
}
|
||||
|
||||
template <int Idx> Use &Op() {
|
||||
return OpFrom<Idx>(this);
|
||||
}
|
||||
@ -205,10 +206,10 @@ public:
|
||||
// ---------------------------------------------------------------------------
|
||||
// Operand Iterator interface...
|
||||
//
|
||||
typedef Use* op_iterator;
|
||||
typedef const Use* const_op_iterator;
|
||||
typedef iterator_range<op_iterator> op_range;
|
||||
typedef iterator_range<const_op_iterator> const_op_range;
|
||||
using op_iterator = Use*;
|
||||
using const_op_iterator = const Use*;
|
||||
using op_range = iterator_range<op_iterator>;
|
||||
using const_op_range = iterator_range<const_op_iterator>;
|
||||
|
||||
op_iterator op_begin() { return getOperandList(); }
|
||||
const_op_iterator op_begin() const { return getOperandList(); }
|
||||
@ -252,6 +253,7 @@ public:
|
||||
ptrdiff_t, const Value *, const Value *> {
|
||||
explicit const_value_op_iterator(const Use *U = nullptr) :
|
||||
iterator_adaptor_base(U) {}
|
||||
|
||||
const Value *operator*() const { return *I; }
|
||||
const Value *operator->() const { return operator*(); }
|
||||
};
|
||||
@ -290,6 +292,7 @@ public:
|
||||
return isa<Instruction>(V) || isa<Constant>(V);
|
||||
}
|
||||
};
|
||||
|
||||
// Either Use objects, or a Use pointer can be prepended to User.
|
||||
static_assert(alignof(Use) >= alignof(User),
|
||||
"Alignment is insufficient after objects prepended to User");
|
||||
@ -297,13 +300,15 @@ static_assert(alignof(Use *) >= alignof(User),
|
||||
"Alignment is insufficient after objects prepended to User");
|
||||
|
||||
template<> struct simplify_type<User::op_iterator> {
|
||||
typedef Value* SimpleType;
|
||||
using SimpleType = Value*;
|
||||
|
||||
static SimpleType getSimplifiedValue(User::op_iterator &Val) {
|
||||
return Val->get();
|
||||
}
|
||||
};
|
||||
template<> struct simplify_type<User::const_op_iterator> {
|
||||
typedef /*const*/ Value* SimpleType;
|
||||
using SimpleType = /*const*/ Value*;
|
||||
|
||||
static SimpleType getSimplifiedValue(User::const_op_iterator &Val) {
|
||||
return Val->get();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Value.h - Definition of the Value class ------------*- C++ -*-===//
|
||||
//===- llvm/Value.h - Definition of the Value class -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -44,12 +44,12 @@ class LLVMContext;
|
||||
class Module;
|
||||
class ModuleSlotTracker;
|
||||
class raw_ostream;
|
||||
template<typename ValueTy> class StringMapEntry;
|
||||
class StringRef;
|
||||
class Twine;
|
||||
class Type;
|
||||
|
||||
template<typename ValueTy> class StringMapEntry;
|
||||
typedef StringMapEntry<Value*> ValueName;
|
||||
using ValueName = StringMapEntry<Value*>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Value Class
|
||||
@ -120,10 +120,12 @@ private:
|
||||
template <typename UseT> // UseT == 'Use' or 'const Use'
|
||||
class use_iterator_impl
|
||||
: public std::iterator<std::forward_iterator_tag, UseT *> {
|
||||
UseT *U;
|
||||
explicit use_iterator_impl(UseT *u) : U(u) {}
|
||||
friend class Value;
|
||||
|
||||
UseT *U;
|
||||
|
||||
explicit use_iterator_impl(UseT *u) : U(u) {}
|
||||
|
||||
public:
|
||||
use_iterator_impl() : U() {}
|
||||
|
||||
@ -309,8 +311,9 @@ public:
|
||||
return UseList == nullptr;
|
||||
}
|
||||
|
||||
typedef use_iterator_impl<Use> use_iterator;
|
||||
typedef use_iterator_impl<const Use> const_use_iterator;
|
||||
using use_iterator = use_iterator_impl<Use>;
|
||||
using const_use_iterator = use_iterator_impl<const Use>;
|
||||
|
||||
use_iterator materialized_use_begin() { return use_iterator(UseList); }
|
||||
const_use_iterator materialized_use_begin() const {
|
||||
return const_use_iterator(UseList);
|
||||
@ -345,8 +348,9 @@ public:
|
||||
return UseList == nullptr;
|
||||
}
|
||||
|
||||
typedef user_iterator_impl<User> user_iterator;
|
||||
typedef user_iterator_impl<const User> const_user_iterator;
|
||||
using user_iterator = user_iterator_impl<User>;
|
||||
using const_user_iterator = user_iterator_impl<const User>;
|
||||
|
||||
user_iterator materialized_user_begin() { return user_iterator(UseList); }
|
||||
const_user_iterator materialized_user_begin() const {
|
||||
return const_user_iterator(UseList);
|
||||
@ -560,7 +564,6 @@ public:
|
||||
/// block.
|
||||
const Value *DoPHITranslation(const BasicBlock *CurBB,
|
||||
const BasicBlock *PredBB) const;
|
||||
|
||||
Value *DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) {
|
||||
return const_cast<Value *>(
|
||||
static_cast<const Value *>(this)->DoPHITranslation(CurBB, PredBB));
|
||||
@ -606,7 +609,7 @@ private:
|
||||
Use *Merged;
|
||||
Use **Next = &Merged;
|
||||
|
||||
for (;;) {
|
||||
while (true) {
|
||||
if (!L) {
|
||||
*Next = R;
|
||||
break;
|
||||
|
@ -17,10 +17,10 @@
|
||||
#include "llvm/ADT/DenseMapInfo.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/IR/Value.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
class ValueHandleBase;
|
||||
template<typename From> struct simplify_type;
|
||||
|
||||
/// \brief This is the common base class of value handles.
|
||||
///
|
||||
@ -29,6 +29,7 @@ template<typename From> struct simplify_type;
|
||||
/// below for details.
|
||||
class ValueHandleBase {
|
||||
friend class Value;
|
||||
|
||||
protected:
|
||||
/// \brief This indicates what sub class the handle actually is.
|
||||
///
|
||||
@ -40,24 +41,23 @@ protected:
|
||||
: ValueHandleBase(RHS.PrevPair.getInt(), RHS) {}
|
||||
|
||||
ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), Val(RHS.getValPtr()) {
|
||||
: PrevPair(nullptr, Kind), Val(RHS.getValPtr()) {
|
||||
if (isValid(getValPtr()))
|
||||
AddToExistingUseList(RHS.getPrevPtr());
|
||||
}
|
||||
|
||||
private:
|
||||
PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
|
||||
ValueHandleBase *Next;
|
||||
|
||||
Value *Val;
|
||||
ValueHandleBase *Next = nullptr;
|
||||
Value *Val = nullptr;
|
||||
|
||||
void setValPtr(Value *V) { Val = V; }
|
||||
|
||||
public:
|
||||
explicit ValueHandleBase(HandleBaseKind Kind)
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), Val(nullptr) {}
|
||||
: PrevPair(nullptr, Kind) {}
|
||||
ValueHandleBase(HandleBaseKind Kind, Value *V)
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), Val(V) {
|
||||
: PrevPair(nullptr, Kind), Val(V) {
|
||||
if (isValid(getValPtr()))
|
||||
AddToUseList();
|
||||
}
|
||||
@ -162,11 +162,13 @@ public:
|
||||
// Specialize simplify_type to allow WeakVH to participate in
|
||||
// dyn_cast, isa, etc.
|
||||
template <> struct simplify_type<WeakVH> {
|
||||
typedef Value *SimpleType;
|
||||
using SimpleType = Value *;
|
||||
|
||||
static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; }
|
||||
};
|
||||
template <> struct simplify_type<const WeakVH> {
|
||||
typedef Value *SimpleType;
|
||||
using SimpleType = Value *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
|
||||
};
|
||||
|
||||
@ -205,11 +207,13 @@ public:
|
||||
// Specialize simplify_type to allow WeakTrackingVH to participate in
|
||||
// dyn_cast, isa, etc.
|
||||
template <> struct simplify_type<WeakTrackingVH> {
|
||||
typedef Value *SimpleType;
|
||||
using SimpleType = Value *;
|
||||
|
||||
static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; }
|
||||
};
|
||||
template <> struct simplify_type<const WeakTrackingVH> {
|
||||
typedef Value *SimpleType;
|
||||
using SimpleType = Value *;
|
||||
|
||||
static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) {
|
||||
return WVH;
|
||||
}
|
||||
@ -236,7 +240,7 @@ class AssertingVH
|
||||
: public ValueHandleBase
|
||||
#endif
|
||||
{
|
||||
friend struct DenseMapInfo<AssertingVH<ValueTy> >;
|
||||
friend struct DenseMapInfo<AssertingVH<ValueTy>>;
|
||||
|
||||
#ifndef NDEBUG
|
||||
Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
|
||||
@ -282,20 +286,23 @@ public:
|
||||
|
||||
// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
|
||||
template<typename T>
|
||||
struct DenseMapInfo<AssertingVH<T> > {
|
||||
struct DenseMapInfo<AssertingVH<T>> {
|
||||
static inline AssertingVH<T> getEmptyKey() {
|
||||
AssertingVH<T> Res;
|
||||
Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey());
|
||||
return Res;
|
||||
}
|
||||
|
||||
static inline AssertingVH<T> getTombstoneKey() {
|
||||
AssertingVH<T> Res;
|
||||
Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey());
|
||||
return Res;
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const AssertingVH<T> &Val) {
|
||||
return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr());
|
||||
}
|
||||
|
||||
static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
|
||||
return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(),
|
||||
RHS.getRawValPtr());
|
||||
@ -303,7 +310,7 @@ struct DenseMapInfo<AssertingVH<T> > {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct isPodLike<AssertingVH<T> > {
|
||||
struct isPodLike<AssertingVH<T>> {
|
||||
#ifdef NDEBUG
|
||||
static const bool value = true;
|
||||
#else
|
||||
@ -356,7 +363,7 @@ public:
|
||||
static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
|
||||
|
||||
public:
|
||||
TrackingVH() {}
|
||||
TrackingVH() = default;
|
||||
TrackingVH(ValueTy *P) { setValPtr(P); }
|
||||
|
||||
operator ValueTy*() const {
|
||||
@ -495,10 +502,12 @@ public:
|
||||
PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {}
|
||||
PoisoningVH(const PoisoningVH &RHS)
|
||||
: CallbackVH(RHS), Poisoned(RHS.Poisoned) {}
|
||||
|
||||
~PoisoningVH() {
|
||||
if (Poisoned)
|
||||
clearValPtr();
|
||||
}
|
||||
|
||||
PoisoningVH &operator=(const PoisoningVH &RHS) {
|
||||
if (Poisoned)
|
||||
clearValPtr();
|
||||
@ -523,14 +532,17 @@ template <typename T> struct DenseMapInfo<PoisoningVH<T>> {
|
||||
Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey());
|
||||
return Res;
|
||||
}
|
||||
|
||||
static inline PoisoningVH<T> getTombstoneKey() {
|
||||
PoisoningVH<T> Res;
|
||||
Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey());
|
||||
return Res;
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const PoisoningVH<T> &Val) {
|
||||
return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr());
|
||||
}
|
||||
|
||||
static bool isEqual(const PoisoningVH<T> &LHS, const PoisoningVH<T> &RHS) {
|
||||
return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(),
|
||||
RHS.getRawValPtr());
|
||||
@ -545,6 +557,6 @@ template <typename T> struct isPodLike<PoisoningVH<T>> {
|
||||
#endif
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_IR_VALUEHANDLE_H
|
||||
|
@ -46,7 +46,6 @@ namespace llvm {
|
||||
|
||||
template<typename KeyT, typename ValueT, typename Config>
|
||||
class ValueMapCallbackVH;
|
||||
|
||||
template<typename DenseMapT, typename KeyT>
|
||||
class ValueMapIterator;
|
||||
template<typename DenseMapT, typename KeyT>
|
||||
@ -57,7 +56,7 @@ class ValueMapConstIterator;
|
||||
/// as possible with future versions of ValueMap.
|
||||
template<typename KeyT, typename MutexT = sys::Mutex>
|
||||
struct ValueMapConfig {
|
||||
typedef MutexT mutex_type;
|
||||
using mutex_type = MutexT;
|
||||
|
||||
/// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
|
||||
/// false, the ValueMap will leave the original mapping in place.
|
||||
@ -87,21 +86,21 @@ template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT>>
|
||||
class ValueMap {
|
||||
friend class ValueMapCallbackVH<KeyT, ValueT, Config>;
|
||||
|
||||
typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH;
|
||||
typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>> MapT;
|
||||
typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;
|
||||
typedef typename Config::ExtraData ExtraData;
|
||||
using ValueMapCVH = ValueMapCallbackVH<KeyT, ValueT, Config>;
|
||||
using MapT = DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH>>;
|
||||
using MDMapT = DenseMap<const Metadata *, TrackingMDRef>;
|
||||
using ExtraData = typename Config::ExtraData;
|
||||
|
||||
MapT Map;
|
||||
Optional<MDMapT> MDMap;
|
||||
ExtraData Data;
|
||||
|
||||
bool MayMapMetadata = true;
|
||||
|
||||
public:
|
||||
typedef KeyT key_type;
|
||||
typedef ValueT mapped_type;
|
||||
typedef std::pair<KeyT, ValueT> value_type;
|
||||
typedef unsigned size_type;
|
||||
using key_type = KeyT;
|
||||
using mapped_type = ValueT;
|
||||
using value_type = std::pair<KeyT, ValueT>;
|
||||
using size_type = unsigned;
|
||||
|
||||
explicit ValueMap(unsigned NumInitBuckets = 64)
|
||||
: Map(NumInitBuckets), Data() {}
|
||||
@ -132,8 +131,9 @@ public:
|
||||
return Where->second.get();
|
||||
}
|
||||
|
||||
typedef ValueMapIterator<MapT, KeyT> iterator;
|
||||
typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
|
||||
using iterator = ValueMapIterator<MapT, KeyT>;
|
||||
using const_iterator = ValueMapConstIterator<MapT, KeyT>;
|
||||
|
||||
inline iterator begin() { return iterator(Map.begin()); }
|
||||
inline iterator end() { return iterator(Map.end()); }
|
||||
inline const_iterator begin() const { return const_iterator(Map.begin()); }
|
||||
@ -244,8 +244,8 @@ class ValueMapCallbackVH final : public CallbackVH {
|
||||
friend class ValueMap<KeyT, ValueT, Config>;
|
||||
friend struct DenseMapInfo<ValueMapCallbackVH>;
|
||||
|
||||
typedef ValueMap<KeyT, ValueT, Config> ValueMapT;
|
||||
typedef typename std::remove_pointer<KeyT>::type KeySansPointerT;
|
||||
using ValueMapT = ValueMap<KeyT, ValueT, Config>;
|
||||
using KeySansPointerT = typename std::remove_pointer<KeyT>::type;
|
||||
|
||||
ValueMapT *Map;
|
||||
|
||||
@ -298,7 +298,7 @@ public:
|
||||
|
||||
template<typename KeyT, typename ValueT, typename Config>
|
||||
struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config>> {
|
||||
typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH;
|
||||
using VH = ValueMapCallbackVH<KeyT, ValueT, Config>;
|
||||
|
||||
static inline VH getEmptyKey() {
|
||||
return VH(DenseMapInfo<Value *>::getEmptyKey());
|
||||
@ -330,8 +330,8 @@ class ValueMapIterator :
|
||||
public std::iterator<std::forward_iterator_tag,
|
||||
std::pair<KeyT, typename DenseMapT::mapped_type>,
|
||||
ptrdiff_t> {
|
||||
typedef typename DenseMapT::iterator BaseT;
|
||||
typedef typename DenseMapT::mapped_type ValueT;
|
||||
using BaseT = typename DenseMapT::iterator;
|
||||
using ValueT = typename DenseMapT::mapped_type;
|
||||
|
||||
BaseT I;
|
||||
|
||||
@ -344,7 +344,9 @@ public:
|
||||
struct ValueTypeProxy {
|
||||
const KeyT first;
|
||||
ValueT& second;
|
||||
|
||||
ValueTypeProxy *operator->() { return this; }
|
||||
|
||||
operator std::pair<KeyT, ValueT>() const {
|
||||
return std::make_pair(first, second);
|
||||
}
|
||||
@ -380,8 +382,8 @@ class ValueMapConstIterator :
|
||||
public std::iterator<std::forward_iterator_tag,
|
||||
std::pair<KeyT, typename DenseMapT::mapped_type>,
|
||||
ptrdiff_t> {
|
||||
typedef typename DenseMapT::const_iterator BaseT;
|
||||
typedef typename DenseMapT::mapped_type ValueT;
|
||||
using BaseT = typename DenseMapT::const_iterator;
|
||||
using ValueT = typename DenseMapT::mapped_type;
|
||||
|
||||
BaseT I;
|
||||
|
||||
|
@ -49,13 +49,13 @@ class ValueSymbolTable {
|
||||
/// @{
|
||||
public:
|
||||
/// @brief A mapping of names to values.
|
||||
typedef StringMap<Value*> ValueMap;
|
||||
using ValueMap = StringMap<Value*>;
|
||||
|
||||
/// @brief An iterator over a ValueMap.
|
||||
typedef ValueMap::iterator iterator;
|
||||
using iterator = ValueMap::iterator;
|
||||
|
||||
/// @brief A const_iterator over a ValueMap.
|
||||
typedef ValueMap::const_iterator const_iterator;
|
||||
using const_iterator = ValueMap::const_iterator;
|
||||
|
||||
/// @}
|
||||
/// @name Constructors
|
||||
|
@ -21,13 +21,17 @@
|
||||
#ifndef LLVM_IR_VERIFIER_H
|
||||
#define LLVM_IR_VERIFIER_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class APInt;
|
||||
class Function;
|
||||
class FunctionPass;
|
||||
class ModulePass;
|
||||
class Instruction;
|
||||
class MDNode;
|
||||
class Module;
|
||||
class raw_ostream;
|
||||
struct VerifierSupport;
|
||||
@ -47,7 +51,7 @@ class TBAAVerifier {
|
||||
/// the offset of the access. If zero, only a zero offset is allowed.
|
||||
///
|
||||
/// \c BitWidth has no meaning if \c IsInvalid is true.
|
||||
typedef std::pair<bool, unsigned> TBAABaseNodeSummary;
|
||||
using TBAABaseNodeSummary = std::pair<bool, unsigned>;
|
||||
DenseMap<const MDNode *, TBAABaseNodeSummary> TBAABaseNodes;
|
||||
|
||||
/// Maps an alleged scalar TBAA node to a boolean that is true if the said
|
||||
@ -101,12 +105,14 @@ FunctionPass *createVerifierPass(bool FatalErrors = true);
|
||||
/// and debug info errors.
|
||||
class VerifierAnalysis : public AnalysisInfoMixin<VerifierAnalysis> {
|
||||
friend AnalysisInfoMixin<VerifierAnalysis>;
|
||||
|
||||
static AnalysisKey Key;
|
||||
|
||||
public:
|
||||
struct Result {
|
||||
bool IRBroken, DebugInfoBroken;
|
||||
};
|
||||
|
||||
Result run(Module &M, ModuleAnalysisManager &);
|
||||
Result run(Function &F, FunctionAnalysisManager &);
|
||||
};
|
||||
@ -136,7 +142,6 @@ public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
#endif // LLVM_IR_VERIFIER_H
|
||||
|
@ -130,6 +130,7 @@ void initializeEfficiencySanitizerPass(PassRegistry&);
|
||||
void initializeEliminateAvailableExternallyLegacyPassPass(PassRegistry&);
|
||||
void initializeExpandISelPseudosPass(PassRegistry&);
|
||||
void initializeExpandPostRAPass(PassRegistry&);
|
||||
void initializeExpandReductionsPass(PassRegistry&);
|
||||
void initializeExternalAAWrapperPassPass(PassRegistry&);
|
||||
void initializeFEntryInserterPass(PassRegistry&);
|
||||
void initializeFinalizeMachineBundlesPass(PassRegistry&);
|
||||
@ -186,6 +187,7 @@ void initializeLintPass(PassRegistry&);
|
||||
void initializeLiveDebugValuesPass(PassRegistry&);
|
||||
void initializeLiveDebugVariablesPass(PassRegistry&);
|
||||
void initializeLiveIntervalsPass(PassRegistry&);
|
||||
void initializeLiveRangeShrinkPass(PassRegistry&);
|
||||
void initializeLiveRegMatrixPass(PassRegistry&);
|
||||
void initializeLiveStacksPass(PassRegistry&);
|
||||
void initializeLiveVariablesPass(PassRegistry&);
|
||||
@ -319,11 +321,12 @@ void initializeSCCPLegacyPassPass(PassRegistry&);
|
||||
void initializeSCEVAAWrapperPassPass(PassRegistry&);
|
||||
void initializeSLPVectorizerPass(PassRegistry&);
|
||||
void initializeSROALegacyPassPass(PassRegistry&);
|
||||
void initializeSafeStackPass(PassRegistry&);
|
||||
void initializeSafeStackLegacyPassPass(PassRegistry&);
|
||||
void initializeSampleProfileLoaderLegacyPassPass(PassRegistry&);
|
||||
void initializeSanitizerCoverageModulePass(PassRegistry&);
|
||||
void initializeScalarEvolutionWrapperPassPass(PassRegistry&);
|
||||
void initializeScalarizerPass(PassRegistry&);
|
||||
void initializeScalarizeMaskedMemIntrinPass(PassRegistry&);
|
||||
void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&);
|
||||
void initializeSeparateConstOffsetFromGEPPass(PassRegistry&);
|
||||
void initializeShadowStackGCLoweringPass(PassRegistry&);
|
||||
|
@ -206,6 +206,7 @@ namespace {
|
||||
(void) llvm::createMemDerefPrinter();
|
||||
(void) llvm::createFloat2IntPass();
|
||||
(void) llvm::createEliminateAvailableExternallyPass();
|
||||
(void) llvm::createScalarizeMaskedMemIntrinPass();
|
||||
|
||||
(void)new llvm::IntervalPartition();
|
||||
(void)new llvm::ScalarEvolutionWrapperPass();
|
||||
|
@ -67,7 +67,8 @@ public:
|
||||
WasmObjectFile(MemoryBufferRef Object, Error &Err);
|
||||
|
||||
const wasm::WasmObjectHeader &getHeader() const;
|
||||
const WasmSymbol &getWasmSymbol(DataRefImpl Symb) const;
|
||||
const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
|
||||
const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
|
||||
const WasmSection &getWasmSection(const SectionRef &Section) const;
|
||||
const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const;
|
||||
|
||||
@ -81,6 +82,10 @@ public:
|
||||
const std::vector<wasm::WasmGlobal>& globals() const { return Globals; }
|
||||
const std::vector<wasm::WasmExport>& exports() const { return Exports; }
|
||||
|
||||
uint32_t getNumberOfSymbols() const {
|
||||
return Symbols.size();
|
||||
}
|
||||
|
||||
const std::vector<wasm::WasmElemSegment>& elements() const {
|
||||
return ElemSegments;
|
||||
}
|
||||
|
@ -34,17 +34,6 @@ struct FileHeader {
|
||||
yaml::Hex32 Version;
|
||||
};
|
||||
|
||||
struct Import {
|
||||
StringRef Module;
|
||||
StringRef Field;
|
||||
ExportKind Kind;
|
||||
union {
|
||||
uint32_t SigIndex;
|
||||
ValueType GlobalType;
|
||||
};
|
||||
bool GlobalMutable;
|
||||
};
|
||||
|
||||
struct Limits {
|
||||
yaml::Hex32 Flags;
|
||||
yaml::Hex32 Initial;
|
||||
@ -74,6 +63,18 @@ struct Global {
|
||||
wasm::WasmInitExpr InitExpr;
|
||||
};
|
||||
|
||||
struct Import {
|
||||
StringRef Module;
|
||||
StringRef Field;
|
||||
ExportKind Kind;
|
||||
union {
|
||||
uint32_t SigIndex;
|
||||
Global GlobalImport;
|
||||
Table TableImport;
|
||||
Limits Memory;
|
||||
};
|
||||
};
|
||||
|
||||
struct LocalDecl {
|
||||
ValueType Type;
|
||||
uint32_t Count;
|
||||
|
@ -43,16 +43,7 @@ public:
|
||||
/// Write all the sample profiles in the given map of samples.
|
||||
///
|
||||
/// \returns status code of the file update operation.
|
||||
std::error_code write(const StringMap<FunctionSamples> &ProfileMap) {
|
||||
if (std::error_code EC = writeHeader(ProfileMap))
|
||||
return EC;
|
||||
for (const auto &I : ProfileMap) {
|
||||
const FunctionSamples &Profile = I.second;
|
||||
if (std::error_code EC = write(Profile))
|
||||
return EC;
|
||||
}
|
||||
return sampleprof_error::success;
|
||||
}
|
||||
std::error_code write(const StringMap<FunctionSamples> &ProfileMap);
|
||||
|
||||
raw_ostream &getOutputStream() { return *OutputStream; }
|
||||
|
||||
|
@ -139,6 +139,7 @@ public:
|
||||
}
|
||||
|
||||
uint32_t offset() const { return AbsOffset; }
|
||||
uint32_t getRecordLength() const { return ThisLen; }
|
||||
|
||||
private:
|
||||
void moveToEnd() {
|
||||
@ -294,6 +295,8 @@ template <typename T> class FixedStreamArray {
|
||||
friend class FixedStreamArrayIterator<T>;
|
||||
|
||||
public:
|
||||
typedef FixedStreamArrayIterator<T> Iterator;
|
||||
|
||||
FixedStreamArray() = default;
|
||||
explicit FixedStreamArray(BinaryStreamRef Stream) : Stream(Stream) {
|
||||
assert(Stream.getLength() % sizeof(T) == 0);
|
||||
@ -371,7 +374,7 @@ public:
|
||||
}
|
||||
|
||||
FixedStreamArrayIterator<T> &operator-=(std::ptrdiff_t N) {
|
||||
assert(Index >= N);
|
||||
assert(std::ptrdiff_t(Index) >= N);
|
||||
Index -= N;
|
||||
return *this;
|
||||
}
|
||||
|
@ -111,12 +111,6 @@
|
||||
#define LLVM_PREFETCH(addr, rw, locality)
|
||||
#endif
|
||||
|
||||
#if __has_attribute(sentinel) || LLVM_GNUC_PREREQ(3, 0, 0)
|
||||
#define LLVM_END_WITH_NULL __attribute__((sentinel))
|
||||
#else
|
||||
#define LLVM_END_WITH_NULL
|
||||
#endif
|
||||
|
||||
#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0)
|
||||
#define LLVM_ATTRIBUTE_USED __attribute__((__used__))
|
||||
#else
|
||||
@ -233,6 +227,8 @@
|
||||
/// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
|
||||
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
|
||||
#define LLVM_FALLTHROUGH [[fallthrough]]
|
||||
#elif __has_cpp_attribute(gnu::fallthrough)
|
||||
#define LLVM_FALLTHROUGH [[gnu::fallthrough]]
|
||||
#elif !__cplusplus
|
||||
// Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
|
||||
// error when __has_cpp_attribute is given a scoped attribute in C mode.
|
||||
|
@ -133,6 +133,66 @@ public:
|
||||
KnownBits zextOrTrunc(unsigned BitWidth) {
|
||||
return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth));
|
||||
}
|
||||
|
||||
/// Returns the minimum number of trailing zero bits.
|
||||
unsigned countMinTrailingZeros() const {
|
||||
return Zero.countTrailingOnes();
|
||||
}
|
||||
|
||||
/// Returns the minimum number of trailing one bits.
|
||||
unsigned countMinTrailingOnes() const {
|
||||
return One.countTrailingOnes();
|
||||
}
|
||||
|
||||
/// Returns the minimum number of leading zero bits.
|
||||
unsigned countMinLeadingZeros() const {
|
||||
return Zero.countLeadingOnes();
|
||||
}
|
||||
|
||||
/// Returns the minimum number of leading one bits.
|
||||
unsigned countMinLeadingOnes() const {
|
||||
return One.countLeadingOnes();
|
||||
}
|
||||
|
||||
/// Returns the number of times the sign bit is replicated into the other
|
||||
/// bits.
|
||||
unsigned countMinSignBits() const {
|
||||
if (isNonNegative())
|
||||
return countMinLeadingZeros();
|
||||
if (isNegative())
|
||||
return countMinLeadingOnes();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Returns the maximum number of trailing zero bits possible.
|
||||
unsigned countMaxTrailingZeros() const {
|
||||
return One.countTrailingZeros();
|
||||
}
|
||||
|
||||
/// Returns the maximum number of trailing one bits possible.
|
||||
unsigned countMaxTrailingOnes() const {
|
||||
return Zero.countTrailingZeros();
|
||||
}
|
||||
|
||||
/// Returns the maximum number of leading zero bits possible.
|
||||
unsigned countMaxLeadingZeros() const {
|
||||
return One.countLeadingZeros();
|
||||
}
|
||||
|
||||
/// Returns the maximum number of leading one bits possible.
|
||||
unsigned countMaxLeadingOnes() const {
|
||||
return Zero.countLeadingZeros();
|
||||
}
|
||||
|
||||
/// Returns the number of bits known to be one.
|
||||
unsigned countMinPopulation() const {
|
||||
return One.countPopulation();
|
||||
}
|
||||
|
||||
/// Returns the maximum number of bits that could be one.
|
||||
unsigned countMaxPopulation() const {
|
||||
return getBitWidth() - Zero.countPopulation();
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
249
include/llvm/Support/Parallel.h
Normal file
249
include/llvm/Support/Parallel.h
Normal file
@ -0,0 +1,249 @@
|
||||
//===- llvm/Support/Parallel.h - Parallel algorithms ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_SUPPORT_PARALLEL_H
|
||||
#define LLVM_SUPPORT_PARALLEL_H
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
#if defined(_MSC_VER) && LLVM_ENABLE_THREADS
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4530)
|
||||
#include <concrt.h>
|
||||
#include <ppl.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace parallel {
|
||||
struct sequential_execution_policy {};
|
||||
struct parallel_execution_policy {};
|
||||
|
||||
template <typename T>
|
||||
struct is_execution_policy
|
||||
: public std::integral_constant<
|
||||
bool, llvm::is_one_of<T, sequential_execution_policy,
|
||||
parallel_execution_policy>::value> {};
|
||||
|
||||
constexpr sequential_execution_policy seq{};
|
||||
constexpr parallel_execution_policy par{};
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if LLVM_ENABLE_THREADS
|
||||
|
||||
class Latch {
|
||||
uint32_t Count;
|
||||
mutable std::mutex Mutex;
|
||||
mutable std::condition_variable Cond;
|
||||
|
||||
public:
|
||||
explicit Latch(uint32_t Count = 0) : Count(Count) {}
|
||||
~Latch() { sync(); }
|
||||
|
||||
void inc() {
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
++Count;
|
||||
}
|
||||
|
||||
void dec() {
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
if (--Count == 0)
|
||||
Cond.notify_all();
|
||||
}
|
||||
|
||||
void sync() const {
|
||||
std::unique_lock<std::mutex> lock(Mutex);
|
||||
Cond.wait(lock, [&] { return Count == 0; });
|
||||
}
|
||||
};
|
||||
|
||||
class TaskGroup {
|
||||
Latch L;
|
||||
|
||||
public:
|
||||
void spawn(std::function<void()> f);
|
||||
|
||||
void sync() const { L.sync(); }
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
template <class RandomAccessIterator, class Comparator>
|
||||
void parallel_sort(RandomAccessIterator Start, RandomAccessIterator End,
|
||||
const Comparator &Comp) {
|
||||
concurrency::parallel_sort(Start, End, Comp);
|
||||
}
|
||||
template <class IterTy, class FuncTy>
|
||||
void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
|
||||
concurrency::parallel_for_each(Begin, End, Fn);
|
||||
}
|
||||
|
||||
template <class IndexTy, class FuncTy>
|
||||
void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
|
||||
concurrency::parallel_for(Begin, End, Fn);
|
||||
}
|
||||
|
||||
#else
|
||||
const ptrdiff_t MinParallelSize = 1024;
|
||||
|
||||
/// \brief Inclusive median.
|
||||
template <class RandomAccessIterator, class Comparator>
|
||||
RandomAccessIterator medianOf3(RandomAccessIterator Start,
|
||||
RandomAccessIterator End,
|
||||
const Comparator &Comp) {
|
||||
RandomAccessIterator Mid = Start + (std::distance(Start, End) / 2);
|
||||
return Comp(*Start, *(End - 1))
|
||||
? (Comp(*Mid, *(End - 1)) ? (Comp(*Start, *Mid) ? Mid : Start)
|
||||
: End - 1)
|
||||
: (Comp(*Mid, *Start) ? (Comp(*(End - 1), *Mid) ? Mid : End - 1)
|
||||
: Start);
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator, class Comparator>
|
||||
void parallel_quick_sort(RandomAccessIterator Start, RandomAccessIterator End,
|
||||
const Comparator &Comp, TaskGroup &TG, size_t Depth) {
|
||||
// Do a sequential sort for small inputs.
|
||||
if (std::distance(Start, End) < detail::MinParallelSize || Depth == 0) {
|
||||
std::sort(Start, End, Comp);
|
||||
return;
|
||||
}
|
||||
|
||||
// Partition.
|
||||
auto Pivot = medianOf3(Start, End, Comp);
|
||||
// Move Pivot to End.
|
||||
std::swap(*(End - 1), *Pivot);
|
||||
Pivot = std::partition(Start, End - 1, [&Comp, End](decltype(*Start) V) {
|
||||
return Comp(V, *(End - 1));
|
||||
});
|
||||
// Move Pivot to middle of partition.
|
||||
std::swap(*Pivot, *(End - 1));
|
||||
|
||||
// Recurse.
|
||||
TG.spawn([=, &Comp, &TG] {
|
||||
parallel_quick_sort(Start, Pivot, Comp, TG, Depth - 1);
|
||||
});
|
||||
parallel_quick_sort(Pivot + 1, End, Comp, TG, Depth - 1);
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator, class Comparator>
|
||||
void parallel_sort(RandomAccessIterator Start, RandomAccessIterator End,
|
||||
const Comparator &Comp) {
|
||||
TaskGroup TG;
|
||||
parallel_quick_sort(Start, End, Comp, TG,
|
||||
llvm::Log2_64(std::distance(Start, End)) + 1);
|
||||
}
|
||||
|
||||
template <class IterTy, class FuncTy>
|
||||
void parallel_for_each(IterTy Begin, IterTy End, FuncTy Fn) {
|
||||
// TaskGroup has a relatively high overhead, so we want to reduce
|
||||
// the number of spawn() calls. We'll create up to 1024 tasks here.
|
||||
// (Note that 1024 is an arbitrary number. This code probably needs
|
||||
// improving to take the number of available cores into account.)
|
||||
ptrdiff_t TaskSize = std::distance(Begin, End) / 1024;
|
||||
if (TaskSize == 0)
|
||||
TaskSize = 1;
|
||||
|
||||
TaskGroup TG;
|
||||
while (TaskSize <= std::distance(Begin, End)) {
|
||||
TG.spawn([=, &Fn] { std::for_each(Begin, Begin + TaskSize, Fn); });
|
||||
Begin += TaskSize;
|
||||
}
|
||||
TG.spawn([=, &Fn] { std::for_each(Begin, End, Fn); });
|
||||
}
|
||||
|
||||
template <class IndexTy, class FuncTy>
|
||||
void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
|
||||
ptrdiff_t TaskSize = (End - Begin) / 1024;
|
||||
if (TaskSize == 0)
|
||||
TaskSize = 1;
|
||||
|
||||
TaskGroup TG;
|
||||
IndexTy I = Begin;
|
||||
for (; I + TaskSize < End; I += TaskSize) {
|
||||
TG.spawn([=, &Fn] {
|
||||
for (IndexTy J = I, E = I + TaskSize; J != E; ++J)
|
||||
Fn(J);
|
||||
});
|
||||
}
|
||||
TG.spawn([=, &Fn] {
|
||||
for (IndexTy J = I; J < End; ++J)
|
||||
Fn(J);
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Iter>
|
||||
using DefComparator =
|
||||
std::less<typename std::iterator_traits<Iter>::value_type>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// sequential algorithm implementations.
|
||||
template <class Policy, class RandomAccessIterator,
|
||||
class Comparator = detail::DefComparator<RandomAccessIterator>>
|
||||
void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End,
|
||||
const Comparator &Comp = Comparator()) {
|
||||
static_assert(is_execution_policy<Policy>::value,
|
||||
"Invalid execution policy!");
|
||||
std::sort(Start, End, Comp);
|
||||
}
|
||||
|
||||
template <class Policy, class IterTy, class FuncTy>
|
||||
void for_each(Policy policy, IterTy Begin, IterTy End, FuncTy Fn) {
|
||||
static_assert(is_execution_policy<Policy>::value,
|
||||
"Invalid execution policy!");
|
||||
std::for_each(Begin, End, Fn);
|
||||
}
|
||||
|
||||
template <class Policy, class IndexTy, class FuncTy>
|
||||
void for_each_n(Policy policy, IndexTy Begin, IndexTy End, FuncTy Fn) {
|
||||
static_assert(is_execution_policy<Policy>::value,
|
||||
"Invalid execution policy!");
|
||||
for (IndexTy I = Begin; I != End; ++I)
|
||||
Fn(I);
|
||||
}
|
||||
|
||||
// Parallel algorithm implementations, only available when LLVM_ENABLE_THREADS
|
||||
// is true.
|
||||
#if LLVM_ENABLE_THREADS
|
||||
template <class RandomAccessIterator,
|
||||
class Comparator = detail::DefComparator<RandomAccessIterator>>
|
||||
void sort(parallel_execution_policy policy, RandomAccessIterator Start,
|
||||
RandomAccessIterator End, const Comparator &Comp = Comparator()) {
|
||||
detail::parallel_sort(Start, End, Comp);
|
||||
}
|
||||
|
||||
template <class IterTy, class FuncTy>
|
||||
void for_each(parallel_execution_policy policy, IterTy Begin, IterTy End,
|
||||
FuncTy Fn) {
|
||||
detail::parallel_for_each(Begin, End, Fn);
|
||||
}
|
||||
|
||||
template <class IndexTy, class FuncTy>
|
||||
void for_each_n(parallel_execution_policy policy, IndexTy Begin, IndexTy End,
|
||||
FuncTy Fn) {
|
||||
detail::parallel_for_each_n(Begin, End, Fn);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace parallel
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_SUPPORT_PARALLEL_H
|
@ -37,17 +37,6 @@ struct WasmSignature {
|
||||
int32_t ReturnType;
|
||||
};
|
||||
|
||||
struct WasmImport {
|
||||
StringRef Module;
|
||||
StringRef Field;
|
||||
uint32_t Kind;
|
||||
union {
|
||||
uint32_t SigIndex;
|
||||
int32_t GlobalType;
|
||||
};
|
||||
bool GlobalMutable;
|
||||
};
|
||||
|
||||
struct WasmExport {
|
||||
StringRef Name;
|
||||
uint32_t Kind;
|
||||
@ -82,6 +71,18 @@ struct WasmGlobal {
|
||||
WasmInitExpr InitExpr;
|
||||
};
|
||||
|
||||
struct WasmImport {
|
||||
StringRef Module;
|
||||
StringRef Field;
|
||||
uint32_t Kind;
|
||||
union {
|
||||
uint32_t SigIndex;
|
||||
WasmGlobal Global;
|
||||
WasmTable Table;
|
||||
WasmLimits Memory;
|
||||
};
|
||||
};
|
||||
|
||||
struct WasmLocalDecl {
|
||||
int32_t Type;
|
||||
uint32_t Count;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user