├── test
├── CMakeLists.txt
├── LLILCTestEnv.cmd
├── const.py
├── llilc_roslyn_stage.cmd
├── llilc_hook.py
├── applyfilter.py
└── llilc_run.py
├── include
├── Jit
│ ├── CMakeLists.txt
│ ├── jitpch.h
│ ├── global.h
│ ├── compiler.h
│ ├── jitoptions.h
│ ├── utility.h
│ └── EEMemoryManager.h
├── clr
│ ├── CMakeLists.txt
│ ├── pshpack2.h
│ ├── pshpack1.h
│ ├── pshpack4.h
│ ├── pshpack8.h
│ ├── poppack.h
│ └── misc.h
├── Driver
│ └── CMakeLists.txt
├── GcInfo
│ ├── CMakeLists.txt
│ ├── eexcp.h
│ └── Target.h
├── Pal
│ ├── Rt
│ │ ├── CMakeLists.txt
│ │ ├── ole2.h
│ │ ├── windef.h
│ │ ├── winerror.h
│ │ └── specstrings.h
│ ├── CMakeLists.txt
│ └── earlyincludes.h
├── Reader
│ ├── CMakeLists.txt
│ ├── imeta.h
│ ├── gverify.h
│ ├── imeta.def
│ ├── options.h
│ ├── ophelper.def
│ ├── newvstate.h
│ ├── abisignature.h
│ └── abi.h
└── CMakeLists.txt
├── tools
├── Driver
│ ├── CMakeLists.txt
│ └── ReadMe.txt
└── CMakeLists.txt
├── .clang-format
├── lib
├── Jit
│ ├── LLILCJit.exports
│ ├── jitpch.cpp
│ ├── CMakeLists.txt
│ └── utility.cpp
├── CMakeLists.txt
├── CoreDisTools
│ ├── coredistools.exports
│ ├── .nuget
│ │ ├── Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.win-x64.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.win-x86.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.centos.7.1-x64.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.centos.7.1-x86.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.osx.10.11-x64.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.osx.10.11-x86.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.ubuntu.14.04-x64.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.ubuntu.14.04-x86.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.ubuntu.16.04-x64.Microsoft.NETCore.CoreDisTools.nuspec
│ │ ├── runtime.ubuntu.16.04-x86.Microsoft.NETCore.CoreDisTools.nuspec
│ │ └── runtime.json
│ └── CMakeLists.txt
├── ObjWriter
│ ├── objwriter.exports
│ ├── .nuget
│ │ ├── runtime.json
│ │ ├── Microsoft.DotNet.ObjectWriter.nuspec
│ │ ├── toolchain.win7-x64.Microsoft.DotNet.ObjectWriter.nuspec
│ │ ├── toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter.nuspec
│ │ └── toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter.nuspec
│ ├── CMakeLists.txt
│ └── jitDebugInfo.h
├── GcInfo
│ ├── CMakeLists.txt
│ └── GcInfoUtil.cpp
└── Reader
│ └── CMakeLists.txt
├── Documentation
├── Images
│ ├── AOTArch.png
│ └── JITArch.png
├── llilc-at-six-months.md
├── index.md
├── Background.md
├── Welcome.md
├── Contributing.md
├── Getting-Started-For-Linux-and-OS-X.md
├── llilc-milestones.md
├── Code-Formatting.md
├── llilc-faq.md
├── Long-Running-Branch-Workflow.md
├── llilc-Coding-Conventions-and-Commenting-Style.md
├── Developer-Workflow.md
├── Areas-To-Contribute.md
├── Getting-Started-For-Windows.md
├── Setup-With-LLILC-Out-Of-LLVM-Tree.md
├── Testing.md
└── llilc-gc-transition.md
├── utils
├── packages.config
├── NuGet.config
├── make_package.py
└── BuildPackages.ps1
├── CODE-OF-CONDUCT.md
├── LICENSE.TXT
├── CODE_OWNERS.TXT
├── .gitattributes
├── .gitignore
├── README.md
└── netci.groovy
/test/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/Jit/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/clr/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tools/Driver/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/Driver/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/GcInfo/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/Pal/Rt/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/Reader/CMakeLists.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/include/Pal/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(Rt)
2 |
--------------------------------------------------------------------------------
/tools/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(Driver)
2 |
--------------------------------------------------------------------------------
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: LLVM
2 | SortIncludes: false
3 |
--------------------------------------------------------------------------------
/lib/Jit/LLILCJit.exports:
--------------------------------------------------------------------------------
1 | getJit
2 | sxsJitStartup
3 | jitStartup
4 |
--------------------------------------------------------------------------------
/tools/Driver/ReadMe.txt:
--------------------------------------------------------------------------------
1 | This is a placeholder for an AOT (Ahead Of Time) compilation driver.
2 |
--------------------------------------------------------------------------------
/Documentation/Images/AOTArch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnet/llilc/HEAD/Documentation/Images/AOTArch.png
--------------------------------------------------------------------------------
/Documentation/Images/JITArch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnet/llilc/HEAD/Documentation/Images/JITArch.png
--------------------------------------------------------------------------------
/Documentation/llilc-at-six-months.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnet/llilc/HEAD/Documentation/llilc-at-six-months.md
--------------------------------------------------------------------------------
/include/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_subdirectory(clr)
2 | add_subdirectory(Driver)
3 | add_subdirectory(GcInfo)
4 | add_subdirectory(Jit)
5 | add_subdirectory(Pal)
6 | add_subdirectory(Reader)
7 |
--------------------------------------------------------------------------------
/utils/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/lib/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Enable ObjWriter/CoreDisTools only
2 | #add_subdirectory(Reader)
3 | #add_subdirectory(Jit)
4 | #add_subdirectory(GcInfo)
5 | add_subdirectory(ObjWriter)
6 | add_subdirectory(CoreDisTools)
7 |
8 |
--------------------------------------------------------------------------------
/CODE-OF-CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | This project has adopted the code of conduct defined by the Contributor Covenant
4 | to clarify expected behavior in our community.
5 |
6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
7 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/coredistools.exports:
--------------------------------------------------------------------------------
1 | InitDisasm
2 | InitBufferedDisasm
3 | NewDisasm
4 | FinishDisasm
5 | DisasmInstruction
6 | DumpInstruction
7 | InitBufferedDiffer
8 | NewDiffer
9 | FinishDiff
10 | NearDiffCodeBlocks
11 | DumpCodeBlock
12 | DumpDiffBlocks
13 | GetOutputBuffer
14 | ClearOutputBuffer
15 |
--------------------------------------------------------------------------------
/lib/ObjWriter/objwriter.exports:
--------------------------------------------------------------------------------
1 | InitObjWriter
2 | FinishObjWriter
3 | SwitchSection
4 | EmitAlignment
5 | EmitBlob
6 | EmitIntValue
7 | EmitSymbolDef
8 | EmitSymbolRef
9 | EmitWinFrameInfo
10 | EmitCFIStart
11 | EmitCFIEnd
12 | EmitCFICode
13 | EmitCFILsda
14 | EmitDebugFileInfo
15 | EmitDebugLoc
16 | EmitDebugFunctionInfo
17 | EmitDebugModuleInfo
18 | EmitDebugVar
19 | CreateCustomSection
20 |
--------------------------------------------------------------------------------
/test/LLILCTestEnv.cmd:
--------------------------------------------------------------------------------
1 | REM -------------------------------------------------------------------------
2 | REM
3 | REM This script provides LLILC test environment settings
4 | REM
5 | REM -------------------------------------------------------------------------
6 |
7 | set COMPLUS_AltJit=*
8 | set COMPLUS_AltJitNgen=*
9 | set COMPLUS_AltJitName=LLILCJit.dll
10 | set COMPLUS_GCCONSERVATIVE=1
11 | set COMPLUS_ZapDisable=1
12 | set COMPLUS_NoGuiOnAssert=1
13 |
--------------------------------------------------------------------------------
/utils/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/include/Pal/Rt/ole2.h:
--------------------------------------------------------------------------------
1 | //===--- include/Pal/Rt/ole2.h ----------------------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Dummy ole2.h for non-Windows platforms.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
--------------------------------------------------------------------------------
/include/Pal/Rt/windef.h:
--------------------------------------------------------------------------------
1 | //===--- include/Pal/Rt/windef.h ------------------------- ------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Dummy windef.h for non-Windows platforms.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
--------------------------------------------------------------------------------
/include/Pal/Rt/winerror.h:
--------------------------------------------------------------------------------
1 | //===--- include/Pal/Rt/winerror.h ------------------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Dummy winerror.h for non-Windows platforms.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
--------------------------------------------------------------------------------
/include/Pal/Rt/specstrings.h:
--------------------------------------------------------------------------------
1 | //===--- include/Pal/Rt/specstrings.h ---------------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Dummy specstrings.h for non-Windows platforms.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
--------------------------------------------------------------------------------
/lib/Jit/jitpch.cpp:
--------------------------------------------------------------------------------
1 | //===---- lib/Jit/jitpch.cpp ------------------------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Code portion of precompiled header support.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #include "jitpch.h"
--------------------------------------------------------------------------------
/test/const.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | #title :const.py
4 | #description :
5 | #
6 | # const class does not allow rebinding value to name so that name is constant.
7 | #
8 | #==========================================================================================
9 |
10 | class _const:
11 | class ConstError(TypeError): pass
12 | def __setattr__(self,name,value):
13 | if name in self.__dict__:
14 | message = "Can't rebind const " + name
15 | raise self.ConstError(message)
16 | self.__dict__[name]=value
17 | import sys
18 | sys.modules[__name__]=_const()
19 |
--------------------------------------------------------------------------------
/lib/ObjWriter/.nuget/runtime.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimes": {
3 | "win7-x64": {
4 | "Microsoft.DotNet.ObjectWriter": {
5 | "toolchain.win7-x64.Microsoft.DotNet.ObjectWriter": "1.0.13-prerelease-00001"
6 | }
7 | },
8 | "ubuntu.14.04-x64": {
9 | "Microsoft.DotNet.ObjectWriter": {
10 | "toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter": "1.0.13-prerelease-00001"
11 | }
12 | },
13 | "osx.10.10-x64": {
14 | "Microsoft.DotNet.ObjectWriter": {
15 | "toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter": "1.0.13-prerelease-00001"
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Documentation/index.md:
--------------------------------------------------------------------------------
1 | # LLILC
2 |
3 | ## Introduction
4 | Welcome to LLILC.
5 |
6 | This documentation describes the **internals** of
7 | LLILC, not the **external** use of LLILC. There are no instructions
8 | here on how to use LLILC, only the APIs that make up the software. For usage
9 | instructions, please see the programmer's guide or reference manual.
10 |
11 | ## Caveat
12 | This documentation is generated directly from the source code with doxygen.
13 | Since LLILC is under active development, what you're about to
14 | read is likely out of date! However, it may still be useful since certain portions
15 | of LLILC are very stable.
16 |
--------------------------------------------------------------------------------
/lib/GcInfo/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | get_filename_component(LLILC_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../../include ABSOLUTE)
2 |
3 | include_directories(${LLILC_INCLUDES}/clr
4 | ${LLILC_INCLUDES}/GcInfo
5 | ${LLILC_INCLUDES}/Jit
6 | ${LLILC_INCLUDES}/Pal)
7 |
8 | add_definitions(-DSTANDALONE_BUILD)
9 |
10 | if(CLR_CMAKE_PLATFORM_UNIX)
11 | add_compile_options(-fPIC)
12 | endif(CLR_CMAKE_PLATFORM_UNIX)
13 |
14 | add_llilcjit_library(GcInfo
15 | STATIC
16 | ${CORECLR_GCINFO}/gcinfoencoder.cpp
17 | GcInfoUtil.cpp
18 | GcInfo.cpp
19 | )
20 |
21 | if( NOT LLILC_BUILT_STANDALONE )
22 | add_dependencies(GcInfo intrinsics_gen)
23 | endif()
24 |
--------------------------------------------------------------------------------
/include/Reader/imeta.h:
--------------------------------------------------------------------------------
1 | //===------------------- include/Reader/imeta.h -----------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declares extra information not provided by the jit interface.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef MSIL_READER_IMETA_H
17 | #define MSIL_READER_IMETA_H
18 |
19 | #include "imeta.def"
20 |
21 | #endif // MSIL_READER_IMETA_H
22 |
--------------------------------------------------------------------------------
/lib/Reader/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | get_filename_component(LLILC_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../../include ABSOLUTE)
2 |
3 | include_directories(${LLILC_INCLUDES}/clr
4 | ${LLILC_INCLUDES}/Pal
5 | ${LLILC_INCLUDES}/GcInfo
6 | ${LLILC_INCLUDES}/Reader
7 | ${LLILC_INCLUDES}/Jit)
8 |
9 | set(LLILCJIT_LINK_LIBRARIES GcInfo)
10 |
11 | add_definitions(-DSTANDALONE_BUILD)
12 |
13 | add_llilcjit_library(LLILCReader
14 | abi.cpp
15 | abisignature.cpp
16 | reader.cpp
17 | readerir.cpp
18 | GenIRStubs.cpp
19 | )
20 |
21 | if( NOT LLILC_BUILT_STANDALONE )
22 | add_dependencies(LLILCReader intrinsics_gen)
23 | endif()
24 |
--------------------------------------------------------------------------------
/include/Pal/earlyincludes.h:
--------------------------------------------------------------------------------
1 | //===--- include/Pal/earlyincludes.h ----------------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | //
11 | // Include files that must be included early to avoid interference with
12 | // Windows #defines.
13 | //
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef EARLYINCLUDES_INC
17 | #define EARLYINCLUDES_INC
18 |
19 | #include "llvm/Object/RelocVisitor.h"
20 |
21 | #endif // EARLYINCLUDES_INC
22 |
--------------------------------------------------------------------------------
/include/Jit/jitpch.h:
--------------------------------------------------------------------------------
1 | //===--------------- include/Jit/jitpch.h -----------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Jit precompiled header
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef JIT_PCH_H
17 | #define JIT_PCH_H
18 |
19 | #include "global.h"
20 | #include "LLILCPal.h"
21 |
22 | #if defined(_MSC_VER)
23 | #include
24 | #else
25 | #include
26 | #include
27 | #include "ntimage.h"
28 | #endif
29 |
30 | #include "corjit.h"
31 |
32 | #endif // JIT_PCH_H
33 |
--------------------------------------------------------------------------------
/Documentation/Background.md:
--------------------------------------------------------------------------------
1 | # Background
2 |
3 | LLILC is an Open-Source project that Compiles msIL (.NET) code to native
4 | binary, using the LLVM compiler framework. We pronounce it "lilac". The
5 | project will provide both a JIT ("Just-In-Time") and an AOT ("Ahead-Of-Time")
6 | compiler targeting [CoreCLR](https://github.com/dotnet/coreclr).
7 |
8 | The LLILC LLVM based toolchain is a companion project to the CoreCLR RyuJIT
9 | providing the community with an accessible infrastructure for experimentation
10 | and porting to new targets. Our goal is to make it easy(-ier) to make new
11 | tools or take C# to new platforms. Our initial supported platform is Windows
12 | but we plan to extend support to Linux and Mac in the near term.
13 |
14 | For more background on the .NET Architecture, see its [ECMA Specification](http://www.ecma-international.org/publications/standards/Ecma-335.htm).
15 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00005
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/ObjWriter/.nuget/Microsoft.DotNet.ObjectWriter.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.DotNet.ObjectWriter
5 | 1.0.13-prerelease-00001
6 | Microsoft .NET Object File Generator
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/corert
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Provides object writer to the managed to native code-generator.
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/include/GcInfo/eexcp.h:
--------------------------------------------------------------------------------
1 | //===----------------- include/clr/eexcp.h ----------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Definition of some Exception handling structure definitions
13 | /// used in partially interruptible GC scenarios.
14 | ///
15 | //===----------------------------------------------------------------------===//
16 |
17 | #ifndef __EEXCP_X__
18 | #define __EEXCP_X__
19 |
20 | struct EE_ILEXCEPTION_CLAUSE {
21 | CorExceptionFlag Flags;
22 | DWORD TryStartPC;
23 | DWORD TryEndPC;
24 | DWORD HandlerStartPC;
25 | DWORD HandlerEndPC;
26 | union {
27 | void *TypeHandle;
28 | mdToken ClassToken;
29 | DWORD FilterOffset;
30 | };
31 | };
32 |
33 | #endif // __EEXCP_X__
34 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.win-x64.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.win-x64.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00005
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.win-x86.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.win-x86.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00005
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/ObjWriter/.nuget/toolchain.win7-x64.Microsoft.DotNet.ObjectWriter.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | toolchain.win7-x64.Microsoft.DotNet.ObjectWriter
5 | 1.0.13-prerelease-00001
6 | Microsoft .NET Object File Generator
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/corert
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Provides object writer to the managed to native code-generator.
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.centos.7.1-x64.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.centos.7.1-x64.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.centos.7.1-x86.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.centos.7.1-x86.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.osx.10.11-x64.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.osx.10.11-x64.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.osx.10.11-x86.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.osx.10.11-x86.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.ubuntu.14.04-x64.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.ubuntu.14.04-x64.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.ubuntu.14.04-x86.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.ubuntu.14.04-x86.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.ubuntu.16.04-x64.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.ubuntu.16.04-x64.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.ubuntu.16.04-x86.Microsoft.NETCore.CoreDisTools.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | runtime.ubuntu.16.04-x86.Microsoft.NETCore.CoreDisTools
5 | 1.0.1-prerelease-00002
6 | Microsoft.NETCore Instruction-wise Disassembler
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/coreclr
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Disassembly Tools for CoreCLR
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/ObjWriter/.nuget/toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter
5 | 1.0.13-prerelease-00001
6 | Microsoft .NET Object File Generator
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/corert
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Provides object writer to the managed to native code-generator.
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib/ObjWriter/.nuget/toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter
5 | 1.0.13-prerelease-00001
6 | Microsoft .NET Object File Generator
7 | Microsoft
8 | Microsoft
9 | http://go.microsoft.com/fwlink/?LinkId=329770
10 | https://github.com/dotnet/corert
11 | http://go.microsoft.com/fwlink/?LinkID=288859
12 | true
13 | Provides object writer to the managed to native code-generator.
14 | Initial release
15 | Copyright © Microsoft Corporation
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/include/Jit/global.h:
--------------------------------------------------------------------------------
1 | //===--------------- include/Jit/global.h -----------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Host and target defines.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef JIT_GLOBAL_H
17 | #define JIT_GLOBAL_H
18 |
19 | #if defined(_M_IX86) || defined(__i386__)
20 | #define _TARGET_X86_ 1
21 | #define _HOST_X86_ 1
22 | #elif defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__)
23 | #define _TARGET_X64_ 1
24 | #define _TARGET_AMD64_ 1
25 | #define _HOST_X64_ 1
26 | #define _HOST_AMD64_ 1
27 | #elif defined(_M_ARM) || defined(__arm__)
28 | #define _TARGET_ARM_ 1
29 | #define _HOST_ARM_ 1
30 | #elif defined(_M_ARM64) || defined(__aarch64__)
31 | #define _TARGET_ARM64_ 1
32 | #define _HOST_ARM64_ 1
33 | #endif
34 |
35 | #endif // JIT_GLOBAL_H
36 |
--------------------------------------------------------------------------------
/LICENSE.TXT:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Microsoft Corporation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/CODE_OWNERS.TXT:
--------------------------------------------------------------------------------
1 | The following is a list of owners for different areas of the LLILC code.
2 | Each of the owners is responsible for ensuring that changes in their areas
3 | are reviewed, either by themselves or by someone they designate, in
4 | addition to being the final word for the architecture and content of an area.
5 |
6 | List sorted by last name and the fields are Name (N), GitHub user account (G),
7 | Description (D).
8 |
9 | Note: If you don't find the area in the below list, or you have a general
10 | question, send a message to Andy Ayers and Russell Hadley. They can ensure
11 | that the question gets forwarded to the right person or answer it themselves.
12 |
13 | N: Andy Ayers
14 | G: AndyAyersMS
15 | D: JIT context/multi-threading, MSIL types in bitcode, test harness,
16 | everything else.
17 |
18 | N: Pat Gavlin
19 | G: pgavlin
20 | D: CLR/Target ABI processing.
21 |
22 | N: Russell C Hadley
23 | G: Russell Hadley
24 | D: JIT infrastructure, everything else.
25 |
26 | N: Eugene Rozenfeld
27 | G: erozenfeld
28 | D: MSIL reader.
29 |
30 | N: Swaroop Sridhar
31 | G: swaroop-sridhar
32 | D: CLR GC support
33 |
34 | N: Joseph Tremoulet
35 | G: JosephTremoulet
36 | D: CLR EH support.
37 |
--------------------------------------------------------------------------------
/Documentation/Welcome.md:
--------------------------------------------------------------------------------
1 | # Welcome to LLILC
2 |
3 | We pronounce it 'lilac'. LLILC is comprised of a JIT and AOT compiler for C#.
4 | They work with the dotnet [CoreCLR](https://github.com/dotnet/coreclr) and
5 | will complement the current CoreCLR JIT by providing an alternate code
6 | generator built on the LLVM infrastructure.
7 |
8 | ## Developer Guides
9 |
10 | * [Background](Background.md)
11 | * [FAQ](llilc-faq.md)
12 | * [Getting Started for Windows](Getting-Started-For-Windows.md)
13 | * [Getting Started For Linux and OS X](Getting-Started-For-Linux-and-OS-X.md)
14 | * [Testing](Testing.md)
15 | * [Debugging](Debugging.md)
16 | * [Contribution Guide](Contributing.md)
17 | * [Areas To Contribute](Areas-To-Contribute.md)
18 | * [LLILC Coding Conventions and Commenting Style](llilc-Coding-Conventions-and-Commenting-Style.md)
19 |
20 | ## Architecture
21 |
22 | * [LLILC Architecture Overview](llilc-arch.md)
23 |
24 | ### Supporting managed constructs in LLVM
25 | * [LLILC MSIL Reader](llilc-reader.md)
26 | * [GC Support in LLILC](llilc-gc.md)
27 | * [EH Support in LLILC](llilc-jit-eh.md)
28 |
29 | ## Other Resources
30 | * [dotnet/CoreCLR](https://github.com/dotnet/coreclr)
31 | * [dotnet/CoreFx](https://github.com/dotnet/corefx)
32 |
--------------------------------------------------------------------------------
/include/clr/pshpack2.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft. All rights reserved.
3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 | //
5 | //
6 |
7 | //
8 | // ===========================================================================
9 | // File: pshpack2.h
10 | //
11 | // ===========================================================================
12 | /*++
13 |
14 | Abstract:
15 |
16 | This file turns 2 byte packing of structures on. (That is, it disables
17 | automatic alignment of structure fields.) An include file is needed
18 | because various compilers do this in different ways. For Microsoft
19 | compatible compilers, this files uses the push option to the pack pragma
20 | so that the poppack.h include file can restore the previous packing
21 | reliably.
22 |
23 | The file poppack.h is the complement to this file.
24 |
25 | --*/
26 |
27 | #if ! (defined(lint) || defined(RC_INVOKED))
28 | #if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
29 | #pragma warning(disable:4103)
30 | #if !(defined( MIDL_PASS )) || defined( __midl )
31 | #pragma pack(push,2)
32 | #else
33 | #pragma pack(2)
34 | #endif
35 | #else
36 | #pragma pack(2)
37 | #endif
38 | #endif // ! (defined(lint) || defined(RC_INVOKED))
39 |
--------------------------------------------------------------------------------
/include/clr/pshpack1.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft. All rights reserved.
3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 | //
5 | //
6 |
7 | //
8 | // ===========================================================================
9 | // File: pshpack1.h
10 | //
11 | // ===========================================================================
12 |
13 | /*++
14 |
15 | Abstract:
16 |
17 | This file turns 1 byte packing of structures on. (That is, it disables
18 | automatic alignment of structure fields.) An include file is needed
19 | because various compilers do this in different ways. For Microsoft
20 | compatible compilers, this files uses the push option to the pack pragma
21 | so that the poppack.h include file can restore the previous packing
22 | reliably.
23 |
24 | The file poppack.h is the complement to this file.
25 |
26 | --*/
27 |
28 | #if ! (defined(lint) || defined(RC_INVOKED))
29 | #if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
30 | #pragma warning(disable:4103)
31 | #if !(defined( MIDL_PASS )) || defined( __midl )
32 | #pragma pack(push,1)
33 | #else
34 | #pragma pack(1)
35 | #endif
36 | #else
37 | #pragma pack(1)
38 | #endif
39 | #endif // ! (defined(lint) || defined(RC_INVOKED))
40 |
--------------------------------------------------------------------------------
/include/clr/pshpack4.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft. All rights reserved.
3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 | //
5 | //
6 |
7 | //
8 | // ===========================================================================
9 | // File: pshpack4.h
10 | //
11 | // ===========================================================================
12 |
13 | /*++
14 |
15 | Abstract:
16 |
17 | This file turns 4 byte packing of structures on. (That is, it disables
18 | automatic alignment of structure fields.) An include file is needed
19 | because various compilers do this in different ways. For Microsoft
20 | compatible compilers, this files uses the push option to the pack pragma
21 | so that the poppack.h include file can restore the previous packing
22 | reliably.
23 |
24 | The file poppack.h is the complement to this file.
25 |
26 | --*/
27 |
28 | #if ! (defined(lint) || defined(RC_INVOKED))
29 | #if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
30 | #pragma warning(disable:4103)
31 | #if !(defined( MIDL_PASS )) || defined( __midl )
32 | #pragma pack(push,4)
33 | #else
34 | #pragma pack(4)
35 | #endif
36 | #else
37 | #pragma pack(4)
38 | #endif
39 | #endif // ! (defined(lint) || defined(RC_INVOKED))
40 |
--------------------------------------------------------------------------------
/include/clr/pshpack8.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft. All rights reserved.
3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 | //
5 | //
6 |
7 | //
8 | // ===========================================================================
9 | // File: pshpack8.h
10 | //
11 | // ===========================================================================
12 |
13 | /*++
14 |
15 | Abstract:
16 |
17 | This file turns 8 byte packing of structures on. (That is, it disables
18 | automatic alignment of structure fields.) An include file is needed
19 | because various compilers do this in different ways. For Microsoft
20 | compatible compilers, this files uses the push option to the pack pragma
21 | so that the poppack.h include file can restore the previous packing
22 | reliably.
23 |
24 | The file poppack.h is the complement to this file.
25 |
26 | --*/
27 |
28 | #if ! (defined(lint) || defined(RC_INVOKED))
29 | #if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
30 | #pragma warning(disable:4103)
31 | #if !(defined( MIDL_PASS )) || defined( __midl )
32 | #pragma pack(push,8)
33 | #else
34 | #pragma pack(8)
35 | #endif
36 | #else
37 | #pragma pack(8)
38 | #endif
39 | #endif // ! (defined(lint) || defined(RC_INVOKED))
40 |
--------------------------------------------------------------------------------
/test/llilc_roslyn_stage.cmd:
--------------------------------------------------------------------------------
1 | REM Usage: llilc_roslyn_stage.cmd workspace buildsubdir stagedir
2 | REM
3 | REM Will first delete (if present) and then create %workspace%/roslyn/%stagedir%
4 | REM directory and set it up as the directory
5 | REM from which Roslyn will run on CoreClr, with LLILC as JIT.
6 | REM buildsubdir is the subdirectory of the workspace where LLVM (and LLILC) were built.
7 |
8 | setlocal
9 | set WORKSPACE=%1
10 | set buildsubdir=%2
11 | set buildtype=%3
12 | set stagedir=%4
13 | cd %WORKSPACE%
14 | call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x86
15 | echo on
16 | cd roslyn
17 | if exist %stagedir%/ rd /s /q %stagedir%
18 | mkdir %stagedir%
19 | xcopy /y %buildsubdir%\bin\%buildtype%\llilcjit.dll %stagedir%
20 | xcopy /S /Q Binaries\Debug\core-clr\* %stagedir%
21 | xcopy /S /Q /Y %WORKSPACE%\coreclr\bin\Product\Windows_NT.x64.Debug\* %stagedir%
22 | set command=python %WORKSPACE%\llvm\tools\llilc\test\llilc_run.py -c %WORKSPACE%\roslyn\%stagedir% -r corerun.exe /v -a %WORKSPACE%\roslyn\%stagedir%\csc.exe -- %%*
23 | echo %command% > %stagedir%\runcsc.cmd
24 | echo exit /b %%ERRORLEVEL%% >> %stagedir%\runcsc.cmd
25 |
26 | rd /s /q Binaries
27 | msbuild /m /v:d /p:CSCTOOLPATH=%WORKSPACE%\roslyn\%stagedir% /p:CSCTOOLEXE=runcsc.cmd /p:UseRoslynAnalyzers=false src/Compilers/CSharp/CscCore/CscCore.csproj
28 | endlocal
29 |
--------------------------------------------------------------------------------
/include/clr/poppack.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) Microsoft. All rights reserved.
3 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 | //
5 | //
6 |
7 | //
8 | // ===========================================================================
9 | // File: poppack.h
10 | //
11 | // ===========================================================================
12 | /*
13 | Abstract:
14 |
15 | This file turns packing of structures off. (That is, it enables
16 | automatic alignment of structure fields.) An include file is needed
17 | because various compilers do this in different ways.
18 |
19 | poppack.h is the complement to pshpack?.h. An inclusion of poppack.h
20 | MUST ALWAYS be preceded by an inclusion of one of pshpack?.h, in one-to-one
21 | correspondence.
22 |
23 | For Microsoft compatible compilers, this file uses the pop option
24 | to the pack pragma so that it can restore the previous saved by the
25 | pshpack?.h include file.
26 |
27 | */
28 |
29 | #if ! (defined(lint) || defined(RC_INVOKED))
30 | #if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
31 | #pragma warning(disable:4103)
32 | #if !(defined( MIDL_PASS )) || defined( __midl )
33 | #pragma pack(pop)
34 | #else
35 | #pragma pack()
36 | #endif
37 | #else
38 | #pragma pack()
39 | #endif
40 | #endif // ! (defined(lint) || defined(RC_INVOKED))
41 |
--------------------------------------------------------------------------------
/lib/ObjWriter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project(objwriter)
2 |
3 | include_directories(${LLVM_INCLUDE_DIRS})
4 | include_directories(${CORECLR_INCLUDE})
5 | add_definitions(${LLVM_DEFINITIONS})
6 |
7 | if (WIN32)
8 | # Create .def file containing a list of exports preceeded by
9 | # 'EXPORTS'. The file "objwriter.exports" already contains the list, so we
10 | # massage it into the correct format here to create "objwriter.exports.def".
11 | set(OBJWRITER_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/objwriter.exports.def)
12 | set(OBJWRITER_EXPORTS_DEF_TEMP ${OBJWRITER_EXPORTS_DEF}.txt)
13 | file(READ "objwriter.exports" exports_list)
14 | file(WRITE ${OBJWRITER_EXPORTS_DEF_TEMP} "LIBRARY OBJWRITER\n")
15 | file(APPEND ${OBJWRITER_EXPORTS_DEF_TEMP} "EXPORTS\n")
16 | file(APPEND ${OBJWRITER_EXPORTS_DEF_TEMP} ${exports_list})
17 | # Copy the file only if it has changed.
18 | execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
19 | ${OBJWRITER_EXPORTS_DEF_TEMP} ${OBJWRITER_EXPORTS_DEF})
20 | endif()
21 |
22 | # Now build our tools
23 | add_library(objwriter
24 | SHARED
25 | objwriter.cpp
26 | ${OBJWRITER_EXPORTS_DEF}
27 | )
28 |
29 | # Find the libraries that correspond to the LLVM components
30 | # that we wish to use
31 |
32 | llvm_map_components_to_libnames(llvm_libs
33 | ${LLVM_TARGETS_TO_BUILD}
34 | )
35 |
36 | # Link against LLVM libraries
37 | target_link_libraries(objwriter
38 | ${llvm_libs})
39 |
--------------------------------------------------------------------------------
/lib/ObjWriter/jitDebugInfo.h:
--------------------------------------------------------------------------------
1 | #ifndef JIT_DEBUG_INFO_H
2 | #define JIT_DEBUG_INFO_H
3 |
4 | typedef unsigned int DWORD;
5 | #define _TARGET_AMD64_ 1
6 |
7 | #include "cordebuginfo.h"
8 | #include "cvconst.h"
9 | #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
10 |
11 | struct DebugLocInfo {
12 | int NativeOffset;
13 | int FileId;
14 | int LineNumber;
15 | int ColNumber;
16 | };
17 |
18 | struct DebugVarInfo {
19 | std::string Name;
20 | int TypeIndex;
21 | bool IsParam;
22 | std::vector Ranges;
23 |
24 | DebugVarInfo() {}
25 | DebugVarInfo(char *ArgName, int ArgTypeIndex, bool ArgIsParam)
26 | : Name(ArgName), TypeIndex(ArgTypeIndex), IsParam(ArgIsParam) {}
27 | };
28 |
29 | typedef unsigned short CVRegMapping;
30 |
31 | #define CVREGDAT(p2, cv) cv
32 |
33 | const CVRegMapping cvRegMapAmd64[] = {
34 | CVREGDAT(REGNUM_RAX, CV_AMD64_RAX), CVREGDAT(REGNUM_RCX, CV_AMD64_RCX),
35 | CVREGDAT(REGNUM_RDX, CV_AMD64_RDX), CVREGDAT(REGNUM_RBX, CV_AMD64_RBX),
36 | CVREGDAT(REGNUM_RSP, CV_AMD64_RSP), CVREGDAT(REGNUM_RBP, CV_AMD64_RBP),
37 | CVREGDAT(REGNUM_RSI, CV_AMD64_RSI), CVREGDAT(REGNUM_RDI, CV_AMD64_RDI),
38 | CVREGDAT(REGNUM_R8, CV_AMD64_R8), CVREGDAT(REGNUM_R9, CV_AMD64_R9),
39 | CVREGDAT(REGNUM_R10, CV_AMD64_R10), CVREGDAT(REGNUM_R11, CV_AMD64_R11),
40 | CVREGDAT(REGNUM_R12, CV_AMD64_R12), CVREGDAT(REGNUM_R13, CV_AMD64_R13),
41 | CVREGDAT(REGNUM_R14, CV_AMD64_R14), CVREGDAT(REGNUM_R15, CV_AMD64_R15)};
42 |
43 | #endif // JIT_DEBUG_INFO_H
44 |
--------------------------------------------------------------------------------
/include/Reader/gverify.h:
--------------------------------------------------------------------------------
1 | //===------------------- include/Reader/gverify.h ---------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declares data structures useful for MSIL bytecode verification.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef MSIL_READER_GVERIFY_H
17 | #define MSIL_READER_GVERIFY_H
18 |
19 | #include "vtypeinfo.h"
20 |
21 | class FlowGraphNode;
22 |
23 | // global verification structures
24 | typedef struct {
25 | FlowGraphNode *Block;
26 | int32_t TosIndex;
27 | int32_t SsaIndex;
28 | } TOSTemp;
29 |
30 | struct TagGlobalVerifyData;
31 | typedef struct TagGlobalVerifyData GlobalVerifyData;
32 |
33 | enum InitState {
34 | ThisUnreached = -1,
35 | ThisUnInit = 0,
36 | ThisInited = 1,
37 | ThisInconsistent = 2,
38 | ThisEHReached = 3
39 | };
40 |
41 | struct TagGlobalVerifyData {
42 | int32_t MinStack;
43 | int32_t MaxStack;
44 | int32_t NetStack;
45 | int32_t TOSTempsCount;
46 | TOSTemp *TOSTemps;
47 | int32_t SsaBase;
48 |
49 | int32_t StkDepth;
50 | VerType *TiStack;
51 | bool IsOnWorklist, BlockIsBad;
52 | GlobalVerifyData *WorklistPrev, *WorklistNext;
53 | FlowGraphNode *Block;
54 | InitState ThisInitialized;
55 | bool ContainsCtorCall;
56 | };
57 |
58 | #endif // MSIL_READER_GVERIFY_H
59 |
--------------------------------------------------------------------------------
/include/Reader/imeta.def:
--------------------------------------------------------------------------------
1 | //===------------------- include/Reader/imeta.def ----------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declares constants useful for imeta.h interface
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #define mdtJitHelper 0x73000000
17 | #define mdtInterfaceOffset 0x74000000
18 | #define mdtCodeOffset 0x75000000
19 | #define mdtSyncHandle 0x76000000
20 | #define mdtVarArgsHandle 0x77000000
21 | #define mdtPInvokeCalliHandle 0x78000000
22 | #define mdtIBCProfHandle 0x79000000
23 |
24 | // When returning a struct with gc through a hidden param, we
25 | // call the ASSIGN_STRUCT helper and we need a dummy token to pass
26 | // around with the class handle we got from the method sig.
27 | #define mdtMBReturnHandle 0x7A000000
28 | #define mdtGSCookie 0x7B000000
29 |
30 | #define mdtJMCHandle 0x7C000000
31 | #define mdtCaptureThreadGlobal 0x7D000000
32 | #define mdtModuleID 0x7E000000
33 |
34 | // For instantiation parameters where we have a handle, but no token
35 | #define mdtMethodHandle 0x7F000000
36 | #define mdtClassHandle 0x80000000
37 |
38 | #define mdtVarArgsSigHandle 0x81000000
39 | #define mdtVarArgsMDHandle 0x82000000
40 | #define mdtVarArgsMSHandle 0x83000000
41 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project(coredistools)
2 |
3 | get_filename_component(LLILC_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../../include ABSOLUTE)
4 |
5 | include_directories(${LLVM_INCLUDE_DIRS}
6 | ${CORECLR_INCLUDE})
7 |
8 | add_definitions(${LLVM_DEFINITIONS})
9 |
10 | if (WIN32)
11 | # Create .def file containing a list of exports preceeded by
12 | # 'EXPORTS'. The file "coredistools.exports" already contains the list,
13 | # so we massage it into the correct format here to create
14 | # "coredistools.exports.def".
15 | set(COREDISTOOLS_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/coredistools.exports.def)
16 | set(COREDISTOOLS_EXPORTS_DEF_TEMP ${COREDISTOOLS_EXPORTS_DEF}.txt)
17 | file(READ "coredistools.exports" exports_list)
18 | file(WRITE ${COREDISTOOLS_EXPORTS_DEF_TEMP} "LIBRARY COREDISTOOLS\n")
19 | file(APPEND ${COREDISTOOLS_EXPORTS_DEF_TEMP} "EXPORTS\n")
20 | file(APPEND ${COREDISTOOLS_EXPORTS_DEF_TEMP} ${exports_list})
21 | # Copy the file only if it has changed.
22 | execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
23 | ${COREDISTOOLS_EXPORTS_DEF_TEMP} ${COREDISTOOLS_EXPORTS_DEF})
24 | endif()
25 |
26 | # Now build our tools
27 | add_library(coredistools
28 | SHARED
29 | coredistools.cpp
30 | ${COREDISTOOLS_EXPORTS_DEF}
31 | )
32 |
33 | # Find the libraries that correspond to the LLVM components
34 | # that we wish to use
35 | llvm_map_components_to_libnames(llvm_libs
36 | ${LLVM_TARGETS_TO_BUILD}
37 | )
38 |
39 | # Link against LLVM libraries
40 | target_link_libraries(coredistools
41 | ${llvm_libs})
42 |
43 | # Output the export header corresponding to the coredistools library
44 | add_custom_command(TARGET coredistools POST_BUILD
45 | COMMAND ${CMAKE_COMMAND} -E copy_if_different
46 | ${CORECLR_INCLUDE}/coredistools.h
47 | $/include/coredistools.h)
48 |
--------------------------------------------------------------------------------
/lib/CoreDisTools/.nuget/runtime.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimes": {
3 | "win-x64": {
4 | "Microsoft.NETCore.CoreDisTools": {
5 | "runtime.win-x64.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00005"
6 | }
7 | },
8 | "ubuntu.14.04-x64": {
9 | "Microsoft.NETCore.CoreDisTools": {
10 | "runtime.ubuntu.14.04-x64.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
11 | }
12 | },
13 | "ubuntu.16.04-x64": {
14 | "Microsoft.NETCore.CoreDisTools": {
15 | "runtime.ubuntu.16.04-x64.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
16 | }
17 | },
18 | "centos.7.1-x64": {
19 | "Microsoft.NETCore.CoreDisTools": {
20 | "runtime.centos.7.1-x64.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
21 | }
22 | },
23 | "osx.10.11-x64": {
24 | "Microsoft.NETCore.CoreDisTools": {
25 | "runtime.osx.10.11-x64.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
26 | }
27 | },
28 | "win-x86": {
29 | "Microsoft.NETCore.CoreDisTools": {
30 | "runtime.win-x86.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00005"
31 | }
32 | },
33 | "ubuntu.14.04-x86": {
34 | "Microsoft.NETCore.CoreDisTools": {
35 | "runtime.ubuntu.14.04-x86.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
36 | }
37 | },
38 | "ubuntu.16.04-x86": {
39 | "Microsoft.NETCore.CoreDisTools": {
40 | "runtime.ubuntu.16.04-x86.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
41 | }
42 | },
43 | "centos.7.1-x86": {
44 | "Microsoft.NETCore.CoreDisTools": {
45 | "runtime.centos.7.1-x86.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
46 | }
47 | },
48 | "osx.10.11-x86": {
49 | "Microsoft.NETCore.CoreDisTools": {
50 | "runtime.osx.10.11-x86.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00002"
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/include/clr/misc.h:
--------------------------------------------------------------------------------
1 | //===----------------- include/clr/misc.h -----------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Miscellaneous helper functions defined in Windows CRT
13 | /// Explicitly defined here for use in other platforms.
14 | ///
15 | //===----------------------------------------------------------------------===//
16 |
17 | #ifndef _MISC_H_
18 | #define _MISC_H_
19 |
20 | #if !defined(_MSC_VER)
21 |
22 | //-- Bit Manipulation --
23 |
24 | #ifndef _rotl
25 | inline unsigned int __cdecl _rotl(unsigned int value, int shift)
26 | {
27 | unsigned int retval = 0;
28 |
29 | shift &= 0x1f;
30 | retval = (value << shift) | (value >> (sizeof(int)* 8 - shift));
31 | return retval;
32 | }
33 | #endif
34 |
35 | #ifndef _rotr
36 | inline unsigned int __cdecl _rotr(unsigned int value, int shift)
37 | {
38 | unsigned int retval;
39 |
40 | shift &= 0x1f;
41 | retval = (value >> shift) | (value << (sizeof(int)* 8 - shift));
42 | return retval;
43 | }
44 | #endif
45 |
46 | //-- Memory move/copy/set/cmp operations
47 |
48 | #define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length)))
49 | #define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
50 | #define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
51 | #define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
52 | #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
53 |
54 | #define MoveMemory RtlMoveMemory
55 | #define CopyMemory RtlCopyMemory
56 | #define FillMemory RtlFillMemory
57 | #define ZeroMemory RtlZeroMemory
58 |
59 |
60 | #endif // defined(MSC_VER)
61 | #endif // _MISC_H_
62 |
--------------------------------------------------------------------------------
/include/GcInfo/Target.h:
--------------------------------------------------------------------------------
1 | //===---- include/gcinfo/target.h -------------------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Target specific definitions for GCInfo generation
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef GCINFO_TARGET_H
17 | #define GCINFO_TARGET_H
18 |
19 | #include "global.h"
20 | #include "corinfo.h"
21 |
22 | #if (defined(_TARGET_X86_) || defined(_TARGET_X64_) || \
23 | defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_))
24 |
25 | // Identify the frame-pointer register number
26 |
27 | #if defined(_TARGET_X86_)
28 | #define REGNUM_FPBASE ICorDebugInfo::RegNum::REGNUM_EBP
29 | #elif (defined(_TARGET_AMD64_) || defined(_TARGET_X64_))
30 | #define REGNUM_FPBASE ICorDebugInfo::RegNum::REGNUM_RBP
31 | #elif defined(_TARGET_ARM64_)
32 | #define REGNUM_FPBASE ICorDebugInfo::RegNum::REGNUM_FP
33 | #endif
34 |
35 | #if (defined(_TARGET_X86_) || defined(_TARGET_X64_) || defined(_TARGET_AMD64_))
36 |
37 | // Define encodings for DWARF registers
38 | // Size variants (ex: AL,AH,AX,EAX,RAX) all get the same Dwarf register number
39 |
40 | #define DW_RAX 0
41 | #define DW_RBX 3
42 | #define DW_RCX 2
43 | #define DW_RDX 1
44 | #define DW_RSI 4
45 | #define DW_RDI 5
46 | #define DW_RBP 6
47 | #define DW_RSP 7
48 | #define DW_RIP 16
49 | #define DW_R8 8
50 | #define DW_R9 9
51 | #define DW_R10 10
52 | #define DW_R11 11
53 | #define DW_R12 12
54 | #define DW_R13 13
55 | #define DW_R14 14
56 | #define DW_R15 15
57 |
58 | #define DW_STACK_POINTER DW_RSP
59 |
60 | #elif defined(_TARGET_ARM64_)
61 |
62 | #define DW_FRAME_POINTER 29
63 | #define DW_STACK_POINTER 31
64 |
65 | #endif
66 |
67 | #else
68 | #error GCTables not implemented for this target
69 | #endif // defined(_TARGET_X86_ || _TARGET_X64_ || _TARGET_AMD64_ ||
70 | // _TARGET_ARM64_)
71 |
72 | #endif // GCINFO_TARGET_H
73 |
--------------------------------------------------------------------------------
/test/llilc_hook.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Title :llilc_hook.py
4 | # Description :
5 | #
6 | # Hook is called from runjs which during its build step requires llilc specific
7 | # setup. Currently all that is required is just a simple copy of llilcjit.dll.
8 | # The script requires two arguments to function the path of llilcjit.dll and the
9 | # bin path to copy into.
10 | #
11 | # Usage: llilc_hook.py
12 | #
13 | ################################################################################
14 |
15 | import os
16 | import shutil
17 | import sys
18 |
19 | ################################################################################
20 |
21 | def copydll(llilc_dll, drop_path):
22 | print "Copying %s into %s." % (llilc_dll, drop_path)
23 |
24 | shutil.copy2(llilc_dll, drop_path)
25 |
26 | print "Copied successfully."
27 |
28 | def handle_args(args):
29 | if (len(args) < 2):
30 | print "Incorrect number of arguments."
31 |
32 | print_usage()
33 |
34 | return None, None
35 |
36 | if (os.path.isfile(args[1]) is not True):
37 | print "lliljit.dll must be a valid file."
38 |
39 | print_usage()
40 |
41 | return None, None
42 |
43 | if (os.path.isdir(args[2]) is not True):
44 | print "run.js bin must be a valid directory."
45 |
46 | print_usage()
47 |
48 | return None, None
49 |
50 | return args[1], args[2]
51 |
52 | def print_usage():
53 |
54 | # User has run the script incorrectly
55 |
56 | print "Hook to copy llilcdll.jit during runjs run."
57 | print ""
58 | print "Usage: llilcHook.py "
59 | print ""
60 |
61 | if __name__ == "__main__":
62 |
63 | print "Starting LLILC Hook: Last Updated - 26-Jul-15"
64 |
65 | # Expect two arguments, the first is the path to
66 | # llilc and the other is the directory to copy into.
67 |
68 | llilc_path, drop_path = handle_args(sys.argv)
69 |
70 | if (llilc_path is None or drop_path is None):
71 | sys.exit(-1)
72 |
73 | # Copy the dll
74 | copydll(llilc_path, drop_path)
75 |
--------------------------------------------------------------------------------
/include/Jit/compiler.h:
--------------------------------------------------------------------------------
1 | //===--------------- include/Jit/compiler.h ---------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declaration of the compiler functor used in the ORC infrastructure
13 | /// to compile a module.
14 | ///
15 | //===----------------------------------------------------------------------===//
16 |
17 | #ifndef COMPILER_H
18 | #define COMPILER_H
19 |
20 | #include "GcInfo.h"
21 | #include "LLILCJit.h"
22 | #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
23 | #include "llvm/IR/LegacyPassManager.h"
24 | #include "llvm/MC/MCContext.h"
25 | #include "llvm/Object/ObjectFile.h"
26 | #include "llvm/Target/TargetMachine.h"
27 |
28 | namespace llvm {
29 | namespace orc {
30 |
31 | /// \brief Default compile functor: Takes a single IR module and returns an
32 | /// ObjectFile.
33 | class LLILCCompiler {
34 | public:
35 | /// \brief Construct a simple compile functor with the given target.
36 | LLILCCompiler(TargetMachine &TM) : TM(TM) {}
37 |
38 | /// \brief Compile a Module to an ObjectFile.
39 | object::OwningBinary operator()(Module &M) const {
40 | SmallVector ObjBufferSV;
41 | raw_svector_ostream ObjStream(ObjBufferSV);
42 |
43 | legacy::PassManager PM;
44 | MCContext *Ctx;
45 | if (TM.addPassesToEmitMC(PM, Ctx, ObjStream))
46 | llvm_unreachable("Target does not support MC emission.");
47 | PM.add(new GcInfoRecorder());
48 | PM.run(M);
49 | std::unique_ptr ObjBuffer(
50 | new ObjectMemoryBuffer(std::move(ObjBufferSV)));
51 | ErrorOr> Obj =
52 | object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
53 | // TODO: Actually report errors helpfully.
54 | typedef object::OwningBinary OwningObj;
55 | if (Obj)
56 | return OwningObj(std::move(*Obj), std::move(ObjBuffer));
57 | return OwningObj(nullptr, nullptr);
58 | }
59 |
60 | private:
61 | TargetMachine &TM;
62 | };
63 | } // namespace orc
64 | } // namespace llvm
65 | #endif // COMPILER_H
66 |
--------------------------------------------------------------------------------
/Documentation/Contributing.md:
--------------------------------------------------------------------------------
1 | # Contribution Guide
2 |
3 | ## Workflow
4 | We follow the standard [GitHub workflow](https://guides.github.com/introduction/flow/).
5 | We like to track ongoing work using GitHub issues as described in the
6 | [developer workflow document](Developer-Workflow.md).
7 | - To submit changes, please create a personal fork of the LLILC repo, push
8 | your changes there, and issue a pull request to merge those changes into
9 | the master branch of the main repository.
10 | - Please be sure to perform the appropriate [formatting](#coding-conventions-and-formatting)
11 | and [testing](#testing) as described below before submitting your pull
12 | request.
13 | - Whenever possible, please divide any changes you want to make into a
14 | series of small, incremental changes that can be submitted and reviewed
15 | independently. Doing so will
16 | - Make the code easier to review (allowing for higher quality review
17 | feedback)
18 | - Keep your work aligned with LLILC's direction and architecture along
19 | the way (avoiding wasted time pursuing a direction that ultimately
20 | gets abandoned)
21 | - Spare you the pain of keeping large outstanding changes up-to-date
22 | with tip-of-tree
23 | - Occasionally we'll deviate from this model and use long-lived branches,
24 | which follow [another workflow](Long-Running-Branch-Workflow.md).
25 |
26 | ## Coding Conventions and Formatting
27 | Any code being submitted must be formatted per the instructions in the
28 | [code formatting document](Code-Formatting.md). We follow LLVM's coding
29 | conventions, as described in our [coding conventions document](llilc-Coding-Conventions-and-Commenting-Style.md).
30 |
31 | The clang-format and clang-tidy exes used in the lab are generated nightly
32 | and can be downloaded for local use:
33 | [here for clang-format](http://dotnet-ci.cloudapp.net/view/dotnet_llilc/job/dotnet_llilc_code_formatter_drop/lastSuccessfulBuild/Azure/processDownloadRequest/build/Release/bin/clang-format.exe)
34 | and [here for clang-tidy](http://dotnet-ci.cloudapp.net/view/dotnet_llilc/job/dotnet_llilc_code_formatter_drop/lastSuccessfulBuild/Azure/processDownloadRequest/build/Release/bin/clang-tidy.exe).
35 |
36 | ## Testing
37 | The [test harness document](Testing.md) describes the tests we expect to be
38 | run for each submission and how to run them.
39 |
40 | ## Open Areas
41 | Looking for an area to contribute to? See our [list of open areas](Areas-To-Contribute.md).
42 |
--------------------------------------------------------------------------------
/lib/Jit/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | get_filename_component(LLILC_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../../include ABSOLUTE)
2 |
3 | include_directories(${LLILC_INCLUDES}/clr
4 | ${LLILC_INCLUDES}/Pal
5 | ${LLILC_INCLUDES}/GcInfo
6 | ${LLILC_INCLUDES}/Jit
7 | ${LLILC_INCLUDES}/Reader)
8 |
9 | set(LLVM_LINK_COMPONENTS
10 | Analysis
11 | CodeGen
12 | Core
13 | DebugInfoDWARF
14 | ExecutionEngine
15 | IPO
16 | IRReader
17 | OrcJIT
18 | MC
19 | Support
20 | native
21 | )
22 |
23 | set(LLILCJIT_LINK_LIBRARIES LLILCReader GcInfo)
24 |
25 | if (WIN32)
26 | # Create .def file containing a list of exports preceeded by
27 | # 'EXPORTS'. The file "LLILCJit.exports" already contains the list, so we
28 | # massage it into the correct format here to create "LLILCJit.exports.def".
29 | set(LLILCJIT_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/LLILCJit.exports.def)
30 | set(LLILCJIT_EXPORTS_DEF_TEMP ${LLILCJIT_EXPORTS_DEF}.txt)
31 | file(READ "LLILCJit.exports" exports_list)
32 | file(WRITE ${LLILCJIT_EXPORTS_DEF_TEMP} "LIBRARY LLILCJIT\n")
33 | file(APPEND ${LLILCJIT_EXPORTS_DEF_TEMP} "EXPORTS\n")
34 | file(APPEND ${LLILCJIT_EXPORTS_DEF_TEMP} ${exports_list})
35 |
36 | # Copy the file only if it has changed.
37 | execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
38 | ${LLILCJIT_EXPORTS_DEF_TEMP} ${LLILCJIT_EXPORTS_DEF})
39 |
40 | set(SHARED_LIB_SOURCES ${SOURCES} ${LLILCJIT_EXPORTS_DEF})
41 |
42 | # For windows we need to specify the CoreCLR environment
43 | set(LLILC_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}-coreclr")
44 | else()
45 | if (UNIX)
46 | set(LLILCJIT_LINK_LIBRARIES ${LLILCJIT_LINK_LIBRARIES} coreclr)
47 | endif()
48 |
49 | set(SHARED_LIB_SOURCES ${SOURCES})
50 |
51 | # For non-windows we can use the default triple for now
52 | set(LLILC_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}")
53 | endif()
54 |
55 | add_definitions(-DSTANDALONE_BUILD)
56 |
57 | message(STATUS "LLILC_TARGET_TRIPLE is ${LLILC_TARGET_TRIPLE}")
58 | add_definitions(-DLLILC_TARGET_TRIPLE="${LLILC_TARGET_TRIPLE}")
59 |
60 | set(LLVM_EXPORTED_SYMBOL_FILE ${LLILCJIT_EXPORTS_DEF})
61 |
62 | add_llilcjit_library(
63 | llilcjit
64 | SHARED
65 | jitpch.cpp
66 | LLILCJit.cpp
67 | EEMemoryManager.cpp
68 | jitoptions.cpp
69 | utility.cpp
70 | ${LLILCJIT_EXPORTS_DEF}
71 | )
72 |
73 | add_dependencies(llilcjit LLILCReader GcInfo)
74 |
75 | target_link_libraries(
76 | llilcjit
77 | PRIVATE
78 | ${LLILCJIT_LINK_LIBRARIES}
79 | )
80 |
--------------------------------------------------------------------------------
/Documentation/Getting-Started-For-Linux-and-OS-X.md:
--------------------------------------------------------------------------------
1 | # Getting Started for Linux and OS X
2 |
3 | ## Caveats
4 |
5 | Support for LLILC on Linux and OS X is still in its early stages. While the
6 | instructions below should get you up and running, the workflow is a bit rough
7 | around the edges and there are certainly holes with respect to what is
8 | supported. The most obvious missing piece is that without following the steps
9 | on the [CoreCLR wiki](https://github.com/dotnet/coreclr/wiki/Building-and-Running-CoreCLR-on-Linux)
10 | to obtain a version of mscorlib that is functional on these platforms, there
11 | is no way to run or test the output of the LLILC build.
12 |
13 | ## Prerequisites
14 |
15 | The prerequisites for building LLILC on Linux and OS X are the same as the
16 | [prerequisites for building LLVM](http://llvm.org/docs/GettingStarted.html#software)
17 | with CMake unioned with the prerequisites for building [CoreCLR](https://github.com/dotnet/coreclr).
18 |
19 | * [GCC](http://gcc.gnu.org) >= 4.7.0
20 | * [Clang](http://clang.llvm.org/) >= 3.5.0
21 | * [Python](http://python.org) >= 2.7
22 | * [CMake](http://cmake.org) >= 2.8.8
23 | * [libunwind](http://www.nongnu.org/libunwind/) >= 1.1
24 |
25 | In addition, LLILC requires very recent builds of the [Microsoft fork of LLVM](https://github.com/microsoft/llvm)
26 | and [CoreCLR](https://github.com/dotnet/coreclr). Instructions for fetching
27 | and building both can be found below.
28 |
29 | ## Getting and building the code
30 |
31 | 1. Clone and build CoreCLR:
32 |
33 | ```
34 | $ git clone https://github.com/dotnet/coreclr
35 | $ cd coreclr
36 | $ ./build.sh
37 | $ cd ..
38 | ```
39 |
40 | After it completes, the build will indicate where the CoreCLR binaries
41 | are available. Make a note of this location
42 | (typically binaries/Product/.x64.debug).
43 |
44 | 2. Clone the Microsoft fork of LLVM:
45 |
46 | ```
47 | $ git clone -b MS https://github.com/microsoft/llvm
48 | ```
49 |
50 | 3. Clone LLILC:
51 |
52 | ```
53 | $ cd llvm/tools
54 | $ git clone https://github.com/dotnet/llilc
55 | $ cd ..
56 | ```
57 |
58 | 4. Configure LLVM and LLILC:
59 |
60 | ```
61 | $ mkdir build
62 | $ cd build
63 | $ cmake -DWITH_CORECLR=../../coreclr/path/to/CoreCLR/binaries -DLLVM_OPTIMIZED_TABLEGEN=ON ..
64 | ```
65 |
66 | Ie, ../../coreclr/bin/Product/OSX.x64.Debug
67 |
68 | 5. Build LLVM and LLILC:
69 |
70 | ```
71 | $ make
72 | ```
73 |
74 | If all goes well, the build will complete without errors.
75 |
--------------------------------------------------------------------------------
/Documentation/llilc-milestones.md:
--------------------------------------------------------------------------------
1 | # LLILC Bring-Up Milestones
2 |
3 | To meet the overarching goal of fully functional JIT and AOT code
4 | generators we've broken out some intermediate milestones that we
5 | think are good steps along the way. Each of these milestones represent
6 | a new level of functionality or robustness on the way to a production
7 | quality tool.
8 |
9 | ## Milestones
10 |
11 | * [X] **"Hello World"** - Using LLILC, JIT all the methods for runtime
12 | start-up and "Hello World" console app execution. This is the classic first
13 | app. Success is that the CLR comes up, and prints "Hello World" and
14 | exits cleanly.
15 | * [X] **Roslyn compiling "Hello World" on Windows** - Using LLILC, JIT
16 | all of Roslyn through a compile of "Hello World" then JIT and run
17 | "Hello World" on Windows. This is our first larger RWC test case.
18 | * [X] **Roslyn compiling "Hello World" on Linux** - Using LLILC, JIT all
19 | of Roslyn through a compile of "Hello World" then JIT and run on Linux.
20 | (Note: the run of Roslyn and everything else is on Linux) Porting this from
21 | Windows was a matter of a few commits. LLVM portability appears to be
22 | living up to its billing.
23 | * [ ] **Roslyn compiling Roslyn on Windows** - Full Roslyn compiling itself for
24 | CoreCLR on Windows with the JIT.
25 | * [ ] **Roslyn compiling Roslyn on Linux** - Full Roslyn compiling itself for
26 | CoreCLR on Linux with the JIT.
27 | * [ ] **NGen Roslyn on Windows/Linux** - Use crossgen to compile all of Roslyn at
28 | install time using LLILC.
29 | * [ ] **corefx tests on Windows** - Run corefx unit tests as an integration
30 | test. This tests a broad set of framework functionality. Success is a clean
31 | test run using run-test from the corefx repo.
32 | * [ ] **corefx tests on Linux** - Same as above just on Linux.
33 | * [ ] **JIT SelfHost on Linux** - Pass ~6k Jit SelfHost tests on Linux.
34 | These tests are currently being added to coreclr. Success will
35 | be running clean for the whole set.
36 | * [ ] **JIT SelfHost Stress on Linux** - Pass ~6k JIT SelfHost tests under
37 | GCStress. This will do basic validation of the GC implementation.
38 | * [ ] **AOT Roslyn on Linux** - Full Roslyn compiling itself as a command line
39 | AOT tool.
40 |
41 | We'll check these off as we get through them but we're evaluating open issues
42 | with respect to how fixing them will advance these goals.
43 |
44 | Note: To add a milestone to this list open an issue to start the discussion,
45 | then create a PR for a community review.
46 |
--------------------------------------------------------------------------------
/include/Reader/options.h:
--------------------------------------------------------------------------------
1 | //===----------------- include/Jit/options.h -------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declaration of the Options class that encapsulates JIT options
13 | /// extracted from CoreCLR config values.
14 | ///
15 | //===----------------------------------------------------------------------===//
16 |
17 | #ifndef OPTIONS_H
18 | #define OPTIONS_H
19 |
20 | #include "utility.h"
21 |
22 | struct LLILCJitContext;
23 |
24 | /// \brief Enum for JIT optimization level.
25 | enum class OptLevel {
26 | INVALID,
27 | DEBUG_CODE, ///< No/Low optimization to preserve debug semantics.
28 | BLENDED_CODE, ///< Fast code that remains sensitive to code size.
29 | SMALL_CODE, ///< Optimized for small size.
30 | FAST_CODE ///< Optimized for speed.
31 | };
32 |
33 | /// \brief Enum for LLVM IR Dump Level
34 | enum class DumpLevel {
35 | NODUMP, ///< Do not dump any LLVM IR or summary.
36 | SUMMARY, ///< Only dump one line summary per method.
37 | VERBOSE ///< Dump full LLVM IR and method summary.
38 | };
39 |
40 | // Macro to determine the default behavior of automatically
41 | // detecting tail calls (without the "tail." opcode in MSIL).
42 | #define DEFAULT_TAIL_CALL_OPT 1
43 |
44 | /// \brief The JIT options provided via CoreCLR configurations.
45 | ///
46 | /// This class exposes the JIT options flags. This interface is passed
47 | /// around to Options consumers to give them access to the results of
48 | /// the ConfigValue queries but no query logic is exposed here.
49 | ///
50 | struct Options {
51 | ::DumpLevel DumpLevel; ///< Dump level for this JIT invocation.
52 | ::OptLevel OptLevel; ///< Optimization level for this JIT invocation.
53 | bool EnableOptimization; ///< True iff OptLevel is not debug
54 | bool UseConservativeGC; ///< True if the environment is set to use CGC.
55 | bool DoInsertStatepoints; ///< True if the environment calls for statepoints.
56 | bool DoTailCallOpt; ///< Tail call optimization.
57 | bool LogGcInfo; ///< Generate GCInfo Translation logs
58 | bool ExecuteHandlers; ///< Squelch handler suppression.
59 | bool DoSIMDIntrinsic; ///< True if SIMD intrinsic is on.
60 | unsigned PreferredIntrinsicSIMDVectorLength; ///< Prefer Intrinsic SIMD Vector
61 | /// Length in bytes.
62 | };
63 | #endif // OPTIONS_H
64 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/Documentation/Code-Formatting.md:
--------------------------------------------------------------------------------
1 | # Enforcing Coding Conventions
2 |
3 | The LLILC project is structured as a subproject of LLVM so we are using the
4 | same coding conventions as LLVM. See the [coding convention document](llilc-Coding-Conventions-and-Commenting-Style.md)
5 | for more details. To maintain these conventions, we require all contributors
6 | to run our code formatting script over their changes before submitting a pull
7 | request. The code formatting script is found at LLILC\utils\ccformat.py.
8 |
9 | ## Prerequisites
10 |
11 | * Binaries for clang-format and clang-tidy are required to run ccformat.py.
12 | * clang-format is available in the clang repository. It can either be downloaded
13 | from [LLVM](http://llvm.org/releases/download.html), or built from clang source tree.
14 | * clang-tidy is available in the clang-tools-extra repository. It should be built
15 | from the [MS branch](https://github.com/Microsoft/clang-tools-extra/tree/MS)
16 | of the clang-tools-extra repository.
17 |
18 | ## Setup
19 |
20 | * Set the INCLUDE=. On Windows, this can be done by executing
21 | > "%VS120COMNTOOLS%\\..\\..\VC\vcvarsall.bat" x64
22 |
23 | * Provide a full path to the following locations via the corresponding environment settings
24 | or command line arguments.
25 |
26 | Description | Environment Variable | Argument to ccFormat.py
27 | ------------|----------------------|-----------------------------
28 | LLVM source directory | LLVMSOURCE | --llvm-source \
29 | LLVM build directory | LLVMBUILD | --llvm-build \
30 | CoreClr build directory | CORECLRBUILD | --coreclr-build \
31 | clang-format binary | /< on path/> | --clang-format \
32 | clang-tidy binary | /< on path/> | --clang-tidy \
33 |
34 | ## Running ccformat
35 |
36 | To check if a submission conforms to coding conventions, contributors
37 | should run from their main LLILC enlistment directory:
38 |
39 | > utils\ccformat.py
40 |
41 | ### Choosing Checks
42 |
43 | By default, ccFormat will run both clang-format and clang-tidy checks.
44 | To disable clang-format checks, run:
45 | > utils\ccformat.py --noformat
46 |
47 | To disable clang-tidy checks, run:
48 | > utils\ccformat.py --untidy
49 |
50 | ### Hiding Formatting Diffs
51 |
52 | If you do not want to see the diffs generated by clang-format
53 | (but only want to check if there are any formatting errors), run:
54 | > utils\ccformat.py --hide-diffs
55 |
56 | ### Fixing Formatting Errors
57 |
58 | If ccformat.py informs you that there are diffs between your code and the
59 | formatted version returned by clang-format, contributors need to run with
60 | --fix to automatically fix formatting errors:
61 |
62 | > utils\ccformat.py --fix
63 |
64 | ## Further Information
65 |
66 | For further information, please run:
67 |
68 | > utils\ccformat.py --help
69 |
70 |
71 |
--------------------------------------------------------------------------------
/Documentation/llilc-faq.md:
--------------------------------------------------------------------------------
1 | # LLILC FAQ
2 |
3 | + Q: What is LLILC?
4 | A: LLILC is an MSIL code generator based on LLVM. Today LLILC can produce a JIT
5 | compiler that can be used with [CoreCLR](https://github.com/dotnet/coreclr), but our
6 | over-arching aim is to allow easier porting of managed languages to any platform
7 | while supporting a spectrum of compilation strategies.
8 |
9 | + Q: What targets will LLILC generate code for?
10 | A: Initially x64. In future: any target that LLVM supports is
11 | possible (x86, ARM-64, ...)
12 |
13 | + Q: What platforms will LLILC target?
14 | A: LLILC targets the same platforms as CoreCLR: Linux, MAC OS X and Windows
15 |
16 | + Q: How does the LLILC JIT compiler relate to the CoreCLR RyuJIT compiler?
17 | A: Their aims are different: RyuJIT is a high-performance,
18 | custom JIT, in that it implements its own optimizatons
19 | and codegen, specific to C#. It matches the high throughput required by
20 | the CoreCLR runtime. LLILC, by contrast, uses the LLVM framework,
21 | which provides industrial-strength optimizations, leveraged by
22 | the Clang C++ compiler. It thereby offers a familiar environment
23 | within which developers can implement low-level, ‘backend’ tools,
24 | such as code analyzers, obfuscators, verifiers, etc.
25 |
26 | + Q: How do I get started?
27 | A: See the [Welcome Document](Welcome.md)
28 |
29 | + Q: Are there any demos?
30 | A: Not as yet. We need to extend the JIT to handle more
31 | tests first.
32 |
33 | + Q: How does LLILC differ from Roslyn in the features it provides
34 | for building software tools?
35 | A: Roslyn provides *frontend* support, whilst LLILC
36 | (via LLVM) provides *backend* support:
37 |
38 | + Roslyn exposes the data structures of a *frontend* – so it’s ideal
39 | for building tools such as IDEs, with syntax coloring, warning
40 | squiggles, use/definition lookup, refactoring, etc; or
41 | translators that convert C# to some other language; or
42 | pretty-print formatters; or analyzers that check conformance
43 | with coding guidelines (think FxCop).
44 |
45 | + LLILC, via LLVM, exposes the data structures of a *backend* – so
46 | it’s ideal for building tools that inject extra code (eg: performance
47 | profiler, code tracer, debugger, parallelism analyzer, race
48 | detector); or super-optimizing code (eg: auto-vectorizer, auto-parallelizer);
49 | or test-case reduction.
50 |
51 | + Q: When will the LLILC AOT (Ahead-Of-Time) compiler be ready?
52 | A: At the moment, CoreCLR does not include an AOT. We envisage
53 | that the LLILC AOT will work in two kinds of environment – those
54 | that allow runtime codegen, and those where the entire code is converted to native binary.
55 |
56 | + Q: How does LLILC relate to the .NET Native work?
57 | A: .NET Native provides a broad tool-chain, targeting Windows. The LLILC AOT could
58 | be used as the compiler component of .NET Native to target other platforms.
59 |
--------------------------------------------------------------------------------
/Documentation/Long-Running-Branch-Workflow.md:
--------------------------------------------------------------------------------
1 | # Long-Running Branches
2 |
3 | The first rule of long-running branches on the main LLILC repo is that they
4 | should be the exception, not the norm. Most changes should be pushed to a
5 | personal fork and a pull request issued to merge from the fork directly to
6 | the master branch of the main LLILC repo, per the [contribution guide](Contributing.md#workflow).
7 |
8 | Occasionally, however, we'll need to make changes that simultaneously
9 | - Involve a lot of code
10 | - Will take a long time to develop
11 | - Will begin with tentative/exploratory changes that are likely to be revised
12 | before the feature is complete
13 | - Are likely to destabilize the codebase until complete
14 | - Don't have a reasonably efficient incremental implementation path available
15 |
16 | For such changes, it makes sense to work in a long-lived branch, then
17 | retroactively parcel out the change into non-destabilizing pieces, as
18 | incremental as possible, for integration back into the master branch. When
19 | key features meet these criteria, we may create a long-lived branch on the
20 | main repo where the work will occur, to publicize it and facilitate
21 | collaboration/review in even the early tentative stages. For example, the
22 | initial bring-up of [exception handling support](https://github.com/dotnet/llilc/tree/EH)
23 | and [precise garbage collection support](https://github.com/dotnet/llilc/tree/GC)
24 | are both following this model.
25 |
26 | The expected workflow for long-lived branches in the main repo is:
27 | 1. The branch maintainer(s) will regularly push merges from master to the
28 | long-lived branch
29 | - Merging is preferred over rebasing to simplify collaboration
30 | - Pull requests are not expected for these merges (there's not really
31 | anything to review); the branch maintainer(s) will push them directly
32 | 2. All other changes in the branch should be made via pull requests from
33 | personal forks. These changes should be small and incremental, but may
34 | be destabilizing (when warranted to make forward progress). Getting
35 | code reviews along the way should help us end up with higher quality code
36 | and fewer late-stage surprises than delaying review until merging back to
37 | master would.
38 | 3. Any such branch may have its own policy for what level of testing is
39 | expected/required to maintain the quality bar as changes are made.
40 | Code style/formatting should be held to [the usual standards](Code-Formatting.md).
41 | 4. When the feature is stable/complete, the branch maintainer(s) should
42 | rebase/repackage the changes in a way that is logical to merge into master.
43 | - The individual changes to be merged must be stable, and should be as
44 | incremental as possible.
45 | - Pull requests should be opened to merge the changes into master.
46 | - Typically, each incremental change should have its own pull request.
47 | - A single pull request for a series of incremental changes is ok if
48 | they are a straightforward replay of already-reviewed commits from the
49 | branch.
50 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 |
11 | [Dd]ebug/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | [Bb]in/
16 | [Oo]bj/
17 |
18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
19 | !packages/*/build/
20 |
21 | # MSTest test Results
22 | [Tt]est[Rr]esult*/
23 | [Bb]uild[Ll]og.*
24 |
25 | *_i.c
26 | *_p.c
27 | *.ilk
28 | *.meta
29 | *.obj
30 | *.pch
31 | *.pdb
32 | *.pgc
33 | *.pgd
34 | *.rsp
35 | *.sbr
36 | *.tlb
37 | *.tli
38 | *.tlh
39 | *.tmp
40 | *.tmp_proj
41 | *.log
42 | *.vspscc
43 | *.vssscc
44 | .builds
45 | *.pidb
46 | *.log
47 | *.scc
48 |
49 | # Python cache
50 | __pycache__
51 | *.pyc
52 |
53 | # Visual C++ cache files
54 | ipch/
55 | *.aps
56 | *.ncb
57 | *.opensdf
58 | *.sdf
59 | *.cachefile
60 |
61 | # Visual Studio profiler
62 | *.psess
63 | *.vsp
64 | *.vspx
65 |
66 | # Guidance Automation Toolkit
67 | *.gpState
68 |
69 | # ReSharper is a .NET coding add-in
70 | _ReSharper*/
71 | *.[Rr]e[Ss]harper
72 |
73 | # TeamCity is a build add-in
74 | _TeamCity*
75 |
76 | # DotCover is a Code Coverage Tool
77 | *.dotCover
78 |
79 | # NCrunch
80 | *.ncrunch*
81 | .*crunch*.local.xml
82 |
83 | # Installshield output folder
84 | [Ee]xpress/
85 |
86 | # DocProject is a documentation generator add-in
87 | DocProject/buildhelp/
88 | DocProject/Help/*.HxT
89 | DocProject/Help/*.HxC
90 | DocProject/Help/*.hhc
91 | DocProject/Help/*.hhk
92 | DocProject/Help/*.hhp
93 | DocProject/Help/Html2
94 | DocProject/Help/html
95 |
96 | # Click-Once directory
97 | publish/
98 |
99 | # Publish Web Output
100 | *.Publish.xml
101 |
102 | # NuGet Packages Directory
103 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
104 | #packages/
105 |
106 | # Windows Azure Build Output
107 | csx
108 | *.build.csdef
109 |
110 | # Windows Store app package directory
111 | AppPackages/
112 |
113 | # Others
114 | sql/
115 | *.Cache
116 | ClientBin/
117 | [Ss]tyle[Cc]op.*
118 | ~$*
119 | *~
120 | *.dbmdl
121 | *.[Pp]ublish.xml
122 | *.pfx
123 | *.publishsettings
124 |
125 | # RIA/Silverlight projects
126 | Generated_Code/
127 |
128 | # Backup & report files from converting an old project file to a newer
129 | # Visual Studio version. Backup files are not needed, because we have git ;-)
130 | _UpgradeReport_Files/
131 | Backup*/
132 | UpgradeLog*.XML
133 | UpgradeLog*.htm
134 |
135 | # SQL Server files
136 | App_Data/*.mdf
137 | App_Data/*.ldf
138 |
139 |
140 | #LightSwitch generated files
141 | GeneratedArtifacts/
142 | _Pvt_Extensions/
143 | ModelManifest.xml
144 |
145 | # =========================
146 | # Windows detritus
147 | # =========================
148 |
149 | # Windows image file caches
150 | Thumbs.db
151 | ehthumbs.db
152 |
153 | # Folder config file
154 | Desktop.ini
155 |
156 | # Recycle Bin used on file shares
157 | $RECYCLE.BIN/
158 |
159 | # Mac desktop service store files
160 | .DS_Store
161 | /src/3fjtrdxe.dt5
162 | /src/j1xrvkr3.mrf
163 | TAGS
164 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LLILC Is Now Archived
2 |
3 | LLILC was an experimental project to build a .NET compatible JIT from LLVM. It is no longer under active development.
4 |
5 | For questions or concerns please open an issue on https://github.com/dotnet/core.
6 |
7 | Welcome to LLILC
8 | ------------
9 |
10 | [](https://gitter.im/dotnet/llilc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
11 |
12 | Build Status
13 | ------------
14 |
15 | | | Windows | Linux |
16 | |-----------|---------------|-------------|
17 | | **Debug** |[](http://dotnet-ci.cloudapp.net/job/dotnet_llilc/job/master/job/windows_nt_debug/)|[](http://dotnet-ci.cloudapp.net/job/dotnet_llilc/job/master/job/ubuntu_debug/)|
18 | |**Release**|[](http://dotnet-ci.cloudapp.net/job/dotnet_llilc/job/master/job/windows_nt_release/)|[](http://dotnet-ci.cloudapp.net/job/dotnet_llilc/job/master/job/ubuntu_release/)|
19 |
20 |
21 | Introduction
22 | -------------
23 |
24 | LLILC is an **LL**VM based MS**IL** **C**ompiler - we pronounce it 'lilac' -
25 | with a goal of producing a set of cross-platform .NET code generation tools.
26 | Today LLILC is being developed against [dotnet/CoreCLR](https://github.com/dotnet/coreclr)
27 | for use as a JIT, as well as an cross platform platform object emitter and disassembler
28 | that is used by CoreRT as well as other dotnet utilites.
29 |
30 | See the [documentation](Documentation/Welcome.md) for more information.
31 | It has a more complete discussion of our background and goals as well as
32 | "getting started" details and developer information.
33 |
34 | ObjectWriter for [CoreRT](https://github.com/dotnet/corert):
35 | CoreRT project uses ObjectWriter that lives in its own branch in this repo,
36 | if you want to build it then follow instructions from getting started, but use the following branches:
37 | 1. latest LLVM [version](https://github.com/llvm-mirror/llvm) and apply this [patch](https://reviews.llvm.org/D29483) or take the known working version from [Microsoft/llvm/CoreRT_ObjectWriter branch](https://github.com/dotnet/llilc/tree/ObjectWriter);
38 | 2. [llilc/ObjectWriter branch](https://github.com/dotnet/llilc/tree/ObjectWriter);
39 |
40 | libcoredistools: CoreCLR has a ongoing dependency on libcoredistools which is built out of this repo and placed into build/lib/libcoredistools.dylib|so|dll. To build coredistools follow the default workflow for building llilc/llvm on the master branch.
41 |
42 |
43 | Supported Platforms
44 | -------------------
45 |
46 | Our initial supported platform is [Windows](Documentation/Getting-Started-For-Windows.md),
47 | but [Linux and Mac OS X](Documentation/Getting-Started-For-Linux-and-OS-X.md)
48 | support are under development.
49 |
50 | Contributions
51 | -------------
52 |
53 | Please see our [issues](https://github.com/dotnet/llilc/issues)
54 | or the [contributing document](Documentation/Areas-To-Contribute.md)
55 | for how to pitch in.
56 |
--------------------------------------------------------------------------------
/utils/make_package.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 | import argparse
5 | import os
6 | import subprocess
7 | import platform
8 | import io
9 | import string
10 | try:
11 | # For Python >= 3.0
12 | from urllib.request import urlopen
13 | except ImportError:
14 | # For Python < 3.0
15 | from urllib2 import urlopen
16 | import shutil
17 | import stat
18 |
19 | def run(args):
20 | nugetFolder = os.path.join(args.target, ".nuget")
21 | print("\nEnsuring folder: %s" % nugetFolder )
22 | if not os.path.exists(nugetFolder):
23 | os.makedirs(nugetFolder)
24 |
25 | nugetExe = os.path.join(nugetFolder, "nuget.exe")
26 | if not os.path.exists(nugetExe):
27 | nugetOrg = "http://nuget.org/nuget.exe"
28 | print("Downloading... %s" % nugetOrg )
29 | response = urlopen(nugetOrg)
30 | output = open(nugetExe,'wb')
31 | output.write(response.read())
32 | output.close()
33 | # Ensure it's executable
34 | st = os.stat(nugetExe)
35 | os.chmod(nugetExe, st.st_mode | stat.S_IEXEC)
36 |
37 | if (sys.platform != "win32"):
38 | # shutil.which can be used for python 3.3 or later, instead.
39 | for mono in ["/usr/bin/mono", "/usr/local/bin/mono"]:
40 | if os.path.exists(mono):
41 | monopath = mono
42 | if not monopath:
43 | raise "mono is required to run nuget.exe"
44 | nugetExe = monopath + " " + nugetExe
45 |
46 | nugetSpec = os.path.join(nugetFolder, os.path.basename(args.nuspec))
47 | if args.nuspec != nugetSpec:
48 | print("\nCopying " + args.nuspec + " to " + nugetSpec)
49 | shutil.copyfile(args.nuspec, nugetSpec)
50 |
51 | if args.json != None:
52 | nugetJson = os.path.join(nugetFolder, os.path.basename(args.json))
53 | if args.json != nugetJson:
54 | print("\nCopying " + args.json + " to " + nugetJson)
55 | shutil.copyfile(args.json, nugetJson)
56 |
57 | nugetCommand = nugetExe + " pack " + nugetSpec \
58 | + " -NoPackageAnalysis -NoDefaultExcludes" \
59 | " -OutputDirectory %s" % nugetFolder
60 |
61 | ret = os.system(nugetCommand)
62 | return ret
63 |
64 | def main(argv):
65 | parser = argparse.ArgumentParser(description=
66 | "Download nuget and run it to create a package using the given nuspec. " \
67 | "Example: make_package.py " \
68 | "--target f:\llilc-rel\\bin\Release " \
69 | "--nuspec f:\llilc\lib\ObjWriter\.nuget\Microsoft.Dotnet.ObjectWriter.nuspec",
70 | formatter_class=argparse.ArgumentDefaultsHelpFormatter)
71 | parser.add_argument("--target", metavar="PATH",
72 | default=None,
73 | help="path to a target directory that contains files that will " \
74 | "packaged")
75 | parser.add_argument("--nuspec", metavar="PATH",
76 | default=None,
77 | help="path to a nuspec file. This file is assumed to be under " \
78 | "a child directory (.nuget) of the target by convetion")
79 | parser.add_argument("--json", metavar="PATH",
80 | default=None,
81 | help="path to a json file. This file is used to create " \
82 | "a redirection package")
83 | args,unknown = parser.parse_known_args(argv)
84 |
85 | if unknown:
86 | print("Unknown argument(s): ", ", ".join(unknown))
87 | return -3
88 |
89 | returncode=0
90 | if args.target == None:
91 | print("--target is not specified.")
92 | return -3
93 |
94 | if args.nuspec == None:
95 | print("--nuspec is not specified")
96 | return -3
97 |
98 | returncode = run(args)
99 |
100 | return returncode
101 |
102 |
103 | if __name__ == "__main__":
104 | returncode = main(sys.argv[1:])
105 | sys.exit(returncode)
106 |
--------------------------------------------------------------------------------
/lib/GcInfo/GcInfoUtil.cpp:
--------------------------------------------------------------------------------
1 | //===---- include/gcinfo/gcinfoutil.cpp -------------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Implementation of utility classes used by GCInfoEncoder library
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #include
17 | #include "GcInfoUtil.h"
18 |
19 | //*****************************************************************************
20 | // GcInfoAllocator
21 | //*****************************************************************************
22 |
23 | int GcInfoAllocator::ZeroLengthAlloc = 0;
24 |
25 | //*****************************************************************************
26 | // Utility Functions
27 | //*****************************************************************************
28 |
29 | //------------------------------------------------------------------------
30 | // BitPosition: Return the position of the single bit that is set in 'value'.
31 | //
32 | // Return Value:
33 | // The position (0 is LSB) of bit that is set in 'value'
34 | //
35 | // Notes:
36 | // 'value' must have exactly one bit set.
37 | // The algorithm is as follows:
38 | // - PRIME is a prime bigger than sizeof(unsigned int), which is not of the
39 | // form 2^n-1.
40 | // - Taking the modulo of 'value' with this will produce a unique hash for
41 | // all powers of 2 (which is what "value" is).
42 | // - Entries in hashTable[] which are -1 should never be used. There
43 | // should be PRIME-8*sizeof(value) entries which are -1 .
44 | //------------------------------------------------------------------------
45 |
46 | unsigned BitPosition(unsigned value) {
47 | _ASSERTE((value != 0) && ((value & (value - 1)) == 0));
48 | const unsigned PRIME = 37;
49 |
50 | static const int8_t hashTable[PRIME] = {
51 | -1, 0, 1, 26, 2, 23, 27, -1, 3, 16, 24, 30, 28, 11, -1, 13, 4, 7, 17,
52 | -1, 25, 22, 31, 15, 29, 10, 12, 6, -1, 21, 14, 9, 5, 20, 8, 19, 18};
53 |
54 | _ASSERTE(PRIME >= 8 * sizeof(value));
55 | _ASSERTE(sizeof(hashTable) == PRIME);
56 |
57 | unsigned hash = value % PRIME;
58 | int8_t index = hashTable[hash];
59 | _ASSERTE(index != -1);
60 |
61 | return (unsigned)index;
62 | }
63 |
64 | //*****************************************************************************
65 | // ArrayList
66 | //*****************************************************************************
67 |
68 | void StructArrayListBase::CreateNewChunk(SIZE_T InitialChunkLength,
69 | SIZE_T ChunkLengthGrowthFactor,
70 | SIZE_T cbElement, AllocProc *pfnAlloc,
71 | SIZE_T alignment) {
72 | _ASSERTE(InitialChunkLength > 0);
73 | _ASSERTE(ChunkLengthGrowthFactor > 0);
74 | _ASSERTE(cbElement > 0);
75 |
76 | SIZE_T cbBaseSize =
77 | SIZE_T(roundUp(sizeof(StructArrayListEntryBase), alignment));
78 | SIZE_T maxChunkCapacity = (MAXSIZE_T - cbBaseSize) / cbElement;
79 |
80 | _ASSERTE(maxChunkCapacity > 0);
81 |
82 | SIZE_T nChunkCapacity;
83 | if (!m_pChunkListHead)
84 | nChunkCapacity = InitialChunkLength;
85 | else
86 | nChunkCapacity = m_nLastChunkCapacity * ChunkLengthGrowthFactor;
87 |
88 | if (nChunkCapacity > maxChunkCapacity) {
89 | // Limit nChunkCapacity such that cbChunk computation does not overflow.
90 | nChunkCapacity = maxChunkCapacity;
91 | }
92 |
93 | SIZE_T cbChunk = cbBaseSize + SIZE_T(cbElement) * SIZE_T(nChunkCapacity);
94 |
95 | StructArrayListEntryBase *pNewChunk =
96 | (StructArrayListEntryBase *)pfnAlloc(this, cbChunk);
97 |
98 | if (m_pChunkListTail) {
99 | _ASSERTE(m_pChunkListHead);
100 | m_pChunkListTail->pNext = pNewChunk;
101 | } else {
102 | _ASSERTE(!m_pChunkListHead);
103 | m_pChunkListHead = pNewChunk;
104 | }
105 |
106 | pNewChunk->pNext = NULL;
107 | m_pChunkListTail = pNewChunk;
108 |
109 | m_nItemsInLastChunk = 0;
110 | m_nLastChunkCapacity = nChunkCapacity;
111 | }
112 |
--------------------------------------------------------------------------------
/Documentation/llilc-Coding-Conventions-and-Commenting-Style.md:
--------------------------------------------------------------------------------
1 | # LLILC Coding Guidelines
2 |
3 | ## General Coding Guidelines
4 |
5 | The LLILC project is structured as a subproject of LLVM so we are using the
6 | same coding conventions as LLVM. The LLVM coding conventions are at
7 | . We use clang-format to
8 | check/enforce some formatting rules, as described on our
9 | [code formatting document](Code-Formatting.md).
10 |
11 | ## Commenting Guidelines
12 |
13 | In particular has
14 | guidelines for commenting code and using Doxygen markup. For a complete
15 | description of Doxygen markup see .
16 |
17 | We can summarize these as follows:
18 |
19 | * Use the "///" style of comment unless that file is written in C or may be
20 | included into a C file.
21 |
22 | * For Doyxygen markup, use the "\" form, e.g. \brief, rather than the "@"
23 | form, e.g. @brief.
24 |
25 | * Use the \file command to turn the standard file header into a file-level
26 | comment.
27 |
28 | * Include descriptive \brief paragraphs for all public interfaces (public
29 | classes, member and non-member functions). Explain API use and purpose in
30 | \brief paragraphs, don’t just restate the information that can be inferred
31 | from the API name. Put detailed discussion into separate paragraphs.
32 |
33 | * To refer to parameter names inside a paragraph, use the \p name command.
34 | Don’t use the \arg name command since it starts a new paragraph that
35 | contains documentation for the parameter.
36 |
37 | * Wrap non-inline code examples in \code ... \endcode.
38 |
39 | * To document a function parameter, start a new paragraph with the \param
40 | name command. If the parameter is used as an out or an in/out parameter,
41 | use the \param [out] name or \param [in,out] name command, respectively.
42 |
43 | * To describe function return value, start a new paragraph with the \returns
44 | command
45 |
46 | * For classes and class members that are declared in a header, put the Doxygen
47 | comments there. Otherwise put the comments in the implementation file.
48 |
49 | * For declaration of fields of a class, if the declaration is short
50 | use the "//<" form of document comments at the end of the line,
51 | if the comment will fit on not more than two lines.
52 | If the comment would be longer than two lines, put the documentation
53 | comment before the declaration.
54 |
55 | * When a documentation comment precedes a declaration, separate it from
56 | preceding declarations by a blank line.
57 |
58 | * For virtual methods, put the documentation on the method declaration in the
59 | base class that first introduced the method. Do not put documentation on
60 | the method overrides. In the Doxygen output the comments from the base
61 | class method will also be shown for the overriding methods.
62 |
63 | In addition to these recommendations from the LLVM coding standards I have
64 | the following recommendations:
65 |
66 | * Doxygen supports Markdown, so use it in your comments when it can do what
67 | you want. See
68 |
69 | * In order to provide greater logical clarity on the semantics of classes
70 | and methods I suggest using the Doxygen
71 | [\pre](http://www.stack.nl/~dimitri/doxygen/manual/commands.html#cmdpre),
72 | [\post](http://www.stack.nl/~dimitri/doxygen/manual/commands.html#cmdpost),
73 | and [\invariant](http://www.stack.nl/~dimitri/doxygen/manual/commands.html#cmdinvariant)
74 | [special commands](http://www.stack.nl/~dimitri/doxygen/manual/commands.html)
75 | to specify method preconditions and postconditions and class invariants.
76 |
77 | ## Use of LLVM I/O APIs
78 |
79 | Rather than using the printf family of output functions the LLILC team
80 | uses the LLVML I/O APIs. This is a simplified form of C++ output.
81 |
82 | - The base type is raw_ostream.
83 | - Derived classes are:
84 | - raw_fd_ostream, for output to a file descriptor. Two of these are
85 | made and accessed as follows:
86 | - outs() is connected to stdout
87 | - errs() is connected to stderr.
88 | - dbgs() is a debug stream that is connected to stderr but which
89 | may optionally have circular buffering but by default it is
90 | an unbuffered connection to errs().
91 | - raw_string_ostream connects to a std::string given in its
92 | - constructor. Any output to that stream is appended to the
93 | end of the string.
94 | - As with C++ the "<<" operator has overloads for outputting all the
95 | common data types.
96 | - In addition the form "<< format(formatstring, args)" may be
97 | used to get the usual printf-stype formatting to a stream.
98 |
--------------------------------------------------------------------------------
/lib/Jit/utility.cpp:
--------------------------------------------------------------------------------
1 | // Utility code
2 |
3 | #include
4 |
5 | #include "global.h"
6 | #include "jitpch.h"
7 |
8 | #include "cor.h" // CorSigUncompressData
9 | #include "utility.h"
10 | #include "llvm/Support/ConvertUTF.h"
11 |
12 | using std::string;
13 | using std::unique_ptr;
14 |
15 | int MethodID::parseArgs(const string &S, size_t &I) {
16 | size_t Start = ++I; // skip '('
17 |
18 | I = S.find_first_of(")", I);
19 | if (I == string::npos)
20 | return MethodIDState::AnyArgs;
21 |
22 | string Num = string(S, Start, I - Start);
23 | int NArgs = atoi(Num.c_str());
24 | ++I; // skip )
25 | return NArgs;
26 | }
27 |
28 | unique_ptr MethodID::parse(const string &S, size_t &I) {
29 | MethodID MId;
30 | size_t SLen = S.length();
31 |
32 | string Token = MId.scan(S, I);
33 |
34 | if (Token == "") // off the end of S
35 | return nullptr;
36 |
37 | if (Token == "*") {
38 | MId.ClassName = llvm::make_unique(Token);
39 | MId.MethodName = nullptr;
40 | if (I >= SLen || S[I] == ' ') {
41 | MId.NumArgs = MethodIDState::AnyArgs;
42 | }
43 | return llvm::make_unique(MId);
44 | return nullptr;
45 | }
46 |
47 | if (S[I] == ':') { // C:M | C:M(A)
48 | MId.ClassName = llvm::make_unique(Token);
49 | Token = MId.scan(S, ++I); // M | M(A)
50 | }
51 |
52 | MId.MethodName = llvm::make_unique(Token);
53 |
54 | if (I >= SLen || S[I] == ' ') {
55 | MId.NumArgs = MethodIDState::AnyArgs;
56 | return llvm::make_unique(MId);
57 | return nullptr;
58 | }
59 |
60 | if (S[I] != '(') // illegal
61 | return nullptr;
62 |
63 | MId.NumArgs = MId.parseArgs(S, I);
64 | return llvm::make_unique(MId);
65 | return nullptr;
66 | }
67 |
68 | string MethodID::scan(const string &S, size_t &I) {
69 | const size_t SLen = S.length();
70 |
71 | if (I >= SLen) // already 'off the end'
72 | return string{""};
73 |
74 | size_t Start = I = S.find_first_not_of(" \t", I); // skip whitespace
75 |
76 | I = S.find_first_of(" :()", I);
77 |
78 | if (I == string::npos) // eg: S = "*"
79 | I = SLen;
80 |
81 | return string(S, Start, I - Start);
82 | }
83 |
84 | void MethodSet::init(unique_ptr ConfigValue) {
85 | if (this->isInitialized()) {
86 | return;
87 | }
88 | insert(std::move(ConfigValue));
89 | }
90 |
91 | void MethodSet::insert(unique_ptr Ups) {
92 | size_t I = 0;
93 | std::list *MIdList = new std::list();
94 | string S = *Ups;
95 |
96 | auto MId = MethodID::parse(S, I);
97 | while (MId) {
98 | MIdList->push_back(*MId);
99 | MId = MethodID::parse(S, I);
100 | }
101 |
102 | // This write should be atomic, delete if we're not the first.
103 | llvm::sys::cas_flag F = llvm::sys::CompareAndSwap(
104 | (llvm::sys::cas_flag *)&(this->Initialized), 0x1, 0x0);
105 | if (F != 0x0) {
106 | delete MIdList;
107 | } else {
108 | this->MethodIDList = MIdList;
109 | }
110 | }
111 |
112 | bool MethodSet::contains(const char *MethodName, const char *ClassName,
113 | PCCOR_SIGNATURE PCSig) {
114 |
115 | assert(this->isInitialized());
116 |
117 | int NumArgs = MethodIDState::AnyArgs; // assume no signature supplied
118 |
119 | if (PCSig) {
120 | PCSig++; // skip calling convention
121 | NumArgs = CorSigUncompressData(PCSig);
122 | }
123 |
124 | string StrClassName = ClassName ? ClassName : "";
125 | string StrMethodName = MethodName ? MethodName : "";
126 |
127 | auto Begin = this->MethodIDList->begin();
128 | auto End = this->MethodIDList->end();
129 |
130 | for (auto P = Begin; P != End; ++P) { // P => "pattern"
131 |
132 | // Check for "*", the common case, first
133 | if (P->ClassName && *P->ClassName == "*")
134 | return true;
135 |
136 | // Check for mis-match on NumArgs
137 | if (P->NumArgs != MethodIDState::AnyArgs && P->NumArgs != NumArgs)
138 | continue;
139 |
140 | // Check for mis-match on MethodName
141 | if (P->MethodName && (*P->MethodName != StrMethodName))
142 | continue;
143 |
144 | // Check for match on ClassName (we already match NumArgs and MethodName)
145 | if (!P->ClassName) // no ClassName
146 | return true;
147 |
148 | if (*P->ClassName == StrClassName)
149 | return true;
150 | }
151 |
152 | return false;
153 | }
154 |
155 | unique_ptr Convert::utf16ToUtf8(const char16_t *WideStr) {
156 | // Get the length of the input
157 | size_t SrcLen = 0;
158 | for (; WideStr[SrcLen] != (char16_t)0; SrcLen++)
159 | ;
160 |
161 | llvm::ArrayRef SrcBytes((const char *)WideStr, 2 * SrcLen);
162 | unique_ptr OutString(new std::string);
163 | convertUTF16ToUTF8String(SrcBytes, *OutString);
164 |
165 | return OutString;
166 | }
167 |
--------------------------------------------------------------------------------
/Documentation/Developer-Workflow.md:
--------------------------------------------------------------------------------
1 | # Developer Workflow
2 |
3 | ## Introduction
4 |
5 | This documents our typical workflow. At a high level this covers how we
6 | expect issues to work, what our development cadence is, and how we do design
7 | for larger features. And by we, we mean the whole community. These guidelines
8 | hopefully foster collaboration and high quality, useful software.
9 | (Some fun wouldn't hurt either.)
10 |
11 | ## Issues
12 |
13 | We use GitHub issues to track work, so if you're working on something, open
14 | an issue. It gives the community a place to have a conversation about the
15 | fix/feature that's being worked on. In addition it helps everybody keep
16 | track of who is working on what so that we can minimize duplication and
17 | redundant work.
18 |
19 | The typical issue flow is as follows:
20 | - Have a great idea, or find a bug, and open issue.
21 | - Issue is discussed on GitHub and a direction is established.
22 | - Somebody signs up to do the work and potentially a sprint milestone is
23 | assigned if the work directly effects a particular near term project
24 | [goal](https://github.com/dotnet/llilc/blob/master/Documentation/llilc-milestones.md).
25 | - Ongoing notes on the implementation are added to the issue as work progresses.
26 | - Work is completed, tested, PR'd, and merged in.
27 | - Issue is closed
28 |
29 | Note on 'assigning' issues: The only people that can be assigned to an issue
30 | in GitHub are people that are in one of the project groups (either *llilc* -
31 | read/write access, or *llilc-community* - read only access). We add people
32 | to the Community group after their first PR is accepted by the collaborators.
33 | This enables you to be added as the assignee for issues. So if this is your
34 | first issue, note your Github account name in the issue as the person
35 | working on it and others will understand that it's in flight.
36 |
37 | Note on read/write access: We'd like to develop a broad set of committers to
38 | the project from the community (we don't have any non-MS committers at this
39 | point) we think that this should happen after people build a track record in
40 | the llilc-community group. The expectation is that after few (3-5) non-trivial
41 | contributions a community member can request to be added to the project group
42 | and gain read/write access to the source. With this access also comes the
43 | expectation that the collaborator will help review others PR's, help maintain
44 | documentation, as well as generally facilitate the smooth running of the project.
45 |
46 | ## Workflow
47 |
48 | We use 3 week sprints in a agile(-ish) model. These sprints are added as
49 | Milestones in Github (not to be confused with the project [Milestones](llilc-milestones.md)
50 | which are larger granularity proof points of functionality.) Look at the
51 | [Github milestones page](https://github.com/dotnet/llilc/milestones) to see
52 | the individual sprints and their end dates. These sprints are used by core
53 | members of the team to managed work toward near term goals, but it is not
54 | necessary for community contributors to use these milestones. The only place
55 | where this could potentially cause some complication is if a particular
56 | feature/fix is needed for a near term goal. In this case we would have a
57 | conversation about assigning the issue to a milestone and potentially moving
58 | the work to a collaborator that can commit to a solution in the needed time
59 | frame. We're attempting to have a balance between an open and friendly
60 | environment to hack and the necessity to drive functionality (as well as
61 | meet product goals).
62 |
63 | A typical flow is as follows:
64 | - Day one of a sprint milestone work is self-assigned by developers based on
65 | a combination of priority and what the think that they can get done in a 3
66 | week period.
67 | - Through out the sprint notes are added to the issues assigned to the sprint
68 | outlining progress.
69 | - Issues are closed as they are merged back in and the CI system stays green.
70 | - On the first day of the next sprint, any items not completed are triaged
71 | and moved to the appropriate sprint. (Typically this is the next sprint)
72 |
73 | ## Design process
74 |
75 | As stated above, all features start as issues. If as part of the conversation
76 | about an issue, the community decides that a particular feature is large or
77 | complicated enough to warrant a separate write up a document will be created
78 | by interested parties describing the design and the staging of bring up.
79 | This document will be reviewed via PR and checked in as separate markdown in
80 | the project Documentation directory off the root. A good example of this is
81 | the [EH design document](llilc-jit-eh.md). As you can see today only larger,
82 | more complicated areas warrant this treatment. I want to highlight that
83 | typical work will be handled via issues, reserving this process for areas
84 | that require months of development to bring to fruition.
85 |
--------------------------------------------------------------------------------
/netci.groovy:
--------------------------------------------------------------------------------
1 | import jobs.generation.Utilities;
2 |
3 | def project = GithubProject
4 | def branch = GithubBranchName
5 |
6 | static void addMultiScm(def myJob, boolean isPR) {
7 | if (isPR) {
8 | addPRTestMultiScm(myJob)
9 | }
10 | else {
11 | addMultiScm(myJob)
12 | }
13 | }
14 |
15 | static void addPRTestMultiScm(def job) {
16 | job.with {
17 | multiscm {
18 | git {
19 | remote {
20 | github('Microsoft/llvm')
21 | }
22 | branch('*/MS')
23 | wipeOutWorkspace(true)
24 | shallowClone(true)
25 | relativeTargetDir('llvm')
26 | }
27 | git {
28 | remote {
29 | github('dotnet/coreclr')
30 | }
31 | branch('*/master')
32 | relativeTargetDir('coreclr')
33 | }
34 | git {
35 | remote {
36 | github('dotnet/llilc')
37 | refspec('${GitRefSpec}')
38 | url('${GitRepoUrl}')
39 | }
40 | branch('${sha1}')
41 | relativeTargetDir('llvm\\tools\\llilc')
42 | }
43 | }
44 | }
45 | }
46 |
47 | static void addMultiScm(def myJob) {
48 | myJob.with {
49 | multiscm {
50 | git {
51 | remote {
52 | github('Microsoft/llvm')
53 | }
54 | branch('*/MS')
55 | wipeOutWorkspace(true)
56 | shallowClone(true)
57 | relativeTargetDir('llvm')
58 | }
59 | git {
60 | remote {
61 | github('dotnet/coreclr')
62 | }
63 | branch('*/master')
64 | relativeTargetDir('coreclr')
65 | }
66 | git {
67 | remote {
68 | github('dotnet/llilc')
69 | }
70 | branch('*/master')
71 | relativeTargetDir('llvm\\tools\\llilc')
72 | }
73 | }
74 | }
75 | }
76 |
77 | [true, false].each { isPR ->
78 | ['Debug', 'Release'].each { configuration ->
79 | lowerConfiguration = configuration.toLowerCase()
80 | def newJobName = Utilities.getFullJobName(project, "windows_nt_${lowerConfiguration}", isPR)
81 |
82 | def newJob = job (newJobName) {
83 | steps {
84 | batchFile("""cd llvm
85 | echo |set /p="LLVMCommit=" > %WORKSPACE%\\commits.txt
86 | git rev-parse "refs/remotes/origin/MS^{commit}" >> %WORKSPACE%\\commits.txt
87 |
88 | cd tools\\llilc
89 | echo |set /p="LLILCCommit=" >> %WORKSPACE%\\commits.txt
90 | git rev-parse "refs/remotes/origin/master^{commit}" >> %WORKSPACE%\\commits.txt
91 |
92 | cd %workspace%\\coreclr
93 | echo |set /p="CoreCLRCommit=" >> %WORKSPACE%\\commits.txt
94 | git rev-parse "refs/remotes/origin/master^{commit}" >> %WORKSPACE%\\commits.txt""")
95 | batchFile("""if exist build/ rd /s /q build
96 | mkdir build
97 |
98 | cd coreclr
99 | ./build.cmd ${lowerConfiguration} skiptests""")
100 | batchFile("""cd build
101 | cmake -G \"Visual Studio 14 2015 Win64\" -DWITH_CORECLR=%WORKSPACE%\\coreclr\\bin\\Product\\Windows_NT.x64.${configuration} -DLLVM_OPTIMIZED_TABLEGEN=ON ..\\llvm
102 | \"%VS140COMNTOOLS%\\..\\..\\VC\\vcvarsall.bat\" x86 && msbuild llvm.sln /p:Configuration=${configuration} /p:Platform=x64 /t:ALL_BUILD /m""")
103 | }
104 | }
105 |
106 | Utilities.setMachineAffinity(newJob, 'Windows_NT', 'latest-or-auto')
107 | Utilities.addStandardParameters(newJob, project, isPR, '*/master')
108 | addMultiScm(newJob, isPR)
109 | Utilities.addStandardOptions(newJob, isPR)
110 | if (isPR) {
111 | Utilities.addGithubPRTriggerForBranch(newJob, branch, "Windows ${lowerConfiguration}")
112 | }
113 | else {
114 | Utilities.addGithubPushTrigger(newJob)
115 | }
116 | }
117 | }
118 |
119 | [true, false].each { isPR ->
120 | ['Debug', 'Release'].each { configuration ->
121 | String lowerConfiguration = configuration.toLowerCase()
122 | def newJobName = Utilities.getFullJobName(project, "ubuntu_${lowerConfiguration}", isPR)
123 |
124 | def newJob = job (newJobName) {
125 | steps {
126 | shell("if which clang-3.5; then \n export CC=\$(which clang-3.5)\n export CXX=\$(which clang++-3.5)\nelif which clang; then\n export CC=\$(which clang)\n export CXX=\$(which clang++)\nelse\n echo Could not find clang or clang-3.5\n exit 1\nfi\n\n(cd coreclr && ./build.sh ${lowerConfiguration}) && (cd llvm && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=${configuration} -DWITH_CORECLR=../../coreclr/bin/Product/Linux.x64.${configuration} .. && make -j 5)")
127 | }
128 | }
129 |
130 | Utilities.setMachineAffinity(newJob, 'Ubuntu', 'latest-or-auto')
131 | Utilities.addStandardParameters(newJob, project, isPR, '*/master')
132 | addMultiScm(newJob, isPR)
133 | Utilities.addStandardOptions(newJob, isPR)
134 | if (isPR) {
135 | Utilities.addGithubPRTriggerForBranch(newJob, branch, "ubuntu ${lowerConfiguration}")
136 | }
137 | else {
138 | Utilities.addGithubPushTrigger(newJob)
139 | }
140 | }
141 | }
142 |
143 |
--------------------------------------------------------------------------------
/Documentation/Areas-To-Contribute.md:
--------------------------------------------------------------------------------
1 | # Areas to Contribute
2 |
3 | Below is a list of areas where LLILC needs work.
4 | Their order follows the path to creating a functioning JIT, that can compile
5 | most C# programs; and doing so with contributions from the Community - so good
6 | documentation comes early.
7 | Each item is given a "star" rating: 1 star denotes easy; many stars denote challenging.
8 |
9 | We always keep a [list of open issues](https://github.com/dotnet/llilc/issues)
10 | in the repo, to track open work items. This is a good place to start. But
11 | beware that it changes day-by-day. So if you spot an item you'd like to work
12 | on, assign it to yourself, so everyone can see it's being worked on.
13 |
14 | As you work on an issue, it will likely spawn more work. So enter these as issues.
15 |
16 | ## Major Areas
17 |
18 | + (*) Areas where documentation needs improving.
19 | Eg: [#122](https://github.com/dotnet/llilc/issues/122),
20 | [#124](https://github.com/dotnet/llilc/issues/124),
21 | [#128](https://github.com/dotnet/llilc/issues/128),
22 | [#129](https://github.com/dotnet/llilc/issues/129),
23 | [#130](https://github.com/dotnet/llilc/issues/130),
24 | [#131](https://github.com/dotnet/llilc/issues/131),
25 | [#145](https://github.com/dotnet/llilc/issues/145),
26 | [#154](https://github.com/dotnet/llilc/issues/154),
27 | [#174](https://github.com/dotnet/llilc/issues/174),
28 | [#175](https://github.com/dotnet/llilc/issues/175),
29 | [#176](https://github.com/dotnet/llilc/issues/176)
30 |
31 | + (**) Extend the Reader
32 | Eg: [#281](https://github.com/dotnet/llilc/issues/281),
33 | [#283](https://github.com/dotnet/llilc/issues/283),
34 | [#284](https://github.com/dotnet/llilc/issues/284),
35 | [#286](https://github.com/dotnet/llilc/issues/286)
36 |
37 | + (**) Add support for more MSIL opcodes.
38 | Eg: [#191](https://github.com/dotnet/llilc/issues/191),
39 | [#192](https://github.com/dotnet/llilc/issues/192)
40 |
41 | + (**) Implement missing TODO features. Eg:
42 | + Synchronized methods [#271](https://github.com/dotnet/llilc/issues/271)
43 | + Just my code [#272](https://github.com/dotnet/llilc/issues/272)
44 | + Explicit class initialization [#274](https://github.com/dotnet/llilc/issues/274)
45 | + Union types [#275](https://github.com/dotnet/llilc/issues/275)
46 | + Virtual stub dispatch [#267](https://github.com/dotnet/llilc/issues/267)
47 | + Intrinsic calls
48 |
49 | + (***) Finish support for CoreCLR Generics.
50 |
51 | + (****) Exception Handling.
52 | Eg: [#66](https://github.com/dotnet/llilc/issues/66),
53 | [#67](https://github.com/dotnet/llilc/issues/67),
54 | [#68](https://github.com/dotnet/llilc/issues/68),
55 | [#69](https://github.com/dotnet/llilc/issues/69),
56 | [#70](https://github.com/dotnet/llilc/issues/70),
57 | [#71](https://github.com/dotnet/llilc/issues/71),
58 | [#73](https://github.com/dotnet/llilc/issues/73),
59 | [#74](https://github.com/dotnet/llilc/issues/74),
60 | [#75](https://github.com/dotnet/llilc/issues/75),
61 | [#76](https://github.com/dotnet/llilc/issues/76),
62 | [#77](https://github.com/dotnet/llilc/issues/77)
63 |
64 | + (**) Memory allocation [#233](https://github.com/dotnet/llilc/issues/233)
65 |
66 | + (***) Function inlining [#239](https://github.com/dotnet/llilc/issues/239)
67 |
68 | + (*) Enable vectorization (System.Numerics.Vector)
69 |
70 | + (**) Add aliasing information for loads that are known to be
71 | invariants (eg array length, vtables, etc).
72 | [#291](https://github.com/dotnet/llilc/issues/291)
73 |
74 | + (**) GC Lifetime Checker.
75 | [#34](https://github.com/dotnet/llilc/issues/34)
76 |
77 | + (***) Ports to other platforms.
78 | + Linux and MAC OSX are basically working, but need refining
79 | + Other platforms (eg: ARM-64)
80 |
81 | + (**) Enable deferred lowering of certain runtime
82 | constructs [#292](https://github.com/dotnet/llilc/issues/292)
83 | + Helper calls (eg: double->int conversions)
84 | + Write barriers
85 | + Struct copying
86 |
87 |
88 | + (***)Design & Architecture.
89 | Eg: [#22](https://github.com/dotnet/llilc/issues/22); Object-Model Operators;
90 |
91 | + (**) Optimizations specific to C#:
92 | + null check
93 | + bounds check
94 | + type check
95 | + overflow check
96 | + etc
97 |
98 | + (*) Add benchmarks for optimization
99 |
100 | + (\*\*) Add web-crawler to *harvest* MSIL tests and execute
101 |
102 | + (***) Generator for random (but legal) MSIL code [#503](https://github.com/dotnet/llilc/issues/503)
103 |
104 | + (**) Bugs
105 | + If you want to fix an existing bug, assign to yourself and go
106 | + If you find a new bug, please check it's not a
107 | duplicate, then enter as an issue, with as simple a repro as you can devise
108 |
109 | + (**) NGEN support [#287](https://github.com/dotnet/llilc/issues/287)
110 |
--------------------------------------------------------------------------------
/test/applyfilter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | #title :applyfilter.py
4 | #description :
5 | # This script performs normalization of verbose LLVM IR dump generated by LLILC JIT.
6 | # The module also provides support facilty for llilc_runtest and llilc_checkpass
7 | # such as ApplyAll etc.
8 | #
9 | # Normalized cases include:
10 | #
11 | # Suppress address difference from run to run
12 | # Assume the address is at least 10-digit number
13 | # Example 1:
14 | #
15 | # Normalize
16 | # %2 = call i64 inttoptr (i64 140704958972024 to i64 (i64)*)(i64 140704956891884)
17 | # to
18 | # %2 = call i64 inttoptr (i64 NORMALIZED_ADDRESS to i64 (i64)*)(i64 NORMALIZED_ADDRESS)
19 | #
20 | # Example 2:
21 | #
22 | # Normalize
23 | # %3 = icmp eq i64 140704956891886, %2
24 | # to
25 | # %3 = icmp eq i64 NORMALIZED_ADDRESS, %2
26 | #
27 | # Example 3:
28 | #
29 | # Normalize
30 | # %12 = phi i64 [ 709816494128, %3 ], [ 709816494128, %7 ]
31 | # to
32 | # %12 = phi i64 [ NORMALIZED_ADDRESS, %3 ], [ NORMALIZED_ADDRESS, %7 ]
33 | #
34 | # Suppress type id difference from run to run
35 | #
36 | # Example 1:
37 | #
38 | # Normalize
39 | # %3 = load %System.AppDomainSetup.239 addrspace(1)** %1
40 | # to
41 | # %3 = load %System.AppDomainSetup.NORMALIZED_TYPEID addrspace(1)** %1
42 | #
43 | # Example 2:
44 | #
45 | # Normalize
46 | # %0 = alloca %AppDomain.24 addrspace(1)*
47 | # to
48 | # %0 = alloca %AppDomain.NORMALIZED_TYPEID addrspace(1)*
49 | #
50 | # Suppress type id difference from run to run, string name with double quotes
51 | #==========================================================================================
52 |
53 | import os
54 | import sys
55 | import re
56 | import argparse
57 |
58 | # Apply filter on src and create a normalized file dest.
59 | # And extract out function summary if specified.
60 | def ApplyOne(src, dest, summary=None):
61 | re_addr = re.compile(r'i64 \d{10}\d*')
62 | re_type = re.compile(r'%("?)(.*?)\.\d+\1 addrspace')
63 | re_phi = re.compile(r'\[ \d{10}\d*, %')
64 | if summary is None:
65 | with open(src, 'r') as ins, open(dest, 'w') as outs:
66 | for line in ins:
67 | line = re_addr.sub(r'i64 NORMALIZED_ADDRESS', line)
68 | line = re_type.sub(r'%\1\2.NORMALIZED_TYPEID\1 addrspace', line)
69 | line = re_phi.sub(r'[ NORMALIZED_ADDRESS, %', line)
70 | outs.write(line)
71 | else:
72 | re_read_failure = re.compile(r'Failed to read ')
73 | re_read_success = re.compile(r'Successfully read ')
74 | with open(src, 'r') as ins, open(dest, 'w') as outs, open(summary, 'w') as sums:
75 | for line in ins:
76 | extract = re_read_failure.search(line)
77 | if extract is None:
78 | extract = re_read_success.search(line)
79 | if extract is not None:
80 | sums.write(line)
81 | else:
82 | line = re_addr.sub(r'i64 NORMALIZED_ADDRESS', line)
83 | line = re_type.sub(r'%\1\2.NORMALIZED_TYPEID\1 addrspace', line)
84 | line = re_phi.sub(r'[ NORMALIZED_ADDRESS, %', line)
85 | outs.write(line)
86 |
87 | # Apply filter recursively on directory walk_dir.
88 | # And extract out function summary.
89 | def ApplyAll(walk_dir):
90 | for root, sub_dirs, files in os.walk(walk_dir):
91 | for file_name in files:
92 | if file_name.endswith('error.txt'):
93 | sum_file_name = str(file_name).replace('error.txt', 'sum.txt')
94 | tmp_file_name = file_name + '.tmp'
95 | file_path = os.path.join(root, file_name)
96 | sum_file_path = os.path.join(root, sum_file_name)
97 | tmp_file_path = os.path.join(root, tmp_file_name)
98 | ApplyOne(file_path, tmp_file_path, sum_file_path)
99 | os.remove(file_path)
100 | os.rename(tmp_file_path, file_path)
101 |
102 | # Rename file name in summary result to match what ApplyAll may create
103 | # so that llilc_checkpass can perform checking.
104 | def SummaryRenameAll(walk_dir):
105 | for root, sub_dirs, files in os.walk(walk_dir):
106 | for file_name in files:
107 | if file_name.endswith('error.txt'):
108 | sum_file_name = str(file_name).replace('error.txt', 'sum.txt')
109 | file_path = os.path.join(root, file_name)
110 | sum_file_path = os.path.join(root, sum_file_name)
111 | os.rename(file_path, sum_file_path)
112 |
113 | # The script itself applies the filter on one file
114 | if __name__=='__main__':
115 | # Parse the command line
116 | parser = argparse.ArgumentParser()
117 | parser.add_argument('src', type=str, help='source result to apply filter on')
118 | parser.add_argument('dest', type=str, help='destination result after applying filter')
119 | args = parser.parse_args()
120 |
121 | # Apply the filter on one file
122 | ApplyOne(args.src, args.dest)
--------------------------------------------------------------------------------
/include/Reader/ophelper.def:
--------------------------------------------------------------------------------
1 | //===------------------- include/Reader/ophelper.h --------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Include file to make cleaner use of the opcode.def file to create mappings
13 | /// for info on MSIL ops.
14 | ///
15 | /// To use this header you must use
16 | ///
17 | /// ~~~
18 | /// #define OPDEF_HELPER
19 | /// #include ophelper.def
20 | /// ~~~
21 | ///
22 | /// This has the effect of extracting information from the opcode.def file. In particular
23 | /// a list of values is produced suitable for initializing a table.
24 | ///
25 | /// is one of these:
26 | /// - OPDEF_OPCODENAME: to get the opcode name
27 | /// - OPDEF_OPERANDSIZE: to get the operand size
28 | /// - OPDEF_PUSHCOUNT: to get the number of operands pushed
29 | /// - OPDEF_POPCOUNT: to get the number of operands popped
30 | /// - OPDEF_ISBRANCH: to tell if opcode is for a conditional branch.
31 | //===----------------------------------------------------------------------===//
32 |
33 | #ifndef OPDEF_HELPER
34 | #error "Must specify OPDEF_HELPER"
35 | #endif
36 |
37 | #define OPDEF_OPCODENAME 123001
38 | #define OPDEF_OPERANDSIZE 123002
39 | #define OPDEF_PUSHCOUNT 123003
40 | #define OPDEF_POPCOUNT 123004
41 | #define OPDEF_ISBRANCH 123005
42 |
43 |
44 | #if OPDEF_HELPER == OPDEF_OPCODENAME
45 | #define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) s,
46 | #include "opcode.def"
47 | #undef OPDEF
48 |
49 | #elif OPDEF_HELPER == OPDEF_OPERANDSIZE
50 | #define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) args,
51 | #define InlineNone 0
52 | #define ShortInlineVar 1
53 | #define ShortInlineI 1
54 | #define InlineI 4
55 | #define InlineI8 8
56 | #define ShortInlineR 4
57 | #define InlineR 8
58 | #define InlineMethod 4
59 | #define InlineSig 4
60 | #define ShortInlineBrTarget 1
61 | #define InlineBrTarget 4
62 | #define InlineSwitch -1
63 | #define InlineType 4
64 | #define InlineString 4
65 | #define InlineField 4
66 | #define InlineTok 4
67 | #define InlineVar 2
68 | #include "opcode.def"
69 | #undef OPDEF
70 | #undef InlineNone
71 | #undef ShortInlineVar
72 | #undef ShortInlineI
73 | #undef InlineI
74 | #undef InlineI8
75 | #undef ShortInlineR
76 | #undef InlineR
77 | #undef InlineMethod
78 | #undef InlineSig
79 | #undef ShortInlineBrTarget
80 | #undef InlineBrTarget
81 | #undef InlineSwitch
82 | #undef InlineType
83 | #undef InlineString
84 | #undef InlineField
85 | #undef InlineTok
86 | #undef InlineVar
87 |
88 | #elif OPDEF_HELPER == OPDEF_PUSHCOUNT
89 | #define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) push,
90 | #define Push0 0
91 | #define Push1 1
92 | #define VarPush -1
93 | #define PushI 1
94 | #define PushI4 1
95 | #define PushI8 1
96 | #define PushR4 1
97 | #define PushR8 1
98 | #define PushRef 1
99 | #include "opcode.def"
100 | #undef OPDEF
101 | #undef Push0
102 | #undef Push1
103 | #undef VarPush
104 | #undef PushI
105 | #undef PushI4
106 | #undef PushI8
107 | #undef PushR4
108 | #undef PushR8
109 | #undef PushRef
110 |
111 | #elif OPDEF_HELPER == OPDEF_POPCOUNT
112 | #define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) pop,
113 | #define Pop0 0
114 | #define Pop1 1
115 | #define VarPop -1
116 | #define PopI 1
117 | #define PopI4 1
118 | #define PopI8 1
119 | #define PopR4 1
120 | #define PopR8 1
121 | #define PopRef 1
122 | #include "opcode.def"
123 | #undef OPDEF
124 | #undef Pop0
125 | #undef Pop1
126 | #undef VarPop
127 | #undef PopI
128 | #undef PopI4
129 | #undef PopI8
130 | #undef PopR4
131 | #undef PopR8
132 | #undef PopRef
133 |
134 | #elif OPDEF_HELPER == OPDEF_ISBRANCH
135 | #define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) ctrl,
136 | #define NEXT 0
137 | #define BREAK 0
138 | #define CALL 0
139 |
140 | #if defined(_MSC_VER)
141 | #pragma push_macro("RETURN")
142 | #endif // _MSC_VER
143 |
144 | #if defined(RETURN)
145 | #undef RETURN
146 | #endif
147 | #define RETURN 0
148 | #define BRANCH 0
149 | #define COND_BRANCH 1
150 | #define THROW 0
151 | #define META 0
152 | #include "opcode.def"
153 | #undef OPDEF
154 | #undef NEXT
155 | #undef BREAK
156 | #undef CALL
157 | #undef RETURN
158 |
159 | #if defined(_MSC_VER)
160 | #pragma pop_macro("RETURN")
161 | #else
162 | #undef RETURN
163 | #endif // defined(_MSC_VER)
164 |
165 | #undef BRANCH
166 | #undef COND_BRANCH
167 | #undef THROW
168 | #undef META
169 |
170 | #else
171 | #error "Unrecognized OPDEF_HELPER"
172 | #endif
173 |
174 | #undef OPDEF_OPCODENAME
175 | #undef OPDEF_OPERANDSIZE
176 | #undef OPDEF_PUSHCOUNT
177 | #undef OPDEF_POPCOUNT
178 |
--------------------------------------------------------------------------------
/Documentation/Getting-Started-For-Windows.md:
--------------------------------------------------------------------------------
1 | # Getting Started for Windows
2 |
3 | Note: all commands are typed from a Windows Command Prompt, and `c:\dotnet`
4 | may be replaced in all commands below with the directory of your choice.
5 |
6 | * Install Git
7 | * Follow the instructions at [git-scm downloads](http://git-scm.com/downloads).
8 | All of the installer's defaults are acceptable.
9 |
10 | * Install CMake
11 | * Follow the instructions at [CMake Install](http://www.cmake.org/install/)
12 | * Make sure to select "Add CMake to the system PATH for all users" when
13 | running the installer (all other defaults are acceptable).
14 |
15 | * Clone and build CoreCLR:
16 | ```
17 | $ git clone https://github.com/dotnet/coreclr
18 | $ cd coreclr
19 | $ .\build.cmd
20 | $ cd ..
21 | ```
22 | After it completes, the build will indicate where the CoreCLR binaries
23 | are available. Make a note of this location
24 | (typically bin/Product/Windows_NT.x64.debug).
25 |
26 | * Clone the Microsoft fork of LLVM to your PC
27 | * Change directories to where you want to place your clone and run `git`
28 | to clone the Microsoft fork of LLVM:
29 | ```
30 | > cd c:\dotnet
31 | > git clone -b MS https://github.com/microsoft/llvm
32 | ```
33 |
34 | * This will create a directory tree under `llvm` that contains the cloned
35 | sources.
36 |
37 | * Clone LLILC to your PC
38 | * Because LLILC is structured as an LLVM tool, it is canonically cloned
39 | into the `tools` subdirectory of the LLVM tree created above:
40 |
41 | ```
42 | > cd c:\dotnet\llvm\tools
43 | > git clone https://github.com/dotnet/llilc
44 | ```
45 |
46 | * This will create a directory tree under `llilc` that contains the cloned
47 | sources.
48 |
49 | * Install Python
50 | * Follow the instructions at [Python Downloads](https://www.python.org/downloads/)
51 | * Choose Python 2.7.9 for Windows
52 |
53 | * Install Visual Studio 2013
54 | * Follow the instructions at [Visual Studio](http://www.visualstudio.com/en-us/products/visual-studio-community-vs)
55 | to install the free Community edition of Visual Studio 2013.
56 | * Update the product to [Visual Studio Update 4](http://www.microsoft.com/en-us/download/details.aspx?id=39305)
57 |
58 | * If you want to run [Doxygen](http://www.stack.nl/~dimitri/doxygen/) to
59 | produce documentation from your code comments, then in addition do the following:
60 | * Install [Doxygen](http://www.stack.nl/~dimitri/doxygen/) using the
61 | instructions on its web site. The LLVM web site is using Doxygen 1.7.6.1
62 | however the 1.8 series added support for Markdown formatting. We would like
63 | to use Markdown in our comments, so use the latest version of Doxygen.
64 | * Install [graphviz](http://graphviz.org/) using instructions on their
65 | site. The current version no longer modifies your path, so you should
66 | manually modify your path so that it includes "dot".
67 | * Create a Visual Studio Solution for LLVM + LLILC
68 | * Create a directory to hold the LLVM build output:
69 |
70 | ```
71 | > cd c:\dotnet
72 | > mkdir llvm-build
73 | ```
74 |
75 | * Run cmake from within the newly-created `llvm-build` directory with the
76 | Visual Studio backend to generate the LLVM solution:
77 |
78 | ```
79 | > cd llvm-build
80 | > cmake -G "Visual Studio 12 2013 Win64" ..\llvm -DWITH_CORECLR=\bin\Product\$platform.$arch.$build> -DLLVM_OPTIMIZED_TABLEGEN=ON
81 | ```
82 | note: for Windows $platform should resolve to 'Windows_NT'
83 |
84 | * However if you also want to run Doxygen, use the following instead:
85 |
86 | ```
87 | > cd llvm-build
88 | > cmake -G "Visual Studio 12 2013 Win64" ..\llvm -DLLVM_ENABLE_DOXYGEN=ON -DWITH_CORECLR=\bin\Product\$platform.$arch.$build> -DLLVM_OPTIMIZED_TABLEGEN=ON
89 | ```
90 |
91 | * This will generate `LLVM.sln` inside the `llvm-build` directory.
92 |
93 | * Build LLVM + LLILC from the command line
94 | * Change directories to the LLVM build directory and set up environment
95 | variables for the Visual Studio toolchain:
96 |
97 | ```
98 | > cd c:\dotnet\llvm-build
99 | > "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x64
100 | ```
101 |
102 | * Start the build. Note that If you have a multi-core machine, you may
103 | request a faster, parallel build by adding the `/m` flag to the command
104 | line, optionally specifying the degree of parallelism (e.g. `/m:4`).
105 |
106 | ```
107 | > msbuild LLVM.sln /p:Configuration=Debug /p:Platform=x64 /t:ALL_BUILD
108 | ```
109 |
110 | * To run doxygen over the LLILC sources use the following command line:
111 |
112 | ```
113 | > msbuild LLVM.sln /p:Configuration=Debug /p:Platform=x64 /t:doxygen-llilc
114 | ```
115 |
116 | The build steps above can also be done from Visual Studio by going to the
117 | solution explorer, right clicking the desired project (e.g. ALL_BUILD or
118 | doxygen-llilc) and selecting "build".
119 |
--------------------------------------------------------------------------------
/utils/BuildPackages.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Builds and publishes the cross-platform and combined pacakges for RyuJit. Cross-platform binaries
4 | are sourced from Azure Blob Storage.
5 | #>
6 |
7 | [CmdletBinding()]
8 | Param(
9 | # The feed to publish to.
10 | [string]$feed,
11 |
12 | # The API key to use during publishing.
13 | [string]$apiKey,
14 |
15 | # The Azure account to use.
16 | [string]$storageAccount,
17 |
18 | # The Azure account key to use.
19 | [string]$storageKey,
20 |
21 | # The Azure container to use.
22 | [string]$storageContainer,
23 |
24 | # The path to NuGet. Defaults to "nuget.exe".
25 | [string]$nugetPath = "nuget.exe",
26 |
27 | # The output directory for the cross-platform binaries.
28 | [string]$binariesDir,
29 |
30 | # The package output directory.
31 | [string]$packageOutputDir,
32 |
33 | # The directory that contains the .nuspec files that will be used to create the
34 | # cross-platform and combined packages.
35 | [string]$nuspecDir
36 | )
37 |
38 | function Get-Latest-Blob-Name
39 | {
40 | Param([array]$blobs, [string]$expectedSuffix)
41 |
42 | $chosenBlob = $null
43 | $chosenDate = $null
44 | foreach ($blob in $blobs)
45 | {
46 | if ($blob.name -notlike "*$expectedSuffix")
47 | {
48 | continue
49 | }
50 |
51 | $date = [datetime]($blob.properties."last-modified")
52 | if (!$chosenBlob -or ($chosenDate -and $date -ge $chosenDate))
53 | {
54 | $chosenBlob = $blob.name
55 | $chosenDate = $date
56 | }
57 | }
58 |
59 | return $chosenBlob
60 | }
61 |
62 | # Get the list of blobs in storage
63 | $json = (azure storage blob list -a $storageAccount -k $storageKey $storageContainer --json) -join ""
64 | $blobs = ConvertFrom-Json $json
65 |
66 | # Find, fetch, and extract the latest Ubuntu and OSX blobs
67 | [System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
68 |
69 | $ubuntuBlob = Get-Latest-Blob-Name $blobs "Ubuntu.14.04_LLILC_x64_Release_Enu.zip"
70 | $osxBlob = Get-Latest-Blob-Name $blobs "OSX_LLILC_x64_Release_Enu.zip"
71 |
72 | if (!$ubuntuBlob)
73 | {
74 | Write-Error "Could not locate an Ubuntu drop in Azure."
75 | exit 1
76 | }
77 |
78 | if (!$osxBlob)
79 | {
80 | Write-Error "Could not locate an OS X drop in Azure."
81 | exit 1
82 | }
83 |
84 | azure storage blob download -m -q -a $storageAccount -k $storageKey $storageContainer $ubuntuBlob
85 | if ($LastExitCode -ne 0)
86 | {
87 | Write-Error "Failed to fetch Ubuntu drop $ubuntuDrop from Azure."
88 | exit 1
89 | }
90 |
91 | azure storage blob download -m -q -a $storageAccount -k $storageKey $storageContainer $osxBlob
92 | if ($LastExitCode -ne 0)
93 | {
94 | Write-Error "Failed to fetch OS X drop $osxBlob from Azure."
95 | exit 1
96 | }
97 |
98 | $ubuntuDirectory = [System.IO.Path]::GetFileNameWithoutExtension($ubuntuBlob)
99 | try
100 | {
101 | [System.IO.Compression.ZipFile]::ExtractToDirectory($ubuntuBlob, $ubuntuDirectory)
102 | }
103 | catch
104 | {
105 | Write-Error "Failed to extract Ubuntu drop to $ubuntuDirectory`: $_.Exception.Message"
106 | exit 1
107 | }
108 |
109 | $osxDirectory = [System.IO.Path]::GetFileNameWithoutExtension($osxBlob)
110 | try
111 | {
112 | [System.IO.Compression.ZipFile]::ExtractToDirectory($osxBlob, $osxDirectory)
113 | }
114 | catch
115 | {
116 | Write-Error "Failed to extract OS X drop to $osxDirectory`: $_.Exception.Message"
117 | exit 1
118 | }
119 |
120 | # Gather the bits from the Ubuntu and OSX blobs into the bin directory
121 | $items = @(
122 | "$ubuntuDirectory\libobjwriter.so",
123 | "$osxDirectory\libobjwriter.dylib",
124 | )
125 |
126 | Copy-Item -Path $items -Destination $binariesDir
127 | if ($LastExitCode -ne 0)
128 | {
129 | Write-Error "Failed to copy cross-platform bits to $binariesDir."
130 | exit 1
131 | }
132 |
133 | if (!(Test-Path $packageOutputDir))
134 | {
135 | New-Item $packageOutputDir -Type Directory
136 | if ($LastExitCode -ne 0)
137 | {
138 | Write-Error "Failed to create $packageOutputDir"
139 | exit 1
140 | }
141 | }
142 |
143 | # Gather the .nuspecs and their dependencies into the package output directory
144 | $files = @(
145 | "$nuspecDir\Microsoft.DotNet.ObjectWriter.nuspec",
146 | "$nuspecDir\runtime.json",
147 | "$nuspecDir\toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter.nuspec",
148 | "$nuspecDir\toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter.nuspec",
149 | "$nuspecDir\toolchain.win7-x64.Microsoft.DotNet.ObjectWriter.nuspec"
150 | )
151 | Copy-Item -Path $files -Destination $packageOutputDir
152 | if ($LastExitCode -ne 0)
153 | {
154 | Write-Error "Failed to copy nuspecs to $packageOutputDir."
155 | exit 1
156 | }
157 |
158 | # Create the packages.
159 | $packages = @(
160 | "Microsoft.DotNet.ObjectWriter",
161 | "toolchain.osx.10.10-x64.Microsoft.DotNet.ObjectWriter",
162 | "toolchain.ubuntu.14.04-x64.Microsoft.DotNet.ObjectWriter",
163 | "toolchain.win7-x64.Microsoft.DotNet.ObjectWriter"
164 | )
165 |
166 | # Note: nuget appears to exit with code 0 in every case, so there's no way to detect failure here
167 | # other than looking at the output.
168 | foreach ($package in $packages) {
169 | Invoke-Expression "$nugetPath pack $packageOutputDir\$package.nuspec -NoPackageAnalysis -NoDefaultExludes -OutputDirectory $packageOutputDir"
170 | Invoke-Expression "$nugetPath push -NonInteractive $packageOutputDir\$package.nupkg -s $feed $apiKey"
171 | }
172 |
--------------------------------------------------------------------------------
/Documentation/Setup-With-LLILC-Out-Of-LLVM-Tree.md:
--------------------------------------------------------------------------------
1 | # Setup With LLILC Out-Of LLVM Tree
2 |
3 | The [Getting Started for Windows doc](Getting-Started-For-Windows.md) tells
4 | how to configure LLILC when the LLILC repository is placed in the LLVM/tools
5 | subdirectory. This page tells how to configure LLVM and LLILC when the LLILC
6 | workspace is separate from the LLVM workspace. This might be desirable, for
7 | example, if you want to have multiple LLILC workspaces (for working on
8 | multiple branches simultaneously) but want to share a single LLVM workspace
9 | and LLVM build.
10 |
11 | We document which steps are the same and which steps that are different
12 | from the [Getting Started for Windows document](Getting-Started-For-Windows.md).
13 |
14 | Steps that are the same are:
15 |
16 | * Install Git
17 | * Clone and build CoreCLR:
18 | * Clone the Microsoft fork of LLVM to your PC
19 | * Install Python
20 | * Install CMake
21 | * Install Visual Studio 2013
22 | * Install [Doxygen](http://www.stack.nl/~dimitri/doxygen/)
23 | * Install [graphviz](http://graphviz.org/)
24 |
25 | In what follows, let
26 |
27 | * $coreclr-repo-dir be the directory where the the coreclr was cloned.
28 | * $coreclr-build-dir be $coreclr-repo-dir\bin\Product\$platform.$arch.$build> directory.
29 | * $llvm-repo-dir be the directory where LLVM was cloned.
30 | * $llvm-build-dir be the directory where LLVM was built.
31 | * $llilc-repo-dir be the directory where LLILC was cloned
32 | * $llilc-build-dir be the directory where LLILC is built
33 |
34 | $coreclr-build-dir is fixed relative to $coreclr-repo-dir, but all of the others can be
35 | placed wherever you like. Below we use paths like $llilc-repo-dir/.. to denote the
36 | parent directory of $llilc-repo-dir. When we do a `cd` to a directory we assume you
37 | have previously created the directory. To simplify the description we also assume you
38 | will be enabling Doxygen.
39 |
40 | Steps that are different:
41 |
42 | * Clone LLILC to your PC
43 | * Unlike the [Getting Started for Windows](Getting-Started-For-Windows.md)
44 | directions, create a separate LLILC directory.:
45 |
46 | ```
47 | > cd $llilc-repo-dir/..
48 | > git clone https://github.com/dotnet/llilc
49 | ```
50 |
51 | * This will create a directory tree under $llilc-repo-dir that contains
52 | the cloned sources.
53 |
54 | * Create a Visual Studio Solution for LLVM
55 | * Create a directory to hold the LLVM build output:
56 |
57 | ```
58 | > mkdir $llvm-build-dir
59 | ```
60 |
61 | * Run cmake from within the newly-created `llvm-build` directory with the
62 | Visual Studio backend to generate the LLVM solution:
63 |
64 | ```
65 | > cd $llvm-build-dir
66 | > cmake -G "Visual Studio 12 2013 Win64" $llvm-repo-dir -DLLVM_OPTIMIZED_TABLEGEN=ON -DLLVM_TARGETS_TO_BUILD:STRING=X86 -DLLVM_ENABLE_DOXYGEN=ON
67 | ```
68 |
69 | * This will generate `LLVM.sln` inside the $llvm-build-dir directory.
70 |
71 | * Build LLVM from the command line
72 | * Change directories to the LLVM build directory and set up environment
73 | variables for the Visual Studio toolchain:
74 |
75 | ```
76 | > cd $llvm-build-dir
77 | > "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x64
78 | ```
79 |
80 | * Start the build. Note that If you have a multi-core machine, you may
81 | request a faster, parallel build by adding the `/m` flag to the command
82 | line, optionally specifying the degree of parallelism (e.g. `/m:4`).
83 |
84 | ```
85 | > msbuild LLVM.sln /p:Configuration=Debug /p:Platform=x64 /t:ALL_BUILD
86 | ```
87 |
88 | * Create a Visual Studio Solution for LLILC
89 | * Create a directory to hold the LLILC build output:
90 |
91 | ```
92 | > mkdir $llilc-build-dir
93 | ```
94 |
95 | * Run cmake from within the newly-created `llilc-build` directory with the
96 | Visual Studio backend to generate the LLVM solution:
97 |
98 | ```
99 | > cd $llilc-build-dir
100 | > cmake -G "Visual Studio 12 2013 Win64" $llilc-repo-dir -DWITH_CORECLR=$coreclr-build-dir -DWITH_LLVM=$llvm-build-dir -DLLVM_OPTIMIZED_TABLEGEN=ON -DLLVM_TARGETS_TO_BUILD:STRING=X86 -DLLVM_ENABLE_DOXYGEN=ON
101 | ```
102 |
103 | * This will generate `LLILC.sln` inside the $llilc-build-dir directory.
104 | * Currently there is a bug in the LLVM configuration that leaves some file
105 | paths in Windows format with back slashes. If you get an error message
106 | when configuring, like
107 | ```
108 | Syntax error in cmake code at
109 |
110 | share/llvm/cmake/LLVMExports.cmake:233
111 |
112 | when parsing string
113 |
114 | ...C:\Program Files (x86)\...
115 |
116 | Invalid escape sequence \P
117 | ```
118 | you can work around it by editing the offending line by
119 | changing the back slashes to forward slashes.
120 |
121 | * Build LLILC from the command line
122 | * Change directories to the LLVM build directory and set up environment
123 | variables for the Visual Studio toolchain:
124 |
125 | ```
126 | > cd $llilc-build-dir
127 | > "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x64
128 | ```
129 |
130 | * Start the build. Note that If you have a multi-core machine, you may
131 | request a faster, parallel build by adding the `/m` flag to the command
132 | line, optionally specifying the degree of parallelism (e.g. `/m:4`).
133 |
134 | ```
135 | > msbuild LLILC.sln /p:Configuration=Debug /p:Platform=x64 /t:ALL_BUILD
136 | ```
137 |
138 | * To run doxgen over the LLILC sources use the following command line:
139 |
140 | ```
141 | > msbuild LLVM.sln /p:Configuration=Debug /p:Platform=x64 /t:doxygen-llilc
142 | ```
143 |
--------------------------------------------------------------------------------
/Documentation/Testing.md:
--------------------------------------------------------------------------------
1 | # Testing LLILC
2 |
3 | ## Test Harness
4 |
5 | LLILC's test harness uses CoreCLR's test assets as underlying engine. It
6 | provides a LLILC-specific wrapper layer above it. The test harness is located
7 | at llilc\test. Please add this path to your PATH environment variable before
8 | using it.
9 |
10 | There are three steps in LLILC testing: building tests, running tests, and
11 | checking results.
12 |
13 | ## Building tests:
14 |
15 | Building tests is performed with CoreCLR script directly. A CoreCLR build
16 | automatically performs building tests. If it is done already, you can choose
17 | to skip this step. If you want to build test as a separate step, do the following:
18 |
19 | ```
20 | cd C:\coreclr\tests
21 | buildtest.cmd clean
22 | ```
23 | https://github.com/dotnet/coreclr/wiki/Test-instructions for more information.
24 |
25 | ## Running tests:
26 |
27 | Use llilc_runtest.py to run tests. With specified LLILC JIT and pre-built
28 | CoreCLR runtime, llilc_runtest runs CoreCLR testing. You can choose to create
29 | a running result if you want to. The result contains LLILC specific dumps:
30 | per function summary or detailed LLVM IR dumps. You need to run this script
31 | from coreclr\tests directory.
32 | ```
33 | cd C:\coreclr\tests
34 | llilc_runtest -d verbose -j C:\llvm-build\bin\Debug\llilcjit.dll -c C:\coreclr\bin\Product\Windows_NT.x64.Debug -r C:\results\base
35 | ```
36 | llilc_runtest --help for more information.
37 |
38 | **Note:** You may find that running tests with a pure DEBUG build of LLILC
39 | is very slow. To get a faster build that still has assertion checking, pass
40 | `-DCMAKE_BUILD_TYPE=RELWITHDEBINFO -DLLVM_ENABLE_ASSERTIONS=ON` to cmake and
41 | `/p:Configuration=RelWithDebInfo` to msbuild when you configure/build LLILC/LLVM.
42 |
43 | ## Checking results:
44 |
45 | Use llilc_checkpass to check the results. It takes two test results, using
46 | one as base result, one as diff result to perform the checking. This step is
47 | LLILC-specific. Because LLILC is still under early stage of development, we
48 | need to guarantee that any function that was successfully jitted by LLILC is
49 | not broken by new change.
50 | ```
51 | llilc_checkpass -b C:\results\base -d C:\results\diff
52 | ```
53 | llilc_checkpass --help for more information.
54 |
55 | It is required that developer has to guarantee all LLVM IR changes are benign.
56 | It can be achieved with any diff tool.
57 |
58 | ## Running individual tests:
59 |
60 | The process for running individual test cases on Windows in cmd is:
61 | * Copy the LLILCJit.dll in `llvm-build/bin/Debug` to the CoreCLR binary
62 | directory (`coreclr/bin/Product//`)
63 | * Run the `llilc/test/LLILCTestEnv.cmd` to set the needed env variables. If
64 | debug printing is desired, also run `set COMPlus_DumpLLVMIR=[summary, verbose]`.
65 | * Set the code page to 65001 (See #527 and #12).
66 | * Run the test binary via CoreRun.exe.
67 |
68 | ## Using llilc as an ngen jit:
69 |
70 | crossgen.exe is the tool used to generate ngen images for CoreCLR. The
71 | generated native image has .ni.exe or .ni.dll suffix. crossgen requires
72 | mscorlib.ni.dll to be available – you have to generate mscorlib.ni.dll first.
73 | The following environment variable needs to be set (in addition to running
74 | llilc/test/LLILCTestEnv.cmd):
75 | `set COMPlus_AltJitNgen=*`.
76 |
77 | ## Use Cases
78 |
79 | ### Developer Use Case
80 | Step 1: Update CoreCLR to latest, and build CoreCLR
81 |
82 | Step 2: Update LLILC master to latest, and build your baseline JIT
83 |
84 | Step 3: Create a verbose baseline result:
85 |
86 | ```
87 | cd coreclr\tests
88 | llilc_runtest -j -c -d verbose -r
89 | ```
90 | Step 4: Create your own branch
91 |
92 | Step 5: Do new development or fix issues on your branch, and build your new diff JIT
93 |
94 | Step 6: Check your change pass overall testing:
95 |
96 | ```
97 | cd coreclr\tests
98 | llilc_runtest -j -c
99 | ```
100 | If failed, back to step 5 for fixing.
101 |
102 | Step 7: Check you change does not cause new jitting failure:
103 |
104 | ```
105 | cd coreclr\tests
106 | llilc_runtest -j -c -d summary -r
107 | llilc_checkpass -b -d
108 | ```
109 | If failed, back to step 5 for fixing.
110 |
111 | Step 8: Check your change does not cause bad LLVM IR change.
112 |
113 | ```
114 | llilc_runtest -j -c -d verbose -r
115 | ```
116 | Use any diff tool to compare \ and \.
117 | If there is bad LLVM IR change, back to step 5 for fixing.
118 |
119 | Step 9: Now you are ready for a pull request.
120 |
121 | ### Lab CI Use Case
122 | Lab CI usage is the most simplified version. It only checks for overall
123 | pass/fail and does not keep any result.
124 | ```
125 | cd coreclr\tests
126 | llilc_runtest -j -c
127 | ```
128 |
129 | ### Lab Nightly Use Case
130 | Step 1. Create a summary result with last-known-good JIT as a baseline or use
131 | a previous last-known-good summary result as a baseline
132 | ```
133 | cd coreclr\tests
134 | llilc_runtest -j -c -d summary -c
135 | ```
136 |
137 | Step 2. Create a summary result with latest JIT as diff result
138 | ```
139 | cd coreclr\tests
140 | llilc_runtest -j -c -d summary -r
141 | ```
142 |
143 | Step 3. Check if there is any new jitting failure
144 | ```
145 | cd coreclr\tests
146 | llilc_checkpass -b -d
147 | ```
148 |
149 | Step 4. If llilc_checkpass result is negative, there is unexpected error.
150 |
151 | Step 5.If llilc_checkpass result is 0, mark latest JIT as last-known-good JIT.
152 | Result \ could be kept as last-known-good summary result.
153 |
154 | Step 6.If llilc_checkpass result is 1, send out failure notice to branch owner.
155 | Branch owner should analyze the case and bring relevant developer for fixing.
156 |
--------------------------------------------------------------------------------
/include/Jit/jitoptions.h:
--------------------------------------------------------------------------------
1 | //===----------------- include/Jit/options.h -------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declaration of the Options class that encapsulates JIT options
13 | /// extracted from CoreCLR config values.
14 | ///
15 | //===----------------------------------------------------------------------===//
16 |
17 | #ifndef JITOPTIONS_H
18 | #define JITOPTIONS_H
19 |
20 | #include "options.h"
21 |
22 | /// \brief The JIT options implementation.
23 | ///
24 | /// This class queries the CoreCLR interface to compute the Options flags
25 | /// consumed by the JIT. The query logic here should only be usable from the
26 | /// base JIT at initialization time of the context.
27 | ///
28 | /// This derived class is responsible for filling out the base fields
29 | /// as well as it's own. The base Options class contains options used in
30 | /// all configurations but includes to query logic to fill them out as that
31 | /// will be client based (JIT or AOT)
32 | ///
33 | class JitOptions : public Options {
34 | public:
35 | /// Construct an JitOptions object based on the passed JitContext.
36 | JitOptions(LLILCJitContext &JitContext);
37 |
38 | /// Destruct Options object.
39 | ~JitOptions();
40 |
41 | private:
42 | /// Set current JIT invocation as "AltJit". This sets up
43 | /// the JIT to filter based on the AltJit flag contents.
44 | /// \returns true if runing as the alternate JIT
45 | static bool queryIsAltJit(LLILCJitContext &JitContext);
46 |
47 | /// \brief Compute dump level for the JIT
48 | ///
49 | /// Dump level requested via CLR config for the JIT
50 | /// \returns Computed DumpLevel
51 | static ::DumpLevel queryDumpLevel(LLILCJitContext &JitContext);
52 |
53 | /// \brief Set optimization level for the JIT.
54 | ///
55 | /// Opt Level based on CLR provided flags and environment.
56 | /// \returns Computed OptLevel
57 | static ::OptLevel queryOptLevel(LLILCJitContext &JitContext);
58 |
59 | /// \brief Set UseConservativeGC based on environment variable.
60 | ///
61 | /// \returns true if COMPLUS_GCCONSERVATIVE is set in the environment.
62 | static bool queryUseConservativeGC(LLILCJitContext &JitContext);
63 |
64 | /// \brief Set DoInsertStatepoints
65 | ///
66 | /// \returns true if insert statepoints is indicated in the
67 | /// environment to model precise GC. (COMPLUS_INSERTSTATEPOINTS)
68 | static bool queryDoInsertStatepoints(LLILCJitContext &JitContext);
69 |
70 | /// \brief Set DoTailCallOpt based on environment variable.
71 | ///
72 | /// \returns true if COMPLUS_TAILCALLOPT is set in the environment.
73 | static bool queryDoTailCallOpt(LLILCJitContext &JitContext);
74 |
75 | /// \brief Set LogGcInfo based on environment variable.
76 | ///
77 | /// \returns true if COMPLUS_JitGCInfoLogging is set in the environment.
78 | static bool queryLogGcInfo(LLILCJitContext &JitContext);
79 |
80 | /// \brief Set ExecuteHandlers based on envirionment variable.
81 | ///
82 | /// \returns true if COMPlus_ExecuteHandlers is set in the environment.
83 | static bool queryExecuteHandlers(LLILCJitContext &JitContext);
84 |
85 | /// \brief Define set of methods to exclude from LLILC compilation
86 | ///
87 | /// \returns true if current method is in that set.
88 | static bool queryIsExcludeMethod(LLILCJitContext &JitContext);
89 |
90 | /// \brief Define set of methods on which to break.
91 | ///
92 | /// \returns true if current method is in that set.
93 | static bool queryIsBreakMethod(LLILCJitContext &JitContext);
94 |
95 | /// \brief Define set of methods for which to dump MSIL
96 | ///
97 | /// \returns true if current method is in that set.
98 | static bool queryIsMSILDumpMethod(LLILCJitContext &JitContext);
99 |
100 | /// \brief Define set of methods for which to dump LLVM IR.
101 | ///
102 | /// \returns true if current method is in that set.
103 | static bool queryIsLLVMDumpMethod(LLILCJitContext &JitContext);
104 |
105 | /// \brief Define set of methods for which to print code address range.
106 | ///
107 | /// \returns true if current method is in that set.
108 | static bool queryIsCodeRangeMethod(LLILCJitContext &JitContext);
109 |
110 | static bool queryMethodSet(LLILCJitContext &JitContext, MethodSet &TheSet,
111 | const char16_t *Name);
112 |
113 | /// \brief Check for non-null non-empty configuration variable.
114 | ///
115 | /// \param Name The name of the configuration variable
116 | /// \returns true if configuration variable is non-null and non-empty.
117 | static bool queryNonNullNonEmpty(LLILCJitContext &JitContext,
118 | const char16_t *Name);
119 |
120 | /// \brief Set SIMD intrinsics using.
121 | ///
122 | /// \returns true if SIMD_INTRINSIC is set in the environment set.
123 | static bool queryDoSIMDIntrinsic(LLILCJitContext &JitContext);
124 |
125 | public:
126 | bool IsAltJit; ///< True if running as the alternative JIT.
127 | bool IsExcludeMethod; ///< True if method is to be excluded.
128 | ///< Jit if IsAltJit && !IsExcludeMethod
129 | bool IsBreakMethod; ///< True if break requested when compiling this method.
130 | bool IsMSILDumpMethod; ///< True if dump of MSIL requested.
131 | bool IsLLVMDumpMethod; ///< True if dump of LLVM requested.
132 | bool IsCodeRangeMethod; ///< True if desired to dump entry address and size.
133 |
134 | private:
135 | static MethodSet AltJitMethodSet; ///< Singleton AltJit MethodSet.
136 | static MethodSet AltJitNgenMethodSet; ///< Singleton AltJitNgen MethodSet.
137 | static MethodSet ExcludeMethodSet; ///< Methods to exclude from jitting.
138 | static MethodSet BreakMethodSet; ///< Methods to break.
139 | static MethodSet MSILMethodSet; ///< Methods to dump MSIL.
140 | static MethodSet LLVMMethodSet; ///< Methods to dump LLVM IR.
141 | static MethodSet CodeRangeMethodSet; ///< Methods to dump code range
142 | };
143 |
144 | #endif // JITOPTIONS_H
145 |
--------------------------------------------------------------------------------
/include/Jit/utility.h:
--------------------------------------------------------------------------------
1 | //===----------------- include/Jit/utility.h -------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declarations of utility classes.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef UTILITY_H
17 | #define UTILITY_H
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #include "cor.h"
24 | #include "utility.h"
25 |
26 | #include "llvm/Support/Atomic.h"
27 | #include "llvm/ADT/STLExtras.h"
28 | #include "llvm/Config/llvm-config.h"
29 |
30 | // The MethodID.NumArgs field may hold either of 2 values:
31 | // Empty => the input string was all-blank, or empty.
32 | // AnyArgs => the pattern did not specify any constraint on the number of
33 | // arguments. Eg: "foo" as opposed to "foo()", "foo(3)", etc
34 |
35 | enum MethodIDState { Empty = -7, AnyArgs = -1 };
36 |
37 | /// \brief MethodID struct represents a Method Signature.
38 | ///
39 | /// MethodIDs are held in a MethodSet and are used to decide which
40 | /// methods should be compiled when running as an "alt" JIT.
41 |
42 | class MethodID {
43 | public:
44 | /// Class name.
45 | std::unique_ptr ClassName;
46 | /// Method Name
47 | std::unique_ptr MethodName;
48 | /// Number of method arguments. MethodIDState::AnyArgs => not specified
49 | int NumArgs;
50 |
51 | /// Default constructor.
52 | MethodID()
53 | : ClassName(nullptr), MethodName(nullptr),
54 | NumArgs(MethodIDState::AnyArgs) {}
55 |
56 | /// Copy constructor.
57 | MethodID(const MethodID &Other) {
58 | if (Other.ClassName) {
59 | ClassName = llvm::make_unique(*Other.ClassName);
60 | } else {
61 | ClassName = nullptr;
62 | }
63 | if (Other.MethodName) {
64 | MethodName = llvm::make_unique(*Other.MethodName);
65 | } else {
66 | MethodName = nullptr;
67 | }
68 | this->NumArgs = Other.NumArgs;
69 | }
70 |
71 | /// Copy assignment operator.
72 |
73 | MethodID &operator=(const MethodID &Other) {
74 | if (this == &Other)
75 | return *this;
76 | if (Other.ClassName) {
77 | ClassName = llvm::make_unique(*Other.ClassName);
78 | } else {
79 | ClassName = nullptr;
80 | }
81 | if (Other.MethodName) {
82 | MethodName = llvm::make_unique(*Other.MethodName);
83 | } else {
84 | MethodName = nullptr;
85 | }
86 | NumArgs = Other.NumArgs;
87 | return *this;
88 | }
89 |
90 | /// Parse a string into a MethodID.
91 | /// Parse string S, starting at index I, into a MethodID. The string can be
92 | /// any of the following patterns:
93 | /// * => any method.
94 | /// M => method M, with any number of arguments.
95 | /// C:M => method M in class C.
96 | ///
97 | /// C can be a simple class name, or a namespace.classname. For example,
98 | /// "Sort" or "System.Array:Sort". (The dots in a namespace are ignored).
99 | ///
100 | /// M can be followed by the pattern (number) to specify its number of
101 | /// arguments. For example, .ctor(0) or Adjust(2)
102 | ///
103 | /// If the parse encounters an invalid pattern, we return nullptr.
104 | ///
105 | /// In actual use, S may consist of several such patterns, separated by one
106 | /// or more spaces. Therefore, leading spaces are skipped, but subsequent
107 | /// space is significant.
108 | ///
109 | // Eg: " foo Ns.MyClass:bar System.Array.Sort " holds 3 patterns.
110 |
111 | static std::unique_ptr parse(const std::string &S, size_t &I);
112 |
113 | // Scan the string S, starting at index I, for the next lexical token.
114 | // A token is terminated by any of {space, end-of-string, :, (, )}.
115 | //
116 | // Return the token, or empty string if none found. Update I to index
117 | // the character just past the end of the token.
118 |
119 | std::string scan(const std::string &S, size_t &I);
120 |
121 | // Parse string S, starting at index I, to determine how many arguments
122 | // the function specifies. On entry, S[I] holds the character '('.
123 |
124 | int parseArgs(const std::string &S, size_t &I);
125 | };
126 |
127 | /// \brief MethodSet comprises a set of MethodID objects
128 | ///
129 | /// MethodSet specifies the methods to compile with the "alt" JIT.
130 |
131 | class MethodSet {
132 | public:
133 | /// Test if the MethodSet is empty.
134 | /// \returns true if MethodSet is empty.
135 |
136 | bool isEmpty() {
137 | assert(this->isInitialized());
138 | return (this->MethodIDList->size() == 0);
139 | }
140 |
141 | /// Test whether specified method is matched in current MethodSet.
142 | /// \param MethodName Name of method
143 | /// \param ClassName Encapsulating namespace+class of the method.
144 | /// \param sig Pointer to method signature.
145 | /// \return true if Method is contained in Set.
146 |
147 | bool contains(const char *MethodName, const char *ClassName,
148 | PCCOR_SIGNATURE Sig);
149 |
150 | /// Initialize a new MethodSet - once only.
151 | void init(std::unique_ptr ConfigValue);
152 |
153 | /// Check whether current MethodSet has been initialized.
154 | bool isInitialized() { return MethodIDList != nullptr; }
155 |
156 | /// \brief Parse the string S into one or more MethodIDs, and insert
157 | /// them into current MethodSet.
158 | void insert(std::unique_ptr S);
159 |
160 | private:
161 | /// Internal initialized flag. This should only be accessed via interlocked
162 | /// exchange operations, since several methods may be JIT'ing concurrently.
163 | uint32_t Initialized = 0;
164 |
165 | /// MethodSigList implementing the set.
166 | std::list *MethodIDList = nullptr;
167 | };
168 |
169 | /// \brief Class implementing miscellaneous conversion functions.
170 | class Convert {
171 | public:
172 | /// Convert a UTF-16 string to a UTF-8 string.
173 | static std::unique_ptr utf16ToUtf8(const char16_t *WideStr);
174 | };
175 |
176 | #endif // UTILITY_H
177 |
--------------------------------------------------------------------------------
/include/Reader/newvstate.h:
--------------------------------------------------------------------------------
1 | //===------------------- include/Reader/newvstate.h -------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Data structures for holding verification state.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef MSIL_READER_NEW_VSTATE_H
17 | #define MSIL_READER_NEW_VSTATE_H
18 |
19 | #include "vtypeinfo.h"
20 | #include "corerror.h"
21 | #include "gverify.h"
22 |
23 | class LocalDescr {
24 | public:
25 | CorInfoType Type;
26 | CORINFO_CLASS_HANDLE Class;
27 | };
28 |
29 | class VerificationState {
30 | public:
31 | bool BlockIsBad;
32 | bool *ArgsInitialized;
33 |
34 | // This field caches the token of the delegate method
35 | // in a potential delegate creation sequence.
36 | mdToken DelegateMethodRef;
37 |
38 | uint32_t ConstrainedPrefix : 1;
39 | uint32_t ReadonlyPrefix : 1;
40 | uint32_t TailPrefix : 1;
41 | uint32_t VolatilePrefix : 1;
42 | uint32_t UnalignedPrefix : 1;
43 | uint32_t TailInBlock : 1;
44 | // say we initialize the 'this' pointer in a try.
45 | // Real successors of the block can assume 'this' is inited.
46 | // nominal successors cannot. However if we know 'this' was inited in
47 | uint32_t ThisInitializedThisBlock : 1;
48 | uint32_t StrongThisInitialized : 1;
49 | uint32_t ContainsCtorCall : 1; // block is in a ctor and calls a parent or
50 | // same class ctor
51 | const uint8_t *DelegateCreateStart;
52 |
53 | InitState ThisInitialized; // 'this' has been initialized on some paths
54 | private:
55 | VerType *Vstack;
56 | uint32_t Vsp;
57 | uint32_t MaxStack;
58 |
59 | VerificationState() {}
60 |
61 | public:
62 | ReaderBase *Base;
63 |
64 | inline void setStack(VerType *StackMem);
65 |
66 | inline void init(uint32_t MaxStackSize, uint32_t NumLocals, bool InitLocals,
67 | InitState InitState);
68 |
69 | inline void print();
70 |
71 | inline void push(VerType Typ);
72 |
73 | inline VerType pop();
74 |
75 | inline VerType impStackTop(uint32_t N = 0);
76 |
77 | // pop an objref which might be an uninitialized 'this' ptr
78 | // See Partion 3 1.8.1.4
79 | // No operations can be performed on an uninitialized 'this'
80 | // except for storing into and loading from the object's fields.
81 | inline VerType popPossiblyUninit();
82 |
83 | inline uint32_t stackLevel() { return Vsp; }
84 |
85 | bool isThisPublishable() {
86 | if (ThisInitialized == ThisInited || ThisInitialized == ThisEHReached)
87 | return true;
88 | else
89 | return false;
90 | }
91 |
92 | bool isThisInitialized() { return (ThisInitialized == ThisInited); }
93 |
94 | void setThisInitialized() {
95 | // if its EHREACHED keep that
96 | if (ThisInitialized != ThisEHReached)
97 | ThisInitialized = ThisInited;
98 | }
99 | };
100 |
101 | void VerificationState::setStack(VerType *StackMem) { Vstack = StackMem; }
102 |
103 | void VerificationState::init(uint32_t MaxStackSize, uint32_t NumLocals,
104 | bool InitLocals, InitState InitState) {
105 | Vsp = 0;
106 | MaxStack = MaxStackSize;
107 | DelegateMethodRef = mdTokenNil;
108 |
109 | BlockIsBad = false;
110 | ConstrainedPrefix = false;
111 | ReadonlyPrefix = false;
112 | TailPrefix = false;
113 | VolatilePrefix = false;
114 | UnalignedPrefix = false;
115 | TailInBlock = false;
116 | DelegateCreateStart = nullptr;
117 | ThisInitializedThisBlock = false;
118 |
119 | ThisInitialized = InitState;
120 | StrongThisInitialized = false;
121 |
122 | for (uint32_t I = 0; I < NumLocals; I++) {
123 | ArgsInitialized[I] = InitLocals;
124 | }
125 | }
126 |
127 | VerType VerificationState::pop() {
128 | VerType Ret = popPossiblyUninit();
129 | Base->verifyAndReportFound((!Ret.isObjRef()) ||
130 | (!Ret.isUninitialisedObjRef()),
131 | Ret, MVER_E_STACK_UNINIT);
132 | return Ret;
133 | }
134 |
135 | // See Partion 3 1.8.1.4
136 | // No operations can be performed on an uninitialized 'this'
137 | // except for storing into and loading from the object's fields.
138 | VerType VerificationState::popPossiblyUninit() {
139 | Base->gverifyOrReturn(Vsp > 0, MVER_E_STACK_UNDERFLOW);
140 |
141 | Vsp--;
142 | VerType Result = Vstack[Vsp];
143 |
144 | // blank out the thing we just popped
145 | #ifndef NDEBUG
146 | memset(Vstack + Vsp, 0xcd, sizeof(VerType));
147 | #endif
148 |
149 | return Result;
150 | }
151 |
152 | void VerificationState::push(VerType Typ) {
153 | Base->gverifyOrReturn(Vsp < MaxStack, MVER_E_STACK_OVERFLOW);
154 | Vstack[Vsp] = Typ;
155 | Vsp++;
156 | }
157 |
158 | VerType VerificationState::impStackTop(uint32_t N) {
159 | Base->gverifyOrReturn(Vsp > N, MVER_E_STACK_UNDERFLOW);
160 |
161 | return Vstack[Vsp - N - 1];
162 | }
163 |
164 | // =========================================================================
165 | // ================ Exceptions
166 | // =========================================================================
167 |
168 | class CallAuthorizationException : public ReaderException {};
169 |
170 | class VerificationException : public ReaderException {
171 | public:
172 | uint32_t DwFlags; // VER_ERR_XXX
173 |
174 | union {
175 | ReaderBaseNS::OPCODE Opcode;
176 | uint32_t Padding1; // to match with idl generated struct size
177 | };
178 |
179 | union {
180 | uint32_t DwOffset; // #of bytes from start of method
181 | long Offset; // for backward compat with Metadata validator
182 | };
183 |
184 | union {
185 | mdToken Token; // for backward compat with metadata validator
186 | uint8_t CallConv;
187 | CorElementType Elem;
188 | uint32_t StackSlot; // positon in the Stack
189 | uint32_t Padding2; // to match with idl generated struct size
190 | };
191 |
192 | union {
193 | uint32_t Exception1; // Exception Record #
194 | uint32_t VarNumber; // Variable #
195 | uint32_t ArgNumber; // Argument #
196 | uint32_t Operand; // Operand for the opcode
197 | };
198 |
199 | union {
200 | uint32_t Exception2; // Exception Record #
201 | };
202 | };
203 |
204 | #endif // MSIL_READER_NEW_VSTATE_H
205 |
--------------------------------------------------------------------------------
/Documentation/llilc-gc-transition.md:
--------------------------------------------------------------------------------
1 | # GC Transition Support in LLILC
2 |
3 | The CoreCLR runtime supports calls from managed (i.e. GC-aware) code to
4 | unmanaged (i.e. GC-unaware) code. In the runtime's parlance, such calls are
5 | termed "P/Invokes" (short for Platform Invoke); in LLILC/LLVM they are referred
6 | to as "unmanaged calls" or "GC transitions". Because the target of such a call
7 | is not aware of the CoreCLR GC, such calls require runtime-specific setup and
8 | teardown code. The nature of this transition code requires code in both LLILC
9 | and LLVM. A brief discussion of the specifics of GC transitions in CoreCLR and
10 | the support for these transitions in LLILC and LLVM follows.
11 |
12 | ## GC transitions in CoreCLR
13 |
14 | In order for the CoreCLR garbage collector to perform garbage collection it must
15 | be able to
16 | 1. logically pause all threads that are running managed code, and
17 | 2. scan each thread's stack for GC references.
18 |
19 | ### Thread suspension and GC modes
20 |
21 | To meet the first requirement above without physically suspending arbitrary
22 | threads (and thus aggravating the chance of deadlocks in the runtime), each
23 | thread that the runtime is tracking is assigned one of two modes: cooperative
24 | mode and preemptive mode.
25 |
26 | #### Cooperative mode
27 |
28 | Threads in cooperative mode are considered to be running managed code. These
29 | threads are therefore potentially modifying GC references, and must cooperate
30 | with the runtime in order to reach a GC safepoint before a collection may
31 | occur. All managed code (and almost all JIT compiled code) will run in
32 | cooperative mode.
33 |
34 | #### Preemptive mode
35 |
36 | Threads in preemptive mode are considered to be running unmanaged code. Such a
37 | thread obeys three invariants:
38 | 1. It must not currently be manipulating GC references, and all live GC
39 | references must be reachable from managed frames.
40 | 2. It must have registered the last managed frame on its stack with the runtime
41 | so that the GC may avoid scanning unmanaged frames.
42 | 3. It must not reenter managed code if a GC is in progress.
43 |
44 | Threads that are running in preemptive mode need not be driven to a GC safe
45 | point before a collection, as invariants (1) and (3) guarantee that the
46 | managed code on such threads is already logically paused. Invariants (1) and
47 | (2) serve to satisfy the requirement that the GC must be able to scan the
48 | thread's stack for GC references.
49 |
50 | ### Transitioning from managed and unmanaged code
51 |
52 | Transitioning from managed to unmanaged code boils down to switching the active
53 | thread from cooperative to preemptive mode while ensuring that the invariants
54 | associated with preemptive mode are obeyed. Abstractly, this looks something
55 | like the following, where `>> {Managed,Unmanaged} code` indicates the type of
56 | code currently running on the thread:
57 |
58 | ```
59 | >> Managed code
60 | - Ensure all GC references in registers that might be updated by unmanaged code
61 | have been spilled to locations that will not be updated by unmanaged code.
62 | This satisfies the first preemptive mode invariant.
63 | - Register this frame as the last managed frame on this thread. This satisfies
64 | the second preemptive mode invariant.
65 | - Flip this thread's GC mode to preemptive mode.
66 |
67 | >> Unmanaged code
68 | - Run unmanaged code. Usually this is just a call to an unmanaged function.
69 | - Once the unmanaged code has run, flip this thread's GC mode to cooperative
70 | mode.
71 |
72 | >> Managed code
73 | - Check to see if a collection is in progress and if so, block this thread until
74 | it completes. This satisfies the third preemptive mode invariant.
75 | ```
76 |
77 | ## Supporting GC transitions in LLILC and LLVM
78 |
79 | Ideally, LLILC would be able to emit all of the necessary transition code in
80 | LLVM IR. Unfortunately, it is not possible to do so while preserving the
81 | preemptive mode invariants:
82 | - The frame registration, mode transitions, and collection rendezvous must be
83 | positioned immediately before and after the unmanaged code. LLVM IR has no
84 | way of expressing this restriction.
85 | - Registering the managed frame requires knowing the address of the first
86 | managed instruction following the unmanaged code. Again, LLVM IR has no
87 | way of expressing this.
88 |
89 | As a result, the gc.statepoint intrinsic has been extended to support marking
90 | certain statepoints as transitions between code with differing GC models.
91 | These calls are then lowered differently by the backend, which is given an
92 | opportunity to lower the GC transition prologue and epilogue in a
93 | GC-model-specific fashion. In the case of CoreCLR, the backend is responsible
94 | for emitting the frame registration, mode transitions, and the collection
95 | rendezvous, while the frontend is responsible for allocating (and partially
96 | initializing) the frame registration data structure and marking calls to
97 | unamanged code as GC transitions. Example IR is given below.
98 |
99 | ```
100 | !0 = !{!"rsp"}
101 | !1 = !{!"rbp"}
102 |
103 | void @DomainNeutralILStubClass.IL_STUB_PInvoke() gc "coreclr" {
104 | %InlinedCallFrame = alloca [64 x i8] ; Frame registration data structure for CoreCLR
105 | %ThreadPointer = alloca [0 x i8]* ; Pointer to current CoreCLR thread
106 |
107 | ; Get the current thread of execution
108 | %0 = getelementptr inbounds [64 x i8], [64 x i8]* %InlinedCallFrame, i32 0, i32 8
109 | %1 = call [0 x i8]* inttoptr (i64 140505971852800 to [0 x i8]* (i8*, i64)*)(i8* %0, i64 %param2)
110 | store [0 x i8]* %1, [0 x i8]** %ThreadPointer
111 |
112 | ; Record the stack pointer in the frame registration data
113 | %2 = getelementptr inbounds [64 x i8], [64 x i8]* %InlinedCallFrame, i32 0, i32 40
114 | %3 = bitcast i8* %2 to i64*
115 | %4 = call i64 @llvm.read_register.i64(metadata !0)
116 | store i64 %4, i64* %3
117 |
118 | ; Record the frame pointer in the frame registration data
119 | %5 = getelementptr inbounds [64 x i8], [64 x i8]* %InlinedCallFrame, i32 0, i32 56
120 | %6 = bitcast i8* %5 to i64*
121 | %7 = call i64 @llvm.read_register.i64(metadata !1)
122 | store i64 %7, i64* %6
123 |
124 | ; Push the current frame onto the frame registration stack
125 | %10 = getelementptr inbounds [64 x i8], [64 x i8]* %InlinedCallFrame, i32 0, i32 8
126 | %11 = load [0 x i8]*, [0 x i8]** %ThreadPointer
127 | %12 = getelementptr inbounds [0 x i8], [0 x i8]* %11, i32 0, i32 16
128 | %13 = bitcast i8* %12 to i8**
129 | store i8* %10, i8** %13
130 |
131 | ; Compute addresses for GC transition code
132 | %14 = getelementptr inbounds [64 x i8], [64 x i8]* %InlinedCallFrame, i32 0, i32 48
133 | %15 = bitcast i8* %14 to i8**
134 | %16 = getelementptr inbounds [0 x i8], [0 x i8]* %11, i32 0, i32 12
135 | %17 = load i64, i64* inttoptr (i64 140505987192288 to i64*)
136 |
137 | ; Perform the call.
138 | ;
139 | ; The fifth argument (i32 1) marks this statepoint as a GC transition. The
140 | ; backend will generate code to spill callee-saves, perform the GC mode
141 | ; switch, and check for a collection before reentering managed
142 | ; code. The four arguments immediately preceding the final argument provide
143 | ; data that is needed by the transition code.
144 | call void (i64, i32, void()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* null, i32 0, i32 1, i32 4, i8** %15, i8* %16, i32* inttoptr (i64 140505987311808 to i32*), i64 %17, i32 0)
145 |
146 | ; Pop the current frame from the registration stack
147 | store i8* null, i8** %15
148 | %18 = getelementptr inbounds [64 x i8], [64 x i8]* %InlinedCallFrame, i32 0, i32 16
149 | %19 = bitcast i8* %18 to i8**
150 | %20 = load i8*, i8** %19
151 | store i8* %20, i8** %13
152 |
153 | ret void
154 | }
155 | ```
156 |
--------------------------------------------------------------------------------
/include/Jit/EEMemoryManager.h:
--------------------------------------------------------------------------------
1 | //===--------------- include/Jit/EEMemoryManager.h --------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declaration of the memory manager interface to the EE.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef EE_MEMORYMANAGER_H
17 | #define EE_MEMORYMANAGER_H
18 |
19 | #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
20 |
21 | struct LLILCJitContext;
22 |
23 | namespace llvm {
24 |
25 | /// \brief Memory manager for LLILC
26 | ///
27 | /// This class extends \p RTDyldMemoryManager to obtain memory from the
28 | /// CoreCLR's EE for the persistent jit outputs (code, data, and unwind
29 | /// information). Each jit request instantiates its own memory manager.
30 | class EEMemoryManager : public RTDyldMemoryManager {
31 |
32 | public:
33 | /// Construct a new \p EEMemoryManager
34 | /// \param C Jit context for the method being jitted.
35 | EEMemoryManager(LLILCJitContext *C)
36 | : Context(C), HotCodeBlock(nullptr), ColdCodeBlock(nullptr),
37 | ReadOnlyDataBlock(nullptr), StackMapBlock(nullptr) {}
38 |
39 | /// Destroy an \p EEMemoryManager
40 | ~EEMemoryManager() override;
41 |
42 | /// \brief Allocates a memory block of (at least) the given size suitable
43 | /// for executable code.
44 | ///
45 | /// The value of \p Alignment must be a power of two. If \p Alignment is
46 | /// zero a default alignment of 16 will be used.
47 | ///
48 | /// \param Size Size of allocation request in bytes
49 | /// \param Alignment Alignment demand for the allocation
50 | /// \param SectionID SectionID for this particular section of code
51 | /// \param SectionName Name of the section
52 | /// \returns Pointer to the newly allocated memory region
53 | uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
54 | unsigned SectionID,
55 | StringRef SectionName) override;
56 |
57 | // \brief Returns code section address.
58 | // \returns Code section address.
59 | uint8_t *getCodeSection();
60 |
61 | /// \brief Allocates a memory block of (at least) the given size suitable
62 | /// for executable code.
63 | ///
64 | /// The value of \p Alignment must be a power of two. If \p Alignment is
65 | /// zero a default alignment of 16 will be used.
66 | ///
67 | /// \param Size Size of allocation request in bytes
68 | /// \param Alignment Alignment demand for the allocation
69 | /// \param SectionID SectionID for this particular section of code
70 | /// \param SectionName Name of the section
71 | /// \param IsReadOnly True if this is intended for read-only data
72 | /// \returns Pointer to the newly allocated memory region
73 | uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
74 | unsigned SectionID, StringRef SectionName,
75 | bool IsReadOnly) override;
76 |
77 | /// \brief Update section-specific memory permissions and other attributes.
78 | ///
79 | /// This method is called when object loading is complete and section page
80 | /// permissions can be applied. It is up to the memory manager
81 | /// implementation to decide whether or not to act on this method.
82 | /// The memory manager will typically allocate all sections as read-write
83 | /// and then apply specific permissions when this method is called. Code
84 | /// sections cannot be executed until this function has been called.
85 | /// In addition, any cache coherency operations needed to reliably use the
86 | /// memory are also performed.
87 | ///
88 | /// \param ErrMsg [out] Additional information about finalization errors.
89 | /// \returns false if an error occurred, true otherwise.
90 | bool finalizeMemory(std::string *ErrMsg = nullptr) override;
91 |
92 | /// Inform the memory manager about the total amount of memory required to
93 | /// allocate all sections to be loaded.
94 | ///
95 | /// \param CodeSize - the total size of all code sections.
96 | /// \param CodeAlign - alignment required for the code sections.
97 | /// \param RODataSize - the total size of all read-only data sections.
98 | /// \param RODataAlign - alignment required for read-only data sections.
99 | /// \param RWDataSize - the total size of all read-write data sections.
100 | /// \param RWDataAlign - alignment required for read-write data sections.
101 | ///
102 | /// Note that by default the callback is disabled. To enable it
103 | /// redefine the method needsToReserveAllocationSpace to return true.
104 | void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
105 | uintptr_t RODataSize, uint32_t RODataAlign,
106 | uintptr_t RWDataSize,
107 | uint32_t RWDataAlign) override;
108 |
109 | /// Inform the memory manager about the amount of memory required to hold
110 | /// unwind codes for the function and funclets being loaded.
111 | ///
112 | /// \param Obj - the Object being loaded
113 | void reserveUnwindSpace(const object::ObjectFile &Obj);
114 |
115 | /// \brief Override to enable the reserveAllocationSpace callback.
116 | ///
117 | /// The CoreCLR's EE requires an up-front resevation of the total allocation
118 | /// demands from the jit. This callback enables that to happen.
119 | /// \returns true to enable the callback.
120 | bool needsToReserveAllocationSpace() override { return true; }
121 |
122 | /// \brief Callback to handle processing unwind data.
123 | ///
124 | /// This is currently invoked once per .xdata section. The EE uses this info
125 | /// to build and register the appropriate .pdata with the OS.
126 | ///
127 | /// \param Addr The address of the data in the pre-loaded image.
128 | /// \param LoadAddr The address the data will have once loaded.
129 | /// \param Size Size of the unwind data in bytes.
130 | ///
131 | /// \note Because we're not relocating data during loading, \p Addr and
132 | /// \p LoadAddr are currently identical.
133 | void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
134 |
135 | /// \brief Callback to handle unregistering unwind data.
136 | ///
137 | /// This is currently a no-op.
138 | ///
139 | /// \param Addr The address of the data in the image.
140 | /// \param LoadAddr The address the data has after loading.
141 | /// \param Size Size of the unwind data in bytes.
142 | void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
143 | size_t Size) override;
144 |
145 | /// \brief Get the LLVM Stackmap section if allocated.
146 | ///
147 | /// Returns a pointer to the .llvm_stackmaps section
148 | /// if it is already loaded into memory.
149 |
150 | uint8_t *getStackMapSection() { return StackMapBlock; }
151 |
152 | /// \brief Get the HotCode section if allocated.
153 | ///
154 | /// Returns a pointer to the HotCode section
155 | /// if it is already loaded into memory.
156 |
157 | uint8_t *getHotCodeBlock() { return HotCodeBlock; }
158 |
159 | private:
160 | LLILCJitContext *Context; ///< LLVM context for types, etc.
161 | uint8_t *HotCodeBlock; ///< Memory to hold the hot method code.
162 | uint8_t *ColdCodeBlock; ///< Memory to hold the cold method code.
163 | uint8_t *ReadOnlyDataBlock; ///< Memory to hold the readonly data.
164 | uint8_t *StackMapBlock; ///< Memory to hold the readonly StackMap
165 | uint8_t *ReadOnlyDataUnallocated; ///< Address of unallocated part of RO data.
166 | };
167 | } // namespace llvm
168 |
169 | #endif // EEMEMORYMANAGER_H
170 |
--------------------------------------------------------------------------------
/include/Reader/abisignature.h:
--------------------------------------------------------------------------------
1 | //===------------------- include/Reader/abisignature.h ----------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declares ABI signature abstractions used when lowering functions to
13 | /// LLVM IR.
14 | ///
15 | //===----------------------------------------------------------------------===//
16 |
17 | #ifndef _READER_ABISIGNATURE_H_
18 | #define _READER_ABISIGNATURE_H_
19 |
20 | /// \brief Encapsulates ABI-specific argument and result passing information for
21 | /// a particular function signature.
22 | class ABISignature {
23 | protected:
24 | llvm::Type *FuncResultType; ///< The return type of this function signature.
25 | ABIArgInfo Result; ///< Describes how the result of the function is passed.
26 | std::vector Args; ///< Describes how each argument to the function
27 | ///< is passed.
28 |
29 | ABISignature() {}
30 |
31 | /// \brief Fills in argument and result passing information for the given
32 | /// function signature.
33 | ///
34 | /// \param Signature The function signature.
35 | /// \param Reader The \p GenIR instance that will be used to emit IR.
36 | /// \param TheABIInfo The target \p ABIInfo.
37 | ABISignature(const ReaderCallSignature &Signature, GenIR &Reader,
38 | const ABIInfo &TheABIInfo);
39 |
40 | /// \brief Returns the number of arguments to the ABI signature.
41 | ///
42 | /// \returns The number of arguments to the ABI signature.
43 | uint32_t getNumABIArgs() const;
44 |
45 | public:
46 | /// \brief Expand a value according to a specific list of expansions.
47 | ///
48 | /// \param Reader The \p GenIR instance that will be used to emit IR.
49 | /// \param Expansions The list of expansions to be applied.
50 | /// \param Source The value to expand.
51 | /// \param Values [in] A slice that will hold the values that result from
52 | /// the expansion.
53 | /// \param Values [in] A slice that will hold the types of the values that
54 | /// result from the expansion.
55 | /// \param IsResult True if the value being expanded is the result value
56 | /// for a function.
57 | static void expand(GenIR &Reader,
58 | llvm::ArrayRef Expansions,
59 | llvm::Value *Source,
60 | llvm::MutableArrayRef Values,
61 | llvm::MutableArrayRef Types, bool IsResult);
62 |
63 | /// \brief Store a single value from an expanded argument into its
64 | /// destination.
65 | ///
66 | /// \param Reader The \p GenIR instance that will be used to emit IR.
67 | /// \param Exp The expansion information for the given value.
68 | /// \param Val The value to be collapsed.
69 | /// \param Base The base address of the target value as an i8*.
70 | static void collapse(GenIR &Reader, const ABIArgInfo::Expansion &Exp,
71 | llvm::Value *Val, llvm::Value *Base);
72 |
73 | /// \brief Coerces a value to a particular target type, casting or
74 | /// reinterpreting as necessary.
75 | ///
76 | /// \param Reader The \p GenIR instance that will be used to emit IR.
77 | /// \param TheType The target type of the coercion.
78 | /// \param TheValue The value to coerce.
79 | ///
80 | /// \returns A \p Value that represents the result of the coercion.
81 | static llvm::Value *coerce(GenIR &Reader, llvm::Type *TheType,
82 | llvm::Value *TheValue);
83 | };
84 |
85 | /// \brief Encapsulates ABI-specific argument and result passing information for
86 | /// a particular call target signature and provides facilities to emit
87 | /// a call to a target with that signature.
88 | class ABICallSignature : public ABISignature {
89 | private:
90 | const ReaderCallSignature &Signature; ///< The target function signature.
91 |
92 | /// \brief Emits a call to an unmanaged function.
93 | ///
94 | /// This method is called by \p emitCall when emitting a call that targets an
95 | /// unmanaged function. It is responsible for emitting the IR required to
96 | /// perform any necessary bookkeeping for the GC as well as the call itself.
97 | /// The arguments must already have been arranged as per the calling
98 | /// convention and target ABI.
99 | ///
100 | /// \param Reader The \p GenIR instance that will be used to emit IR.
101 | /// \param Target The call target.
102 | /// \oaram MayThrow True iff the callee may raise an exception.
103 | /// \param Args The arguments to the call, arranged as per the
104 | /// calling convention and target ABI.
105 | ///
106 | /// \returns The call site corresponding to the unmanaged call.
107 | llvm::CallSite emitUnmanagedCall(GenIR &Reader, llvm::Value *Target,
108 | bool MayThrow,
109 | llvm::ArrayRef Args) const;
110 |
111 | public:
112 | ABICallSignature(const ReaderCallSignature &Signature, GenIR &Reader,
113 | const ABIInfo &TheABIInfo);
114 |
115 | /// \brief Emits a call to a function using the argument and result passing
116 | /// information for the signature provided when this value was created.
117 | ///
118 | /// \param Reader The \p GenIR instance that will be used to emit
119 | /// IR.
120 | /// \param Target The call target.
121 | /// \param MayThrow True iff the callee may raise an exception
122 | /// \param Args The arguments to the call.
123 | /// \param IndirectionCell The indirection cell argument for the call, if
124 | /// any.
125 | /// \param IsJmp True iff this is a call for a jmp instruction.
126 | /// \param CallNode [out] The call instruction.
127 | ///
128 | /// \returns The result of the call to the target.
129 | llvm::Value *emitCall(GenIR &Reader, llvm::Value *Target, bool MayThrow,
130 | llvm::ArrayRef Args,
131 | llvm::Value *IndirectionCell, bool IsJmp,
132 | llvm::Value **CallNode) const;
133 |
134 | /// \brief Check for an indirect result or indirect argument.
135 | ///
136 | /// Determines if expansion of this call might result in references to temps
137 | /// that live on the caller's stack.
138 | ///
139 | /// \returns True if there is an indirect result or indirect argument.
140 | bool hasIndirectResultOrArg() const;
141 | };
142 |
143 | /// \brief Encapsulates ABI-specific argument and result passing information for
144 | /// a particular method signature and provides facilites to create an
145 | // appropriately-typed function symbol.
146 | class ABIMethodSignature : public ABISignature {
147 | private:
148 | const ReaderMethodSignature *Signature; ///< The target method signature.
149 |
150 | public:
151 | ABIMethodSignature() {}
152 | ABIMethodSignature(const ReaderMethodSignature &Signature, GenIR &Reader,
153 | const ABIInfo &TheABIInfo);
154 |
155 | /// \brief Creates a function symbol for the method signature provided when
156 | /// this vaule was created.
157 | ///
158 | /// \param Reader The \p GenIR instance that will be used to emit IR.
159 | /// \param M The module in which this function is to be created.
160 | ///
161 | /// \returns The newly-created function symbol.
162 | llvm::Function *createFunction(GenIR &Reader, llvm::Module &M);
163 |
164 | /// \brief Gets result passing information for this signature.
165 | ///
166 | /// \returns Result passing information for this signature.
167 | const ABIArgInfo &getResultInfo() const;
168 |
169 | /// \brief Gets argument passing information for the runtime argument at the
170 | /// given index into its parent \p ReaderMethodSignature.
171 | ///
172 | /// \param I The index of the runtime argument into its parent
173 | /// \p ReaderMethodSignature.
174 | ///
175 | /// \returns Argument passing information for the argument.
176 | const ABIArgInfo &getArgumentInfo(uint32_t I) const;
177 | };
178 |
179 | #endif
180 |
--------------------------------------------------------------------------------
/test/llilc_run.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # title : llilcrun.py
4 | # description : Run a managed application using LLILC jit.
5 | #
6 | # This script has been tested running on both Python 2.7 and Python 3.4.
7 | #
8 | # usage: llilc_run.py [-h] [-d {summary,verbose}] [-x [EXTRA [EXTRA ...]]] [-n]
9 | # [-p] [-v] [-r [CORERUN_AND_ARGS [CORERUN_AND_ARGS ...]]]
10 | # [-j JIT_PATH] [-w [WINDBG_AND_ARGS [WINDBG_AND_ARGS ...]]]
11 | # -a APP_PATH -c CORECLR_RUNTIME_PATH
12 | #
13 | # Run a managed application with LLILC as the JIT. If the application has any
14 | # arguments, they must be appended to the end of the command line, preceded by
15 | # "--".
16 | #
17 | # optional arguments:
18 | # -h, --help show this help message and exit
19 | # -d {summary,verbose}, --dump-level {summary,verbose}
20 | # the dump level: summary, or verbose
21 | # -x [EXTRA [EXTRA ...]], --extra [EXTRA [EXTRA ...]]
22 | # list of extra COMPlus settings. Each item is
23 | # Name=Value, where Name does not have the
24 | # COMPlus_ prefix.
25 | # -n, --ngen use ngened mscorlib
26 | # -p, --precise-gc test with precise gc
27 | # -v, --verbose echo commands
28 | # -e, --eh enable exception handlers to run (as opposed to failfast)
29 | # -r [CORERUN_AND_ARGS [CORERUN_AND_ARGS ...]], --corerun-and-args [CORERUN_AND_ARGS [CORERUN_AND_ARGS ...]]
30 | # If explicit CoreRun is needed (app is not
31 | # CoreConsole), the CoreRun command and args to pass to
32 | # CoreRun, e.g. /v for verbose.
33 | # -j JIT_PATH, --jit-path JIT_PATH
34 | # full path to jit .dll. If given it is copied to
35 | # coreclr directory. If not given we check that it
36 | # exists in the coreclr directory.
37 | # -w [WINDBG_AND_ARGS [WINDBG_AND_ARGS ...]], --windbg-and-args [WINDBG_AND_ARGS [WINDBG_AND_ARGS ...]]
38 | # Full path to windbg executable followed by any
39 | # arguments you want to pass to windbg.
40 | #
41 | # required arguments:
42 | # -a APP_PATH, --app-path APP_PATH
43 | # full path to application to run with llilc.
44 | # -c CORECLR_RUNTIME_PATH, --coreclr-runtime-path CORECLR_RUNTIME_PATH
45 | # full path to CoreCLR run-time binary directory
46 |
47 |
48 | import argparse
49 | import os
50 | import shutil
51 | import subprocess
52 | import sys
53 |
54 | llilcverbose = False
55 |
56 | def QuoteArg(arg):
57 | '''Strip off any enclosing single quotes and enclose in double quotes'''
58 | arg = '"' + arg.strip("'").strip('"') + '"'
59 | return arg
60 |
61 | def UnquoteArg(arg):
62 | ''' Remove single and double quotes from front and back of arg'''
63 | return arg.strip("'").strip('"')
64 |
65 | def GetPrintString(*args):
66 | return ' '.join(map(str, args))
67 |
68 | def Print(*args):
69 | print (GetPrintString(*args))
70 |
71 | def PrintError(*args):
72 | ''' Mimic the python 3.x print statement (should the community ever go to 3.4, we would not need to change much.)'''
73 | sys.stderr.write(GetPrintString(*args) + '\n')
74 |
75 | def log(*objs):
76 | '''Print log message to both stdout and stderr'''
77 | Print("llilc_run\stdout: ", *objs)
78 | PrintError("llilc_run\stderr: ", *objs)
79 |
80 | def RunCommand(command):
81 | ''' Run a command and return its exit code, optionally echoing it.'''
82 | global llilcverbose
83 | if llilcverbose:
84 | log ('About to execute: ', command)
85 | error_level = subprocess.call(command, shell=True)
86 | return error_level
87 |
88 | def main(argv):
89 | '''
90 | main method of script. arguments are script path and remaining arguments.
91 | '''
92 | global llilcverbose
93 | parser = argparse.ArgumentParser(description='''Run a managed application with LLILC as the JIT.
94 | If the application has any arguments, they must be
95 | appended to the end of the command line, preceded by "--".
96 | '''
97 | )
98 | parser.add_argument('-d', '--dump-level', type=str, choices={'summary', 'verbose'},
99 | help='the dump level: summary, or verbose')
100 | parser.add_argument('-x', '--extra', type=str, default=[], nargs='*',
101 | help='''list of extra COMPlus settings. Each item is Name=Value, where
102 | Name does not have the COMPlus_ prefix.
103 | ''')
104 | parser.add_argument('-n', '--ngen', help='use ngened mscorlib', default=False, action="store_true")
105 | parser.add_argument('-p', '--precise-gc', help='test with precise gc', default=False, action="store_true")
106 | parser.add_argument('-v', '--verbose', help='echo commands', default=False, action="store_true")
107 | parser.add_argument('-e', '--eh', help='enable exception handlers to run (as opposed to failfast)', default=False, action="store_true")
108 | parser.add_argument('-r', '--corerun-and-args', type=str, nargs='*', default=[],
109 | help='''If explicit CoreRun is needed (app is not CoreConsole),
110 | the CoreRun command and args to pass to CoreRun, e.g. /v for verbose.
111 | ''')
112 | parser.add_argument('-j', '--jit-path', type=str,
113 | help='''full path to jit .dll. If given it is copied to coreclr directory.
114 | If not given we check that it exists in the coreclr directory.
115 | ''')
116 | parser.add_argument('-w', '--windbg-and-args', type=str, nargs='*', default=[],
117 | help='''Full path to windbg executable followed by any arguments you
118 | want to pass to windbg.
119 | ''')
120 | required = parser.add_argument_group('required arguments')
121 | required.add_argument('-a', '--app-path', type=str, required=True,
122 | help='full path to application to run with llilc.')
123 | required.add_argument('-c', '--coreclr-runtime-path', required=True,
124 | help='full path to CoreCLR run-time binary directory')
125 | args, unknown = parser.parse_known_args(argv)
126 | llilcverbose = args.verbose
127 | if llilcverbose:
128 | log('Starting llilcrun.py')
129 | log(' argv=', argv)
130 |
131 | # Skip separating '--', if any.
132 | if unknown and (unknown[0] == '--'):
133 | unknown = unknown[1:]
134 |
135 | program_dir = os.path.dirname(args.app_path)
136 | jit_name = "llilcjit.dll"
137 |
138 | # jit_path is the path to where the jit would be in the CoreClr directory in order
139 | # to be used as the alternate jit.
140 | jit_path = os.path.join(args.coreclr_runtime_path, jit_name)
141 |
142 | if args.jit_path:
143 | # User specified a source path to the LLILC JIT. Copy it even if there
144 | # already is one, as it may be a revised version.
145 | shutil.copy2(args.jit_path, jit_path)
146 | elif not os.path.exists(jit_path):
147 | log("llilc jit not found at ", jit_path)
148 | return 1
149 |
150 | os.environ["COMPlus_AltJit"]="*"
151 | os.environ["COMPlus_AltJitNgen"]="*"
152 | os.environ["COMPlus_AltJitName"]=jit_name
153 | os.environ["COMPlus_NoGuiOnAssert"]="1"
154 | if (args.precise_gc):
155 | os.environ["COMPlus_InsertStatepoints"]="1"
156 | else:
157 | os.environ["COMPlus_GCConservative"]="1"
158 | if not args.ngen:
159 | os.environ["COMPlus_ZapDisable"]="1"
160 | if args.dump_level:
161 | os.environ["COMPlus_DumpLLVMIR"]=args.dump_level
162 | if args.eh:
163 | os.environ["COMPlus_ExecuteHandlers"]="1"
164 | for arg in args.extra:
165 | pair = UnquoteArg(arg).split('=', 1)
166 | name = 'COMPLUS_' + pair[0]
167 | value = pair[1]
168 | os.environ[name] = value
169 | os.environ["CORE_ROOT"]=args.coreclr_runtime_path
170 | os.environ["CORE_LIBRARIES"]=program_dir
171 | if llilcverbose:
172 | RunCommand('set complus_')
173 | RunCommand('set CORE_ROOT')
174 | RunCommand('set CORE_LIBRARIES')
175 | command = []
176 | if args.windbg_and_args:
177 | for arg in args.windbg_and_args:
178 | command.append(arg)
179 | if args.corerun_and_args:
180 | first_corerun = True
181 | for arg in args.corerun_and_args:
182 | if first_corerun:
183 | # First of these will be the CoreRun.exe, so prefix with
184 | # the path.
185 | arg = os.path.join(args.coreclr_runtime_path, arg)
186 | first_corerun = False
187 | command.append(arg)
188 |
189 | command.append(args.app_path)
190 | for arg in unknown:
191 | command.append(arg)
192 | error_level = RunCommand(command)
193 | if llilcverbose:
194 | log ('Exiting llilc_run.py with exit code ', error_level)
195 | return error_level
196 |
197 | if __name__ == '__main__':
198 | return_code = main(sys.argv[1:])
199 | sys.exit(return_code)
200 |
--------------------------------------------------------------------------------
/include/Reader/abi.h:
--------------------------------------------------------------------------------
1 | //===------------------- include/Reader/abi.h -------------------*- C++ -*-===//
2 | //
3 | // LLILC
4 | //
5 | // Copyright (c) Microsoft. All rights reserved.
6 | // Licensed under the MIT license.
7 | // See LICENSE file in the project root for full license information.
8 | //
9 | //===----------------------------------------------------------------------===//
10 | ///
11 | /// \file
12 | /// \brief Declares the ABI abstraction used when lowering functions to LLVM IR.
13 | ///
14 | //===----------------------------------------------------------------------===//
15 |
16 | #ifndef _READER_ABI_H_
17 | #define _READER_ABI_H_
18 |
19 | /// \brief Information about how a particular argument is passed to a function.
20 | ///
21 | /// This class encapsulates information such as whether a parameter is passed
22 | /// by value or by implicit reference, whether it must be coerced to a different
23 | /// type, etc. This information is used when generating call sequences or
24 | /// accessing method parameters/results.
25 | class ABIArgInfo {
26 | public:
27 | /// \brief Describes how a particular argument is passed to a function.
28 | enum Kind {
29 | Direct, ///< Pass the argument directly, optionally coercing it to a
30 | ///< different type.
31 |
32 | Expand, ///< Pass the argument directly after expanding its contents
33 | ///< according to the expansion records.
34 |
35 | ZeroExtend, ///< Pass the argument directly with zero-extension.
36 |
37 | SignExtend, ///< Pass the argument directly with sign-extension.
38 |
39 | Indirect, ///< Pass the argument indirectly via a hidden pointer
40 | };
41 |
42 | /// \brief Describes how a subfield of a value is expanded into an argument.
43 | struct Expansion {
44 | llvm::Type *TheType; ///< The type of the expanded subfield.
45 | unsigned Offset; ///< The offset of the subfield in the value.
46 | };
47 |
48 | private:
49 | Kind TheKind; ///< How this argument is to be passed
50 | union {
51 | llvm::Type *TheType; ///< The type this argument is to be passed as.
52 | ///< Especially relevant for Kind::Direct.
53 |
54 | llvm::SmallVector *Expansions; ///< The expansions used to
55 | ///< pass this arg.
56 | ///< Relevant only for
57 | ///< Kind::Expand.
58 | };
59 | uint32_t Index; ///< Index of this argument in the argument list of
60 | ///< its containing \p Function. Currently only used by
61 | ///< \p ABIMethodSignature.
62 |
63 | ABIArgInfo(const ABIArgInfo &other) = delete;
64 | ABIArgInfo &operator=(const ABIArgInfo &other) = delete;
65 |
66 | ABIArgInfo(Kind TheKind, llvm::Type *TheType);
67 | ABIArgInfo(Kind TheKind, llvm::ArrayRef Expansions);
68 |
69 | public:
70 | ABIArgInfo(ABIArgInfo &&other);
71 | ~ABIArgInfo();
72 |
73 | ABIArgInfo &operator=(ABIArgInfo &&other);
74 |
75 | /// \brief Create an \p ABIIArgInfo value for an argument that is to be
76 | /// passed by value with a particular type.
77 | ///
78 | /// \param TheType The type that this argument is passed as.
79 | ///
80 | /// \returns An \p ABIArgInfo value describing the argument.
81 | static ABIArgInfo getDirect(llvm::Type *TheType);
82 |
83 | /// \brief Create an \p ABIIArgInfo value for an argument that is to be
84 | /// passed by expansion.
85 | ///
86 | /// \param Expansions The expansion records for this argument.
87 | ///
88 | /// \returns An \p ABIArgInfo value describing the argument.
89 | static ABIArgInfo getExpand(llvm::ArrayRef Expansions);
90 |
91 | /// \brief Create an \p ABIIArgInfo value for an argument that is to be
92 | /// passed by value with zero extension.
93 | ///
94 | /// \param TheType The type that this argument is passed as.
95 | ///
96 | /// \returns An \p ABIArgInfo value describing the argument.
97 | static ABIArgInfo getZeroExtend(llvm::Type *TheType);
98 |
99 | /// \brief Create an \p ABIIArgInfo value for an argument that is to be
100 | /// passed by value with sign extension.
101 | ///
102 | /// \param TheType The type that this argument is passed as.
103 | ///
104 | /// \returns An \p ABIArgInfo value describing the argument.
105 | static ABIArgInfo getSignExtend(llvm::Type *TheType);
106 |
107 | /// \brief Create an \p ABIIArgInfo value for an argument that is to be
108 | /// passed by an implicit reference to a particular type.
109 | ///
110 | /// \param TheType The referent type for this argument.
111 | ///
112 | /// \returns An \p ABIArgInfo value describing the argument.
113 | static ABIArgInfo getIndirect(llvm::Type *TheType);
114 |
115 | /// \brief Empty constructor to allow vectors, data-dependent construction,
116 | /// etc.
117 | ///
118 | /// Actual values should be created using \p getDirect and \p getIndirect.
119 | ABIArgInfo() {}
120 |
121 | /// \brief Get the \p Kind that describes how this argument is passed.
122 | ///
123 | /// \returns The \p Kind that describes how this argument is passed.
124 | Kind getKind() const;
125 |
126 | /// \brief Get the type of this argument.
127 | ///
128 | /// \returns The type of the argument for direct args or the referent type
129 | /// of the argument for indirect args.
130 | llvm::Type *getType() const;
131 |
132 | /// \brief Get the expansions for this argument.
133 | ///
134 | /// \returns The expansion records for this argument. Only valid for expanded
135 | /// arguments.
136 | llvm::ArrayRef getExpansions() const;
137 |
138 | /// \brief Set the index of this argument in its containing argument list.
139 | ///
140 | /// \param Index The index of this argument in its containing agument list.
141 | void setIndex(uint32_t Index);
142 |
143 | /// \brief Get the index of this argument in its containing argument list.
144 | ///
145 | /// \returns The index of this argument in its containing argument list.
146 | uint32_t getIndex() const;
147 | };
148 |
149 | /// \brief Encapsulates an \p llvm::Type* and its signedness.
150 | class ABIType {
151 | private:
152 | llvm::Type *TheType; ///< The type of this argument.
153 | CORINFO_CLASS_HANDLE Class; ///< The class handle for this argument.
154 | bool IsSigned; ///< True if the type is a signed integral type.
155 |
156 | public:
157 | /// \brief Creates an \p ABIType with the given type and signedness.
158 | ///
159 | /// \param TheType The \p llvm::Type* for this \p ABIType.
160 | /// \param Class The \p CORINFO_CLASS_HANDLE for this \p ABIType.
161 | /// \param IsSigned True if this \p ABIType is a signed integral type.
162 | ABIType(llvm::Type *TheType, CORINFO_CLASS_HANDLE Class, bool IsSigned);
163 |
164 | /// \brief Empty constructor to allow vectors, data-dependent construction,
165 | /// etc.
166 | ABIType() {}
167 |
168 | /// \brief Get the \p llvm::Type* for this \p ABIType.
169 | ///
170 | /// \returns The \p llvm::Type* for this \p ABIType.
171 | llvm::Type *getType() const;
172 |
173 | /// \brief Get the \p CORINFO_CLASS_HANDLE for this \p ABIType.
174 | ///
175 | /// \returns the \p CORINFO_CLASS_HANDLE for this \p ABIType.
176 | CORINFO_CLASS_HANDLE getClass() const;
177 |
178 | /// \brief Get the signedness of this \p ABIType.
179 | ///
180 | /// \returns True if this \p ABIType is a signed integral type.
181 | bool isSigned() const;
182 | };
183 |
184 | /// \brief Encapsulautes ABI-specific functionality.
185 | ///
186 | /// The \p ABIInfo class provides ABI-specific services. Currently, this is
187 | /// limited to computing the details of how arguments are passed to functions
188 | /// for a given platform.
189 | class ABIInfo {
190 | public:
191 | /// \brief Gets an \p ABIInfo that corresponds to the target of the given
192 | /// \p Module.
193 | ///
194 | /// \returns An \p ABIInfo instance. This instance belongs to the caller and
195 | /// should be deleted when it is no longer needed.
196 | static ABIInfo *get(llvm::Module &M);
197 |
198 | /// \brief Computes argument passing information for the target ABI.
199 | ///
200 | /// This function is used to determine how the parameters to and result of a
201 | /// function are passed for the given calling convention and types for the
202 | /// target ABI.
203 | ///
204 | /// \param Context The \p LLILCJitContext instance that will be
205 | /// used to retrieve extended type information.
206 | /// \param CC The calling convention for the call target.
207 | /// \param IsManagedCallingConv True if the callling convention targets
208 | /// managed code.
209 | /// \param ResultType The type of the target's result.
210 | /// \param ArgTypes The types of the target's arguments.
211 | /// \param ResultInfo [out] Argument passing information for the target's
212 | /// result.
213 | /// \param ArgInfos [out] Argument passing information for the target's
214 | /// arguments.
215 | virtual void
216 | computeSignatureInfo(LLILCJitContext &Context, llvm::CallingConv::ID CC,
217 | bool IsManagedCallingConv, ABIType ResultType,
218 | llvm::ArrayRef ArgTypes, ABIArgInfo &ResultInfo,
219 | std::vector &ArgInfos) const = 0;
220 |
221 | /// \brief Virtual Destructor
222 | virtual ~ABIInfo() = default;
223 | };
224 |
225 | #endif
226 |
--------------------------------------------------------------------------------