1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-07 13:14:51 +00:00

Vendor import of llvm trunk r306325:

https://llvm.org/svn/llvm-project/llvm/trunk@306325
This commit is contained in:
Dimitry Andric 2017-06-26 20:32:52 +00:00
parent 7c7aba6e5f
commit 08bbd35a80
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/llvm/dist/; revision=320374
svn path=/vendor/llvm/llvm-trunk-r306325/; revision=320375; tag=vendor/llvm/llvm-trunk-r306325
982 changed files with 304204 additions and 106401 deletions

View File

@ -94,7 +94,7 @@ if(CMAKE_HOST_APPLE AND APPLE)
set(LIBTOOL_NO_WARNING_FLAG "-no_warning_for_no_symbols")
endif()
endif()
foreach(lang ${languages})
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY
"${CMAKE_LIBTOOL} -static ${LIBTOOL_NO_WARNING_FLAG} -o <TARGET> \
@ -570,6 +570,10 @@ if (LLVM_BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
# Override the default target with an environment variable named by LLVM_TARGET_TRIPLE_ENV.
set(LLVM_TARGET_TRIPLE_ENV CACHE STRING "The name of environment variable to override default target. Disabled by blank.")
mark_as_advanced(LLVM_TARGET_TRIPLE_ENV)
# All options referred to from HandleLLVMOptions have to be specified
# BEFORE this include, otherwise options will not be correctly set on
# first cmake run
@ -800,7 +804,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
endif(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
if( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include llvm/Support/Solaris.h")
# special hack for Solaris to handle crazy system sys/regset.h
include_directories("${LLVM_MAIN_INCLUDE_DIR}/llvm/Support/Solaris")
endif( ${CMAKE_SYSTEM_NAME} MATCHES SunOS )
# Make sure we don't get -rdynamic in every binary. For those that need it,

View File

@ -195,6 +195,7 @@ D: MemorySanitizer (LLVM part)
N: Craig Topper
E: craig.topper@gmail.com
E: craig.topper@intel.com
D: X86 Backend
N: Ulrich Weigand

View File

@ -220,7 +220,7 @@ W: http://randomhacks.net/
D: llvm-config script
N: Anton Korobeynikov
E: asl@math.spbu.ru
E: anton at korobeynikov dot info
D: Mingw32 fixes, cross-compiling support, stdcall/fastcall calling conv.
D: x86/linux PIC codegen, aliases, regparm/visibility attributes
D: Switch lowering refactoring

View File

@ -1133,6 +1133,19 @@ function(configure_lit_site_cfg input output)
set(LIT_SITE_CFG_IN_HEADER "## Autogenerated from ${input}\n## Do not edit!")
# Override config_target_triple (and the env)
if(LLVM_TARGET_TRIPLE_ENV)
# This is expanded into the heading.
string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n"
"import os\n"
"target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n"
"config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${TARGET_TRIPLE}\")\n"
)
# This is expanded to; config.target_triple = ""+config.target_triple+""
set(TARGET_TRIPLE "\"+config.target_triple+\"")
endif()
configure_file(${input} ${output} @ONLY)
endfunction()

View File

@ -642,6 +642,9 @@ if(LLVM_USE_SANITIZER)
append_common_sanitizer_flags()
append("-fsanitize=address,undefined -fno-sanitize=vptr,function -fno-sanitize-recover=all"
CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
elseif (LLVM_USE_SANITIZER STREQUAL "Leaks")
append_common_sanitizer_flags()
append("-fsanitize=leak" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
else()
message(FATAL_ERROR "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}")
endif()

View File

@ -14,8 +14,31 @@ function(tablegen project ofn)
message(FATAL_ERROR "${project}_TABLEGEN_EXE not set")
endif()
file(GLOB local_tds "*.td")
file(GLOB_RECURSE global_tds "${LLVM_MAIN_INCLUDE_DIR}/llvm/*.td")
# Use depfile instead of globbing arbitrary *.td(s)
# DEPFILE is available for Ninja Generator with CMake>=3.7.
if(CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_VERSION VERSION_LESS 3.7)
# Make output path relative to build.ninja, assuming located on
# ${CMAKE_BINARY_DIR}.
# CMake emits build targets as relative paths but Ninja doesn't identify
# absolute path (in *.d) as relative path (in build.ninja)
# Note that tblgen is executed on ${CMAKE_BINARY_DIR} as working directory.
file(RELATIVE_PATH ofn_rel
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${ofn})
set(additional_cmdline
-o ${ofn_rel}.tmp
-d ${ofn_rel}.d
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.d
)
set(local_tds)
set(global_tds)
else()
file(GLOB local_tds "*.td")
file(GLOB_RECURSE global_tds "${LLVM_MAIN_INCLUDE_DIR}/llvm/*.td")
set(additional_cmdline
-o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
)
endif()
if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})
@ -44,7 +67,7 @@ function(tablegen project ofn)
COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR}
${LLVM_TABLEGEN_FLAGS}
${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
-o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
${additional_cmdline}
# The file in LLVM_TARGET_DEFINITIONS may be not in the current
# directory and local_tds may not contain it, so we must
# explicitly list it here:
@ -104,7 +127,8 @@ macro(add_tablegen target project)
set(${target}_OLD_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS})
set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} TableGen)
if(NOT XCODE)
# CMake-3.9 doesn't let compilation units depend on their dependent libraries.
if(NOT (CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_VERSION VERSION_LESS 3.9) AND NOT XCODE)
# FIXME: It leaks to user, callee of add_tablegen.
set(LLVM_ENABLE_OBJLIB ON)
endif()

View File

@ -587,7 +587,7 @@ Code Object Metadata
The code object metadata is specified by the ``NT_AMD_AMDHSA_METADATA`` note
record (see :ref:`amdgpu-note-records`).
The metadata is specified as a YAML formated string (see [YAML]_ and
The metadata is specified as a YAML formatted string (see [YAML]_ and
:doc:`YamlIO`).
The metadata is represented as a single YAML document comprised of the mapping
@ -1031,11 +1031,11 @@ Global variable
appropriate section according to if it has initialized data or is readonly.
If the symbol is external then its section is ``STN_UNDEF`` and the loader
will resolve relocations using the defintion provided by another code object
will resolve relocations using the definition provided by another code object
or explicitly defined by the runtime.
All global symbols, whether defined in the compilation unit or external, are
accessed by the machine code indirectly throught a GOT table entry. This
accessed by the machine code indirectly through a GOT table entry. This
allows them to be preemptable. The GOT table is only supported when the target
triple OS is ``amdhsa`` (see :ref:`amdgpu-target-triples`).
@ -1160,7 +1160,7 @@ Register Mapping
Define DWARF register enumeration.
If want to present a wavefront state then should expose vector registers as
64 wide (rather than per work-item view that LLVM uses). Either as seperate
64 wide (rather than per work-item view that LLVM uses). Either as separate
registers, or a 64x4 byte single register. In either case use a new LANE op
(akin to XDREF) to select the current lane usage in a location
expression. This would also allow scalar register spilling to vector register
@ -1653,7 +1653,7 @@ CP microcode requires the Kernel descritor to be allocated on 64 byte alignment.
``COMPUTE_PGM_RSRC2.USER_SGPR``.
6 1 bit enable_trap_handler Set to 1 if code contains a
TRAP instruction which
requires a trap hander to
requires a trap handler to
be enabled.
CP sets
@ -2146,7 +2146,7 @@ This section describes the mapping of LLVM memory model onto AMDGPU machine code
.. TODO
Update when implementation complete.
Support more relaxed OpenCL memory model to be controled by environment
Support more relaxed OpenCL memory model to be controlled by environment
component of target triple.
The AMDGPU backend supports the memory synchronization scopes specified in
@ -2201,7 +2201,7 @@ For GFX6-GFX9:
can be reordered relative to each other, which can result in reordering the
visibility of vector memory operations with respect to LDS operations of other
wavefronts in the same work-group. A ``s_waitcnt lgkmcnt(0)`` is required to
ensure synchonization between LDS operations and vector memory operations
ensure synchronization between LDS operations and vector memory operations
between waves of a work-group, but not between operations performed by the
same wavefront.
* The vector memory operations are performed as wavefront wide operations and
@ -2226,7 +2226,7 @@ For GFX6-GFX9:
scalar memory operations performed by waves executing in different work-groups
(which may be executing on different CUs) of an agent can be reordered
relative to each other. A ``s_waitcnt vmcnt(0)`` is required to ensure
synchonization between vector memory operations of different CUs. It ensures a
synchronization between vector memory operations of different CUs. It ensures a
previous vector memory operation has completed before executing a subsequent
vector memory or LDS operation and so can be used to meet the requirements of
acquire and release.
@ -2268,7 +2268,7 @@ and vector L1 caches are invalidated between kernel dispatches by CP since
constant address space data may change between kernel dispatch executions. See
:ref:`amdgpu-amdhsa-memory-spaces`.
The one exeception is if scalar writes are used to spill SGPR registers. In this
The one execption is if scalar writes are used to spill SGPR registers. In this
case the AMDGPU backend ensures the memory location used to spill is never
accessed by vector memory operations at the same time. If scalar writes are used
then a ``s_dcache_wb`` is inserted before the ``s_endpgm`` and before a function
@ -3310,7 +3310,7 @@ table
be moved before the acquire.
- If a fence then same as load atomic, plus no preceding
associated fence-paired-atomic can be moved after the fence.
release - If a store atomic/atomicrmw then no preceeding load/load
release - If a store atomic/atomicrmw then no preceding load/load
atomic/store/ store atomic/atomicrmw/fence instruction can
be moved after the release.
- If a fence then same as store atomic, plus no following

View File

@ -27,7 +27,7 @@ questions.
What is the first index of the GEP instruction?
-----------------------------------------------
Quick answer: The index stepping through the first operand.
Quick answer: The index stepping through the second operand.
The confusion with the first index usually arises from thinking about the
GetElementPtr instruction as if it was a C index operator. They aren't the
@ -59,7 +59,7 @@ Sometimes this question gets rephrased as:
won't be dereferenced?*
The answer is simply because memory does not have to be accessed to perform the
computation. The first operand to the GEP instruction must be a value of a
computation. The second operand to the GEP instruction must be a value of a
pointer type. The value of the pointer is provided directly to the GEP
instruction as an operand without any need for accessing memory. It must,
therefore be indexed and requires an index operand. Consider this example:
@ -80,8 +80,8 @@ therefore be indexed and requires an index operand. Consider this example:
In this "C" example, the front end compiler (Clang) will generate three GEP
instructions for the three indices through "P" in the assignment statement. The
function argument ``P`` will be the first operand of each of these GEP
instructions. The second operand indexes through that pointer. The third
function argument ``P`` will be the second operand of each of these GEP
instructions. The third operand indexes through that pointer. The fourth
operand will be the field offset into the ``struct munger_struct`` type, for
either the ``f1`` or ``f2`` field. So, in LLVM assembly the ``munge`` function
looks like:
@ -100,8 +100,8 @@ looks like:
ret void
}
In each case the first operand is the pointer through which the GEP instruction
starts. The same is true whether the first operand is an argument, allocated
In each case the second operand is the pointer through which the GEP instruction
starts. The same is true whether the second operand is an argument, allocated
memory, or a global variable.
To make this clear, let's consider a more obtuse example:
@ -159,11 +159,11 @@ confusion:
i32 }*``. That is, ``%MyStruct`` is a pointer to a structure containing a
pointer to a ``float`` and an ``i32``.
#. Point #1 is evidenced by noticing the type of the first operand of the GEP
#. Point #1 is evidenced by noticing the type of the second operand of the GEP
instruction (``%MyStruct``) which is ``{ float*, i32 }*``.
#. The first index, ``i64 0`` is required to step over the global variable
``%MyStruct``. Since the first argument to the GEP instruction must always
``%MyStruct``. Since the second argument to the GEP instruction must always
be a value of pointer type, the first index steps through that pointer. A
value of 0 means 0 elements offset from that pointer.
@ -267,7 +267,7 @@ in the IR. In the future, it will probably be outright disallowed.
What effect do address spaces have on GEPs?
-------------------------------------------
None, except that the address space qualifier on the first operand pointer type
None, except that the address space qualifier on the second operand pointer type
always matches the address space qualifier on the result type.
How is GEP different from ``ptrtoint``, arithmetic, and ``inttoptr``?
@ -526,7 +526,7 @@ instruction:
#. The GEP instruction never accesses memory, it only provides pointer
computations.
#. The first operand to the GEP instruction is always a pointer and it must be
#. The second operand to the GEP instruction is always a pointer and it must be
indexed.
#. There are no superfluous indices for the GEP instruction.

View File

@ -7,7 +7,7 @@ Introduction
Building with link time optimization requires cooperation from
the system linker. LTO support on Linux systems requires that you use the
`gold linker`_ which supports LTO via plugins. This is the same mechanism
`gold linker`_ or ld.bfd from binutils >= 2.21.51.0.2, as they support LTO via plugins. This is the same mechanism
used by the `GCC LTO`_ project.
The LLVM gold plugin implements the gold plugin interface on top of
@ -23,24 +23,22 @@ The LLVM gold plugin implements the gold plugin interface on top of
How to build it
===============
You need to have gold with plugin support and build the LLVMgold plugin.
Check whether you have gold running ``/usr/bin/ld -v``. It will report "GNU
gold" or else "GNU ld" if not. If you have gold, check for plugin support
by running ``/usr/bin/ld -plugin``. If it complains "missing argument" then
you have plugin support. If not, such as an "unknown option" error then you
will either need to build gold or install a version with plugin support.
Check for plugin support by running ``/usr/bin/ld -plugin``. If it complains
"missing argument" then you have plugin support. If not, such as an "unknown option"
error then you will either need to build gold or install a recent version
of ld.bfd with plugin support and then build gold plugin.
* Download, configure and build gold with plugin support:
* Download, configure and build ld.bfd with plugin support:
.. code-block:: bash
$ git clone --depth 1 git://sourceware.org/git/binutils-gdb.git binutils
$ mkdir build
$ cd build
$ ../binutils/configure --enable-gold --enable-plugins --disable-werror
$ make all-gold
$ ../binutils/configure --disable-werror # ld.bfd includes plugin support by default
$ make all-ld
That should leave you with ``build/gold/ld-new`` which supports
That should leave you with ``build/ld/ld-new`` which supports
the ``-plugin`` option. Running ``make`` will additionally build
``build/binutils/ar`` and ``nm-new`` binaries supporting plugins.

View File

