mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 14:26:03 -04:00
Vendor import of llvm trunk r301939:
https://llvm.org/svn/llvm-project/llvm/trunk@301939
This commit is contained in:
parent
12f3ca4cdb
commit
a303c417bb
695 changed files with 22442 additions and 10438 deletions
|
|
@ -17,6 +17,9 @@ else()
|
|||
set(LINKER_IS_LLD_LINK FALSE)
|
||||
endif()
|
||||
|
||||
set(LLVM_ENABLE_LTO OFF CACHE STRING "Build LLVM with LTO. May be specified as Thin or Full to use a particular kind of LTO")
|
||||
string(TOUPPER "${LLVM_ENABLE_LTO}" uppercase_LLVM_ENABLE_LTO)
|
||||
|
||||
# Ninja Job Pool support
|
||||
# The following only works with the Ninja generator in CMake >= 3.0.
|
||||
set(LLVM_PARALLEL_COMPILE_JOBS "" CACHE STRING
|
||||
|
|
@ -32,16 +35,19 @@ endif()
|
|||
|
||||
set(LLVM_PARALLEL_LINK_JOBS "" CACHE STRING
|
||||
"Define the maximum number of concurrent link jobs.")
|
||||
if(LLVM_PARALLEL_LINK_JOBS)
|
||||
if(NOT CMAKE_MAKE_PROGRAM MATCHES "ninja")
|
||||
message(WARNING "Job pooling is only available with Ninja generators.")
|
||||
else()
|
||||
if(CMAKE_MAKE_PROGRAM MATCHES "ninja")
|
||||
if(NOT LLVM_PARALLEL_LINK_JOBS AND uppercase_LLVM_ENABLE_LTO STREQUAL "THIN")
|
||||
message(STATUS "ThinLTO provides its own parallel linking - limiting parallel link jobs to 2.")
|
||||
set(LLVM_PARALLEL_LINK_JOBS "2")
|
||||
endif()
|
||||
if(LLVM_PARALLEL_LINK_JOBS)
|
||||
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${LLVM_PARALLEL_LINK_JOBS})
|
||||
set(CMAKE_JOB_POOL_LINK link_job_pool)
|
||||
endif()
|
||||
elseif(LLVM_PARALLEL_LINK_JOBS)
|
||||
message(WARNING "Job pooling is only available with Ninja generators.")
|
||||
endif()
|
||||
|
||||
|
||||
if (LINKER_IS_LLD_LINK)
|
||||
# Pass /MANIFEST:NO so that CMake doesn't run mt.exe on our binaries. Adding
|
||||
# manifests with mt.exe breaks LLD's symbol tables and takes as much time as
|
||||
|
|
@ -724,8 +730,6 @@ append_if(LLVM_BUILD_INSTRUMENTED_COVERAGE "-fprofile-instr-generate='${LLVM_PRO
|
|||
CMAKE_EXE_LINKER_FLAGS
|
||||
CMAKE_SHARED_LINKER_FLAGS)
|
||||
|
||||
set(LLVM_ENABLE_LTO OFF CACHE STRING "Build LLVM with LTO. May be specified as Thin or Full to use a particular kind of LTO")
|
||||
string(TOUPPER "${LLVM_ENABLE_LTO}" uppercase_LLVM_ENABLE_LTO)
|
||||
if(LLVM_ENABLE_LTO AND LLVM_ON_WIN32 AND NOT LINKER_IS_LLD_LINK)
|
||||
message(FATAL_ERROR "When compiling for Windows, LLVM_ENABLE_LTO requires using lld as the linker (point CMAKE_LINKER at lld-link.exe)")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ function(add_version_info_from_vcs VERS)
|
|||
execute_process(COMMAND ${git_executable} rev-parse --git-dir
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}/cmake
|
||||
RESULT_VARIABLE git_result
|
||||
OUTPUT_VARIABLE git_dir)
|
||||
OUTPUT_VARIABLE git_dir
|
||||
ERROR_QUIET)
|
||||
if(git_result EQUAL 0)
|
||||
# Try to get a ref-id
|
||||
string(STRIP "${git_dir}" git_dir)
|
||||
|
|
@ -45,7 +46,8 @@ function(add_version_info_from_vcs VERS)
|
|||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
TIMEOUT 5
|
||||
RESULT_VARIABLE git_result
|
||||
OUTPUT_VARIABLE git_output)
|
||||
OUTPUT_VARIABLE git_output
|
||||
ERROR_QUIET)
|
||||
if( git_result EQUAL 0 )
|
||||
string(REGEX MATCH "URL: ([^ \n]*)" svn_url ${git_output})
|
||||
if(svn_url)
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ handler as follows:
|
|||
Usage Code Sequence Description
|
||||
=============== ============= ===============================================
|
||||
llvm.trap s_endpgm Causes wavefront to be terminated.
|
||||
llvm.debugtrap Nothing. Compiler warning generated that there is no trap handler installed.
|
||||
llvm.debugtrap Nothing Compiler warning generated that there is no trap handler installed.
|
||||
=============== ============= ===============================================
|
||||
|
||||
Assembler
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
|
||||
if (DOXYGEN_FOUND)
|
||||
if (LLVM_ENABLE_DOXYGEN)
|
||||
set(abs_top_srcdir ${LLVM_MAIN_SRC_DIR})
|
||||
set(abs_top_builddir ${LLVM_BINARY_DIR})
|
||||
set(abs_top_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(abs_top_builddir ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if (HAVE_DOT)
|
||||
set(DOT ${LLVM_PATH_DOT})
|
||||
|
|
|
|||
|
|
@ -1535,6 +1535,17 @@ example:
|
|||
``sanitize_thread``
|
||||
This attribute indicates that ThreadSanitizer checks
|
||||
(dynamic thread safety analysis) are enabled for this function.
|
||||
``speculatable``
|
||||
This function attribute indicates that the function does not have any
|
||||
effects besides calculating its result and does not have undefined behavior.
|
||||
Note that ``speculatable`` is not enough to conclude that along any
|
||||
particular exection path the number of calls to this function will not be
|
||||
externally observable. This attribute is only valid on functions
|
||||
and declarations, not on individual call sites. If a function is
|
||||
incorrectly marked as speculatable and really does exhibit
|
||||
undefined behavior, the undefined behavior may be observed even
|
||||
if the call site is dead code.
|
||||
|
||||
``ssp``
|
||||
This attribute indicates that the function should emit a stack
|
||||
smashing protector. It is in the form of a "canary" --- a random value
|
||||
|
|
|
|||
|
|
@ -776,22 +776,21 @@ readability.
|
|||
Using cantFail to simplify safe callsites
|
||||
"""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Some functions may only fail for a subset of their inputs. For such functions
|
||||
call-sites using known-safe inputs can assume that the result will be a success
|
||||
value.
|
||||
Some functions may only fail for a subset of their inputs, so calls using known
|
||||
safe inputs can be assumed to succeed.
|
||||
|
||||
The cantFail functions encapsulate this by wrapping an assertion that their
|
||||
argument is a success value and, in the case of Expected<T>, unwrapping the
|
||||
T value from the Expected<T> argument:
|
||||
T value:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
Error mayFail(int X);
|
||||
Expected<int> mayFail2(int X);
|
||||
Error onlyFailsForSomeXValues(int X);
|
||||
Expected<int> onlyFailsForSomeXValues2(int X);
|
||||
|
||||
void foo() {
|
||||
cantFail(mayFail(KnownSafeValue));
|
||||
int Y = cantFail(mayFail2(KnownSafeValue));
|
||||
cantFail(onlyFailsForSomeXValues(KnownSafeValue));
|
||||
int Y = cantFail(onlyFailsForSomeXValues2(KnownSafeValue));
|
||||
...
|
||||
}
|
||||
|
||||
|
|
@ -801,8 +800,8 @@ terminate the program on an error input, cantFile simply asserts that the result
|
|||
is success. In debug builds this will result in an assertion failure if an error
|
||||
is encountered. In release builds the behavior of cantFail for failure values is
|
||||
undefined. As such, care must be taken in the use of cantFail: clients must be
|
||||
certain that a cantFail wrapped call really can not fail under any
|
||||
circumstances.
|
||||
certain that a cantFail wrapped call really can not fail with the given
|
||||
arguments.
|
||||
|
||||
Use of the cantFail functions should be rare in library code, but they are
|
||||
likely to be of more use in tool and unit-test code where inputs and/or
|
||||
|
|
|
|||
|
|
@ -51,3 +51,18 @@ running:
|
|||
|
||||
cd docs/
|
||||
make -f Makefile.sphinx linkcheck
|
||||
|
||||
Doxygen page Output
|
||||
==============
|
||||
|
||||
Install doxygen <http://www.stack.nl/~dimitri/doxygen/download.html> and dot2tex <https://dot2tex.readthedocs.io/en/latest>.
|
||||
|
||||
cd <build-dir>
|
||||
cmake -DLLVM_ENABLE_DOXYGEN=On <llvm-top-src-dir>
|
||||
make doxygen-llvm # for LLVM docs
|
||||
make doxygen-clang # for clang docs
|
||||
|
||||
It will generate html in
|
||||
|
||||
<build-dir>/docs/doxygen/html # for LLVM docs
|
||||
<build-dir>/tools/clang/docs/doxygen/html # for clang docs
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ format of this section follows:
|
|||
.. code-block:: none
|
||||
|
||||
Header {
|
||||
uint8 : Stack Map Version (current version is 2)
|
||||
uint8 : Stack Map Version (current version is 3)
|
||||
uint8 : Reserved (expected to be 0)
|
||||
uint16 : Reserved (expected to be 0)
|
||||
}
|
||||
|
|
@ -341,10 +341,13 @@ format of this section follows:
|
|||
uint16 : NumLocations
|
||||
Location[NumLocations] {
|
||||
uint8 : Register | Direct | Indirect | Constant | ConstantIndex
|
||||
uint8 : Reserved (location flags)
|
||||
uint8 : Reserved (expected to be 0)
|
||||
uint16 : Location Size
|
||||
uint16 : Dwarf RegNum
|
||||
uint16 : Reserved (expected to be 0)
|
||||
int32 : Offset or SmallConstant
|
||||
}
|
||||
uint32 : Padding (only if required to align to 8 byte)
|
||||
uint16 : Padding
|
||||
uint16 : NumLiveOuts
|
||||
LiveOuts[NumLiveOuts]
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ types are:
|
|||
The 'string' type represents an ordered sequence of characters of arbitrary
|
||||
length.
|
||||
|
||||
``code``
|
||||
The `code` type represents a code fragment, which can be single/multi-line
|
||||
string literal.
|
||||
|
||||
``bits<n>``
|
||||
A 'bits' type is an arbitrary, but fixed, size integer that is broken up
|
||||
into individual bits. This type is useful because it can handle some bits
|
||||
|
|
@ -105,7 +109,7 @@ supported include:
|
|||
hexadecimal integer value
|
||||
|
||||
``"foo"``
|
||||
string value
|
||||
a single-line string value, can be assigned to ``string`` or ``code`` variable.
|
||||
|
||||
``[{ ... }]``
|
||||
usually called a "code fragment", but is just a multiline string literal
|
||||
|
|
@ -126,7 +130,8 @@ supported include:
|
|||
access to one bit of a value
|
||||
|
||||
``value{15-17}``
|
||||
access to multiple bits of a value
|
||||
access to an ordered sequence of bits of a value, in particular ``value{15-17}``
|
||||
produces an order that is the reverse of ``value{17-15}``.
|
||||
|
||||
``DEF``
|
||||
reference to a record definition
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ PROJECT_LOGO =
|
|||
# entered, it will be relative to the location where doxygen was started. If
|
||||
# left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = @abs_top_builddir@/docs/doxygen
|
||||
OUTPUT_DIRECTORY = @abs_top_builddir@/doxygen
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
|
||||
# directories (in 2 levels) under the output directory of each output format and
|
||||
|
|
@ -132,7 +132,7 @@ INLINE_INHERITED_MEMB = NO
|
|||
# shortest path that makes the file name unique will be used
|
||||
# The default value is: YES.
|
||||
|
||||
FULL_PATH_NAMES = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
|
||||
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
|
||||
# Stripping is only done if one of the specified strings matches the left-hand
|
||||
|
|
@ -144,7 +144,7 @@ FULL_PATH_NAMES = NO
|
|||
# will be relative from the directory where doxygen is started.
|
||||
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||
|
||||
STRIP_FROM_PATH = ../..
|
||||
STRIP_FROM_PATH = @abs_top_srcdir@/..
|
||||
|
||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||
# path mentioned in the documentation of a class, which tells the reader which
|
||||
|
|
@ -153,7 +153,8 @@ STRIP_FROM_PATH = ../..
|
|||
# specify the list of include paths that are normally passed to the compiler
|
||||
# using the -I flag.
|
||||
|
||||
STRIP_FROM_INC_PATH =
|
||||
STRIP_FROM_INC_PATH = @abs_top_srcdir@/../include
|
||||
STRIP_FROM_INC_PATH += @abs_top_srcdir@/../lib
|
||||
|
||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
||||
# less readable) file names. This can be useful is your file systems doesn't
|
||||
|
|
@ -513,7 +514,7 @@ SHOW_GROUPED_MEMB_INC = NO
|
|||
# files with double quotes in the documentation rather than with sharp brackets.
|
||||
# The default value is: NO.
|
||||
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
FORCE_LOCAL_INCLUDES = YES
|
||||
|
||||
# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
|
||||
# documentation for inline members.
|
||||
|
|
@ -743,9 +744,9 @@ WARN_LOGFILE =
|
|||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = @abs_top_srcdir@/include \
|
||||
@abs_top_srcdir@/lib \
|
||||
@abs_top_srcdir@/docs/doxygen-mainpage.dox
|
||||
INPUT = @abs_top_srcdir@/../include \
|
||||
@abs_top_srcdir@/../lib \
|
||||
@abs_top_srcdir@/doxygen-mainpage.dox
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
|
|
@ -813,7 +814,7 @@ EXCLUDE_SYMBOLS =
|
|||
# that contain example code fragments that are included (see the \include
|
||||
# command).
|
||||
|
||||
EXAMPLE_PATH = @abs_top_srcdir@/examples
|
||||
EXAMPLE_PATH = @abs_top_srcdir@/../examples
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||
|
|
@ -833,7 +834,7 @@ EXAMPLE_RECURSIVE = YES
|
|||
# that contain images that are to be included in the documentation (see the
|
||||
# \image command).
|
||||
|
||||
IMAGE_PATH = @abs_top_srcdir@/docs/img
|
||||
IMAGE_PATH = @abs_top_srcdir@/img
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
|
|
|
|||
|
|
@ -366,7 +366,7 @@ public:
|
|||
/// that 0 is not a positive value.
|
||||
///
|
||||
/// \returns true if this APInt is positive.
|
||||
bool isStrictlyPositive() const { return isNonNegative() && !!*this; }
|
||||
bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
|
||||
|
||||
/// \brief Determine if all bits are set
|
||||
///
|
||||
|
|
@ -377,6 +377,12 @@ public:
|
|||
return countPopulationSlowCase() == BitWidth;
|
||||
}
|
||||
|
||||
/// \brief Determine if all bits are clear
|
||||
///
|
||||
/// This checks to see if the value has all bits of the APInt are clear or
|
||||
/// not.
|
||||
bool isNullValue() const { return !*this; }
|
||||
|
||||
/// \brief Determine if this is the largest unsigned value.
|
||||
///
|
||||
/// This checks to see if the value of this APInt is the maximum unsigned
|
||||
|
|
@ -395,7 +401,7 @@ public:
|
|||
///
|
||||
/// This checks to see if the value of this APInt is the minimum unsigned
|
||||
/// value for the APInt's bit width.
|
||||
bool isMinValue() const { return !*this; }
|
||||
bool isMinValue() const { return isNullValue(); }
|
||||
|
||||
/// \brief Determine if this is the smallest signed value.
|
||||
///
|
||||
|
|
@ -611,15 +617,7 @@ public:
|
|||
}
|
||||
|
||||
/// \brief Return a value containing V broadcasted over NewLen bits.
|
||||
static APInt getSplat(unsigned NewLen, const APInt &V) {
|
||||
assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
|
||||
|
||||
APInt Val = V.zextOrSelf(NewLen);
|
||||
for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
|
||||
Val |= Val << I;
|
||||
|
||||
return Val;
|
||||
}
|
||||
static APInt getSplat(unsigned NewLen, const APInt &V);
|
||||
|
||||
/// \brief Determine if two APInts have the same value, after zero-extending
|
||||
/// one of them (if needed!) to ensure that the bit-widths match.
|
||||
|
|
@ -687,7 +685,9 @@ public:
|
|||
///
|
||||
/// \returns true if *this is zero, false otherwise.
|
||||
bool operator!() const {
|
||||
return *this == 0;
|
||||
if (isSingleWord())
|
||||
return VAL == 0;
|
||||
return countLeadingZerosSlowCase() == BitWidth;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
|
@ -874,6 +874,13 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Left-shift assignment function.
|
||||
///
|
||||
/// Shifts *this left by shiftAmt and assigns the result to *this.
|
||||
///
|
||||
/// \returns *this after shifting left by ShiftAmt
|
||||
APInt &operator<<=(const APInt &ShiftAmt);
|
||||
|
||||
/// @}
|
||||
/// \name Binary Operators
|
||||
/// @{
|
||||
|
|
@ -981,7 +988,11 @@ public:
|
|||
/// \brief Left-shift function.
|
||||
///
|
||||
/// Left-shift this APInt by shiftAmt.
|
||||
APInt shl(const APInt &shiftAmt) const;
|
||||
APInt shl(const APInt &ShiftAmt) const {
|
||||
APInt R(*this);
|
||||
R <<= ShiftAmt;
|
||||
return R;
|
||||
}
|
||||
|
||||
/// \brief Rotate left by rotateAmt.
|
||||
APInt rotl(const APInt &rotateAmt) const;
|
||||
|
|
@ -1333,7 +1344,14 @@ public:
|
|||
/// \brief Set a given bit to 1.
|
||||
///
|
||||
/// Set the given bit to 1 whose position is given as "bitPosition".
|
||||
void setBit(unsigned bitPosition);
|
||||
void setBit(unsigned BitPosition) {
|
||||
assert(BitPosition <= BitWidth && "BitPosition out of range");
|
||||
WordType Mask = maskBit(BitPosition);
|
||||
if (isSingleWord())
|
||||
VAL |= Mask;
|
||||
else
|
||||
pVal[whichWord(BitPosition)] |= Mask;
|
||||
}
|
||||
|
||||
/// Set the sign bit to 1.
|
||||
void setSignBit() {
|
||||
|
|
@ -1344,13 +1362,9 @@ public:
|
|||
void setBits(unsigned loBit, unsigned hiBit) {
|
||||
assert(hiBit <= BitWidth && "hiBit out of range");
|
||||
assert(loBit <= BitWidth && "loBit out of range");
|
||||
assert(loBit <= hiBit && "loBit greater than hiBit");
|
||||
if (loBit == hiBit)
|
||||
return;
|
||||
if (loBit > hiBit) {
|
||||
setLowBits(hiBit);
|
||||
setHighBits(BitWidth - loBit);
|
||||
return;
|
||||
}
|
||||
if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) {
|
||||
uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
|
||||
mask <<= loBit;
|
||||
|
|
@ -1389,7 +1403,19 @@ public:
|
|||
/// \brief Set a given bit to 0.
|
||||
///
|
||||
/// Set the given bit to 0 whose position is given as "bitPosition".
|
||||
void clearBit(unsigned bitPosition);
|
||||
void clearBit(unsigned BitPosition) {
|
||||
assert(BitPosition <= BitWidth && "BitPosition out of range");
|
||||
WordType Mask = ~maskBit(BitPosition);
|
||||
if (isSingleWord())
|
||||
VAL &= Mask;
|
||||
else
|
||||
pVal[whichWord(BitPosition)] &= Mask;
|
||||
}
|
||||
|
||||
/// Set the sign bit to 0.
|
||||
void clearSignBit() {
|
||||
clearBit(BitWidth - 1);
|
||||
}
|
||||
|
||||
/// \brief Toggle every bit to its opposite value.
|
||||
void flipAllBits() {
|
||||
|
|
@ -1695,7 +1721,7 @@ public:
|
|||
return VAL - 1;
|
||||
|
||||
// Handle the zero case.
|
||||
if (!getBoolValue())
|
||||
if (isNullValue())
|
||||
return UINT32_MAX;
|
||||
|
||||
// The non-zero case is handled by computing:
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class AssumptionCache {
|
|||
|
||||
/// \brief Vector of weak value handles to calls of the @llvm.assume
|
||||
/// intrinsic.
|
||||
SmallVector<WeakVH, 4> AssumeHandles;
|
||||
SmallVector<WeakTrackingVH, 4> AssumeHandles;
|
||||
|
||||
class AffectedValueCallbackVH final : public CallbackVH {
|
||||
AssumptionCache *AC;
|
||||
|
|
@ -62,12 +62,12 @@ class AssumptionCache {
|
|||
/// \brief A map of values about which an assumption might be providing
|
||||
/// information to the relevant set of assumptions.
|
||||
using AffectedValuesMap =
|
||||
DenseMap<AffectedValueCallbackVH, SmallVector<WeakVH, 1>,
|
||||
AffectedValueCallbackVH::DMI>;
|
||||
DenseMap<AffectedValueCallbackVH, SmallVector<WeakTrackingVH, 1>,
|
||||
AffectedValueCallbackVH::DMI>;
|
||||
AffectedValuesMap AffectedValues;
|
||||
|
||||
/// Get the vector of assumptions which affect a value from the cache.
|
||||
SmallVector<WeakVH, 1> &getOrInsertAffectedValues(Value *V);
|
||||
SmallVector<WeakTrackingVH, 1> &getOrInsertAffectedValues(Value *V);
|
||||
|
||||
/// Copy affected values in the cache for OV to be affected values for NV.
|
||||
void copyAffectedValuesInCache(Value *OV, Value *NV);
|
||||
|
|
@ -120,20 +120,20 @@ public:
|
|||
/// FIXME: We should replace this with pointee_iterator<filter_iterator<...>>
|
||||
/// when we can write that to filter out the null values. Then caller code
|
||||
/// will become simpler.
|
||||
MutableArrayRef<WeakVH> assumptions() {
|
||||
MutableArrayRef<WeakTrackingVH> assumptions() {
|
||||
if (!Scanned)
|
||||
scanFunction();
|
||||
return AssumeHandles;
|
||||
}
|
||||
|
||||
/// \brief Access the list of assumptions which affect this value.
|
||||
MutableArrayRef<WeakVH> assumptionsFor(const Value *V) {
|
||||
MutableArrayRef<WeakTrackingVH> assumptionsFor(const Value *V) {
|
||||
if (!Scanned)
|
||||
scanFunction();
|
||||
|
||||
auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
|
||||
if (AVI == AffectedValues.end())
|
||||
return MutableArrayRef<WeakVH>();
|
||||
return MutableArrayRef<WeakTrackingVH>();
|
||||
|
||||
return AVI->second;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -646,7 +646,7 @@ public:
|
|||
LazyCallGraph::SCC *C = &InitialC;
|
||||
|
||||
// Collect value handles for all of the indirect call sites.
|
||||
SmallVector<WeakVH, 8> CallHandles;
|
||||
SmallVector<WeakTrackingVH, 8> CallHandles;
|
||||
|
||||
// Struct to track the counts of direct and indirect calls in each function
|
||||
// of the SCC.
|
||||
|
|
@ -658,7 +658,7 @@ public:
|
|||
// Put value handles on all of the indirect calls and return the number of
|
||||
// direct calls for each function in the SCC.
|
||||
auto ScanSCC = [](LazyCallGraph::SCC &C,
|
||||
SmallVectorImpl<WeakVH> &CallHandles) {
|
||||
SmallVectorImpl<WeakTrackingVH> &CallHandles) {
|
||||
assert(CallHandles.empty() && "Must start with a clear set of handles.");
|
||||
|
||||
SmallVector<CallCount, 4> CallCounts;
|
||||
|
|
@ -671,7 +671,7 @@ public:
|
|||
++Count.Direct;
|
||||
} else {
|
||||
++Count.Indirect;
|
||||
CallHandles.push_back(WeakVH(&I));
|
||||
CallHandles.push_back(WeakTrackingVH(&I));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -699,7 +699,7 @@ public:
|
|||
"Cannot have changed the size of the SCC!");
|
||||
|
||||
// Check whether any of the handles were devirtualized.
|
||||
auto IsDevirtualizedHandle = [&](WeakVH &CallH) {
|
||||
auto IsDevirtualizedHandle = [&](WeakTrackingVH &CallH) {
|
||||
if (!CallH)
|
||||
return false;
|
||||
auto CS = CallSite(CallH);
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ class CallGraphNode {
|
|||
public:
|
||||
/// \brief A pair of the calling instruction (a call or invoke)
|
||||
/// and the call graph node being called.
|
||||
typedef std::pair<WeakVH, CallGraphNode *> CallRecord;
|
||||
typedef std::pair<WeakTrackingVH, CallGraphNode *> CallRecord;
|
||||
|
||||
public:
|
||||
typedef std::vector<CallRecord> CalledFunctionsVector;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ private:
|
|||
|
||||
/// OperandValToReplace - The Value of the operand in the user instruction
|
||||
/// that this IVStrideUse is representing.
|
||||
WeakVH OperandValToReplace;
|
||||
WeakTrackingVH OperandValToReplace;
|
||||
|
||||
/// PostIncLoops - The set of loops for which Expr has been adjusted to
|
||||
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
|
||||
|
|
|
|||
|
|
@ -160,6 +160,10 @@ InlineParams getInlineParams(int Threshold);
|
|||
/// the -Oz flag.
|
||||
InlineParams getInlineParams(unsigned OptLevel, unsigned SizeOptLevel);
|
||||
|
||||
/// Return the cost associated with a callsite, including paramater passing
|
||||
/// and the call/return instruction.
|
||||
int getCallsiteCost(CallSite CS, const DataLayout &DL);
|
||||
|
||||
/// \brief Get an InlineCost object representing the cost of inlining this
|
||||
/// callsite.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -35,35 +35,41 @@
|
|||
#include "llvm/IR/User.h"
|
||||
|
||||
namespace llvm {
|
||||
template<typename T>
|
||||
class ArrayRef;
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class DataLayout;
|
||||
class FastMathFlags;
|
||||
class OptimizationRemarkEmitter;
|
||||
class TargetLibraryInfo;
|
||||
class Type;
|
||||
class Value;
|
||||
class Function;
|
||||
template <typename T, typename... TArgs> class AnalysisManager;
|
||||
template <class T> class ArrayRef;
|
||||
class AssumptionCache;
|
||||
class DominatorTree;
|
||||
class Instruction;
|
||||
class DataLayout;
|
||||
class FastMathFlags;
|
||||
struct LoopStandardAnalysisResults;
|
||||
class OptimizationRemarkEmitter;
|
||||
class Pass;
|
||||
class TargetLibraryInfo;
|
||||
class Type;
|
||||
class Value;
|
||||
|
||||
struct SimplifyQuery {
|
||||
const DataLayout &DL;
|
||||
const TargetLibraryInfo *TLI = nullptr;
|
||||
const DominatorTree *DT = nullptr;
|
||||
AssumptionCache *AC = nullptr;
|
||||
const Instruction *CxtI = nullptr;
|
||||
SimplifyQuery(const DataLayout &DL) : DL(DL) {}
|
||||
struct SimplifyQuery {
|
||||
const DataLayout &DL;
|
||||
const TargetLibraryInfo *TLI = nullptr;
|
||||
const DominatorTree *DT = nullptr;
|
||||
AssumptionCache *AC = nullptr;
|
||||
const Instruction *CxtI = nullptr;
|
||||
|
||||
SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT, AssumptionCache *AC = nullptr,
|
||||
const Instruction *CXTI = nullptr)
|
||||
: DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {}
|
||||
SimplifyQuery getWithInstruction(Instruction *I) const {
|
||||
SimplifyQuery Copy(*this);
|
||||
Copy.CxtI = I;
|
||||
return Copy;
|
||||
}
|
||||
SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr)
|
||||
: DL(DL), CxtI(CXTI) {}
|
||||
|
||||
SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CXTI = nullptr)
|
||||
: DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {}
|
||||
SimplifyQuery getWithInstruction(Instruction *I) const {
|
||||
SimplifyQuery Copy(*this);
|
||||
Copy.CxtI = I;
|
||||
return Copy;
|
||||
}
|
||||
};
|
||||
|
||||
// NOTE: the explicit multiple argument versions of these functions are
|
||||
|
|
@ -73,257 +79,103 @@ namespace llvm {
|
|||
/// Given operands for an Add, fold the result or return null.
|
||||
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a Sub, fold the result or return null.
|
||||
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FAdd, fold the result or return null.
|
||||
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FSub, fold the result or return null.
|
||||
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FMul, fold the result or return null.
|
||||
Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a Mul, fold the result or return null.
|
||||
Value *SimplifyMulInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an SDiv, fold the result or return null.
|
||||
Value *SimplifySDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a UDiv, fold the result or return null.
|
||||
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FDiv, fold the result or return null.
|
||||
Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an SRem, fold the result or return null.
|
||||
Value *SimplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a URem, fold the result or return null.
|
||||
Value *SimplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FRem, fold the result or return null.
|
||||
Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a Shl, fold the result or return null.
|
||||
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a LShr, fold the result or return null.
|
||||
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a AShr, fold the result or return nulll.
|
||||
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an And, fold the result or return null.
|
||||
Value *SimplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an Or, fold the result or return null.
|
||||
Value *SimplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an Xor, fold the result or return null.
|
||||
Value *SimplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q);
|
||||
Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an ICmpInst, fold the result or return null.
|
||||
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FCmpInst, fold the result or return null.
|
||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
FastMathFlags FMF, const SimplifyQuery &Q);
|
||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
FastMathFlags FMF, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a SelectInst, fold the result or return null.
|
||||
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a GetElementPtrInst, fold the result or return null.
|
||||
Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an InsertValueInst, fold the result or return null.
|
||||
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
|
||||
ArrayRef<unsigned> Idxs, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an ExtractValueInst, fold the result or return null.
|
||||
Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an ExtractElementInst, fold the result or return null.
|
||||
Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a CastInst, fold the result or return null.
|
||||
Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a ShuffleVectorInst, fold the result or return null.
|
||||
Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
|
||||
Type *RetTy, const SimplifyQuery &Q);
|
||||
Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
|
||||
Type *RetTy, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
//=== Helper functions for higher up the class hierarchy.
|
||||
|
||||
|
|
@ -331,63 +183,29 @@ namespace llvm {
|
|||
/// Given operands for a CmpInst, fold the result or return null.
|
||||
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for a BinaryOperator, fold the result or return null.
|
||||
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
const SimplifyQuery &Q);
|
||||
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given operands for an FP BinaryOperator, fold the result or return null.
|
||||
/// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the
|
||||
/// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp.
|
||||
Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
FastMathFlags FMF, const SimplifyQuery &Q);
|
||||
Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
|
||||
FastMathFlags FMF, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given a function and iterators over arguments, fold the result or return
|
||||
/// null.
|
||||
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
|
||||
User::op_iterator ArgEnd, const SimplifyQuery &Q);
|
||||
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
|
||||
User::op_iterator ArgEnd, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// Given a function and set of arguments, fold the result or return null.
|
||||
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const SimplifyQuery &Q);
|
||||
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
const Instruction *CxtI = nullptr);
|
||||
|
||||
/// See if we can compute a simplified version of this instruction. If not,
|
||||
/// return null.
|
||||
Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q,
|
||||
OptimizationRemarkEmitter *ORE = nullptr);
|
||||
Value *SimplifyInstruction(Instruction *I, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr,
|
||||
OptimizationRemarkEmitter *ORE = nullptr);
|
||||
|
||||
/// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively.
|
||||
///
|
||||
|
|
@ -411,6 +229,15 @@ namespace llvm {
|
|||
const TargetLibraryInfo *TLI = nullptr,
|
||||
const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr);
|
||||
// These helper functions return a SimplifyQuery structure that contains as
|
||||
// many of the optional analysis we use as are currently valid. This is the
|
||||
// strongly preferred way of constructing SimplifyQuery in passes.
|
||||
const SimplifyQuery getBestSimplifyQuery(Pass &, Function &);
|
||||
template <class T, class... TArgs>
|
||||
const SimplifyQuery getBestSimplifyQuery(AnalysisManager<T, TArgs...> &,
|
||||
Function &);
|
||||
const SimplifyQuery getBestSimplifyQuery(LoopStandardAnalysisResults &,
|
||||
const DataLayout &);
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ class ObjectSizeOffsetEvaluator
|
|||
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
|
||||
|
||||
typedef IRBuilder<TargetFolder> BuilderTy;
|
||||
typedef std::pair<WeakVH, WeakVH> WeakEvalType;
|
||||
typedef std::pair<WeakTrackingVH, WeakTrackingVH> WeakEvalType;
|
||||
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
|
||||
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ namespace llvm {
|
|||
/// replace congruent phis with their most canonical representative. Return
|
||||
/// the number of phis eliminated.
|
||||
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
|
||||
SmallVectorImpl<WeakVH> &DeadInsts,
|
||||
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
|
||||
const TargetTransformInfo *TTI = nullptr);
|
||||
|
||||
/// Insert code to directly compute the specified SCEV expression into the
|
||||
|
|
|
|||
|
|
@ -197,6 +197,12 @@ public:
|
|||
int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
|
||||
ArrayRef<const Value *> Arguments) const;
|
||||
|
||||
/// \return The estimated number of case clusters when lowering \p 'SI'.
|
||||
/// \p JTSize Set a jump table size only when \p SI is suitable for a jump
|
||||
/// table.
|
||||
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
|
||||
unsigned &JTSize) const;
|
||||
|
||||
/// \brief Estimate the cost of a given IR user when lowered.
|
||||
///
|
||||
/// This can estimate the cost of either a ConstantExpr or Instruction when
|
||||
|
|
@ -764,6 +770,8 @@ public:
|
|||
ArrayRef<Type *> ParamTys) = 0;
|
||||
virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
|
||||
ArrayRef<const Value *> Arguments) = 0;
|
||||
virtual unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
|
||||
unsigned &JTSize) = 0;
|
||||
virtual int getUserCost(const User *U) = 0;
|
||||
virtual bool hasBranchDivergence() = 0;
|
||||
virtual bool isSourceOfDivergence(const Value *V) = 0;
|
||||
|
|
@ -1067,6 +1075,10 @@ public:
|
|||
unsigned getMaxInterleaveFactor(unsigned VF) override {
|
||||
return Impl.getMaxInterleaveFactor(VF);
|
||||
}
|
||||
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
|
||||
unsigned &JTSize) override {
|
||||
return Impl.getEstimatedNumberOfCaseClusters(SI, JTSize);
|
||||
}
|
||||
unsigned
|
||||
getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
|
||||
OperandValueKind Opd2Info,
|
||||
|
|
|
|||
|
|
@ -114,6 +114,12 @@ public:
|
|||
return TTI::TCC_Free;
|
||||
}
|
||||
|
||||
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
|
||||
unsigned &JTSize) {
|
||||
JTSize = 0;
|
||||
return SI.getNumCases();
|
||||
}
|
||||
|
||||
unsigned getCallCost(FunctionType *FTy, int NumArgs) {
|
||||
assert(FTy && "FunctionType must be provided to this routine.");
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ template <typename T> class ArrayRef;
|
|||
/// \p KnownZero the set of bits that are known to be zero
|
||||
/// \p KnownOne the set of bits that are known to be one
|
||||
void computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
|
||||
APInt &KnownZero, APInt &KnownOne);
|
||||
KnownBits &Known);
|
||||
/// Return true if LHS and RHS have no common bits set.
|
||||
bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
|
||||
const DataLayout &DL,
|
||||
|
|
@ -417,7 +417,7 @@ template <typename T> class ArrayRef;
|
|||
///
|
||||
/// Note that this currently only considers the basic block that is
|
||||
/// the parent of I.
|
||||
bool isKnownNotFullPoison(const Instruction *PoisonI);
|
||||
bool programUndefinedIfFullPoison(const Instruction *PoisonI);
|
||||
|
||||
/// \brief Specific patterns of select instructions we can match.
|
||||
enum SelectPatternFlavor {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,10 @@ namespace llvm {
|
|||
|
||||
/// Parse the specified bitcode buffer, returning the module summary index.
|
||||
Expected<std::unique_ptr<ModuleSummaryIndex>> getSummary();
|
||||
|
||||
/// Parse the specified bitcode buffer and merge its module summary index
|
||||
/// into CombinedIndex.
|
||||
Error readSummary(ModuleSummaryIndex &CombinedIndex, unsigned ModuleId);
|
||||
};
|
||||
|
||||
/// Returns a list of modules in the specified bitcode buffer.
|
||||
|
|
@ -141,6 +145,18 @@ namespace llvm {
|
|||
Expected<std::unique_ptr<ModuleSummaryIndex>>
|
||||
getModuleSummaryIndex(MemoryBufferRef Buffer);
|
||||
|
||||
/// Parse the specified bitcode buffer and merge the index into CombinedIndex.
|
||||
Error readModuleSummaryIndex(MemoryBufferRef Buffer,
|
||||
ModuleSummaryIndex &CombinedIndex,
|
||||
unsigned ModuleId);
|
||||
|
||||
/// 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
|
||||
/// this function will return nullptr.
|
||||
Expected<std::unique_ptr<ModuleSummaryIndex>>
|
||||
getModuleSummaryIndexForFile(StringRef Path);
|
||||
|
||||
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
|
||||
/// for an LLVM IR bitcode wrapper.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -545,7 +545,8 @@ enum AttributeKindCodes {
|
|||
ATTR_KIND_INACCESSIBLEMEM_ONLY = 49,
|
||||
ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
|
||||
ATTR_KIND_ALLOC_SIZE = 51,
|
||||
ATTR_KIND_WRITEONLY = 52
|
||||
ATTR_KIND_WRITEONLY = 52,
|
||||
ATTR_KIND_SPECULATABLE = 53
|
||||
};
|
||||
|
||||
enum ComdatSelectionKindCodes {
|
||||
|
|
|
|||
|
|
@ -171,6 +171,62 @@ public:
|
|||
return BaseT::getIntrinsicCost(IID, RetTy, ParamTys);
|
||||
}
|
||||
|
||||
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
|
||||
unsigned &JumpTableSize) {
|
||||
/// Try to find the estimated number of clusters. Note that the number of
|
||||
/// clusters identified in this function could be different from the actural
|
||||
/// numbers found in lowering. This function ignore switches that are
|
||||
/// lowered with a mix of jump table / bit test / BTree. This function was
|
||||
/// initially intended to be used when estimating the cost of switch in
|
||||
/// inline cost heuristic, but it's a generic cost model to be used in other
|
||||
/// places (e.g., in loop unrolling).
|
||||
unsigned N = SI.getNumCases();
|
||||
const TargetLoweringBase *TLI = getTLI();
|
||||
const DataLayout &DL = this->getDataLayout();
|
||||
|
||||
JumpTableSize = 0;
|
||||
bool IsJTAllowed = TLI->areJTsAllowed(SI.getParent()->getParent());
|
||||
|
||||
// Early exit if both a jump table and bit test are not allowed.
|
||||
if (N < 1 || (!IsJTAllowed && DL.getPointerSizeInBits() < N))
|
||||
return N;
|
||||
|
||||
APInt MaxCaseVal = SI.case_begin()->getCaseValue()->getValue();
|
||||
APInt MinCaseVal = MaxCaseVal;
|
||||
for (auto CI : SI.cases()) {
|
||||
const APInt &CaseVal = CI.getCaseValue()->getValue();
|
||||
if (CaseVal.sgt(MaxCaseVal))
|
||||
MaxCaseVal = CaseVal;
|
||||
if (CaseVal.slt(MinCaseVal))
|
||||
MinCaseVal = CaseVal;
|
||||
}
|
||||
|
||||
// Check if suitable for a bit test
|
||||
if (N <= DL.getPointerSizeInBits()) {
|
||||
SmallPtrSet<const BasicBlock *, 4> Dests;
|
||||
for (auto I : SI.cases())
|
||||
Dests.insert(I.getCaseSuccessor());
|
||||
|
||||
if (TLI->isSuitableForBitTests(Dests.size(), N, MinCaseVal, MaxCaseVal,
|
||||
DL))
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if suitable for a jump table.
|
||||
if (IsJTAllowed) {
|
||||
if (N < 2 || N < TLI->getMinimumJumpTableEntries())
|
||||
return N;
|
||||
uint64_t Range =
|
||||
(MaxCaseVal - MinCaseVal).getLimitedValue(UINT64_MAX - 1) + 1;
|
||||
// Check whether a range of clusters is dense enough for a jump table
|
||||
if (TLI->isSuitableForJumpTable(&SI, N, Range)) {
|
||||
JumpTableSize = Range;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return N;
|
||||
}
|
||||
|
||||
unsigned getJumpBufAlignment() { return getTLI()->getJumpBufAlignment(); }
|
||||
|
||||
unsigned getJumpBufSize() { return getTLI()->getJumpBufSize(); }
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/IR/InlineAsm.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
#include "llvm/Support/KnownBits.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -171,9 +172,8 @@ public:
|
|||
struct LiveOutInfo {
|
||||
unsigned NumSignBits : 31;
|
||||
unsigned IsValid : 1;
|
||||
APInt KnownOne, KnownZero;
|
||||
LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
|
||||
KnownZero(1, 0) {}
|
||||
KnownBits Known;
|
||||
LiveOutInfo() : NumSignBits(0), IsValid(true), Known(1) {}
|
||||
};
|
||||
|
||||
/// Record the preferred extend type (ISD::SIGN_EXTEND or ISD::ZERO_EXTEND)
|
||||
|
|
@ -247,16 +247,16 @@ public:
|
|||
|
||||
/// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
|
||||
void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
|
||||
const APInt &KnownZero, const APInt &KnownOne) {
|
||||
const KnownBits &Known) {
|
||||
// Only install this information if it tells us something.
|
||||
if (NumSignBits == 1 && KnownZero == 0 && KnownOne == 0)
|
||||
if (NumSignBits == 1 && Known.Zero == 0 && Known.One == 0)
|
||||
return;
|
||||
|
||||
LiveOutRegInfo.grow(Reg);
|
||||
LiveOutInfo &LOI = LiveOutRegInfo[Reg];
|
||||
LOI.NumSignBits = NumSignBits;
|
||||
LOI.KnownOne = KnownOne;
|
||||
LOI.KnownZero = KnownZero;
|
||||
LOI.Known.One = Known.One;
|
||||
LOI.Known.Zero = Known.Zero;
|
||||
}
|
||||
|
||||
/// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination
|
||||
|
|
|
|||
|
|
@ -61,9 +61,6 @@ class InstructionSelector {
|
|||
public:
|
||||
virtual ~InstructionSelector() {}
|
||||
|
||||
/// This is executed before selecting a function.
|
||||
virtual void beginFunction(const MachineFunction &MF) {}
|
||||
|
||||
/// Select the (possibly generic) instruction \p I to only use target-specific
|
||||
/// opcodes. It is OK to insert multiple instructions, but they cannot be
|
||||
/// generic pre-isel instructions.
|
||||
|
|
|
|||
|
|
@ -216,6 +216,9 @@ namespace ISD {
|
|||
/// These nodes take two operands of the same value type, and produce two
|
||||
/// results. The first result is the normal add or sub result, the second
|
||||
/// result is the carry flag result.
|
||||
/// FIXME: These nodes are deprecated in favor of ADDCARRY and SUBCARRY.
|
||||
/// They are kept around for now to provide a smooth transition path
|
||||
/// toward the use of ADDCARRY/SUBCARRY and will eventually be removed.
|
||||
ADDC, SUBC,
|
||||
|
||||
/// Carry-using nodes for multiple precision addition and subtraction. These
|
||||
|
|
@ -227,6 +230,16 @@ namespace ISD {
|
|||
/// values.
|
||||
ADDE, SUBE,
|
||||
|
||||
/// Carry-using nodes for multiple precision addition and subtraction.
|
||||
/// These nodes take three operands: The first two are the normal lhs and
|
||||
/// rhs to the add or sub, and the third is a boolean indicating if there
|
||||
/// is an incoming carry. These nodes produce two results: the normal
|
||||
/// result of the add or sub, and the output carry so they can be chained
|
||||
/// together. The use of this opcode is preferable to adde/sube if the
|
||||
/// target supports it, as the carry is a regular value rather than a
|
||||
/// glue, which allows further optimisation.
|
||||
ADDCARRY, SUBCARRY,
|
||||
|
||||
/// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
|
||||
/// These nodes take two operands: the normal LHS and RHS to the add. They
|
||||
/// produce two results: the normal result of the add, and a boolean that
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ struct MachineFrameInfo {
|
|||
bool HasCalls = false;
|
||||
StringValue StackProtector;
|
||||
// TODO: Serialize FunctionContextIdx
|
||||
unsigned MaxCallFrameSize = 0;
|
||||
unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet.
|
||||
bool HasOpaqueSPAdjustment = false;
|
||||
bool HasVAStart = false;
|
||||
bool HasMustTailInVarArgFunc = false;
|
||||
|
|
@ -366,7 +366,7 @@ template <> struct MappingTraits<MachineFrameInfo> {
|
|||
YamlIO.mapOptional("hasCalls", MFI.HasCalls);
|
||||
YamlIO.mapOptional("stackProtector", MFI.StackProtector,
|
||||
StringValue()); // Don't print it out when it's empty.
|
||||
YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
|
||||
YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, ~0u);
|
||||
YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
|
||||
YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
|
||||
YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc);
|
||||
|
|
|
|||
|
|
@ -21,15 +21,9 @@
|
|||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
class DataLayout;
|
||||
class TargetRegisterClass;
|
||||
class Type;
|
||||
class MachineFunction;
|
||||
class MachineBasicBlock;
|
||||
class TargetFrameLowering;
|
||||
class TargetMachine;
|
||||
class BitVector;
|
||||
class Value;
|
||||
class AllocaInst;
|
||||
|
||||
/// The CalleeSavedInfo class tracks the information need to locate where a
|
||||
|
|
@ -226,7 +220,7 @@ class MachineFrameInfo {
|
|||
/// setup/destroy pseudo instructions (as defined in the TargetFrameInfo
|
||||
/// class). This information is important for frame pointer elimination.
|
||||
/// It is only valid during and after prolog/epilog code insertion.
|
||||
unsigned MaxCallFrameSize = 0;
|
||||
unsigned MaxCallFrameSize = ~0u;
|
||||
|
||||
/// The prolog/epilog code inserter fills in this vector with each
|
||||
/// callee saved register saved in the frame. Beyond its use by the prolog/
|
||||
|
|
@ -531,7 +525,16 @@ public:
|
|||
/// CallFrameSetup/Destroy pseudo instructions are used by the target, and
|
||||
/// then only during or after prolog/epilog code insertion.
|
||||
///
|
||||
unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
|
||||
unsigned getMaxCallFrameSize() const {
|
||||
// TODO: Enable this assert when targets are fixed.
|
||||
//assert(isMaxCallFrameSizeComputed() && "MaxCallFrameSize not computed yet");
|
||||
if (!isMaxCallFrameSizeComputed())
|
||||
return 0;
|
||||
return MaxCallFrameSize;
|
||||
}
|
||||
bool isMaxCallFrameSizeComputed() const {
|
||||
return MaxCallFrameSize != ~0u;
|
||||
}
|
||||
void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
|
||||
|
||||
/// Create a new object at a fixed location on the stack.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
struct KnownBits;
|
||||
class MachineConstantPoolValue;
|
||||
class MachineFunction;
|
||||
class MDNode;
|
||||
|
|
@ -687,6 +688,10 @@ public:
|
|||
/// Example: shuffle A, B, <0,5,2,7> -> shuffle B, A, <4,1,6,3>
|
||||
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV);
|
||||
|
||||
/// Convert Op, which must be of float type, to the
|
||||
/// float type VT, by either extending or rounding (by truncation).
|
||||
SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT);
|
||||
|
||||
/// Convert Op, which must be of integer type, to the
|
||||
/// integer type VT, by either any-extending or truncating it.
|
||||
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
|
||||
|
|
@ -773,7 +778,7 @@ public:
|
|||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDUse> Ops);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDValue> Ops, const SDNodeFlags *Flags = nullptr);
|
||||
ArrayRef<SDValue> Ops, const SDNodeFlags Flags = SDNodeFlags());
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys,
|
||||
ArrayRef<SDValue> Ops);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs,
|
||||
|
|
@ -781,9 +786,10 @@ public:
|
|||
|
||||
// Specialize based on number of operands.
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N,
|
||||
const SDNodeFlags Flags = SDNodeFlags());
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
|
||||
SDValue N2, const SDNodeFlags *Flags = nullptr);
|
||||
SDValue N2, const SDNodeFlags Flags = SDNodeFlags());
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
|
||||
SDValue N2, SDValue N3);
|
||||
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
|
||||
|
|
@ -1103,7 +1109,7 @@ public:
|
|||
|
||||
/// Get the specified node if it's already available, or else return NULL.
|
||||
SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops,
|
||||
const SDNodeFlags *Flags = nullptr);
|
||||
const SDNodeFlags Flags = SDNodeFlags());
|
||||
|
||||
/// Creates a SDDbgValue node.
|
||||
SDDbgValue *getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R,
|
||||
|
|
@ -1266,7 +1272,7 @@ public:
|
|||
|
||||
SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
|
||||
ArrayRef<SDValue> Ops,
|
||||
const SDNodeFlags *Flags = nullptr);
|
||||
const SDNodeFlags Flags = SDNodeFlags());
|
||||
|
||||
/// Constant fold a setcc to true or false.
|
||||
SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
|
||||
|
|
@ -1283,21 +1289,19 @@ public:
|
|||
const;
|
||||
|
||||
/// Determine which bits of Op are known to be either zero or one and return
|
||||
/// them in the KnownZero/KnownOne bitsets. For vectors, the known bits are
|
||||
/// those that are shared by every vector element.
|
||||
/// them in Known. For vectors, the known bits are those that are shared by
|
||||
/// every vector element.
|
||||
/// Targets can implement the computeKnownBitsForTargetNode method in the
|
||||
/// TargetLowering class to allow target nodes to be understood.
|
||||
void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
|
||||
unsigned Depth = 0) const;
|
||||
void computeKnownBits(SDValue Op, KnownBits &Known, unsigned Depth = 0) const;
|
||||
|
||||
/// Determine which bits of Op are known to be either zero or one and return
|
||||
/// them in the KnownZero/KnownOne bitsets. The DemandedElts argument allows
|
||||
/// us to only collect the known bits that are shared by the requested vector
|
||||
/// elements.
|
||||
/// them in Known. The DemandedElts argument allows us to only collect the
|
||||
/// known bits that are shared by the requested vector elements.
|
||||
/// Targets can implement the computeKnownBitsForTargetNode method in the
|
||||
/// TargetLowering class to allow target nodes to be understood.
|
||||
void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
|
||||
const APInt &DemandedElts, unsigned Depth = 0) const;
|
||||
void computeKnownBits(SDValue Op, KnownBits &Known, const APInt &DemandedElts,
|
||||
unsigned Depth = 0) const;
|
||||
|
||||
/// Used to represent the possible overflow behavior of an operation.
|
||||
/// Never: the operation cannot overflow.
|
||||
|
|
@ -1439,10 +1443,6 @@ private:
|
|||
|
||||
void allnodes_clear();
|
||||
|
||||
SDNode *GetBinarySDNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs,
|
||||
SDValue N1, SDValue N2,
|
||||
const SDNodeFlags *Flags = nullptr);
|
||||
|
||||
/// Look up the node specified by ID in CSEMap. If it exists, return it. If
|
||||
/// not, return the insertion token that will make insertion faster. This
|
||||
/// overload is for nodes other than Constant or ConstantFP, use the other one
|
||||
|
|
|
|||
|
|
@ -341,6 +341,11 @@ template<> struct simplify_type<SDUse> {
|
|||
/// the backend.
|
||||
struct SDNodeFlags {
|
||||
private:
|
||||
// This bit is used to determine if the flags are in a defined state.
|
||||
// Flag bits can only be masked out during intersection if the masking flags
|
||||
// are defined.
|
||||
bool AnyDefined : 1;
|
||||
|
||||
bool NoUnsignedWrap : 1;
|
||||
bool NoSignedWrap : 1;
|
||||
bool Exact : 1;
|
||||
|
|
@ -355,22 +360,57 @@ private:
|
|||
public:
|
||||
/// Default constructor turns off all optimization flags.
|
||||
SDNodeFlags()
|
||||
: NoUnsignedWrap(false), NoSignedWrap(false), Exact(false),
|
||||
UnsafeAlgebra(false), NoNaNs(false), NoInfs(false),
|
||||
: AnyDefined(false), NoUnsignedWrap(false), NoSignedWrap(false),
|
||||
Exact(false), UnsafeAlgebra(false), NoNaNs(false), NoInfs(false),
|
||||
NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false),
|
||||
AllowContract(false) {}
|
||||
|
||||
/// Sets the state of the flags to the defined state.
|
||||
void setDefined() { AnyDefined = true; }
|
||||
/// Returns true if the flags are in a defined state.
|
||||
bool isDefined() const { return AnyDefined; }
|
||||
|
||||
// These are mutators for each flag.
|
||||
void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; }
|
||||
void setNoSignedWrap(bool b) { NoSignedWrap = b; }
|
||||
void setExact(bool b) { Exact = b; }
|
||||
void setUnsafeAlgebra(bool b) { UnsafeAlgebra = b; }
|
||||
void setNoNaNs(bool b) { NoNaNs = b; }
|
||||
void setNoInfs(bool b) { NoInfs = b; }
|
||||
void setNoSignedZeros(bool b) { NoSignedZeros = b; }
|
||||
void setAllowReciprocal(bool b) { AllowReciprocal = b; }
|
||||
void setVectorReduction(bool b) { VectorReduction = b; }
|
||||
void setAllowContract(bool b) { AllowContract = b; }
|
||||
void setNoUnsignedWrap(bool b) {
|
||||
setDefined();
|
||||
NoUnsignedWrap = b;
|
||||
}
|
||||
void setNoSignedWrap(bool b) {
|
||||
setDefined();
|
||||
NoSignedWrap = b;
|
||||
}
|
||||
void setExact(bool b) {
|
||||
setDefined();
|
||||
Exact = b;
|
||||
}
|
||||
void setUnsafeAlgebra(bool b) {
|
||||
setDefined();
|
||||
UnsafeAlgebra = b;
|
||||
}
|
||||
void setNoNaNs(bool b) {
|
||||
setDefined();
|
||||
NoNaNs = b;
|
||||
}
|
||||
void setNoInfs(bool b) {
|
||||
setDefined();
|
||||
NoInfs = b;
|
||||
}
|
||||
void setNoSignedZeros(bool b) {
|
||||
setDefined();
|
||||
NoSignedZeros = b;
|
||||
}
|
||||
void setAllowReciprocal(bool b) {
|
||||
setDefined();
|
||||
AllowReciprocal = b;
|
||||
}
|
||||
void setVectorReduction(bool b) {
|
||||
setDefined();
|
||||
VectorReduction = b;
|
||||
}
|
||||
void setAllowContract(bool b) {
|
||||
setDefined();
|
||||
AllowContract = b;
|
||||
}
|
||||
|
||||
// These are accessors for each flag.
|
||||
bool hasNoUnsignedWrap() const { return NoUnsignedWrap; }
|
||||
|
|
@ -385,17 +425,20 @@ public:
|
|||
bool hasAllowContract() const { return AllowContract; }
|
||||
|
||||
/// Clear any flags in this flag set that aren't also set in Flags.
|
||||
void intersectWith(const SDNodeFlags *Flags) {
|
||||
NoUnsignedWrap &= Flags->NoUnsignedWrap;
|
||||
NoSignedWrap &= Flags->NoSignedWrap;
|
||||
Exact &= Flags->Exact;
|
||||
UnsafeAlgebra &= Flags->UnsafeAlgebra;
|
||||
NoNaNs &= Flags->NoNaNs;
|
||||
NoInfs &= Flags->NoInfs;
|
||||
NoSignedZeros &= Flags->NoSignedZeros;
|
||||
AllowReciprocal &= Flags->AllowReciprocal;
|
||||
VectorReduction &= Flags->VectorReduction;
|
||||
AllowContract &= Flags->AllowContract;
|
||||
/// If the given Flags are undefined then don't do anything.
|
||||
void intersectWith(const SDNodeFlags Flags) {
|
||||
if (!Flags.isDefined())
|
||||
return;
|
||||
NoUnsignedWrap &= Flags.NoUnsignedWrap;
|
||||
NoSignedWrap &= Flags.NoSignedWrap;
|
||||
Exact &= Flags.Exact;
|
||||
UnsafeAlgebra &= Flags.UnsafeAlgebra;
|
||||
NoNaNs &= Flags.NoNaNs;
|
||||
NoInfs &= Flags.NoInfs;
|
||||
NoSignedZeros &= Flags.NoSignedZeros;
|
||||
AllowReciprocal &= Flags.AllowReciprocal;
|
||||
VectorReduction &= Flags.VectorReduction;
|
||||
AllowContract &= Flags.AllowContract;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -527,6 +570,8 @@ private:
|
|||
/// Return a pointer to the specified value type.
|
||||
static const EVT *getValueTypeList(EVT VT);
|
||||
|
||||
SDNodeFlags Flags;
|
||||
|
||||
public:
|
||||
/// Unique and persistent id per SDNode in the DAG.
|
||||
/// Used for debug printing.
|
||||
|
|
@ -799,12 +844,12 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/// This could be defined as a virtual function and implemented more simply
|
||||
/// and directly, but it is not to avoid creating a vtable for this class.
|
||||
const SDNodeFlags *getFlags() const;
|
||||
const SDNodeFlags getFlags() const { return Flags; }
|
||||
void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
|
||||
|
||||
/// Clear any flags in this node that aren't also set in Flags.
|
||||
void intersectFlagsWith(const SDNodeFlags *Flags);
|
||||
/// If Flags is not in a defined state then this has no effect.
|
||||
void intersectFlagsWith(const SDNodeFlags Flags);
|
||||
|
||||
/// Return the number of values defined/returned by this operator.
|
||||
unsigned getNumValues() const { return NumValues; }
|
||||
|
|
@ -1032,43 +1077,6 @@ inline void SDUse::setNode(SDNode *N) {
|
|||
if (N) N->addUse(*this);
|
||||
}
|
||||
|
||||
/// Returns true if the opcode is a binary operation with flags.
|
||||
static bool isBinOpWithFlags(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case ISD::SDIV:
|
||||
case ISD::UDIV:
|
||||
case ISD::SRA:
|
||||
case ISD::SRL:
|
||||
case ISD::MUL:
|
||||
case ISD::ADD:
|
||||
case ISD::SUB:
|
||||
case ISD::SHL:
|
||||
case ISD::FADD:
|
||||
case ISD::FDIV:
|
||||
case ISD::FMUL:
|
||||
case ISD::FREM:
|
||||
case ISD::FSUB:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// This class is an extension of BinarySDNode
|
||||
/// used from those opcodes that have associated extra flags.
|
||||
class BinaryWithFlagsSDNode : public SDNode {
|
||||
public:
|
||||
SDNodeFlags Flags;
|
||||
|
||||
BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
|
||||
SDVTList VTs, const SDNodeFlags &NodeFlags)
|
||||
: SDNode(Opc, Order, dl, VTs), Flags(NodeFlags) {}
|
||||
|
||||
static bool classof(const SDNode *N) {
|
||||
return isBinOpWithFlags(N->getOpcode());
|
||||
}
|
||||
};
|
||||
|
||||
/// This class is used to form a handle around another node that
|
||||
/// is persistent and is updated across invocations of replaceAllUsesWith on its
|
||||
/// operand. This node should be directly created by end-users and not added to
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ def v64i1 : ValueType<64 , 19>; // 64 x i1 vector value
|
|||
def v512i1 : ValueType<512, 20>; // 512 x i1 vector value
|
||||
def v1024i1: ValueType<1024,21>; //1024 x i1 vector value
|
||||
|
||||
def v1i8 : ValueType<16, 22>; // 1 x i8 vector value
|
||||
def v1i8 : ValueType<8, 22>; // 1 x i8 vector value
|
||||
def v2i8 : ValueType<16 , 23>; // 2 x i8 vector value
|
||||
def v4i8 : ValueType<32 , 24>; // 4 x i8 vector value
|
||||
def v8i8 : ValueType<64 , 25>; // 8 x i8 vector value
|
||||
|
|
|
|||
|
|
@ -50,8 +50,10 @@ public:
|
|||
|
||||
template <typename Kind>
|
||||
struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> {
|
||||
Error operator()(BinaryStreamRef Stream, uint32_t &Len,
|
||||
codeview::CVRecord<Kind> &Item) const {
|
||||
typedef void ContextType;
|
||||
|
||||
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
|
||||
codeview::CVRecord<Kind> &Item, void *Ctx) {
|
||||
using namespace codeview;
|
||||
const RecordPrefix *Prefix = nullptr;
|
||||
BinaryStreamReader Reader(Stream);
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ enum class ModifierOptions : uint16_t {
|
|||
};
|
||||
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions)
|
||||
|
||||
enum class ModuleSubstreamKind : uint32_t {
|
||||
enum class ModuleDebugFragmentKind : uint32_t {
|
||||
None = 0,
|
||||
Symbols = 0xf1,
|
||||
Lines = 0xf2,
|
||||
|
|
@ -547,7 +547,8 @@ enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland };
|
|||
enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
|
||||
|
||||
enum LineFlags : uint16_t {
|
||||
HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
|
||||
LF_None = 0,
|
||||
LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,27 +127,6 @@ public:
|
|||
bool isNeverStepInto() const { return LineInf.isNeverStepInto(); }
|
||||
};
|
||||
|
||||
enum class InlineeLinesSignature : uint32_t {
|
||||
Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
|
||||
ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
|
||||
};
|
||||
|
||||
struct InlineeSourceLine {
|
||||
TypeIndex Inlinee; // ID of the function that was inlined.
|
||||
ulittle32_t FileID; // Offset into FileChecksums subsection.
|
||||
ulittle32_t SourceLineNum; // First line of inlined code.
|
||||
// If extra files present:
|
||||
// ulittle32_t ExtraFileCount;
|
||||
// ulittle32_t Files[];
|
||||
};
|
||||
|
||||
struct FileChecksum {
|
||||
ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
|
||||
uint8_t ChecksumSize; // Number of bytes of checksum.
|
||||
uint8_t ChecksumKind; // FileChecksumKind
|
||||
// Checksum bytes follow.
|
||||
};
|
||||
|
||||
} // namespace codeview
|
||||
} // namespace llvm
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
//===- ModuleDebugFileChecksumFragment.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_MODULEDEBUGFILECHECKSUMFRAGMENT_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/BinaryStreamArray.h"
|
||||
#include "llvm/Support/BinaryStreamReader.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
struct FileChecksumEntry {
|
||||
uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
|
||||
FileChecksumKind Kind; // The type of checksum.
|
||||
ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> {
|
||||
public:
|
||||
typedef void ContextType;
|
||||
|
||||
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
|
||||
codeview::FileChecksumEntry &Item, void *Ctx);
|
||||
};
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
class ModuleDebugFileChecksumFragmentRef final : public ModuleDebugFragmentRef {
|
||||
typedef VarStreamArray<codeview::FileChecksumEntry> FileChecksumArray;
|
||||
typedef FileChecksumArray::Iterator Iterator;
|
||||
|
||||
public:
|
||||
ModuleDebugFileChecksumFragmentRef()
|
||||
: ModuleDebugFragmentRef(ModuleDebugFragmentKind::FileChecksums) {}
|
||||
|
||||
static bool classof(const ModuleDebugFragmentRef *S) {
|
||||
return S->kind() == ModuleDebugFragmentKind::FileChecksums;
|
||||
}
|
||||
|
||||
Error initialize(BinaryStreamReader Reader);
|
||||
|
||||
Iterator begin() const { return Checksums.begin(); }
|
||||
Iterator end() const { return Checksums.end(); }
|
||||
|
||||
const FileChecksumArray &getArray() const { return Checksums; }
|
||||
|
||||
private:
|
||||
FileChecksumArray Checksums;
|
||||
};
|
||||
|
||||
class ModuleDebugFileChecksumFragment final : public ModuleDebugFragment {
|
||||
public:
|
||||
ModuleDebugFileChecksumFragment();
|
||||
|
||||
static bool classof(const ModuleDebugFragment *S) {
|
||||
return S->kind() == ModuleDebugFragmentKind::FileChecksums;
|
||||
}
|
||||
|
||||
void addChecksum(uint32_t StringTableOffset, FileChecksumKind Kind,
|
||||
ArrayRef<uint8_t> Bytes);
|
||||
|
||||
uint32_t calculateSerializedLength() override;
|
||||
Error commit(BinaryStreamWriter &Writer) override;
|
||||
uint32_t mapChecksumOffset(uint32_t StringTableOffset) const;
|
||||
|
||||
private:
|
||||
DenseMap<uint32_t, uint32_t> OffsetMap;
|
||||
uint32_t SerializedSize = 0;
|
||||
llvm::BumpPtrAllocator Storage;
|
||||
std::vector<FileChecksumEntry> Checksums;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
48
include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
Normal file
48
include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
//===- ModuleDebugFragment.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_MODULEDEBUGFRAGMENT_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/Support/BinaryStreamWriter.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
class ModuleDebugFragmentRef {
|
||||
public:
|
||||
explicit ModuleDebugFragmentRef(ModuleDebugFragmentKind Kind) : Kind(Kind) {}
|
||||
virtual ~ModuleDebugFragmentRef();
|
||||
|
||||
ModuleDebugFragmentKind kind() const { return Kind; }
|
||||
|
||||
protected:
|
||||
ModuleDebugFragmentKind Kind;
|
||||
};
|
||||
|
||||
class ModuleDebugFragment {
|
||||
public:
|
||||
explicit ModuleDebugFragment(ModuleDebugFragmentKind Kind) : Kind(Kind) {}
|
||||
virtual ~ModuleDebugFragment();
|
||||
|
||||
ModuleDebugFragmentKind kind() const { return Kind; }
|
||||
|
||||
virtual Error commit(BinaryStreamWriter &Writer) = 0;
|
||||
virtual uint32_t calculateSerializedLength() = 0;
|
||||
|
||||
protected:
|
||||
ModuleDebugFragmentKind Kind;
|
||||
};
|
||||
|
||||
} // namespace codeview
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
|
||||
78
include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
Normal file
78
include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//===- ModuleDebugFragment.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_MODULEDEBUGFRAGMENTRECORD_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/Support/BinaryStreamArray.h"
|
||||
#include "llvm/Support/BinaryStreamRef.h"
|
||||
#include "llvm/Support/BinaryStreamWriter.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
class ModuleDebugFragment;
|
||||
|
||||
// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
|
||||
struct ModuleDebugFragmentHeader {
|
||||
support::ulittle32_t Kind; // codeview::ModuleDebugFragmentKind enum
|
||||
support::ulittle32_t Length; // number of bytes occupied by this record.
|
||||
};
|
||||
|
||||
class ModuleDebugFragmentRecord {
|
||||
public:
|
||||
ModuleDebugFragmentRecord();
|
||||
ModuleDebugFragmentRecord(ModuleDebugFragmentKind Kind, BinaryStreamRef Data);
|
||||
|
||||
static Error initialize(BinaryStreamRef Stream,
|
||||
ModuleDebugFragmentRecord &Info);
|
||||
|
||||
uint32_t getRecordLength() const;
|
||||
ModuleDebugFragmentKind kind() const;
|
||||
BinaryStreamRef getRecordData() const;
|
||||
|
||||
private:
|
||||
ModuleDebugFragmentKind Kind;
|
||||
BinaryStreamRef Data;
|
||||
};
|
||||
|
||||
class ModuleDebugFragmentRecordBuilder {
|
||||
public:
|
||||
ModuleDebugFragmentRecordBuilder(ModuleDebugFragmentKind Kind,
|
||||
ModuleDebugFragment &Frag);
|
||||
uint32_t calculateSerializedLength();
|
||||
Error commit(BinaryStreamWriter &Writer);
|
||||
|
||||
private:
|
||||
ModuleDebugFragmentKind Kind;
|
||||
ModuleDebugFragment &Frag;
|
||||
};
|
||||
|
||||
typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray;
|
||||
|
||||
} // namespace codeview
|
||||
|
||||
template <>
|
||||
struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> {
|
||||
typedef void ContextType;
|
||||
|
||||
static Error extract(BinaryStreamRef Stream, uint32_t &Length,
|
||||
codeview::ModuleDebugFragmentRecord &Info, void *Ctx) {
|
||||
if (auto EC = codeview::ModuleDebugFragmentRecord::initialize(Stream, Info))
|
||||
return EC;
|
||||
Length = Info.getRecordLength();
|
||||
return Error::success();
|
||||
}
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
|
||||
68
include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
Normal file
68
include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//===- ModuleDebugFragmentVisitor.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_MODULEDEBUGFRAGMENTVISITOR_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
|
||||
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace codeview {
|
||||
|
||||
class ModuleDebugFileChecksumFragmentRef;
|
||||
class ModuleDebugFragmentRecord;
|
||||
class ModuleDebugInlineeLineFragmentRef;
|
||||
class ModuleDebugLineFragmentRef;
|
||||
class ModuleDebugUnknownFragmentRef;
|
||||
|
||||
class ModuleDebugFragmentVisitor {
|
||||
public:
|
||||
virtual ~ModuleDebugFragmentVisitor() = default;
|
||||
|
||||
virtual Error visitUnknown(ModuleDebugUnknownFragmentRef &Unknown) {
|
||||
return Error::success();
|
||||
}
|
||||
virtual Error visitLines(ModuleDebugLineFragmentRef &Lines) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
virtual Error
|
||||
visitFileChecksums(ModuleDebugFileChecksumFragmentRef &Checksums) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
virtual Error visitInlineeLines(ModuleDebugInlineeLineFragmentRef &Inlinees) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
virtual Error finished() { return Error::success(); }
|
||||
};
|
||||
|
||||
Error visitModuleDebugFragment(const ModuleDebugFragmentRecord &R,
|
||||
ModuleDebugFragmentVisitor &V);
|
||||
|
||||
template <typename T>
|
||||
Error visitModuleDebugFragments(T &&FragmentRange,
|
||||
ModuleDebugFragmentVisitor &V) {
|
||||
for (const auto &L : FragmentRange) {
|
||||
if (auto EC = visitModuleDebugFragment(L, V))
|
||||
return EC;
|
||||
}
|
||||
if (auto EC = V.finished())
|
||||
return EC;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
} // end namespace codeview
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
//===- ModuleDebugInlineeLinesFragment.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_MODULEDEBUGINLINEELINESFRAGMENT_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGINLINEELINESFRAGMENT_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/Line.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
|
||||
#include "llvm/Support/BinaryStreamArray.h"
|
||||
#include "llvm/Support/BinaryStreamReader.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
class ModuleDebugInlineeLineFragmentRef;
|
||||
|
||||
enum class InlineeLinesSignature : uint32_t {
|
||||
Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE
|
||||
ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
|
||||
};
|
||||
|
||||
struct InlineeSourceLineHeader {
|
||||
TypeIndex Inlinee; // ID of the function that was inlined.
|
||||
support::ulittle32_t FileID; // Offset into FileChecksums subsection.
|
||||
support::ulittle32_t SourceLineNum; // First line of inlined code.
|
||||
// If extra files present:
|
||||
// ulittle32_t ExtraFileCount;
|
||||
// ulittle32_t Files[];
|
||||
};
|
||||
|
||||
struct InlineeSourceLine {
|
||||
const InlineeSourceLineHeader *Header;
|
||||
FixedStreamArray<support::ulittle32_t> ExtraFiles;
|
||||
};
|
||||
}
|
||||
|
||||
template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> {
|
||||
typedef codeview::ModuleDebugInlineeLineFragmentRef ContextType;
|
||||
|
||||
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
|
||||
codeview::InlineeSourceLine &Item,
|
||||
ContextType *Fragment);
|
||||
};
|
||||
|
||||
namespace codeview {
|
||||
class ModuleDebugInlineeLineFragmentRef final : public ModuleDebugFragmentRef {
|
||||
typedef VarStreamArray<InlineeSourceLine> LinesArray;
|
||||
typedef LinesArray::Iterator Iterator;
|
||||
|
||||
public:
|
||||
ModuleDebugInlineeLineFragmentRef();
|
||||
|
||||
static bool classof(const ModuleDebugFragmentRef *S) {
|
||||
return S->kind() == ModuleDebugFragmentKind::InlineeLines;
|
||||
}
|
||||
|
||||
Error initialize(BinaryStreamReader Reader);
|
||||
bool hasExtraFiles() const;
|
||||
|
||||
Iterator begin() const { return Lines.begin(); }
|
||||
Iterator end() const { return Lines.end(); }
|
||||
|
||||
private:
|
||||
InlineeLinesSignature Signature;
|
||||
VarStreamArray<InlineeSourceLine> Lines;
|
||||
};
|
||||
|
||||
class ModuleDebugInlineeLineFragment final : public ModuleDebugFragment {
|
||||
public:
|
||||
explicit ModuleDebugInlineeLineFragment(bool HasExtraFiles);
|
||||
|
||||
static bool classof(const ModuleDebugFragment *S) {
|
||||
return S->kind() == ModuleDebugFragmentKind::InlineeLines;
|
||||
}
|
||||
|
||||
Error commit(BinaryStreamWriter &Writer) override;
|
||||
uint32_t calculateSerializedLength() override;
|
||||
|
||||
void addInlineSite(TypeIndex FuncId, uint32_t FileOffset,
|
||||
uint32_t SourceLine);
|
||||
void addExtraFile(uint32_t FileOffset);
|
||||
|
||||
private:
|
||||
bool HasExtraFiles = false;
|
||||
uint32_t ExtraFileCount = 0;
|
||||
|
||||
struct Entry {
|
||||
std::vector<support::ulittle32_t> ExtraFiles;
|
||||
InlineeSourceLineHeader Header;
|
||||
};
|
||||
std::vector<Entry> Entries;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
137
include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
Normal file
137
include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
//===- ModuleDebugLineFragment.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_MODULEDEBUGLINEFRAGMENT_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/Line.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
|
||||
#include "llvm/Support/BinaryStreamArray.h"
|
||||
#include "llvm/Support/BinaryStreamReader.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
// Corresponds to the `CV_DebugSLinesHeader_t` structure.
|
||||
struct LineFragmentHeader {
|
||||
support::ulittle32_t RelocOffset; // Code offset of line contribution.
|
||||
support::ulittle16_t RelocSegment; // Code segment of line contribution.
|
||||
support::ulittle16_t Flags; // See LineFlags enumeration.
|
||||
support::ulittle32_t CodeSize; // Code size of this line contribution.
|
||||
};
|
||||
|
||||
// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
|
||||
struct LineBlockFragmentHeader {
|
||||
support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File
|
||||
// checksums buffer. The checksum entry then
|
||||
// contains another offset into the string
|
||||
// table of the actual name.
|
||||
support::ulittle32_t NumLines; // Number of lines
|
||||
support::ulittle32_t BlockSize; // Code size of block, in bytes.
|
||||
// The following two variable length arrays appear immediately after the
|
||||
// header. The structure definitions follow.
|
||||
// LineNumberEntry Lines[NumLines];
|
||||
// ColumnNumberEntry Columns[NumLines];
|
||||
};
|
||||
|
||||
// Corresponds to `CV_Line_t` structure
|
||||
struct LineNumberEntry {
|
||||
support::ulittle32_t Offset; // Offset to start of code bytes for line number
|
||||
support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
|
||||
};
|
||||
|
||||
// Corresponds to `CV_Column_t` structure
|
||||
struct ColumnNumberEntry {
|
||||
support::ulittle16_t StartColumn;
|
||||
support::ulittle16_t EndColumn;
|
||||
};
|
||||
|
||||
struct LineColumnEntry {
|
||||
support::ulittle32_t NameIndex;
|
||||
FixedStreamArray<LineNumberEntry> LineNumbers;
|
||||
FixedStreamArray<ColumnNumberEntry> Columns;
|
||||
};
|
||||
|
||||
class LineColumnExtractor {
|
||||
public:
|
||||
typedef const LineFragmentHeader ContextType;
|
||||
|
||||
static Error extract(BinaryStreamRef Stream, uint32_t &Len,
|
||||
LineColumnEntry &Item, const LineFragmentHeader *Header);
|
||||
};
|
||||
|
||||
class ModuleDebugLineFragmentRef final : public ModuleDebugFragmentRef {
|
||||
friend class LineColumnExtractor;
|
||||
typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray;
|
||||
typedef LineInfoArray::Iterator Iterator;
|
||||
|
||||
public:
|
||||
ModuleDebugLineFragmentRef();
|
||||
|
||||
static bool classof(const ModuleDebugFragmentRef *S) {
|
||||
return S->kind() == ModuleDebugFragmentKind::Lines;
|
||||
}
|
||||
|
||||
Error initialize(BinaryStreamReader Reader);
|
||||
|
||||
Iterator begin() const { return LinesAndColumns.begin(); }
|
||||
Iterator end() const { return LinesAndColumns.end(); }
|
||||
|
||||
const LineFragmentHeader *header() const { return Header; }
|
||||
|
||||
bool hasColumnInfo() const;
|
||||
|
||||
private:
|
||||
const LineFragmentHeader *Header = nullptr;
|
||||
LineInfoArray LinesAndColumns;
|
||||
};
|
||||
|
||||
class ModuleDebugLineFragment final : public ModuleDebugFragment {
|
||||
struct Block {
|
||||
Block(uint32_t ChecksumBufferOffset)
|
||||
: ChecksumBufferOffset(ChecksumBufferOffset) {}
|
||||
|
||||
uint32_t ChecksumBufferOffset;
|
||||
std::vector<LineNumberEntry> Lines;
|
||||
std::vector<ColumnNumberEntry> Columns;
|
||||
};
|
||||
|
||||
public:
|
||||
ModuleDebugLineFragment();
|
||||
|
||||
static bool classof(const ModuleDebugFragment *S) {
|
||||
return S->kind() == ModuleDebugFragmentKind::Lines;
|
||||
}
|
||||
|
||||
void createBlock(uint32_t ChecksumBufferOffset);
|
||||
void addLineInfo(uint32_t Offset, const LineInfo &Line);
|
||||
void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
|
||||
uint32_t ColStart, uint32_t ColEnd);
|
||||
|
||||
uint32_t calculateSerializedLength() override;
|
||||
Error commit(BinaryStreamWriter &Writer) override;
|
||||
|
||||
void setRelocationAddress(uint16_t Segment, uint16_t Offset);
|
||||
void setCodeSize(uint32_t Size);
|
||||
void setFlags(LineFlags Flags);
|
||||
|
||||
bool hasColumnInfo() const;
|
||||
|
||||
private:
|
||||
uint16_t RelocOffset = 0;
|
||||
uint16_t RelocSegment = 0;
|
||||
uint32_t CodeSize = 0;
|
||||
LineFlags Flags = LF_None;
|
||||
std::vector<Block> Blocks;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
33
include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h
Normal file
33
include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
//===- ModuleDebugUnknownFragment.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_MODULEDEBUGUNKNOWNFRAGMENT_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
|
||||
#include "llvm/Support/BinaryStreamRef.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
class ModuleDebugUnknownFragmentRef final : public ModuleDebugFragmentRef {
|
||||
public:
|
||||
ModuleDebugUnknownFragmentRef(ModuleDebugFragmentKind Kind,
|
||||
BinaryStreamRef Data)
|
||||
: ModuleDebugFragmentRef(Kind), Data(Data) {}
|
||||
|
||||
BinaryStreamRef getData() const { return Data; }
|
||||
|
||||
private:
|
||||
BinaryStreamRef Data;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
//===- ModuleSubstream.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_MODULESUBSTREAM_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/Support/BinaryStreamArray.h"
|
||||
#include "llvm/Support/BinaryStreamRef.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
|
||||
// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
|
||||
struct ModuleSubsectionHeader {
|
||||
support::ulittle32_t Kind; // codeview::ModuleSubstreamKind enum
|
||||
support::ulittle32_t Length; // number of bytes occupied by this record.
|
||||
};
|
||||
|
||||
// Corresponds to the `CV_DebugSLinesHeader_t` structure.
|
||||
struct LineSubstreamHeader {
|
||||
support::ulittle32_t RelocOffset; // Code offset of line contribution.
|
||||
support::ulittle16_t RelocSegment; // Code segment of line contribution.
|
||||
support::ulittle16_t Flags; // See LineFlags enumeration.
|
||||
support::ulittle32_t CodeSize; // Code size of this line contribution.
|
||||
};
|
||||
|
||||
// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
|
||||
struct LineFileBlockHeader {
|
||||
support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
|
||||
support::ulittle32_t NumLines; // Number of lines
|
||||
support::ulittle32_t BlockSize; // Code size of block, in bytes.
|
||||
// The following two variable length arrays appear immediately after the
|
||||
// header. The structure definitions follow.
|
||||
// LineNumberEntry Lines[NumLines];
|
||||
// ColumnNumberEntry Columns[NumLines];
|
||||
};
|
||||
|
||||
// Corresponds to `CV_Line_t` structure
|
||||
struct LineNumberEntry {
|
||||
support::ulittle32_t Offset; // Offset to start of code bytes for line number
|
||||
support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
|
||||
};
|
||||
|
||||
// Corresponds to `CV_Column_t` structure
|
||||
struct ColumnNumberEntry {
|
||||
support::ulittle16_t StartColumn;
|
||||
support::ulittle16_t EndColumn;
|
||||
};
|
||||
|
||||
class ModuleSubstream {
|
||||
public:
|
||||
ModuleSubstream();
|
||||
ModuleSubstream(ModuleSubstreamKind Kind, BinaryStreamRef Data);
|
||||
static Error initialize(BinaryStreamRef Stream, ModuleSubstream &Info);
|
||||
uint32_t getRecordLength() const;
|
||||
ModuleSubstreamKind getSubstreamKind() const;
|
||||
BinaryStreamRef getRecordData() const;
|
||||
|
||||
private:
|
||||
ModuleSubstreamKind Kind;
|
||||
BinaryStreamRef Data;
|
||||
};
|
||||
|
||||
typedef VarStreamArray<ModuleSubstream> ModuleSubstreamArray;
|
||||
} // namespace codeview
|
||||
|
||||
template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> {
|
||||
Error operator()(BinaryStreamRef Stream, uint32_t &Length,
|
||||
codeview::ModuleSubstream &Info) const {
|
||||
if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info))
|
||||
return EC;
|
||||
Length = Info.getRecordLength();
|
||||
return Error::success();
|
||||
}
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
//===- ModuleSubstreamVisitor.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_MODULESUBSTREAMVISITOR_H
|
||||
#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
|
||||
#include "llvm/DebugInfo/CodeView/Line.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
|
||||
#include "llvm/Support/BinaryStreamArray.h"
|
||||
#include "llvm/Support/BinaryStreamReader.h"
|
||||
#include "llvm/Support/BinaryStreamRef.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace codeview {
|
||||
|
||||
struct LineColumnEntry {
|
||||
support::ulittle32_t NameIndex;
|
||||
FixedStreamArray<LineNumberEntry> LineNumbers;
|
||||
FixedStreamArray<ColumnNumberEntry> Columns;
|
||||
};
|
||||
|
||||
struct FileChecksumEntry {
|
||||
uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
|
||||
FileChecksumKind Kind; // The type of checksum.
|
||||
ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
|
||||
};
|
||||
|
||||
typedef VarStreamArray<LineColumnEntry> LineInfoArray;
|
||||
typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
|
||||
|
||||
class IModuleSubstreamVisitor {
|
||||
public:
|
||||
virtual ~IModuleSubstreamVisitor() = default;
|
||||
|
||||
virtual Error visitUnknown(ModuleSubstreamKind Kind,
|
||||
BinaryStreamRef Data) = 0;
|
||||
virtual Error visitSymbols(BinaryStreamRef Data);
|
||||
virtual Error visitLines(BinaryStreamRef Data,
|
||||
const LineSubstreamHeader *Header,
|
||||
const LineInfoArray &Lines);
|
||||
virtual Error visitStringTable(BinaryStreamRef Data);
|
||||
virtual Error visitFileChecksums(BinaryStreamRef Data,
|
||||
const FileChecksumArray &Checksums);
|
||||
virtual Error visitFrameData(BinaryStreamRef Data);
|
||||
virtual Error visitInlineeLines(BinaryStreamRef Data);
|
||||
virtual Error visitCrossScopeImports(BinaryStreamRef Data);
|
||||
virtual Error visitCrossScopeExports(BinaryStreamRef Data);
|
||||
virtual Error visitILLines(BinaryStreamRef Data);
|
||||
virtual Error visitFuncMDTokenMap(BinaryStreamRef Data);
|
||||
virtual Error visitTypeMDTokenMap(BinaryStreamRef Data);
|
||||
virtual Error visitMergedAssemblyInput(BinaryStreamRef Data);
|
||||
virtual Error visitCoffSymbolRVA(BinaryStreamRef Data);
|
||||
};
|
||||
|
||||
Error visitModuleSubstream(const ModuleSubstream &R,
|
||||
IModuleSubstreamVisitor &V);
|
||||
} // end namespace codeview
|
||||
|
||||
template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> {
|
||||
public:
|
||||
VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header)
|
||||
: Header(Header) {}
|
||||
|
||||
Error operator()(BinaryStreamRef Stream, uint32_t &Len,
|
||||
codeview::LineColumnEntry &Item) const {
|
||||
using namespace codeview;
|
||||
const LineFileBlockHeader *BlockHeader;
|
||||
BinaryStreamReader Reader(Stream);
|
||||
if (auto EC = Reader.readObject(BlockHeader))
|
||||
return EC;
|
||||
bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns);
|
||||
uint32_t LineInfoSize =
|
||||
BlockHeader->NumLines *
|
||||
(sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
|
||||
if (BlockHeader->BlockSize < sizeof(LineFileBlockHeader))
|
||||
return make_error<CodeViewError>(cv_error_code::corrupt_record,
|
||||
"Invalid line block record size");
|
||||
uint32_t Size = BlockHeader->BlockSize - sizeof(LineFileBlockHeader);
|
||||
if (LineInfoSize > Size)
|
||||
return make_error<CodeViewError>(cv_error_code::corrupt_record,
|
||||
"Invalid line block record size");
|
||||
// The value recorded in BlockHeader->BlockSize includes the size of
|
||||
// LineFileBlockHeader.
|
||||
Len = BlockHeader->BlockSize;
|
||||
Item.NameIndex = BlockHeader->NameIndex;
|
||||
if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
|
||||
return EC;
|
||||
if (HasColumn) {
|
||||
if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
|
||||
return EC;
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
private:
|
||||
const codeview::LineSubstreamHeader *Header;
|
||||
};
|
||||
|
||||
template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
|
||||
public:
|
||||
Error operator()(BinaryStreamRef Stream, uint32_t &Len,
|
||||
codeview::FileChecksumEntry &Item) const {
|
||||
using namespace codeview;
|
||||
const FileChecksum *Header;
|
||||
BinaryStreamReader Reader(Stream);
|
||||
if (auto EC = Reader.readObject(Header))
|
||||
return EC;
|
||||
Item.FileNameOffset = Header->FileNameOffset;
|
||||
Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
|
||||
if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
|
||||
return EC;
|
||||
Len = sizeof(FileChecksum) + Header->ChecksumSize;
|
||||
return Error::success();
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
|
||||
|
|
@ -35,6 +35,7 @@ public:
|
|||
StringRef getTypeName(TypeIndex Index) const;
|
||||
|
||||
const CVType &getTypeRecord(TypeIndex Index) const;
|
||||
CVType &getTypeRecord(TypeIndex Index);
|
||||
|
||||
bool containsTypeIndex(TypeIndex Index) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -161,6 +161,10 @@ public:
|
|||
virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
|
||||
bool DumpEH = false, bool SummarizeTypes = false) = 0;
|
||||
|
||||
virtual bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) {
|
||||
// No verifier? Just say things went well.
|
||||
return true;
|
||||
}
|
||||
virtual DILineInfo getLineInfoForAddress(uint64_t Address,
|
||||
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
|
||||
virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ public:
|
|||
void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
|
||||
bool DumpEH = false, bool SummarizeTypes = false) override;
|
||||
|
||||
bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
|
||||
|
||||
typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
|
||||
typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
|
||||
typedef iterator_range<decltype(TUs)::iterator> tu_section_iterator_range;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ class raw_ostream;
|
|||
|
||||
class DWARFDebugLine {
|
||||
public:
|
||||
DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {}
|
||||
DWARFDebugLine(const RelocAddrMap *LineInfoRelocMap)
|
||||
: RelocMap(LineInfoRelocMap) {}
|
||||
|
||||
struct FileNameEntry {
|
||||
FileNameEntry() = default;
|
||||
|
|
@ -38,50 +39,46 @@ public:
|
|||
struct Prologue {
|
||||
Prologue();
|
||||
|
||||
// The size in bytes of the statement information for this compilation unit
|
||||
// (not including the total_length field itself).
|
||||
/// The size in bytes of the statement information for this compilation unit
|
||||
/// (not including the total_length field itself).
|
||||
uint64_t TotalLength;
|
||||
// Version identifier for the statement information format.
|
||||
/// Version identifier for the statement information format.
|
||||
uint16_t Version;
|
||||
// The number of bytes following the prologue_length field to the beginning
|
||||
// of the first byte of the statement program itself.
|
||||
/// The number of bytes following the prologue_length field to the beginning
|
||||
/// of the first byte of the statement program itself.
|
||||
uint64_t PrologueLength;
|
||||
// The size in bytes of the smallest target machine instruction. Statement
|
||||
// program opcodes that alter the address register first multiply their
|
||||
// operands by this value.
|
||||
/// The size in bytes of the smallest target machine instruction. Statement
|
||||
/// program opcodes that alter the address register first multiply their
|
||||
/// operands by this value.
|
||||
uint8_t MinInstLength;
|
||||
// The maximum number of individual operations that may be encoded in an
|
||||
// instruction.
|
||||
/// The maximum number of individual operations that may be encoded in an
|
||||
/// instruction.
|
||||
uint8_t MaxOpsPerInst;
|
||||
// The initial value of theis_stmtregister.
|
||||
/// The initial value of theis_stmtregister.
|
||||
uint8_t DefaultIsStmt;
|
||||
// This parameter affects the meaning of the special opcodes. See below.
|
||||
/// This parameter affects the meaning of the special opcodes. See below.
|
||||
int8_t LineBase;
|
||||
// This parameter affects the meaning of the special opcodes. See below.
|
||||
/// This parameter affects the meaning of the special opcodes. See below.
|
||||
uint8_t LineRange;
|
||||
// The number assigned to the first special opcode.
|
||||
/// The number assigned to the first special opcode.
|
||||
uint8_t OpcodeBase;
|
||||
std::vector<uint8_t> StandardOpcodeLengths;
|
||||
std::vector<const char*> IncludeDirectories;
|
||||
std::vector<const char *> IncludeDirectories;
|
||||
std::vector<FileNameEntry> FileNames;
|
||||
|
||||
bool IsDWARF64;
|
||||
|
||||
uint32_t sizeofTotalLength() const {
|
||||
return IsDWARF64 ? 12 : 4;
|
||||
}
|
||||
uint32_t sizeofTotalLength() const { return IsDWARF64 ? 12 : 4; }
|
||||
|
||||
uint32_t sizeofPrologueLength() const {
|
||||
return IsDWARF64 ? 8 : 4;
|
||||
}
|
||||
uint32_t sizeofPrologueLength() const { return IsDWARF64 ? 8 : 4; }
|
||||
|
||||
// Length of the prologue in bytes.
|
||||
/// Length of the prologue in bytes.
|
||||
uint32_t getLength() const {
|
||||
return PrologueLength + sizeofTotalLength() + sizeof(Version) +
|
||||
sizeofPrologueLength();
|
||||
}
|
||||
|
||||
// Length of the line table data in bytes (not including the prologue).
|
||||
/// Length of the line table data in bytes (not including the prologue).
|
||||
uint32_t getStatementTableLength() const {
|
||||
return TotalLength + sizeofTotalLength() - getLength();
|
||||
}
|
||||
|
|
@ -92,70 +89,70 @@ public:
|
|||
|
||||
void clear();
|
||||
void dump(raw_ostream &OS) const;
|
||||
bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr);
|
||||
bool parse(DataExtractor DebugLineData, uint32_t *OffsetPtr);
|
||||
};
|
||||
|
||||
// Standard .debug_line state machine structure.
|
||||
/// Standard .debug_line state machine structure.
|
||||
struct Row {
|
||||
explicit Row(bool default_is_stmt = false);
|
||||
explicit Row(bool DefaultIsStmt = false);
|
||||
|
||||
/// Called after a row is appended to the matrix.
|
||||
void postAppend();
|
||||
void reset(bool default_is_stmt);
|
||||
void reset(bool DefaultIsStmt);
|
||||
void dump(raw_ostream &OS) const;
|
||||
|
||||
static bool orderByAddress(const Row& LHS, const Row& RHS) {
|
||||
static bool orderByAddress(const Row &LHS, const Row &RHS) {
|
||||
return LHS.Address < RHS.Address;
|
||||
}
|
||||
|
||||
// The program-counter value corresponding to a machine instruction
|
||||
// generated by the compiler.
|
||||
/// The program-counter value corresponding to a machine instruction
|
||||
/// generated by the compiler.
|
||||
uint64_t Address;
|
||||
// An unsigned integer indicating a source line number. Lines are numbered
|
||||
// beginning at 1. The compiler may emit the value 0 in cases where an
|
||||
// instruction cannot be attributed to any source line.
|
||||
/// An unsigned integer indicating a source line number. Lines are numbered
|
||||
/// beginning at 1. The compiler may emit the value 0 in cases where an
|
||||
/// instruction cannot be attributed to any source line.
|
||||
uint32_t Line;
|
||||
// An unsigned integer indicating a column number within a source line.
|
||||
// Columns are numbered beginning at 1. The value 0 is reserved to indicate
|
||||
// that a statement begins at the 'left edge' of the line.
|
||||
/// An unsigned integer indicating a column number within a source line.
|
||||
/// Columns are numbered beginning at 1. The value 0 is reserved to indicate
|
||||
/// that a statement begins at the 'left edge' of the line.
|
||||
uint16_t Column;
|
||||
// An unsigned integer indicating the identity of the source file
|
||||
// corresponding to a machine instruction.
|
||||
/// An unsigned integer indicating the identity of the source file
|
||||
/// corresponding to a machine instruction.
|
||||
uint16_t File;
|
||||
// An unsigned integer representing the DWARF path discriminator value
|
||||
// for this location.
|
||||
/// An unsigned integer representing the DWARF path discriminator value
|
||||
/// for this location.
|
||||
uint32_t Discriminator;
|
||||
// An unsigned integer whose value encodes the applicable instruction set
|
||||
// architecture for the current instruction.
|
||||
/// An unsigned integer whose value encodes the applicable instruction set
|
||||
/// architecture for the current instruction.
|
||||
uint8_t Isa;
|
||||
// A boolean indicating that the current instruction is the beginning of a
|
||||
// statement.
|
||||
uint8_t IsStmt:1,
|
||||
// A boolean indicating that the current instruction is the
|
||||
// beginning of a basic block.
|
||||
BasicBlock:1,
|
||||
// A boolean indicating that the current address is that of the
|
||||
// first byte after the end of a sequence of target machine
|
||||
// instructions.
|
||||
EndSequence:1,
|
||||
// A boolean indicating that the current address is one (of possibly
|
||||
// many) where execution should be suspended for an entry breakpoint
|
||||
// of a function.
|
||||
PrologueEnd:1,
|
||||
// A boolean indicating that the current address is one (of possibly
|
||||
// many) where execution should be suspended for an exit breakpoint
|
||||
// of a function.
|
||||
EpilogueBegin:1;
|
||||
/// A boolean indicating that the current instruction is the beginning of a
|
||||
/// statement.
|
||||
uint8_t IsStmt : 1,
|
||||
/// A boolean indicating that the current instruction is the
|
||||
/// beginning of a basic block.
|
||||
BasicBlock : 1,
|
||||
/// A boolean indicating that the current address is that of the
|
||||
/// first byte after the end of a sequence of target machine
|
||||
/// instructions.
|
||||
EndSequence : 1,
|
||||
/// A boolean indicating that the current address is one (of possibly
|
||||
/// many) where execution should be suspended for an entry breakpoint
|
||||
/// of a function.
|
||||
PrologueEnd : 1,
|
||||
/// A boolean indicating that the current address is one (of possibly
|
||||
/// many) where execution should be suspended for an exit breakpoint
|
||||
/// of a function.
|
||||
EpilogueBegin : 1;
|
||||
};
|
||||
|
||||
// Represents a series of contiguous machine instructions. Line table for each
|
||||
// compilation unit may consist of multiple sequences, which are not
|
||||
// guaranteed to be in the order of ascending instruction address.
|
||||
/// Represents a series of contiguous machine instructions. Line table for
|
||||
/// each compilation unit may consist of multiple sequences, which are not
|
||||
/// guaranteed to be in the order of ascending instruction address.
|
||||
struct Sequence {
|
||||
Sequence();
|
||||
|
||||
// Sequence describes instructions at address range [LowPC, HighPC)
|
||||
// and is described by line table rows [FirstRowIndex, LastRowIndex).
|
||||
/// Sequence describes instructions at address range [LowPC, HighPC)
|
||||
/// and is described by line table rows [FirstRowIndex, LastRowIndex).
|
||||
uint64_t LowPC;
|
||||
uint64_t HighPC;
|
||||
unsigned FirstRowIndex;
|
||||
|
|
@ -164,7 +161,7 @@ public:
|
|||
|
||||
void reset();
|
||||
|
||||
static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) {
|
||||
static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS) {
|
||||
return LHS.LowPC < RHS.LowPC;
|
||||
}
|
||||
|
||||
|
|
@ -172,42 +169,38 @@ public:
|
|||
return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
|
||||
}
|
||||
|
||||
bool containsPC(uint64_t pc) const {
|
||||
return (LowPC <= pc && pc < HighPC);
|
||||
}
|
||||
bool containsPC(uint64_t PC) const { return (LowPC <= PC && PC < HighPC); }
|
||||
};
|
||||
|
||||
struct LineTable {
|
||||
LineTable();
|
||||
|
||||
// Represents an invalid row
|
||||
/// Represents an invalid row
|
||||
const uint32_t UnknownRowIndex = UINT32_MAX;
|
||||
|
||||
void appendRow(const DWARFDebugLine::Row &R) {
|
||||
Rows.push_back(R);
|
||||
}
|
||||
void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); }
|
||||
|
||||
void appendSequence(const DWARFDebugLine::Sequence &S) {
|
||||
Sequences.push_back(S);
|
||||
}
|
||||
|
||||
// Returns the index of the row with file/line info for a given address,
|
||||
// or UnknownRowIndex if there is no such row.
|
||||
uint32_t lookupAddress(uint64_t address) const;
|
||||
/// Returns the index of the row with file/line info for a given address,
|
||||
/// or UnknownRowIndex if there is no such row.
|
||||
uint32_t lookupAddress(uint64_t Address) const;
|
||||
|
||||
bool lookupAddressRange(uint64_t address, uint64_t size,
|
||||
std::vector<uint32_t> &result) const;
|
||||
bool lookupAddressRange(uint64_t Address, uint64_t Size,
|
||||
std::vector<uint32_t> &Result) const;
|
||||
|
||||
bool hasFileAtIndex(uint64_t FileIndex) const;
|
||||
|
||||
// Extracts filename by its index in filename table in prologue.
|
||||
// Returns true on success.
|
||||
/// Extracts filename by its index in filename table in prologue.
|
||||
/// Returns true on success.
|
||||
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir,
|
||||
DILineInfoSpecifier::FileLineInfoKind Kind,
|
||||
std::string &Result) const;
|
||||
|
||||
// Fills the Result argument with the file and line information
|
||||
// corresponding to Address. Returns true on success.
|
||||
/// Fills the Result argument with the file and line information
|
||||
/// corresponding to Address. Returns true on success.
|
||||
bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir,
|
||||
DILineInfoSpecifier::FileLineInfoKind Kind,
|
||||
DILineInfo &Result) const;
|
||||
|
|
@ -216,8 +209,8 @@ public:
|
|||
void clear();
|
||||
|
||||
/// Parse prologue and all rows.
|
||||
bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap,
|
||||
uint32_t *offset_ptr);
|
||||
bool parse(DataExtractor DebugLineData, const RelocAddrMap *RMap,
|
||||
uint32_t *OffsetPtr);
|
||||
|
||||
struct Prologue Prologue;
|
||||
typedef std::vector<Row> RowVector;
|
||||
|
|
@ -228,25 +221,25 @@ public:
|
|||
SequenceVector Sequences;
|
||||
|
||||
private:
|
||||
uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq,
|
||||
uint64_t address) const;
|
||||
uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
|
||||
uint64_t Address) const;
|
||||
};
|
||||
|
||||
const LineTable *getLineTable(uint32_t offset) const;
|
||||
const LineTable *getOrParseLineTable(DataExtractor debug_line_data,
|
||||
uint32_t offset);
|
||||
const LineTable *getLineTable(uint32_t Offset) const;
|
||||
const LineTable *getOrParseLineTable(DataExtractor DebugLineData,
|
||||
uint32_t Offset);
|
||||
|
||||
private:
|
||||
struct ParsingState {
|
||||
ParsingState(struct LineTable *LT);
|
||||
|
||||
void resetRowAndSequence();
|
||||
void appendRowToMatrix(uint32_t offset);
|
||||
void appendRowToMatrix(uint32_t Offset);
|
||||
|
||||
// Line table we're currently parsing.
|
||||
/// Line table we're currently parsing.
|
||||
struct LineTable *LineTable;
|
||||
// The row number that starts at zero for the prologue, and increases for
|
||||
// each row added to the matrix.
|
||||
/// The row number that starts at zero for the prologue, and increases for
|
||||
/// each row added to the matrix.
|
||||
unsigned RowNumber;
|
||||
struct Row Row;
|
||||
struct Sequence Sequence;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ public:
|
|||
DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
|
||||
|
||||
dwarf::Form getForm() const { return Form; }
|
||||
uint64_t getRawUValue() const { return Value.uval; }
|
||||
void setForm(dwarf::Form F) { Form = F; }
|
||||
void setUValue(uint64_t V) { Value.uval = V; }
|
||||
void setSValue(int64_t V) { Value.sval = V; }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//===- ModInfo.h - PDB module information -----------------------*- C++ -*-===//
|
||||
//===- DbiModuleDescriptor.h - PDB module information -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
|
@ -7,8 +7,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
|
||||
#ifndef LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
|
||||
|
|
@ -22,21 +22,21 @@ namespace llvm {
|
|||
|
||||
namespace pdb {
|
||||
|
||||
class ModInfo {
|
||||
class DbiModuleDescriptor {
|
||||
friend class DbiStreamBuilder;
|
||||
|
||||
public:
|
||||
ModInfo();
|
||||
ModInfo(const ModInfo &Info);
|
||||
~ModInfo();
|
||||
DbiModuleDescriptor();
|
||||
DbiModuleDescriptor(const DbiModuleDescriptor &Info);
|
||||
~DbiModuleDescriptor();
|
||||
|
||||
static Error initialize(BinaryStreamRef Stream, ModInfo &Info);
|
||||
static Error initialize(BinaryStreamRef Stream, DbiModuleDescriptor &Info);
|
||||
|
||||
bool hasECInfo() const;
|
||||
uint16_t getTypeServerIndex() const;
|
||||
uint16_t getModuleStreamIndex() const;
|
||||
uint32_t getSymbolDebugInfoByteSize() const;
|
||||
uint32_t getLineInfoByteSize() const;
|
||||
uint32_t getC11LineInfoByteSize() const;
|
||||
uint32_t getC13LineInfoByteSize() const;
|
||||
uint32_t getNumberOfFiles() const;
|
||||
uint32_t getSourceFileNameIndex() const;
|
||||
|
|
@ -54,19 +54,20 @@ private:
|
|||
};
|
||||
|
||||
struct ModuleInfoEx {
|
||||
ModuleInfoEx(const ModInfo &Info) : Info(Info) {}
|
||||
ModuleInfoEx(const DbiModuleDescriptor &Info) : Info(Info) {}
|
||||
ModuleInfoEx(const ModuleInfoEx &Ex) = default;
|
||||
|
||||
ModInfo Info;
|
||||
DbiModuleDescriptor Info;
|
||||
std::vector<StringRef> SourceFiles;
|
||||
};
|
||||
|
||||
} // end namespace pdb
|
||||
|
||||
template <> struct VarStreamArrayExtractor<pdb::ModInfo> {
|
||||
Error operator()(BinaryStreamRef Stream, uint32_t &Length,
|
||||
pdb::ModInfo &Info) const {
|
||||
if (auto EC = pdb::ModInfo::initialize(Stream, Info))
|
||||
template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> {
|
||||
typedef void ContextType;
|
||||
static Error extract(BinaryStreamRef Stream, uint32_t &Length,
|
||||
pdb::DbiModuleDescriptor &Info, void *Ctx) {
|
||||
if (auto EC = pdb::DbiModuleDescriptor::initialize(Stream, Info))
|
||||
return EC;
|
||||
Length = Info.getRecordLength();
|
||||
return Error::success();
|
||||
|
|
@ -75,4 +76,4 @@ template <> struct VarStreamArrayExtractor<pdb::ModInfo> {
|
|||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_PDB_RAW_MODINFO_H
|
||||
#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H
|
||||
101
include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
Normal file
101
include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
//===- DbiModuleDescriptorBuilder.h - PDB module information ----*- 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_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class BinaryStreamWriter;
|
||||
|
||||
namespace codeview {
|
||||
class ModuleDebugFragmentRecordBuilder;
|
||||
}
|
||||
|
||||
namespace msf {
|
||||
class MSFBuilder;
|
||||
struct MSFLayout;
|
||||
}
|
||||
namespace pdb {
|
||||
|
||||
class DbiModuleDescriptorBuilder {
|
||||
friend class DbiStreamBuilder;
|
||||
|
||||
public:
|
||||
DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex,
|
||||
msf::MSFBuilder &Msf);
|
||||
~DbiModuleDescriptorBuilder();
|
||||
|
||||
DbiModuleDescriptorBuilder(const DbiModuleDescriptorBuilder &) = delete;
|
||||
DbiModuleDescriptorBuilder &
|
||||
operator=(const DbiModuleDescriptorBuilder &) = delete;
|
||||
|
||||
void setObjFileName(StringRef Name);
|
||||
void addSymbol(codeview::CVSymbol Symbol);
|
||||
|
||||
void addC13Fragment(std::unique_ptr<codeview::ModuleDebugLineFragment> Lines);
|
||||
void addC13Fragment(
|
||||
std::unique_ptr<codeview::ModuleDebugInlineeLineFragment> Inlinees);
|
||||
void setC13FileChecksums(
|
||||
std::unique_ptr<codeview::ModuleDebugFileChecksumFragment> Checksums);
|
||||
|
||||
uint16_t getStreamIndex() const;
|
||||
StringRef getModuleName() const { return ModuleName; }
|
||||
StringRef getObjFileName() const { return ObjFileName; }
|
||||
|
||||
ArrayRef<std::string> source_files() const {
|
||||
return makeArrayRef(SourceFiles);
|
||||
}
|
||||
|
||||
uint32_t calculateSerializedLength() const;
|
||||
|
||||
void finalize();
|
||||
Error finalizeMsfLayout();
|
||||
|
||||
Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout,
|
||||
WritableBinaryStreamRef MsfBuffer);
|
||||
|
||||
private:
|
||||
uint32_t calculateC13DebugInfoSize() const;
|
||||
|
||||
void addSourceFile(StringRef Path);
|
||||
msf::MSFBuilder &MSF;
|
||||
|
||||
uint32_t SymbolByteSize = 0;
|
||||
std::string ModuleName;
|
||||
std::string ObjFileName;
|
||||
std::vector<std::string> SourceFiles;
|
||||
std::vector<codeview::CVSymbol> Symbols;
|
||||
|
||||
std::unique_ptr<codeview::ModuleDebugFileChecksumFragment> ChecksumInfo;
|
||||
std::vector<std::unique_ptr<codeview::ModuleDebugLineFragment>> LineInfo;
|
||||
std::vector<std::unique_ptr<codeview::ModuleDebugInlineeLineFragment>>
|
||||
Inlinees;
|
||||
|
||||
std::vector<std::unique_ptr<codeview::ModuleDebugFragmentRecordBuilder>>
|
||||
C13Builders;
|
||||
|
||||
ModuleInfoHeader Layout;
|
||||
};
|
||||
|
||||
} // end namespace pdb
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H
|
||||
|
|
@ -10,9 +10,9 @@
|
|||
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
|
||||
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/ModInfo.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/StringTable.h"
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ struct coff_section;
|
|||
namespace pdb {
|
||||
class DbiStream;
|
||||
struct DbiStreamHeader;
|
||||
class ModInfoBuilder;
|
||||
class DbiModuleDescriptorBuilder;
|
||||
class PDBFile;
|
||||
|
||||
class DbiStreamBuilder {
|
||||
|
|
@ -57,8 +57,9 @@ public:
|
|||
|
||||
uint32_t calculateSerializedLength() const;
|
||||
|
||||
Expected<ModInfoBuilder &> addModuleInfo(StringRef ModuleName);
|
||||
Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
|
||||
Error addModuleSourceFile(StringRef Module, StringRef File);
|
||||
Expected<uint32_t> getSourceFileNameIndex(StringRef FileName);
|
||||
|
||||
Error finalizeMsfLayout();
|
||||
|
||||
|
|
@ -103,8 +104,8 @@ private:
|
|||
|
||||
const DbiStreamHeader *Header;
|
||||
|
||||
StringMap<std::unique_ptr<ModInfoBuilder>> ModiMap;
|
||||
std::vector<ModInfoBuilder *> ModiList;
|
||||
StringMap<std::unique_ptr<DbiModuleDescriptorBuilder>> ModiMap;
|
||||
std::vector<DbiModuleDescriptorBuilder *> ModiList;
|
||||
|
||||
StringMap<uint32_t> SourceFileNames;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
//===- ModInfoBuilder.h - PDB module information ----------------*- 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_PDB_RAW_MODINFOBUILDER_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_MODINFOBUILDER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class BinaryStreamWriter;
|
||||
|
||||
namespace msf {
|
||||
class MSFBuilder;
|
||||
struct MSFLayout;
|
||||
}
|
||||
namespace pdb {
|
||||
|
||||
class ModInfoBuilder {
|
||||
friend class DbiStreamBuilder;
|
||||
|
||||
public:
|
||||
ModInfoBuilder(StringRef ModuleName, uint32_t ModIndex, msf::MSFBuilder &Msf);
|
||||
|
||||
ModInfoBuilder(const ModInfoBuilder &) = delete;
|
||||
ModInfoBuilder &operator=(const ModInfoBuilder &) = delete;
|
||||
|
||||
void setObjFileName(StringRef Name);
|
||||
void addSymbol(codeview::CVSymbol Symbol);
|
||||
|
||||
uint16_t getStreamIndex() const;
|
||||
StringRef getModuleName() const { return ModuleName; }
|
||||
StringRef getObjFileName() const { return ObjFileName; }
|
||||
|
||||
ArrayRef<std::string> source_files() const {
|
||||
return makeArrayRef(SourceFiles);
|
||||
}
|
||||
|
||||
uint32_t calculateSerializedLength() const;
|
||||
|
||||
void finalize();
|
||||
Error finalizeMsfLayout();
|
||||
|
||||
Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout,
|
||||
WritableBinaryStreamRef MsfBuffer);
|
||||
|
||||
private:
|
||||
void addSourceFile(StringRef Path);
|
||||
msf::MSFBuilder &MSF;
|
||||
|
||||
uint32_t SymbolByteSize = 0;
|
||||
std::string ModuleName;
|
||||
std::string ObjFileName;
|
||||
std::vector<std::string> SourceFiles;
|
||||
std::vector<codeview::CVSymbol> Symbols;
|
||||
ModuleInfoHeader Layout;
|
||||
};
|
||||
|
||||
} // end namespace pdb
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_DEBUGINFO_PDB_RAW_MODINFOBUILDER_H
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
//===- ModStream.h - PDB Module Info Stream Access ------------------------===//
|
||||
//===- ModuleDebugStream.h - PDB Module Info Stream Access ----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
|
@ -7,12 +7,12 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H
|
||||
#ifndef LLVM_DEBUGINFO_PDB_RAW_MODULEDEBUGSTREAM_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_MODULEDEBUGSTREAM_H
|
||||
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/DebugInfo/CodeView/CVRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
|
||||
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
||||
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
|
||||
#include "llvm/Support/BinaryStreamArray.h"
|
||||
|
|
@ -22,13 +22,16 @@
|
|||
namespace llvm {
|
||||
namespace pdb {
|
||||
class PDBFile;
|
||||
class ModInfo;
|
||||
class DbiModuleDescriptor;
|
||||
|
||||
class ModuleDebugStreamRef {
|
||||
typedef codeview::ModuleDebugFragmentArray::Iterator
|
||||
LinesAndChecksumsIterator;
|
||||
|
||||
class ModStream {
|
||||
public:
|
||||
ModStream(const ModInfo &Module,
|
||||
std::unique_ptr<msf::MappedBlockStream> Stream);
|
||||
~ModStream();
|
||||
ModuleDebugStreamRef(const DbiModuleDescriptor &Module,
|
||||
std::unique_ptr<msf::MappedBlockStream> Stream);
|
||||
~ModuleDebugStreamRef();
|
||||
|
||||
Error reload();
|
||||
|
||||
|
|
@ -37,26 +40,25 @@ public:
|
|||
iterator_range<codeview::CVSymbolArray::Iterator>
|
||||
symbols(bool *HadError) const;
|
||||
|
||||
iterator_range<codeview::ModuleSubstreamArray::Iterator>
|
||||
lines(bool *HadError) const;
|
||||
llvm::iterator_range<LinesAndChecksumsIterator> linesAndChecksums() const;
|
||||
|
||||
bool hasLineInfo() const;
|
||||
|
||||
Error commit();
|
||||
|
||||
private:
|
||||
const ModInfo &Mod;
|
||||
const DbiModuleDescriptor &Mod;
|
||||
|
||||
uint32_t Signature;
|
||||
|
||||
std::unique_ptr<msf::MappedBlockStream> Stream;
|
||||
|
||||
codeview::CVSymbolArray SymbolsSubstream;
|
||||
BinaryStreamRef LinesSubstream;
|
||||
BinaryStreamRef C11LinesSubstream;
|
||||
BinaryStreamRef C13LinesSubstream;
|
||||
BinaryStreamRef GlobalRefsSubstream;
|
||||
|
||||
codeview::ModuleSubstreamArray LineInfo;
|
||||
codeview::ModuleDebugFragmentArray LinesAndChecksums;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H
|
||||
#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H
|
||||
|
||||
#include "llvm/DebugInfo/PDB/Native/ModInfo.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
|
||||
|
||||
namespace llvm {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMMODULES_H
|
||||
|
||||
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/ModInfo.h"
|
||||
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
|
||||
namespace llvm {
|
||||
namespace pdb {
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ struct FileInfoSubstreamHeader {
|
|||
};
|
||||
|
||||
struct ModInfoFlags {
|
||||
/// uint16_t fWritten : 1; // True if ModInfo is dirty
|
||||
/// uint16_t fWritten : 1; // True if DbiModuleDescriptor is dirty
|
||||
/// uint16_t fECEnabled : 1; // Is EC symbolic info present? (What is EC?)
|
||||
/// uint16_t unused : 6; // Reserved
|
||||
/// uint16_t iTSM : 8; // Type Server Index for this module
|
||||
|
|
@ -231,8 +231,8 @@ struct ModuleInfoHeader {
|
|||
/// Size of local symbol debug info in above stream
|
||||
support::ulittle32_t SymBytes;
|
||||
|
||||
/// Size of line number debug info in above stream
|
||||
support::ulittle32_t LineBytes;
|
||||
/// Size of C11 line number info in above stream
|
||||
support::ulittle32_t C11Bytes;
|
||||
|
||||
/// Size of C13 line number info in above stream
|
||||
support::ulittle32_t C13Bytes;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public:
|
|||
// If string S does not exist in the string table, insert it.
|
||||
// Returns the ID for S.
|
||||
uint32_t insert(StringRef S);
|
||||
uint32_t getStringIndex(StringRef S);
|
||||
|
||||
uint32_t finalize();
|
||||
Error commit(BinaryStreamWriter &Writer) const;
|
||||
|
|
|
|||
|
|
@ -56,8 +56,9 @@ public:
|
|||
Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
|
||||
uint64_t ModuleOffset);
|
||||
void flush();
|
||||
static std::string DemangleName(const std::string &Name,
|
||||
const SymbolizableModule *ModInfo);
|
||||
static std::string
|
||||
DemangleName(const std::string &Name,
|
||||
const SymbolizableModule *DbiModuleDescriptor);
|
||||
|
||||
private:
|
||||
// Bundles together object file with code/data and object file with
|
||||
|
|
|
|||
|
|
@ -115,8 +115,6 @@ public:
|
|||
void addAttr(Attribute Attr);
|
||||
|
||||
/// Remove attributes from an argument.
|
||||
void removeAttr(AttributeList AS);
|
||||
|
||||
void removeAttr(Attribute::AttrKind Kind);
|
||||
|
||||
/// Check if an argument has a given attribute.
|
||||
|
|
|
|||
|
|
@ -457,8 +457,11 @@ public:
|
|||
/// \brief Return the attribute object that exists at the given index.
|
||||
Attribute getAttribute(unsigned Index, StringRef Kind) const;
|
||||
|
||||
/// \brief Return the alignment of the return value.
|
||||
unsigned getRetAlignment() const;
|
||||
|
||||
/// \brief Return the alignment for the specified function parameter.
|
||||
unsigned getParamAlignment(unsigned Index) const;
|
||||
unsigned getParamAlignment(unsigned ArgNo) const;
|
||||
|
||||
/// \brief Get the stack alignment.
|
||||
unsigned getStackAlignment(unsigned Index) const;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,9 @@ def SExt : EnumAttr<"signext">;
|
|||
/// +1 bias 0 means unaligned (different from alignstack=(1)).
|
||||
def StackAlignment : EnumAttr<"alignstack">;
|
||||
|
||||
/// Function can be speculated.
|
||||
def Speculatable : EnumAttr<"speculatable">;
|
||||
|
||||
/// Stack protection.
|
||||
def StackProtect : EnumAttr<"ssp">;
|
||||
|
||||
|
|
|
|||
|
|
@ -386,20 +386,25 @@ public:
|
|||
CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, Kind));
|
||||
}
|
||||
|
||||
/// Extract the alignment of the return value.
|
||||
unsigned getRetAlignment() const {
|
||||
CALLSITE_DELEGATE_GETTER(getRetAlignment());
|
||||
}
|
||||
|
||||
/// Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const {
|
||||
CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
|
||||
unsigned getParamAlignment(unsigned ArgNo) const {
|
||||
CALLSITE_DELEGATE_GETTER(getParamAlignment(ArgNo));
|
||||
}
|
||||
|
||||
/// Extract the number of dereferenceable bytes for a call or parameter
|
||||
/// (0=unknown).
|
||||
uint64_t getDereferenceableBytes(uint16_t i) const {
|
||||
uint64_t getDereferenceableBytes(unsigned i) const {
|
||||
CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i));
|
||||
}
|
||||
|
||||
/// Extract the number of dereferenceable_or_null bytes for a call or
|
||||
/// parameter (0=unknown).
|
||||
uint64_t getDereferenceableOrNullBytes(uint16_t i) const {
|
||||
uint64_t getDereferenceableOrNullBytes(unsigned i) const {
|
||||
CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i));
|
||||
}
|
||||
|
||||
|
|
@ -599,7 +604,7 @@ public:
|
|||
bool isReturnNonNull() const {
|
||||
if (hasRetAttr(Attribute::NonNull))
|
||||
return true;
|
||||
else if (getDereferenceableBytes(0) > 0 &&
|
||||
else if (getDereferenceableBytes(AttributeList::ReturnIndex) > 0 &&
|
||||
getType()->getPointerAddressSpace() == 0)
|
||||
return true;
|
||||
|
||||
|
|
|
|||
|
|
@ -196,6 +196,10 @@ namespace CallingConv {
|
|||
/// Register calling convention used for parameters transfer optimization
|
||||
X86_RegCall = 92,
|
||||
|
||||
/// Calling convention used for Mesa hull shaders. (= tessellation control
|
||||
/// shaders)
|
||||
AMDGPU_HS = 93,
|
||||
|
||||
/// The highest possible calling convention ID. Must be some 2^k - 1.
|
||||
MaxID = 1023
|
||||
};
|
||||
|
|
|
|||
|
|
@ -577,15 +577,14 @@ namespace llvm {
|
|||
/// These flags are used to emit dwarf attributes.
|
||||
/// \param isOptimized True if optimization is ON.
|
||||
/// \param TParams Function template parameters.
|
||||
DISubprogram *createFunction(DIScope *Scope, StringRef Name,
|
||||
StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty,
|
||||
bool isLocalToUnit, bool isDefinition,
|
||||
unsigned ScopeLine,
|
||||
DINode::DIFlags Flags = DINode::FlagZero,
|
||||
bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DISubprogram *Decl = nullptr);
|
||||
/// \param ThrownTypes Exception types this function may throw.
|
||||
DISubprogram *createFunction(
|
||||
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
|
||||
bool isDefinition, unsigned ScopeLine,
|
||||
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr);
|
||||
|
||||
/// Identical to createFunction,
|
||||
/// except that the resulting DbgNode is meant to be RAUWed.
|
||||
|
|
@ -595,7 +594,7 @@ namespace llvm {
|
|||
bool isDefinition, unsigned ScopeLine,
|
||||
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DISubprogram *Decl = nullptr);
|
||||
DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr);
|
||||
|
||||
/// Create a new descriptor for the specified C++ method.
|
||||
/// See comments in \a DISubprogram* for descriptions of these fields.
|
||||
|
|
@ -619,23 +618,23 @@ namespace llvm {
|
|||
/// This flags are used to emit dwarf attributes.
|
||||
/// \param isOptimized True if optimization is ON.
|
||||
/// \param TParams Function template parameters.
|
||||
/// \param ThrownTypes Exception types this function may throw.
|
||||
DISubprogram *createMethod(
|
||||
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
|
||||
bool isDefinition, unsigned Virtuality = 0, unsigned VTableIndex = 0,
|
||||
int ThisAdjustment = 0, DIType *VTableHolder = nullptr,
|
||||
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr);
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DITypeArray ThrownTypes = nullptr);
|
||||
|
||||
/// This creates new descriptor for a namespace with the specified
|
||||
/// parent scope.
|
||||
/// \param Scope Namespace scope
|
||||
/// \param Name Name of this namespace
|
||||
/// \param File Source file
|
||||
/// \param LineNo Line number
|
||||
/// \param ExportSymbols True for C++ inline namespaces.
|
||||
DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File,
|
||||
unsigned LineNo, bool ExportSymbols);
|
||||
DINamespace *createNameSpace(DIScope *Scope, StringRef Name,
|
||||
bool ExportSymbols);
|
||||
|
||||
/// This creates new descriptor for a module with the specified
|
||||
/// parent scope.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
class DIBuilder;
|
||||
|
||||
template <typename T> class Optional;
|
||||
|
||||
/// Holds a subclass of DINode.
|
||||
|
|
@ -433,7 +435,7 @@ public:
|
|||
|
||||
/// Return the raw underlying file.
|
||||
///
|
||||
/// An \a DIFile is an \a DIScope, but it doesn't point at a separate file
|
||||
/// A \a DIFile is a \a DIScope, but it doesn't point at a separate file
|
||||
/// (it\em is the file). If \c this is an \a DIFile, we need to return \c
|
||||
/// this. Otherwise, return the first operand, which is where all other
|
||||
/// subclasses store their file pointer.
|
||||
|
|
@ -1509,14 +1511,14 @@ class DISubprogram : public DILocalScope {
|
|||
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
|
||||
bool IsOptimized, DICompileUnit *Unit,
|
||||
DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
|
||||
DILocalVariableArray Variables, StorageType Storage,
|
||||
bool ShouldCreate = true) {
|
||||
DILocalVariableArray Variables, DITypeArray ThrownTypes,
|
||||
StorageType Storage, bool ShouldCreate = true) {
|
||||
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
|
||||
getCanonicalMDString(Context, LinkageName), File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams.get(), Declaration, Variables.get(),
|
||||
Storage, ShouldCreate);
|
||||
ThrownTypes.get(), Storage, ShouldCreate);
|
||||
}
|
||||
static DISubprogram *
|
||||
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
|
||||
|
|
@ -1525,15 +1527,16 @@ class DISubprogram : public DILocalScope {
|
|||
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
|
||||
int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
|
||||
Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true);
|
||||
|
||||
TempDISubprogram cloneImpl() const {
|
||||
return getTemporary(
|
||||
getContext(), getScope(), getName(), getLinkageName(), getFile(),
|
||||
getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(),
|
||||
getContainingType(), getVirtuality(), getVirtualIndex(),
|
||||
getThisAdjustment(), getFlags(), isOptimized(), getUnit(),
|
||||
getTemplateParams(), getDeclaration(), getVariables());
|
||||
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
|
||||
getFile(), getLine(), getType(), isLocalToUnit(),
|
||||
isDefinition(), getScopeLine(), getContainingType(),
|
||||
getVirtuality(), getVirtualIndex(), getThisAdjustment(),
|
||||
getFlags(), isOptimized(), getUnit(),
|
||||
getTemplateParams(), getDeclaration(), getVariables(),
|
||||
getThrownTypes());
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -1546,11 +1549,12 @@ public:
|
|||
bool IsOptimized, DICompileUnit *Unit,
|
||||
DITemplateParameterArray TemplateParams = nullptr,
|
||||
DISubprogram *Declaration = nullptr,
|
||||
DILocalVariableArray Variables = nullptr),
|
||||
DILocalVariableArray Variables = nullptr,
|
||||
DITypeArray ThrownTypes = nullptr),
|
||||
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
|
||||
IsDefinition, ScopeLine, ContainingType, Virtuality,
|
||||
VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables))
|
||||
TemplateParams, Declaration, Variables, ThrownTypes))
|
||||
DEFINE_MDNODE_GET(
|
||||
DISubprogram,
|
||||
(Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
|
||||
|
|
@ -1558,10 +1562,12 @@ public:
|
|||
unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
|
||||
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
|
||||
bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr,
|
||||
Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
|
||||
Metadata *Declaration = nullptr, Metadata *Variables = nullptr,
|
||||
Metadata *ThrownTypes = nullptr),
|
||||
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
|
||||
ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment,
|
||||
Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables))
|
||||
Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables,
|
||||
ThrownTypes))
|
||||
|
||||
TempDISubprogram clone() const { return cloneImpl(); }
|
||||
|
||||
|
|
@ -1610,11 +1616,7 @@ public:
|
|||
DIScopeRef getScope() const { return DIScopeRef(getRawScope()); }
|
||||
|
||||
StringRef getName() const { return getStringOperand(2); }
|
||||
StringRef getDisplayName() const { return getStringOperand(3); }
|
||||
StringRef getLinkageName() const { return getStringOperand(4); }
|
||||
|
||||
MDString *getRawName() const { return getOperandAs<MDString>(2); }
|
||||
MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); }
|
||||
StringRef getLinkageName() const { return getStringOperand(3); }
|
||||
|
||||
DISubroutineType *getType() const {
|
||||
return cast_or_null<DISubroutineType>(getRawType());
|
||||
|
|
@ -1626,9 +1628,7 @@ public:
|
|||
DICompileUnit *getUnit() const {
|
||||
return cast_or_null<DICompileUnit>(getRawUnit());
|
||||
}
|
||||
void replaceUnit(DICompileUnit *CU) {
|
||||
replaceOperandWith(7, CU);
|
||||
}
|
||||
void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }
|
||||
DITemplateParameterArray getTemplateParams() const {
|
||||
return cast_or_null<MDTuple>(getRawTemplateParams());
|
||||
}
|
||||
|
|
@ -1638,14 +1638,26 @@ public:
|
|||
DILocalVariableArray getVariables() const {
|
||||
return cast_or_null<MDTuple>(getRawVariables());
|
||||
}
|
||||
DITypeArray getThrownTypes() const {
|
||||
return cast_or_null<MDTuple>(getRawThrownTypes());
|
||||
}
|
||||
|
||||
Metadata *getRawScope() const { return getOperand(1); }
|
||||
Metadata *getRawType() const { return getOperand(5); }
|
||||
Metadata *getRawContainingType() const { return getOperand(6); }
|
||||
Metadata *getRawUnit() const { return getOperand(7); }
|
||||
Metadata *getRawTemplateParams() const { return getOperand(8); }
|
||||
Metadata *getRawDeclaration() const { return getOperand(9); }
|
||||
Metadata *getRawVariables() const { return getOperand(10); }
|
||||
MDString *getRawName() const { return getOperandAs<MDString>(2); }
|
||||
MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); }
|
||||
Metadata *getRawType() const { return getOperand(4); }
|
||||
Metadata *getRawUnit() const { return getOperand(5); }
|
||||
Metadata *getRawDeclaration() const { return getOperand(6); }
|
||||
Metadata *getRawVariables() const { return getOperand(7); }
|
||||
Metadata *getRawContainingType() const {
|
||||
return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr;
|
||||
}
|
||||
Metadata *getRawTemplateParams() const {
|
||||
return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr;
|
||||
}
|
||||
Metadata *getRawThrownTypes() const {
|
||||
return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr;
|
||||
}
|
||||
|
||||
/// Check if this subprogram describes the given function.
|
||||
///
|
||||
|
|
@ -1841,45 +1853,40 @@ class DINamespace : public DIScope {
|
|||
friend class LLVMContextImpl;
|
||||
friend class MDNode;
|
||||
|
||||
unsigned Line;
|
||||
unsigned ExportSymbols : 1;
|
||||
|
||||
DINamespace(LLVMContext &Context, StorageType Storage, unsigned Line,
|
||||
bool ExportSymbols, ArrayRef<Metadata *> Ops)
|
||||
DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
|
||||
ArrayRef<Metadata *> Ops)
|
||||
: DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace,
|
||||
Ops),
|
||||
Line(Line), ExportSymbols(ExportSymbols) {}
|
||||
ExportSymbols(ExportSymbols) {}
|
||||
~DINamespace() = default;
|
||||
|
||||
static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope,
|
||||
DIFile *File, StringRef Name, unsigned Line,
|
||||
bool ExportSymbols, StorageType Storage,
|
||||
bool ShouldCreate = true) {
|
||||
return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name),
|
||||
Line, ExportSymbols, Storage, ShouldCreate);
|
||||
StringRef Name, bool ExportSymbols,
|
||||
StorageType Storage, bool ShouldCreate = true) {
|
||||
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
|
||||
ExportSymbols, Storage, ShouldCreate);
|
||||
}
|
||||
static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope,
|
||||
Metadata *File, MDString *Name, unsigned Line,
|
||||
bool ExportSymbols, StorageType Storage,
|
||||
bool ShouldCreate = true);
|
||||
MDString *Name, bool ExportSymbols,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
|
||||
TempDINamespace cloneImpl() const {
|
||||
return getTemporary(getContext(), getScope(), getFile(), getName(),
|
||||
getLine(), getExportSymbols());
|
||||
return getTemporary(getContext(), getScope(), getName(),
|
||||
getExportSymbols());
|
||||
}
|
||||
|
||||
public:
|
||||
DEFINE_MDNODE_GET(DINamespace, (DIScope * Scope, DIFile *File, StringRef Name,
|
||||
unsigned Line, bool ExportSymbols),
|
||||
(Scope, File, Name, Line, ExportSymbols))
|
||||
DEFINE_MDNODE_GET(DINamespace,
|
||||
(Metadata * Scope, Metadata *File, MDString *Name,
|
||||
unsigned Line, bool ExportSymbols),
|
||||
(Scope, File, Name, Line, ExportSymbols))
|
||||
(DIScope *Scope, StringRef Name, bool ExportSymbols),
|
||||
(Scope, Name, ExportSymbols))
|
||||
DEFINE_MDNODE_GET(DINamespace,
|
||||
(Metadata *Scope, MDString *Name, bool ExportSymbols),
|
||||
(Scope, Name, ExportSymbols))
|
||||
|
||||
TempDINamespace clone() const { return cloneImpl(); }
|
||||
|
||||
unsigned getLine() const { return Line; }
|
||||
bool getExportSymbols() const { return ExportSymbols; }
|
||||
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
|
||||
StringRef getName() const { return getStringOperand(2); }
|
||||
|
|
@ -2265,6 +2272,17 @@ public:
|
|||
|
||||
/// Return whether this is a piece of an aggregate variable.
|
||||
bool isFragment() const { return getFragmentInfo().hasValue(); }
|
||||
|
||||
/// Append \p Ops with operations to apply the \p Offset.
|
||||
static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
|
||||
|
||||
/// Constants for DIExpression::prepend.
|
||||
enum { NoDeref = false, WithDeref = true, WithStackValue = true };
|
||||
|
||||
/// Prepend \p DIExpr with a deref and offset operation and optionally turn it
|
||||
/// into a stack value.
|
||||
static DIExpression *prepend(const DIExpression *DIExpr, bool Deref,
|
||||
int64_t Offset = 0, bool StackValue = false);
|
||||
};
|
||||
|
||||
/// Global variables.
|
||||
|
|
|
|||
|
|
@ -316,18 +316,20 @@ public:
|
|||
void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes);
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
unsigned getParamAlignment(unsigned i) const {
|
||||
return AttributeSets.getParamAlignment(i);
|
||||
unsigned getParamAlignment(unsigned ArgNo) const {
|
||||
return AttributeSets.getParamAlignment(ArgNo);
|
||||
}
|
||||
|
||||
/// @brief Extract the number of dereferenceable bytes for a call or
|
||||
/// parameter (0=unknown).
|
||||
/// @param i AttributeList index, referring to a return value or argument.
|
||||
uint64_t getDereferenceableBytes(unsigned i) const {
|
||||
return AttributeSets.getDereferenceableBytes(i);
|
||||
}
|
||||
|
||||
/// @brief Extract the number of dereferenceable_or_null bytes for a call or
|
||||
/// parameter (0=unknown).
|
||||
/// @param i AttributeList index, referring to a return value or argument.
|
||||
uint64_t getDereferenceableOrNullBytes(unsigned i) const {
|
||||
return AttributeSets.getDereferenceableOrNullBytes(i);
|
||||
}
|
||||
|
|
@ -416,6 +418,14 @@ public:
|
|||
removeFnAttr(Attribute::Convergent);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call has sideeffects.
|
||||
bool isSpeculatable() const {
|
||||
return hasFnAttribute(Attribute::Speculatable);
|
||||
}
|
||||
void setSpeculatable() {
|
||||
addFnAttr(Attribute::Speculatable);
|
||||
}
|
||||
|
||||
/// Determine if the function is known not to recurse, directly or
|
||||
/// indirectly.
|
||||
bool doesNotRecurse() const {
|
||||
|
|
@ -440,10 +450,10 @@ public:
|
|||
}
|
||||
|
||||
/// @brief Determine if the function returns a structure through first
|
||||
/// pointer argument.
|
||||
/// or second pointer argument.
|
||||
bool hasStructRetAttr() const {
|
||||
return AttributeSets.hasAttribute(1, Attribute::StructRet) ||
|
||||
AttributeSets.hasAttribute(2, Attribute::StructRet);
|
||||
return AttributeSets.hasParamAttribute(0, Attribute::StructRet) ||
|
||||
AttributeSets.hasParamAttribute(1, Attribute::StructRet);
|
||||
}
|
||||
|
||||
/// @brief Determine if the parameter or return value is marked with NoAlias
|
||||
|
|
|
|||
|
|
@ -1059,18 +1059,6 @@ public:
|
|||
return isFalseWhenEqual(getPredicate());
|
||||
}
|
||||
|
||||
/// @brief Determine if Pred1 implies Pred2 is true when two compares have
|
||||
/// matching operands.
|
||||
bool isImpliedTrueByMatchingCmp(Predicate Pred2) const {
|
||||
return isImpliedTrueByMatchingCmp(getPredicate(), Pred2);
|
||||
}
|
||||
|
||||
/// @brief Determine if Pred1 implies Pred2 is false when two compares have
|
||||
/// matching operands.
|
||||
bool isImpliedFalseByMatchingCmp(Predicate Pred2) const {
|
||||
return isImpliedFalseByMatchingCmp(getPredicate(), Pred2);
|
||||
}
|
||||
|
||||
/// @returns true if the predicate is unsigned, false otherwise.
|
||||
/// @brief Determine if the predicate is an unsigned operation.
|
||||
static bool isUnsigned(Predicate predicate);
|
||||
|
|
|
|||
|
|
@ -1714,9 +1714,12 @@ public:
|
|||
/// (\p i - 1) in the operand list.
|
||||
bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const;
|
||||
|
||||
/// Extract the alignment of the return value.
|
||||
unsigned getRetAlignment() const { return Attrs.getRetAlignment(); }
|
||||
|
||||
/// Extract the alignment for a call or parameter (0=unknown).
|
||||
unsigned getParamAlignment(unsigned i) const {
|
||||
return Attrs.getParamAlignment(i);
|
||||
unsigned getParamAlignment(unsigned ArgNo) const {
|
||||
return Attrs.getParamAlignment(ArgNo);
|
||||
}
|
||||
|
||||
/// Extract the number of dereferenceable bytes for a call or
|
||||
|
|
@ -3804,9 +3807,12 @@ public:
|
|||
/// (\p i - 1) in the operand list.
|
||||
bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const;
|
||||
|
||||
/// Extract the alignment of the return value.
|
||||
unsigned getRetAlignment() const { return Attrs.getRetAlignment(); }
|
||||
|
||||
/// Extract the alignment for a call or parameter (0=unknown).
|
||||
unsigned getParamAlignment(unsigned i) const {
|
||||
return Attrs.getParamAlignment(i);
|
||||
unsigned getParamAlignment(unsigned ArgNo) const {
|
||||
return Attrs.getParamAlignment(ArgNo);
|
||||
}
|
||||
|
||||
/// Extract the number of dereferenceable bytes for a call or
|
||||
|
|
|
|||
|
|
@ -201,8 +201,8 @@ namespace llvm {
|
|||
Value *getNumElements() const { return getArgOperand(2); }
|
||||
void setNumElements(Value *V) { setArgOperand(2, V); }
|
||||
|
||||
uint64_t getSrcAlignment() const { return getParamAlignment(1); }
|
||||
uint64_t getDstAlignment() const { return getParamAlignment(2); }
|
||||
uint64_t getSrcAlignment() const { return getParamAlignment(0); }
|
||||
uint64_t getDstAlignment() const { return getParamAlignment(1); }
|
||||
|
||||
uint64_t getElementSizeInBytes() const {
|
||||
Value *Arg = getArgOperand(3);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,18 @@ def IntrNoDuplicate : IntrinsicProperty;
|
|||
// Parallels the convergent attribute on LLVM IR functions.
|
||||
def IntrConvergent : IntrinsicProperty;
|
||||
|
||||
// This property indicates that the intrinsic is safe to speculate.
|
||||
def IntrSpeculatable : IntrinsicProperty;
|
||||
|
||||
// This property can be used to override the 'has no other side effects'
|
||||
// language of the IntrNoMem, IntrReadMem, IntrWriteMem, and IntrArgMemOnly
|
||||
// intrinsic properties. By default, intrinsics are assumed to have side
|
||||
// effects, so this property is only necessary if you have defined one of
|
||||
// the memory properties listed above.
|
||||
// For this property, 'side effects' has the same meaning as 'side effects'
|
||||
// defined by the hasSideEffects property of the TableGen Instruction class.
|
||||
def IntrHasSideEffects : IntrinsicProperty;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Types used by intrinsics.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class AMDGPUReadPreloadRegisterIntrinsic
|
||||
: Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
|
||||
: Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
class AMDGPUReadPreloadRegisterIntrinsicNamed<string name>
|
||||
: Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, GCCBuiltin<name>;
|
||||
: Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>, GCCBuiltin<name>;
|
||||
|
||||
let TargetPrefix = "r600" in {
|
||||
|
||||
|
|
@ -47,7 +47,8 @@ def int_r600_group_barrier : GCCBuiltin<"__builtin_r600_group_barrier">,
|
|||
// AS 7 is PARAM_I_ADDRESS, used for kernel arguments
|
||||
def int_r600_implicitarg_ptr :
|
||||
GCCBuiltin<"__builtin_r600_implicitarg_ptr">,
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 7>], [], [IntrNoMem]>;
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 7>], [],
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_r600_rat_store_typed :
|
||||
// 1st parameter: Data
|
||||
|
|
@ -57,15 +58,15 @@ def int_r600_rat_store_typed :
|
|||
GCCBuiltin<"__builtin_r600_rat_store_typed">;
|
||||
|
||||
def int_r600_recipsqrt_ieee : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_r600_recipsqrt_clamped : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_r600_cube : Intrinsic<
|
||||
[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]
|
||||
[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
} // End TargetPrefix = "r600"
|
||||
|
|
@ -82,31 +83,51 @@ defm int_amdgcn_workgroup_id : AMDGPUReadPreloadRegisterIntrinsic_xyz_named
|
|||
|
||||
def int_amdgcn_dispatch_ptr :
|
||||
GCCBuiltin<"__builtin_amdgcn_dispatch_ptr">,
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_amdgcn_queue_ptr :
|
||||
GCCBuiltin<"__builtin_amdgcn_queue_ptr">,
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_amdgcn_kernarg_segment_ptr :
|
||||
GCCBuiltin<"__builtin_amdgcn_kernarg_segment_ptr">,
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_amdgcn_implicitarg_ptr :
|
||||
GCCBuiltin<"__builtin_amdgcn_implicitarg_ptr">,
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_amdgcn_groupstaticsize :
|
||||
GCCBuiltin<"__builtin_amdgcn_groupstaticsize">,
|
||||
Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_amdgcn_dispatch_id :
|
||||
GCCBuiltin<"__builtin_amdgcn_dispatch_id">,
|
||||
Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_amdgcn_implicit_buffer_ptr :
|
||||
GCCBuiltin<"__builtin_amdgcn_implicit_buffer_ptr">,
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>;
|
||||
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [],
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
// Set EXEC to the 64-bit value given.
|
||||
// This is always moved to the beginning of the basic block.
|
||||
def int_amdgcn_init_exec : Intrinsic<[],
|
||||
[llvm_i64_ty], // 64-bit literal constant
|
||||
[IntrConvergent]>;
|
||||
|
||||
// Set EXEC according to a thread count packed in an SGPR input:
|
||||
// thread_count = (input >> bitoffset) & 0x7f;
|
||||
// This is always moved to the beginning of the basic block.
|
||||
def int_amdgcn_init_exec_from_input : Intrinsic<[],
|
||||
[llvm_i32_ty, // 32-bit SGPR input
|
||||
llvm_i32_ty], // bit offset of the thread count
|
||||
[IntrConvergent]>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Intrinsics
|
||||
|
|
@ -135,115 +156,129 @@ def int_amdgcn_div_scale : Intrinsic<
|
|||
// second. (0 = first, 1 = second).
|
||||
[llvm_anyfloat_ty, llvm_i1_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
|
||||
[IntrNoMem]
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_div_fmas : Intrinsic<[llvm_anyfloat_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
|
||||
[IntrNoMem]
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_div_fixup : Intrinsic<[llvm_anyfloat_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem]
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_trig_preop : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_sin : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_cos : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_log_clamp : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_fmul_legacy : GCCBuiltin<"__builtin_amdgcn_fmul_legacy">,
|
||||
Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]
|
||||
Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_rcp : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_rcp_legacy : GCCBuiltin<"__builtin_amdgcn_rcp_legacy">,
|
||||
Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem]
|
||||
Intrinsic<[llvm_float_ty], [llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_rsq : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_rsq_legacy : GCCBuiltin<"__builtin_amdgcn_rsq_legacy">,
|
||||
Intrinsic<
|
||||
[llvm_float_ty], [llvm_float_ty], [IntrNoMem]
|
||||
[llvm_float_ty], [llvm_float_ty], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_rsq_clamp : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
def int_amdgcn_ldexp : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_frexp_mant : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_frexp_exp : Intrinsic<
|
||||
[llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem]
|
||||
[llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
// v_fract is buggy on SI/CI. It mishandles infinities, may return 1.0
|
||||
// and always uses rtz, so is not suitable for implementing the OpenCL
|
||||
// fract function. It should be ok on VI.
|
||||
def int_amdgcn_fract : Intrinsic<
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]
|
||||
[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_cvt_pkrtz : Intrinsic<
|
||||
[llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]
|
||||
[llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_class : Intrinsic<
|
||||
[llvm_i1_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem]
|
||||
[llvm_i1_ty], [llvm_anyfloat_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_fmed3 : GCCBuiltin<"__builtin_amdgcn_fmed3">,
|
||||
Intrinsic<[llvm_anyfloat_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_cubeid : GCCBuiltin<"__builtin_amdgcn_cubeid">,
|
||||
Intrinsic<[llvm_float_ty],
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_cubema : GCCBuiltin<"__builtin_amdgcn_cubema">,
|
||||
Intrinsic<[llvm_float_ty],
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_cubesc : GCCBuiltin<"__builtin_amdgcn_cubesc">,
|
||||
Intrinsic<[llvm_float_ty],
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_cubetc : GCCBuiltin<"__builtin_amdgcn_cubetc">,
|
||||
Intrinsic<[llvm_float_ty],
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem]
|
||||
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
// v_ffbh_i32, as opposed to v_ffbh_u32. For v_ffbh_u32, llvm.ctlz
|
||||
// should be used.
|
||||
def int_amdgcn_sffbh :
|
||||
Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
|
||||
// Fields should mirror atomicrmw
|
||||
|
|
@ -527,7 +562,9 @@ def int_amdgcn_s_decperflevel :
|
|||
|
||||
def int_amdgcn_s_getreg :
|
||||
GCCBuiltin<"__builtin_amdgcn_s_getreg">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty],
|
||||
[IntrReadMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
// __builtin_amdgcn_interp_mov <param>, <attr_chan>, <attr>, <m0>
|
||||
// param values: 0 = P10, 1 = P20, 2 = P0
|
||||
|
|
@ -535,23 +572,24 @@ def int_amdgcn_interp_mov :
|
|||
GCCBuiltin<"__builtin_amdgcn_interp_mov">,
|
||||
Intrinsic<[llvm_float_ty],
|
||||
[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>;
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
// __builtin_amdgcn_interp_p1 <i>, <attr_chan>, <attr>, <m0>
|
||||
// This intrinsic reads from lds, but the memory values are constant,
|
||||
// so it behaves like IntrNoMem.
|
||||
def int_amdgcn_interp_p1 :
|
||||
GCCBuiltin<"__builtin_amdgcn_interp_p1">,
|
||||
Intrinsic<[llvm_float_ty],
|
||||
[llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>; // This intrinsic reads from lds, but the memory
|
||||
// values are constant, so it behaves like IntrNoMem.
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
// __builtin_amdgcn_interp_p2 <p1>, <j>, <attr_chan>, <attr>, <m0>
|
||||
def int_amdgcn_interp_p2 :
|
||||
GCCBuiltin<"__builtin_amdgcn_interp_p2">,
|
||||
Intrinsic<[llvm_float_ty],
|
||||
[llvm_float_ty, llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem]>; // See int_amdgcn_v_interp_p1 for why this is
|
||||
// IntrNoMem.
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
// See int_amdgcn_v_interp_p1 for why this is IntrNoMem.
|
||||
|
||||
// Pixel shaders only: whether the current pixel is live (i.e. not a helper
|
||||
// invocation for derivative computation).
|
||||
|
|
@ -574,48 +612,68 @@ def int_amdgcn_ds_swizzle :
|
|||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
|
||||
|
||||
def int_amdgcn_ubfe : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]
|
||||
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_sbfe : Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]
|
||||
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_lerp :
|
||||
GCCBuiltin<"__builtin_amdgcn_lerp">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_sad_u8 :
|
||||
GCCBuiltin<"__builtin_amdgcn_sad_u8">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_msad_u8 :
|
||||
GCCBuiltin<"__builtin_amdgcn_msad_u8">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_sad_hi_u8 :
|
||||
GCCBuiltin<"__builtin_amdgcn_sad_hi_u8">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_sad_u16 :
|
||||
GCCBuiltin<"__builtin_amdgcn_sad_u16">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_qsad_pk_u16_u8 :
|
||||
GCCBuiltin<"__builtin_amdgcn_qsad_pk_u16_u8">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_mqsad_pk_u16_u8 :
|
||||
GCCBuiltin<"__builtin_amdgcn_mqsad_pk_u16_u8">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_mqsad_u32_u8 :
|
||||
GCCBuiltin<"__builtin_amdgcn_mqsad_u32_u8">,
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_v4i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_cvt_pk_u8_f32 :
|
||||
GCCBuiltin<"__builtin_amdgcn_cvt_pk_u8_f32">,
|
||||
Intrinsic<[llvm_i32_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
|
||||
Intrinsic<[llvm_i32_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
|
||||
def int_amdgcn_icmp :
|
||||
Intrinsic<[llvm_i64_ty], [llvm_anyint_ty, LLVMMatchType<0>, llvm_i32_ty],
|
||||
|
|
@ -716,6 +774,7 @@ def int_amdgcn_unreachable : Intrinsic<[], [], [IntrConvergent]>;
|
|||
// Emit 2.5 ulp, no denormal division. Should only be inserted by
|
||||
// pass based on !fpmath metadata.
|
||||
def int_amdgcn_fdiv_fast : Intrinsic<
|
||||
[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem]
|
||||
[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
|
||||
[IntrNoMem, IntrSpeculatable]
|
||||
>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -644,13 +644,6 @@ public:
|
|||
return It->second.second;
|
||||
}
|
||||
|
||||
/// Add the given per-module index into this module index/summary,
|
||||
/// assigning it the given module ID. Each module merged in should have
|
||||
/// a unique ID, necessary for consistent renaming of promoted
|
||||
/// static (local) variables.
|
||||
void mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other,
|
||||
uint64_t NextModuleId);
|
||||
|
||||
/// Convenience method for creating a promoted global name
|
||||
/// for the given value name of a local, and its original module's ID.
|
||||
static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) {
|
||||
|
|
@ -703,13 +696,6 @@ public:
|
|||
return &I->second;
|
||||
}
|
||||
|
||||
/// Remove entries in the GlobalValueMap that have empty summaries due to the
|
||||
/// eager nature of map entry creation during VST parsing. These would
|
||||
/// also be suppressed during combined index generation in mergeFrom(),
|
||||
/// but if there was only one module or this was the first module we might
|
||||
/// not invoke mergeFrom.
|
||||
void removeEmptySummaryEntries();
|
||||
|
||||
/// Collect for the given module the list of function it defines
|
||||
/// (GUID -> Summary).
|
||||
void collectDefinedFunctionsForModule(StringRef ModulePath,
|
||||
|
|
|
|||
|
|
@ -34,19 +34,14 @@ protected:
|
|||
///
|
||||
/// This is to avoid having a vtable for the light-weight handle pointers. The
|
||||
/// fully general Callback version does have a vtable.
|
||||
enum HandleBaseKind {
|
||||
Assert,
|
||||
Callback,
|
||||
Tracking,
|
||||
Weak
|
||||
};
|
||||
enum HandleBaseKind { Assert, Callback, Weak, WeakTracking };
|
||||
|
||||
ValueHandleBase(const ValueHandleBase &RHS)
|
||||
: ValueHandleBase(RHS.PrevPair.getInt(), RHS) {}
|
||||
|
||||
ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), V(RHS.V) {
|
||||
if (isValid(V))
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), Val(RHS.getValPtr()) {
|
||||
if (isValid(getValPtr()))
|
||||
AddToExistingUseList(RHS.getPrevPtr());
|
||||
}
|
||||
|
||||
|
|
@ -54,43 +49,51 @@ private:
|
|||
PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
|
||||
ValueHandleBase *Next;
|
||||
|
||||
Value* V;
|
||||
Value *Val;
|
||||
|
||||
void setValPtr(Value *V) { Val = V; }
|
||||
|
||||
public:
|
||||
explicit ValueHandleBase(HandleBaseKind Kind)
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), V(nullptr) {}
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), Val(nullptr) {}
|
||||
ValueHandleBase(HandleBaseKind Kind, Value *V)
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), V(V) {
|
||||
if (isValid(V))
|
||||
: PrevPair(nullptr, Kind), Next(nullptr), Val(V) {
|
||||
if (isValid(getValPtr()))
|
||||
AddToUseList();
|
||||
}
|
||||
|
||||
~ValueHandleBase() {
|
||||
if (isValid(V))
|
||||
if (isValid(getValPtr()))
|
||||
RemoveFromUseList();
|
||||
}
|
||||
|
||||
Value *operator=(Value *RHS) {
|
||||
if (V == RHS) return RHS;
|
||||
if (isValid(V)) RemoveFromUseList();
|
||||
V = RHS;
|
||||
if (isValid(V)) AddToUseList();
|
||||
if (getValPtr() == RHS)
|
||||
return RHS;
|
||||
if (isValid(getValPtr()))
|
||||
RemoveFromUseList();
|
||||
setValPtr(RHS);
|
||||
if (isValid(getValPtr()))
|
||||
AddToUseList();
|
||||
return RHS;
|
||||
}
|
||||
|
||||
Value *operator=(const ValueHandleBase &RHS) {
|
||||
if (V == RHS.V) return RHS.V;
|
||||
if (isValid(V)) RemoveFromUseList();
|
||||
V = RHS.V;
|
||||
if (isValid(V)) AddToExistingUseList(RHS.getPrevPtr());
|
||||
return V;
|
||||
if (getValPtr() == RHS.getValPtr())
|
||||
return RHS.getValPtr();
|
||||
if (isValid(getValPtr()))
|
||||
RemoveFromUseList();
|
||||
setValPtr(RHS.getValPtr());
|
||||
if (isValid(getValPtr()))
|
||||
AddToExistingUseList(RHS.getPrevPtr());
|
||||
return getValPtr();
|
||||
}
|
||||
|
||||
Value *operator->() const { return V; }
|
||||
Value &operator*() const { return *V; }
|
||||
Value *operator->() const { return getValPtr(); }
|
||||
Value &operator*() const { return *getValPtr(); }
|
||||
|
||||
protected:
|
||||
Value *getValPtr() const { return V; }
|
||||
Value *getValPtr() const { return Val; }
|
||||
|
||||
static bool isValid(Value *V) {
|
||||
return V &&
|
||||
|
|
@ -105,7 +108,7 @@ protected:
|
|||
///
|
||||
/// This should only be used if a derived class has manually removed the
|
||||
/// handle from the use list.
|
||||
void clearValPtr() { V = nullptr; }
|
||||
void clearValPtr() { setValPtr(nullptr); }
|
||||
|
||||
public:
|
||||
// Callbacks made from Value.
|
||||
|
|
@ -131,19 +134,16 @@ private:
|
|||
void AddToUseList();
|
||||
};
|
||||
|
||||
/// \brief Value handle that is nullable, but tries to track the Value.
|
||||
/// \brief A nullable Value handle that is nullable.
|
||||
///
|
||||
/// This is a value handle that tries hard to point to a Value, even across
|
||||
/// RAUW operations, but will null itself out if the value is destroyed. this
|
||||
/// is useful for advisory sorts of information, but should not be used as the
|
||||
/// key of a map (since the map would have to rearrange itself when the pointer
|
||||
/// changes).
|
||||
/// This is a value handle that points to a value, and nulls itself
|
||||
/// out if that value is deleted.
|
||||
class WeakVH : public ValueHandleBase {
|
||||
public:
|
||||
WeakVH() : ValueHandleBase(Weak) {}
|
||||
WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
|
||||
WeakVH(const WeakVH &RHS)
|
||||
: ValueHandleBase(Weak, RHS) {}
|
||||
: ValueHandleBase(Weak, RHS) {}
|
||||
|
||||
WeakVH &operator=(const WeakVH &RHS) = default;
|
||||
|
||||
|
|
@ -170,6 +170,51 @@ template <> struct simplify_type<const WeakVH> {
|
|||
static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
|
||||
};
|
||||
|
||||
/// \brief Value handle that is nullable, but tries to track the Value.
|
||||
///
|
||||
/// This is a value handle that tries hard to point to a Value, even across
|
||||
/// RAUW operations, but will null itself out if the value is destroyed. this
|
||||
/// is useful for advisory sorts of information, but should not be used as the
|
||||
/// key of a map (since the map would have to rearrange itself when the pointer
|
||||
/// changes).
|
||||
class WeakTrackingVH : public ValueHandleBase {
|
||||
public:
|
||||
WeakTrackingVH() : ValueHandleBase(WeakTracking) {}
|
||||
WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {}
|
||||
WeakTrackingVH(const WeakTrackingVH &RHS)
|
||||
: ValueHandleBase(WeakTracking, RHS) {}
|
||||
|
||||
WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default;
|
||||
|
||||
Value *operator=(Value *RHS) {
|
||||
return ValueHandleBase::operator=(RHS);
|
||||
}
|
||||
Value *operator=(const ValueHandleBase &RHS) {
|
||||
return ValueHandleBase::operator=(RHS);
|
||||
}
|
||||
|
||||
operator Value*() const {
|
||||
return getValPtr();
|
||||
}
|
||||
|
||||
bool pointsToAliveValue() const {
|
||||
return ValueHandleBase::isValid(getValPtr());
|
||||
}
|
||||
};
|
||||
|
||||
// Specialize simplify_type to allow WeakTrackingVH to participate in
|
||||
// dyn_cast, isa, etc.
|
||||
template <> struct simplify_type<WeakTrackingVH> {
|
||||
typedef Value *SimpleType;
|
||||
static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; }
|
||||
};
|
||||
template <> struct simplify_type<const WeakTrackingVH> {
|
||||
typedef Value *SimpleType;
|
||||
static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) {
|
||||
return WVH;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Value handle that asserts if the Value is deleted.
|
||||
///
|
||||
/// This is a Value Handle that points to a value and asserts out if the value
|
||||
|
|
@ -272,39 +317,37 @@ struct isPodLike<AssertingVH<T> > {
|
|||
/// to a Value (or subclass) across some operations which may move that value,
|
||||
/// but should never destroy it or replace it with some unacceptable type.
|
||||
///
|
||||
/// It is an error to do anything with a TrackingVH whose value has been
|
||||
/// destroyed, except to destruct it.
|
||||
///
|
||||
/// It is an error to attempt to replace a value with one of a type which is
|
||||
/// incompatible with any of its outstanding TrackingVHs.
|
||||
template<typename ValueTy>
|
||||
class TrackingVH : public ValueHandleBase {
|
||||
void CheckValidity() const {
|
||||
Value *VP = ValueHandleBase::getValPtr();
|
||||
///
|
||||
/// It is an error to read from a TrackingVH that does not point to a valid
|
||||
/// value. A TrackingVH is said to not point to a valid value if either it
|
||||
/// hasn't yet been assigned a value yet or because the value it was tracking
|
||||
/// has since been deleted.
|
||||
///
|
||||
/// Assigning a value to a TrackingVH is always allowed, even if said TrackingVH
|
||||
/// no longer points to a valid value.
|
||||
template <typename ValueTy> class TrackingVH {
|
||||
WeakTrackingVH InnerHandle;
|
||||
|
||||
// Null is always ok.
|
||||
if (!VP) return;
|
||||
|
||||
// Check that this value is valid (i.e., it hasn't been deleted). We
|
||||
// explicitly delay this check until access to avoid requiring clients to be
|
||||
// unnecessarily careful w.r.t. destruction.
|
||||
assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
|
||||
public:
|
||||
ValueTy *getValPtr() const {
|
||||
assert(InnerHandle.pointsToAliveValue() &&
|
||||
"TrackingVH must be non-null and valid on dereference!");
|
||||
|
||||
// Check that the value is a member of the correct subclass. We would like
|
||||
// to check this property on assignment for better debugging, but we don't
|
||||
// want to require a virtual interface on this VH. Instead we allow RAUW to
|
||||
// replace this value with a value of an invalid type, and check it here.
|
||||
assert(isa<ValueTy>(VP) &&
|
||||
assert(isa<ValueTy>(InnerHandle) &&
|
||||
"Tracked Value was replaced by one with an invalid type!");
|
||||
return cast<ValueTy>(InnerHandle);
|
||||
}
|
||||
|
||||
ValueTy *getValPtr() const {
|
||||
CheckValidity();
|
||||
return (ValueTy*)ValueHandleBase::getValPtr();
|
||||
}
|
||||
void setValPtr(ValueTy *P) {
|
||||
CheckValidity();
|
||||
ValueHandleBase::operator=(GetAsValue(P));
|
||||
// Assigning to non-valid TrackingVH's are fine so we just unconditionally
|
||||
// assign here.
|
||||
InnerHandle = GetAsValue(P);
|
||||
}
|
||||
|
||||
// Convert a ValueTy*, which may be const, to the type the base
|
||||
|
|
@ -313,8 +356,8 @@ class TrackingVH : public ValueHandleBase {
|
|||
static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
|
||||
|
||||
public:
|
||||
TrackingVH() : ValueHandleBase(Tracking) {}
|
||||
TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
|
||||
TrackingVH() {}
|
||||
TrackingVH(ValueTy *P) { setValPtr(P); }
|
||||
|
||||
operator ValueTy*() const {
|
||||
return getValPtr();
|
||||
|
|
@ -359,7 +402,8 @@ public:
|
|||
///
|
||||
/// Called when this->getValPtr() is destroyed, inside ~Value(), so you
|
||||
/// may call any non-virtual Value method on getValPtr(), but no subclass
|
||||
/// methods. If WeakVH were implemented as a CallbackVH, it would use this
|
||||
/// methods. If WeakTrackingVH were implemented as a CallbackVH, it would use
|
||||
/// this
|
||||
/// method to call setValPtr(NULL). AssertingVH would use this method to
|
||||
/// cause an assertion failure.
|
||||
///
|
||||
|
|
@ -370,7 +414,8 @@ public:
|
|||
/// \brief Callback for Value RAUW.
|
||||
///
|
||||
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
|
||||
/// _before_ any of the uses have actually been replaced. If WeakVH were
|
||||
/// _before_ any of the uses have actually been replaced. If WeakTrackingVH
|
||||
/// were
|
||||
/// implemented as a CallbackVH, it would use this method to call
|
||||
/// setValPtr(new_value). AssertingVH would do nothing in this method.
|
||||
virtual void allUsesReplacedWith(Value *) {}
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ void initializeSeparateConstOffsetFromGEPPass(PassRegistry&);
|
|||
void initializeShadowStackGCLoweringPass(PassRegistry&);
|
||||
void initializeShrinkWrapPass(PassRegistry&);
|
||||
void initializeSimpleInlinerPass(PassRegistry&);
|
||||
void initializeSimpleLoopUnswitchLegacyPassPass(PassRegistry&);
|
||||
void initializeSingleLoopExtractorPass(PassRegistry&);
|
||||
void initializeSinkingLegacyPassPass(PassRegistry&);
|
||||
void initializeSjLjEHPreparePass(PassRegistry&);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ struct ConstantPoolEntry {
|
|||
// A class to keep track of assembler-generated constant pools that are use to
|
||||
// implement the ldr-pseudo.
|
||||
class ConstantPool {
|
||||
typedef SmallVector<ConstantPoolEntry, 4> EntryVecTy;
|
||||
using EntryVecTy = SmallVector<ConstantPoolEntry, 4>;
|
||||
EntryVecTy Entries;
|
||||
DenseMap<int64_t, const MCSymbolRefExpr *> CachedEntries;
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ class AssemblerConstantPools {
|
|||
// sections in a stable order to ensure that we have print the
|
||||
// constant pools in a deterministic order when printing an assembly
|
||||
// file.
|
||||
typedef MapVector<MCSection *, ConstantPool> ConstantPoolMapTy;
|
||||
using ConstantPoolMapTy = MapVector<MCSection *, ConstantPool>;
|
||||
ConstantPoolMapTy ConstantPools;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//===-- llvm/MC/LaneBitmask.h -----------------------------------*- C++ -*-===//
|
||||
//===- llvm/MC/LaneBitmask.h ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
|
@ -30,14 +30,16 @@
|
|||
#ifndef LLVM_MC_LANEBITMASK_H
|
||||
#define LLVM_MC_LANEBITMASK_H
|
||||
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/Printable.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
struct LaneBitmask {
|
||||
// When changing the underlying type, change the format string as well.
|
||||
typedef unsigned Type;
|
||||
using Type = unsigned;
|
||||
enum : unsigned { BitWidth = 8*sizeof(Type) };
|
||||
constexpr static const char *const FormatStr = "%08X";
|
||||
|
||||
|
|
@ -84,6 +86,7 @@ namespace llvm {
|
|||
OS << format(LaneBitmask::FormatStr, LaneMask.getAsInteger());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_MC_LANEBITMASK_H
|
||||
|
|
|
|||
|
|
@ -60,36 +60,36 @@ class MCAssembler {
|
|||
friend class MCAsmLayout;
|
||||
|
||||
public:
|
||||
typedef std::vector<MCSection *> SectionListType;
|
||||
typedef std::vector<const MCSymbol *> SymbolDataListType;
|
||||
using SectionListType = std::vector<MCSection *>;
|
||||
using SymbolDataListType = std::vector<const MCSymbol *>;
|
||||
|
||||
typedef pointee_iterator<SectionListType::const_iterator> const_iterator;
|
||||
typedef pointee_iterator<SectionListType::iterator> iterator;
|
||||
using const_iterator = pointee_iterator<SectionListType::const_iterator>;
|
||||
using iterator = pointee_iterator<SectionListType::iterator>;
|
||||
|
||||
typedef pointee_iterator<SymbolDataListType::const_iterator>
|
||||
const_symbol_iterator;
|
||||
typedef pointee_iterator<SymbolDataListType::iterator> symbol_iterator;
|
||||
using const_symbol_iterator =
|
||||
pointee_iterator<SymbolDataListType::const_iterator>;
|
||||
using symbol_iterator = pointee_iterator<SymbolDataListType::iterator>;
|
||||
|
||||
typedef iterator_range<symbol_iterator> symbol_range;
|
||||
typedef iterator_range<const_symbol_iterator> const_symbol_range;
|
||||
using symbol_range = iterator_range<symbol_iterator>;
|
||||
using const_symbol_range = iterator_range<const_symbol_iterator>;
|
||||
|
||||
typedef std::vector<IndirectSymbolData>::const_iterator
|
||||
const_indirect_symbol_iterator;
|
||||
typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
|
||||
using const_indirect_symbol_iterator =
|
||||
std::vector<IndirectSymbolData>::const_iterator;
|
||||
using indirect_symbol_iterator = std::vector<IndirectSymbolData>::iterator;
|
||||
|
||||
typedef std::vector<DataRegionData>::const_iterator
|
||||
const_data_region_iterator;
|
||||
typedef std::vector<DataRegionData>::iterator data_region_iterator;
|
||||
using const_data_region_iterator =
|
||||
std::vector<DataRegionData>::const_iterator;
|
||||
using data_region_iterator = std::vector<DataRegionData>::iterator;
|
||||
|
||||
/// MachO specific deployment target version info.
|
||||
// A Major version of 0 indicates that no version information was supplied
|
||||
// and so the corresponding load command should not be emitted.
|
||||
typedef struct {
|
||||
using VersionMinInfoType = struct {
|
||||
MCVersionMinType Kind;
|
||||
unsigned Major;
|
||||
unsigned Minor;
|
||||
unsigned Update;
|
||||
} VersionMinInfoType;
|
||||
};
|
||||
|
||||
private:
|
||||
MCContext &Context;
|
||||
|
|
|
|||
|
|
@ -46,17 +46,19 @@ namespace llvm {
|
|||
class MCSectionELF;
|
||||
class MCSectionMachO;
|
||||
class MCSectionWasm;
|
||||
class MCStreamer;
|
||||
class MCSymbol;
|
||||
class MCSymbolELF;
|
||||
class MCSymbolWasm;
|
||||
class SMLoc;
|
||||
class SourceMgr;
|
||||
|
||||
/// Context object for machine code objects. This class owns all of the
|
||||
/// sections that it creates.
|
||||
///
|
||||
class MCContext {
|
||||
public:
|
||||
typedef StringMap<MCSymbol *, BumpPtrAllocator &> SymbolTable;
|
||||
using SymbolTable = StringMap<MCSymbol *, BumpPtrAllocator &>;
|
||||
|
||||
private:
|
||||
/// The SourceMgr for this object, if any.
|
||||
|
|
@ -223,10 +225,12 @@ namespace llvm {
|
|||
std::string SectionName;
|
||||
StringRef GroupName;
|
||||
unsigned UniqueID;
|
||||
|
||||
WasmSectionKey(StringRef SectionName, StringRef GroupName,
|
||||
unsigned UniqueID)
|
||||
: SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
|
||||
}
|
||||
|
||||
bool operator<(const WasmSectionKey &Other) const {
|
||||
if (SectionName != Other.SectionName)
|
||||
return SectionName < Other.SectionName;
|
||||
|
|
|
|||
|
|
@ -168,10 +168,10 @@ public:
|
|||
MCLineDivisions[Sec].push_back(LineEntry);
|
||||
}
|
||||
|
||||
typedef std::vector<MCDwarfLineEntry> MCDwarfLineEntryCollection;
|
||||
typedef MCDwarfLineEntryCollection::iterator iterator;
|
||||
typedef MCDwarfLineEntryCollection::const_iterator const_iterator;
|
||||
typedef MapVector<MCSection *, MCDwarfLineEntryCollection> MCLineDivisionMap;
|
||||
using MCDwarfLineEntryCollection = std::vector<MCDwarfLineEntry>;
|
||||
using iterator = MCDwarfLineEntryCollection::iterator;
|
||||
using const_iterator = MCDwarfLineEntryCollection::const_iterator;
|
||||
using MCLineDivisionMap = MapVector<MCSection *, MCDwarfLineEntryCollection>;
|
||||
|
||||
private:
|
||||
// A collection of MCDwarfLineEntry for each section.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ class MCSymbol;
|
|||
class MCValue;
|
||||
class raw_ostream;
|
||||
class StringRef;
|
||||
typedef DenseMap<const MCSection *, uint64_t> SectionAddrMap;
|
||||
|
||||
using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
|
||||
|
||||
/// \brief Base class for the full range of assembler expressions which are
|
||||
/// needed for parsing.
|
||||
|
|
|
|||
|
|
@ -200,8 +200,8 @@ protected:
|
|||
Sec) {}
|
||||
|
||||
public:
|
||||
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
|
||||
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
|
||||
using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator;
|
||||
using fixup_iterator = SmallVectorImpl<MCFixup>::iterator;
|
||||
|
||||
SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
|
||||
const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
|
||||
|
|
|
|||
|
|
@ -176,8 +176,9 @@ public:
|
|||
|
||||
void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
|
||||
|
||||
typedef SmallVectorImpl<MCOperand>::iterator iterator;
|
||||
typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
|
||||
using iterator = SmallVectorImpl<MCOperand>::iterator;
|
||||
using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
|
||||
|
||||
void clear() { Operands.clear(); }
|
||||
void erase(iterator I) { Operands.erase(I); }
|
||||
size_t size() const { return Operands.size(); }
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class MCLOHDirective {
|
|||
const MCAsmLayout &Layout) const;
|
||||
|
||||
public:
|
||||
typedef SmallVectorImpl<MCSymbol *> LOHArgs;
|
||||
using LOHArgs = SmallVectorImpl<MCSymbol *>;
|
||||
|
||||
MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
|
||||
: Kind(Kind), Args(Args.begin(), Args.end()) {
|
||||
|
|
@ -140,7 +140,7 @@ class MCLOHContainer {
|
|||
SmallVector<MCLOHDirective, 32> Directives;
|
||||
|
||||
public:
|
||||
typedef SmallVectorImpl<MCLOHDirective> LOHDirectives;
|
||||
using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
|
||||
|
||||
MCLOHContainer() = default;
|
||||
|
||||
|
|
@ -179,8 +179,8 @@ public:
|
|||
};
|
||||
|
||||
// Add types for specialized template using MCSymbol.
|
||||
typedef MCLOHDirective::LOHArgs MCLOHArgs;
|
||||
typedef MCLOHContainer::LOHDirectives MCLOHDirectives;
|
||||
using MCLOHArgs = MCLOHDirective::LOHArgs;
|
||||
using MCLOHDirectives = MCLOHContainer::LOHDirectives;
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ protected: // Can only create subclasses.
|
|||
bool IsAtStartOfStatement = true;
|
||||
AsmCommentConsumer *CommentConsumer = nullptr;
|
||||
|
||||
bool AltMacroMode;
|
||||
MCAsmLexer();
|
||||
|
||||
virtual AsmToken LexToken() = 0;
|
||||
|
|
@ -175,6 +176,14 @@ public:
|
|||
MCAsmLexer &operator=(const MCAsmLexer &) = delete;
|
||||
virtual ~MCAsmLexer();
|
||||
|
||||
bool IsaAltMacroMode() {
|
||||
return AltMacroMode;
|
||||
}
|
||||
|
||||
void SetAltMacroMode(bool AltMacroSet) {
|
||||
AltMacroMode = AltMacroSet;
|
||||
}
|
||||
|
||||
/// Consume the next token from the input stream and return it.
|
||||
///
|
||||
/// The lexer will continuosly return the end-of-file token once the end of
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ public:
|
|||
/// assembly parsers.
|
||||
class MCAsmParser {
|
||||
public:
|
||||
typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
|
||||
typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
|
||||
ExtensionDirectiveHandler;
|
||||
using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
|
||||
using ExtensionDirectiveHandler =
|
||||
std::pair<MCAsmParserExtension*, DirectiveHandler>;
|
||||
|
||||
struct MCPendingError {
|
||||
SMLoc Loc;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class MCStreamer;
|
|||
class MCSubtargetInfo;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
|
||||
typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector;
|
||||
using OperandVector = SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>>;
|
||||
|
||||
enum AsmRewriteKind {
|
||||
AOK_Delete = 0, // Rewrite should be ignored.
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ namespace llvm {
|
|||
|
||||
/// An unsigned integer type large enough to represent all physical registers,
|
||||
/// but not necessarily virtual registers.
|
||||
typedef uint16_t MCPhysReg;
|
||||
using MCPhysReg = uint16_t;
|
||||
|
||||
/// MCRegisterClass - Base class of TargetRegisterClass.
|
||||
class MCRegisterClass {
|
||||
public:
|
||||
typedef const MCPhysReg* iterator;
|
||||
typedef const MCPhysReg* const_iterator;
|
||||
using iterator = const MCPhysReg*;
|
||||
using const_iterator = const MCPhysReg*;
|
||||
|
||||
const iterator RegsBegin;
|
||||
const uint8_t *const RegSet;
|
||||
|
|
@ -134,7 +134,7 @@ struct MCRegisterDesc {
|
|||
///
|
||||
class MCRegisterInfo {
|
||||
public:
|
||||
typedef const MCRegisterClass *regclass_iterator;
|
||||
using regclass_iterator = const MCRegisterClass *;
|
||||
|
||||
/// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be
|
||||
/// performed with a binary search.
|
||||
|
|
|
|||
|
|
@ -47,13 +47,13 @@ public:
|
|||
BundleLockedAlignToEnd
|
||||
};
|
||||
|
||||
typedef iplist<MCFragment> FragmentListType;
|
||||
using FragmentListType = iplist<MCFragment>;
|
||||
|
||||
typedef FragmentListType::const_iterator const_iterator;
|
||||
typedef FragmentListType::iterator iterator;
|
||||
using const_iterator = FragmentListType::const_iterator;
|
||||
using iterator = FragmentListType::iterator;
|
||||
|
||||
typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
|
||||
typedef FragmentListType::reverse_iterator reverse_iterator;
|
||||
using const_reverse_iterator = FragmentListType::const_reverse_iterator;
|
||||
using reverse_iterator = FragmentListType::reverse_iterator;
|
||||
|
||||
private:
|
||||
MCSymbol *Begin;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class MCSymbol;
|
|||
|
||||
/// This represents a section on wasm.
|
||||
class MCSectionWasm final : public MCSection {
|
||||
private:
|
||||
/// This is the name of the section. The referenced memory is owned by
|
||||
/// TargetLoweringObjectFileWasm's WasmUniqueMap.
|
||||
StringRef SectionName;
|
||||
|
|
@ -40,10 +41,11 @@ class MCSectionWasm final : public MCSection {
|
|||
|
||||
const MCSymbolWasm *Group;
|
||||
|
||||
// The offset of the MC function section in the wasm code section.
|
||||
// The offset of the MC function/data section in the wasm code/data section.
|
||||
// For data relocations the offset is relative to start of the data payload
|
||||
// itself and does not include the size of the section header.
|
||||
uint64_t SectionOffset;
|
||||
|
||||
private:
|
||||
friend class MCContext;
|
||||
MCSectionWasm(StringRef Section, unsigned type, unsigned flags, SectionKind K,
|
||||
const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin)
|
||||
|
|
|
|||
|
|
@ -44,12 +44,11 @@ class MCInstPrinter;
|
|||
class MCSection;
|
||||
class MCStreamer;
|
||||
class MCSymbolRefExpr;
|
||||
class MCSymbolWasm;
|
||||
class MCSubtargetInfo;
|
||||
class raw_ostream;
|
||||
class Twine;
|
||||
|
||||
typedef std::pair<MCSection *, const MCExpr *> MCSectionSubPair;
|
||||
using MCSectionSubPair = std::pair<MCSection *, const MCExpr *>;
|
||||
|
||||
/// Target specific streamer interface. This is used so that targets can
|
||||
/// implement support for target specific assembly directives.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineInstr;
|
||||
class MCInst;
|
||||
|
||||
|
|
@ -63,8 +64,7 @@ public:
|
|||
MCSubtargetInfo() = delete;
|
||||
MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
|
||||
MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
|
||||
|
||||
virtual ~MCSubtargetInfo() {}
|
||||
virtual ~MCSubtargetInfo() = default;
|
||||
|
||||
/// getTargetTriple - Return the target triple string.
|
||||
const Triple &getTargetTriple() const { return TargetTriple; }
|
||||
|
|
@ -178,11 +178,11 @@ public:
|
|||
|
||||
/// Returns string representation of scheduler comment
|
||||
virtual std::string getSchedInfoStr(const MachineInstr &MI) const {
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual std::string getSchedInfoStr(MCInst const &MCI) const {
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -145,10 +145,10 @@ protected:
|
|||
/// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit
|
||||
/// system, the name is a pointer so isn't going to satisfy the 8 byte
|
||||
/// alignment of uint64_t. Account for that here.
|
||||
typedef union {
|
||||
using NameEntryStorageTy = union {
|
||||
const StringMapEntry<bool> *NameEntry;
|
||||
uint64_t AlignmentPadding;
|
||||
} NameEntryStorageTy;
|
||||
};
|
||||
|
||||
MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary)
|
||||
: IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false),
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ class raw_pwrite_stream;
|
|||
struct WasmRelocationEntry {
|
||||
uint64_t Offset; // Where is the relocation.
|
||||
const MCSymbolWasm *Symbol; // The symbol to relocate with.
|
||||
uint64_t Addend; // A value to add to the symbol.
|
||||
int64_t Addend; // A value to add to the symbol.
|
||||
unsigned Type; // The type of the relocation.
|
||||
MCSectionWasm *FixupSection;// The section the relocation is targeting.
|
||||
|
||||
WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol,
|
||||
uint64_t Addend, unsigned Type,
|
||||
int64_t Addend, unsigned Type,
|
||||
MCSectionWasm *FixupSection)
|
||||
: Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type),
|
||||
FixupSection(FixupSection) {}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ protected:
|
|||
ID_MachOUniversalBinary,
|
||||
ID_COFFImportFile,
|
||||
ID_IR, // LLVM IR
|
||||
ID_ModuleSummaryIndex, // Module summary index
|
||||
|
||||
// Object and children.
|
||||
ID_StartObjects,
|
||||
|
|
@ -128,8 +127,6 @@ public:
|
|||
return TypeID == ID_IR;
|
||||
}
|
||||
|
||||
bool isModuleSummaryIndex() const { return TypeID == ID_ModuleSummaryIndex; }
|
||||
|
||||
bool isLittleEndian() const {
|
||||
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
|
||||
TypeID == ID_MachO32B || TypeID == ID_MachO64B);
|
||||
|
|
|
|||
|
|
@ -623,6 +623,15 @@ struct coff_base_reloc_block_entry {
|
|||
int getOffset() const { return Data & ((1 << 12) - 1); }
|
||||
};
|
||||
|
||||
struct coff_resource_dir_table {
|
||||
support::ulittle32_t Characteristics;
|
||||
support::ulittle32_t TimeDateStamp;
|
||||
support::ulittle16_t MajorVersion;
|
||||
support::ulittle16_t MinorVersion;
|
||||
support::ulittle16_t NumberOfNameEntries;
|
||||
support::ulittle16_t NumberOfIDEntries;
|
||||
};
|
||||
|
||||
class COFFObjectFile : public ObjectFile {
|
||||
private:
|
||||
friend class ImportDirectoryEntryRef;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
basic_symbol_iterator symbol_end() const override {
|
||||
DataRefImpl Symb;
|
||||
Symb.p = isCode() ? 2 : 1;
|
||||
Symb.p = isData() ? 1 : 2;
|
||||
return BasicSymbolRef(Symb, this);
|
||||
}
|
||||
|
||||
|
|
@ -63,8 +63,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool isCode() const {
|
||||
return getCOFFImportHeader()->getType() == COFF::IMPORT_CODE;
|
||||
bool isData() const {
|
||||
return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue