Most of the work here involves adding support for aggregate arguments
that are represented as multiple primitive and aggregate arguments
that are represented as LLVM 'byvalue' arguments (i.e. LLVM arguments
with the 'byvalue' attribute). The former are used for IL by-value
struct arguments that must be passed in multiple registers; the latter
are used for by-value struct arguments that must be passed on the
stack. All arguments are classified as do enregister/do not
enregister using the interface provided by CoreCLR.
- _DEBUG was not being defined when CMake was invoked without an explicit
build type. The build now defaults to debug unless otherwise specified.
- A couple of GC-related types needed global namespace qualifiers to avoid
name collisions.
- There were various const-cast related issues that needed resolution.
Suppress warnings about virtual dtors since the CLR header patterns are not clean.
Disable warnings about unknown pragmas since we use #pragma region.
Disable warnings about covered switch defaults since we use this to detect upstream enum changes.
Add a missing dtor to ReaderStack.
For headers in "fixed" locations like the ones we get from the CLR, suppress CMake's desire to add cross-targeting prefixes.
Add some Arm64 register mappings for the GC info.
Fix warnings from Clang that were not caused by `-Wnon-virtual-dtor` or `-Wunknown-pragma`.
When cmake is "cross-compiling" LLVM (which means that the build-host
which LLVM will be built on differs from the build-target/compile-host
that LLVM will be built to run on [regardless whether the built LLVM is a
cross-compiler or not]), it uses a recursive cmake invocation targeting
the build-host to build some tools that LLVM uses in its build process.
Check the LLVM_TARGET_IS_CROSSCOMPILE_HOST flag that is set in these
recursive invocations, and skip adding LLILC targets when it is set; this
is fine to do because LLILC is not one of the tools that LLVM uses in its
build process, and is necessary because the recursive invocations do not
pass the WITH_CORECLR setting that LLILC requires.
This will allow configuring with LLVM_OPTIMIZED_TABLEGEN=ON (which
internally uses cross-compiling), which can provide substantial build-time
savings.
These changes implement jit features for ReadyToRun compilation.
The ReadyToRun overview is located here:
https://github.com/dotnet/coreclr/blob/master/Documentation/botr/readytorun-overview.md
It's a format that provides version resiliency on top of ngen.
These changes mostly follow what's implemented in RyuJit.
Special handling is done for the following operations:
* Type context creation
* Struct copy with write barriers: CORINFO_HELP_ASSIGN_STRUCT is not available for ReadyToRun
and is not used by RyuJit at all (it's considered inefficient). I implemented inline copy expansion.
* Field access
* isinst and castclass
* Class constructor insertion
* Static field address calculation
* Direct call target computation
* Indirect virtual call target computation
* Function pointer loading
* Object creation
* Array creation
Some additional changes:
* OptLevel is set to Default for ngen and ReadyToRun compilation
regardless of whether we are compiling debug or release.
* CodeModel is set to Default instead of JITDefault for ngen
and ReadyToRun compilation. We get rel32 relocations, which matches
what RyuJit generates.
COMPLUS_AltJitNgen is now set to * for our test runs. That ensures that
the existing ReadyToRun tests will use llilc to generate ReadyToRun images.
I verified that llilc can produce ReadyToRun images of tiny Roslyn and
can use them to compile itself and the result can run.
Closes#751, #750, #749, #748, #747, #745, #746
Turn on -WX for MSVC builds of the LLILC code, if LLVM hasn't already enabled it (via LLVM_ENABLE_WERROR ON).
Make some variable definitions conditional if the only uses are in asserts.
In Microsoft/llvm@84b1665, LLVM stopped supplying a custom argument parser in favor of using the CMake builtin. We need to do likewise in LLIIC.
This is a prerequisite to merging latest LLVM sources.
This change build LLILC with CoreCLR's GcInfoEncoding Library.
-> The GcInfoEncoder headers and implementation are available in CoreCLR's
Output directory.
-> include\GcInfoUtil provides (alternate implementations for) some
data-structures and utilities used by the encoder
-> LLILC generates GcInfo correctly using the encoder.
GcInfoUtil provides the following utilities used by the GcInfoEncoder:
1) Logging functions used by the encoder
2) Helpers for bit-manipulation and overflow checking
3) A simple allocator (using new and delete)
4) SList -- a singly linked list that supports insert-at-tail.
This is a subset of SList in CoreCLR tree, with only necessary functionality.
5) CQuickSort - A simple quick sort implementation with comparer
overridden by the GcInfo encoder library -- from the CoreClr tree.
6) StructArrayList -- a list of arrays which has specific growth and location
preserving characteristics -- simplified version from CoreCLR tree.
7) SimplerHashTable -- a wrapper around standard unordered map, with
the encoder's own hashing and comparison functions.
Testing:
All LLILC Unit tests passed locally
Rosly builds without the need for code-size workarounds.
LLVMConfig.cmake (which we use when building out-of-tree) sets
TARGET_TRIPLE instead of LLVM_DEFAULT_TARGET_TRIPLE. Work around this
by setting LLVM_DEFAULT_TARGET_TRIPLE to TARGET_TRIPLE when building
out-of-tree.
When configuring standalone LLILC (i.e. when the LLILC repo
is not placed in LLVM/tools), we were not setting
LLVM_RUNTIME_OUTPUT_INTDIR and LLVM_LIBRARY_OUTPUT_INTDIR.
These must be set if an executable is added.
While testing I also added a dummy (placeholder) driver to verify that
it is compiled and executable created for it. However we will wait to
check in a driver until it is actually functional.
- The PAL definitions we need from CoreCLR moved out of libcoreclr and
into libcoreclrpal. Update CMakeLists accordingly.
- The JIT options sources were inconsistent with the rest of the code
w.r.t. the use of the `this` pointer and were missing copyright
headers.
Remove CLR headers and add dependency on a prebuild CoreCLR. Most of the headers in the
include\clr subdirectory are removed and now are picked up from a prebuilt coreclr so that
keeping in sync is clearer.
Remaining headers are used to support packing in the PAL. Follow on
work will remove these dependencies.
First, we need to remove CACHE from the line to avoid any previously
wrong path name that polluted the cache and cmake might pick it up
from the cache.
Second, the way to pass LLVM Build directory in cmake command line
should be -DWITH_LLVM:STRING=[path to your llvm build directory] not
-DWITH_LLVM=[path to your llvm build directory].
- LLVM recently bumped the required version of CMake to 2.8.12.2, which
contains proper support for private linkage in link_target_library.
This commit removes the workaround that had previously been in place.
- LLVM probing was slightly off for out-of-tree builds.
- Set LLILC_ENABLE_DOXYGEN if LLVM_ENABLE_DOXYGEN is set
- Find Doxygen and Graphviz at configure time when building out-of-tree
or when LLILC_ENABLE_DOXYGEN is set and LLVM_ENABLE_DOXYGEN is not
In more detail:
Modified LLILC's CMakeLists.txt to
1. Add an LLILC_ENABLE_DOXYGEN option (ON by default)
2. configure a Doxygen configuration file.
3. Add a custom target, doxygen-llilc, to run doxygen.
In addition a file, Documentation/index.dox, is added that has the main page
for the LLILC Doxygen output.
To use you need to do the following:
1. Install Doxygen
2. Install Graphviz, ensuring that dot is on your path.
3. In your LLVM source directory, edit the CMakeLists.txt file so that LLVM_ENABLE_DOXYGEN is ON, or alternately when you run cmake give it an option to enable it.
4. After you configure LLVM you can open the LLVM.sln file, right click on doxygen-llilc, and select "build". You do not need to build LLVM before doing this.
- Don't use find_package for LLVM if MSILC_WITH_LLVM is defined
- Probe for libcoreclr.so whether or not we are building from within
the LLVM tree.
- Move the definition for __stdcall outside of an outer _MSC_VER guard.
- Remove MSILCJIT_PATH_TO_LLVM_SOURCE
- Rename MSILCJIT_PATH_TO_{LLVM_BUILD,CORECLR} to MSILC_WITH_{LLVM,CORECLR}
- Improve probing for LLVM and CoreCLR
- Switch ad-hoc discovery of certain LLVM components to definitions from
LLVMConfig.cmake
The backend will fail to emit functions containing FRem instructions
on platforms where fmod is not available at runtime; this currently
includes CoreCLR on Windows (by default, at least).
We may be able to defer this lowering by changing the target library
options for the backend, but this likely requires a change to MCJIT.
Fixes#19.
- libcoreclr need to be passed to the linker when linking libmsilcjit
on Linux in order to avoid undefined symbol errors
- Replace a number of MSVC-specific attributes with their GCC/Clang
equivalents
- Clean up some type/variable naming conflicts
- Migrate MSILCJit to use unique_ptr to track module ownership.
Don't link against libcoreclr on Windows.