@ -1468,6 +1468,19 @@ example:
This attribute by itself does not imply restrictions on
inter-procedural optimizations. All of the semantic effects the
patching may have to be separately conveyed via the linkage type.
``"probe-stack"``
This attribute indicates that the function will trigger a guard region
in the end of the stack. It ensures that accesses to the stack must be
no further apart than the size of the guard region to a previous
access of the stack. It takes one required string value, the name of
the stack probing function that will be called.
If a function that has a ``"probe-stack"`` attribute is inlined into
a function with another ``"probe-stack"`` attribute, the resulting
function has the ``"probe-stack"`` attribute of the caller. If a
function that has a ``"probe-stack"`` attribute is inlined into a
function that has no ``"probe-stack"`` attribute at all, the resulting
function has the ``"probe-stack"`` attribute of the callee.
``readnone``
On a function, this attribute indicates that the function computes its
result (or decides to unwind an exception) based strictly on its arguments,
@ -1498,6 +1511,21 @@ example:
On an argument, this attribute indicates that the function does not write
through this pointer argument, even though it may write to the memory that
the pointer points to.
``"stack-probe-size"``
This attribute controls the behavior of stack probes: either
the ``"probe-stack"`` attribute, or ABI-required stack probes, if any.
It defines the size of the guard region. It ensures that if the function
may use more stack space than the size of the guard region, stack probing
sequence will be emitted. It takes one required integer value, which
is 4096 by default.
If a function that has a ``"stack-probe-size"`` attribute is inlined into
a function with another ``"stack-probe-size"`` attribute, the resulting
function has the ``"stack-probe-size"`` attribute that has the lower
numeric value. If a function that has a ``"stack-probe-size"`` attribute is
inlined into a function that has no ``"stack-probe-size"`` attribute
at all, the resulting function has the ``"stack-probe-size"`` attribute
of the callee.
``writeonly``
On a function, this attribute indicates that the function may write to but
does not read from memory.
@ -1989,7 +2017,7 @@ A pointer value is *based* on another pointer value according to the
following rules:
- A pointer value formed from a ``getelementptr`` operation is *based*
on the first value operand of the ``getelementptr``.
on the second value operand of the ``getelementptr``.
- The result value of a ``bitcast`` is *based* on the operand of the
``bitcast``.
- A pointer value formed by an ``inttoptr`` is *based* on all pointer
@ -3166,7 +3194,7 @@ The following is the syntax for constant expressions:
``getelementptr (TY, CSTPTR, IDX0, IDX1, ...)``, ``getelementptr inbounds (TY, CSTPTR, IDX0, IDX1, ...)``
Perform the :ref:`getelementptr operation <i_getelementptr>` on
constants. As with the :ref:`getelementptr <i_getelementptr>`
instruction, the index list may have zero or more indexes, which are
instruction, the index list may have one or more indexes, which are
required to make sense for the type of "pointer to TY".
``select (COND, VAL1, VAL2)``
Perform the :ref:`select operation <i_select>` on constants.
@ -7805,7 +7833,7 @@ base address to start from. The remaining arguments are indices
that indicate which of the elements of the aggregate object are indexed.
The interpretation of each index is dependent on the type being indexed
into. The first index always indexes the pointer value given as the
first argument, the second index indexes a value of the type pointed to
second argument, the second index indexes a value of the type pointed to
(not necessarily the value directly pointed to, since the first index
can be non-zero), etc. The first type indexed into must be a pointer
value, subsequent types can be arrays, vectors, and structs. Note that

View File

@ -27,7 +27,7 @@ Vectorization Workflow
VPlan-based vectorization involves three major steps, taking a "scenario-based
approach" to vectorization planning:
1. Legal Step: check if a loop can be legally vectorized; encode contraints and
1. Legal Step: check if a loop can be legally vectorized; encode constraints and
artifacts if so.
2. Plan Step:

View File

@ -150,7 +150,7 @@ variable, where we list down the options and their defaults below.
| xray_logfile_base | ``const char*`` | ``xray-log.`` | Filename base for the |
| | | | XRay logfile. |
+-------------------+-----------------+---------------+------------------------+
| xray_fdr_log | ``bool`` | ``false`` | Wheter to install the |
| xray_fdr_log | ``bool`` | ``false`` | Whether to install the |
| | | | Flight Data Recorder |
| | | | (FDR) mode. |
+-------------------+-----------------+---------------+------------------------+

View File

