Vendor import of llvm trunk r301939:

https://llvm.org/svn/llvm-project/llvm/trunk@301939
This commit is contained in:
Dimitry Andric 2017-05-02 18:30:13 +00:00
parent 12f3ca4cdb
commit a303c417bb
695 changed files with 22442 additions and 10438 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View 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

View 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

View 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

View file

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

View 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

View 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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View 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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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