Vendor import of llvm trunk r303197:

https://llvm.org/svn/llvm-project/llvm/trunk@303197
This commit is contained in:
dim 2017-05-16 19:46:52 +00:00
parent 7577e511db
commit d8101ca407
869 changed files with 56421 additions and 21293 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -120,6 +120,10 @@ private:
buildInitialSymbolTable(PFC->Objects);
}
~ConcreteLinkedObjectSet() override {
MemMgr->deregisterEHFrames();
}
void setHandle(ObjSetHandleT H) {
PFC->Handle = H;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,7 +37,7 @@ struct UseListOrder {
UseListOrder &operator=(UseListOrder &&) = default;
};
typedef std::vector<UseListOrder> UseListOrderStack;
using UseListOrderStack = std::vector<UseListOrder>;
} // end namespace llvm

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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