@ -40,11 +40,11 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
public:
using ModuleHandle = decltype(CompileLayer)::ModuleSetHandleT;
using ModuleHandle = decltype(CompileLayer)::ModuleHandleT;
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
@ -72,15 +72,11 @@ class KaleidoscopeJIT {
return JITSymbol(nullptr);
});
// Build a singleton module set to hold our module.
std::vector<std::unique_ptr<Module>> Ms;
Ms.push_back(std::move(M));
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return CompileLayer.addModuleSet(std::move(Ms),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
return CompileLayer.addModule(std::move(M),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
}
JITSymbol findSymbol(const std::string Name) {
@ -91,7 +87,7 @@ class KaleidoscopeJIT {
}
void removeModule(ModuleHandle H) {
CompileLayer.removeModuleSet(H);
CompileLayer.removeModule(H);
}
};

View File

@ -44,22 +44,22 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;
std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>;
IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
public:
using ModuleHandle = decltype(OptimizeLayer)::ModuleSetHandleT;
using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
OptimizeLayer(CompileLayer,
[this](std::unique_ptr<Module> M) {
[this](std::shared_ptr<Module> M) {
return optimizeModule(std::move(M));
}) {
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
@ -85,15 +85,11 @@ class KaleidoscopeJIT {
return JITSymbol(nullptr);
});
// Build a singleton module set to hold our module.
std::vector<std::unique_ptr<Module>> Ms;
Ms.push_back(std::move(M));
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return OptimizeLayer.addModuleSet(std::move(Ms),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
return OptimizeLayer.addModule(std::move(M),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
}
JITSymbol findSymbol(const std::string Name) {
@ -104,11 +100,11 @@ class KaleidoscopeJIT {
}
void removeModule(ModuleHandle H) {
OptimizeLayer.removeModuleSet(H);
OptimizeLayer.removeModule(H);
}
private:
std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) {
// Create a function pass manager.
auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());

View File

@ -47,11 +47,11 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;
std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>;
IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
@ -59,13 +59,13 @@ class KaleidoscopeJIT {
CompileOnDemandLayer<decltype(OptimizeLayer)> CODLayer;
public:
using ModuleHandle = decltype(CODLayer)::ModuleSetHandleT;
using ModuleHandle = decltype(CODLayer)::ModuleHandleT;
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
OptimizeLayer(CompileLayer,
[this](std::unique_ptr<Module> M) {
[this](std::shared_ptr<Module> M) {
return optimizeModule(std::move(M));
}),
CompileCallbackManager(
@ -98,15 +98,11 @@ class KaleidoscopeJIT {
return JITSymbol(nullptr);
});
// Build a singleton module set to hold our module.
std::vector<std::unique_ptr<Module>> Ms;
Ms.push_back(std::move(M));
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return CODLayer.addModuleSet(std::move(Ms),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
return CODLayer.addModule(std::move(M),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
}
JITSymbol findSymbol(const std::string Name) {
@ -117,11 +113,11 @@ class KaleidoscopeJIT {
}
void removeModule(ModuleHandle H) {
CODLayer.removeModuleSet(H);
CODLayer.removeModule(H);
}
private:
std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) {
// Create a function pass manager.
auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());

View File

@ -73,11 +73,11 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;
std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>;
IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
@ -85,14 +85,14 @@ class KaleidoscopeJIT {
std::unique_ptr<IndirectStubsManager> IndirectStubsMgr;
public:
using ModuleHandle = decltype(OptimizeLayer)::ModuleSetHandleT;
using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()),
DL(TM->createDataLayout()),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
OptimizeLayer(CompileLayer,
[this](std::unique_ptr<Module> M) {
[this](std::shared_ptr<Module> M) {
return optimizeModule(std::move(M));
}),
CompileCallbackMgr(
@ -125,15 +125,11 @@ class KaleidoscopeJIT {
return JITSymbol(nullptr);
});
// Build a singleton module set to hold our module.
std::vector<std::unique_ptr<Module>> Ms;
Ms.push_back(std::move(M));
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return OptimizeLayer.addModuleSet(std::move(Ms),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
return OptimizeLayer.addModule(std::move(M),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
}
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
@ -199,7 +195,7 @@ class KaleidoscopeJIT {
}
void removeModule(ModuleHandle H) {
OptimizeLayer.removeModuleSet(H);
OptimizeLayer.removeModule(H);
}
private:
@ -210,7 +206,7 @@ class KaleidoscopeJIT {
return MangledNameStream.str();
}
std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) {
// Create a function pass manager.
auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());

View File

@ -78,11 +78,11 @@ class KaleidoscopeJIT {
private:
std::unique_ptr<TargetMachine> TM;
const DataLayout DL;
RTDyldObjectLinkingLayer<> ObjectLayer;
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
RTDyldObjectLinkingLayer ObjectLayer;
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
using OptimizeFunction =
std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>;
std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>;
IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
@ -91,7 +91,7 @@ class KaleidoscopeJIT {
MyRemote &Remote;
public:
using ModuleHandle = decltype(OptimizeLayer)::ModuleSetHandleT;
using ModuleHandle = decltype(OptimizeLayer)::ModuleHandleT;
KaleidoscopeJIT(MyRemote &Remote)
: TM(EngineBuilder().selectTarget(Triple(Remote.getTargetTriple()), "",
@ -99,7 +99,7 @@ class KaleidoscopeJIT {
DL(TM->createDataLayout()),
CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
OptimizeLayer(CompileLayer,
[this](std::unique_ptr<Module> M) {
[this](std::shared_ptr<Module> M) {
return optimizeModule(std::move(M));
}),
Remote(Remote) {
@ -153,15 +153,11 @@ class KaleidoscopeJIT {
exit(1);
}
// Build a singleton module set to hold our module.
std::vector<std::unique_ptr<Module>> Ms;
Ms.push_back(std::move(M));
// Add the set to the JIT with the resolver we created above and a newly
// created SectionMemoryManager.
return OptimizeLayer.addModuleSet(std::move(Ms),
std::move(MemMgr),
std::move(Resolver));
return OptimizeLayer.addModule(std::move(M),
std::move(MemMgr),
std::move(Resolver));
}
Error addFunctionAST(std::unique_ptr<FunctionAST> FnAST) {
@ -231,7 +227,7 @@ class KaleidoscopeJIT {
}
void removeModule(ModuleHandle H) {
OptimizeLayer.removeModuleSet(H);
OptimizeLayer.removeModule(H);
}
private:
@ -242,7 +238,7 @@ class KaleidoscopeJIT {
return MangledNameStream.str();
}
std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
std::shared_ptr<Module> optimizeModule(std::shared_ptr<Module> M) {
// Create a function pass manager.
auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());

View File

@ -39,9 +39,9 @@ namespace orc {
class KaleidoscopeJIT {
public:
using ObjLayerT = RTDyldObjectLinkingLayer<>;
using CompileLayerT = IRCompileLayer<ObjLayerT>;
using ModuleHandleT = CompileLayerT::ModuleSetHandleT;
using ObjLayerT = RTDyldObjectLinkingLayer;
using CompileLayerT = IRCompileLayer<ObjLayerT, SimpleCompiler>;
using ModuleHandleT = CompileLayerT::ModuleHandleT;
KaleidoscopeJIT()
: TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
@ -62,9 +62,9 @@ class KaleidoscopeJIT {
return JITSymbol(nullptr);
},
[](const std::string &S) { return nullptr; });
auto H = CompileLayer.addModuleSet(singletonSet(std::move(M)),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
auto H = CompileLayer.addModule(std::move(M),
make_unique<SectionMemoryManager>(),
std::move(Resolver));
ModuleHandles.push_back(H);
return H;
@ -72,7 +72,7 @@ class KaleidoscopeJIT {
void removeModule(ModuleHandleT H) {
ModuleHandles.erase(find(ModuleHandles, H));
CompileLayer.removeModuleSet(H);
CompileLayer.removeModule(H);
}
JITSymbol findSymbol(const std::string Name) {
@ -89,12 +89,6 @@ class KaleidoscopeJIT {
return MangledName;
}
template <typename T> static std::vector<T> singletonSet(T t) {
std::vector<T> Vec;
Vec.push_back(std::move(t));
return Vec;
}
JITSymbol findMangledSymbol(const std::string &Name) {
#ifdef LLVM_ON_WIN32
// The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported

View File

@ -29,6 +29,8 @@
extern "C" {
#endif
typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef;
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
typedef uint32_t LLVMOrcModuleHandle;
typedef uint64_t LLVMOrcTargetAddress;
@ -38,6 +40,45 @@ typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
typedef enum { LLVMOrcErrSuccess = 0, LLVMOrcErrGeneric } LLVMOrcErrorCode;
/**
* Turn an LLVMModuleRef into an LLVMSharedModuleRef.
*
* The JIT uses shared ownership for LLVM modules, since it is generally
* difficult to know when the JIT will be finished with a module (and the JIT
* has no way of knowing when a user may be finished with one).
*
* Calling this method with an LLVMModuleRef creates a shared-pointer to the
* module, and returns a reference to this shared pointer.
*
* The shared module should be disposed when finished with by calling
* LLVMOrcDisposeSharedModule (not LLVMDisposeModule). The Module will be
* deleted when the last shared pointer owner relinquishes it.
*/
LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod);
/**
* Dispose of a shared module.
*
* The module should not be accessed after this call. The module will be
* deleted once all clients (including the JIT itself) have released their
* shared pointers.
*/
void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod);
/**
* Get an LLVMSharedObjectBufferRef from an LLVMMemoryBufferRef.
*/
LLVMSharedObjectBufferRef
LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer);
/**
* Dispose of a shared object buffer.
*/
void
LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer);
/**
* Create an ORC JIT stack.
*
@ -95,7 +136,8 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
* Add module to be eagerly compiled.
*/
LLVMOrcModuleHandle
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack,
LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
@ -103,7 +145,8 @@ LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
* Add module to be lazily compiled one function at a time.
*/
LLVMOrcModuleHandle
LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
LLVMSharedModuleRef Mod,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);
@ -111,7 +154,7 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
* Add an object file.
*/
LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
LLVMObjectFileRef Obj,
LLVMSharedObjectBufferRef Obj,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);

View File

@ -140,8 +140,8 @@ enum lostFraction { // Example of truncated bits:
// implementation classes. This struct should not define any non-static data
// members.
struct APFloatBase {
// TODO remove this and use APInt typedef directly.
typedef APInt::WordType integerPart;
static const unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD;
/// A signed type to represent a floating point numbers unbiased exponent.
typedef signed short ExponentType;

View File

@ -213,6 +213,12 @@ class LLVM_NODISCARD APInt {
/// out-of-line slow case for countLeadingZeros
unsigned countLeadingZerosSlowCase() const LLVM_READONLY;
/// out-of-line slow case for countLeadingOnes.
unsigned countLeadingOnesSlowCase() const LLVM_READONLY;
/// out-of-line slow case for countTrailingZeros.
unsigned countTrailingZerosSlowCase() const LLVM_READONLY;
/// out-of-line slow case for countTrailingOnes
unsigned countTrailingOnesSlowCase() const LLVM_READONLY;
@ -383,7 +389,7 @@ class LLVM_NODISCARD APInt {
bool isAllOnesValue() const {
if (isSingleWord())
return U.VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth);
return countPopulationSlowCase() == BitWidth;
return countTrailingOnesSlowCase() == BitWidth;
}
/// \brief Determine if all bits are clear
@ -408,7 +414,9 @@ class LLVM_NODISCARD APInt {
/// This checks to see if the value of this APInt is the maximum signed
/// value for the APInt's bit width.
bool isMaxSignedValue() const {
return !isNegative() && countPopulation() == BitWidth - 1;
if (isSingleWord())
return U.VAL == ((WordType(1) << (BitWidth - 1)) - 1);
return !isNegative() && countTrailingOnesSlowCase() == BitWidth - 1;
}
/// \brief Determine if this is the smallest unsigned value.
@ -422,7 +430,9 @@ class LLVM_NODISCARD APInt {
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
bool isMinSignedValue() const {
return isNegative() && isPowerOf2();
if (isSingleWord())
return U.VAL == (WordType(1) << (BitWidth - 1));
return isNegative() && countTrailingZerosSlowCase() == BitWidth - 1;
}
/// \brief Check if this APInt has an N-bits unsigned integer value.
@ -1574,7 +1584,11 @@ class LLVM_NODISCARD APInt {
///
/// \returns 0 if the high order bit is not set, otherwise returns the number
/// of 1 bits from the most significant to the least
unsigned countLeadingOnes() const LLVM_READONLY;
unsigned countLeadingOnes() const {
if (isSingleWord())
return llvm::countLeadingOnes(U.VAL << (APINT_BITS_PER_WORD - BitWidth));
return countLeadingOnesSlowCase();
}
/// Computes the number of leading bits of this APInt that are equal to its
/// sign bit.
@ -1590,7 +1604,11 @@ class LLVM_NODISCARD APInt {
///
/// \returns BitWidth if the value is zero, otherwise returns the number of
/// zeros from the least significant bit to the first one bit.
unsigned countTrailingZeros() const LLVM_READONLY;
unsigned countTrailingZeros() const {
if (isSingleWord())
return std::min(unsigned(llvm::countTrailingZeros(U.VAL)), BitWidth);
return countTrailingZerosSlowCase();
}
/// \brief Count the number of trailing one bits.
///

View File

@ -15,10 +15,12 @@
#define LLVM_ADT_STRINGEXTRAS_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <iterator>
#include <string>
@ -129,6 +131,32 @@ template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
return !S.getAsInteger(Base, Num);
}
namespace detail {
template <typename N>
inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
SmallString<32> Storage;
StringRef S = T.toNullTerminatedStringRef(Storage);
char *End;
N Temp = StrTo(S.data(), &End);
if (*End != '\0')
return false;
Num = Temp;
return true;
}
}
inline bool to_float(const Twine &T, float &Num) {
return detail::to_float(T, Num, strtof);
}
inline bool to_float(const Twine &T, double &Num) {
return detail::to_float(T, Num, strtod);
}
inline bool to_float(const Twine &T, long double &Num) {
return detail::to_float(T, Num, strtold);
}
static inline std::string utostr(uint64_t X, bool isNeg = false) {
char Buffer[21];
char *BufPtr = std::end(Buffer);

View File

@ -147,6 +147,7 @@ class Triple {
enum OSType {
UnknownOS,
Ananas,
CloudABI,
Darwin,
DragonFly,

View File

@ -93,6 +93,13 @@ class LazyValueInfo {
Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
Instruction *CxtI = nullptr);
/// Return the ConstantRage constraint that is known to hold for the
/// specified value on the specified edge. This may be only be called
/// on integer-typed Values.
ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
BasicBlock *ToBB,
Instruction *CxtI = nullptr);
/// Inform the analysis cache that we have threaded an edge from
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);

View File

@ -39,6 +39,15 @@ bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
/// Returns true if V is always dereferenceable for Size byte with alignment
/// greater or equal than requested. If the context instruction is specified
/// performs context-sensitive analysis and returns true if the pointer is
/// dereferenceable at the specified instruction.
bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
const APInt &Size, const DataLayout &DL,
const Instruction *CtxI = nullptr,
const DominatorTree *DT = nullptr);
/// Return true if we know that executing a load from this value cannot trap.
///
/// If DT and ScanFrom are specified this method performs context-sensitive

View File

@ -91,8 +91,9 @@ getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
/// getLoopPreheader - If there is a preheader for this loop, return it. A
/// loop has a preheader if there is only one edge to the header of the loop
/// from outside of the loop. If this is the case, the block branching to the
/// header of the loop is the preheader node.
/// from outside of the loop and it is legal to hoist instructions into the
/// predecessor. If this is the case, the block branching to the header of the
/// loop is the preheader node.
///
/// This method returns null if there is no preheader for the loop.
///
@ -102,6 +103,10 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPreheader() const {
BlockT *Out = getLoopPredecessor();
if (!Out) return nullptr;
// Make sure we are allowed to hoist instructions into the predecessor.
if (!Out->isLegalToHoistInto())
return nullptr;
// Make sure there is only one exit out of the preheader.
typedef GraphTraits<BlockT*> BlockTraits;
typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);

View File

@ -784,7 +784,9 @@ class ScalarEvolution {
}
/// Determine the range for a particular SCEV.
ConstantRange getRange(const SCEV *S, RangeSignHint Hint);
/// NOTE: This returns a reference to an entry in a cache. It must be
/// copied if its needed for longer.
const ConstantRange &getRangeRef(const SCEV *S, RangeSignHint Hint);
/// Determines the range for the affine SCEVAddRecExpr {\p Start,+,\p Stop}.
/// Helper for \c getRange.
@ -1464,15 +1466,35 @@ class ScalarEvolution {
uint32_t GetMinTrailingZeros(const SCEV *S);
/// Determine the unsigned range for a particular SCEV.
///
/// NOTE: This returns a copy of the reference returned by getRangeRef.
ConstantRange getUnsignedRange(const SCEV *S) {
return getRange(S, HINT_RANGE_UNSIGNED);
return getRangeRef(S, HINT_RANGE_UNSIGNED);
}
/// Determine the min of the unsigned range for a particular SCEV.
APInt getUnsignedRangeMin(const SCEV *S) {
return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMin();
}
/// Determine the max of the unsigned range for a particular SCEV.
APInt getUnsignedRangeMax(const SCEV *S) {
return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMax();
}
/// Determine the signed range for a particular SCEV.
///
/// NOTE: This returns a copy of the reference returned by getRangeRef.
ConstantRange getSignedRange(const SCEV *S) {
return getRange(S, HINT_RANGE_SIGNED);
return getRangeRef(S, HINT_RANGE_SIGNED);
}
/// Determine the min of the signed range for a particular SCEV.
APInt getSignedRangeMin(const SCEV *S) {
return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMin();
}
/// Determine the max of the signed range for a particular SCEV.
APInt getSignedRangeMax(const SCEV *S) {
return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMax();
}
/// Test if the given expression is known to be negative.

View File

@ -46,6 +46,12 @@ static const char ClGlObjMagic[] = {
'\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2',
};
// The signature bytes that start a .res file.
static const char WinResMagic[] = {
'\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00',
'\xff', '\xff', '\x00', '\x00', '\xff', '\xff', '\x00', '\x00',
};
// Sizes in bytes of various things in the COFF format.
enum {
Header16Size = 20,

View File

@ -484,7 +484,7 @@ struct PubIndexEntryDescriptor {
};
/// Constants that define the DWARF format as 32 or 64 bit.
enum DwarfFormat { DWARF32, DWARF64 };
enum DwarfFormat : uint8_t { DWARF32, DWARF64 };
} // End of namespace dwarf

View File

@ -78,7 +78,8 @@ enum {
MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u,
MH_HAS_TLV_DESCRIPTORS = 0x00800000u,
MH_NO_HEAP_EXECUTION = 0x01000000u,
MH_APP_EXTENSION_SAFE = 0x02000000u
MH_APP_EXTENSION_SAFE = 0x02000000u,
MH_NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000u
};
enum : uint32_t {

View File

@ -176,6 +176,11 @@ enum class ValType {
// Linking metadata kinds.
enum : unsigned {
WASM_STACK_POINTER = 0x1,
WASM_SYMBOL_INFO = 0x2,
};
enum : unsigned {
WASM_SYMBOL_FLAG_WEAK = 0x1,
};
#define WASM_RELOC(name, value) name = value,

View File

@ -121,8 +121,8 @@ class DIEAbbrev : public FoldingSetNode {
/// Print the abbreviation using the specified asm printer.
void Emit(const AsmPrinter *AP) const;
void print(raw_ostream &O);
void dump();
void print(raw_ostream &O) const;
void dump() const;
};
//===--------------------------------------------------------------------===//
@ -780,7 +780,7 @@ class DIE : IntrusiveBackListNode, public DIEValueList {
DIEValue findAttribute(dwarf::Attribute Attribute) const;
void print(raw_ostream &O, unsigned IndentCount = 0) const;
void dump();
void dump() const;
};
//===--------------------------------------------------------------------===//

View File

@ -29,6 +29,7 @@ class MachineOperand;
class MachineRegisterInfo;
class RegisterBankInfo;
class TargetInstrInfo;
class TargetRegisterClass;
class TargetRegisterInfo;
/// Container class for CodeGen predicate results.
@ -79,6 +80,16 @@ class InstructionSelector {
InstructionSelector();
/// Constrain a register operand of an instruction \p I to a specified
/// register class. This could involve inserting COPYs before (for uses) or
/// after (for defs) and may replace the operand of \p I.
/// \returns whether operand regclass constraining succeeded.
bool constrainOperandRegToRegClass(MachineInstr &I, unsigned OpIdx,
const TargetRegisterClass &RC,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
const RegisterBankInfo &RBI) const;
/// Mutate the newly-selected instruction \p I to constrain its (possibly
/// generic) virtual register operands to the instruction's register class.
/// This could involve inserting COPYs before (for uses) or after (for defs).

View File

@ -59,7 +59,7 @@ class Legalizer : public MachineFunctionPass {
const TargetInstrInfo &TII);
bool combineMerges(MachineInstr &MI, MachineRegisterInfo &MRI,
const TargetInstrInfo &TII);
const TargetInstrInfo &TII, MachineIRBuilder &MIRBuilder);
bool runOnMachineFunction(MachineFunction &MF) override;
};

View File

@ -471,10 +471,12 @@ class MachineIRBuilder {
/// Build and insert \p Res = IMPLICIT_DEF.
MachineInstrBuilder buildUndef(unsigned Dst);
/// Build and insert \p Res<def> = G_SEQUENCE \p Op0, \p Idx0...
/// Build and insert instructions to put \p Ops together at the specified p
/// Indices to form a larger register.
///
/// G_SEQUENCE inserts each element of Ops into an IMPLICIT_DEF register,
/// where each entry starts at the bit-index specified by \p Indices.
/// If the types of the input registers are uniform and cover the entirity of
/// \p Res then a G_MERGE_VALUES will be produced. Otherwise an IMPLICIT_DEF
/// followed by a sequence of G_INSERT instructions.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre The final element of the sequence must not extend past the end of the
@ -482,11 +484,8 @@ class MachineIRBuilder {
/// \pre The bits defined by each Op (derived from index and scalar size) must
/// not overlap.
/// \pre \p Indices must be in ascending order of bit position.
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildSequence(unsigned Res,
ArrayRef<unsigned> Ops,
ArrayRef<uint64_t> Indices);
void buildSequence(unsigned Res, ArrayRef<unsigned> Ops,
ArrayRef<uint64_t> Indices);
/// Build and insert \p Res<def> = G_MERGE_VALUES \p Op0, ...
///
@ -513,24 +512,6 @@ class MachineIRBuilder {
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildUnmerge(ArrayRef<unsigned> Res, unsigned Op);
void addUsesWithIndices(MachineInstrBuilder MIB) {}
template <typename... ArgTys>
void addUsesWithIndices(MachineInstrBuilder MIB, unsigned Reg,
unsigned BitIndex, ArgTys... Args) {
MIB.addUse(Reg).addImm(BitIndex);
addUsesWithIndices(MIB, Args...);
}
template <typename... ArgTys>
MachineInstrBuilder buildSequence(unsigned Res, unsigned Op,
unsigned Index, ArgTys... Args) {
MachineInstrBuilder MIB =
buildInstr(TargetOpcode::G_SEQUENCE).addDef(Res);
addUsesWithIndices(MIB, Op, Index, Args...);
return MIB;
}
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src,
unsigned Op, unsigned Index);

View File

@ -29,13 +29,26 @@ class RegisterBankInfo;
class TargetInstrInfo;
class TargetPassConfig;
class TargetRegisterInfo;
class TargetRegisterClass;
class Twine;
class ConstantFP;
/// Try to constrain Reg to the specified register class. If this fails,
/// create a new virtual register in the correct class and insert a COPY before
/// \p InsertPt. The debug location of \p InsertPt is used for the new copy.
///
/// \return The virtual register constrained to the right register class.
unsigned constrainRegToClass(MachineRegisterInfo &MRI,
const TargetInstrInfo &TII,
const RegisterBankInfo &RBI,
MachineInstr &InsertPt, unsigned Reg,
const TargetRegisterClass &RegClass);
/// Try to constrain Reg so that it is usable by argument OpIdx of the
/// provided MCInstrDesc \p II. If this fails, create a new virtual
/// register in the correct class and insert a COPY before \p InsertPt.
/// The debug location of \p InsertPt is used for the new copy.
/// This is equivalent to constrainRegToClass() with RegClass obtained from the
/// MCInstrDesc. The debug location of \p InsertPt is used for the new copy.
///
/// \return The virtual register constrained to the right register class.
unsigned constrainOperandRegClass(const MachineFunction &MF,

View File

@ -196,7 +196,7 @@ class LexicalScopes {
}
/// dump - Print data structures to dbgs().
void dump();
void dump() const;
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope *getOrCreateAbstractScope(const DILocalScope *Scope);

View File

@ -376,6 +376,9 @@ class MachineBasicBlock
/// Indicates if this is the entry block of a cleanup funclet.
void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
/// Returns true if it is legal to hoist instructions into this block.
bool isLegalToHoistInto() const;
// Code Layout methods.
/// Move 'this' block before or after the specified block. This only moves

View File

@ -59,6 +59,11 @@ struct MachinePointerInfo {
return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset+O);
}
/// Return true if memory region [V, V+Offset+Size) is known to be
/// dereferenceable.
bool isDereferenceable(unsigned Size, LLVMContext &C,
const DataLayout &DL) const;
/// Return the LLVM IR address space number that this pointer points into.
unsigned getAddrSpace() const;

View File

@ -77,33 +77,6 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); }
};
/// MachineModuleInfoWasm - This is a MachineModuleInfoImpl implementation
/// for Wasm targets.
class MachineModuleInfoWasm : public MachineModuleInfoImpl {
/// WebAssembly global variables defined by CodeGen.
std::vector<wasm::Global> Globals;
/// The WebAssembly global variable which is the stack pointer.
unsigned StackPointerGlobal;
virtual void anchor(); // Out of line virtual method.
public:
MachineModuleInfoWasm(const MachineModuleInfo &)
: StackPointerGlobal(-1U) {}
void addGlobal(const wasm::Global &G) { Globals.push_back(G); }
const std::vector<wasm::Global> &getGlobals() const { return Globals; }
bool hasStackPointerGlobal() const {
return StackPointerGlobal != -1U;
}
unsigned getStackPointerGlobal() const {
assert(hasStackPointerGlobal() && "Stack ptr global hasn't been set");
return StackPointerGlobal;
}
void setStackPointerGlobal(unsigned Global) { StackPointerGlobal = Global; }
};
} // end namespace llvm
#endif

View File

@ -203,7 +203,7 @@ class MachineSchedStrategy {
MachineBasicBlock::iterator End,
unsigned NumRegionInstrs) {}
virtual void dumpPolicy() {}
virtual void dumpPolicy() const {}
/// Check if pressure tracking is needed before building the DAG and
/// initializing this strategy. Called after initPolicy.
@ -555,7 +555,7 @@ class ReadyQueue {
return Queue.begin() + idx;
}
void dump();
void dump() const;
};
/// Summarize the unscheduled region.
@ -756,7 +756,7 @@ class SchedBoundary {
SUnit *pickOnlyChoice();
#ifndef NDEBUG
void dumpScheduledState();
void dumpScheduledState() const;
#endif
};
@ -890,7 +890,7 @@ class GenericScheduler : public GenericSchedulerBase {
MachineBasicBlock::iterator End,
unsigned NumRegionInstrs) override;
void dumpPolicy() override;
void dumpPolicy() const override;
bool shouldTrackPressure() const override {
return RegionPolicy.ShouldTrackPressure;

View File

@ -0,0 +1,41 @@
//===- MacroFusion.h - Macro Fusion ------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file This file contains the definition of the DAG scheduling mutation to
/// pair instructions back to back.
//
//===----------------------------------------------------------------------===//
#include <functional>
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/CodeGen/MachineScheduler.h"
namespace llvm {
/// \brief Check if the instr pair, FirstMI and SecondMI, should be fused
/// together. Given SecondMI, when FirstMI is unspecified, then check if
/// SecondMI may be part of a fused pair at all.
typedef std::function<bool(const TargetInstrInfo &TII,
const TargetSubtargetInfo &TSI,
const MachineInstr *FirstMI,
const MachineInstr &SecondMI)> ShouldSchedulePredTy;
/// \brief Create a DAG scheduling mutation to pair instructions back to back
/// for instructions that benefit according to the target-specific
/// shouldScheduleAdjacent predicate function.
std::unique_ptr<ScheduleDAGMutation>
createMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent);
/// \brief Create a DAG scheduling mutation to pair branch instructions with one
/// of their predecessors back to back for instructions that benefit according
/// to the target-specific shouldScheduleAdjacent predicate function.
std::unique_ptr<ScheduleDAGMutation>
createBranchMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent);
} // end namespace llvm

View File

@ -156,12 +156,24 @@ class RegScavenger {
/// available and do the appropriate bookkeeping. SPAdj is the stack
/// adjustment due to call frame, it's passed along to eliminateFrameIndex().
/// Returns the scavenged register.
/// This is deprecated as it depends on the quality of the kill flags being
/// present; Use scavengeRegisterBackwards() instead!
unsigned scavengeRegister(const TargetRegisterClass *RegClass,
MachineBasicBlock::iterator I, int SPAdj);
unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
return scavengeRegister(RegClass, MBBI, SPAdj);
}
/// Make a register of the specific register class available from the current
/// position backwards to the place before \p To. If \p RestoreAfter is true
/// this includes the instruction following the current position.
/// SPAdj is the stack adjustment due to call frame, it's passed along to
/// eliminateFrameIndex().
/// Returns the scavenged register.
unsigned scavengeRegisterBackwards(const TargetRegisterClass &RC,
MachineBasicBlock::iterator To,
bool RestoreAfter, int SPAdj);
/// Tell the scavenger a register is used.
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = LaneBitmask::getAll());
@ -202,6 +214,12 @@ class RegScavenger {
/// Mark live-in registers of basic block as used.
void setLiveInsUsed(const MachineBasicBlock &MBB);
/// Spill a register after position \p After and reload it before position
/// \p UseMI.
ScavengedInfo &spill(unsigned Reg, const TargetRegisterClass &RC, int SPAdj,
MachineBasicBlock::iterator After,
MachineBasicBlock::iterator &UseMI);
};
/// Replaces all frame index virtual registers with physical registers. Uses the

View File

@ -0,0 +1,64 @@
//===-- llvm/CodeGen/SelectionDAGAddressAnalysis.h ------- DAG Address Analysis
//---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_CODEGEN_SELECTIONDAGADDRESSANALYSIS_H
#define LLVM_CODEGEN_SELECTIONDAGADDRESSANALYSIS_H
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
namespace llvm {
/// Helper struct to parse and store a memory address as base + index + offset.
/// We ignore sign extensions when it is safe to do so.
/// The following two expressions are not equivalent. To differentiate we need
/// to store whether there was a sign extension involved in the index
/// computation.
/// (load (i64 add (i64 copyfromreg %c)
/// (i64 signextend (add (i8 load %index)
/// (i8 1))))
/// vs
///
/// (load (i64 add (i64 copyfromreg %c)
/// (i64 signextend (i32 add (i32 signextend (i8 load %index))
/// (i32 1)))))
class BaseIndexOffset {
private:
SDValue Base;
SDValue Index;
int64_t Offset;
bool IsIndexSignExt;
public:
BaseIndexOffset() : Offset(0), IsIndexSignExt(false) {}
BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset,
bool IsIndexSignExt)
: Base(Base), Index(Index), Offset(Offset),
IsIndexSignExt(IsIndexSignExt) {}
SDValue getBase() { return Base; }
SDValue getIndex() { return Index; }
bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG) {
int64_t Off;
return equalBaseIndex(Other, DAG, Off);
}
bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG,
int64_t &Off);
/// Parses tree in Ptr for base, index, offset addresses.
static BaseIndexOffset match(SDValue Ptr);
};
} // namespace llvm
#endif

View File

@ -2107,7 +2107,7 @@ class MaskedGatherScatterSDNode : public MemSDNode {
public:
friend class SelectionDAG;
MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
MaskedGatherScatterSDNode(unsigned NodeTy, unsigned Order,
const DebugLoc &dl, SDVTList VTs, EVT MemVT,
MachineMemOperand *MMO)
: MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {}

View File

@ -356,6 +356,9 @@
/* Define if this is Win32ish platform */
#cmakedefine LLVM_ON_WIN32 ${LLVM_ON_WIN32}
/* Define if overriding target triple is enabled */
#cmakedefine LLVM_TARGET_TRIPLE_ENV "${LLVM_TARGET_TRIPLE_ENV}"
/* Define if we have the Intel JIT API runtime support library */
#cmakedefine01 LLVM_USE_INTEL_JITEVENTS

View File

@ -27,9 +27,12 @@ namespace codeview {
template <typename Kind> class CVRecord {
public:
CVRecord() = default;
CVRecord() : Type(static_cast<Kind>(0)) {}
CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
bool valid() const { return Type != static_cast<Kind>(0); }
uint32_t length() const { return RecordData.size(); }
Kind kind() const { return Type; }
ArrayRef<uint8_t> data() const { return RecordData; }

View File

@ -402,6 +402,16 @@ enum class LocalSymFlags : uint16_t {
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(LocalSymFlags)
/// Corresponds to the CV_PUBSYMFLAGS bitfield.
enum class PublicSymFlags : uint32_t {
None = 0,
Code = 1 << 0,
Function = 1 << 1,
Managed = 1 << 2,
MSIL = 1 << 3,
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PublicSymFlags)
/// Corresponds to the CV_PROCFLAGS bitfield.
enum class ProcSymFlags : uint8_t {
None = 0,

View File

@ -51,11 +51,23 @@ class DebugSubsectionRecordBuilder {
public:
DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
CodeViewContainer Container);
/// Use this to copy existing subsections directly from source to destination.
/// For example, line table subsections in an object file only need to be
/// relocated before being copied into the PDB.
DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents,
CodeViewContainer Container);
uint32_t calculateSerializedLength();
Error commit(BinaryStreamWriter &Writer) const;
private:
/// The subsection to build. Will be null if Contents is non-empty.
std::shared_ptr<DebugSubsection> Subsection;
/// The bytes of the subsection. Only non-empty if Subsection is null.
DebugSubsectionRecord Contents;
CodeViewContainer Container;
};

View File

@ -22,6 +22,7 @@ namespace codeview {
ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();
ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames();
ArrayRef<EnumEntry<uint16_t>> getRegisterNames();
ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames();
ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();
ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();
ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames();

View File

@ -11,18 +11,15 @@
#define LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/StringSaver.h"
namespace llvm {
namespace codeview {
class TypeDatabase;
class TypeVisitorCallbacks;
/// \brief Provides amortized O(1) random access to a CodeView type stream.
/// Normally to access a type from a type stream, you must know its byte
/// offset into the type stream, because type records are variable-lengthed.
@ -47,6 +44,11 @@ class TypeVisitorCallbacks;
/// of O(N/M) and an amortized time of O(1).
class LazyRandomTypeCollection : public TypeCollection {
typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray;
struct CacheEntry {
CVType Type;
uint32_t Offset;
StringRef Name;
};
public:
explicit LazyRandomTypeCollection(uint32_t RecordCountHint);
@ -56,8 +58,10 @@ class LazyRandomTypeCollection : public TypeCollection {
PartialOffsetArray PartialOffsets);
LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint);
void reset(ArrayRef<uint8_t> Data);
void reset(StringRef Data);
void reset(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
void reset(StringRef Data, uint32_t RecordCountHint);
uint32_t getOffsetOfType(TypeIndex Index);
CVType getType(TypeIndex Index) override;
StringRef getTypeName(TypeIndex Index) override;
@ -68,27 +72,26 @@ class LazyRandomTypeCollection : public TypeCollection {
Optional<TypeIndex> getNext(TypeIndex Prev) override;
private:
const TypeDatabase &database() const { return Database; }
Error ensureTypeExists(TypeIndex Index);
void ensureCapacityFor(TypeIndex Index);
Error visitRangeForType(TypeIndex TI);
Error fullScanForType(TypeIndex TI);
Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
Error visitOneRecord(TypeIndex TI, uint32_t Offset, CVType &Record);
void visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
/// Visited records get automatically added to the type database.
TypeDatabase Database;
/// Number of actual records.
uint32_t Count = 0;
/// The largest type index which we've visited.
TypeIndex LargestTypeIndex = TypeIndex::None();
BumpPtrAllocator Allocator;
StringSaver NameStorage;
/// The type array to allow random access visitation of.
CVTypeArray Types;
/// The database visitor which adds new records to the database.
TypeDatabaseVisitor DatabaseVisitor;
/// A vector mapping type indices to type offset. For every record that has
/// been visited, contains the absolute offset of that record in the record
/// array.
std::vector<uint32_t> KnownOffsets;
std::vector<CacheEntry> Records;
/// An array of index offsets for the given type stream, allowing log(N)
/// lookups of a type record by index. Similar to KnownOffsets but only

View File

@ -363,7 +363,7 @@ class PublicSym32 : public SymbolRecord {
: SymbolRecord(SymbolRecordKind::PublicSym32),
RecordOffset(RecordOffset) {}
TypeIndex Index;
PublicSymFlags Flags;
uint32_t Offset;
uint16_t Segment;
StringRef Name;

View File

@ -1,84 +0,0 @@
//===- TypeDatabase.h - A collection of CodeView type records ---*- 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_TYPEDATABASE_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/StringSaver.h"
namespace llvm {
namespace codeview {
class TypeDatabase : public TypeCollection {
friend class RandomAccessTypeVisitor;
public:
explicit TypeDatabase(uint32_t Capacity);
/// Records the name of a type, and reserves its type index.
TypeIndex appendType(StringRef Name, const CVType &Data);
/// Records the name of a type, and reserves its type index.
void recordType(StringRef Name, TypeIndex Index, const CVType &Data);
/// Saves the name in a StringSet and creates a stable StringRef.
StringRef saveTypeName(StringRef TypeName);
StringRef getTypeName(TypeIndex Index) const;
const CVType &getTypeRecord(TypeIndex Index) const;
CVType &getTypeRecord(TypeIndex Index);
bool contains(TypeIndex Index) const;
uint32_t size() const;
uint32_t capacity() const;
bool empty() const;
CVType getType(TypeIndex Index) override;
StringRef getTypeName(TypeIndex Index) override;
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
Optional<TypeIndex> largestTypeIndexLessThan(TypeIndex TI) const;
private:
TypeIndex getAppendIndex() const;
void grow();
void grow(TypeIndex Index);
BumpPtrAllocator Allocator;
uint32_t Count = 0;
TypeIndex LargestTypeIndex;
/// All user defined type records in .debug$T live in here. Type indices
/// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
/// index into this vector.
SmallVector<StringRef, 10> CVUDTNames;
SmallVector<CVType, 10> TypeRecords;
StringSaver TypeNameStorage;
BitVector ValidRecords;
};
}
}
#endif

View File

@ -1,62 +0,0 @@
//===-- TypeDatabaseVisitor.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_TYPEDATABASEVISITOR_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H
#include "llvm/ADT/PointerUnion.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
namespace llvm {
namespace codeview {
/// Dumper for CodeView type streams found in COFF object files and PDB files.
class TypeDatabaseVisitor : public TypeVisitorCallbacks {
public:
explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(&TypeDB) {}
/// Paired begin/end actions for all types. Receives all record data,
/// including the fixed-length record prefix.
Error visitTypeBegin(CVType &Record) override;
Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;
Error visitMemberEnd(CVMemberRecord &Record) override;
#define TYPE_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
#define MEMBER_RECORD(EnumName, EnumVal, Name) \
Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
private:
StringRef getTypeName(TypeIndex Index) const;
StringRef saveTypeName(StringRef Name);
bool IsInFieldList = false;
/// Name of the current type. Only valid before visitTypeEnd.
StringRef Name;
/// Current type index. Only valid before visitTypeEnd, and if we are
/// visiting a random access type database.
Optional<TypeIndex> CurrentTypeIndex;
TypeDatabase *TypeDB;
};
} // end namespace codeview
} // end namespace llvm
#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H

View File

@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEXDISCOVERY_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/Support/Error.h"
@ -27,6 +28,11 @@ void discoverTypeIndices(ArrayRef<uint8_t> RecordData,
SmallVectorImpl<TiReference> &Refs);
void discoverTypeIndices(const CVType &Type,
SmallVectorImpl<TiReference> &Refs);
/// Discover type indices in symbol records. Returns false if this is an unknown
/// record.
bool discoverTypeIndices(const CVSymbol &Symbol,
SmallVectorImpl<TiReference> &Refs);
}
}

View File

@ -0,0 +1,22 @@
//===- TypeName.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_TYPENAME_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
namespace llvm {
namespace codeview {
std::string computeTypeName(TypeCollection &Types, TypeIndex Index);
}
} // namespace llvm
#endif

View File

@ -25,6 +25,7 @@ class TypeRecordMapping : public TypeVisitorCallbacks {
explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {}
explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {}
using TypeVisitorCallbacks::visitTypeBegin;
Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;

View File

@ -93,6 +93,7 @@ class TypeSerializer : public TypeVisitorCallbacks {
TypeIndex insertRecord(const RemappedType &Record);
Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record);
using TypeVisitorCallbacks::visitTypeBegin;
Error visitTypeBegin(CVType &Record) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;

View File

@ -11,7 +11,9 @@
#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/Support/StringSaver.h"
#include <vector>
namespace llvm {
namespace codeview {
@ -30,11 +32,10 @@ class TypeTableCollection : public TypeCollection {
uint32_t capacity() override;
private:
bool hasCapacityFor(TypeIndex Index) const;
void ensureTypeExists(TypeIndex Index);
BumpPtrAllocator Allocator;
StringSaver NameStorage;
std::vector<StringRef> Names;
ArrayRef<ArrayRef<uint8_t>> Records;
TypeDatabase Database;
};
}
}

View File

@ -57,7 +57,7 @@ struct DILineInfo {
}
};
typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable;
using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
/// DIInliningInfo - a format-neutral container for inlined code description.
class DIInliningInfo {
@ -102,7 +102,7 @@ enum class DINameKind { None, ShortName, LinkageName };
/// should be filled with data.
struct DILineInfoSpecifier {
enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
typedef DINameKind FunctionNameKind;
using FunctionNameKind = DINameKind;
FileLineInfoKind FLIKind;
FunctionNameKind FNKind;
@ -174,6 +174,7 @@ class DIContext {
// 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

@ -33,6 +33,7 @@ class DWARFAbbreviationDeclaration {
dwarf::Attribute Attr;
dwarf::Form Form;
/// The following field is used for ByteSize for non-implicit_const
/// attributes and as value for implicit_const ones, indicated by
/// Form == DW_FORM_implicit_const.
@ -58,7 +59,7 @@ class DWARFAbbreviationDeclaration {
/// the ByteSize member.
Optional<int64_t> getByteSize(const DWARFUnit &U) const;
};
typedef SmallVector<AttributeSpec, 8> AttributeSpecVector;
using AttributeSpecVector = SmallVector<AttributeSpec, 8>;
DWARFAbbreviationDeclaration();
@ -67,8 +68,8 @@ class DWARFAbbreviationDeclaration {
dwarf::Tag getTag() const { return Tag; }
bool hasChildren() const { return HasChildren; }
typedef iterator_range<AttributeSpecVector::const_iterator>
attr_iterator_range;
using attr_iterator_range =
iterator_range<AttributeSpecVector::const_iterator>;
attr_iterator_range attributes() const {
return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end());

View File

@ -32,8 +32,9 @@ class DWARFAcceleratorTable {
};
struct HeaderData {
typedef uint16_t AtomType;
typedef dwarf::Form Form;
using AtomType = uint16_t;
using Form = dwarf::Form;
uint32_t DIEOffsetBase;
SmallVector<std::pair<AtomType, Form>, 3> Atoms;
};

View File

@ -10,7 +10,6 @@
#ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
#define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@ -25,21 +24,24 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Host.h"
#include <cstdint>
#include <deque>
#include <map>
#include <memory>
#include <utility>
namespace llvm {
class DataExtractor;
class MemoryBuffer;
class raw_ostream;
@ -73,7 +75,7 @@ class DWARFContext : public DIContext {
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
/// The maximum DWARF version of all units.
unsigned MaxVersion;
unsigned MaxVersion = 0;
struct DWOFile {
object::OwningBinary<object::ObjectFile> File;
@ -100,7 +102,7 @@ class DWARFContext : public DIContext {
void parseDWOTypeUnits();
public:
DWARFContext() : DIContext(CK_DWARF), MaxVersion(0) {}
DWARFContext() : DIContext(CK_DWARF) {}
DWARFContext(DWARFContext &) = delete;
DWARFContext &operator=(DWARFContext &) = delete;
@ -112,9 +114,9 @@ class DWARFContext : public DIContext {
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;
using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;
using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>;
/// Get compile units in this context.
cu_iterator_range compile_units() {
@ -230,8 +232,10 @@ class DWARFContext : public DIContext {
virtual bool isLittleEndian() const = 0;
virtual uint8_t getAddressSize() const = 0;
virtual const DWARFSection &getInfoSection() = 0;
typedef MapVector<object::SectionRef, DWARFSection,
std::map<object::SectionRef, unsigned>> TypeSectionMap;
using TypeSectionMap = MapVector<object::SectionRef, DWARFSection,
std::map<object::SectionRef, unsigned>>;
virtual const TypeSectionMap &getTypesSections() = 0;
virtual StringRef getAbbrevSection() = 0;
virtual const DWARFSection &getLocSection() = 0;

View File

@ -18,6 +18,8 @@
namespace llvm {
class raw_ostream;
class DWARFAbbreviationDeclarationSet {
uint32_t Offset;
/// Code of the first abbreviation, if all abbreviations in the set have
@ -25,8 +27,8 @@ class DWARFAbbreviationDeclarationSet {
uint32_t FirstAbbrCode;
std::vector<DWARFAbbreviationDeclaration> Decls;
typedef std::vector<DWARFAbbreviationDeclaration>::const_iterator
const_iterator;
using const_iterator =
std::vector<DWARFAbbreviationDeclaration>::const_iterator;
public:
DWARFAbbreviationDeclarationSet();
@ -51,8 +53,8 @@ class DWARFAbbreviationDeclarationSet {
};
class DWARFDebugAbbrev {
typedef std::map<uint64_t, DWARFAbbreviationDeclarationSet>
DWARFAbbreviationDeclarationSetMap;
using DWARFAbbreviationDeclarationSetMap =
std::map<uint64_t, DWARFAbbreviationDeclarationSet>;
DWARFAbbreviationDeclarationSetMap AbbrDeclSets;
mutable DWARFAbbreviationDeclarationSetMap::const_iterator PrevAbbrOffsetPos;

View File

@ -46,8 +46,8 @@ class DWARFDebugArangeSet {
};
private:
typedef std::vector<Descriptor> DescriptorColl;
typedef iterator_range<DescriptorColl::const_iterator> desc_iterator_range;
using DescriptorColl = std::vector<Descriptor>;
using desc_iterator_range = iterator_range<DescriptorColl::const_iterator>;
uint32_t Offset;
Header HeaderData;

View File

@ -76,8 +76,8 @@ class DWARFDebugAranges {
}
};
typedef std::vector<Range> RangeColl;
typedef RangeColl::const_iterator RangeCollIterator;
using RangeColl = std::vector<Range>;
using RangeCollIterator = RangeColl::const_iterator;
std::vector<RangeEndpoint> Endpoints;
RangeColl Aranges;

View File

@ -10,7 +10,9 @@
#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H
#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/DataExtractor.h"
#include <cstdint>
@ -42,10 +44,10 @@ class DWARFDebugLine {
/// 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.
uint16_t Version;
/// In v5, size in bytes of an address (or segment offset).
uint8_t AddressSize;
/// Version, address size (starting in v5), and DWARF32/64 format; these
/// parameters affect interpretation of forms (used in the directory and
/// file tables starting with v5).
DWARFFormParams FormParams;
/// In v5, size in bytes of a segment selector.
uint8_t SegSelectorSize;
/// The number of bytes following the prologue_length field to the beginning
@ -70,15 +72,18 @@ class DWARFDebugLine {
std::vector<StringRef> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
bool IsDWARF64;
const DWARFFormParams getFormParams() const { return FormParams; }
uint16_t getVersion() const { return FormParams.Version; }
uint8_t getAddressSize() const { return FormParams.AddrSize; }
bool isDWARF64() const { return FormParams.Format == dwarf::DWARF64; }
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.
uint32_t getLength() const {
return PrologueLength + sizeofTotalLength() + sizeof(Version) +
return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) +
sizeofPrologueLength();
}
@ -104,7 +109,9 @@ class DWARFDebugLine {
void postAppend();
void reset(bool DefaultIsStmt);
void dump(raw_ostream &OS) const;
static void dumpTableHeader(raw_ostream &OS);
static bool orderByAddress(const Row &LHS, const Row &RHS) {
return LHS.Address < RHS.Address;
}
@ -216,11 +223,12 @@ class DWARFDebugLine {
bool parse(DataExtractor DebugLineData, const RelocAddrMap *RMap,
uint32_t *OffsetPtr);
using RowVector = std::vector<Row>;
using RowIter = RowVector::const_iterator;
using SequenceVector = std::vector<Sequence>;
using SequenceIter = SequenceVector::const_iterator;
struct Prologue Prologue;
typedef std::vector<Row> RowVector;
typedef RowVector::const_iterator RowIter;
typedef std::vector<Sequence> SequenceVector;
typedef SequenceVector::const_iterator SequenceIter;
RowVector Rows;
SequenceVector Sequences;
@ -244,14 +252,14 @@ class DWARFDebugLine {
struct LineTable *LineTable;
/// The row number that starts at zero for the prologue, and increases for
/// each row added to the matrix.
unsigned RowNumber;
unsigned RowNumber = 0;
struct Row Row;
struct Sequence Sequence;
};
typedef std::map<uint32_t, LineTable> LineTableMapTy;
typedef LineTableMapTy::iterator LineTableIter;
typedef LineTableMapTy::const_iterator LineTableConstIter;
using LineTableMapTy = std::map<uint32_t, LineTable>;
using LineTableIter = LineTableMapTy::iterator;
using LineTableConstIter = LineTableMapTy::const_iterator;
const RelocAddrMap *RelocMap;
LineTableMapTy LineTableMap;

View File

@ -39,7 +39,7 @@ class DWARFDebugLoc {
SmallVector<Entry, 2> Entries;
};
typedef SmallVector<LocationList, 4> LocationLists;
using LocationLists = SmallVector<LocationList, 4>;
/// A list of all the variables in the debug_loc section, each one describing
/// the locations in which the variable is stored.
@ -71,7 +71,7 @@ class DWARFDebugLocDWO {
SmallVector<Entry, 2> Entries;
};
typedef SmallVector<LocationList, 4> LocationLists;
using LocationLists = SmallVector<LocationList, 4>;
LocationLists Locations;

View File

@ -40,7 +40,7 @@ class DWARFDebugMacro {
};
};
typedef SmallVector<Entry, 4> MacroList;
using MacroList = SmallVector<Entry, 4>;
/// A list of all the macro entries in the debug_macinfo section.
MacroList Macros;

View File

@ -12,10 +12,8 @@
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/DataExtractor.h"
#include <cassert>
#include <cstdint>
#include <utility>
#include <vector>
namespace llvm {
@ -29,7 +27,7 @@ struct DWARFAddressRange {
};
/// DWARFAddressRangesVector - represents a set of absolute address ranges.
typedef std::vector<DWARFAddressRange> DWARFAddressRangesVector;
using DWARFAddressRangesVector = std::vector<DWARFAddressRange>;
class DWARFDebugRangeList {
public:

View File

@ -22,6 +22,35 @@ namespace llvm {
class DWARFUnit;
class raw_ostream;
/// A helper struct for DWARFFormValue methods, providing information that
/// allows it to know the byte size of DW_FORM values that vary in size
/// depending on the DWARF version, address byte size, or DWARF32/DWARF64.
struct DWARFFormParams {
uint16_t Version;
uint8_t AddrSize;
dwarf::DwarfFormat Format;
/// The definition of the size of form DW_FORM_ref_addr depends on the
/// version. In DWARF v2 it's the size of an address; after that, it's the
/// size of a reference.
uint8_t getRefAddrByteSize() const {
if (Version == 2)
return AddrSize;
return getDwarfOffsetByteSize();
}
/// The size of a reference is determined by the DWARF 32/64-bit format.
uint8_t getDwarfOffsetByteSize() const {
switch (Format) {
case dwarf::DwarfFormat::DWARF32:
return 4;
case dwarf::DwarfFormat::DWARF64:
return 8;
}
llvm_unreachable("Invalid Format value");
}
};
class DWARFFormValue {
public:
enum FormClass {
@ -104,79 +133,43 @@ class DWARFFormValue {
/// Get the fixed byte size for a given form.
///
/// If the form always has a fixed valid byte size that doesn't depend on a
/// DWARFUnit, then an Optional with a value will be returned. If the form
/// can vary in size depending on the DWARFUnit (DWARF version, address byte
/// size, or DWARF 32/64) and the DWARFUnit is valid, then an Optional with a
/// valid value is returned. If the form is always encoded using a variable
/// length storage format (ULEB or SLEB numbers or blocks) or the size
/// depends on a DWARFUnit and the DWARFUnit is NULL, then None will be
/// returned.
/// \param Form The DWARF form to get the fixed byte size for
/// \param U The DWARFUnit that can be used to help determine the byte size.
/// If the form has a fixed byte size, then an Optional with a value will be
/// returned. If the form is always encoded using a variable length storage
/// format (ULEB or SLEB numbers or blocks) then None will be returned.
///
/// \returns Optional<uint8_t> value with the fixed byte size or None if
/// \p Form doesn't have a fixed byte size or a DWARFUnit wasn't supplied
/// and was needed to calculate the byte size.
static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
const DWARFUnit *U = nullptr);
/// Get the fixed byte size for a given form.
///
/// If the form has a fixed byte size given a valid DWARF version and address
/// byte size, then an Optional with a valid value is returned. If the form
/// is always encoded using a variable length storage format (ULEB or SLEB
/// numbers or blocks) then None will be returned.
///
/// \param Form DWARF form to get the fixed byte size for
/// \param Version DWARF version number.
/// \param AddrSize size of an address in bytes.
/// \param Format enum value from llvm::dwarf::DwarfFormat.
/// \param Form DWARF form to get the fixed byte size for.
/// \param FormParams DWARF parameters to help interpret forms.
/// \returns Optional<uint8_t> value with the fixed byte size or None if
/// \p Form doesn't have a fixed byte size.
static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, uint16_t Version,
uint8_t AddrSize,
llvm::dwarf::DwarfFormat Format);
static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
const DWARFFormParams FormParams);
/// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
/// Skip a form's value in \p DebugInfoData at the offset specified by
/// \p OffsetPtr.
///
/// Skips the bytes for this form in the debug info and updates the offset.
/// Skips the bytes for the current form and updates the offset.
///
/// \param DebugInfoData the .debug_info data to use to skip the value.
/// \param OffsetPtr a reference to the offset that will be updated.
/// \param U the DWARFUnit to use when skipping the form in case the form
/// size differs according to data in the DWARFUnit.
/// \param DebugInfoData The data where we want to skip the value.
/// \param OffsetPtr A reference to the offset that will be updated.
/// \param Params DWARF parameters to help interpret forms.
/// \returns true on success, false if the form was not skipped.
bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
const DWARFUnit *U) const;
const DWARFFormParams Params) const {
return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params);
}
/// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
/// Skip a form's value in \p DebugInfoData at the offset specified by
/// \p OffsetPtr.
///
/// Skips the bytes for this form in the debug info and updates the offset.
/// Skips the bytes for the specified form and updates the offset.
///
/// \param Form the DW_FORM enumeration that indicates the form to skip.
/// \param DebugInfoData the .debug_info data to use to skip the value.
/// \param OffsetPtr a reference to the offset that will be updated.
/// \param U the DWARFUnit to use when skipping the form in case the form
/// size differs according to data in the DWARFUnit.
/// \param Form The DW_FORM enumeration that indicates the form to skip.
/// \param DebugInfoData The data where we want to skip the value.
/// \param OffsetPtr A reference to the offset that will be updated.
/// \param FormParams DWARF parameters to help interpret forms.
/// \returns true on success, false if the form was not skipped.
static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
uint32_t *OffsetPtr, const DWARFUnit *U);
/// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
///
/// Skips the bytes for this form in the debug info and updates the offset.
///
/// \param Form the DW_FORM enumeration that indicates the form to skip.
/// \param DebugInfoData the .debug_info data to use to skip the value.
/// \param OffsetPtr a reference to the offset that will be updated.
/// \param Version DWARF version number.
/// \param AddrSize size of an address in bytes.
/// \param Format enum value from llvm::dwarf::DwarfFormat.
/// \returns true on success, false if the form was not skipped.
static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
uint32_t *OffsetPtr, uint16_t Version, uint8_t AddrSize,
llvm::dwarf::DwarfFormat Format);
uint32_t *OffsetPtr, const DWARFFormParams FormParams);
private:
void dumpString(raw_ostream &OS) const;

View File

@ -12,7 +12,6 @@
#include "llvm/ADT/DenseMap.h"
#include <cstdint>
#include <utility>
namespace llvm {
@ -28,7 +27,7 @@ struct RelocAddrEntry {
/// dwarf where we expect relocated values. This adds a bit of complexity to the
/// dwarf parsing/extraction at the benefit of not allocating memory for the
/// entire size of the debug info sections.
typedef DenseMap<uint64_t, RelocAddrEntry> RelocAddrMap;
using RelocAddrMap = DenseMap<uint64_t, RelocAddrEntry>;
} // end namespace llvm

View File

@ -19,11 +19,10 @@
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DataExtractor.h"
#include <algorithm>
#include <cassert>
@ -31,6 +30,7 @@
#include <cstdint>
#include <map>
#include <memory>
#include <utility>
#include <vector>
namespace llvm {
@ -72,9 +72,9 @@ class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
bool Parsed = false;
public:
typedef SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector;
typedef typename UnitVector::iterator iterator;
typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range;
using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>;
using iterator = typename UnitVector::iterator;
using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
UnitType *getUnitForOffset(uint32_t Offset) const override {
auto *CU = std::upper_bound(
@ -128,12 +128,13 @@ class DWARFUnit {
bool isDWO;
const DWARFUnitSectionBase &UnitSection;
// Version, address size, and DWARF format.
DWARFFormParams FormParams;
uint32_t Offset;
uint32_t Length;
const DWARFAbbreviationDeclarationSet *Abbrevs;
uint16_t Version;
uint8_t UnitType;
uint8_t AddrSize;
uint64_t BaseAddr;
/// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
@ -142,8 +143,9 @@ class DWARFUnit {
/// IntervalMap does not support range removal, as a result, we use the
/// std::map::upper_bound for address range lookup.
std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>
die_iterator_range;
using die_iterator_range =
iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
std::shared_ptr<DWARFUnit> DWO;
@ -159,7 +161,7 @@ class DWARFUnit {
virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
/// Size in bytes of the unit header.
virtual uint32_t getHeaderSize() const { return Version <= 4 ? 11 : 12; }
virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
@ -197,7 +199,8 @@ class DWARFUnit {
uint64_t getStringOffsetSectionRelocation(uint32_t Index) const;
DataExtractor getDebugInfoExtractor() const {
return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
return DataExtractor(InfoSection.Data, isLittleEndian,
getAddressByteSize());
}
DataExtractor getStringExtractor() const {
@ -220,10 +223,14 @@ class DWARFUnit {
uint32_t getOffset() const { return Offset; }
uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
uint32_t getLength() const { return Length; }
uint16_t getVersion() const { return Version; }
dwarf::DwarfFormat getFormat() const {
return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64.
const DWARFFormParams &getFormParams() const { return FormParams; }
uint16_t getVersion() const { return FormParams.Version; }
dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
uint8_t getDwarfOffsetByteSize() const {
return FormParams.getDwarfOffsetByteSize();
}
const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
@ -231,19 +238,6 @@ class DWARFUnit {
}
uint8_t getUnitType() const { return UnitType; }
uint8_t getAddressByteSize() const { return AddrSize; }
uint8_t getRefAddrByteSize() const {
if (Version == 2)
return AddrSize;
return getDwarfOffsetByteSize();
}
uint8_t getDwarfOffsetByteSize() const {
if (getFormat() == dwarf::DwarfFormat::DWARF64)
return 8;
return 4;
}
uint64_t getBaseAddress() const { return BaseAddr; }

View File

@ -12,18 +12,16 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <utility>
#include <vector>
namespace llvm {
namespace msf {
class MSFBuilder {
public:
/// \brief Create a new `MSFBuilder`.
@ -122,7 +120,7 @@ class MSFBuilder {
Error allocateBlocks(uint32_t NumBlocks, MutableArrayRef<uint32_t> Blocks);
uint32_t computeDirectoryByteSize() const;
typedef std::vector<uint32_t> BlockList;
using BlockList = std::vector<uint32_t>;
BumpPtrAllocator &Allocator;
@ -136,7 +134,8 @@ class MSFBuilder {
std::vector<uint32_t> DirectoryBlocks;
std::vector<std::pair<uint32_t, BlockList>> StreamData;
};
} // namespace msf
} // namespace llvm
} // end namespace msf
} // end namespace llvm
#endif // LLVM_DEBUGINFO_MSF_MSFBUILDER_H

View File

@ -12,15 +12,15 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
#include <cstdint>
#include <vector>
namespace llvm {
namespace msf {
static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
't', ' ', 'C', '/', 'C', '+', '+', ' ',
'M', 'S', 'F', ' ', '7', '.', '0', '0',
@ -50,8 +50,9 @@ struct SuperBlock {
};
struct MSFLayout {
MSFLayout() : SB(nullptr) {}
const SuperBlock *SB;
MSFLayout() = default;
const SuperBlock *SB = nullptr;
BitVector FreePageMap;
ArrayRef<support::ulittle32_t> DirectoryBlocks;
ArrayRef<support::ulittle32_t> StreamSizes;
@ -90,15 +91,16 @@ inline uint32_t getFpmIntervalLength(const MSFLayout &L) {
inline uint32_t getNumFpmIntervals(const MSFLayout &L) {
uint32_t Length = getFpmIntervalLength(L);
return llvm::alignTo(L.SB->NumBlocks, Length) / Length;
return alignTo(L.SB->NumBlocks, Length) / Length;
}
inline uint32_t getFullFpmByteSize(const MSFLayout &L) {
return llvm::alignTo(L.SB->NumBlocks, 8) / 8;
return alignTo(L.SB->NumBlocks, 8) / 8;
}
Error validateSuperBlock(const SuperBlock &SB);
} // namespace msf
} // namespace llvm
} // end namespace msf
} // end namespace llvm
#endif // LLVM_DEBUGINFO_MSF_MSFCOMMON_H

View File

@ -1,5 +1,4 @@
//===- MappedBlockStream.h - Discontiguous stream data in an MSF -*- C++
//-*-===//
//==- MappedBlockStream.h - Discontiguous stream data in an MSF --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@ -13,7 +12,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryStream.h"
@ -21,6 +19,7 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <memory>
#include <vector>
namespace llvm {
@ -40,6 +39,7 @@ struct MSFLayout;
/// of bytes.
class MappedBlockStream : public BinaryStream {
friend class WritableMappedBlockStream;
public:
static std::unique_ptr<MappedBlockStream>
createStream(uint32_t BlockSize, const MSFStreamLayout &Layout,
@ -57,8 +57,8 @@ class MappedBlockStream : public BinaryStream {
createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData,
BumpPtrAllocator &Allocator);
llvm::support::endianness getEndian() const override {
return llvm::support::little;
support::endianness getEndian() const override {
return support::little;
}
Error readBytes(uint32_t Offset, uint32_t Size,
@ -68,7 +68,7 @@ class MappedBlockStream : public BinaryStream {
uint32_t getLength() override;
llvm::BumpPtrAllocator &getAllocator() { return Allocator; }
BumpPtrAllocator &getAllocator() { return Allocator; }
void invalidateCache();
@ -92,7 +92,7 @@ class MappedBlockStream : public BinaryStream {
const MSFStreamLayout StreamLayout;
BinaryStreamRef MsfData;
typedef MutableArrayRef<uint8_t> CacheEntry;
using CacheEntry = MutableArrayRef<uint8_t>;
// We just store the allocator by reference. We use this to allocate
// contiguous memory for things like arrays or strings that cross a block
@ -124,8 +124,8 @@ class WritableMappedBlockStream : public WritableBinaryStream {
createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
BumpPtrAllocator &Allocator);
llvm::support::endianness getEndian() const override {
return llvm::support::little;
support::endianness getEndian() const override {
return support::little;
}
Error readBytes(uint32_t Offset, uint32_t Size,
@ -141,6 +141,7 @@ class WritableMappedBlockStream : public WritableBinaryStream {
const MSFStreamLayout &getStreamLayout() const {
return ReadInterface.getStreamLayout();
}
uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); }
uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); }
uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); }
@ -153,7 +154,6 @@ class WritableMappedBlockStream : public WritableBinaryStream {
private:
MappedBlockStream ReadInterface;
WritableBinaryStreamRef WriteInterface;
};

View File

@ -31,7 +31,7 @@ class DIASession : public IPDBSession {
uint64_t getLoadAddress() const override;
void setLoadAddress(uint64_t Address) override;
std::unique_ptr<PDBSymbolExe> getGlobalScope() const override;
std::unique_ptr<PDBSymbolExe> getGlobalScope() override;
std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
std::unique_ptr<PDBSymbol>

View File

@ -29,7 +29,7 @@ class IPDBSession {
virtual uint64_t getLoadAddress() const = 0;
virtual void setLoadAddress(uint64_t Address) = 0;
virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() const = 0;
virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() = 0;
virtual std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const = 0;
template <typename T>

View File

@ -14,6 +14,7 @@
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/Error.h"
@ -52,6 +53,9 @@ class DbiModuleDescriptorBuilder {
void
addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
void
addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents);
uint16_t getStreamIndex() const;
StringRef getModuleName() const { return ModuleName; }
StringRef getObjFileName() const { return ObjFileName; }

View File

@ -63,6 +63,13 @@ class DbiStream {
PDB_Machine getMachineType() const;
BinarySubstreamRef getSectionContributionData() const;
BinarySubstreamRef getSecMapSubstreamData() const;
BinarySubstreamRef getModiSubstreamData() const;
BinarySubstreamRef getFileInfoSubstreamData() const;
BinarySubstreamRef getTypeServerMapSubstreamData() const;
BinarySubstreamRef getECSubstreamData() const;
/// If the given stream type is present, returns its stream index. If it is
/// not present, returns InvalidStreamIndex.
uint32_t getDebugStreamIndex(DbgHeaderType Type) const;
@ -87,10 +94,12 @@ class DbiStream {
PDBStringTable ECNames;
BinaryStreamRef SecContrSubstream;
BinaryStreamRef SecMapSubstream;
BinaryStreamRef TypeServerMapSubstream;
BinaryStreamRef ECSubstream;
BinarySubstreamRef SecContrSubstream;
BinarySubstreamRef SecMapSubstream;
BinarySubstreamRef ModiSubstream;
BinarySubstreamRef FileInfoSubstream;
BinarySubstreamRef TypeServerMapSubstream;
BinarySubstreamRef ECSubstream;
DbiModuleList Modules;

View File

@ -58,6 +58,7 @@ class DbiStreamBuilder {
Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName);
Error addModuleSourceFile(StringRef Module, StringRef File);
Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File);
Expected<uint32_t> getSourceFileNameIndex(StringRef FileName);
Error finalizeMsfLayout();

View File

@ -47,6 +47,8 @@ class InfoStream {
const NamedStreamMap &getNamedStreams() const;
BinarySubstreamRef getNamedStreamsBuffer() const;
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
@ -71,6 +73,8 @@ class InfoStream {
// universally unique.
PDB_UniqueId Guid;
BinarySubstreamRef SubNamedStreams;
std::vector<PdbRaw_FeatureSig> FeatureSignatures;
PdbRaw_Features Features = PdbFeatureNone;

View File

@ -41,9 +41,12 @@ class ModuleDebugStreamRef {
iterator_range<codeview::CVSymbolArray::Iterator>
symbols(bool *HadError) const;
const codeview::CVSymbolArray &getSymbolArray() const {
return SymbolsSubstream;
}
const codeview::CVSymbolArray &getSymbolArray() const { return SymbolArray; }
BinarySubstreamRef getSymbolsSubstream() const;
BinarySubstreamRef getC11LinesSubstream() const;
BinarySubstreamRef getC13LinesSubstream() const;
BinarySubstreamRef getGlobalRefsSubstream() const;
ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = default;
@ -63,10 +66,12 @@ class ModuleDebugStreamRef {
std::shared_ptr<msf::MappedBlockStream> Stream;
codeview::CVSymbolArray SymbolsSubstream;
BinaryStreamRef C11LinesSubstream;
BinaryStreamRef C13LinesSubstream;
BinaryStreamRef GlobalRefsSubstream;
codeview::CVSymbolArray SymbolArray;
BinarySubstreamRef SymbolsSubstream;
BinarySubstreamRef C11LinesSubstream;
BinarySubstreamRef C13LinesSubstream;
BinarySubstreamRef GlobalRefsSubstream;
codeview::DebugSubsectionArray Subsections;
};

View File

@ -18,7 +18,11 @@ namespace pdb {
class NativeCompilandSymbol : public NativeRawSymbol {
public:
NativeCompilandSymbol(NativeSession &Session, DbiModuleDescriptor MI);
NativeCompilandSymbol(NativeSession &Session, uint32_t SymbolId,
DbiModuleDescriptor MI);
std::unique_ptr<NativeRawSymbol> clone() const override;
PDB_SymType getSymTag() const override;
bool isEditAndContinueEnabled() const override;
uint32_t getLexicalParentId() const override;

View File

@ -18,7 +18,9 @@ namespace pdb {
class NativeExeSymbol : public NativeRawSymbol {
public:
NativeExeSymbol(NativeSession &Session);
NativeExeSymbol(NativeSession &Session, uint32_t SymbolId);
std::unique_ptr<NativeRawSymbol> clone() const override;
std::unique_ptr<IPDBEnumSymbols>
findChildren(PDB_SymType Type) const override;

View File

@ -19,7 +19,9 @@ class NativeSession;
class NativeRawSymbol : public IPDBRawSymbol {
public:
explicit NativeRawSymbol(NativeSession &PDBSession);
NativeRawSymbol(NativeSession &PDBSession, uint32_t SymbolId);
virtual std::unique_ptr<NativeRawSymbol> clone() const = 0;
void dump(raw_ostream &OS, int Indent) const override;
@ -201,6 +203,7 @@ class NativeRawSymbol : public IPDBRawSymbol {
protected:
NativeSession &Session;
uint32_t SymbolId;
};
}

View File

@ -32,7 +32,7 @@ class NativeSession : public IPDBSession {
uint64_t getLoadAddress() const override;
void setLoadAddress(uint64_t Address) override;
std::unique_ptr<PDBSymbolExe> getGlobalScope() const override;
std::unique_ptr<PDBSymbolExe> getGlobalScope() override;
std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override;
std::unique_ptr<PDBSymbol>

View File

@ -13,6 +13,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/DebugInfo/MSF/IMSFFile.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
@ -85,6 +86,8 @@ class PDBFile : public msf::IMSFFile {
ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
msf::MSFStreamLayout getStreamLayout(uint32_t StreamIdx) const;
Error parseFileHeaders();
Error parseStreamData();

View File

@ -16,6 +16,7 @@
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Error.h"
@ -57,6 +58,8 @@ class TpiStream {
codeview::LazyRandomTypeCollection &typeCollection() { return *Types; }
BinarySubstreamRef getTypeRecordsSubstream() const;
Error commit();
private:
@ -65,6 +68,8 @@ class TpiStream {
std::unique_ptr<codeview::LazyRandomTypeCollection> Types;
BinarySubstreamRef TypeRecordsSubstream;
codeview::CVTypeArray TypeRecords;
std::unique_ptr<BinaryStream> HashStream;

View File

@ -1,4 +1,4 @@
//===-- SymbolizableModule.h ------------------------------------ C++ -----===//
//===- SymbolizableModule.h -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -14,12 +14,7 @@
#define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H
#include "llvm/DebugInfo/DIContext.h"
namespace llvm {
namespace object {
class ObjectFile;
}
}
#include <cstdint>
namespace llvm {
namespace symbolize {
@ -28,7 +23,8 @@ using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
class SymbolizableModule {
public:
virtual ~SymbolizableModule() {}
virtual ~SymbolizableModule() = default;
virtual DILineInfo symbolizeCode(uint64_t ModuleOffset,
FunctionNameKind FNKind,
bool UseSymbolTable) const = 0;
@ -45,7 +41,7 @@ class SymbolizableModule {
virtual uint64_t getModulePreferredBase() const = 0;
};
} // namespace symbolize
} // namespace llvm
} // end namespace symbolize
} // end namespace llvm
#endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H

View File

@ -1,4 +1,4 @@
//===-- Symbolize.h --------------------------------------------- C++ -----===//
//===- Symbolize.h ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -10,21 +10,27 @@
// Header for LLVM symbolization library.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
#define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace llvm {
namespace symbolize {
using namespace object;
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
class LLVMSymbolizer {
@ -36,6 +42,7 @@ class LLVMSymbolizer {
bool RelativeAddresses : 1;
std::string DefaultArch;
std::vector<std::string> DsymHints;
Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
bool UseSymbolTable = true, bool Demangle = true,
bool RelativeAddresses = false, std::string DefaultArch = "")
@ -45,6 +52,7 @@ class LLVMSymbolizer {
};
LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
~LLVMSymbolizer() {
flush();
}
@ -56,6 +64,7 @@ class LLVMSymbolizer {
Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
uint64_t ModuleOffset);
void flush();
static std::string
DemangleName(const std::string &Name,
const SymbolizableModule *DbiModuleDescriptor);
@ -63,7 +72,7 @@ class LLVMSymbolizer {
private:
// Bundles together object file with code/data and object file with
// corresponding debug info. These objects can be the same.
typedef std::pair<ObjectFile*, ObjectFile*> ObjectPair;
using ObjectPair = std::pair<ObjectFile *, ObjectFile *>;
/// Returns a SymbolizableModule or an error if loading debug info failed.
/// Only one attempt is made to load a module, and errors during loading are
@ -106,7 +115,7 @@ class LLVMSymbolizer {
Options Opts;
};
} // namespace symbolize
} // namespace llvm
} // end namespace symbolize
} // end namespace llvm
#endif
#endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H

View File

@ -15,54 +15,58 @@
#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
#include "RuntimeDyld.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/Object/Binary.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace llvm {
struct GenericValue;
class Constant;
class DataLayout;
class ExecutionEngine;
class Function;
class GlobalVariable;
struct GenericValue;
class GlobalValue;
class GlobalVariable;
class JITEventListener;
class MachineCodeInfo;
class MCJITMemoryManager;
class MutexGuard;
class ObjectCache;
class RTDyldMemoryManager;
class Triple;
class Type;
namespace object {
class Archive;
class ObjectFile;
}
class Archive;
class ObjectFile;
} // end namespace object
/// \brief Helper class for helping synchronize access to the global address map
/// table. Access to this class should be serialized under a mutex.
class ExecutionEngineState {
public:
typedef StringMap<uint64_t> GlobalAddressMapTy;
using GlobalAddressMapTy = StringMap<uint64_t>;
private:
/// GlobalAddressMap - A mapping between LLVM global symbol names values and
/// their actualized version...
GlobalAddressMapTy GlobalAddressMap;
@ -74,7 +78,6 @@ class ExecutionEngineState {
std::map<uint64_t, std::string> GlobalAddressReverseMap;
public:
GlobalAddressMapTy &getGlobalAddressMap() {
return GlobalAddressMap;
}
@ -509,13 +512,15 @@ class ExecutionEngine {
};
namespace EngineKind {
// These are actually bitmasks that get or-ed together.
enum Kind {
JIT = 0x1,
Interpreter = 0x2
};
const static Kind Either = (Kind)(JIT | Interpreter);
}
} // end namespace EngineKind
/// Builder class for ExecutionEngines. Use this by stack-allocating a builder,
/// chaining the various set* methods, and terminating it with a .create()
@ -655,6 +660,6 @@ class EngineBuilder {
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef)
} // End llvm namespace
} // end namespace llvm
#endif
#endif // LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H

View File

@ -1,4 +1,4 @@
//===-- GenericValue.h - Represent any type of LLVM value -------*- C++ -*-===//
//===- GenericValue.h - Represent any type of LLVM value --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -11,18 +11,15 @@
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_EXECUTIONENGINE_GENERICVALUE_H
#define LLVM_EXECUTIONENGINE_GENERICVALUE_H
#include "llvm/ADT/APInt.h"
#include "llvm/Support/DataTypes.h"
#include <vector>
namespace llvm {
typedef void* PointerTy;
class APInt;
using PointerTy = void *;
struct GenericValue {
struct IntPair {
@ -30,25 +27,29 @@ struct GenericValue {
unsigned int second;
};
union {
double DoubleVal;
float FloatVal;
PointerTy PointerVal;
struct IntPair UIntPairVal;
unsigned char Untyped[8];
double DoubleVal;
float FloatVal;
PointerTy PointerVal;
struct IntPair UIntPairVal;
unsigned char Untyped[8];
};
APInt IntVal; // also used for long doubles.
APInt IntVal; // also used for long doubles.
// For aggregate data types.
std::vector<GenericValue> AggregateVal;
// to make code faster, set GenericValue to zero could be omitted, but it is
// potentially can cause problems, since GenericValue to store garbage
// instead of zero.
GenericValue() : IntVal(1,0) {UIntPairVal.first = 0; UIntPairVal.second = 0;}
explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { }
GenericValue() : IntVal(1, 0) {
UIntPairVal.first = 0;
UIntPairVal.second = 0;
}
explicit GenericValue(void *V) : PointerVal(V), IntVal(1, 0) {}
};
inline GenericValue PTOGV(void *P) { return GenericValue(P); }
inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; }
inline void *GVTOP(const GenericValue &GV) { return GV.PointerVal; }
} // End llvm namespace.
#endif
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_GENERICVALUE_H

View File

@ -15,8 +15,8 @@
#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
#include "RuntimeDyld.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/DebugLoc.h"
#include <cstdint>
#include <vector>
@ -28,7 +28,9 @@ class MachineFunction;
class OProfileWrapper;
namespace object {
class ObjectFile;
class ObjectFile;
} // end namespace object
/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
@ -57,7 +59,7 @@ struct JITEvent_EmittedFunctionDetails {
/// The default implementation of each method does nothing.
class JITEventListener {
public:
typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails;
using EmittedFunctionDetails = JITEvent_EmittedFunctionDetails;
public:
JITEventListener() = default;

View File

@ -1,4 +1,4 @@
//===----------- JITSymbol.h - JIT symbol abstraction -----------*- C++ -*-===//
//===- JITSymbol.h - JIT symbol abstraction ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -26,16 +26,18 @@ namespace llvm {
class GlobalValue;
namespace object {
class BasicSymbolRef;
class BasicSymbolRef;
} // end namespace object
/// @brief Represents an address in the target process's address space.
typedef uint64_t JITTargetAddress;
using JITTargetAddress = uint64_t;
/// @brief Flags for symbols in the JIT.
class JITSymbolFlags {
public:
typedef uint8_t UnderlyingType;
using UnderlyingType = uint8_t;
enum FlagNames : UnderlyingType {
None = 0,
@ -46,7 +48,7 @@ class JITSymbolFlags {
};
/// @brief Default-construct a JITSymbolFlags instance.
JITSymbolFlags() : Flags(None) {}
JITSymbolFlags() = default;
/// @brief Construct a JITSymbolFlags instance from the given flags.
JITSymbolFlags(FlagNames Flags) : Flags(Flags) {}
@ -81,15 +83,14 @@ class JITSymbolFlags {
static JITSymbolFlags fromObjectSymbol(const object::BasicSymbolRef &Symbol);
private:
UnderlyingType Flags;
UnderlyingType Flags = None;
};
/// @brief Represents a symbol that has been evaluated to an address already.
class JITEvaluatedSymbol {
public:
/// @brief Create a 'null' symbol.
JITEvaluatedSymbol(std::nullptr_t)
: Address(0) {}
JITEvaluatedSymbol(std::nullptr_t) {}
/// @brief Create a symbol for the given address and flags.
JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags)
@ -105,19 +106,18 @@ class JITEvaluatedSymbol {
JITSymbolFlags getFlags() const { return Flags; }
private:
JITTargetAddress Address;
JITTargetAddress Address = 0;
JITSymbolFlags Flags;
};
/// @brief Represents a symbol in the JIT.
class JITSymbol {
public:
typedef std::function<JITTargetAddress()> GetAddressFtor;
using GetAddressFtor = std::function<JITTargetAddress()>;
/// @brief Create a 'null' symbol that represents failure to find a symbol
/// definition.
JITSymbol(std::nullptr_t)
: CachedAddr(0) {}
JITSymbol(std::nullptr_t) {}
/// @brief Create a symbol for a definition with a known address.
JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags)
@ -137,7 +137,7 @@ class JITSymbol {
/// user can materialize the definition at any time by calling the getAddress
/// method.
JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
: GetAddress(std::move(GetAddress)), CachedAddr(0), Flags(Flags) {}
: GetAddress(std::move(GetAddress)), Flags(Flags) {}
/// @brief Returns true if the symbol exists, false otherwise.
explicit operator bool() const { return CachedAddr || GetAddress; }
@ -157,7 +157,7 @@ class JITSymbol {
private:
GetAddressFtor GetAddress;
JITTargetAddress CachedAddr;
JITTargetAddress CachedAddr = 0;
JITSymbolFlags Flags;
};

View File

@ -24,16 +24,20 @@
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
#include <cassert>
#include <functional>
@ -46,6 +50,9 @@
#include <vector>
namespace llvm {
class Value;
namespace orc {
/// @brief Compile-on-demand layer.
@ -77,15 +84,15 @@ class CompileOnDemandLayer {
return LambdaMaterializer<MaterializerFtor>(std::move(M));
}
typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
using BaseLayerModuleHandleT = typename BaseLayerT::ModuleHandleT;
// Provide type-erasure for the Modules and MemoryManagers.
template <typename ResourceT>
class ResourceOwner {
public:
ResourceOwner() = default;
ResourceOwner(const ResourceOwner&) = delete;
ResourceOwner& operator=(const ResourceOwner&) = delete;
ResourceOwner(const ResourceOwner &) = delete;
ResourceOwner &operator=(const ResourceOwner &) = delete;
virtual ~ResourceOwner() = default;
virtual ResourceT& getResource() const = 0;
@ -106,7 +113,7 @@ class CompileOnDemandLayer {
template <typename ResourceT, typename ResourcePtrT>
std::unique_ptr<ResourceOwner<ResourceT>>
wrapOwnership(ResourcePtrT ResourcePtr) {
typedef ResourceOwnerImpl<ResourceT, ResourcePtrT> RO;
using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
return llvm::make_unique<RO>(std::move(ResourcePtr));
}
@ -130,21 +137,21 @@ class CompileOnDemandLayer {
};
struct LogicalDylib {
typedef std::function<JITSymbol(const std::string&)> SymbolResolverFtor;
using SymbolResolverFtor = std::function<JITSymbol(const std::string&)>;
typedef std::function<typename BaseLayerT::ModuleSetHandleT(
BaseLayerT&,
std::unique_ptr<Module>,
std::unique_ptr<JITSymbolResolver>)>
ModuleAdderFtor;
using ModuleAdderFtor =
std::function<typename BaseLayerT::ModuleHandleT(
BaseLayerT&,
std::unique_ptr<Module>,
std::unique_ptr<JITSymbolResolver>)>;
struct SourceModuleEntry {
std::unique_ptr<ResourceOwner<Module>> SourceMod;
std::set<Function*> StubsToClone;
};
typedef std::vector<SourceModuleEntry> SourceModulesList;
typedef typename SourceModulesList::size_type SourceModuleHandle;
using SourceModulesList = std::vector<SourceModuleEntry>;
using SourceModuleHandle = typename SourceModulesList::size_type;
SourceModuleHandle
addSourceModule(std::unique_ptr<ResourceOwner<Module>> M) {
@ -174,7 +181,7 @@ class CompileOnDemandLayer {
void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
for (auto &BLH : BaseLayerHandles)
BaseLayer.removeModuleSet(BLH);
BaseLayer.removeModule(BLH);
}
std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver;
@ -183,21 +190,21 @@ class CompileOnDemandLayer {
StaticGlobalRenamer StaticRenamer;
ModuleAdderFtor ModuleAdder;
SourceModulesList SourceModules;
std::vector<BaseLayerModuleSetHandleT> BaseLayerHandles;
std::vector<BaseLayerModuleHandleT> BaseLayerHandles;
};
typedef std::list<LogicalDylib> LogicalDylibList;
using LogicalDylibList = std::list<LogicalDylib>;
public:
/// @brief Handle to a set of loaded modules.
typedef typename LogicalDylibList::iterator ModuleSetHandleT;
/// @brief Handle to loaded module.
using ModuleHandleT = typename LogicalDylibList::iterator;
/// @brief Module partitioning functor.
typedef std::function<std::set<Function*>(Function&)> PartitioningFtor;
using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
/// @brief Builder for IndirectStubsManagers.
typedef std::function<std::unique_ptr<IndirectStubsMgrT>()>
IndirectStubsManagerBuilderT;
using IndirectStubsManagerBuilderT =
std::function<std::unique_ptr<IndirectStubsMgrT>()>;
/// @brief Construct a compile-on-demand layer instance.
CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition,
@ -211,15 +218,14 @@ class CompileOnDemandLayer {
~CompileOnDemandLayer() {
while (!LogicalDylibs.empty())
removeModuleSet(LogicalDylibs.begin());
removeModule(LogicalDylibs.begin());
}
/// @brief Add a module to the compile-on-demand layer.
template <typename ModuleSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
template <typename MemoryManagerPtrT, typename SymbolResolverPtrT>
ModuleHandleT addModule(std::shared_ptr<Module> M,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
LogicalDylibs.push_back(LogicalDylib());
auto &LD = LogicalDylibs.back();
@ -232,23 +238,25 @@ class CompileOnDemandLayer {
LD.ModuleAdder =
[&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M,
std::unique_ptr<JITSymbolResolver> R) {
std::vector<std::unique_ptr<Module>> Ms;
Ms.push_back(std::move(M));
return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R));
return B.addModule(std::move(M), &MemMgrRef, std::move(R));
};
// Process each of the modules in this module set.
for (auto &M : Ms)
addLogicalModule(LogicalDylibs.back(), std::move(M));
addLogicalModule(LogicalDylibs.back(), std::move(M));
return std::prev(LogicalDylibs.end());
}
/// @brief Add extra modules to an existing logical module.
void addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) {
addLogicalModule(*H, std::move(M));
}
/// @brief Remove the module represented by the given handle.
///
/// This will remove all modules in the layers below that were derived from
/// the module represented by H.
void removeModuleSet(ModuleSetHandleT H) {
void removeModule(ModuleHandleT H) {
H->removeModulesFromBaseLayer(BaseLayer);
LogicalDylibs.erase(H);
}
@ -270,7 +278,7 @@ class CompileOnDemandLayer {
/// @brief Get the address of a symbol provided by this layer, or some layer
/// below this one.
JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
}
@ -303,7 +311,6 @@ class CompileOnDemandLayer {
private:
template <typename ModulePtrT>
void addLogicalModule(LogicalDylib &LD, ModulePtrT SrcMPtr) {
// Rename all static functions / globals to $static.X :
// This will unique the names across all modules in the logical dylib,
// simplifying symbol lookup.
@ -495,7 +502,7 @@ class CompileOnDemandLayer {
}
template <typename PartitionT>
BaseLayerModuleSetHandleT
BaseLayerModuleHandleT
emitPartition(LogicalDylib &LD,
typename LogicalDylib::SourceModuleHandle LMId,
const PartitionT &Part) {
@ -581,6 +588,7 @@ class CompileOnDemandLayer {
};
} // end namespace orc
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H

View File

@ -1,4 +1,4 @@
//===-- CompileUtils.h - Utilities for compiling IR in the JIT --*- C++ -*-===//
//===- CompileUtils.h - Utilities for compiling IR in the JIT ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -14,24 +14,47 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <memory>
namespace llvm {
class MCContext;
class Module;
namespace orc {
/// @brief Simple compile functor: Takes a single IR module and returns an
/// ObjectFile.
class SimpleCompiler {
public:
using CompileResult = object::OwningBinary<object::ObjectFile>;
/// @brief Construct a simple compile functor with the given target.
SimpleCompiler(TargetMachine &TM) : TM(TM) {}
SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr)
: TM(TM), ObjCache(ObjCache) {}
/// @brief Set an ObjectCache to query before compiling.
void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
/// @brief Compile a Module to an ObjectFile.
object::OwningBinary<object::ObjectFile> operator()(Module &M) const {
CompileResult operator()(Module &M) {
CompileResult CachedObject = tryToLoadFromObjectCache(M);
if (CachedObject.getBinary())
return CachedObject;
SmallVector<char, 0> ObjBufferSV;
raw_svector_ostream ObjStream(ObjBufferSV);
@ -44,19 +67,47 @@ class SimpleCompiler {
new ObjectMemoryBuffer(std::move(ObjBufferSV)));
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
typedef object::OwningBinary<object::ObjectFile> OwningObj;
if (Obj)
return OwningObj(std::move(*Obj), std::move(ObjBuffer));
if (Obj) {
notifyObjectCompiled(M, *ObjBuffer);
return CompileResult(std::move(*Obj), std::move(ObjBuffer));
}
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
return OwningObj(nullptr, nullptr);
return CompileResult(nullptr, nullptr);
}
private:
CompileResult tryToLoadFromObjectCache(const Module &M) {
if (!ObjCache)
return CompileResult();
std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
if (!ObjBuffer)
return CompileResult();
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
if (!Obj) {
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
return CompileResult();
}
return CompileResult(std::move(*Obj), std::move(ObjBuffer));
}
void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) {
if (ObjCache)
ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef());
}
TargetMachine &TM;
ObjectCache *ObjCache = nullptr;
};
} // End namespace orc.
} // End namespace llvm.
} // end namespace orc
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H

View File

@ -1,4 +1,4 @@
//===-- ExecutionUtils.h - Utilities for executing code in Orc --*- C++ -*-===//
//===- ExecutionUtils.h - Utilities for executing code in Orc ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -17,8 +17,11 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include <algorithm>
#include <cstdint>
#include <string>
#include <vector>
#include <utility>
namespace llvm {
@ -37,7 +40,6 @@ namespace orc {
/// getConstructors/getDestructors functions.
class CtorDtorIterator {
public:
/// @brief Accessor for an element of the global_ctors/global_dtors array.
///
/// This class provides a read-only view of the element with any casts on
@ -89,17 +91,16 @@ iterator_range<CtorDtorIterator> getDestructors(const Module &M);
template <typename JITLayerT>
class CtorDtorRunner {
public:
/// @brief Construct a CtorDtorRunner for the given range using the given
/// name mangling function.
CtorDtorRunner(std::vector<std::string> CtorDtorNames,
typename JITLayerT::ModuleSetHandleT H)
typename JITLayerT::ModuleHandleT H)
: CtorDtorNames(std::move(CtorDtorNames)), H(H) {}
/// @brief Run the recorded constructors/destructors through the given JIT
/// layer.
bool runViaLayer(JITLayerT &JITLayer) const {
typedef void (*CtorDtorTy)();
using CtorDtorTy = void (*)();
bool Error = false;
for (const auto &CtorDtorName : CtorDtorNames)
@ -115,7 +116,7 @@ class CtorDtorRunner {
private:
std::vector<std::string> CtorDtorNames;
typename JITLayerT::ModuleSetHandleT H;
typename JITLayerT::ModuleHandleT H;
};
/// @brief Support class for static dtor execution. For hosted (in-process) JITs
@ -135,7 +136,6 @@ class CtorDtorRunner {
/// called.
class LocalCXXRuntimeOverrides {
public:
/// Create a runtime-overrides class.
template <typename MangleFtorT>
LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) {
@ -156,7 +156,6 @@ class LocalCXXRuntimeOverrides {
void runDestructors();
private:
template <typename PtrTy>
JITTargetAddress toTargetAddress(PtrTy* P) {
return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(P));
@ -168,15 +167,16 @@ class LocalCXXRuntimeOverrides {
StringMap<JITTargetAddress> CXXRuntimeOverrides;
typedef void (*DestructorPtr)(void*);
typedef std::pair<DestructorPtr, void*> CXXDestructorDataPair;
typedef std::vector<CXXDestructorDataPair> CXXDestructorDataPairList;
using DestructorPtr = void (*)(void *);
using CXXDestructorDataPair = std::pair<DestructorPtr, void *>;
using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>;
CXXDestructorDataPairList DSOHandleOverride;
static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
void *DSOHandle);
};
} // End namespace orc.
} // End namespace llvm.
} // end namespace orc
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H

View File

@ -1,4 +1,4 @@
//===---- GlobalMappingLayer.h - Run all IR through a functor ---*- C++ -*-===//
//===- GlobalMappingLayer.h - Run all IR through a functor ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -17,6 +17,7 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include <map>
#include <string>
namespace llvm {
namespace orc {
@ -32,7 +33,7 @@ template <typename BaseLayerT>
class GlobalMappingLayer {
public:
/// @brief Handle to a set of added modules.
typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
using ModuleSetHandleT = typename BaseLayerT::ModuleSetHandleT;
/// @brief Construct an GlobalMappingLayer with the given BaseLayer
GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
@ -102,7 +103,7 @@ class GlobalMappingLayer {
std::map<std::string, JITTargetAddress> SymbolTable;
};
} // End namespace orc.
} // End namespace llvm.
} // end namespace orc
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H

View File

@ -1,4 +1,4 @@
//===------ IRCompileLayer.h -- Eagerly compile IR for JIT ------*- C++ -*-===//
//===- IRCompileLayer.h -- Eagerly compile IR for JIT -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -14,79 +14,54 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"
#include <memory>
#include <string>
namespace llvm {
class Module;
namespace orc {
/// @brief Eager IR compiling layer.
///
/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
/// immediately compiles each IR module to an object file (each IR Module is
/// compiled separately). The resulting set of object files is then added to
/// the layer below, which must implement the object layer concept.
template <typename BaseLayerT> class IRCompileLayer {
/// This layer immediately compiles each IR module added via addModule to an
/// object file and adds this module file to the layer below, which must
/// implement the object layer concept.
template <typename BaseLayerT, typename CompileFtor>
class IRCompileLayer {
public:
typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
CompileFtor;
private:
typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
public:
/// @brief Handle to a set of compiled modules.
typedef ObjSetHandleT ModuleSetHandleT;
/// @brief Handle to a compiled module.
using ModuleHandleT = typename BaseLayerT::ObjHandleT;
/// @brief Construct an IRCompileLayer with the given BaseLayer, which must
/// implement the ObjectLayer concept.
IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
: BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
: BaseLayer(BaseLayer), Compile(std::move(Compile)) {}
/// @brief Set an ObjectCache to query before compiling.
void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
/// @brief Get a reference to the compiler functor.
CompileFtor& getCompiler() { return Compile; }
/// @brief Compile each module in the given module set, then add the resulting
/// set of objects to the base layer along with the memory manager and
/// symbol resolver.
/// @brief Compile the module, and add the resulting object to the base layer
/// along with the given memory manager and symbol resolver.
///
/// @return A handle for the added modules.
template <typename ModuleSetT, typename MemoryManagerPtrT,
typename SymbolResolverPtrT>
ModuleSetHandleT addModuleSet(ModuleSetT Ms,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>>
Objects;
for (const auto &M : Ms) {
auto Object =
llvm::make_unique<object::OwningBinary<object::ObjectFile>>();
if (ObjCache)
*Object = tryToLoadFromObjectCache(*M);
if (!Object->getBinary()) {
*Object = Compile(*M);
if (ObjCache)
ObjCache->notifyObjectCompiled(&*M,
Object->getBinary()->getMemoryBufferRef());
}
Objects.push_back(std::move(Object));
}
ModuleSetHandleT H =
BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
std::move(Resolver));
return H;
/// @return A handle for the added module.
template <typename MemoryManagerPtrT, typename SymbolResolverPtrT>
ModuleHandleT addModule(std::shared_ptr<Module> M,
MemoryManagerPtrT MemMgr,
SymbolResolverPtrT Resolver) {
using CompileResult = decltype(Compile(*M));
auto Obj = std::make_shared<CompileResult>(Compile(*M));
return BaseLayer.addObject(std::move(Obj), std::move(MemMgr),
std::move(Resolver));
}
/// @brief Remove the module set associated with the handle H.
void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
/// @brief Remove the module associated with the handle H.
void removeModule(ModuleHandleT H) { BaseLayer.removeObject(H); }
/// @brief Search for the given named symbol.
/// @param Name The name of the symbol to search for.
@ -96,51 +71,33 @@ template <typename BaseLayerT> class IRCompileLayer {
return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
}
/// @brief Get the address of the given symbol in the context of the set of
/// compiled modules represented by the handle H. This call is
/// forwarded to the base layer's implementation.
/// @param H The handle for the module set to search in.
/// @brief Get the address of the given symbol in compiled module represented
/// by the handle H. This call is forwarded to the base layer's
/// implementation.
/// @param H The handle for the module to search in.
/// @param Name The name of the symbol to search for.
/// @param ExportedSymbolsOnly If true, search only for exported symbols.
/// @return A handle for the given named symbol, if it is found in the
/// given module set.
JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
/// given module.
JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
}
/// @brief Immediately emit and finalize the moduleOB set represented by the
/// given handle.
/// @param H Handle for module set to emit/finalize.
void emitAndFinalize(ModuleSetHandleT H) {
/// @brief Immediately emit and finalize the module represented by the given
/// handle.
/// @param H Handle for module to emit/finalize.
void emitAndFinalize(ModuleHandleT H) {
BaseLayer.emitAndFinalize(H);
}
private:
object::OwningBinary<object::ObjectFile>
tryToLoadFromObjectCache(const Module &M) {
std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
if (!ObjBuffer)
return object::OwningBinary<object::ObjectFile>();
Expected<std::unique_ptr<object::ObjectFile>> Obj =
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
if (!Obj) {
// TODO: Actually report errors helpfully.
consumeError(Obj.takeError());
return object::OwningBinary<object::ObjectFile>();
}
return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
std::move(ObjBuffer));
}
BaseLayerT &BaseLayer;
CompileFtor Compile;
ObjectCache *ObjCache;
};
} // End namespace orc.
} // End namespace llvm.
} // end namespace orc
} // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H

Some files were not shown because too many files have changed in this diff Show More