Compare commits
22 Commits
Author | SHA1 | Date |
---|---|---|
Dibyendu Majumdar | 68b0359383 | 6 years ago |
Dibyendu Majumdar | be17c645c3 | 6 years ago |
Dibyendu Majumdar | 56c3af3285 | 6 years ago |
Dibyendu Majumdar | 320e6b5da6 | 6 years ago |
Dibyendu Majumdar | e75b146bfc | 6 years ago |
Dibyendu Majumdar | 6cea3bc383 | 6 years ago |
Dibyendu Majumdar | 64dfadd3a6 | 6 years ago |
Dibyendu Majumdar | 6bbfb88799 | 6 years ago |
Dibyendu Majumdar | b450f3dac3 | 6 years ago |
dylan | ef7a270433 | 6 years ago |
Dibyendu Majumdar | 3426e55dd8 | 6 years ago |
Dibyendu Majumdar | 7c8e9bcf27 | 6 years ago |
Dibyendu Majumdar | 60b75db2ed | 6 years ago |
Dibyendu Majumdar | bc68457199 | 6 years ago |
Dibyendu Majumdar | 6bdfe1fbd2 | 6 years ago |
Dibyendu Majumdar | 123fb4079a | 6 years ago |
Dibyendu Majumdar | 7c5b846a7b | 6 years ago |
Dibyendu Majumdar | 971b548f1b | 6 years ago |
Dibyendu Majumdar | 157bc43162 | 6 years ago |
Dibyendu Majumdar | caf59c84a7 | 6 years ago |
Dibyendu Majumdar | 136dd5623b | 6 years ago |
Dibyendu Majumdar | 87cf534302 | 6 years ago |
@ -1,7 +0,0 @@
|
||||
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
|
||||
ARG VARIANT=buster
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/cpp:dev-${VARIANT}
|
||||
|
||||
# [Optional] Uncomment this section to install additional packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
@ -1,12 +0,0 @@
|
||||
# [Choice] Debian / Ubuntu version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
|
||||
ARG VARIANT=buster
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/base:${VARIANT}
|
||||
|
||||
# Install needed packages. Use a separate RUN statement to add your own dependencies.
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install build-essential cmake cppcheck valgrind clang lldb llvm gdb \
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "C++",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
|
||||
"args": { "VARIANT": "debian-10" }
|
||||
},
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "gcc -v",
|
||||
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode"
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get install -y libreadline-dev
|
||||
|
||||
- name: Create Build Environment
|
||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
||||
|
||||
- name: Configure CMake
|
||||
# Use a bash shell so we can use the same syntax for environment variable
|
||||
# access regardless of the host operating system
|
||||
shell: bash
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
# Note the current convention is to use the -S and -B options here to specify source
|
||||
# and build directories, but this is only available with CMake 3.13 and higher.
|
||||
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
|
||||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{runner.workspace}}/build
|
||||
shell: bash
|
||||
# Execute the build. You can specify a specific target with "--target <NAME>"
|
||||
run: cmake --build . --config $BUILD_TYPE
|
||||
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: cd tests && sh run_tests.sh ${{runner.workspace}}/build/ravi
|
@ -1 +1,3 @@
|
||||
|
||||
[submodule "dmr_c"]
|
||||
path = dmr_c
|
||||
url = https://github.com/dibyendumajumdar/dmr_c.git
|
||||
|
@ -1,20 +1,33 @@
|
||||
language: cpp
|
||||
os:
|
||||
- linux
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
env:
|
||||
- ARCH="x86_64"
|
||||
compiler:
|
||||
- gcc
|
||||
cache: ccache
|
||||
dist: focal
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-precise
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc
|
||||
- clang-3.7
|
||||
- g++-5
|
||||
- gcc-5
|
||||
- ccache
|
||||
install:
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="ccache g++-5" CC="ccache gcc-5"; fi
|
||||
- if [ "$CXX" = "clang++" ]; then export CXX="ccache clang++-3.7" CC="ccache clang-3.7"; fi
|
||||
- curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar -xzf -
|
||||
- curl http://www.llvm.org/releases/3.7.0/llvm-3.7.0.src.tar.xz | tar -xJf -
|
||||
- mkdir $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build
|
||||
- cd $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build && $TRAVIS_BUILD_DIR/cmake-3.4.0-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/LLVM37 -DLLVM_TARGETS_TO_BUILD="X86" ..
|
||||
- cd $TRAVIS_BUILD_DIR/llvm-3.7.0.src/build && make install
|
||||
script:
|
||||
- mkdir $TRAVIS_BUILD_DIR/buildmir
|
||||
- cd $TRAVIS_BUILD_DIR/buildmir && cmake -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON -DMIR_JIT=ON -G "Unix Makefiles" ..
|
||||
- cd $TRAVIS_BUILD_DIR/buildmir && make
|
||||
- cd $TRAVIS_BUILD_DIR/tests && sh ./run_tests.sh $TRAVIS_BUILD_DIR/buildmir/ravi
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="ccache g++-5" CC="ccache gcc-5"; fi
|
||||
- if [ "$CXX" = "clang++" ]; then export CXX="ccache clang++-3.7" CC="ccache clang-3.7"; fi
|
||||
- mkdir $TRAVIS_BUILD_DIR/build
|
||||
- cd $TRAVIS_BUILD_DIR/build && $TRAVIS_BUILD_DIR/cmake-3.4.0-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_DIR=/tmp/LLVM37/share/llvm/cmake -G "Unix Makefiles" -DLLVM_JIT=ON ..
|
||||
- cd $TRAVIS_BUILD_DIR/build && make
|
||||
- cd $TRAVIS_BUILD_DIR/lua-tests && sh ./run_travis_tests.sh $TRAVIS_BUILD_DIR/build/ravi
|
||||
|
@ -1,23 +1,5 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2019 Lua.org, PUC-Rio.
|
||||
* Portions Copyright (C) 2015-2020 Dibyendu Majumdar
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
Most of Ravi is under MIT License
|
||||
There are components that are under GPL - please see relevant
|
||||
source files. These are optional components that are part of the
|
||||
libgccjit implementation of the JIT compiler. You can remove these
|
||||
components if you do not want GPL license.
|
||||
|
@ -1,195 +0,0 @@
|
||||
Ravi Programming Language
|
||||
=========================
|
||||
|
||||
![image](https://travis-ci.org/dibyendumajumdar/ravi.svg?branch=master%0A%20:target:%20https://travis-ci.org/dibyendumajumdar/ravi)
|
||||
|
||||
Ravi is a dialect of [Lua](http://www.lua.org/) with limited optional
|
||||
static typing and features [MIR](https://github.com/vnmakarov/mir)
|
||||
powered JIT compilers. The name Ravi comes from the Sanskrit word for
|
||||
the Sun. Interestingly a precursor to Lua was
|
||||
[Sol](http://www.lua.org/history.html) which had support for static
|
||||
types; Sol means the Sun in Portugese.
|
||||
|
||||
Lua is perfect as a small embeddable dynamic language so why a
|
||||
derivative? Ravi extends Lua with static typing for improved performance
|
||||
when JIT compilation is enabled. However, the static typing is optional
|
||||
and therefore Lua programs are also valid Ravi programs.
|
||||
|
||||
There are other attempts to add static typing to Lua - e.g. [Typed
|
||||
Lua](https://github.com/andremm/typedlua) but these efforts are mostly
|
||||
about adding static type checks in the language while leaving the VM
|
||||
unmodified. The Typed Lua effort is very similar to the approach taken
|
||||
by Typescript in the JavaScript world. The static typing is to aid
|
||||
programming in the large - the code is eventually translated to standard
|
||||
Lua and executed in the unmodified Lua VM.
|
||||
|
||||
My motivation is somewhat different - I want to enhance the VM to
|
||||
support more efficient operations when types are known. Type information
|
||||
can be exploited by JIT compilation technology to improve performance.
|
||||
At the same time, I want to keep the language safe and therefore usable
|
||||
by non-expert programmers.
|
||||
|
||||
Of course there is the fantastic [LuaJIT](http://luajit.org)
|
||||
implementation. Ravi has a different goal compared to LuaJIT. Ravi
|
||||
prioritizes ease of maintenance and support, language safety, and
|
||||
compatibility with Lua 5.3, over maximum performance. For more detailed
|
||||
comparison please refer to the documentation links below.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Optional static typing - for details [see the reference
|
||||
manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
|
||||
- Type specific bytecodes to improve performance
|
||||
- Compatibility with Lua 5.3 (see Compatibility section below)
|
||||
- Generational GC from Lua 5.4
|
||||
- `defer` statement for releasing resources
|
||||
- Compact JIT backend [MIR](https://github.com/vnmakarov/mir).
|
||||
- A [distribution with
|
||||
batteries](https://github.com/dibyendumajumdar/Suravi).
|
||||
- A [Visual Studio Code debugger
|
||||
extension](https://marketplace.visualstudio.com/items?itemName=ravilang.ravi-debug)
|
||||
- interpreted mode debugger.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
- For the Lua extensions in Ravi see the [Reference
|
||||
Manual](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-reference.html).
|
||||
- [MIR JIT Build
|
||||
instructions](https://the-ravi-programming-language.readthedocs.io/en/latest/ravi-mir-instructions.html).
|
||||
- Also see [Ravi
|
||||
Documentation](http://the-ravi-programming-language.readthedocs.org/en/latest/index.html).
|
||||
- and the slides I presented at the [Lua 2015
|
||||
Workshop](http://www.lua.org/wshop15.html).
|
||||
|
||||
Lua Goodies
|
||||
-----------
|
||||
|
||||
- [An Introduction to
|
||||
Lua](http://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html)
|
||||
attempts to provide a quick overview of Lua for folks coming from
|
||||
other languages.
|
||||
- [Lua 5.3 Bytecode
|
||||
Reference](http://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html)
|
||||
is my attempt to bring up to date the [Lua 5.1 Bytecode
|
||||
Reference](http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf).
|
||||
- A [patch for Lua
|
||||
5.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_3.patch)
|
||||
implements the 'defer' statement.
|
||||
- A [patch for Lua
|
||||
5.4.[0-2]](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_for_Lua_5_4.patch)
|
||||
implements the 'defer' statement.
|
||||
- Updated [patch for Lua
|
||||
5.4.3](https://github.com/dibyendumajumdar/ravi/blob/master/patches/defer_statement_patch_for_Lua_5_4_3.patch)
|
||||
implements the 'defer' statement.
|
||||
|
||||
Lua 5.4 Position Statement
|
||||
--------------------------
|
||||
|
||||
Lua 5.4 relationship to Ravi is as follows:
|
||||
|
||||
- Generational GC - back-ported to Ravi.
|
||||
- New random number generator - back-ported to Ravi.
|
||||
- Multiple user values can be associated with userdata - under
|
||||
consideration.
|
||||
- `<const>` variables - not planned.
|
||||
- `<close>` variables - Ravi has `'defer'` statement which is the
|
||||
better option in my opinion, hence no plans to support `<close>`
|
||||
variables.
|
||||
- Interpreter performance improvements - these are beneficial to Lua
|
||||
interpreter but not to the JIT backends, hence not much point in
|
||||
back-porting.
|
||||
- Table implementation changes - under consideration.
|
||||
- String to number coercion is now part of string library metamethods
|
||||
- back-ported to Ravi.
|
||||
- utf8 library accepts codepoints up to 2\^31 - back-ported to Ravi.
|
||||
- Removal of compatibility layers for 5.1, and 5.2 - not implemented
|
||||
as Ravi continues to provide these layers as per Lua 5.3.
|
||||
|
||||
Compatibility with Lua 5.3
|
||||
--------------------------
|
||||
|
||||
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but
|
||||
following should be noted:
|
||||
|
||||
- Ravi supports optional typing and enhanced types such as arrays (see
|
||||
the documentation). Programs using these features cannot be run by
|
||||
standard Lua. However all types in Ravi can be passed to Lua
|
||||
functions; operations on Ravi arrays within Lua code will be subject
|
||||
to restrictions as described in the section above on arrays.
|
||||
- Values crossing from Lua to Ravi will be subjected to typechecks
|
||||
should these values be assigned to typed variables.
|
||||
- Upvalues cannot subvert the static typing of local variables (issue
|
||||
\#26) when types are annotated.
|
||||
- Certain Lua limits are reduced due to changed byte code structure.
|
||||
These are described below.
|
||||
- Ravi uses an extended bytecode which means it is not compatible with
|
||||
Lua 5.x bytecode.
|
||||
- Ravi incorporates the new Generational GC from Lua 5.4, hence the GC
|
||||
interface has changed.
|
||||
|
||||
Limit name Lua value Ravi value
|
||||
------------------ -------------- --------------
|
||||
MAXUPVAL 255 125
|
||||
LUAI\_MAXCCALLS 200 125
|
||||
MAXREGS 255 125
|
||||
MAXVARS 200 125
|
||||
MAXARGLINE 250 120
|
||||
|
||||
When JIT compilation is enabled there are following additional
|
||||
constraints:
|
||||
|
||||
- Ravi will only execute JITed code from the main Lua thread; any
|
||||
secondary threads (coroutines) execute in interpreter mode.
|
||||
- In JITed code tailcalls are implemented as regular calls so unlike
|
||||
the interpreter VM which supports infinite tail recursion JIT
|
||||
compiled code only supports tail recursion to a depth of about 110
|
||||
(issue \#17)
|
||||
- Debug api and hooks are not supported in JIT mode
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
- 2015
|
||||
: - Implemented JIT compilation using LLVM
|
||||
- Implemented [libgccjit based alternative
|
||||
JIT](https://github.com/dibyendumajumdar/ravi/tree/gccjit-ravi534)
|
||||
(now discontinued)
|
||||
|
||||
- 2016
|
||||
: - Implemented debugger for Ravi and Lua 5.3 for [Visual Studio
|
||||
Code](https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger)
|
||||
|
||||
- 2017
|
||||
: - Embedded C compiler using dmrC project (C JIT compiler) (now
|
||||
discontinued)
|
||||
- Additional type-annotations
|
||||
|
||||
- 2018
|
||||
: - Implemented [Eclipse OMR JIT
|
||||
backend](https://github.com/dibyendumajumdar/ravi/tree/omrjit)
|
||||
(now discontinued)
|
||||
- Created [Ravi with
|
||||
batteries](https://github.com/dibyendumajumdar/Suravi).
|
||||
|
||||
- 2019
|
||||
: - New language feature - defer statement
|
||||
- New JIT backend [MIR](https://github.com/vnmakarov/mir).
|
||||
|
||||
- 2020
|
||||
: - [New parser / type checker /
|
||||
compiler](https://github.com/dibyendumajumdar/ravi-compiler)
|
||||
- Generational GC back-ported from Lua 5.4
|
||||
- Support for [LLVM
|
||||
backend](https://github.com/dibyendumajumdar/ravi/tree/llvm)
|
||||
archived
|
||||
|
||||
- 2021 (Plan)
|
||||
: - Integrated AOT and JIT compilation support
|
||||
- Ravi 1.0 release
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT License
|
@ -0,0 +1,524 @@
|
||||
=========================
|
||||
Ravi Programming Language
|
||||
=========================
|
||||
|
||||
Ravi is a derivative/dialect of `Lua 5.3 <http://www.lua.org/>`_ with limited optional static typing and an `LLVM <http://www.llvm.org/>`_ powered JIT compiler. The name Ravi comes from the Sanskrit word for the Sun. Interestingly a precursor to Lua was `Sol <http://www.lua.org/history.html>`_ which had support for static types; Sol means the Sun in Portugese.
|
||||
|
||||
Lua is perfect as a small embeddable dynamic language so why a derivative? Ravi extends Lua with static typing for greater performance under JIT compilation. However, the static typing is optional and therefore Lua programs are also valid Ravi programs.
|
||||
|
||||
There are other attempts to add static typing to Lua - e.g. `Typed Lua <https://github.com/andremm/typedlua>`_ but these efforts are mostly about adding static type checks in the language while leaving the VM unmodified. The Typed Lua effort is very similar to the approach taken by Typescript in the JavaScript world. The static typing is to aid programming in the large - the code is eventually translated to standard Lua and executed in the unmodified Lua VM.
|
||||
|
||||
My motivation is somewhat different - I want to enhance the VM to support more efficient operations when types are known. Type information can be exploited by JIT compilation technology to improve performance. At the same time, I want to keep the language safe and therefore usable by non-expert programmers.
|
||||
|
||||
Of course there is also the fantastic `LuaJIT <http://luajit.org>`_ implementation. Ravi has a different goal compared to
|
||||
LuaJIT. Ravi prioritizes ease of maintenance and support, language safety, and compatibility with Lua 5.3, over maximum performance. For more detailed comparison please refer to the documentation links below.
|
||||
|
||||
|
||||
.. contents:: Table of Contents
|
||||
:depth: 1
|
||||
:backlinks: top
|
||||
|
||||
Features
|
||||
========
|
||||
* Optional static typing
|
||||
* Type specific bytecodes to improve performance
|
||||
* Compatibility with Lua 5.3 (see Compatibility section below)
|
||||
* `LLVM <http://www.llvm.org/>`_ powered JIT compiler
|
||||
* Additionally a `libgccjit <https://gcc.gnu.org/wiki/JIT>`_ based alternative JIT compiler is also available (on a branch), although this is not currently being worked on
|
||||
* LLVM bindings exposed in Lua
|
||||
|
||||
Recent Work
|
||||
===========
|
||||
* A `distribution of Ravi/Lua 5.3 <https://github.com/dibyendumajumdar/ravi-distro>`_ is in the works - this will provide ready made binary downloads of Ravi/Lua with select high quality libraries.
|
||||
* `Experimental Type Annotations`_ for user defined types was implemented in Oct 2017.
|
||||
* A new `X86-64 VM written in assembler <https://github.com/dibyendumajumdar/ravi/tree/master/vmbuilder>`_ using `dynasm <https://luajit.org/dynasm.html>`_ tool is under development currently.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
See `Ravi Documentation <http://the-ravi-programming-language.readthedocs.org/en/latest/index.html>`_.
|
||||
As more stuff is built I will keep updating the documentation so please revisit for latest information.
|
||||
|
||||
Also see the slides I presented at the `Lua 2015 Workshop <http://www.lua.org/wshop15.html>`_.
|
||||
|
||||
Lua Goodies
|
||||
===========
|
||||
* `An Introduction to Lua <http://the-ravi-programming-language.readthedocs.io/en/latest/lua-introduction.html>`_ attempts to provide a quick overview of Lua for folks coming from other languages.
|
||||
* `Lua 5.3 Bytecode Reference <http://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html>`_ is my attempt to bring up to date the `Lua 5.1 Bytecode Reference <http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf>`_.
|
||||
|
||||
JIT Implementation
|
||||
==================
|
||||
The LLVM JIT compiler is functional. The Lua and Ravi bytecodes currently implemented in LLVM are described in `JIT Status <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-jit-status.html>`_ page.
|
||||
|
||||
Ravi also provides an `LLVM binding <http://the-ravi-programming-language.readthedocs.org/en/latest/llvm-bindings.html>`_; this is still work in progress so please check documentation for the latest status.
|
||||
|
||||
Ravi Extensions to Lua 5.3
|
||||
==========================
|
||||
|
||||
Optional Static Typing
|
||||
----------------------
|
||||
Ravi allows you to annotate ``local`` variables and function parameters with static types. The supported types and the resulting behaviour are as follows:
|
||||
|
||||
``integer``
|
||||
denotes an integral value of 64-bits.
|
||||
``number``
|
||||
denotes a double (floating point) value of 8 bytes.
|
||||
``integer[]``
|
||||
denotes an array of integers
|
||||
``number[]``
|
||||
denotes an array of numbers
|
||||
``table``
|
||||
a Lua table
|
||||
|
||||
Additionally there are some `Experimental Type Annotations`_.
|
||||
|
||||
Declaring the types of ``local`` variables and function parameters has following advantages.
|
||||
|
||||
* ``integer`` and ``number`` types are automatically initialized to zero
|
||||
* Arithmetic operations on numeric types make use of type specific bytecodes which leads to more efficient JIT compilation
|
||||
* Specialised operators to get/set from array types are implemented; this makes array access more efficient in JIT mode as the access can be inlined
|
||||
* Declared tables allow specialized opcodes for table gets involving integer and short literal string keys; these opcodes result in more efficient JIT code
|
||||
* Values assigned to typed variables are checked statically when possible; if the values are results from a function call then runtime type checking is performed
|
||||
* The standard table operations on arrays are checked to ensure that the type is not subverted
|
||||
* Even if a typed variable is captured in a closure its type must be respected
|
||||
* When function parameters are decorated with types, Ravi performs an implicit coersion of those parameters to the required types. If the coersion fails a runtime error occurs.
|
||||
|
||||
The array types (``number[]`` and ``integer[]``) are specializations of Lua table with some additional special behaviour:
|
||||
|
||||
* Array types are not compatible with declared table variables, i.e. following is not allowed::
|
||||
|
||||
local t: table = {}
|
||||
local t2: number[] = t -- error!
|
||||
|
||||
local t3: number[] = {}
|
||||
local t4: table = t3 -- error!
|
||||
|
||||
But following is okay::
|
||||
|
||||
local t5: number[] = {}
|
||||
local t6 = t5 -- t6 treated as table
|
||||
|
||||
The reason for these restrictions is that declared table types generate optimized JIT code which assumes that the keys are integers
|
||||
or literal short strings. Similarly declared array types result in specialized JIT code that assume integer keys and numeric values.
|
||||
The generated JIT code would be incorrect if the types were not as expected.
|
||||
|
||||
* Indices >= 1 should be used when accessing array elements. Ravi arrays (and slices) have a hidden slot at index 0 for performance reasons, but this is not visible in ``pairs()`` or ``ipairs()``, or when initializing an array using a literal initializer; only direct access via the ``[]`` operator can see this slot.
|
||||
* Arrays must always be initialized::
|
||||
|
||||
local t: number[] = {} -- okay
|
||||
local t2: number[] -- error!
|
||||
|
||||
This restriction is placed as otherwise the JIT code would need to insert tests to validate that the variable is not nil.
|
||||
|
||||
* An array will grow automatically (unless the array was created as fixed length using ``table.intarray()`` or ``table.numarray()``) if the user sets the element just past the array length::
|
||||
|
||||
local t: number[] = {} -- dynamic array
|
||||
t[1] = 4.2 -- okay, array grows by 1
|
||||
t[5] = 2.4 -- error! as attempt to set value
|
||||
|
||||
* It is an error to attempt to set an element that is beyond len+1 on dynamic arrays; for fixed length arrays attempting to set elements at positions greater than len will cause an error.
|
||||
* The current used length of the array is recorded and returned by len operations
|
||||
* The array only permits the right type of value to be assigned (this is also checked at runtime to allow compatibility with Lua)
|
||||
* Accessing out of bounds elements will cause an error, except for setting the len+1 element on dynamic arrays
|
||||
* It is possible to pass arrays to functions and return arrays from functions. Arrays passed to functions appear as Lua tables inside
|
||||
those functions if the parameters are untyped - however the tables will still be subject to restrictions as above. If the parameters are typed then the arrays will be recognized at compile time::
|
||||
|
||||
local function f(a, b: integer[], c)
|
||||
-- Here a is dynamic type
|
||||
-- b is declared as integer[]
|
||||
-- c is also a dynamic type
|
||||
b[1] = a[1] -- Okay only if a is actually also integer[]
|
||||
b[1] = c[1] -- Will fail if c[1] cannot be converted to an integer
|
||||
end
|
||||
|
||||
local a : integer[] = {1}
|
||||
local b : integer[] = {}
|
||||
local c = {1}
|
||||
|
||||
f(a,b,c) -- ok as c[1] is integer
|
||||
f(a,b, {'hi'}) -- error!
|
||||
|
||||
* Arrays returned from functions can be stored into appropriately typed local variables - there is validation that the types match::
|
||||
|
||||
local t: number[] = f() -- type will be checked at runtime
|
||||
|
||||
* Operations on array types can be optimised to special bytecode and JIT only when the array type is statically known. Otherwise regular table access will be used subject to runtime checks.
|
||||
* Array types ignore ``__index``, ``__newindex`` and ``__len`` metamethods.
|
||||
* Array types cannot be set as metatables for other values.
|
||||
* ``pairs()`` and ``ipairs()`` work on arrays as normal
|
||||
* There is no way to delete an array element.
|
||||
* The array data is stored in contiguous memory just like native C arrays; morever the garbage collector does not scan the array data
|
||||
|
||||
A declared table (as shown below) has some additional nuances::
|
||||
|
||||
local t: table = {}
|
||||
|
||||
* Like array types, a variable of ``table`` type must be initialized
|
||||
* Array types are not compatible with declared table variables, i.e. following is not allowed::
|
||||
|
||||
local t: table = {}
|
||||
local t2: number[] = t -- error!
|
||||
|
||||
* When short string literals are used to access a table element, specialized bytecodes are generated that are more efficiently JIT compiled::
|
||||
|
||||
local t: table = { name='dibyendu'}
|
||||
print(t.name) -- The GETTABLE opcode is specialized in this case
|
||||
|
||||
* As with array types, specialized bytecodes are generated when integer keys are used
|
||||
|
||||
Following library functions allow creation of array types of defined length.
|
||||
|
||||
``table.intarray(num_elements, initial_value)``
|
||||
creates an integer array of specified size, and initializes with initial value. The return type is integer[]. The size of the array cannot be changed dynamically, i.e. it is fixed to the initial specified size. This allows slices to be created on such arrays.
|
||||
|
||||
``table.numarray(num_elements, initial_value)``
|
||||
creates an number array of specified size, and initializes with initial value. The return type is number[]. The size of the array cannot be changed dynamically, i.e. it is fixed to the initial specified size. This allows slices to be created on such arrays.
|
||||
|
||||
Type Assertions
|
||||
---------------
|
||||
Ravi does not support defining new types, or structured types based on tables. This creates some practical issues when dynamic types are mixed with static types. For example::
|
||||
|
||||
local t = { 1,2,3 }
|
||||
local i: integer = t[1] -- generates an error
|
||||
|
||||
Above code generates an error as the compiler does not know that the value in ``t[1]`` is an integer. However often we as programmers know the type that is expected and it would be nice to be able to tell the compiler what the expected type of ``t[1]`` is above. To enable this Ravi supports type assertion operators. A type assertion is introduced by the '``@``' symbol, which must be followed by the type name. So we can rewrite the above example as::
|
||||
|
||||
local t = { 1,2,3 }
|
||||
local i: integer = @integer( t[1] )
|
||||
|
||||
The type assertion operator is a unary operator and binds to the expression following the operator. We use the parenthesis above to enure that the type assertion is applied to ``t[1]`` rather than ``t``. More examples are shown below::
|
||||
|
||||
local a: number[] = @number[] { 1,2,3 }
|
||||
local t = { @number[] { 4,5,6 }, @integer[] { 6,7,8 } }
|
||||
local a1: number[] = @number[]( t[1] )
|
||||
local a2: integer[] = @integer[]( t[2] )
|
||||
|
||||
For a real example of how type assertions can be used, please have a look at the test program `gaussian2.lua <https://github.com/dibyendumajumdar/ravi/blob/master/ravi-tests/gaussian2.lua>`_
|
||||
|
||||
Experimental Type Annotations
|
||||
-----------------------------
|
||||
Following type annotations have experimental support. These type annotations are not always statically enforced. Furthermore using these types does not affect the JIT code generation, i.e. variables annotated using these types are still treated as dynamic types.
|
||||
|
||||
The scenarios where these type annotations have an impact are:
|
||||
|
||||
* Function parameters containing these annotations lead to type assertions at runtime.
|
||||
* The type assertion operator @ can be applied to these types - leading to runtime assertions.
|
||||
* Annotating ``local`` declarations results in type assertions.
|
||||
|
||||
``string``
|
||||
denotes a string
|
||||
``closure``
|
||||
denotes a function
|
||||
Name
|
||||
Denotes a value that has a `metatable registered under Name <https://www.lua.org/pil/28.2.html>`_ in the Lua registry. The Name must be a valid Lua name - hence periods in the name are not allowed.
|
||||
|
||||
The main use case for these annotations is to help with type checking of larger Ravi programs. These type checks, particularly the one for user defined types, are executed directly by the VM and hence are more efficient than performing the checks in other ways.
|
||||
|
||||
All three types above allow ``nil`` assignment.
|
||||
|
||||
Examples::
|
||||
|
||||
-- Create a metatable
|
||||
local mt = { __name='MyType'}
|
||||
|
||||
-- Register the metatable in Lua registry
|
||||
debug.getregistry().MyType = mt
|
||||
|
||||
-- Create an object and assign the metatable as its type
|
||||
local t = {}
|
||||
setmetatable(t, mt)
|
||||
|
||||
-- Use the metatable name as the object's type
|
||||
function x(s: MyType)
|
||||
local assert = assert
|
||||
assert(@MyType(s) == @MyType(t))
|
||||
assert(@MyType(t) == t)
|
||||
end
|
||||
|
||||
-- Here we use the string type
|
||||
function x(s1: string, s2: string)
|
||||
return @string( s1 .. s2 )
|
||||
end
|
||||
|
||||
-- Following demonstrates an error caused by the type checking
|
||||
-- Note that this error is raised at runtime
|
||||
function x()
|
||||
local s: string
|
||||
-- call a function that returns integer value
|
||||
-- and try to assign to s
|
||||
s = (function() return 1 end)()
|
||||
end
|
||||
x() -- will fail at runtime
|
||||
|
||||
Array Slices
|
||||
------------
|
||||
Since release 0.6 Ravi supports array slices. An array slice allows a portion of a Ravi array to be treated as if it is an array - this allows efficient access to the underlying array elements. Following new functions are available:
|
||||
|
||||
``table.slice(array, start_index, num_elements)``
|
||||
creates a slice from an existing *fixed size* array - allowing efficient access to the underlying array elements.
|
||||
|
||||
Slices access the memory of the underlying array; hence a slice can only be created on fixed size arrays (constructed by ``table.numarray()`` or ``table.intarray()``). This ensures that the array memory cannot be reallocated while a slice is referring to it. Ravi does not track the slices that refer to arrays - slices get garbage collected as normal.
|
||||
|
||||
Slices cannot extend the array size for the same reasons above.
|
||||
|
||||
The type of a slice is the same as that of the underlying array - hence slices get the same optimized JIT operations for array access.
|
||||
|
||||
Each slice holds an internal reference to the underlying array to ensure that the garbage collector does not reclaim the array while there are slices pointing to it.
|
||||
|
||||
For an example use of slices please see the `matmul1.ravi <https://github.com/dibyendumajumdar/ravi/blob/master/ravi-tests/matmul1.ravi>`_ benchmark program in the repository. Note that this feature is highly experimental and not very well tested.
|
||||
|
||||
Examples
|
||||
--------
|
||||
Example of code that works - you can copy this to the command line input::
|
||||
|
||||
function tryme()
|
||||
local i,j = 5,6
|
||||
return i,j
|
||||
end
|
||||
local i:integer, j:integer = tryme(); print(i+j)
|
||||
|
||||
When values from a function call are assigned to a typed variable, an implicit type coersion takes place. In above example an error would occur if the function returned values that could not converted to integers.
|
||||
|
||||
In the following example, the parameter ``j`` is defined as a ``number``, hence it is an error to pass a value that cannot be converted to a ``number``::
|
||||
|
||||
function tryme(j: number)
|
||||
for i=1,1000000000 do
|
||||
j = j+1
|
||||
end
|
||||
return j
|
||||
end
|
||||
print(tryme(0.0))
|
||||
|
||||
An example with arrays::
|
||||
|
||||
function tryme()
|
||||
local a : number[], j:number = {}
|
||||
for i=1,10 do
|
||||
a[i] = i
|
||||
j = j + a[i]
|
||||
end
|
||||
return j
|
||||
end
|
||||
print(tryme())
|
||||
|
||||
Another example using arrays. Here the function receives a parameter ``arr`` of type ``number[]`` - it would be an error to pass any other type to the function because only ``number[]`` types can be converted to ``number[]`` types::
|
||||
|
||||
function sum(arr: number[])
|
||||
local n: number = 0.0
|
||||
for i = 1,#arr do
|
||||
n = n + arr[i]
|
||||
end
|
||||
return n
|
||||
end
|
||||
|
||||
print(sum(table.numarray(10, 2.0)))
|
||||
|
||||
The ``table.numarray(n, initial_value)`` creates a ``number[]`` of specified size and initializes the array with the given initial value.
|
||||
|
||||
All type checks are at runtime
|
||||
------------------------------
|
||||
To keep with Lua's dynamic nature Ravi uses a mix of compile type checking and runtime type checks. However due to the dynamic nature of Lua, compilation happens at runtime anyway so effectually all checks are at runtime.
|
||||
|
||||
JIT API
|
||||
-------
|
||||
The LLVM based JIT compiler is functional.
|
||||
There are two modes of JIT compilation.
|
||||
|
||||
auto mode
|
||||
in this mode the compiler decides when to compile a Lua function. The current implementation is very simple - any Lua function call is checked to see if the bytecodes contained in it can be compiled. If this is true then the function is compiled provided either a) function has a fornum loop, or b) it is largish (greater than 150 bytecodes) or c) it is being executed many times (> 50). Because of the simplistic behaviour performance the benefit of JIT compilation is only available if the JIT compiled functions will be executed many times so that the cost of JIT compilation can be amortized.
|
||||
manual mode
|
||||
in this mode user must explicitly request compilation. This is the default mode. This mode is suitable for library developers who can pre compile the functions in library module table.
|
||||
|
||||
A JIT api is available with following functions:
|
||||
|
||||
``ravi.jit([b])``
|
||||
returns enabled setting of JIT compiler; also enables/disables the JIT compiler; defaults to true
|
||||
``ravi.auto([b [, min_size [, min_executions]]])``
|
||||
returns setting of auto compilation and compilation thresholds; also sets the new settings if values are supplied; defaults are false, 150, 50.
|
||||
``ravi.compile(func_or_table[, options])``
|
||||
compiles a Lua function (or functions if a table is supplied) if possible, returns ``true`` if compilation was successful for at least one function. ``options`` is an optional table with compilation options - in particular ``omitArrayGetRangeCheck`` - which disables range checks in array get operations to improve performance in some cases. Note that at present if the first argument is a table of functions and has more than 100 functions then only the first 100 will be compiled. You can invoke compile() repeatedly on the table until it returns false. Each invocation leads to a new module being created; any functions already compiled are skipped.
|
||||
``ravi.iscompiled(func)``
|
||||
returns the JIT status of a function
|
||||
``ravi.dumplua(func)``
|
||||
dumps the Lua bytecode of the function
|
||||
``ravi.dumpir(func)``
|
||||
(deprecated) dumps the IR of the compiled function (only if function was compiled; only available in LLVM 4.0 and earlier)
|
||||
``ravi.dumpasm(func)``
|
||||
(deprecated) dumps the machine code using the currently set optimization level (only if function was compiled; only available in LLVM version 4.0 and earlier)
|
||||
``ravi.optlevel([n])``
|
||||
sets LLVM optimization level (0, 1, 2, 3); defaults to 2. These levels are handled by reusing LLVMs default pass definitions which are geared towards C/C++ programs, but appear to work well here. If level is set to 0, then an attempt is made to use fast instruction selection to further speed up compilation.
|
||||
``ravi.sizelevel([n])``
|
||||
sets LLVM size level (0, 1, 2); defaults to 0
|
||||
``ravi.tracehook([b])``
|
||||
Enables support for line hooks via the debug api. Note that enabling this option will result in inefficient JIT as a call to a C function will be inserted at beginning of every Lua bytecode boundary; use this option only when you want to use the debug api to step through code line by line
|
||||
``ravi.verbosity([b])``
|
||||
Controls the amount of verbose messages generated during compilation. Currently only available for LLVM.
|
||||
|
||||
Performance
|
||||
===========
|
||||
For performance benchmarks please visit the `Ravi Performance Benchmarks <http://the-ravi-programming-language.readthedocs.org/en/latest/ravi-benchmarks.html>`_ page.
|
||||
|
||||
To obtain the best possible performance, types must be annotated so that Ravi's JIT compiler can generate efficient code.
|
||||
Additionally function calls are expensive - as the JIT compiler cannot inline function calls, all function calls go via the Lua call protocol which has a large overhead. This is true for both Lua functions and C functions. For best performance avoid function calls inside loops.
|
||||
|
||||
Compatibility with Lua
|
||||
======================
|
||||
Ravi should be able to run all Lua 5.3 programs in interpreted mode, but following should be noted:
|
||||
|
||||
* Ravi supports optional typing and enhanced types such as arrays (described above). Programs using these features cannot be run by standard Lua. However all types in Ravi can be passed to Lua functions; operations on Ravi arrays within Lua code will be subject to restrictions as described in the section above on arrays.
|
||||
* Values crossing from Lua to Ravi will be subjected to typechecks should these values be assigned to typed variables.
|
||||
* Upvalues cannot subvert the static typing of local variables (issue #26) when types are annotated.
|
||||
* Certain Lua limits are reduced due to changed byte code structure. These are described below.
|
||||
|
||||
+-----------------+-------------+-------------+
|
||||
| Limit name | Lua value | Ravi value |
|
||||
+=================+=============+=============+
|
||||
| MAXUPVAL | 255 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| LUAI_MAXCCALLS | 200 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| MAXREGS | 255 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| MAXVARS | 200 | 125 |
|
||||
+-----------------+-------------+-------------+
|
||||
| MAXARGLINE | 250 | 120 |
|
||||
+-----------------+-------------+-------------+
|
||||
|
||||
When JIT compilation is enabled there are following additional constraints:
|
||||
|
||||
* Ravi will only execute JITed code from the main Lua thread; any secondary threads (coroutines) execute in interpreter mode.
|
||||
* In JITed code tailcalls are implemented as regular calls so unlike the interpreter VM which supports infinite tail recursion JIT compiled code only supports tail recursion to a depth of about 110 (issue #17)
|
||||
|
||||
Building Ravi
|
||||
=============
|
||||
|
||||
Quick build without JIT
|
||||
-----------------------
|
||||
A Makefile is supplied for a simple build without the JIT. Just run ``make`` and follow instructions. You may need to customize the Makefiles.
|
||||
|
||||
For building Ravi with JIT options please read on.
|
||||
|
||||
Build Dependencies
|
||||
------------------
|
||||
|
||||
* CMake
|
||||
|
||||
Ravi can be built with or without LLVM. Following versions of LLVM work with Ravi.
|
||||
|
||||
* LLVM 3.7 or 3.8 or 3.9 or 4.0 or 5.0
|
||||
* LLVM 3.5 and 3.6 should also work but have not been recently tested
|
||||
|
||||
Unless otherwise noted the instructions below should work for LLVM 3.9 and later.
|
||||
|
||||
Since LLVM 5.0 Ravi has begun to use the new ORC JIT apis. These apis are more memory efficient compared to the MCJIT apis because they release the Module IR as early as possible, whereas with MCJIT the Module IR hangs around as long as the compiled code is held. Because of this significant improvement, I recommend using LLVM 5.0 and above.
|
||||
|
||||
Building LLVM on Windows
|
||||
------------------------
|
||||
I built LLVM from source. I used the following sequence from the VS2017 command window::
|
||||
|
||||
cd \github\llvm
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\LLVM -DLLVM_TARGETS_TO_BUILD="X86" -G "Visual Studio 15 2017 Win64" ..
|
||||
|
||||
I then opened the generated solution in VS2017 and performed a INSTALL build from there. Above will build the 64-bit version of LLVM libraries. To build a 32-bit version omit the ``Win64`` parameter.
|
||||
|
||||
.. note:: Note that if you perform a Release build of LLVM then you will also need to do a Release build of Ravi otherwise you will get link errors.
|
||||
|
||||
Building LLVM on Ubuntu
|
||||
-----------------------
|
||||
On Ubuntu I found that the official LLVM distributions don't work with CMake. The CMake config files appear to be broken.
|
||||
So I ended up downloading and building LLVM from source and that worked. The approach is similar to that described for MAC OS X below.
|
||||
|
||||
Building LLVM on MAC OS X
|
||||
-------------------------
|
||||
I am using Max OSX El Capitan. Pre-requisites are XCode 7.x and CMake.
|
||||
Ensure cmake is on the path.
|
||||
Assuming that LLVM source has been extracted to ``$HOME/llvm-3.7.0.src`` I follow these steps::
|
||||
|
||||
cd llvm-3.7.0.src
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/LLVM -DLLVM_TARGETS_TO_BUILD="X86" ..
|
||||
make install
|
||||
|
||||
Building Ravi with JIT enabled
|
||||
------------------------------
|
||||
I am developing Ravi using Visual Studio 2017 Community Edition on Windows 10 64bit, gcc on Unbuntu 64-bit, and clang/Xcode on MAC OS X. I was also able to successfully build a Ubuntu version on Windows 10 using the newly released Ubuntu/Linux sub-system for Windows 10.
|
||||
|
||||
.. note:: Location of cmake files prior to LLVM 3.9 was ``$LLVM_INSTALL_DIR/share/llvm/cmake``.
|
||||
|
||||
Assuming that LLVM has been installed as described above, then on Windows I invoke the cmake config as follows::
|
||||
|
||||
cd build
|
||||
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=c:\ravi -DLLVM_DIR=c:\LLVM\lib\cmake\llvm -G "Visual Studio 15 2017 Win64" ..
|
||||
|
||||
I then open the solution in VS2017 and do a build from there.
|
||||
|
||||
On Ubuntu I use::
|
||||
|
||||
cd build
|
||||
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" ..
|
||||
make
|
||||
|
||||
Note that on a clean install of Ubuntu 15.10 I had to install following packages:
|
||||
|
||||
* cmake
|
||||
* git
|
||||
* libreadline-dev
|
||||
|
||||
On MAC OS X I use::
|
||||
|
||||
cd build
|
||||
cmake -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -G "Xcode" ..
|
||||
|
||||
I open the generated project in Xcode and do a build from there. You can also use the command line build tools if you wish - generate the make files in the same way as for Linux.
|
||||
|
||||
Building without JIT
|
||||
--------------------
|
||||
You can omit ``-DLLVM_JIT=ON`` option above to build Ravi with a null JIT implementation.
|
||||
|
||||
Building Static Libraries
|
||||
-------------------------
|
||||
By default the build generates a shared library for Ravi. You can choose to create a static library and statically linked executables by supplying the argument ``-DSTATIC_BUILD=ON`` to CMake.
|
||||
|
||||
Build Artifacts
|
||||
---------------
|
||||
The Ravi build creates a shared or static depending upon options supplied to CMake, the Ravi executable and some test programs. Additionally when JIT compilation is switched off, the ``ravidebug`` executable is generated which is the `debug adapter for use by Visual Studio Code <https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger>`_.
|
||||
|
||||
The ``ravi`` command recognizes following environment variables. Note that these are only for internal debugging purposes.
|
||||
|
||||
``RAVI_DEBUG_EXPR``
|
||||
if set to a value this triggers debug output of expression parsing
|
||||
``RAVI_DEBUG_CODEGEN``
|
||||
if set to a value this triggers a dump of the code being generated
|
||||
``RAVI_DEBUG_VARS``
|
||||
if set this triggers a dump of local variables construction and destruction
|
||||
|
||||
Also see section above on available API for dumping either Lua bytecode or LLVM IR for compiled code.
|
||||
|
||||
Testing
|
||||
-------
|
||||
I test the build by running a modified version of Lua 5.3.3 test suite. These tests are located in the ``lua-tests`` folder. Additionally I have ravi specific tests in the ``ravi-tests`` folder. There is a also a travis build that occurs upon commits - this build runs the tests as well.
|
||||
|
||||
.. note:: To thoroughly test changes, you need to invoke CMake with ``-DCMAKE_BUILD_TYPE=Debug`` option. This turns on assertions, memory checking, and also enables an internal module used by Lua tests.
|
||||
|
||||
Roadmap
|
||||
=======
|
||||
* 2015
|
||||
- Implemented JIT compilation using LLVM
|
||||
- Implemented libgccjit based alternative JIT (now discontinued)
|
||||
* 2016
|
||||
- Implemented debugger for Ravi and Lua 5.3 for `Visual Studio Code <https://github.com/dibyendumajumdar/ravi/tree/master/vscode-debugger>`_
|
||||
* 2017
|
||||
- Embedded C compiler using dmrC project (C JIT compiler)
|
||||
- Additional type annotations
|
||||
* 2018
|
||||
- 1.0 release of Ravi
|
||||
- More testing and test cases
|
||||
- ASM VM for X86-64 platform
|
||||
- Better support for earlier Lua versions (5.1 especially)
|
||||
|
||||
License
|
||||
=======
|
||||
MIT License for LLVM version.
|
||||
|
@ -0,0 +1,5 @@
|
||||
mkdir llvm32
|
||||
cd llvm32
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake -DBUILD_STATIC=OFF ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39_32\lib\cmake\llvm -DSTATIC_BUILD=OFF ..
|
||||
cd ..
|
@ -0,0 +1,5 @@
|
||||
mkdir llvm32
|
||||
cd llvm32
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39\lib\cmake\llvm -DSTATIC_BUILD=ON ..
|
||||
cd ..
|
@ -0,0 +1,5 @@
|
||||
mkdir llvm32d
|
||||
cd llvm32d
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM37_32\share\llvm\cmake ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=\d\ravi32 -G "Visual Studio 14" -DLLVM_JIT=ON -DLLVM_DIR=\d\LLVM39D_32\lib\cmake\llvm -DSTATIC_BUILD=ON ..
|
||||
cd ..
|
@ -0,0 +1,6 @@
|
||||
mkdir llvm64d
|
||||
cd llvm64d
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi64llvmd -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37debug\share\llvm\cmake ..
|
||||
rem cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=c:\d\ravi64llvmd -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DEMBEDDED_DMRC=ON -DLLVM_DIR=c:\d\LLVM39D64\lib\cmake\llvm ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DLTESTS=ON -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501d\lib\cmake\llvm ..
|
||||
cd ..
|
@ -0,0 +1,8 @@
|
||||
mkdir llvm64
|
||||
cd llvm64
|
||||
rem pre LLVM 3.9
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 14 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\LLVM37\share\llvm\cmake ..
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\ravi -G "Visual Studio 15 2017 Win64" -DLLVM_JIT=ON -DLLVM_DIR=c:\d\LLVM40_64\lib\cmake\llvm ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501r\lib\cmake\llvm ..
|
||||
rem cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -G "Visual Studio 15 2017 Win64" -DSTATIC_BUILD=ON -DLLVM_JIT=ON -DLLVM_DIR=c:\Software\llvm501r\lib\cmake\llvm ..
|
||||
cd ..
|
@ -0,0 +1,4 @@
|
||||
mkdir asmvm
|
||||
cd asmvm
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi-asmvm -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Debug -DASM_VM=ON -G "Visual Studio 15 2017 Win64" ..
|
||||
cd ..
|
@ -1,4 +1,4 @@
|
||||
mkdir nojit64a
|
||||
cd nojit64a
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DLTESTS=ON -G "Visual Studio 15 2017 Win64" ..
|
||||
cd ..
|
@ -1,4 +1,4 @@
|
||||
mkdir nojit64
|
||||
cd nojit64
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Release -DSTATIC_BUILD=OFF -G "Visual Studio 15 2017 Win64" ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=c:\Software\ravi -DCMAKE_BUILD_TYPE=Debug -DSTATIC_BUILD=OFF -G "Visual Studio 15 2017 Win64" ..
|
||||
cd ..
|
@ -0,0 +1,4 @@
|
||||
mkdir xcodellvm
|
||||
cd xcodellvm
|
||||
#cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -G Xcode -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
|
@ -0,0 +1,5 @@
|
||||
mkdir buildllvmd
|
||||
cd buildllvmd
|
||||
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
|
||||
#cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DLLVM_JIT=ON -DLTESTS=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravillvm -DLLVM_DIR=$HOME/Software/llvm600/lib/cmake/llvm ..
|
@ -0,0 +1,4 @@
|
||||
mkdir buildllvm
|
||||
cd buildllvm
|
||||
#cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM/share/llvm/cmake ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_JIT=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi -DLLVM_DIR=$HOME/LLVM5/lib/cmake/llvm ..
|
@ -0,0 +1,3 @@
|
||||
mkdir buildasmvm
|
||||
cd buildasmvm
|
||||
cmake -DSTATIC_BUILD=ON -DASM_VM=ON -DCMAKE_BUILD_TYPE=Debug -DCOMPUTED_GOTO=ON -DCMAKE_INSTALL_PREFIX=$HOME/ravi ..
|
@ -0,0 +1,73 @@
|
||||
; ModuleID = 'inline_getstr.c'
|
||||
source_filename = "inline_getstr.c"
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||
target triple = "i686-pc-windows-msvc"
|
||||
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.Table = type { %struct.GCObject*, i8, i8, i8, i8, i32, %struct.TValue*, %struct.Node*, %struct.Node*, %struct.Table*, %struct.GCObject*, %struct.RaviArray, i32 }
|
||||
%struct.Node = type { %struct.TValue, %union.TKey }
|
||||
%union.TKey = type { %struct.anon.1 }
|
||||
%struct.anon.1 = type { %union.Value, i32, i32 }
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.RaviArray = type { i8*, i32, i32, i32 }
|
||||
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.2 }
|
||||
%union.anon.2 = type { i64 }
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define %struct.TValue* @ravi_getstr(%struct.Table* %t, %struct.TString* %key) local_unnamed_addr #0 {
|
||||
entry:
|
||||
%hash = getelementptr inbounds %struct.TString, %struct.TString* %key, i32 0, i32 5
|
||||
%0 = load i32, i32* %hash, align 8, !tbaa !1
|
||||
%hmask = getelementptr inbounds %struct.Table, %struct.Table* %t, i32 0, i32 12
|
||||
%1 = load i32, i32* %hmask, align 4, !tbaa !7
|
||||
%and = and i32 %1, %0
|
||||
%node = getelementptr inbounds %struct.Table, %struct.Table* %t, i32 0, i32 7
|
||||
%2 = load %struct.Node*, %struct.Node** %node, align 4, !tbaa !10
|
||||
%3 = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 1, i32 0, i32 1
|
||||
%4 = load i32, i32* %3, align 8, !tbaa !11
|
||||
%cmp = icmp eq i32 %4, 68
|
||||
br i1 %cmp, label %land.lhs.true, label %if.end
|
||||
|
||||
land.lhs.true: ; preds = %entry
|
||||
%value_ = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 1, i32 0, i32 0
|
||||
%5 = bitcast %union.Value* %value_ to %struct.TString**
|
||||
%6 = load %struct.TString*, %struct.TString** %5, align 8, !tbaa !13
|
||||
%cmp1 = icmp eq %struct.TString* %6, %key
|
||||
br i1 %cmp1, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %land.lhs.true
|
||||
%i_val = getelementptr inbounds %struct.Node, %struct.Node* %2, i32 %and, i32 0
|
||||
br label %cleanup
|
||||
|
||||
if.end: ; preds = %land.lhs.true, %entry
|
||||
%call = tail call %struct.TValue* @luaH_getstr(%struct.Table* nonnull %t, %struct.TString* nonnull %key) #2
|
||||
br label %cleanup
|
||||
|
||||
cleanup: ; preds = %if.end, %if.then
|
||||
%retval.0 = phi %struct.TValue* [ %i_val, %if.then ], [ %call, %if.end ]
|
||||
ret %struct.TValue* %retval.0
|
||||
}
|
||||
|
||||
declare %struct.TValue* @luaH_getstr(%struct.Table*, %struct.TString*) local_unnamed_addr #1
|
||||
|
||||
attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 3.9.0 (trunk)"}
|
||||
!1 = !{!2, !6, i64 8}
|
||||
!2 = !{!"TString", !3, i64 0, !4, i64 4, !4, i64 5, !4, i64 6, !4, i64 7, !6, i64 8, !4, i64 16}
|
||||
!3 = !{!"any pointer", !4, i64 0}
|
||||
!4 = !{!"omnipotent char", !5, i64 0}
|
||||
!5 = !{!"Simple C/C++ TBAA"}
|
||||
!6 = !{!"int", !4, i64 0}
|
||||
!7 = !{!8, !6, i64 48}
|
||||
!8 = !{!"Table", !3, i64 0, !4, i64 4, !4, i64 5, !4, i64 6, !4, i64 7, !6, i64 8, !3, i64 12, !3, i64 16, !3, i64 20, !3, i64 24, !3, i64 28, !9, i64 32, !6, i64 48}
|
||||
!9 = !{!"RaviArray", !3, i64 0, !4, i64 4, !6, i64 8, !6, i64 12}
|
||||
!10 = !{!8, !3, i64 16}
|
||||
!11 = !{!12, !6, i64 8}
|
||||
!12 = !{!"TValue", !4, i64 0, !6, i64 8}
|
||||
!13 = !{!3, !3, i64 0}
|
@ -0,0 +1,784 @@
|
||||
; ModuleID = 'lua_for_num.c'
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
|
||||
target triple = "i686-pc-windows-gnu"
|
||||
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.TValue }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoC }
|
||||
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
|
||||
%struct.lua_Debug = type opaque
|
||||
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
|
||||
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
|
||||
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
|
||||
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
|
||||
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i32, i64, %struct.TString* }
|
||||
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
|
||||
|
||||
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
|
||||
@.str1 = private unnamed_addr constant [29 x i8] c"'for' limit must be a number\00", align 1
|
||||
@.str2 = private unnamed_addr constant [28 x i8] c"'for' step must be a number\00", align 1
|
||||
@.str3 = private unnamed_addr constant [37 x i8] c"'for' initial value must be a number\00", align 1
|
||||
@.str4 = private unnamed_addr constant [13 x i8] c"ptr diff %d\0A\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @testfunc(%struct.GCObject* %obj) #0 {
|
||||
entry:
|
||||
%obj.addr = alloca %struct.GCObject*, align 4
|
||||
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
|
||||
%0 = load %struct.GCObject*, %struct.GCObject** %obj.addr, align 4, !tbaa !1
|
||||
%tt = getelementptr inbounds %struct.GCObject, %struct.GCObject* %0, i32 0, i32 1
|
||||
%1 = load i8, i8* %tt, align 1, !tbaa !5
|
||||
%conv = zext i8 %1 to i32
|
||||
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 %conv)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @printf(i8*, ...) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test1(%struct.lua_State* %L) #0 {
|
||||
entry:
|
||||
%L.addr = alloca %struct.lua_State*, align 4
|
||||
%ci = alloca %struct.CallInfoLua*, align 4
|
||||
%cl = alloca %struct.LClosure*, align 4
|
||||
%k = alloca %struct.TValue*, align 4
|
||||
%base = alloca %struct.TValue*, align 4
|
||||
%cil = alloca %struct.CallInfoL*, align 4
|
||||
%ra = alloca %struct.TValue*, align 4
|
||||
%rb = alloca %struct.TValue*, align 4
|
||||
%rc = alloca %struct.TValue*, align 4
|
||||
%b = alloca i32, align 4
|
||||
%init = alloca %struct.TValue*, align 4
|
||||
%plimit = alloca %struct.TValue*, align 4
|
||||
%pstep = alloca %struct.TValue*, align 4
|
||||
%ilimit = alloca i64, align 8
|
||||
%stopnow = alloca i32, align 4
|
||||
%init_is_integer = alloca i32, align 4
|
||||
%pstep_is_integer = alloca i32, align 4
|
||||
%fl = alloca i32, align 4
|
||||
%initv = alloca i64, align 8
|
||||
%ninit = alloca double, align 8
|
||||
%nlimit = alloca double, align 8
|
||||
%nstep = alloca double, align 8
|
||||
%plimit_is_float = alloca i32, align 4
|
||||
%pstep_is_float = alloca i32, align 4
|
||||
%init_is_float = alloca i32, align 4
|
||||
%step = alloca i64, align 8
|
||||
%idx = alloca i64, align 8
|
||||
%limit = alloca i64, align 8
|
||||
%cleanup.dest.slot = alloca i32
|
||||
%step116 = alloca double, align 8
|
||||
%idx119 = alloca double, align 8
|
||||
%limit124 = alloca double, align 8
|
||||
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%0 = bitcast %struct.CallInfoLua** %ci to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %0) #2
|
||||
%1 = bitcast %struct.LClosure** %cl to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %1) #2
|
||||
%2 = bitcast %struct.TValue** %k to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %2) #2
|
||||
%3 = bitcast %struct.TValue** %base to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %3) #2
|
||||
%4 = bitcast %struct.CallInfoL** %cil to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %4) #2
|
||||
%5 = bitcast %struct.TValue** %ra to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %5) #2
|
||||
%6 = bitcast %struct.TValue** %rb to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %6) #2
|
||||
%7 = bitcast %struct.TValue** %rc to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %7) #2
|
||||
%8 = bitcast i32* %b to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %8) #2
|
||||
%9 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %9, i32 0, i32 6
|
||||
%10 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !7
|
||||
store %struct.CallInfoLua* %10, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%11 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %11, i32 0, i32 4
|
||||
%base2 = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 0
|
||||
%12 = load %struct.TValue*, %struct.TValue** %base2, align 4, !tbaa !13
|
||||
store %struct.TValue* %12, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%13 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%func = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %13, i32 0, i32 0
|
||||
%14 = load %struct.TValue*, %struct.TValue** %func, align 4, !tbaa !16
|
||||
%value_ = getelementptr inbounds %struct.TValue, %struct.TValue* %14, i32 0, i32 0
|
||||
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
|
||||
%15 = load %struct.GCObject*, %struct.GCObject** %gc, align 4, !tbaa !1
|
||||
%16 = bitcast %struct.GCObject* %15 to %struct.LClosure*
|
||||
store %struct.LClosure* %16, %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%17 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%p = getelementptr inbounds %struct.LClosure, %struct.LClosure* %17, i32 0, i32 5
|
||||
%18 = load %struct.Proto*, %struct.Proto** %p, align 4, !tbaa !17
|
||||
%k3 = getelementptr inbounds %struct.Proto, %struct.Proto* %18, i32 0, i32 14
|
||||
%19 = load %struct.TValue*, %struct.TValue** %k3, align 4, !tbaa !19
|
||||
store %struct.TValue* %19, %struct.TValue** %k, align 4, !tbaa !1
|
||||
%20 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr = getelementptr inbounds %struct.TValue, %struct.TValue* %20, i32 0
|
||||
store %struct.TValue* %add.ptr, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%21 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr4 = getelementptr inbounds %struct.TValue, %struct.TValue* %21, i32 0
|
||||
store %struct.TValue* %add.ptr4, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%22 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%23 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%24 = bitcast %struct.TValue* %22 to i8*
|
||||
%25 = bitcast %struct.TValue* %23 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %24, i8* %25, i32 16, i32 8, i1 false), !tbaa.struct !22
|
||||
%26 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr5 = getelementptr inbounds %struct.TValue, %struct.TValue* %26, i32 1
|
||||
store %struct.TValue* %add.ptr5, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%27 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr6 = getelementptr inbounds %struct.TValue, %struct.TValue* %27, i32 1
|
||||
store %struct.TValue* %add.ptr6, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%28 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%29 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%30 = bitcast %struct.TValue* %28 to i8*
|
||||
%31 = bitcast %struct.TValue* %29 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %30, i8* %31, i32 16, i32 8, i1 false), !tbaa.struct !22
|
||||
%32 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr7 = getelementptr inbounds %struct.TValue, %struct.TValue* %32, i32 2
|
||||
store %struct.TValue* %add.ptr7, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%33 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr8 = getelementptr inbounds %struct.TValue, %struct.TValue* %33, i32 2
|
||||
store %struct.TValue* %add.ptr8, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%34 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%35 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%36 = bitcast %struct.TValue* %34 to i8*
|
||||
%37 = bitcast %struct.TValue* %35 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %36, i8* %37, i32 16, i32 8, i1 false), !tbaa.struct !22
|
||||
%38 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr9 = getelementptr inbounds %struct.TValue, %struct.TValue* %38, i32 3
|
||||
store %struct.TValue* %add.ptr9, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%39 = load %struct.TValue*, %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr10 = getelementptr inbounds %struct.TValue, %struct.TValue* %39, i32 1
|
||||
store %struct.TValue* %add.ptr10, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%40 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%41 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%42 = bitcast %struct.TValue* %40 to i8*
|
||||
%43 = bitcast %struct.TValue* %41 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %42, i8* %43, i32 16, i32 8, i1 false), !tbaa.struct !22
|
||||
br label %label_forprep
|
||||
|
||||
label_forprep: ; preds = %entry
|
||||
%44 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr11 = getelementptr inbounds %struct.TValue, %struct.TValue* %44, i32 1
|
||||
store %struct.TValue* %add.ptr11, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%45 = bitcast %struct.TValue** %init to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %45) #2
|
||||
%46 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
store %struct.TValue* %46, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%47 = bitcast %struct.TValue** %plimit to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %47) #2
|
||||
%48 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr12 = getelementptr inbounds %struct.TValue, %struct.TValue* %48, i32 1
|
||||
store %struct.TValue* %add.ptr12, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%49 = bitcast %struct.TValue** %pstep to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %49) #2
|
||||
%50 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr13 = getelementptr inbounds %struct.TValue, %struct.TValue* %50, i32 2
|
||||
store %struct.TValue* %add.ptr13, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%51 = bitcast i64* %ilimit to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %51) #2
|
||||
%52 = bitcast i32* %stopnow to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %52) #2
|
||||
%53 = bitcast i32* %init_is_integer to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %53) #2
|
||||
%54 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%tt_ = getelementptr inbounds %struct.TValue, %struct.TValue* %54, i32 0, i32 1
|
||||
%55 = load i32, i32* %tt_, align 4, !tbaa !27
|
||||
%cmp = icmp eq i32 %55, 19
|
||||
%conv = zext i1 %cmp to i32
|
||||
store i32 %conv, i32* %init_is_integer, align 4, !tbaa !23
|
||||
%56 = bitcast i32* %pstep_is_integer to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %56) #2
|
||||
%57 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%tt_14 = getelementptr inbounds %struct.TValue, %struct.TValue* %57, i32 0, i32 1
|
||||
%58 = load i32, i32* %tt_14, align 4, !tbaa !27
|
||||
%cmp15 = icmp eq i32 %58, 19
|
||||
%conv16 = zext i1 %cmp15 to i32
|
||||
store i32 %conv16, i32* %pstep_is_integer, align 4, !tbaa !23
|
||||
%59 = bitcast i32* %fl to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %59) #2
|
||||
%60 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%61 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%value_17 = getelementptr inbounds %struct.TValue, %struct.TValue* %61, i32 0, i32 0
|
||||
%i = bitcast %union.Value* %value_17 to i64*
|
||||
%62 = load i64, i64* %i, align 8, !tbaa !24
|
||||
%call = call i32 @forlimit(%struct.TValue* %60, i64* %ilimit, i64 %62, i32* %stopnow)
|
||||
store i32 %call, i32* %fl, align 4, !tbaa !23
|
||||
%63 = load i32, i32* %init_is_integer, align 4, !tbaa !23
|
||||
%tobool = icmp ne i32 %63, 0
|
||||
br i1 %tobool, label %land.lhs.true, label %if.else
|
||||
|
||||
land.lhs.true: ; preds = %label_forprep
|
||||
%64 = load i32, i32* %pstep_is_integer, align 4, !tbaa !23
|
||||
%tobool18 = icmp ne i32 %64, 0
|
||||
br i1 %tobool18, label %land.lhs.true19, label %if.else
|
||||
|
||||
land.lhs.true19: ; preds = %land.lhs.true
|
||||
%65 = load i32, i32* %fl, align 4, !tbaa !23
|
||||
%tobool20 = icmp ne i32 %65, 0
|
||||
br i1 %tobool20, label %if.then, label %if.else
|
||||
|
||||
if.then: ; preds = %land.lhs.true19
|
||||
%66 = bitcast i64* %initv to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %66) #2
|
||||
%67 = load i32, i32* %stopnow, align 4, !tbaa !23
|
||||
%tobool21 = icmp ne i32 %67, 0
|
||||
br i1 %tobool21, label %cond.true, label %cond.false
|
||||
|
||||
cond.true: ; preds = %if.then
|
||||
br label %cond.end
|
||||
|
||||
cond.false: ; preds = %if.then
|
||||
%68 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%value_22 = getelementptr inbounds %struct.TValue, %struct.TValue* %68, i32 0, i32 0
|
||||
%i23 = bitcast %union.Value* %value_22 to i64*
|
||||
%69 = load i64, i64* %i23, align 8, !tbaa !24
|
||||
br label %cond.end
|
||||
|
||||
cond.end: ; preds = %cond.false, %cond.true
|
||||
%cond = phi i64 [ 0, %cond.true ], [ %69, %cond.false ]
|
||||
store i64 %cond, i64* %initv, align 8, !tbaa !24
|
||||
%70 = load i64, i64* %ilimit, align 8, !tbaa !24
|
||||
%71 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%value_24 = getelementptr inbounds %struct.TValue, %struct.TValue* %71, i32 0, i32 0
|
||||
%i25 = bitcast %union.Value* %value_24 to i64*
|
||||
store i64 %70, i64* %i25, align 8, !tbaa !24
|
||||
%72 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%tt_26 = getelementptr inbounds %struct.TValue, %struct.TValue* %72, i32 0, i32 1
|
||||
store i32 19, i32* %tt_26, align 4, !tbaa !27
|
||||
%73 = load i64, i64* %initv, align 8, !tbaa !24
|
||||
%74 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%value_27 = getelementptr inbounds %struct.TValue, %struct.TValue* %74, i32 0, i32 0
|
||||
%i28 = bitcast %union.Value* %value_27 to i64*
|
||||
%75 = load i64, i64* %i28, align 8, !tbaa !24
|
||||
%sub = sub nsw i64 %73, %75
|
||||
%76 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%value_29 = getelementptr inbounds %struct.TValue, %struct.TValue* %76, i32 0, i32 0
|
||||
%i30 = bitcast %union.Value* %value_29 to i64*
|
||||
store i64 %sub, i64* %i30, align 8, !tbaa !24
|
||||
%77 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%tt_31 = getelementptr inbounds %struct.TValue, %struct.TValue* %77, i32 0, i32 1
|
||||
store i32 19, i32* %tt_31, align 4, !tbaa !27
|
||||
%78 = bitcast i64* %initv to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %78) #2
|
||||
br label %if.end79
|
||||
|
||||
if.else: ; preds = %land.lhs.true19, %land.lhs.true, %label_forprep
|
||||
%79 = bitcast double* %ninit to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %79) #2
|
||||
%80 = bitcast double* %nlimit to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %80) #2
|
||||
%81 = bitcast double* %nstep to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %81) #2
|
||||
%82 = bitcast i32* %plimit_is_float to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %82) #2
|
||||
store i32 0, i32* %plimit_is_float, align 4, !tbaa !23
|
||||
%83 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%tt_32 = getelementptr inbounds %struct.TValue, %struct.TValue* %83, i32 0, i32 1
|
||||
%84 = load i32, i32* %tt_32, align 4, !tbaa !27
|
||||
%cmp33 = icmp eq i32 %84, 3
|
||||
br i1 %cmp33, label %if.then35, label %if.else37
|
||||
|
||||
if.then35: ; preds = %if.else
|
||||
store i32 1, i32* %plimit_is_float, align 4, !tbaa !23
|
||||
%85 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%value_36 = getelementptr inbounds %struct.TValue, %struct.TValue* %85, i32 0, i32 0
|
||||
%n = bitcast %union.Value* %value_36 to double*
|
||||
%86 = load double, double* %n, align 8, !tbaa !25
|
||||
store double %86, double* %nlimit, align 8, !tbaa !25
|
||||
br label %if.end
|
||||
|
||||
if.else37: ; preds = %if.else
|
||||
%87 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%call38 = call i32 @luaV_tonumber_(%struct.TValue* %87, double* %nlimit)
|
||||
store i32 %call38, i32* %plimit_is_float, align 4, !tbaa !23
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %if.else37, %if.then35
|
||||
%88 = load i32, i32* %plimit_is_float, align 4, !tbaa !23
|
||||
%tobool39 = icmp ne i32 %88, 0
|
||||
br i1 %tobool39, label %if.end42, label %if.then40
|
||||
|
||||
if.then40: ; preds = %if.end
|
||||
%89 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%call41 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %89, i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str1, i32 0, i32 0))
|
||||
br label %if.end42
|
||||
|
||||
if.end42: ; preds = %if.then40, %if.end
|
||||
%90 = load double, double* %nlimit, align 8, !tbaa !25
|
||||
%91 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%value_43 = getelementptr inbounds %struct.TValue, %struct.TValue* %91, i32 0, i32 0
|
||||
%n44 = bitcast %union.Value* %value_43 to double*
|
||||
store double %90, double* %n44, align 8, !tbaa !25
|
||||
%92 = load %struct.TValue*, %struct.TValue** %plimit, align 4, !tbaa !1
|
||||
%tt_45 = getelementptr inbounds %struct.TValue, %struct.TValue* %92, i32 0, i32 1
|
||||
store i32 3, i32* %tt_45, align 4, !tbaa !27
|
||||
%93 = bitcast i32* %pstep_is_float to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %93) #2
|
||||
store i32 0, i32* %pstep_is_float, align 4, !tbaa !23
|
||||
%94 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%tt_46 = getelementptr inbounds %struct.TValue, %struct.TValue* %94, i32 0, i32 1
|
||||
%95 = load i32, i32* %tt_46, align 4, !tbaa !27
|
||||
%cmp47 = icmp eq i32 %95, 3
|
||||
br i1 %cmp47, label %if.then49, label %if.else52
|
||||
|
||||
if.then49: ; preds = %if.end42
|
||||
store i32 1, i32* %pstep_is_float, align 4, !tbaa !23
|
||||
%96 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%value_50 = getelementptr inbounds %struct.TValue, %struct.TValue* %96, i32 0, i32 0
|
||||
%n51 = bitcast %union.Value* %value_50 to double*
|
||||
%97 = load double, double* %n51, align 8, !tbaa !25
|
||||
store double %97, double* %nstep, align 8, !tbaa !25
|
||||
br label %if.end54
|
||||
|
||||
if.else52: ; preds = %if.end42
|
||||
%98 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%call53 = call i32 @luaV_tonumber_(%struct.TValue* %98, double* %nstep)
|
||||
store i32 %call53, i32* %pstep_is_float, align 4, !tbaa !23
|
||||
br label %if.end54
|
||||
|
||||
if.end54: ; preds = %if.else52, %if.then49
|
||||
%99 = load i32, i32* %pstep_is_float, align 4, !tbaa !23
|
||||
%tobool55 = icmp ne i32 %99, 0
|
||||
br i1 %tobool55, label %if.end58, label %if.then56
|
||||
|
||||
if.then56: ; preds = %if.end54
|
||||
%100 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%call57 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %100, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str2, i32 0, i32 0))
|
||||
br label %if.end58
|
||||
|
||||
if.end58: ; preds = %if.then56, %if.end54
|
||||
%101 = load double, double* %nstep, align 8, !tbaa !25
|
||||
%102 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%value_59 = getelementptr inbounds %struct.TValue, %struct.TValue* %102, i32 0, i32 0
|
||||
%n60 = bitcast %union.Value* %value_59 to double*
|
||||
store double %101, double* %n60, align 8, !tbaa !25
|
||||
%103 = load %struct.TValue*, %struct.TValue** %pstep, align 4, !tbaa !1
|
||||
%tt_61 = getelementptr inbounds %struct.TValue, %struct.TValue* %103, i32 0, i32 1
|
||||
store i32 3, i32* %tt_61, align 4, !tbaa !27
|
||||
%104 = bitcast i32* %init_is_float to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %104) #2
|
||||
store i32 0, i32* %init_is_float, align 4, !tbaa !23
|
||||
%105 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%tt_62 = getelementptr inbounds %struct.TValue, %struct.TValue* %105, i32 0, i32 1
|
||||
%106 = load i32, i32* %tt_62, align 4, !tbaa !27
|
||||
%cmp63 = icmp eq i32 %106, 3
|
||||
br i1 %cmp63, label %if.then65, label %if.else68
|
||||
|
||||
if.then65: ; preds = %if.end58
|
||||
store i32 1, i32* %init_is_float, align 4, !tbaa !23
|
||||
%107 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%value_66 = getelementptr inbounds %struct.TValue, %struct.TValue* %107, i32 0, i32 0
|
||||
%n67 = bitcast %union.Value* %value_66 to double*
|
||||
%108 = load double, double* %n67, align 8, !tbaa !25
|
||||
store double %108, double* %ninit, align 8, !tbaa !25
|
||||
br label %if.end70
|
||||
|
||||
if.else68: ; preds = %if.end58
|
||||
%109 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%call69 = call i32 @luaV_tonumber_(%struct.TValue* %109, double* %ninit)
|
||||
store i32 %call69, i32* %init_is_float, align 4, !tbaa !23
|
||||
br label %if.end70
|
||||
|
||||
if.end70: ; preds = %if.else68, %if.then65
|
||||
%110 = load i32, i32* %init_is_float, align 4, !tbaa !23
|
||||
%tobool71 = icmp ne i32 %110, 0
|
||||
br i1 %tobool71, label %if.end74, label %if.then72
|
||||
|
||||
if.then72: ; preds = %if.end70
|
||||
%111 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%call73 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %111, i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str3, i32 0, i32 0))
|
||||
br label %if.end74
|
||||
|
||||
if.end74: ; preds = %if.then72, %if.end70
|
||||
%112 = load double, double* %ninit, align 8, !tbaa !25
|
||||
%113 = load double, double* %nstep, align 8, !tbaa !25
|
||||
%sub75 = fsub double %112, %113
|
||||
%114 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%value_76 = getelementptr inbounds %struct.TValue, %struct.TValue* %114, i32 0, i32 0
|
||||
%n77 = bitcast %union.Value* %value_76 to double*
|
||||
store double %sub75, double* %n77, align 8, !tbaa !25
|
||||
%115 = load %struct.TValue*, %struct.TValue** %init, align 4, !tbaa !1
|
||||
%tt_78 = getelementptr inbounds %struct.TValue, %struct.TValue* %115, i32 0, i32 1
|
||||
store i32 3, i32* %tt_78, align 4, !tbaa !27
|
||||
%116 = bitcast i32* %init_is_float to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %116) #2
|
||||
%117 = bitcast i32* %pstep_is_float to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %117) #2
|
||||
%118 = bitcast i32* %plimit_is_float to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %118) #2
|
||||
%119 = bitcast double* %nstep to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %119) #2
|
||||
%120 = bitcast double* %nlimit to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %120) #2
|
||||
%121 = bitcast double* %ninit to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %121) #2
|
||||
br label %if.end79
|
||||
|
||||
if.end79: ; preds = %if.end74, %cond.end
|
||||
br label %label_forloop
|
||||
|
||||
label_loopbody: ; preds = %cleanup144, %cleanup
|
||||
%122 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr80 = getelementptr inbounds %struct.TValue, %struct.TValue* %122, i32 0
|
||||
store %struct.TValue* %add.ptr80, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%123 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr81 = getelementptr inbounds %struct.TValue, %struct.TValue* %123, i32 4
|
||||
store %struct.TValue* %add.ptr81, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%124 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%125 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%126 = bitcast %struct.TValue* %124 to i8*
|
||||
%127 = bitcast %struct.TValue* %125 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %126, i8* %127, i32 16, i32 8, i1 false), !tbaa.struct !22
|
||||
br label %label_forloop
|
||||
|
||||
label_forloop: ; preds = %label_loopbody, %if.end79
|
||||
%128 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr82 = getelementptr inbounds %struct.TValue, %struct.TValue* %128, i32 1
|
||||
store %struct.TValue* %add.ptr82, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%129 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%tt_83 = getelementptr inbounds %struct.TValue, %struct.TValue* %129, i32 0, i32 1
|
||||
%130 = load i32, i32* %tt_83, align 4, !tbaa !27
|
||||
%cmp84 = icmp eq i32 %130, 19
|
||||
br i1 %cmp84, label %if.then86, label %if.else114
|
||||
|
||||
if.then86: ; preds = %label_forloop
|
||||
%131 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr87 = getelementptr inbounds %struct.TValue, %struct.TValue* %131, i32 2
|
||||
store %struct.TValue* %add.ptr87, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%132 = bitcast i64* %step to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %132) #2
|
||||
%133 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%value_88 = getelementptr inbounds %struct.TValue, %struct.TValue* %133, i32 0, i32 0
|
||||
%i89 = bitcast %union.Value* %value_88 to i64*
|
||||
%134 = load i64, i64* %i89, align 8, !tbaa !24
|
||||
store i64 %134, i64* %step, align 8, !tbaa !24
|
||||
%135 = bitcast i64* %idx to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %135) #2
|
||||
%136 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%value_90 = getelementptr inbounds %struct.TValue, %struct.TValue* %136, i32 0, i32 0
|
||||
%i91 = bitcast %union.Value* %value_90 to i64*
|
||||
%137 = load i64, i64* %i91, align 8, !tbaa !24
|
||||
%138 = load i64, i64* %step, align 8, !tbaa !24
|
||||
%add = add nsw i64 %137, %138
|
||||
store i64 %add, i64* %idx, align 8, !tbaa !24
|
||||
%139 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr92 = getelementptr inbounds %struct.TValue, %struct.TValue* %139, i32 1
|
||||
store %struct.TValue* %add.ptr92, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%140 = bitcast i64* %limit to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %140) #2
|
||||
%141 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%value_93 = getelementptr inbounds %struct.TValue, %struct.TValue* %141, i32 0, i32 0
|
||||
%i94 = bitcast %union.Value* %value_93 to i64*
|
||||
%142 = load i64, i64* %i94, align 8, !tbaa !24
|
||||
store i64 %142, i64* %limit, align 8, !tbaa !24
|
||||
%143 = load i64, i64* %step, align 8, !tbaa !24
|
||||
%cmp95 = icmp slt i64 0, %143
|
||||
br i1 %cmp95, label %cond.true97, label %cond.false100
|
||||
|
||||
cond.true97: ; preds = %if.then86
|
||||
%144 = load i64, i64* %idx, align 8, !tbaa !24
|
||||
%145 = load i64, i64* %limit, align 8, !tbaa !24
|
||||
%cmp98 = icmp sle i64 %144, %145
|
||||
br i1 %cmp98, label %if.then103, label %if.end111
|
||||
|
||||
cond.false100: ; preds = %if.then86
|
||||
%146 = load i64, i64* %limit, align 8, !tbaa !24
|
||||
%147 = load i64, i64* %idx, align 8, !tbaa !24
|
||||
%cmp101 = icmp sle i64 %146, %147
|
||||
br i1 %cmp101, label %if.then103, label %if.end111
|
||||
|
||||
if.then103: ; preds = %cond.false100, %cond.true97
|
||||
%148 = load i64, i64* %idx, align 8, !tbaa !24
|
||||
%149 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%value_104 = getelementptr inbounds %struct.TValue, %struct.TValue* %149, i32 0, i32 0
|
||||
%i105 = bitcast %union.Value* %value_104 to i64*
|
||||
store i64 %148, i64* %i105, align 8, !tbaa !24
|
||||
%150 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%tt_106 = getelementptr inbounds %struct.TValue, %struct.TValue* %150, i32 0, i32 1
|
||||
store i32 19, i32* %tt_106, align 4, !tbaa !27
|
||||
%151 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr107 = getelementptr inbounds %struct.TValue, %struct.TValue* %151, i32 3
|
||||
store %struct.TValue* %add.ptr107, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%152 = load i64, i64* %idx, align 8, !tbaa !24
|
||||
%153 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%value_108 = getelementptr inbounds %struct.TValue, %struct.TValue* %153, i32 0, i32 0
|
||||
%i109 = bitcast %union.Value* %value_108 to i64*
|
||||
store i64 %152, i64* %i109, align 8, !tbaa !24
|
||||
%154 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%tt_110 = getelementptr inbounds %struct.TValue, %struct.TValue* %154, i32 0, i32 1
|
||||
store i32 19, i32* %tt_110, align 4, !tbaa !27
|
||||
store i32 4, i32* %cleanup.dest.slot
|
||||
br label %cleanup
|
||||
|
||||
if.end111: ; preds = %cond.false100, %cond.true97
|
||||
store i32 0, i32* %cleanup.dest.slot
|
||||
br label %cleanup
|
||||
|
||||
cleanup: ; preds = %if.end111, %if.then103
|
||||
%155 = bitcast i64* %limit to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %155) #2
|
||||
%156 = bitcast i64* %idx to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %156) #2
|
||||
%157 = bitcast i64* %step to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %157) #2
|
||||
%cleanup.dest = load i32, i32* %cleanup.dest.slot
|
||||
switch i32 %cleanup.dest, label %unreachable [
|
||||
i32 0, label %cleanup.cont
|
||||
i32 4, label %label_loopbody
|
||||
]
|
||||
|
||||
cleanup.cont: ; preds = %cleanup
|
||||
br label %if.end149
|
||||
|
||||
if.else114: ; preds = %label_forloop
|
||||
%158 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr115 = getelementptr inbounds %struct.TValue, %struct.TValue* %158, i32 2
|
||||
store %struct.TValue* %add.ptr115, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%159 = bitcast double* %step116 to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %159) #2
|
||||
%160 = load %struct.TValue*, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%value_117 = getelementptr inbounds %struct.TValue, %struct.TValue* %160, i32 0, i32 0
|
||||
%n118 = bitcast %union.Value* %value_117 to double*
|
||||
%161 = load double, double* %n118, align 8, !tbaa !25
|
||||
store double %161, double* %step116, align 8, !tbaa !25
|
||||
%162 = bitcast double* %idx119 to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %162) #2
|
||||
%163 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%value_120 = getelementptr inbounds %struct.TValue, %struct.TValue* %163, i32 0, i32 0
|
||||
%n121 = bitcast %union.Value* %value_120 to double*
|
||||
%164 = load double, double* %n121, align 8, !tbaa !25
|
||||
%165 = load double, double* %step116, align 8, !tbaa !25
|
||||
%add122 = fadd double %164, %165
|
||||
store double %add122, double* %idx119, align 8, !tbaa !25
|
||||
%166 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr123 = getelementptr inbounds %struct.TValue, %struct.TValue* %166, i32 1
|
||||
store %struct.TValue* %add.ptr123, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%167 = bitcast double* %limit124 to i8*
|
||||
call void @llvm.lifetime.start(i64 8, i8* %167) #2
|
||||
%168 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%value_125 = getelementptr inbounds %struct.TValue, %struct.TValue* %168, i32 0, i32 0
|
||||
%n126 = bitcast %union.Value* %value_125 to double*
|
||||
%169 = load double, double* %n126, align 8, !tbaa !25
|
||||
store double %169, double* %limit124, align 8, !tbaa !25
|
||||
%170 = load double, double* %step116, align 8, !tbaa !25
|
||||
%cmp127 = fcmp olt double 0.000000e+00, %170
|
||||
br i1 %cmp127, label %cond.true129, label %cond.false132
|
||||
|
||||
cond.true129: ; preds = %if.else114
|
||||
%171 = load double, double* %idx119, align 8, !tbaa !25
|
||||
%172 = load double, double* %limit124, align 8, !tbaa !25
|
||||
%cmp130 = fcmp ole double %171, %172
|
||||
br i1 %cmp130, label %if.then135, label %if.end143
|
||||
|
||||
cond.false132: ; preds = %if.else114
|
||||
%173 = load double, double* %limit124, align 8, !tbaa !25
|
||||
%174 = load double, double* %idx119, align 8, !tbaa !25
|
||||
%cmp133 = fcmp ole double %173, %174
|
||||
br i1 %cmp133, label %if.then135, label %if.end143
|
||||
|
||||
if.then135: ; preds = %cond.false132, %cond.true129
|
||||
%175 = load double, double* %idx119, align 8, !tbaa !25
|
||||
%176 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%value_136 = getelementptr inbounds %struct.TValue, %struct.TValue* %176, i32 0, i32 0
|
||||
%n137 = bitcast %union.Value* %value_136 to double*
|
||||
store double %175, double* %n137, align 8, !tbaa !25
|
||||
%177 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%tt_138 = getelementptr inbounds %struct.TValue, %struct.TValue* %177, i32 0, i32 1
|
||||
store i32 3, i32* %tt_138, align 4, !tbaa !27
|
||||
%178 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%add.ptr139 = getelementptr inbounds %struct.TValue, %struct.TValue* %178, i32 3
|
||||
store %struct.TValue* %add.ptr139, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%179 = load double, double* %idx119, align 8, !tbaa !25
|
||||
%180 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%value_140 = getelementptr inbounds %struct.TValue, %struct.TValue* %180, i32 0, i32 0
|
||||
%n141 = bitcast %union.Value* %value_140 to double*
|
||||
store double %179, double* %n141, align 8, !tbaa !25
|
||||
%181 = load %struct.TValue*, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%tt_142 = getelementptr inbounds %struct.TValue, %struct.TValue* %181, i32 0, i32 1
|
||||
store i32 3, i32* %tt_142, align 4, !tbaa !27
|
||||
store i32 4, i32* %cleanup.dest.slot
|
||||
br label %cleanup144
|
||||
|
||||
if.end143: ; preds = %cond.false132, %cond.true129
|
||||
store i32 0, i32* %cleanup.dest.slot
|
||||
br label %cleanup144
|
||||
|
||||
cleanup144: ; preds = %if.end143, %if.then135
|
||||
%182 = bitcast double* %limit124 to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %182) #2
|
||||
%183 = bitcast double* %idx119 to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %183) #2
|
||||
%184 = bitcast double* %step116 to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %184) #2
|
||||
%cleanup.dest147 = load i32, i32* %cleanup.dest.slot
|
||||
switch i32 %cleanup.dest147, label %unreachable [
|
||||
i32 0, label %cleanup.cont148
|
||||
i32 4, label %label_loopbody
|
||||
]
|
||||
|
||||
cleanup.cont148: ; preds = %cleanup144
|
||||
br label %if.end149
|
||||
|
||||
if.end149: ; preds = %cleanup.cont148, %cleanup.cont
|
||||
store i32 2, i32* %b, align 4, !tbaa !23
|
||||
%185 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr150 = getelementptr inbounds %struct.TValue, %struct.TValue* %185, i32 0
|
||||
store %struct.TValue* %add.ptr150, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%186 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%187 = load i32, i32* %b, align 4, !tbaa !23
|
||||
%add.ptr151 = getelementptr inbounds %struct.TValue, %struct.TValue* %186, i32 %187
|
||||
%add.ptr152 = getelementptr inbounds %struct.TValue, %struct.TValue* %add.ptr151, i32 -1
|
||||
%188 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top = getelementptr inbounds %struct.lua_State, %struct.lua_State* %188, i32 0, i32 4
|
||||
store %struct.TValue* %add.ptr152, %struct.TValue** %top, align 4, !tbaa !29
|
||||
%189 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%190 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top153 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %190, i32 0, i32 4
|
||||
%191 = load %struct.TValue*, %struct.TValue** %top153, align 4, !tbaa !29
|
||||
%sub.ptr.lhs.cast = ptrtoint %struct.TValue* %189 to i32
|
||||
%sub.ptr.rhs.cast = ptrtoint %struct.TValue* %191 to i32
|
||||
%sub.ptr.sub = sub i32 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
|
||||
%sub.ptr.div = sdiv exact i32 %sub.ptr.sub, 16
|
||||
%call154 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str4, i32 0, i32 0), i32 %sub.ptr.div)
|
||||
%192 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%p155 = getelementptr inbounds %struct.LClosure, %struct.LClosure* %192, i32 0, i32 5
|
||||
%193 = load %struct.Proto*, %struct.Proto** %p155, align 4, !tbaa !17
|
||||
%sizep = getelementptr inbounds %struct.Proto, %struct.Proto* %193, i32 0, i32 10
|
||||
%194 = load i32, i32* %sizep, align 4, !tbaa !30
|
||||
%cmp156 = icmp sgt i32 %194, 0
|
||||
br i1 %cmp156, label %if.then158, label %if.end160
|
||||
|
||||
if.then158: ; preds = %if.end149
|
||||
%195 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%196 = load %struct.TValue*, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%call159 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %195, %struct.TValue* %196)
|
||||
br label %if.end160
|
||||
|
||||
if.end160: ; preds = %if.then158, %if.end149
|
||||
%197 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%198 = load %struct.TValue*, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%call161 = call i32 @luaD_poscall(%struct.lua_State* %197, %struct.TValue* %198)
|
||||
store i32 %call161, i32* %b, align 4, !tbaa !23
|
||||
%199 = load i32, i32* %b, align 4, !tbaa !23
|
||||
%tobool162 = icmp ne i32 %199, 0
|
||||
br i1 %tobool162, label %if.then163, label %if.end166
|
||||
|
||||
if.then163: ; preds = %if.end160
|
||||
%200 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%top164 = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %200, i32 0, i32 1
|
||||
%201 = load %struct.TValue*, %struct.TValue** %top164, align 4, !tbaa !31
|
||||
%202 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top165 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %202, i32 0, i32 4
|
||||
store %struct.TValue* %201, %struct.TValue** %top165, align 4, !tbaa !29
|
||||
br label %if.end166
|
||||
|
||||
if.end166: ; preds = %if.then163, %if.end160
|
||||
store i32 1, i32* %cleanup.dest.slot
|
||||
%203 = bitcast i32* %fl to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %203) #2
|
||||
%204 = bitcast i32* %pstep_is_integer to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %204) #2
|
||||
%205 = bitcast i32* %init_is_integer to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %205) #2
|
||||
%206 = bitcast i32* %stopnow to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %206) #2
|
||||
%207 = bitcast i64* %ilimit to i8*
|
||||
call void @llvm.lifetime.end(i64 8, i8* %207) #2
|
||||
%208 = bitcast %struct.TValue** %pstep to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %208) #2
|
||||
%209 = bitcast %struct.TValue** %plimit to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %209) #2
|
||||
%210 = bitcast %struct.TValue** %init to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %210) #2
|
||||
%211 = bitcast i32* %b to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %211) #2
|
||||
%212 = bitcast %struct.TValue** %rc to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %212) #2
|
||||
%213 = bitcast %struct.TValue** %rb to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %213) #2
|
||||
%214 = bitcast %struct.TValue** %ra to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %214) #2
|
||||
%215 = bitcast %struct.CallInfoL** %cil to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %215) #2
|
||||
%216 = bitcast %struct.TValue** %base to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %216) #2
|
||||
%217 = bitcast %struct.TValue** %k to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %217) #2
|
||||
%218 = bitcast %struct.LClosure** %cl to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %218) #2
|
||||
%219 = bitcast %struct.CallInfoLua** %ci to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %219) #2
|
||||
ret void
|
||||
|
||||
unreachable: ; preds = %cleanup144, %cleanup
|
||||
unreachable
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.lifetime.start(i64, i8* nocapture) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #2
|
||||
|
||||
declare i32 @forlimit(%struct.TValue*, i64*, i64, i32*) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.lifetime.end(i64, i8* nocapture) #2
|
||||
|
||||
declare i32 @luaV_tonumber_(%struct.TValue*, double*) #1
|
||||
|
||||
declare i32 @luaG_runerror(...) #1
|
||||
|
||||
declare i32 @luaF_close(...) #1
|
||||
|
||||
declare i32 @luaD_poscall(%struct.lua_State*, %struct.TValue*) #1
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 3.7.0 (trunk)"}
|
||||
!1 = !{!2, !2, i64 0}
|
||||
!2 = !{!"any pointer", !3, i64 0}
|
||||
!3 = !{!"omnipotent char", !4, i64 0}
|
||||
!4 = !{!"Simple C/C++ TBAA"}
|
||||
!5 = !{!6, !3, i64 4}
|
||||
!6 = !{!"GCObject", !2, i64 0, !3, i64 4, !3, i64 5}
|
||||
!7 = !{!8, !2, i64 16}
|
||||
!8 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !9, i64 48, !2, i64 104, !10, i64 112, !12, i64 120, !12, i64 124, !12, i64 128, !11, i64 132, !11, i64 134, !3, i64 136, !3, i64 137}
|
||||
!9 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !10, i64 40, !11, i64 48, !3, i64 50, !3, i64 51}
|
||||
!10 = !{!"long long", !3, i64 0}
|
||||
!11 = !{!"short", !3, i64 0}
|
||||
!12 = !{!"int", !3, i64 0}
|
||||
!13 = !{!14, !2, i64 16}
|
||||
!14 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !15, i64 16, !10, i64 32, !11, i64 40, !3, i64 42, !3, i64 43}
|
||||
!15 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !10, i64 8}
|
||||
!16 = !{!14, !2, i64 0}
|
||||
!17 = !{!18, !2, i64 12}
|
||||
!18 = !{!"LClosure", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !3, i64 16}
|
||||
!19 = !{!20, !2, i64 44}
|
||||
!20 = !{!"Proto", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !3, i64 8, !12, i64 12, !12, i64 16, !12, i64 20, !12, i64 24, !12, i64 28, !12, i64 32, !12, i64 36, !12, i64 40, !2, i64 44, !2, i64 48, !2, i64 52, !2, i64 56, !2, i64 60, !2, i64 64, !2, i64 68, !2, i64 72, !2, i64 76, !21, i64 80}
|
||||
!21 = !{!"RaviJITProto", !3, i64 0, !2, i64 4, !2, i64 8}
|
||||
!22 = !{i64 0, i64 4, !1, i64 0, i64 4, !1, i64 0, i64 4, !23, i64 0, i64 4, !1, i64 0, i64 8, !24, i64 0, i64 8, !25, i64 8, i64 4, !23}
|
||||
!23 = !{!12, !12, i64 0}
|
||||
!24 = !{!10, !10, i64 0}
|
||||
!25 = !{!26, !26, i64 0}
|
||||
!26 = !{!"double", !3, i64 0}
|
||||
!27 = !{!28, !12, i64 8}
|
||||
!28 = !{!"TValue", !3, i64 0, !12, i64 8}
|
||||
!29 = !{!8, !2, i64 8}
|
||||
!30 = !{!20, !12, i64 28}
|
||||
!31 = !{!14, !2, i64 4}
|
@ -0,0 +1,406 @@
|
||||
; ModuleID = 'lua_if_else.c'
|
||||
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
|
||||
target triple = "i686-pc-windows-gnu"
|
||||
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.TValue }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoC }
|
||||
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
|
||||
%struct.lua_Debug = type opaque
|
||||
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
|
||||
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
|
||||
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
|
||||
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
|
||||
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i32, i64, %struct.TString* }
|
||||
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
|
||||
|
||||
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @testfunc(%struct.GCObject* %obj) #0 {
|
||||
entry:
|
||||
%obj.addr = alloca %struct.GCObject*, align 4
|
||||
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
|
||||
%0 = load %struct.GCObject** %obj.addr, align 4, !tbaa !1
|
||||
%tt = getelementptr inbounds %struct.GCObject* %0, i32 0, i32 1
|
||||
%1 = load i8* %tt, align 1, !tbaa !5
|
||||
%conv = zext i8 %1 to i32
|
||||
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @printf(i8*, ...) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test1(%struct.lua_State* %L) #0 {
|
||||
entry:
|
||||
%L.addr = alloca %struct.lua_State*, align 4
|
||||
%ci = alloca %struct.CallInfoLua*, align 4
|
||||
%cl = alloca %struct.LClosure*, align 4
|
||||
%k = alloca %struct.TValue*, align 4
|
||||
%base = alloca %struct.TValue*, align 4
|
||||
%cil = alloca %struct.CallInfoL*, align 4
|
||||
%ra2 = alloca %struct.TValue*, align 4
|
||||
%rb2 = alloca %struct.TValue*, align 4
|
||||
%ra3 = alloca %struct.TValue*, align 4
|
||||
%b = alloca i32, align 4
|
||||
%ra = alloca %struct.TValue*, align 4
|
||||
%rb = alloca %struct.TValue*, align 4
|
||||
%rc = alloca %struct.TValue*, align 4
|
||||
%eq = alloca i32, align 4
|
||||
%a = alloca i32, align 4
|
||||
%a39 = alloca i32, align 4
|
||||
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%0 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%ci1 = getelementptr inbounds %struct.lua_State* %0, i32 0, i32 6
|
||||
%1 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !7
|
||||
store %struct.CallInfoLua* %1, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%2 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l = getelementptr inbounds %struct.CallInfoLua* %2, i32 0, i32 4
|
||||
%base2 = getelementptr inbounds %struct.CallInfoL* %l, i32 0, i32 0
|
||||
%3 = load %struct.TValue** %base2, align 4, !tbaa !13
|
||||
store %struct.TValue* %3, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%4 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%func = getelementptr inbounds %struct.CallInfoLua* %4, i32 0, i32 0
|
||||
%5 = load %struct.TValue** %func, align 4, !tbaa !16
|
||||
%value_ = getelementptr inbounds %struct.TValue* %5, i32 0, i32 0
|
||||
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
|
||||
%6 = load %struct.GCObject** %gc, align 4, !tbaa !1
|
||||
%7 = bitcast %struct.GCObject* %6 to %struct.LClosure*
|
||||
store %struct.LClosure* %7, %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%8 = load %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%p = getelementptr inbounds %struct.LClosure* %8, i32 0, i32 5
|
||||
%9 = load %struct.Proto** %p, align 4, !tbaa !17
|
||||
%k3 = getelementptr inbounds %struct.Proto* %9, i32 0, i32 14
|
||||
%10 = load %struct.TValue** %k3, align 4, !tbaa !19
|
||||
store %struct.TValue* %10, %struct.TValue** %k, align 4, !tbaa !1
|
||||
%11 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr = getelementptr inbounds %struct.TValue* %11, i32 0
|
||||
store %struct.TValue* %add.ptr, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%12 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr4 = getelementptr inbounds %struct.TValue* %12, i32 0
|
||||
store %struct.TValue* %add.ptr4, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%13 = load %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr5 = getelementptr inbounds %struct.TValue* %13, i32 0
|
||||
store %struct.TValue* %add.ptr5, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%14 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%15 = load %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%16 = load %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%call = call i32 bitcast (i32 (...)* @luaV_equalobj to i32 (%struct.lua_State*, %struct.TValue*, %struct.TValue*)*)(%struct.lua_State* %14, %struct.TValue* %15, %struct.TValue* %16)
|
||||
store i32 %call, i32* %eq, align 4, !tbaa !22
|
||||
%17 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l6 = getelementptr inbounds %struct.CallInfoLua* %17, i32 0, i32 4
|
||||
%base7 = getelementptr inbounds %struct.CallInfoL* %l6, i32 0, i32 0
|
||||
%18 = load %struct.TValue** %base7, align 4, !tbaa !13
|
||||
store %struct.TValue* %18, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%19 = load i32* %eq, align 4, !tbaa !22
|
||||
%cmp = icmp eq i32 %19, 0
|
||||
br i1 %cmp, label %if.then, label %if.end15
|
||||
|
||||
if.then: ; preds = %entry
|
||||
store i32 0, i32* %a, align 4, !tbaa !22
|
||||
%20 = load i32* %a, align 4, !tbaa !22
|
||||
%cmp8 = icmp sgt i32 %20, 0
|
||||
br i1 %cmp8, label %if.then9, label %if.end
|
||||
|
||||
if.then9: ; preds = %if.then
|
||||
%21 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%22 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l10 = getelementptr inbounds %struct.CallInfoLua* %22, i32 0, i32 4
|
||||
%base11 = getelementptr inbounds %struct.CallInfoL* %l10, i32 0, i32 0
|
||||
%23 = load %struct.TValue** %base11, align 4, !tbaa !13
|
||||
%24 = load i32* %a, align 4, !tbaa !22
|
||||
%add.ptr12 = getelementptr inbounds %struct.TValue* %23, i32 %24
|
||||
%add.ptr13 = getelementptr inbounds %struct.TValue* %add.ptr12, i32 -1
|
||||
%call14 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %21, %struct.TValue* %add.ptr13)
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %if.then9, %if.then
|
||||
br label %label6
|
||||
|
||||
if.end15: ; preds = %entry
|
||||
br label %label3
|
||||
|
||||
label3: ; preds = %if.end15
|
||||
%25 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr16 = getelementptr inbounds %struct.TValue* %25, i32 1
|
||||
store %struct.TValue* %add.ptr16, %struct.TValue** %ra2, align 4, !tbaa !1
|
||||
%26 = load %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr17 = getelementptr inbounds %struct.TValue* %26, i32 1
|
||||
store %struct.TValue* %add.ptr17, %struct.TValue** %rb2, align 4, !tbaa !1
|
||||
%27 = load %struct.TValue** %ra2, align 4, !tbaa !1
|
||||
%28 = load %struct.TValue** %rb2, align 4, !tbaa !1
|
||||
%29 = bitcast %struct.TValue* %27 to i8*
|
||||
%30 = bitcast %struct.TValue* %28 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %29, i8* %30, i32 16, i32 8, i1 false), !tbaa.struct !23
|
||||
store i32 2, i32* %b, align 4, !tbaa !22
|
||||
%31 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr18 = getelementptr inbounds %struct.TValue* %31, i32 1
|
||||
store %struct.TValue* %add.ptr18, %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%32 = load %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%33 = load i32* %b, align 4, !tbaa !22
|
||||
%add.ptr19 = getelementptr inbounds %struct.TValue* %32, i32 %33
|
||||
%add.ptr20 = getelementptr inbounds %struct.TValue* %add.ptr19, i32 -1
|
||||
%34 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top = getelementptr inbounds %struct.lua_State* %34, i32 0, i32 4
|
||||
store %struct.TValue* %add.ptr20, %struct.TValue** %top, align 4, !tbaa !27
|
||||
%35 = load %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%p21 = getelementptr inbounds %struct.LClosure* %35, i32 0, i32 5
|
||||
%36 = load %struct.Proto** %p21, align 4, !tbaa !17
|
||||
%sizep = getelementptr inbounds %struct.Proto* %36, i32 0, i32 10
|
||||
%37 = load i32* %sizep, align 4, !tbaa !28
|
||||
%cmp22 = icmp sgt i32 %37, 0
|
||||
br i1 %cmp22, label %if.then23, label %if.end25
|
||||
|
||||
if.then23: ; preds = %label3
|
||||
%38 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%39 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%call24 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %38, %struct.TValue* %39)
|
||||
br label %if.end25
|
||||
|
||||
if.end25: ; preds = %if.then23, %label3
|
||||
%40 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%41 = load %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%call26 = call i32 @luaD_poscall(%struct.lua_State* %40, %struct.TValue* %41)
|
||||
store i32 %call26, i32* %b, align 4, !tbaa !22
|
||||
%42 = load i32* %b, align 4, !tbaa !22
|
||||
%tobool = icmp ne i32 %42, 0
|
||||
br i1 %tobool, label %if.then27, label %if.end30
|
||||
|
||||
if.then27: ; preds = %if.end25
|
||||
%43 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%top28 = getelementptr inbounds %struct.CallInfoLua* %43, i32 0, i32 1
|
||||
%44 = load %struct.TValue** %top28, align 4, !tbaa !29
|
||||
%45 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top29 = getelementptr inbounds %struct.lua_State* %45, i32 0, i32 4
|
||||
store %struct.TValue* %44, %struct.TValue** %top29, align 4, !tbaa !27
|
||||
br label %if.end30
|
||||
|
||||
if.end30: ; preds = %if.then27, %if.end25
|
||||
br label %return
|
||||
|
||||
label6: ; preds = %if.end
|
||||
%46 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr31 = getelementptr inbounds %struct.TValue* %46, i32 0
|
||||
store %struct.TValue* %add.ptr31, %struct.TValue** %ra, align 4, !tbaa !1
|
||||
%47 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr32 = getelementptr inbounds %struct.TValue* %47, i32 0
|
||||
store %struct.TValue* %add.ptr32, %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%48 = load %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr33 = getelementptr inbounds %struct.TValue* %48, i32 2
|
||||
store %struct.TValue* %add.ptr33, %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%49 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%50 = load %struct.TValue** %rb, align 4, !tbaa !1
|
||||
%51 = load %struct.TValue** %rc, align 4, !tbaa !1
|
||||
%call34 = call i32 bitcast (i32 (...)* @luaV_equalobj to i32 (%struct.lua_State*, %struct.TValue*, %struct.TValue*)*)(%struct.lua_State* %49, %struct.TValue* %50, %struct.TValue* %51)
|
||||
store i32 %call34, i32* %eq, align 4, !tbaa !22
|
||||
%52 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l35 = getelementptr inbounds %struct.CallInfoLua* %52, i32 0, i32 4
|
||||
%base36 = getelementptr inbounds %struct.CallInfoL* %l35, i32 0, i32 0
|
||||
%53 = load %struct.TValue** %base36, align 4, !tbaa !13
|
||||
store %struct.TValue* %53, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%54 = load i32* %eq, align 4, !tbaa !22
|
||||
%cmp37 = icmp eq i32 %54, 0
|
||||
br i1 %cmp37, label %if.then38, label %if.end48
|
||||
|
||||
if.then38: ; preds = %label6
|
||||
store i32 0, i32* %a39, align 4, !tbaa !22
|
||||
%55 = load i32* %a39, align 4, !tbaa !22
|
||||
%cmp40 = icmp sgt i32 %55, 0
|
||||
br i1 %cmp40, label %if.then41, label %if.end47
|
||||
|
||||
if.then41: ; preds = %if.then38
|
||||
%56 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%57 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l42 = getelementptr inbounds %struct.CallInfoLua* %57, i32 0, i32 4
|
||||
%base43 = getelementptr inbounds %struct.CallInfoL* %l42, i32 0, i32 0
|
||||
%58 = load %struct.TValue** %base43, align 4, !tbaa !13
|
||||
%59 = load i32* %a39, align 4, !tbaa !22
|
||||
%add.ptr44 = getelementptr inbounds %struct.TValue* %58, i32 %59
|
||||
%add.ptr45 = getelementptr inbounds %struct.TValue* %add.ptr44, i32 -1
|
||||
%call46 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %56, %struct.TValue* %add.ptr45)
|
||||
br label %if.end47
|
||||
|
||||
if.end47: ; preds = %if.then41, %if.then38
|
||||
br label %label11
|
||||
|
||||
if.end48: ; preds = %label6
|
||||
br label %label8
|
||||
|
||||
label8: ; preds = %if.end48
|
||||
%60 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr49 = getelementptr inbounds %struct.TValue* %60, i32 1
|
||||
store %struct.TValue* %add.ptr49, %struct.TValue** %ra2, align 4, !tbaa !1
|
||||
%61 = load %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr50 = getelementptr inbounds %struct.TValue* %61, i32 3
|
||||
store %struct.TValue* %add.ptr50, %struct.TValue** %rb2, align 4, !tbaa !1
|
||||
%62 = load %struct.TValue** %ra2, align 4, !tbaa !1
|
||||
%63 = load %struct.TValue** %rb2, align 4, !tbaa !1
|
||||
%64 = bitcast %struct.TValue* %62 to i8*
|
||||
%65 = bitcast %struct.TValue* %63 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %64, i8* %65, i32 16, i32 8, i1 false), !tbaa.struct !23
|
||||
store i32 2, i32* %b, align 4, !tbaa !22
|
||||
%66 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr51 = getelementptr inbounds %struct.TValue* %66, i32 1
|
||||
store %struct.TValue* %add.ptr51, %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%67 = load %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%68 = load i32* %b, align 4, !tbaa !22
|
||||
%add.ptr52 = getelementptr inbounds %struct.TValue* %67, i32 %68
|
||||
%add.ptr53 = getelementptr inbounds %struct.TValue* %add.ptr52, i32 -1
|
||||
%69 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top54 = getelementptr inbounds %struct.lua_State* %69, i32 0, i32 4
|
||||
store %struct.TValue* %add.ptr53, %struct.TValue** %top54, align 4, !tbaa !27
|
||||
%70 = load %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%p55 = getelementptr inbounds %struct.LClosure* %70, i32 0, i32 5
|
||||
%71 = load %struct.Proto** %p55, align 4, !tbaa !17
|
||||
%sizep56 = getelementptr inbounds %struct.Proto* %71, i32 0, i32 10
|
||||
%72 = load i32* %sizep56, align 4, !tbaa !28
|
||||
%cmp57 = icmp sgt i32 %72, 0
|
||||
br i1 %cmp57, label %if.then58, label %if.end60
|
||||
|
||||
if.then58: ; preds = %label8
|
||||
%73 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%74 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%call59 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %73, %struct.TValue* %74)
|
||||
br label %if.end60
|
||||
|
||||
if.end60: ; preds = %if.then58, %label8
|
||||
%75 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%76 = load %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%call61 = call i32 @luaD_poscall(%struct.lua_State* %75, %struct.TValue* %76)
|
||||
store i32 %call61, i32* %b, align 4, !tbaa !22
|
||||
%77 = load i32* %b, align 4, !tbaa !22
|
||||
%tobool62 = icmp ne i32 %77, 0
|
||||
br i1 %tobool62, label %if.then63, label %if.end66
|
||||
|
||||
if.then63: ; preds = %if.end60
|
||||
%78 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%top64 = getelementptr inbounds %struct.CallInfoLua* %78, i32 0, i32 1
|
||||
%79 = load %struct.TValue** %top64, align 4, !tbaa !29
|
||||
%80 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top65 = getelementptr inbounds %struct.lua_State* %80, i32 0, i32 4
|
||||
store %struct.TValue* %79, %struct.TValue** %top65, align 4, !tbaa !27
|
||||
br label %if.end66
|
||||
|
||||
if.end66: ; preds = %if.then63, %if.end60
|
||||
br label %return
|
||||
|
||||
label11: ; preds = %if.end47
|
||||
%81 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr67 = getelementptr inbounds %struct.TValue* %81, i32 1
|
||||
store %struct.TValue* %add.ptr67, %struct.TValue** %ra2, align 4, !tbaa !1
|
||||
%82 = load %struct.TValue** %k, align 4, !tbaa !1
|
||||
%add.ptr68 = getelementptr inbounds %struct.TValue* %82, i32 4
|
||||
store %struct.TValue* %add.ptr68, %struct.TValue** %rb2, align 4, !tbaa !1
|
||||
%83 = load %struct.TValue** %ra2, align 4, !tbaa !1
|
||||
%84 = load %struct.TValue** %rb2, align 4, !tbaa !1
|
||||
%85 = bitcast %struct.TValue* %83 to i8*
|
||||
%86 = bitcast %struct.TValue* %84 to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %85, i8* %86, i32 16, i32 8, i1 false), !tbaa.struct !23
|
||||
store i32 2, i32* %b, align 4, !tbaa !22
|
||||
%87 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%add.ptr69 = getelementptr inbounds %struct.TValue* %87, i32 1
|
||||
store %struct.TValue* %add.ptr69, %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%88 = load %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%89 = load i32* %b, align 4, !tbaa !22
|
||||
%add.ptr70 = getelementptr inbounds %struct.TValue* %88, i32 %89
|
||||
%add.ptr71 = getelementptr inbounds %struct.TValue* %add.ptr70, i32 -1
|
||||
%90 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top72 = getelementptr inbounds %struct.lua_State* %90, i32 0, i32 4
|
||||
store %struct.TValue* %add.ptr71, %struct.TValue** %top72, align 4, !tbaa !27
|
||||
%91 = load %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%p73 = getelementptr inbounds %struct.LClosure* %91, i32 0, i32 5
|
||||
%92 = load %struct.Proto** %p73, align 4, !tbaa !17
|
||||
%sizep74 = getelementptr inbounds %struct.Proto* %92, i32 0, i32 10
|
||||
%93 = load i32* %sizep74, align 4, !tbaa !28
|
||||
%cmp75 = icmp sgt i32 %93, 0
|
||||
br i1 %cmp75, label %if.then76, label %if.end78
|
||||
|
||||
if.then76: ; preds = %label11
|
||||
%94 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%95 = load %struct.TValue** %base, align 4, !tbaa !1
|
||||
%call77 = call i32 bitcast (i32 (...)* @luaF_close to i32 (%struct.lua_State*, %struct.TValue*)*)(%struct.lua_State* %94, %struct.TValue* %95)
|
||||
br label %if.end78
|
||||
|
||||
if.end78: ; preds = %if.then76, %label11
|
||||
%96 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%97 = load %struct.TValue** %ra3, align 4, !tbaa !1
|
||||
%call79 = call i32 @luaD_poscall(%struct.lua_State* %96, %struct.TValue* %97)
|
||||
store i32 %call79, i32* %b, align 4, !tbaa !22
|
||||
%98 = load i32* %b, align 4, !tbaa !22
|
||||
%tobool80 = icmp ne i32 %98, 0
|
||||
br i1 %tobool80, label %if.then81, label %if.end84
|
||||
|
||||
if.then81: ; preds = %if.end78
|
||||
%99 = load %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%top82 = getelementptr inbounds %struct.CallInfoLua* %99, i32 0, i32 1
|
||||
%100 = load %struct.TValue** %top82, align 4, !tbaa !29
|
||||
%101 = load %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%top83 = getelementptr inbounds %struct.lua_State* %101, i32 0, i32 4
|
||||
store %struct.TValue* %100, %struct.TValue** %top83, align 4, !tbaa !27
|
||||
br label %if.end84
|
||||
|
||||
if.end84: ; preds = %if.then81, %if.end78
|
||||
br label %return
|
||||
|
||||
label_return: ; No predecessors!
|
||||
br label %return
|
||||
|
||||
return: ; preds = %label_return, %if.end84, %if.end66, %if.end30
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @luaV_equalobj(...) #1
|
||||
|
||||
declare i32 @luaF_close(...) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #2
|
||||
|
||||
declare i32 @luaD_poscall(%struct.lua_State*, %struct.TValue*) #1
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
|
||||
!1 = metadata !{metadata !2, metadata !2, i64 0}
|
||||
!2 = metadata !{metadata !"any pointer", metadata !3, i64 0}
|
||||
!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0}
|
||||
!4 = metadata !{metadata !"Simple C/C++ TBAA"}
|
||||
!5 = metadata !{metadata !6, metadata !3, i64 4}
|
||||
!6 = metadata !{metadata !"GCObject", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5}
|
||||
!7 = metadata !{metadata !8, metadata !2, i64 16}
|
||||
!8 = metadata !{metadata !"lua_State", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !2, i64 8, metadata !2, i64 12, metadata !2, i64 16, metadata !2, i64 20, metadata !2, i64 24, metadata !2, i64 28, metadata !2, i64 32, metadata !2, i64 36, metadata !2, i64 40, metadata !2, i64 44, metadata !9, i64 48, metadata !2, i64 104, metadata !10, i64 112, metadata !12, i64 120, metadata !12, i64 124, metadata !12, i64 128, metadata !11, i64 132, metadata !11, i64 134, metadata !3, i64 136, metadata !3, i64 137}
|
||||
!9 = metadata !{metadata !"CallInfo", metadata !2, i64 0, metadata !2, i64 4, metadata !2, i64 8, metadata !2, i64 12, metadata !3, i64 16, metadata !10, i64 40, metadata !11, i64 48, metadata !3, i64 50, metadata !3, i64 51}
|
||||
!10 = metadata !{metadata !"long long", metadata !3, i64 0}
|
||||
!11 = metadata !{metadata !"short", metadata !3, i64 0}
|
||||
!12 = metadata !{metadata !"int", metadata !3, i64 0}
|
||||
!13 = metadata !{metadata !14, metadata !2, i64 16}
|
||||
!14 = metadata !{metadata !"CallInfoLua", metadata !2, i64 0, metadata !2, i64 4, metadata !2, i64 8, metadata !2, i64 12, metadata !15, i64 16, metadata !10, i64 32, metadata !11, i64 40, metadata !3, i64 42, metadata !3, i64 43}
|
||||
!15 = metadata !{metadata !"CallInfoL", metadata !2, i64 0, metadata !2, i64 4, metadata !10, i64 8}
|
||||
!16 = metadata !{metadata !14, metadata !2, i64 0}
|
||||
!17 = metadata !{metadata !18, metadata !2, i64 12}
|
||||
!18 = metadata !{metadata !"LClosure", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !2, i64 8, metadata !2, i64 12, metadata !3, i64 16}
|
||||
!19 = metadata !{metadata !20, metadata !2, i64 44}
|
||||
!20 = metadata !{metadata !"Proto", metadata !2, i64 0, metadata !3, i64 4, metadata !3, i64 5, metadata !3, i64 6, metadata !3, i64 7, metadata !3, i64 8, metadata !12, i64 12, metadata !12, i64 16, metadata !12, i64 20, metadata !12, i64 24, metadata !12, i64 28, metadata !12, i64 32, metadata !12, i64 36, metadata !12, i64 40, metadata !2, i64 44, metadata !2, i64 48, metadata !2, i64 52, metadata !2, i64 56, metadata !2, i64 60, metadata !2, i64 64, metadata !2, i64 68, metadata !2, i64 72, metadata !2, i64 76, metadata !21, i64 80}
|
||||
!21 = metadata !{metadata !"RaviJITProto", metadata !3, i64 0, metadata !2, i64 4, metadata !2, i64 8}
|
||||
!22 = metadata !{metadata !12, metadata !12, i64 0}
|
||||
!23 = metadata !{i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !1, i64 0, i64 4, metadata !22, i64 0, i64 4, metadata !1, i64 0, i64 8, metadata !24, i64 0, i64 8, metadata !25, i64 8, i64 4, metadata !22}
|
||||
!24 = metadata !{metadata !10, metadata !10, i64 0}
|
||||
!25 = metadata !{metadata !26, metadata !26, i64 0}
|
||||
!26 = metadata !{metadata !"double", metadata !3, i64 0}
|
||||
!27 = metadata !{metadata !8, metadata !2, i64 8}
|
||||
!28 = metadata !{metadata !20, metadata !12, i64 28}
|
||||
!29 = metadata !{metadata !14, metadata !2, i64 4}
|
@ -0,0 +1,79 @@
|
||||
; ModuleID = 'lua_op_call.c'
|
||||
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
|
||||
target triple = "i686-pc-windows-gnu"
|
||||
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.TValue }
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoC }
|
||||
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
|
||||
%struct.lua_Debug = type opaque
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @luaV_op_call(%struct.lua_State* %L, %struct.CallInfo* nocapture readonly %ci, %struct.TValue* %ra, i32 %b, i32 %c) #0 {
|
||||
entry:
|
||||
%sub = add nsw i32 %c, -1
|
||||
%cmp = icmp eq i32 %b, 0
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%add.ptr = getelementptr inbounds %struct.TValue* %ra, i32 %b
|
||||
%top = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 4
|
||||
store %struct.TValue* %add.ptr, %struct.TValue** %top, align 4, !tbaa !1
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %entry, %if.then
|
||||
%call = tail call i32 @luaD_precall(%struct.lua_State* %L, %struct.TValue* %ra, i32 %sub, i32 1) #2
|
||||
%tobool = icmp eq i32 %call, 0
|
||||
br i1 %tobool, label %if.else, label %if.then1
|
||||
|
||||
if.then1: ; preds = %if.end
|
||||
%cmp2 = icmp eq i32 %call, 1
|
||||
%cmp3 = icmp sgt i32 %c, 0
|
||||
%or.cond = and i1 %cmp3, %cmp2
|
||||
br i1 %or.cond, label %if.then4, label %if.end8
|
||||
|
||||
if.then4: ; preds = %if.then1
|
||||
%top5 = getelementptr inbounds %struct.CallInfo* %ci, i32 0, i32 1
|
||||
%0 = load %struct.TValue** %top5, align 4, !tbaa !10
|
||||
%top6 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 4
|
||||
store %struct.TValue* %0, %struct.TValue** %top6, align 4, !tbaa !1
|
||||
br label %if.end8
|
||||
|
||||
if.else: ; preds = %if.end
|
||||
tail call void @luaV_execute(%struct.lua_State* %L) #2
|
||||
br label %if.end8
|
||||
|
||||
if.end8: ; preds = %if.then1, %if.then4, %if.else
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @luaD_precall(%struct.lua_State*, %struct.TValue*, i32, i32) #1
|
||||
|
||||
declare void @luaV_execute(%struct.lua_State*) #1
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
|
||||
!1 = metadata !{metadata !2, metadata !3, i64 8}
|
||||
!2 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !6, i64 48, metadata !3, i64 104, metadata !7, i64 112, metadata !9, i64 120, metadata !9, i64 124, metadata !9, i64 128, metadata !8, i64 132, metadata !8, i64 134, metadata !4, i64 136, metadata !4, i64 137}
|
||||
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
|
||||
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
|
||||
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
|
||||
!6 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !7, i64 40, metadata !8, i64 48, metadata !4, i64 50, metadata !4, i64 51}
|
||||
!7 = metadata !{metadata !"long long", metadata !4, i64 0}
|
||||
!8 = metadata !{metadata !"short", metadata !4, i64 0}
|
||||
!9 = metadata !{metadata !"int", metadata !4, i64 0}
|
||||
!10 = metadata !{metadata !6, metadata !3, i64 4}
|
@ -0,0 +1,142 @@
|
||||
; ModuleID = 'lua_op_forloop.c'
|
||||
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
|
||||
target triple = "i686-pc-windows-gnu"
|
||||
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.TValue }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoC }
|
||||
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
|
||||
%struct.lua_Debug = type opaque
|
||||
|
||||
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
|
||||
@.str1 = private unnamed_addr constant [6 x i8] c"dummy\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @testfunc(%struct.GCObject* nocapture readonly %obj) #0 {
|
||||
entry:
|
||||
%tt = getelementptr inbounds %struct.GCObject* %obj, i32 0, i32 1
|
||||
%0 = load i8* %tt, align 1, !tbaa !1
|
||||
%conv = zext i8 %0 to i32
|
||||
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv) #1
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(i8* nocapture readonly, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test1(%struct.lua_State* nocapture readonly %L) #0 {
|
||||
entry:
|
||||
%ci1 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 6
|
||||
%0 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !6
|
||||
%base2 = getelementptr inbounds %struct.CallInfoLua* %0, i32 0, i32 4, i32 0
|
||||
%1 = load %struct.TValue** %base2, align 4, !tbaa !12
|
||||
%add.ptr = getelementptr inbounds %struct.TValue* %1, i32 1
|
||||
%tt_ = getelementptr inbounds %struct.TValue* %1, i32 1, i32 1
|
||||
%value_5 = getelementptr inbounds %struct.TValue* %1, i32 3, i32 0
|
||||
%i = getelementptr inbounds %union.Value* %value_5, i32 0, i32 0
|
||||
%i7 = getelementptr inbounds %struct.TValue* %add.ptr, i32 0, i32 0, i32 0
|
||||
%i12 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 0, i32 0
|
||||
%i23 = getelementptr inbounds %struct.TValue* %1, i32 4, i32 0, i32 0
|
||||
%tt_24 = getelementptr inbounds %struct.TValue* %1, i32 4, i32 1
|
||||
%n = bitcast %union.Value* %value_5 to double*
|
||||
%n31 = bitcast %struct.TValue* %add.ptr to double*
|
||||
%value_36 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 0
|
||||
%n37 = bitcast %union.Value* %value_36 to double*
|
||||
%add.ptr48 = getelementptr inbounds %struct.TValue* %1, i32 4
|
||||
%n50 = bitcast %struct.TValue* %add.ptr48 to double*
|
||||
br label %label_loopbody
|
||||
|
||||
label_loopbody: ; preds = %label_loopbody.backedge, %entry
|
||||
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)) #1
|
||||
%2 = load i32* %tt_, align 4, !tbaa !15
|
||||
%cmp = icmp eq i32 %2, 19
|
||||
br i1 %cmp, label %if.then, label %if.else
|
||||
|
||||
if.then: ; preds = %label_loopbody
|
||||
%3 = load i64* %i, align 8, !tbaa !17
|
||||
%4 = load i64* %i7, align 8, !tbaa !17
|
||||
%add8 = add nsw i64 %4, %3
|
||||
%5 = load i64* %i12, align 8, !tbaa !17
|
||||
%cmp13 = icmp sgt i64 %3, 0
|
||||
br i1 %cmp13, label %cond.true, label %cond.false
|
||||
|
||||
cond.true: ; preds = %if.then
|
||||
%cmp14 = icmp sgt i64 %add8, %5
|
||||
br i1 %cmp14, label %if.end53, label %if.then16
|
||||
|
||||
cond.false: ; preds = %if.then
|
||||
%cmp15 = icmp sgt i64 %5, %add8
|
||||
br i1 %cmp15, label %if.end53, label %if.then16
|
||||
|
||||
if.then16: ; preds = %cond.true, %cond.false
|
||||
store i64 %add8, i64* %i7, align 8, !tbaa !17
|
||||
store i32 19, i32* %tt_, align 4, !tbaa !15
|
||||
store i64 %add8, i64* %i23, align 8, !tbaa !17
|
||||
br label %label_loopbody.backedge
|
||||
|
||||
label_loopbody.backedge: ; preds = %if.then16, %if.then43
|
||||
%storemerge = phi i32 [ 3, %if.then43 ], [ 19, %if.then16 ]
|
||||
store i32 %storemerge, i32* %tt_24, align 4, !tbaa !15
|
||||
br label %label_loopbody
|
||||
|
||||
if.else: ; preds = %label_loopbody
|
||||
%6 = load double* %n, align 8, !tbaa !18
|
||||
%7 = load double* %n31, align 8, !tbaa !18
|
||||
%add32 = fadd double %6, %7
|
||||
%8 = load double* %n37, align 8, !tbaa !18
|
||||
%cmp38 = fcmp ogt double %6, 0.000000e+00
|
||||
br i1 %cmp38, label %cond.true39, label %cond.false41
|
||||
|
||||
cond.true39: ; preds = %if.else
|
||||
%cmp40 = fcmp ugt double %add32, %8
|
||||
br i1 %cmp40, label %if.end53, label %if.then43
|
||||
|
||||
cond.false41: ; preds = %if.else
|
||||
%cmp42 = fcmp ugt double %8, %add32
|
||||
br i1 %cmp42, label %if.end53, label %if.then43
|
||||
|
||||
if.then43: ; preds = %cond.true39, %cond.false41
|
||||
store double %add32, double* %n31, align 8, !tbaa !18
|
||||
store i32 3, i32* %tt_, align 4, !tbaa !15
|
||||
store double %add32, double* %n50, align 8, !tbaa !18
|
||||
br label %label_loopbody.backedge
|
||||
|
||||
if.end53: ; preds = %cond.true, %cond.false, %cond.true39, %cond.false41
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
|
||||
!1 = metadata !{metadata !2, metadata !4, i64 4}
|
||||
!2 = metadata !{metadata !"GCObject", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5}
|
||||
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
|
||||
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
|
||||
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
|
||||
!6 = metadata !{metadata !7, metadata !3, i64 16}
|
||||
!7 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !8, i64 48, metadata !3, i64 104, metadata !9, i64 112, metadata !11, i64 120, metadata !11, i64 124, metadata !11, i64 128, metadata !10, i64 132, metadata !10, i64 134, metadata !4, i64 136, metadata !4, i64 137}
|
||||
!8 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !9, i64 40, metadata !10, i64 48, metadata !4, i64 50, metadata !4, i64 51}
|
||||
!9 = metadata !{metadata !"long long", metadata !4, i64 0}
|
||||
!10 = metadata !{metadata !"short", metadata !4, i64 0}
|
||||
!11 = metadata !{metadata !"int", metadata !4, i64 0}
|
||||
!12 = metadata !{metadata !13, metadata !3, i64 16}
|
||||
!13 = metadata !{metadata !"CallInfoLua", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !14, i64 16, metadata !9, i64 32, metadata !10, i64 40, metadata !4, i64 42, metadata !4, i64 43}
|
||||
!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64 4, metadata !9, i64 8}
|
||||
!15 = metadata !{metadata !16, metadata !11, i64 8}
|
||||
!16 = metadata !{metadata !"TValue", metadata !4, i64 0, metadata !11, i64 8}
|
||||
!17 = metadata !{metadata !9, metadata !9, i64 0}
|
||||
!18 = metadata !{metadata !19, metadata !19, i64 0}
|
||||
!19 = metadata !{metadata !"double", metadata !4, i64 0}
|
@ -0,0 +1,204 @@
|
||||
; ModuleID = 'lua_op_forprep.c'
|
||||
target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
|
||||
target triple = "i686-pc-windows-gnu"
|
||||
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.TValue }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoC }
|
||||
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
|
||||
%struct.lua_Debug = type opaque
|
||||
|
||||
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
|
||||
@.str1 = private unnamed_addr constant [29 x i8] c"'for' limit must be a number\00", align 1
|
||||
@.str2 = private unnamed_addr constant [28 x i8] c"'for' step must be a number\00", align 1
|
||||
@.str3 = private unnamed_addr constant [37 x i8] c"'for' initial value must be a number\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @testfunc(%struct.GCObject* nocapture readonly %obj) #0 {
|
||||
entry:
|
||||
%tt = getelementptr inbounds %struct.GCObject* %obj, i32 0, i32 1
|
||||
%0 = load i8* %tt, align 1, !tbaa !1
|
||||
%conv = zext i8 %0 to i32
|
||||
%call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), i32 %conv) #2
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare i32 @printf(i8* nocapture readonly, ...) #0
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test1(%struct.lua_State* %L) #0 {
|
||||
entry:
|
||||
%ilimit = alloca i64, align 8
|
||||
%stopnow = alloca i32, align 4
|
||||
%ninit = alloca double, align 8
|
||||
%nlimit = alloca double, align 8
|
||||
%nstep = alloca double, align 8
|
||||
%ci1 = getelementptr inbounds %struct.lua_State* %L, i32 0, i32 6
|
||||
%0 = load %struct.CallInfoLua** %ci1, align 4, !tbaa !6
|
||||
%base2 = getelementptr inbounds %struct.CallInfoLua* %0, i32 0, i32 4, i32 0
|
||||
%1 = load %struct.TValue** %base2, align 4, !tbaa !12
|
||||
%add.ptr = getelementptr inbounds %struct.TValue* %1, i32 1
|
||||
%add.ptr5 = getelementptr inbounds %struct.TValue* %1, i32 2
|
||||
%add.ptr6 = getelementptr inbounds %struct.TValue* %1, i32 3
|
||||
%tt_ = getelementptr inbounds %struct.TValue* %1, i32 1, i32 1
|
||||
%2 = load i32* %tt_, align 4, !tbaa !15
|
||||
%cmp = icmp eq i32 %2, 19
|
||||
%tt_7 = getelementptr inbounds %struct.TValue* %1, i32 3, i32 1
|
||||
%3 = load i32* %tt_7, align 4, !tbaa !15
|
||||
%cmp8 = icmp eq i32 %3, 19
|
||||
%i = getelementptr inbounds %struct.TValue* %add.ptr6, i32 0, i32 0, i32 0
|
||||
%4 = load i64* %i, align 8, !tbaa !17
|
||||
%call = call i32 @forlimit(%struct.TValue* %add.ptr5, i64* %ilimit, i64 %4, i32* %stopnow) #2
|
||||
%or.cond = and i1 %cmp, %cmp8
|
||||
%tobool13 = icmp ne i32 %call, 0
|
||||
%or.cond73 = and i1 %or.cond, %tobool13
|
||||
br i1 %or.cond73, label %if.then, label %if.else
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%5 = load i32* %stopnow, align 4, !tbaa !18
|
||||
%tobool14 = icmp eq i32 %5, 0
|
||||
%i16 = getelementptr inbounds %struct.TValue* %add.ptr, i32 0, i32 0, i32 0
|
||||
br i1 %tobool14, label %cond.false, label %cond.end
|
||||
|
||||
cond.false: ; preds = %if.then
|
||||
%6 = load i64* %i16, align 8, !tbaa !17
|
||||
br label %cond.end
|
||||
|
||||
cond.end: ; preds = %if.then, %cond.false
|
||||
%cond = phi i64 [ %6, %cond.false ], [ 0, %if.then ]
|
||||
%7 = load i64* %ilimit, align 8, !tbaa !17
|
||||
%i18 = getelementptr inbounds %struct.TValue* %add.ptr5, i32 0, i32 0, i32 0
|
||||
store i64 %7, i64* %i18, align 8, !tbaa !17
|
||||
%tt_19 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 1
|
||||
store i32 19, i32* %tt_19, align 4, !tbaa !15
|
||||
%8 = load i64* %i, align 8, !tbaa !17
|
||||
%sub = sub nsw i64 %cond, %8
|
||||
store i64 %sub, i64* %i16, align 8, !tbaa !17
|
||||
br label %label_forloop
|
||||
|
||||
if.else: ; preds = %entry
|
||||
%tt_25 = getelementptr inbounds %struct.TValue* %1, i32 2, i32 1
|
||||
%9 = load i32* %tt_25, align 4, !tbaa !15
|
||||
%cmp26 = icmp eq i32 %9, 3
|
||||
br i1 %cmp26, label %if.then28, label %if.else30
|
||||
|
||||
if.then28: ; preds = %if.else
|
||||
%n = bitcast %struct.TValue* %add.ptr5 to double*
|
||||
%10 = load double* %n, align 8, !tbaa !19
|
||||
store double %10, double* %nlimit, align 8, !tbaa !19
|
||||
br label %if.end35
|
||||
|
||||
if.else30: ; preds = %if.else
|
||||
%call31 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr5, double* %nlimit) #2
|
||||
%phitmp = icmp eq i32 %call31, 0
|
||||
br i1 %phitmp, label %if.then33, label %if.end35
|
||||
|
||||
if.then33: ; preds = %if.else30
|
||||
%call34 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([29 x i8]* @.str1, i32 0, i32 0)) #2
|
||||
br label %if.end35
|
||||
|
||||
if.end35: ; preds = %if.else30, %if.then28, %if.then33
|
||||
%11 = load double* %nlimit, align 8, !tbaa !19
|
||||
%n37 = bitcast %struct.TValue* %add.ptr5 to double*
|
||||
store double %11, double* %n37, align 8, !tbaa !19
|
||||
store i32 3, i32* %tt_25, align 4, !tbaa !15
|
||||
%12 = load i32* %tt_7, align 4, !tbaa !15
|
||||
%cmp40 = icmp eq i32 %12, 3
|
||||
br i1 %cmp40, label %if.then42, label %if.else45
|
||||
|
||||
if.then42: ; preds = %if.end35
|
||||
%n44 = bitcast %struct.TValue* %add.ptr6 to double*
|
||||
%13 = load double* %n44, align 8, !tbaa !19
|
||||
store double %13, double* %nstep, align 8, !tbaa !19
|
||||
br label %if.end51
|
||||
|
||||
if.else45: ; preds = %if.end35
|
||||
%call46 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr6, double* %nstep) #2
|
||||
%phitmp104 = icmp eq i32 %call46, 0
|
||||
br i1 %phitmp104, label %if.then49, label %if.end51
|
||||
|
||||
if.then49: ; preds = %if.else45
|
||||
%call50 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([28 x i8]* @.str2, i32 0, i32 0)) #2
|
||||
br label %if.end51
|
||||
|
||||
if.end51: ; preds = %if.else45, %if.then42, %if.then49
|
||||
%14 = load double* %nstep, align 8, !tbaa !19
|
||||
%n53 = bitcast %struct.TValue* %add.ptr6 to double*
|
||||
store double %14, double* %n53, align 8, !tbaa !19
|
||||
store i32 3, i32* %tt_7, align 4, !tbaa !15
|
||||
%15 = load i32* %tt_, align 4, !tbaa !15
|
||||
%cmp56 = icmp eq i32 %15, 3
|
||||
br i1 %cmp56, label %if.then58, label %if.else61
|
||||
|
||||
if.then58: ; preds = %if.end51
|
||||
%n60 = bitcast %struct.TValue* %add.ptr to double*
|
||||
%16 = load double* %n60, align 8, !tbaa !19
|
||||
store double %16, double* %ninit, align 8, !tbaa !19
|
||||
br label %if.end67
|
||||
|
||||
if.else61: ; preds = %if.end51
|
||||
%call62 = call i32 @luaV_tonumber_(%struct.TValue* %add.ptr, double* %ninit) #2
|
||||
%phitmp105 = icmp eq i32 %call62, 0
|
||||
br i1 %phitmp105, label %if.then65, label %if.end67
|
||||
|
||||
if.then65: ; preds = %if.else61
|
||||
%call66 = call i32 bitcast (i32 (...)* @luaG_runerror to i32 (%struct.lua_State*, i8*)*)(%struct.lua_State* %L, i8* getelementptr inbounds ([37 x i8]* @.str3, i32 0, i32 0)) #2
|
||||
br label %if.end67
|
||||
|
||||
if.end67: ; preds = %if.else61, %if.then58, %if.then65
|
||||
%17 = load double* %ninit, align 8, !tbaa !19
|
||||
%18 = load double* %nstep, align 8, !tbaa !19
|
||||
%sub68 = fsub double %17, %18
|
||||
%n70 = bitcast %struct.TValue* %add.ptr to double*
|
||||
store double %sub68, double* %n70, align 8, !tbaa !19
|
||||
br label %label_forloop
|
||||
|
||||
label_forloop: ; preds = %cond.end, %if.end67
|
||||
%storemerge = phi i32 [ 3, %if.end67 ], [ 19, %cond.end ]
|
||||
store i32 %storemerge, i32* %tt_, align 4, !tbaa !15
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @forlimit(%struct.TValue*, i64*, i64, i32*) #1
|
||||
|
||||
declare i32 @luaV_tonumber_(%struct.TValue*, double*) #1
|
||||
|
||||
declare i32 @luaG_runerror(...) #1
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = metadata !{metadata !"clang version 3.6.0 (trunk)"}
|
||||
!1 = metadata !{metadata !2, metadata !4, i64 4}
|
||||
!2 = metadata !{metadata !"GCObject", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5}
|
||||
!3 = metadata !{metadata !"any pointer", metadata !4, i64 0}
|
||||
!4 = metadata !{metadata !"omnipotent char", metadata !5, i64 0}
|
||||
!5 = metadata !{metadata !"Simple C/C++ TBAA"}
|
||||
!6 = metadata !{metadata !7, metadata !3, i64 16}
|
||||
!7 = metadata !{metadata !"lua_State", metadata !3, i64 0, metadata !4, i64 4, metadata !4, i64 5, metadata !4, i64 6, metadata !3, i64 8, metadata !3, i64 12, metadata !3, i64 16, metadata !3, i64 20, metadata !3, i64 24, metadata !3, i64 28, metadata !3, i64 32, metadata !3, i64 36, metadata !3, i64 40, metadata !3, i64 44, metadata !8, i64 48, metadata !3, i64 104, metadata !9, i64 112, metadata !11, i64 120, metadata !11, i64 124, metadata !11, i64 128, metadata !10, i64 132, metadata !10, i64 134, metadata !4, i64 136, metadata !4, i64 137}
|
||||
!8 = metadata !{metadata !"CallInfo", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !4, i64 16, metadata !9, i64 40, metadata !10, i64 48, metadata !4, i64 50, metadata !4, i64 51}
|
||||
!9 = metadata !{metadata !"long long", metadata !4, i64 0}
|
||||
!10 = metadata !{metadata !"short", metadata !4, i64 0}
|
||||
!11 = metadata !{metadata !"int", metadata !4, i64 0}
|
||||
!12 = metadata !{metadata !13, metadata !3, i64 16}
|
||||
!13 = metadata !{metadata !"CallInfoLua", metadata !3, i64 0, metadata !3, i64 4, metadata !3, i64 8, metadata !3, i64 12, metadata !14, i64 16, metadata !9, i64 32, metadata !10, i64 40, metadata !4, i64 42, metadata !4, i64 43}
|
||||
!14 = metadata !{metadata !"CallInfoL", metadata !3, i64 0, metadata !3, i64 4, metadata !9, i64 8}
|
||||
!15 = metadata !{metadata !16, metadata !11, i64 8}
|
||||
!16 = metadata !{metadata !"TValue", metadata !4, i64 0, metadata !11, i64 8}
|
||||
!17 = metadata !{metadata !9, metadata !9, i64 0}
|
||||
!18 = metadata !{metadata !11, metadata !11, i64 0}
|
||||
!19 = metadata !{metadata !20, metadata !20, i64 0}
|
||||
!20 = metadata !{metadata !"double", metadata !4, i64 0}
|
@ -0,0 +1,123 @@
|
||||
; ModuleID = 'lua_op_loadk_return.c'
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
|
||||
target triple = "i686-pc-windows-gnu"
|
||||
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.TValue }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoC }
|
||||
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
|
||||
%struct.lua_Debug = type opaque
|
||||
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
|
||||
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
|
||||
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
|
||||
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
|
||||
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
|
||||
%union.anon.1 = type { i64 }
|
||||
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
|
||||
|
||||
@.str = private unnamed_addr constant [12 x i8] c"value = %d\0A\00", align 1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @testfunc(%struct.GCObject* %obj) #0 {
|
||||
entry:
|
||||
%obj.addr = alloca %struct.GCObject*, align 4
|
||||
store %struct.GCObject* %obj, %struct.GCObject** %obj.addr, align 4, !tbaa !1
|
||||
%0 = load %struct.GCObject*, %struct.GCObject** %obj.addr, align 4, !tbaa !1
|
||||
%tt = getelementptr inbounds %struct.GCObject, %struct.GCObject* %0, i32 0, i32 1
|
||||
%1 = load i8, i8* %tt, align 1, !tbaa !5
|
||||
%conv = zext i8 %1 to i32
|
||||
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 %conv)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @printf(i8*, ...) #1
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test1(%struct.lua_State* %L, i32 %b, i32 %x) #0 {
|
||||
entry:
|
||||
%L.addr = alloca %struct.lua_State*, align 4
|
||||
%b.addr = alloca i32, align 4
|
||||
%x.addr = alloca i32, align 4
|
||||
%ci = alloca %struct.CallInfoLua*, align 4
|
||||
%cl = alloca %struct.LClosure*, align 4
|
||||
%k = alloca %struct.TValue*, align 4
|
||||
%base = alloca %struct.TValue*, align 4
|
||||
%cil = alloca %struct.CallInfoL*, align 4
|
||||
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
store i32 %b, i32* %b.addr, align 4, !tbaa !7
|
||||
store i32 %x, i32* %x.addr, align 4, !tbaa !7
|
||||
%0 = bitcast %struct.CallInfoLua** %ci to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %0) #2
|
||||
%1 = bitcast %struct.LClosure** %cl to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %1) #2
|
||||
%2 = bitcast %struct.TValue** %k to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %2) #2
|
||||
%3 = bitcast %struct.TValue** %base to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %3) #2
|
||||
%4 = bitcast %struct.CallInfoL** %cil to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %4) #2
|
||||
%5 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %5, i32 0, i32 6
|
||||
%6 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !9
|
||||
store %struct.CallInfoLua* %6, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%7 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %7, i32 0, i32 4
|
||||
%base2 = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 0
|
||||
%8 = load %struct.TValue*, %struct.TValue** %base2, align 4, !tbaa !14
|
||||
store %struct.TValue* %8, %struct.TValue** %base, align 4, !tbaa !1
|
||||
%9 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l3 = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %9, i32 0, i32 4
|
||||
%savedpc = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l3, i32 0, i32 1
|
||||
store i32* %x.addr, i32** %savedpc, align 4, !tbaa !17
|
||||
%10 = bitcast %struct.CallInfoL** %cil to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %10) #2
|
||||
%11 = bitcast %struct.TValue** %base to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %11) #2
|
||||
%12 = bitcast %struct.TValue** %k to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %12) #2
|
||||
%13 = bitcast %struct.LClosure** %cl to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %13) #2
|
||||
%14 = bitcast %struct.CallInfoLua** %ci to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %14) #2
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.lifetime.start(i64, i8* nocapture) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.lifetime.end(i64, i8* nocapture) #2
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 3.7.0 (trunk)"}
|
||||
!1 = !{!2, !2, i64 0}
|
||||
!2 = !{!"any pointer", !3, i64 0}
|
||||
!3 = !{!"omnipotent char", !4, i64 0}
|
||||
!4 = !{!"Simple C/C++ TBAA"}
|
||||
!5 = !{!6, !3, i64 4}
|
||||
!6 = !{!"GCObject", !2, i64 0, !3, i64 4, !3, i64 5}
|
||||
!7 = !{!8, !8, i64 0}
|
||||
!8 = !{!"int", !3, i64 0}
|
||||
!9 = !{!10, !2, i64 16}
|
||||
!10 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !11, i64 48, !2, i64 104, !12, i64 112, !8, i64 120, !8, i64 124, !8, i64 128, !13, i64 132, !13, i64 134, !3, i64 136, !3, i64 137}
|
||||
!11 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !12, i64 40, !13, i64 48, !3, i64 50, !3, i64 51}
|
||||
!12 = !{!"long long", !3, i64 0}
|
||||
!13 = !{!"short", !3, i64 0}
|
||||
!14 = !{!15, !2, i64 16}
|
||||
!15 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !16, i64 16, !12, i64 32, !13, i64 40, !3, i64 42, !3, i64 43}
|
||||
!16 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !12, i64 8}
|
||||
!17 = !{!15, !2, i64 20}
|
@ -0,0 +1,145 @@
|
||||
; ModuleID = 'lua_savedpc.c'
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-S32"
|
||||
target triple = "i686-pc-windows-gnu"
|
||||
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.UpVal = type { %struct.TValue*, i64, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.TValue }
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoC }
|
||||
%struct.CallInfoC = type { i32 (%struct.lua_State*, i32, i64)*, i64, i64 }
|
||||
%struct.lua_Debug = type opaque
|
||||
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
|
||||
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, %struct.RaviJITProto }
|
||||
%struct.LocVar = type { %struct.TString*, i32, i32, i32 }
|
||||
%struct.Upvaldesc = type { %struct.TString*, i32, i8, i8 }
|
||||
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
|
||||
%union.anon.1 = type { i64 }
|
||||
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @test1(%struct.lua_State* %L, i32 %b) #0 {
|
||||
entry:
|
||||
%L.addr = alloca %struct.lua_State*, align 4
|
||||
%b.addr = alloca i32, align 4
|
||||
%ci = alloca %struct.CallInfoLua*, align 4
|
||||
%cl = alloca %struct.LClosure*, align 4
|
||||
%p = alloca %struct.Proto*, align 4
|
||||
store %struct.lua_State* %L, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
store i32 %b, i32* %b.addr, align 4, !tbaa !5
|
||||
%0 = bitcast %struct.CallInfoLua** %ci to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %0) #1
|
||||
%1 = bitcast %struct.LClosure** %cl to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %1) #1
|
||||
%2 = bitcast %struct.Proto** %p to i8*
|
||||
call void @llvm.lifetime.start(i64 4, i8* %2) #1
|
||||
%3 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%ci1 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %3, i32 0, i32 6
|
||||
%4 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci1, align 4, !tbaa !7
|
||||
store %struct.CallInfoLua* %4, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%5 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%func = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %5, i32 0, i32 0
|
||||
%6 = load %struct.TValue*, %struct.TValue** %func, align 4, !tbaa !12
|
||||
%value_ = getelementptr inbounds %struct.TValue, %struct.TValue* %6, i32 0, i32 0
|
||||
%gc = bitcast %union.Value* %value_ to %struct.GCObject**
|
||||
%7 = load %struct.GCObject*, %struct.GCObject** %gc, align 4, !tbaa !1
|
||||
%8 = bitcast %struct.GCObject* %7 to %struct.LClosure*
|
||||
store %struct.LClosure* %8, %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%9 = load %struct.LClosure*, %struct.LClosure** %cl, align 4, !tbaa !1
|
||||
%p2 = getelementptr inbounds %struct.LClosure, %struct.LClosure* %9, i32 0, i32 5
|
||||
%10 = load %struct.Proto*, %struct.Proto** %p2, align 4, !tbaa !15
|
||||
store %struct.Proto* %10, %struct.Proto** %p, align 4, !tbaa !1
|
||||
%11 = load i32, i32* %b.addr, align 4, !tbaa !5
|
||||
%12 = load %struct.Proto*, %struct.Proto** %p, align 4, !tbaa !1
|
||||
%code = getelementptr inbounds %struct.Proto, %struct.Proto* %12, i32 0, i32 15
|
||||
%13 = load i32*, i32** %code, align 4, !tbaa !17
|
||||
%arrayidx = getelementptr inbounds i32, i32* %13, i32 %11
|
||||
%14 = load %struct.CallInfoLua*, %struct.CallInfoLua** %ci, align 4, !tbaa !1
|
||||
%l = getelementptr inbounds %struct.CallInfoLua, %struct.CallInfoLua* %14, i32 0, i32 4
|
||||
%savedpc = getelementptr inbounds %struct.CallInfoL, %struct.CallInfoL* %l, i32 0, i32 1
|
||||
store i32* %arrayidx, i32** %savedpc, align 4, !tbaa !20
|
||||
%15 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%hookmask = getelementptr inbounds %struct.lua_State, %struct.lua_State* %15, i32 0, i32 22
|
||||
%16 = load i8, i8* %hookmask, align 1, !tbaa !21
|
||||
%conv = zext i8 %16 to i32
|
||||
%and = and i32 %conv, 12
|
||||
%tobool = icmp ne i32 %and, 0
|
||||
br i1 %tobool, label %land.lhs.true, label %if.end
|
||||
|
||||
land.lhs.true: ; preds = %entry
|
||||
%17 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%hookcount = getelementptr inbounds %struct.lua_State, %struct.lua_State* %17, i32 0, i32 19
|
||||
%18 = load i32, i32* %hookcount, align 4, !tbaa !22
|
||||
%dec = add nsw i32 %18, -1
|
||||
store i32 %dec, i32* %hookcount, align 4, !tbaa !22
|
||||
%cmp = icmp eq i32 %dec, 0
|
||||
br i1 %cmp, label %if.then, label %lor.lhs.false
|
||||
|
||||
lor.lhs.false: ; preds = %land.lhs.true
|
||||
%19 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
%hookmask4 = getelementptr inbounds %struct.lua_State, %struct.lua_State* %19, i32 0, i32 22
|
||||
%20 = load i8, i8* %hookmask4, align 1, !tbaa !21
|
||||
%conv5 = zext i8 %20 to i32
|
||||
%and6 = and i32 %conv5, 4
|
||||
%tobool7 = icmp ne i32 %and6, 0
|
||||
br i1 %tobool7, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %lor.lhs.false, %land.lhs.true
|
||||
%21 = load %struct.lua_State*, %struct.lua_State** %L.addr, align 4, !tbaa !1
|
||||
call void @luaG_traceexec(%struct.lua_State* %21)
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %if.then, %lor.lhs.false, %entry
|
||||
%22 = bitcast %struct.Proto** %p to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %22) #1
|
||||
%23 = bitcast %struct.LClosure** %cl to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %23) #1
|
||||
%24 = bitcast %struct.CallInfoLua** %ci to i8*
|
||||
call void @llvm.lifetime.end(i64 4, i8* %24) #1
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.lifetime.start(i64, i8* nocapture) #1
|
||||
|
||||
declare void @luaG_traceexec(%struct.lua_State*) #2
|
||||
|
||||
; Function Attrs: nounwind
|
||||
declare void @llvm.lifetime.end(i64, i8* nocapture) #1
|
||||
|
||||
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { nounwind }
|
||||
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 3.7.0 (trunk)"}
|
||||
!1 = !{!2, !2, i64 0}
|
||||
!2 = !{!"any pointer", !3, i64 0}
|
||||
!3 = !{!"omnipotent char", !4, i64 0}
|
||||
!4 = !{!"Simple C/C++ TBAA"}
|
||||
!5 = !{!6, !6, i64 0}
|
||||
!6 = !{!"int", !3, i64 0}
|
||||
!7 = !{!8, !2, i64 16}
|
||||
!8 = !{!"lua_State", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !2, i64 32, !2, i64 36, !2, i64 40, !2, i64 44, !9, i64 48, !2, i64 104, !10, i64 112, !6, i64 120, !6, i64 124, !6, i64 128, !11, i64 132, !11, i64 134, !3, i64 136, !3, i64 137}
|
||||
!9 = !{!"CallInfo", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !3, i64 16, !10, i64 40, !11, i64 48, !3, i64 50, !3, i64 51}
|
||||
!10 = !{!"long long", !3, i64 0}
|
||||
!11 = !{!"short", !3, i64 0}
|
||||
!12 = !{!13, !2, i64 0}
|
||||
!13 = !{!"CallInfoLua", !2, i64 0, !2, i64 4, !2, i64 8, !2, i64 12, !14, i64 16, !10, i64 32, !11, i64 40, !3, i64 42, !3, i64 43}
|
||||
!14 = !{!"CallInfoL", !2, i64 0, !2, i64 4, !10, i64 8}
|
||||
!15 = !{!16, !2, i64 12}
|
||||
!16 = !{!"LClosure", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !2, i64 8, !2, i64 12, !3, i64 16}
|
||||
!17 = !{!18, !2, i64 48}
|
||||
!18 = !{!"Proto", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !3, i64 8, !6, i64 12, !6, i64 16, !6, i64 20, !6, i64 24, !6, i64 28, !6, i64 32, !6, i64 36, !6, i64 40, !2, i64 44, !2, i64 48, !2, i64 52, !2, i64 56, !2, i64 60, !2, i64 64, !2, i64 68, !2, i64 72, !2, i64 76, !19, i64 80}
|
||||
!19 = !{!"RaviJITProto", !3, i64 0, !2, i64 4, !2, i64 8}
|
||||
!20 = !{!13, !2, i64 20}
|
||||
!21 = !{!8, !3, i64 136}
|
||||
!22 = !{!8, !6, i64 128}
|
@ -0,0 +1,14 @@
|
||||
#include "lua_hdr.h"
|
||||
|
||||
extern int printf(const char *, ...);
|
||||
extern void luaC_upvalbarrier_ (struct lua_State *L, struct GCObject *o, struct GCObject *v);
|
||||
|
||||
void luaV_op_call(struct lua_State *L, struct LClosure *cl, struct TValue *ra, int b, int c) {
|
||||
struct UpVal *uv = cl->upvals[b];
|
||||
|
||||
int ra_iscollectable = iscollectable(ra);
|
||||
int uv_isblack = isblack(uv);
|
||||
int rav_iswhite = iswhite(gcvalue(ra));
|
||||
if (ra_iscollectable && uv_isblack && rav_iswhite)
|
||||
luaC_upvalbarrier_(L,(struct GCObject *)uv, ra->value_.gc);
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
; ModuleID = 'lua_upval.c'
|
||||
source_filename = "lua_upval.c"
|
||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
%struct.lua_State = type { %struct.GCObject*, i8, i8, i8, %struct.TValue*, %struct.global_State*, %struct.CallInfoLua*, i32*, %struct.TValue*, %struct.TValue*, %struct.UpVal*, %struct.GCObject*, %struct.lua_State*, %struct.lua_longjmp*, %struct.CallInfo, void (%struct.lua_State*, %struct.lua_Debug*)*, i64, i32, i32, i32, i16, i16, i8, i8, i16 }
|
||||
%struct.global_State = type opaque
|
||||
%struct.CallInfoLua = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %struct.CallInfoL, i64, i16, i8, i8, i16 }
|
||||
%struct.CallInfoL = type { %struct.TValue*, i32*, i64 }
|
||||
%struct.UpVal = type { %struct.GCObject*, i8, i8, %struct.TValue*, %union.anon.0 }
|
||||
%union.anon.0 = type { %struct.anon }
|
||||
%struct.anon = type { %struct.UpVal*, %struct.UpVal** }
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.lua_longjmp = type opaque
|
||||
%struct.CallInfo = type { %struct.TValue*, %struct.TValue*, %struct.CallInfo*, %struct.CallInfo*, %union.anon, i64, i16, i8, i8 }
|
||||
%union.anon = type { %struct.CallInfoL }
|
||||
%struct.lua_Debug = type opaque
|
||||
%struct.LClosure = type { %struct.GCObject*, i8, i8, i8, %struct.GCObject*, %struct.Proto*, [1 x %struct.UpVal*] }
|
||||
%struct.Proto = type { %struct.GCObject*, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, %struct.TValue*, i32*, %struct.Proto**, i32*, %struct.LocVar*, %struct.Upvaldesc*, %struct.LClosure*, %struct.TString*, %struct.GCObject*, i8, %struct.RaviJITProto }
|
||||
%struct.LocVar = type { %struct.TString*, %struct.TString*, i32, i32, i8 }
|
||||
%struct.Upvaldesc = type { %struct.TString*, %struct.TString*, i8, i8, i8 }
|
||||
%struct.TString = type { %struct.GCObject*, i8, i8, i8, i8, i32, %union.anon.1 }
|
||||
%union.anon.1 = type { i64 }
|
||||
%struct.RaviJITProto = type { i8, i8*, i32 (%struct.lua_State*)* }
|
||||
%struct.TValue = type { %union.Value, i8 }
|
||||
%union.Value = type { %struct.GCObject* }
|
||||
|
||||
; Function Attrs: nounwind
|
||||
define void @luaV_op_call(%struct.lua_State* %L, %struct.LClosure* nocapture readonly %cl, %struct.TValue* nocapture readonly %ra, i32 %b, i32 %c) local_unnamed_addr #0 {
|
||||
entry:
|
||||
%idxprom = sext i32 %b to i64
|
||||
%arrayidx = getelementptr inbounds %struct.LClosure, %struct.LClosure* %cl, i64 0, i32 6, i64 %idxprom
|
||||
%0 = load %struct.UpVal*, %struct.UpVal** %arrayidx, align 8, !tbaa !1
|
||||
%tt_ = getelementptr inbounds %struct.TValue, %struct.TValue* %ra, i64 0, i32 1
|
||||
%1 = load i8, i8* %tt_, align 8, !tbaa !5
|
||||
%2 = and i8 %1, 64
|
||||
%marked = getelementptr inbounds %struct.UpVal, %struct.UpVal* %0, i64 0, i32 2
|
||||
%3 = load i8, i8* %marked, align 1, !tbaa !7
|
||||
%4 = and i8 %3, 32
|
||||
%gc = getelementptr inbounds %struct.TValue, %struct.TValue* %ra, i64 0, i32 0, i32 0
|
||||
%5 = load %struct.GCObject*, %struct.GCObject** %gc, align 8, !tbaa !1
|
||||
%marked3 = getelementptr inbounds %struct.GCObject, %struct.GCObject* %5, i64 0, i32 2
|
||||
%6 = load i8, i8* %marked3, align 1, !tbaa !9
|
||||
%7 = and i8 %6, 24
|
||||
%tobool = icmp ne i8 %2, 0
|
||||
%tobool6 = icmp ne i8 %4, 0
|
||||
%or.cond = and i1 %tobool, %tobool6
|
||||
%tobool8 = icmp ne i8 %7, 0
|
||||
%or.cond11 = and i1 %or.cond, %tobool8
|
||||
br i1 %or.cond11, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%8 = bitcast %struct.UpVal* %0 to %struct.GCObject*
|
||||
tail call void @luaC_upvalbarrier_(%struct.lua_State* %L, %struct.GCObject* %8, %struct.GCObject* %5) #2
|
||||
br label %if.end
|
||||
|
||||
if.end: ; preds = %if.then, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @luaC_upvalbarrier_(%struct.lua_State*, %struct.GCObject*, %struct.GCObject*) local_unnamed_addr #1
|
||||
|
||||
attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 4.0.0 (tags/RELEASE_400/final)"}
|
||||
!1 = !{!2, !2, i64 0}
|
||||
!2 = !{!"any pointer", !3, i64 0}
|
||||
!3 = !{!"omnipotent char", !4, i64 0}
|
||||
!4 = !{!"Simple C/C++ TBAA"}
|
||||
!5 = !{!6, !3, i64 8}
|
||||
!6 = !{!"TValue", !3, i64 0, !3, i64 8}
|
||||
!7 = !{!8, !3, i64 9}
|
||||
!8 = !{!"UpVal", !2, i64 0, !3, i64 8, !3, i64 9, !2, i64 16, !3, i64 24}
|
||||
!9 = !{!10, !3, i64 9}
|
||||
!10 = !{!"GCObject", !2, i64 0, !3, i64 8, !3, i64 9}
|
@ -0,0 +1,5 @@
|
||||
setlocal
|
||||
set PATH=%PATH%;"c:\Program Files (x86)\LLVM\bin"
|
||||
|
||||
rem clang -cc1 -O1 -disable-llvm-optzns -S -emit-llvm %1
|
||||
clang -cc1 -O2 -S -emit-llvm %1
|
@ -0,0 +1,37 @@
|
||||
; ModuleID = 'tab.c'
|
||||
source_filename = "tab.c"
|
||||
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||
target triple = "i686-pc-windows-msvc"
|
||||
|
||||
%struct.TValue = type { %union.Value, i32 }
|
||||
%union.Value = type { i64 }
|
||||
%struct.Table = type { %struct.GCObject*, i8, i8, i8, i8, i32, %struct.TValue*, %struct.Node*, %struct.Node*, %struct.Table*, %struct.GCObject*, %struct.RaviArray, i32 }
|
||||
%struct.Node = type { %struct.TValue, %union.TKey }
|
||||
%union.TKey = type { %struct.anon.2 }
|
||||
%struct.anon.2 = type { %union.Value, i32, i32 }
|
||||
%struct.GCObject = type { %struct.GCObject*, i8, i8 }
|
||||
%struct.RaviArray = type { i8*, i32, i32, i32 }
|
||||
|
||||
; Function Attrs: norecurse nounwind readonly
|
||||
define i32 @tablevalue(%struct.TValue* nocapture readonly %v) local_unnamed_addr #0 {
|
||||
entry:
|
||||
%0 = bitcast %struct.TValue* %v to %struct.Table**
|
||||
%1 = load %struct.Table*, %struct.Table** %0, align 8, !tbaa !1
|
||||
%sizearray = getelementptr inbounds %struct.Table, %struct.Table* %1, i32 0, i32 5
|
||||
%2 = load i32, i32* %sizearray, align 8, !tbaa !5
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
attributes #0 = { norecurse nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
||||
!llvm.ident = !{!0}
|
||||
|
||||
!0 = !{!"clang version 3.9.0 (trunk)"}
|
||||
!1 = !{!2, !2, i64 0}
|
||||
!2 = !{!"any pointer", !3, i64 0}
|
||||
!3 = !{!"omnipotent char", !4, i64 0}
|
||||
!4 = !{!"Simple C/C++ TBAA"}
|
||||
!5 = !{!6, !7, i64 8}
|
||||
!6 = !{!"Table", !2, i64 0, !3, i64 4, !3, i64 5, !3, i64 6, !3, i64 7, !7, i64 8, !2, i64 12, !2, i64 16, !2, i64 20, !2, i64 24, !2, i64 28, !8, i64 32, !7, i64 48}
|
||||
!7 = !{!"int", !3, i64 0}
|
||||
!8 = !{!"RaviArray", !2, i64 0, !3, i64 4, !7, i64 8, !7, i64 12}
|
@ -0,0 +1 @@
|
||||
Subproject commit 5b42a99121627677952d4cf3445d795be85582de
|
@ -1,30 +0,0 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN set -x \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y libreadline-dev \
|
||||
&& apt-get install -y build-essential \
|
||||
&& apt-get install -y git wget \
|
||||
&& apt-get install -y zlib1g-dev \
|
||||
&& apt-get clean \
|
||||
&& mkdir -p /Software \
|
||||
&& wget -O "/Software/cmake-3.14.5-Linux-x86_64.tar.gz" "https://github.com/Kitware/CMake/releases/download/v3.14.5/cmake-3.14.5-Linux-x86_64.tar.gz" \
|
||||
&& cd /Software \
|
||||
&& tar xvf "cmake-3.14.5-Linux-x86_64.tar.gz" \
|
||||
&& rm -rf "/Software/cmake-3.14.5-Linux-x86_64.tar.gz" \
|
||||
&& mkdir -p /sources \
|
||||
&& cd /sources \
|
||||
&& git clone https://github.com/dibyendumajumdar/ravi.git \
|
||||
&& cd /sources/ravi \
|
||||
&& mkdir build \
|
||||
&& cd build \
|
||||
&& /Software/cmake-3.14.5-Linux-x86_64/bin/cmake -DCMAKE_INSTALL_PREFIX=/Software/ravi -DCMAKE_BUILD_TYPE=Release .. \
|
||||
&& make install \
|
||||
&& rm -rf /Software/cmake-3.14.5-Linux-x86_64 \
|
||||
&& rm -rf /sources \
|
||||
&& apt-get autoremove \
|
||||
&& apt-get remove -y --purge git wget build-essential \
|
||||
&& apt-get clean
|
||||
|
||||
ENV PATH /Software/ravi/bin:${PATH}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
|
||||
** $Id: lapi.h,v 2.9 2015/03/06 19:49:50 roberto Exp $
|
||||
** Auxiliary functions from Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
|
||||
** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $
|
||||
** 'ctype' functions for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
|
||||
** $Id: ldebug.h,v 2.14 2015/05/22 17:45:56 roberto Exp $
|
||||
** Auxiliary functions from Debug Interface module
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $
|
||||
** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $
|
||||
** Definitions for Lua code that must come before any other header file
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
|
||||
** $Id: lstring.h,v 1.61 2015/11/03 15:36:01 roberto Exp $
|
||||
** String table (keep all strings handled by Lua)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
** $Id: ltests.h,v 2.49 2015/09/22 14:18:24 roberto Exp roberto $
|
||||
** Internal Header for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef ltests_h
|
||||
#define ltests_h
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* test Lua with no compatibility code */
|
||||
#undef LUA_COMPAT_MATHLIB
|
||||
#undef LUA_COMPAT_IPAIRS
|
||||
#undef LUA_COMPAT_BITLIB
|
||||
#undef LUA_COMPAT_APIINTCASTS
|
||||
#undef LUA_COMPAT_FLOATSTRING
|
||||
#undef LUA_COMPAT_UNPACK
|
||||
#undef LUA_COMPAT_LOADERS
|
||||
#undef LUA_COMPAT_LOG10
|
||||
#undef LUA_COMPAT_LOADSTRING
|
||||
#undef LUA_COMPAT_MAXN
|
||||
#undef LUA_COMPAT_MODULE
|
||||
|
||||
|
||||
#define LUA_DEBUG
|
||||
|
||||
|
||||
/* turn on assertions */
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#define lua_assert(c) assert(c)
|
||||
|
||||
|
||||
#if !defined(RAVI_OPTION_STRING1)
|
||||
#define RAVI_OPTION_STRING1 " assertions"
|
||||
#endif
|
||||
|
||||
#define RAVI_OPTION_STRING2 " ltests"
|
||||
|
||||
/* to avoid warnings, and to make sure value is really unused */
|
||||
#define UNUSED(x) (x=0, (void)(x))
|
||||
|
||||
|
||||
/* test for sizes in 'l_sprintf' (make sure whole buffer is available) */
|
||||
#undef l_sprintf
|
||||
#if !defined(LUA_USE_C89)
|
||||
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i))
|
||||
#else
|
||||
#define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i))
|
||||
#endif
|
||||
|
||||
|
||||
/* memory-allocator control variables */
|
||||
typedef struct Memcontrol {
|
||||
unsigned long numblocks;
|
||||
unsigned long total;
|
||||
unsigned long maxmem;
|
||||
unsigned long memlimit;
|
||||
unsigned long countlimit;
|
||||
unsigned long objcount[LUA_NUMTAGS];
|
||||
} Memcontrol;
|
||||
|
||||
// LUA_API Memcontrol l_memcontrol;
|
||||
|
||||
|
||||
/*
|
||||
** generic variable for debug tricks
|
||||
*/
|
||||
extern void *l_Trick;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Function to traverse and check all memory used by Lua
|
||||
*/
|
||||
int lua_checkmemory (lua_State *L);
|
||||
|
||||
|
||||
/* test for lock/unlock */
|
||||
|
||||
struct L_EXTRA { int lock; int *plock; };
|
||||
#undef LUA_EXTRASPACE
|
||||
#define LUA_EXTRASPACE sizeof(struct L_EXTRA)
|
||||
#define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l))
|
||||
#define luai_userstateopen(l) \
|
||||
(getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
|
||||
#define luai_userstateclose(l) \
|
||||
lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock))
|
||||
#define luai_userstatethread(l,l1) \
|
||||
lua_assert(getlock(l1)->plock == getlock(l)->plock)
|
||||
#define luai_userstatefree(l,l1) \
|
||||
lua_assert(getlock(l)->plock == getlock(l1)->plock)
|
||||
#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
|
||||
#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
|
||||
|
||||
|
||||
|
||||
LUA_API int luaB_opentests (lua_State *L);
|
||||
|
||||
LUA_API void *debug_realloc (void *ud, void *block,
|
||||
size_t osize, size_t nsize);
|
||||
|
||||
LUA_API Memcontrol* luaB_getmemcontrol(void);
|
||||
|
||||
#if defined(lua_c)
|
||||
#define luaL_newstate() lua_newstate(debug_realloc, luaB_getmemcontrol())
|
||||
#define luaL_openlibs(L) \
|
||||
{ (luaL_openlibs)(L); \
|
||||
luaL_requiref(L, "T", luaB_opentests, 1); \
|
||||
lua_pop(L, 1); }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* change some sizes to give some bugs a chance */
|
||||
|
||||
#undef LUAL_BUFFERSIZE
|
||||
#define LUAL_BUFFERSIZE 23
|
||||
#define MINSTRTABSIZE 2
|
||||
//#define MAXINDEXRK 1
|
||||
|
||||
|
||||
/* make stack-overflow tests run faster */
|
||||
#undef LUAI_MAXSTACK
|
||||
#define LUAI_MAXSTACK 50000
|
||||
|
||||
#if 0 /* Ravi change */
|
||||
#undef LUAI_USER_ALIGNMENT_T
|
||||
#define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; }
|
||||
#endif
|
||||
|
||||
#define STRCACHE_N 23
|
||||
#define STRCACHE_M 5
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
|
||||
** $Id: ltm.h,v 2.22 2016/02/26 19:20:15 roberto Exp $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $
|
||||
** $Id: lzio.h,v 1.31 2015/09/08 15:41:05 roberto Exp $
|
||||
** Buffered streams
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
@ -0,0 +1,104 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2015 Dibyendu Majumdar
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
#ifndef RAVI_LLVM_H
|
||||
#define RAVI_LLVM_H
|
||||
|
||||
#ifdef USE_LLVM
|
||||
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
|
||||
#if (LLVM_VERSION_MAJOR < 3 || LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5)
|
||||
#error Unsupported LLVM version
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 5
|
||||
#define USE_ORC_JIT 1
|
||||
#else
|
||||
#define USE_ORC_JIT 0
|
||||
#endif
|
||||
|
||||
// In lua.c we include this just to get version numbers
|
||||
// We cannot have C++ headers in that case
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Analysis/Passes.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/GenericValue.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/MDBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 7
|
||||
#include "llvm/PassManager.h"
|
||||
#else
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#endif
|
||||
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
|
||||
|
||||
#if USE_ORC_JIT
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //USE_LLVM
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
These are examples using the Lua LLVM bindings.
|
||||
|
||||
``helloworld.lua``
|
||||
This illustrates creating a Lua callable C function that prints hello world.
|
||||
``fib.lua``
|
||||
This illustrates implementing a fibonacci sequence in LLVM using Lua.
|
||||
|
||||
|
@ -0,0 +1,107 @@
|
||||
-- ensure that LLVM bindings are available
|
||||
assert(llvm)
|
||||
|
||||
-- Get the LLVM context - right now this is the
|
||||
-- global context
|
||||
context = llvm.context()
|
||||
assert(ravitype(context) == "LLVMcontext")
|
||||
|
||||
-- The bindings provide a number of predefined types that
|
||||
-- are Lua specific plus some standard C types such as 'int',
|
||||
-- 'double', 'int64_t', etc.
|
||||
types = context:types()
|
||||
print 'Listing types'
|
||||
for k,v in pairs(types) do
|
||||
print('\t', k, ravitype(v))
|
||||
llvm.dump(v)
|
||||
end
|
||||
|
||||
-- ***************************************************\
|
||||
-- Test creating a struct type
|
||||
-- Just as an exercise create a struct type
|
||||
-- Initially we have an opaque struct
|
||||
gcobject = context:structtype("GCObject")
|
||||
assert(ravitype(gcobject) == "LLVMstructtype")
|
||||
|
||||
-- Create pointer to GCObject
|
||||
gcobject_p = context:pointertype(gcobject)
|
||||
assert(ravitype(gcobject_p) == "LLVMpointertype")
|
||||
|
||||
-- Add the members of the struct
|
||||
-- Following demonstrates the use of predefined Lua types
|
||||
gcobject:setbody {gcobject_p, types.lu_byte, types.lu_byte}
|
||||
|
||||
-- Display structure of gcobject
|
||||
llvm.dump(gcobject)
|
||||
|
||||
-- ****************************************************/
|
||||
|
||||
-- ****************************************************\
|
||||
-- Test building a Lua C function without writing C code!
|
||||
--
|
||||
-- Create a lua_CFunction instance
|
||||
-- At this stage the function will get a module and
|
||||
-- execution engine but no body
|
||||
myfunc = context:lua_CFunction("myfunc")
|
||||
assert(ravitype(myfunc) == "LLVMmainfunction")
|
||||
|
||||
-- Get a new IRBuilder intance
|
||||
-- this will be garbage collected by Lua
|
||||
irbuilder = context:irbuilder()
|
||||
assert(ravitype(irbuilder) == "LLVMirbuilder")
|
||||
|
||||
-- Create a basic block
|
||||
block = context:basicblock("entry")
|
||||
-- Add it to the end of the function
|
||||
myfunc:appendblock(block)
|
||||
-- Set this as the next instruction point
|
||||
irbuilder:setinsertpoint(block)
|
||||
|
||||
-----------------------------------------------
|
||||
-- Test calling a predefined extern function
|
||||
-- Get printf decl
|
||||
-----------------------------------------------
|
||||
printf = myfunc:extern("printf")
|
||||
assert(ravitype(printf) == "LLVMconstant")
|
||||
|
||||
luaL_checklstring = myfunc:extern("luaL_checklstring")
|
||||
assert(ravitype(luaL_checklstring) == "LLVMconstant")
|
||||
|
||||
hellostr = irbuilder:stringconstant("hello world!\n")
|
||||
irbuilder:call(printf, { hellostr })
|
||||
|
||||
-------------------------------------------------
|
||||
-- Test calling a random function
|
||||
-------------------------------------------------
|
||||
puts_type = context:functiontype(types.int, {types.pchar}, {vararg=false})
|
||||
assert(ravitype(puts_type) == "LLVMfunctiontype")
|
||||
|
||||
-- Declare extern puts()
|
||||
puts = myfunc:extern("puts", puts_type);
|
||||
assert(ravitype(puts) == "LLVMconstant")
|
||||
|
||||
-- Get the L parameter of myfunc
|
||||
L = myfunc:arg(1)
|
||||
|
||||
-- get the first argument as a string
|
||||
str = irbuilder:call(luaL_checklstring, {L, context:intconstant(1),
|
||||
context:nullconstant(types.psize_t)} )
|
||||
|
||||
-- Call puts
|
||||
irbuilder:call(puts, { str })
|
||||
|
||||
-- add CreateRet(0)
|
||||
inst = irbuilder:ret(context:intconstant(0))
|
||||
assert(ravitype(inst) == "LLVMinstruction")
|
||||
-- **************************************************/
|
||||
|
||||
-- what did we get?
|
||||
llvm.dump(myfunc)
|
||||
|
||||
-- JIT compile the function
|
||||
-- returns a C Closure
|
||||
runnable = myfunc:compile()
|
||||
|
||||
print('Type of compiled function is', type(runnable))
|
||||
assert(not runnable('ok\n'))
|
||||
|
@ -0,0 +1,141 @@
|
||||
-- This program demonstrates creating a
|
||||
-- recursive fibonacci calc function in LLVM
|
||||
-- Example based upon
|
||||
-- https://llvm.org/svn/llvm-project/llvm/trunk/examples/Fibonacci/fibonacci.cpp
|
||||
|
||||
|
||||
-- ensure that LLVM bindings are available
|
||||
assert(llvm)
|
||||
|
||||
|
||||
-- Generate the fibonacci function
|
||||
local function makefib(context, module, types)
|
||||
|
||||
-- The goal of this snippet is to create in the memory the LLVM module
|
||||
-- consisting of one function as follow:
|
||||
--
|
||||
-- int fib(int x) {
|
||||
-- if(x<=2) return 1;
|
||||
-- return fib(x-1)+fib(x-2);
|
||||
-- }
|
||||
--
|
||||
|
||||
-- Create the fib function and insert it into module M. This function is said
|
||||
-- to return an int and take an int parameter.
|
||||
local fibtype = context:functiontype(types.int, {types.int})
|
||||
local FibF = module:newfunction("fib", fibtype)
|
||||
|
||||
-- Get a new IRBuilder intance
|
||||
-- this will be garbage collected by Lua
|
||||
local ir = context:irbuilder()
|
||||
|
||||
-- Add a basic block to the function.
|
||||
local BB = context:basicblock("EntryBlock");
|
||||
FibF:appendblock(BB)
|
||||
ir:setinsertpoint(BB)
|
||||
|
||||
-- Get pointers to the constants.
|
||||
local One = context:intconstant(1);
|
||||
local Two = context:intconstant(2);
|
||||
|
||||
-- Get pointer to the integer argument of the add1 function...
|
||||
local ArgX = FibF:arg(1); -- Get the arg.
|
||||
|
||||
-- Create the true_block.
|
||||
local RetBB = context:basicblock("return");
|
||||
FibF:appendblock(RetBB)
|
||||
|
||||
-- Create an exit block.
|
||||
local RecurseBB = context:basicblock("recurse");
|
||||
FibF:appendblock(RecurseBB)
|
||||
|
||||
-- Create the "if (arg <= 2) goto exitbb"
|
||||
local CondInst = ir:icmpsle(ArgX, Two);
|
||||
ir:condbr(CondInst, RetBB, RecurseBB);
|
||||
|
||||
ir:setinsertpoint(RetBB)
|
||||
-- Create: ret int 1
|
||||
ir:ret(One);
|
||||
|
||||
-- create fib(x-1)
|
||||
ir:setinsertpoint(RecurseBB)
|
||||
local Sub = ir:nswsub(ArgX, One);
|
||||
local CallFibX1 = ir:call(FibF, {Sub}, {tailcall=true});
|
||||
|
||||
-- create fib(x-2)
|
||||
Sub = ir:nswsub(ArgX, Two);
|
||||
local CallFibX2 = ir:call(FibF, {Sub}, {tailcall=true});
|
||||
|
||||
-- fib(x-1)+fib(x-2)
|
||||
local Sum = ir:nswadd(CallFibX1, CallFibX2);
|
||||
|
||||
-- Create the return instruction and add it to the basic block
|
||||
ir:ret(Sum);
|
||||
|
||||
return FibF
|
||||
end
|
||||
|
||||
-- Get the LLVM context - right now this is the
|
||||
-- global context
|
||||
local context = llvm.context()
|
||||
|
||||
-- The bindings provide a number of predefined types that
|
||||
-- are Lua specific plus some standard C types such as 'int',
|
||||
-- 'double', 'int64_t', etc.
|
||||
local types = context:types()
|
||||
|
||||
-- Create a lua_CFunction instance
|
||||
-- At this stage the function will get a module and
|
||||
-- execution engine but no body
|
||||
local mainfunc = context:lua_CFunction("demofib")
|
||||
|
||||
-- Get hold of the module
|
||||
-- as we will create the fib function as an
|
||||
-- iternal function
|
||||
local module = mainfunc:module()
|
||||
|
||||
-- The actual fibonacci function is an internal
|
||||
-- function so that it is pure native function
|
||||
local fib = makefib(context, module, types)
|
||||
|
||||
-- Get a new IRBuilder
|
||||
local ir = context:irbuilder()
|
||||
|
||||
-- Our main Lua function has only one block
|
||||
local BB = context:basicblock("entry")
|
||||
mainfunc:appendblock(BB)
|
||||
ir:setinsertpoint(BB)
|
||||
|
||||
-- Declare prototypes
|
||||
local luaL_checkinteger = mainfunc:extern("luaL_checkinteger")
|
||||
local lua_pushinteger = mainfunc:extern("lua_pushinteger")
|
||||
|
||||
-- Get lua_State*
|
||||
local L = mainfunc:arg(1)
|
||||
|
||||
-- We are expecting one integer parameter
|
||||
local intparam = ir:call(luaL_checkinteger, {L, context:intconstant(1)})
|
||||
-- cast from 64 to 32 bit
|
||||
intparam = ir:truncorbitcast(intparam, types.int)
|
||||
|
||||
-- Call the fib calculator
|
||||
local result = ir:call(fib, {intparam})
|
||||
|
||||
-- Extend from 32 to 64 bit
|
||||
result = ir:zext(result, types.lua_Integer)
|
||||
|
||||
-- Push the final integer result
|
||||
ir:call(lua_pushinteger, {L, result})
|
||||
|
||||
-- Return 1
|
||||
ir:ret(context:intconstant(1))
|
||||
|
||||
---- We are done! ---
|
||||
|
||||
-- Dump the module for info
|
||||
module:dump()
|
||||
|
||||
-- compile the Lua callable function
|
||||
local runnable = mainfunc:compile()
|
||||
assert(runnable(11) == 89)
|
||||
print 'Ok'
|
@ -0,0 +1,63 @@
|
||||
-- This small demo creates a compiled function
|
||||
-- takes a string parameter and calls puts() to
|
||||
-- print this
|
||||
|
||||
-- ensure that LLVM bindings are available
|
||||
assert(llvm)
|
||||
|
||||
-- Get the LLVM context - right now this is the
|
||||
-- global context
|
||||
context = llvm.context()
|
||||
|
||||
-- The bindings provide a number of predefined types that
|
||||
-- are Lua specific plus some standard C types such as 'int',
|
||||
-- 'double', 'int64_t', etc.
|
||||
types = context:types()
|
||||
|
||||
-- Create a lua_CFunction instance
|
||||
-- At this stage the function will get a module and
|
||||
-- execution engine but no body
|
||||
myfunc = context:lua_CFunction("myfunc")
|
||||
|
||||
-- Get a new IRBuilder intance
|
||||
-- this will be garbage collected by Lua
|
||||
irbuilder = context:irbuilder()
|
||||
|
||||
-- Create a basic block
|
||||
block = context:basicblock("entry")
|
||||
-- Add it to the end of the function
|
||||
myfunc:appendblock(block)
|
||||
-- Set this as the next instruction point
|
||||
irbuilder:setinsertpoint(block)
|
||||
|
||||
-- get declaration for luaL_checklstring
|
||||
luaL_checklstring = myfunc:extern("luaL_checklstring")
|
||||
|
||||
-- Get the L parameter of myfunc
|
||||
L = myfunc:arg(1)
|
||||
|
||||
-- get the first argument as a string
|
||||
str = irbuilder:call(luaL_checklstring,
|
||||
{L, context:intconstant(1),
|
||||
context:nullconstant(types.psize_t)})
|
||||
|
||||
-- declare puts
|
||||
puts_type = context:functiontype(types.int, {types.pchar})
|
||||
puts = myfunc:extern("puts", puts_type);
|
||||
|
||||
-- Call puts
|
||||
irbuilder:call(puts, {str})
|
||||
|
||||
-- add CreateRet(0)
|
||||
irbuilder:ret(context:intconstant(0))
|
||||
-- **************************************************/
|
||||
|
||||
-- what did we get?
|
||||
llvm.dump(myfunc)
|
||||
|
||||
-- JIT compile the function
|
||||
-- returns a C Closure
|
||||
runnable = myfunc:compile()
|
||||
|
||||
assert(not runnable('hello world\n'))
|
||||
|
@ -1,61 +0,0 @@
|
||||
find_path(LUA_INCLUDE_DIR lua.h
|
||||
PATHS
|
||||
@CMAKE_INSTALL_PREFIX@/include/ravi
|
||||
)
|
||||
|
||||
find_library(LUA_LIBRARIES
|
||||
NAMES @LIBRAVI_NAME@ @LIBRAVI_NAME@.so @LIBRAVI_NAME@.dylib
|
||||
PATHS
|
||||
@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
|
||||
)
|
||||
|
||||
find_program(LUA_EXE
|
||||
NAMES ravi_s
|
||||
PATHS
|
||||
@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@
|
||||
)
|
||||
|
||||
# LUA_INCDIR - place where lua headers exist
|
||||
set(LUA_INCDIR ${LUA_INCLUDE_DIR})
|
||||
|
||||
# LIBDIR - LUA_CPATH
|
||||
if (WIN32)
|
||||
|
||||
get_filename_component(LIBDIR
|
||||
${LUA_EXE}
|
||||
DIRECTORY)
|
||||
|
||||
else()
|
||||
|
||||
get_filename_component(LIBDIR
|
||||
${LUA_LIBRARIES}
|
||||
DIRECTORY)
|
||||
|
||||
endif()
|
||||
|
||||
get_filename_component(LUA_BINDIR
|
||||
${LUA_EXE}
|
||||
DIRECTORY)
|
||||
|
||||
# LUA_LIBDIR - place where lua native libraries exist
|
||||
get_filename_component(LUA_LIBDIR
|
||||
${LUA_LIBRARIES}
|
||||
DIRECTORY
|
||||
)
|
||||
|
||||
if (NOT WIN32)
|
||||
set(LUA_LIBRARIES "${LUA_LIBRARIES};m")
|
||||
endif()
|
||||
|
||||
# LUALIB - the lua library to link against
|
||||
set(LUALIB ${LUA_LIBRARIES})
|
||||
|
||||
# LUADIR - LUA_PATH
|
||||
if (USE_LUA53)
|
||||
set(LUADIR "${LUA_LIBDIR}/../share/lua/5.3")
|
||||
else()
|
||||
set(LUADIR "${LUA_LIBDIR}/../share/lua/5.3")
|
||||
endif()
|
||||
|
||||
set(LUA "${LUA_EXE}")
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue