├── .clang-format ├── .dockerignore ├── .git-blame-ignore-revs ├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── .gitmodules ├── .vscode ├── .gitignore ├── launch.json └── tasks.json ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── ci-skipped-tests.txt ├── dl-llvm.sh ├── doc ├── advopt.txt └── basicopt.txt ├── env.sh ├── llvm ├── README.md ├── llvm.nim ├── llvm.version ├── llvm │ ├── Analysis.nim │ ├── BitReader.nim │ ├── BitWriter.nim │ ├── Comdat.nim │ ├── Core.nim │ ├── DebugInfo.nim │ ├── Error.nim │ ├── ExecutionEngine.nim │ ├── IRReader.nim │ ├── LLJIT.nim │ ├── Linker.nim │ ├── Orc.nim │ ├── OrcEE.nim │ ├── Support.nim │ ├── Target.nim │ ├── TargetMachine.nim │ ├── Transforms │ │ └── PassBuilder.nim │ └── Types.nim ├── preprocessed.nim ├── rebuild.sh └── wrapper.cc ├── make-dist-docker.sh ├── make-dist.sh ├── make-llvm.sh ├── nlvm-lib ├── nlvm_system.nim ├── nlvm_unwind.nim ├── nlvmbase-amd64-Linux.ll ├── nlvmbase-wasm32-Standalone.ll └── stdlib.nimble ├── nlvm ├── llgen.nim ├── lllink.nim ├── llplatform.nim ├── nim.cfg └── nlvm.nim ├── skipped-tests.txt └── upload.sh /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | # Might as well use llvm style since all we have is a couple of llvm wrappers 3 | BasedOnStyle: LLVM 4 | 5 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | ext/* 2 | nlvm/nlvm 3 | nlvm/nlvmr 4 | nlvm/nlvm.ll 5 | nlvm/nlvm.self.ll 6 | nlvm/nlvm.self 7 | Nim 8 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Formatted with nph v0.5.1-0-gde5cd48 2 | 8155ed21a3665d6d6a02b014d647e74fff0a3581 3 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Continuous 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-22.04 6 | steps: 7 | - name: Install deps 8 | run: | 9 | sudo add-apt-repository universe 10 | sudo apt-get update 11 | sudo apt-get install -y libcurl4-openssl-dev libsdl1.2-dev libgc-dev libncurses5-dev jq cmake ninja-build clang libfuse2 valgrind libncurses5 12 | - name: Check out repository code 13 | uses: actions/checkout@v4 14 | with: 15 | submodules: recursive 16 | - name: Set up environment 17 | run: | 18 | echo "CC=clang" >> $GITHUB_ENV 19 | echo "CXX=clang++" >> $GITHUB_ENV 20 | echo "LD=clang++" >> $GITHUB_ENV 21 | echo "LLVM_VERSION=$(cat llvm/llvm.version)" >> $GITHUB_ENV 22 | - name: Cache LLVM 23 | id: cache-llvm 24 | uses: actions/cache@v3 25 | with: 26 | path: | 27 | ext/*-${{ env.LLVM_VERSION }}.src 28 | key: llvm-${{ runner.os }}-${{ env.LLVM_VERSION }} 29 | - name: Set up llvm 30 | run: make STATIC_LLVM=1 prepare-llvm 31 | - name: Compile nim 32 | run: make STATIC_LLVM=1 prepare-nim 33 | - name: Run tests 34 | run: | 35 | cat ci-skipped-tests.txt >>skipped-tests.txt 36 | make STATIC_LLVM=1 test 37 | git checkout skipped-tests.txt # Restore for nph 38 | - name: Run self-compare 39 | run: make STATIC_LLVM=1 compare 40 | 41 | - name: Check nph formatting 42 | # Pin nph to a specific version to avoid sudden style differences. 43 | # Updating nph version should be accompanied with running the new 44 | # version 45 | run: | 46 | VERSION="v0.6.0" 47 | ARCHIVE="nph-linux_x64.tar.gz" 48 | curl -L "https://github.com/arnetheduck/nph/releases/download/${VERSION}/${ARCHIVE}" -o ${ARCHIVE} 49 | tar -xzf ${ARCHIVE} 50 | git ls-files | grep .nim$ | xargs ./nph 51 | git diff --exit-code 52 | 53 | - name: Create distribution 54 | run: bash make-dist.sh 55 | - name: Update release 56 | if: github.ref == 'refs/heads/master' 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 59 | run: | 60 | # Local copy of the following script: 61 | # wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh 62 | bash upload.sh dist/* 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | nlvm/nlvm 2 | nlvm/nlvmr 3 | nimcache 4 | *.s 5 | /nlvm/nlvm.self 6 | /nlvm/nlvm.self.ll 7 | /nlvm/nlvm.ll 8 | /testament.db 9 | *.ndb 10 | ext/ 11 | testresults 12 | badeggs.json 13 | /test.ini 14 | /test.txt 15 | testament/ 16 | tests/ 17 | *.html 18 | lib/ 19 | examples/ 20 | tools 21 | /.vscode/settings.json 22 | dist/ 23 | /megatest.nim 24 | .vscode 25 | /nlvm/nlvmr.self 26 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Nim"] 2 | path = Nim 3 | url = https://github.com/arnetheduck/Nim.git 4 | branch = nlvm 5 | -------------------------------------------------------------------------------- /.vscode/.gitignore: -------------------------------------------------------------------------------- 1 | ipch 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) nlvm.self", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceRoot}/nlvm/nlvm.self", 12 | "args": ["c", "-o:${workspaceRoot}/nlvm/nlvm.self2", "${workspaceRoot}/nlvm/nlvm"], 13 | "stopAtEntry": true, 14 | "cwd": "${workspaceFolder}", 15 | "environment": [], 16 | "externalConsole": true, 17 | "MIMode": "gdb", 18 | "setupCommands": [ 19 | { 20 | "description": "Enable pretty-printing for gdb", 21 | "text": "-enable-pretty-printing", 22 | "ignoreFailures": true 23 | } 24 | ] 25 | }, 26 | { 27 | "name": "(gdb) nlvm", 28 | "type": "cppdbg", 29 | "request": "launch", 30 | "program": "${workspaceRoot}/nlvm/nlvm", 31 | "args": ["c", "-o:${workspaceRoot}/nlvm/nlvm.self", "${workspaceRoot}/nlvm/nlvm"], 32 | "stopAtEntry": true, 33 | "cwd": "${workspaceFolder}", 34 | "environment": [], 35 | "externalConsole": true, 36 | "MIMode": "gdb", 37 | "setupCommands": [ 38 | { 39 | "description": "Enable pretty-printing for gdb", 40 | "text": "-enable-pretty-printing", 41 | "ignoreFailures": true 42 | } 43 | ] 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Build nlvm", 8 | "type": "shell", 9 | "command": "make", 10 | "group": { 11 | "kind": "build", 12 | "isDefault": true 13 | } 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 AS build 2 | 3 | ADD . /code 4 | WORKDIR /code 5 | 6 | RUN apt-get update && \ 7 | apt-get install -y rsync time git apt-utils libpcre3-dev libtinfo-dev libz-dev libssl-dev libsqlite3-dev build-essential cmake ninja-build python-minimal wget && \ 8 | rm -rf /var/lib/apt/lists/* && \ 9 | git submodule update --init && \ 10 | ./make-dist-docker.sh && \ 11 | cd / && \ 12 | rm -rf /code/ && \ 13 | apt-get remove -y git apt-utils libpcre3-dev libssl-dev libsqlite3-dev build-essential cmake ninja-build python-minimal wget 14 | 15 | # Create final image 16 | FROM ubuntu:18.04 17 | 18 | COPY --from=build /usr/bin/nlvm /usr/bin/nlvm 19 | COPY --from=build /usr/lib/ /usr/lib/ 20 | RUN apt-get update && apt-get install -y gcc && rm -rf /var/lib/apt/lists/* 21 | 22 | ENTRYPOINT ["/usr/bin/nlvm"] 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ===================================================== 2 | nlvm -- an llvm IR generator for Nim - https://github.com/arnetheduck/nlvm 3 | 4 | Copyright (C) 2016 Jacek Sieka. All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | 24 | [ MIT license: http://www.opensource.org/licenses/mit-license.php ] 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | NIMC=Nim/bin/nim 2 | 3 | NLVMC=nlvm/nlvm 4 | NLVMR=nlvm/nlvmr 5 | 6 | LLVMPATH=../ext 7 | 8 | #NIMFLAGS=--opt:speed --gc:markandsweep 9 | #NIMFLAGS=-d:release 10 | NIMFLAGS=--debuginfo --linedir:on --cc=clang 11 | 12 | NLVMFLAGS= --debuginfo --linedir:on --cc=clang 13 | 14 | LLVM_MAJ:=$(shell cat llvm/llvm.version | cut -f1 -d.) 15 | LLVM_MIN:=$(shell cat llvm/llvm.version | cut -f2 -d.) 16 | LLVM_PAT:=$(shell cat llvm/llvm.version | cut -f3 -d.) 17 | 18 | LLVM_DIR=llvm-$(LLVM_MAJ).$(LLVM_MIN).$(LLVM_PAT).src 19 | 20 | ifdef STATIC_LLVM 21 | NLVMCFLAGS=-d:staticLLVM --dynliboverrideall 22 | LLVM_DEP=ext/$(LLVM_DIR)/sta/bin/llvm-config 23 | export PATH := $(PWD)/ext/$(LLVM_DIR)/sta/bin:$(PATH) 24 | else 25 | LLVM_DEP=ext/$(LLVM_DIR)/sha/lib/libLLVM.so.$(LLVM_MAJ).$(LLVM_MIN) 26 | NLVMCFLAGS?= 27 | endif 28 | 29 | .PHONY: all 30 | all: $(NLVMC) 31 | 32 | Nim/koch: 33 | cd Nim ;\ 34 | [ -d csources_v2 ] || git clone -q --depth 1 -b master https://github.com/nim-lang/csources_v2.git ;\ 35 | cd csources_v2 ;\ 36 | git pull ;\ 37 | $(MAKE) -f makefile 38 | cd Nim ; bin/nim c koch 39 | 40 | $(NIMC): Nim/koch Nim/compiler/*.nim 41 | cd Nim && ./koch boot -d:release 42 | 43 | $(NLVMC): $(LLVM_DEP) $(NIMC) Nim/compiler/*.nim nlvm/*.nim llvm/*.nim nlvm-lib/*.nim 44 | cd nlvm && time ../$(NIMC) $(NIMFLAGS) $(NLVMCFLAGS) c nlvm 45 | 46 | $(NLVMR): $(LLVM_DEP) $(NIMC) Nim/compiler/*.nim nlvm/*.nim llvm/*.nim nlvm-lib/*.nim 47 | cd nlvm && time ../$(NIMC) $(NIMFLAGS) -d:release $(NLVMCFLAGS) -o:nlvmr c nlvm 48 | 49 | nlvm/nlvm.ll: $(NLVMC) nlvm/*.nim llvm/*.nim nlvm-lib/*.nim 50 | cd nlvm && time ./nlvm $(NLVMFLAGS) -o:nlvm.ll $(NLVMCFLAGS) -c c nlvm 51 | 52 | nlvm/nlvm.self: $(NLVMC) 53 | cd nlvm && time ./nlvm -o:nlvm.self $(NLVMFLAGS) $(NLVMCFLAGS) c nlvm 54 | 55 | nlvm/nlvmr.self: $(NLVMR) 56 | cd nlvm && time ./nlvmr -o:nlvmr.self -d:release $(NLVMFLAGS) $(NLVMCFLAGS) c nlvm 57 | 58 | nlvm/nlvm.self.ll: nlvm/nlvm.self 59 | cd nlvm && time ./nlvm.self -c $(NLVMFLAGS) $(NLVMCFLAGS) -o:nlvm.self.ll c nlvm 60 | 61 | .PHONY: compare 62 | compare: nlvm/nlvm.self.ll nlvm/nlvm.ll 63 | diff -u nlvm/nlvm.self.ll nlvm/nlvm.ll 64 | 65 | Nim/testament/testament: $(NIMC) Nim/testament/*.nim 66 | $(NIMC) -d:release c Nim/testament/testament 67 | 68 | .PHONY: run-testament run-testament-noskip 69 | run-testament: $(NLVMR) Nim/testament/testament 70 | cd Nim; time testament/testament --megatest:off --targets:c "--nim:../nlvm/nlvmr" --skipFrom:../skipped-tests.txt all 71 | 72 | run-testament-noskip: $(NLVMR) Nim/testament/testament 73 | -cd Nim; time testament/testament --megatest:off --targets:c "--nim:../nlvm/nlvmr" all 74 | 75 | .PHONY: test 76 | test: run-testament 77 | -make stats 78 | 79 | update-skipped: run-testament-noskip 80 | # Output suitable for sticking into skipped-tests.txt 81 | -jq -r -s '([.[][]|select(.result != "reSuccess" and .result != "reDisabled")]) | .[].name' Nim/testresults/*json | sort | uniq > skipped-tests.txt 82 | make stats 83 | 84 | .PHONY: badeggs.json 85 | badeggs.json: 86 | -jq -s '[.[][]|select(.result != "reSuccess" and .result != "reDisabled" and .result != "reCodeNotFound")]' Nim/testresults/*.json > badeggs.json 87 | 88 | .PHONY: stats 89 | stats: badeggs.json 90 | -jq 'group_by(.category)|.[]|((unique_by(.category)|.[].category) + " " + (length| tostring))' badeggs.json 91 | -jq -s '. | flatten | group_by(.result) | map({(first.result): (length)}) | add' Nim/testresults/*json 92 | -jq -s '{bad: ([.[][]|select(.result != "reSuccess" and .result != "reDisabled")]) | length, ok: ([.[][]|select(.result == "reSuccess")]|length)}' Nim/testresults/*json 93 | .PHONY: t2 94 | t2: 95 | cp -r Nim/testresults tr2 96 | 97 | .PHONY: self 98 | self: nlvm/nlvm.self 99 | 100 | .PHONY: clean 101 | clean: 102 | rm -rf $(NLVMC) $(NLVMR) nlvm/nlvm.ll nlvm/nlvm.self.ll nlvm/nlvm.self Nim/testresults/ 103 | 104 | ext/$(LLVM_DIR)/sha/lib/libLLVM.so.$(LLVM_MAJ).$(LLVM_MIN): 105 | sh ./make-llvm.sh $(LLVM_MAJ) $(LLVM_MIN) $(LLVM_PAT) sha \ 106 | -DLLVM_BUILD_LLVM_DYLIB=1 \ 107 | -DLLVM_LINK_LLVM_DYLIB=1 \ 108 | -DLLVM_ENABLE_ASSERTIONS=1 \ 109 | -DLLVM_INCLUDE_TESTS=Off \ 110 | -DLLVM_INCLUDE_BENCHMARKS=Off \ 111 | -DCMAKE_BUILD_TYPE=RelWithDebInfo 112 | 113 | ext/$(LLVM_DIR)/sta/bin/llvm-config: 114 | sh ./make-llvm.sh $(LLVM_MAJ) $(LLVM_MIN) $(LLVM_PAT) sta \ 115 | -DLLVM_BUILD_LLVM_DYLIB=0 \ 116 | -DLLVM_LINK_LLVM_DYLIB=0 \ 117 | -DLLVM_ENABLE_ASSERTIONS=0 \ 118 | -DLLVM_INCLUDE_TESTS=Off \ 119 | -DLLVM_INCLUDE_BENCHMARKS=Off \ 120 | -DCMAKE_BUILD_TYPE=Release 121 | 122 | .PHONY: prepare-llvm 123 | prepare-llvm: $(LLVM_DEP) 124 | 125 | .PHONY: prepare-nim 126 | prepare-nim: $(NIMC) 127 | 128 | .PHONY: docker 129 | docker: 130 | docker build . -t nlvm --no-cache 131 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [nlvm](https://github.com/arnetheduck/nlvm) (the nim-level virtual machine?) 4 | is an [LLVM-based](http://llvm.org) compiler for the [Nim](http://nim-lang.org) 5 | programming language. 6 | 7 | From Nim's point of view, it's a backend just like C or JavaScript - from 8 | LLVM's point of view, it's a language frontend that emits IR. 9 | 10 | Questions, patches, improvement suggestions and reviews welcome. When 11 | you find bugs, feel free to fix them as well :) 12 | 13 | Fork and enjoy! 14 | 15 | Jacek Sieka (arnetheduck on gmail point com) 16 | 17 | # Features 18 | 19 | `nlvm` works as a drop-in replacement for `nim` with the following notable differences: 20 | 21 | * Fast compile times - no intermediate `C` compiler step 22 | * DWARF ("zero-cost") exception handling 23 | * High-quality `gdb`/`lldb` debug information with source stepping, type 24 | information etc 25 | * Smart code generation and optimisation 26 | * LTO and whole-program optimisation out-of-the-box 27 | * compiler-intrinsic guided optimisation for overflow checking, memory operations, exception handling 28 | * heap allocation elision 29 | * native constant initialization 30 | * Native `wasm32` support with no extra tooling 31 | * Native integrated fast linker (`lld`) 32 | * Just-in-time execution and REPL (`nlvm r`) using the LLVM [ORCv2 JIT](https://llvm.org/docs/ORCv2.html) 33 | 34 | Most things from `nim` work just fine (see the [porting guide](#porting-guide) below!): 35 | 36 | * the same standard library is used 37 | * similar command line options are supported (just change `nim` to `nlvm`!) 38 | * `C` header files are not used - the declaration in the `.nim` file needs to be accurate 39 | 40 | Test coverage is not too bad either: 41 | 42 | * bootstrapping and compiling itself 43 | * ~95% of all upstream tests - most failures can be traced to 44 | the standard library and compiler relying on C implementation details - see 45 | [skipped-tests.txt](skipped-tests.txt) for an updated list of issues 46 | * compiling most applications 47 | * platforms: linux/x86_64, wasm32 (pre-alpha!) 48 | * majority of the nim standard library (the rest can be fixed easily - 49 | requires upstream changes however) 50 | 51 | How you could contribute: 52 | 53 | * work on making [skipped-tests.txt](skipped-tests.txt) smaller 54 | * improve platform support (`osx` and `windows` should be easy, `arm` would be 55 | nice) 56 | * help `nlvm` generate better IR - optimizations, builtins, exception handling.. 57 | * help upstream make std library smaller and more `nlvm`-compatible 58 | * send me success stories :) 59 | * leave the computer for a bit and do something real for your fellow earthlings 60 | 61 | `nlvm` does _not_: 62 | 63 | * understand `C` - as a consequence, `header`, `emit` and similar pragmas 64 | will not work - neither will the fancy `importcpp`/`C++` features - see the [porting guide](#porting-guide) below! 65 | * support all nim compiler flags and features - do file bugs for anything 66 | useful that's missing 67 | 68 | # Compile instructions 69 | 70 | To do what I do, you will need: 71 | * Linux 72 | * A C/C++ compiler (ironically, I happen to use `gcc` most of the time) 73 | 74 | Start with a clone: 75 | 76 | cd $SRC 77 | git clone https://github.com/arnetheduck/nlvm.git 78 | cd nlvm && git submodule update --init 79 | 80 | We will need a few development libraries installed, mainly due to how `nlvm` 81 | processes library dependencies (see dynlib section below): 82 | 83 | # Fedora 84 | sudo dnf install pcre-devel openssl-devel sqlite-devel ninja-build cmake 85 | 86 | # Debian, ubuntu etc 87 | sudo apt-get install libpcre3-dev libssl-dev libsqlite3-dev ninja-build cmake 88 | 89 | Compile `nlvm` (if needed, this will also build `nim` and `llvm`): 90 | 91 | make 92 | 93 | Compile with itself and compare: 94 | 95 | make compare 96 | 97 | Run test suite: 98 | 99 | make test 100 | make stats 101 | 102 | You can link statically to LLVM to create a stand-alone binary - this will 103 | use a more optimized version of LLVM as well, but takes longer to build: 104 | 105 | make STATIC_LLVM=1 106 | 107 | If you want a faster `nlvm`, you can also try the release build - it will be 108 | called `nlvmr`: 109 | 110 | make STATIC_LLVM=1 nlvmr 111 | 112 | When you update `nlvm` from `git`, don't forget the submodule: 113 | 114 | git pull && git submodule update 115 | 116 | To build a docker image, use: 117 | 118 | make docker 119 | 120 | To run built `nlvm` docker image use: 121 | 122 | docker run -v $(pwd):/code/ nlvm c -r /code/test.nim 123 | 124 | # Compiling your code 125 | 126 | On the command line, `nlvm` is mostly compatible with `nim`. 127 | 128 | When compiling, `nlvm` will generate a single `.o` file with all code from your 129 | project and link it using `$CC` - this helps it pick the right flags for 130 | linking with the C library. 131 | 132 | cd $SRC/nlvm/Nim/examples 133 | ../../nlvm/nlvm c fizzbuzz 134 | 135 | If you want to see the generated LLVM IR, use the `-c` option: 136 | 137 | cd $SRC/nlvm/Nim/examples 138 | ../../nlvm/nlvm c -c fizzbuzz 139 | less fizzbuzz.ll 140 | 141 | You can then run the LLVM optimizer on it: 142 | 143 | opt -Os fizzbuzz.ll | llvm-dis 144 | 145 | ... or compile it to assembly (`.s`): 146 | 147 | llc fizzbuzz.ll 148 | less fizzbuzz.s 149 | 150 | Apart from the code of your `.nim` files, the compiler will also mix in the 151 | compatibility found library in `nlvm-lib/`. 152 | 153 | ## Pipeline 154 | 155 | Generally, the `nim` compiler pipeline looks something like this: 156 | 157 | nim --> c files --> IR --> object files --> linker --> executable 158 | 159 | In `nlvm`, we remove one step and bunch all the code together: 160 | 161 | nim --> single IR file --> built-in LTO linker --> executable 162 | 163 | Going straight to the IR means it's possible to express nim constructs more 164 | clearly, allowing `llvm` to understand the code better and thus do a better 165 | job at optimization. It also helps keep compile times down, because the 166 | `c-to-IR` step can be avoided. 167 | 168 | The practical effect of generating a single object file is similar to 169 | `clang -fwhole-program -flto` - it is a bit more expensive in terms of memory, 170 | but results in slightly smaller and faster binaries. Notably, the 171 | `IR-to-machine-code` step, including any optimizations, is repeated in full for 172 | each recompile. 173 | 174 | ## Porting guide 175 | 176 | ### dynlib 177 | 178 | `nim` uses a runtime dynamic library loading scheme to gain access to shared 179 | libraries. When compiling, no linking is done - instead, when running your 180 | application, `nim` will try to open anything the user has installed. 181 | 182 | `nlvm` does not support the `{.dynlib.}` pragma - instead you can use 183 | `{.passL.}` using normal system linking. 184 | 185 | ```nim 186 | # works with `nim` 187 | proc f() {. importc, dynlib: "mylib" .} 188 | 189 | # works with both `nim` and `nlvm` 190 | {.passL: "-lmylib".} 191 | proc f() {. importc .} 192 | ``` 193 | 194 | ### {.header.} 195 | 196 | When `nim` compiles code, it will generate `c` code which may include other 197 | `c` code, from headers or directly via `emit` statements. This means `nim` has 198 | direct access to symbols declared in the `c` file, which can be both a feature 199 | and a problem. 200 | 201 | In `nlvm`, `{.header.}` directives are ignored - `nlvm` looks strictly at 202 | the signature of the declaration, meaning the declaration must _exactly_ match 203 | the `c` header file or subtly ABI issues and crashes ensue! 204 | 205 | ```nim 206 | 207 | # When `nim` encounters this, it will emit `jmp_buf` in the `c` code without 208 | # knowing the true size of the type, letting the `c` compiler determine it 209 | # instead. 210 | type C_JmpBuf {.importc: "jmp_buf", header: "".} = object 211 | 212 | # nlvm instead ignores the `header` directive completely and will use the 213 | # declaration as written. Failure to correctly declare the type will result 214 | # in crashes and subtle bugs - memory will be overwritten or fields will be 215 | # read from the wrong offsets. 216 | # 217 | # The following works with both `nim` and `nlvm`, but requires you to be 218 | # careful to match the binary size and layout exactly (note how `bycopy` 219 | # sometimes help to further nail down the ABI): 220 | 221 | when defined(linux) and defined(amd64): 222 | type 223 | C_JmpBuf {.importc: "jmp_buf", bycopy.} = object 224 | abi: array[200 div sizeof(clong), clong] 225 | 226 | # In `nim`, `C` constant defines are often imported using the following trick, 227 | # which makes `nim` emit the right `C` code that the value from the header 228 | # can be read (no writing of course, even though it's a `var`!) 229 | # 230 | # assuming a c header with: `#define RTLD_NOW 2` 231 | # works for nim: 232 | var RTLD_NOW* {.importc: "RTLD_NOW", header: "".}: cint 233 | 234 | # both nlvm and nim (note how these values often can be platform-specific): 235 | when defined(linux) and defined(amd64): 236 | const RTLD_NOW* = cint(2) 237 | ``` 238 | 239 | ### {.emit.} 240 | To deal with `emit`, the recommendation is to put the emitted code in a C file 241 | and `{.compile.}` it. 242 | 243 | ```nim 244 | proc myEmittedFunction() {.importc.} 245 | {.compile: "myemits.c".} 246 | ``` 247 | 248 | ```c 249 | void myEmittedFunction() { 250 | /* ... */ 251 | } 252 | ``` 253 | 254 | ### {.asm.} 255 | 256 | Similar to `{.emit.}`, `{.asm.}` functions must be moved to a separate file and 257 | included in the compilation with `{.compile.}` - this works both with `.S` and 258 | `.c` files. 259 | 260 | ### wasm32 support 261 | 262 | Use `--cpu:wasm32 --os:standalone --gc:none` to compile Nim to (barebones) WASM. 263 | 264 | You will need to provide a runtime (ie WASI) and use manual memory allocation as 265 | the garbage collector hasn't yet been ported to WASM and the Nim standard 266 | library lacks WASM / WASI support. 267 | 268 | To compile wasm files, you will thus need a `panicoverride.nim` - a minimal 269 | example looks like this and discards any errors: 270 | 271 | ```nim 272 | # panicoverride.nim 273 | proc rawoutput(s: string) = discard 274 | proc panic(s: string) {.noreturn.} = discard 275 | ``` 276 | 277 | After placing the above code in your project folder, you can compile `.nim` 278 | code to `wasm32`: 279 | 280 | ```nim 281 | # myfile.nim 282 | proc adder*(v: int): int {.exportc.} = 283 | v + 4 284 | ``` 285 | 286 | ```sh 287 | nlvm c --cpu:wasm32 --os:standalone --gc:none --passl:--no-entry myfile.nim 288 | wasm2wat -l myfile.wasm 289 | ``` 290 | 291 | Most WASM-compile code ends up needing WASM [extensions](https://webassembly.org/roadmap/) - 292 | in particular, the bulk memory extension is needed to process data. 293 | 294 | Extensions are enabled by passing `--passc:-mattr=+feature,+feature2`, for example: 295 | 296 | ```sh 297 | nlvm c --cpu:wasm32 --os:standalone --gc:none --passl:--no-entry --passc:-mattr=+bulk-memory 298 | ``` 299 | 300 | Passing `--passc:-mattr=help` will print available features (only works while compiling, for now!) 301 | 302 | To use functions from the environment (with `importc`), compile with `--passl:-Wl,--allow-undefined`. 303 | 304 | # REPL / running your code 305 | 306 | `nlvm` supports directly running Nim code using just-in-time compilation: 307 | 308 | ```sh 309 | # Compile and run `myfile.nim` without creating a binary first 310 | nlvm r myfile.nim 311 | ``` 312 | 313 | This mode can also be used to run code directly from the standard input: 314 | 315 | ```sh 316 | $ nlvm r 317 | ....................................................... 318 | >>> log2(100.0) 319 | stdin(1, 1) Error: undeclared identifier: 'log2' 320 | candidates (edit distance, scope distance); see '--spellSuggest': 321 | (2, 2): 'low' [proc declared in /home/arnetheduck/src/nlvm/Nim/lib/system.nim(1595, 6)] 322 | ... 323 | >>> import math 324 | ..... 325 | >>> log2(100.0) 326 | 6.643856189774724: float64 327 | ``` 328 | 329 | # Random notes 330 | 331 | * Upstream is pinned using a submodule - nlvm relies heavily on internals 332 | that keep changing - it's unlikely that it works with any other versions, 333 | patches welcome to update it 334 | * The nim standard library likes to import C headers directly which works 335 | because the upstream nim compiler uses a C compiler underneath - ergo, 336 | large parts of the standard library don't work with nlvm. 337 | * Happy to take patches for anything, including better platform support! 338 | * For development, it's convenient to build LLVM with assertions turned on - 339 | the API is pretty unforgiving 340 | * When I started on this little project, I knew neither llvm nor Nim. 341 | Therefore, I'd specially like to thank the friendly folks at the #nim 342 | channel that never seemed to tire of my nooby questions. 343 | Also, thanks to all tutorial writers out there, on llvm, programming 344 | and other topics for providing such fine sources of copy-pa... er, 345 | inspiration! 346 | -------------------------------------------------------------------------------- /ci-skipped-tests.txt: -------------------------------------------------------------------------------- 1 | # urandom doesn't work in github actions 2 | tests/stdlib/trandom.nim c 3 | tests/stdlib/ttempfiles.nim c 4 | tests/stdlib/tsysrand.nim c --experimental:vmopsDanger 5 | -------------------------------------------------------------------------------- /dl-llvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ $# -ge 4 ] || { 4 | echo "$0 major minor patch output_dir" 5 | exit 1 6 | } 7 | 8 | set -e 9 | 10 | mkdir -p ext 11 | cd ext 12 | 13 | VER="$1.$2" 14 | VER2="$VER.$3" 15 | TGT="$4" 16 | SUFFIX="x86_64-linux-gnu-ubuntu-18.04" 17 | SUFFIX2="" 18 | 19 | LLVM_ROOT=llvm-$VER2.src 20 | 21 | [ -f clang+llvm-$VER2-$SUFFIX/bin/llvm-config ] || { 22 | 23 | [ -f clang+llvm-$VER2-$SUFFIX.tar.xz ] || { 24 | wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$VER2/clang+llvm-$VER2-$SUFFIX$SUFFIX2.tar.xz 25 | } 26 | 27 | tar xvf clang+llvm-$VER2-$SUFFIX$SUFFIX2.tar.xz 28 | } 29 | 30 | mkdir -p $LLVM_ROOT/ 31 | rm -rf $LLVM_ROOT/$TGT 32 | cd $LLVM_ROOT 33 | ln -s ../clang+llvm-$VER2-$SUFFIX $TGT 34 | cd .. 35 | 36 | -------------------------------------------------------------------------------- /doc/advopt.txt: -------------------------------------------------------------------------------- 1 | Advanced commands: 2 | //run run the project 3 | //dump dump all defined conditionals and search paths 4 | see also: --dump.format:json (useful with: ` | jq`) 5 | 6 | Runtime checks (see -x): 7 | 8 | --objChecks:on|off turn obj conversion checks on|off 9 | --fieldChecks:on|off turn case variant field checks on|off 10 | --rangeChecks:on|off turn range checks on|off 11 | --boundChecks:on|off turn bound checks on|off 12 | --overflowChecks:on|off turn int over-/underflow checks on|off 13 | --floatChecks:on|off turn all floating point (NaN/Inf) checks on|off 14 | --nanChecks:on|off turn NaN checks on|off 15 | --infChecks:on|off turn Inf checks on|off 16 | --nilChecks:on|off turn nil checks on|off 17 | 18 | Advanced options: 19 | -o:FILE, --out:FILE set the output filename 20 | --stdout:on|off output to stdout 21 | --colors:on|off turn compiler messages coloring on|off 22 | --listFullPaths:on|off list full paths in messages 23 | -w:on|off|list, --warnings:on|off|list 24 | turn all warnings on|off or list all available 25 | --warning[X]:on|off turn specific warning X on|off 26 | --hints:on|off|list turn all hints on|off or list all available 27 | --hint[X]:on|off turn specific hint X on|off 28 | --styleCheck:off|hint|error 29 | produce hints or errors for Nim identifiers that 30 | do not adhere to Nim's official style guide 31 | https://nim-lang.org/docs/nep1.html 32 | --showAllMismatches:on|off 33 | show all mismatching candidates in overloading 34 | resolution 35 | --lib:PATH set the system library path 36 | --import:PATH add an automatically imported module 37 | --include:PATH add an automatically included module 38 | --nimcache:PATH set the path used for generated files 39 | --header:FILE the compiler should produce a .h file (FILE 40 | is optional) 41 | -c, --compileOnly:on|off compile Nim files only; do not assemble or link 42 | --noLinking:on|off compile Nim and generated files but do not link 43 | --noMain:on|off do not generate a main procedure 44 | --genScript:on|off generate a compile script (in the 'nimcache' 45 | subdirectory named 'compile_$$project$$scriptext'), 46 | implies --compileOnly 47 | --genDeps:on|off generate a '.deps' file containing the dependencies 48 | --os:SYMBOL set the target operating system (cross-compilation) 49 | --cpu:SYMBOL set the target processor (cross-compilation) 50 | --debuginfo:on|off enables debug information 51 | -t, --passC:OPTION pass an option to the C compiler 52 | -l, --passL:OPTION pass an option to the linker 53 | --cincludes:DIR modify the C compiler header search path 54 | --clibdir:DIR modify the linker library search path 55 | --clib:LIBNAME link an additional C library 56 | (you should omit platform-specific extensions) 57 | --project document the whole project (doc2) 58 | --docSeeSrcUrl:url activate 'see source' for doc and doc2 commands 59 | (see doc.item.seesrc in config/nimdoc.cfg) 60 | --docInternal also generate documentation for non-exported symbols 61 | --lineDir:on|off generation of #line directive on|off 62 | --embedsrc:on|off embeds the original source code as comments 63 | in the generated output 64 | --threadanalysis:on|off turn thread analysis on|off 65 | --tlsEmulation:on|off turn thread local storage emulation on|off 66 | --taintMode:on|off turn taint mode on|off 67 | --implicitStatic:on|off turn implicit compile time evaluation on|off 68 | --patterns:on|off turn pattern matching on|off 69 | --memTracker:on|off turn memory tracker on|off 70 | --hotCodeReloading:on|off 71 | turn support for hot code reloading on|off 72 | --excessiveStackTrace:on|off 73 | stack traces use full file paths 74 | --oldNewlines:on|off turn on|off the old behaviour of "\n" 75 | --laxStrings:on|off when turned on, accessing the zero terminator in 76 | strings is allowed; only for backwards compatibility 77 | --nilseqs:on|off allow 'nil' for strings/seqs for 78 | backwards compatibility 79 | --oldast:on|off use old AST for backwards compatibility 80 | --skipCfg:on|off do not read the nim installation's configuration file 81 | --skipUserCfg:on|off do not read the user's configuration file 82 | --skipParentCfg:on|off do not read the parent dirs' configuration files 83 | --skipProjCfg:on|off do not read the project's configuration file 84 | --gc:refc|markAndSweep|boehm|go|none|regions 85 | select the GC to use; default is 'refc' 86 | --index:on|off turn index file generation on|off 87 | --putenv:key=value set an environment variable 88 | --NimblePath:PATH add a path for Nimble support 89 | --noNimblePath deactivate the Nimble path 90 | --noCppExceptions use default exception handling with C++ backend 91 | --cppCompileToNamespace:namespace 92 | use the provided namespace for the generated C++ code, 93 | if no namespace is provided "Nim" will be used 94 | --excludePath:PATH exclude a path from the list of search paths 95 | --dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL 96 | has no effect and can be statically linked instead; 97 | symbol matching is fuzzy so 98 | that --dynlibOverride:lua matches 99 | dynlib: "liblua.so.3" 100 | --dynlibOverrideAll 101 | disables the effects of the dynlib pragma 102 | --listCmd list the commands used to execute external programs 103 | --parallelBuild:0|1|... perform a parallel build 104 | value = number of processors (0 for auto-detect) 105 | --incremental:on|off only recompile the changed modules (experimental!) 106 | --verbosity:0|1|2|3 set Nim's verbosity level (1 is default) 107 | --errorMax:N stop compilation after N errors; 0 means unlimited 108 | --experimental:$1 109 | enable experimental language feature 110 | -v, --version show detailed version information 111 | --profiler:on|off Enable profiling; requires `import nimprof`, and 112 | works better with `--stackTrace:on` 113 | see also https://nim-lang.github.io/Nim/estp.html 114 | -------------------------------------------------------------------------------- /doc/basicopt.txt: -------------------------------------------------------------------------------- 1 | :: 2 | 3 | nlvm command [options] [projectfile] [arguments] 4 | 5 | Command: 6 | //compile, c compile project 7 | 8 | Arguments: 9 | arguments are passed to the program being run (if --run option is selected) 10 | 11 | nlvm specific options: 12 | --nlvm.target:triple use a specific target triple, for example 13 | arm-linux-gnueabihf or wasm32-unknown-unknown - 14 | this will override --os: and --cpu:! 15 | --llvm- pass opt to the llvm command line parser - see 16 | --llvm-help for available options 17 | 18 | Options: 19 | -p, --path:PATH add path to search paths 20 | -d, --define:SYMBOL(:VAL) 21 | define a conditional symbol 22 | (Optionally: Define the value for that symbol, 23 | see: "compile time define pragmas") 24 | -u, --undef:SYMBOL undefine a conditional symbol 25 | --threads:on|off turn support for multi-threading on|off 26 | -x, --checks:on|off turn all runtime checks on|off 27 | -a, --assertions:on|off turn assertions on|off 28 | --opt:none|speed|size optimize not at all or for speed|size 29 | Note: use -d:release for a release build! 30 | --debugger:native|endb use native debugger (gdb) | ENDB (experimental) 31 | --app:console|gui|lib|staticlib 32 | generate a console app|GUI app|DLL|static library 33 | -r, --run run the compiled program with given arguments 34 | --fullhelp show all command line switches 35 | -h, --help show this help 36 | 37 | Note, single letter options that take an argument require a colon. E.g. -p:PATH. 38 | -------------------------------------------------------------------------------- /env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/env bash 2 | 3 | REL_PATH="$(dirname ${BASH_SOURCE[0]:-${(%):-%x}})" 4 | ABS_PATH="$(cd ${REL_PATH}; pwd)" 5 | 6 | export PATH="$ABS_PATH/Nim/bin:$ABS_PATH/ext/llvm-$(cat $ABS_PATH/llvm/llvm.version).src/sha/bin:$PATH" 7 | 8 | if [[ $# == 1 && $1 == "bash" ]]; then 9 | # the only way to change PS1 in a child shell, apparently 10 | # (we're not getting the original PS1 value in here, so set a complete and nice prompt) 11 | export PS1="[Nimbus env] \[\033[0;31m\]\l \[\033[1;33m\]\d \[\033[1;36m\]\t \[\033[0;32m\]|\w|\[\033[0m\]\n\u\$ " 12 | exec "$1" --login --noprofile 13 | else 14 | # can't use "exec" here if we're getting function names as params 15 | "$@" 16 | fi 17 | 18 | -------------------------------------------------------------------------------- /llvm/README.md: -------------------------------------------------------------------------------- 1 | LLVM wrappers for the llvm-c interfaces to llvm. 2 | 3 | Generated using c2nim 4 | 5 | Structure: 6 | 7 | llvm/ - c2nim-generated interface files 8 | llvm.nim - helpers to make the generated files easier to use 9 | rebuild.sh - helper to regenerate wrappers 10 | -------------------------------------------------------------------------------- /llvm/llvm.nim: -------------------------------------------------------------------------------- 1 | # nlvm - llvm IR generator for Nim 2 | # Copyright (c) Jacek Sieka 2016 3 | # See the LICENSE file for license info (doh!) 4 | 5 | import std/[os, strformat, strutils] 6 | 7 | const 8 | LLVMVersion* = staticRead(currentSourcePath.parentDir & "/llvm.version") 9 | LLVMMaj* = parseInt(LLVMVersion.split('.')[0]) 10 | LLVMMin* = parseInt(LLVMVersion.split('.')[1]) 11 | LLVMPat* = parseInt(LLVMVersion.split('.')[2]) 12 | LLVMLib = "" #fmt"libLLVM-{LLVMMaj}.so" 13 | LLVMRoot = fmt"../ext/llvm-{LLVMVersion}.src/" 14 | LLDRoot = fmt"../ext/lld-{LLVMVersion}.src/" 15 | 16 | {.passL: "-llldELF".} 17 | {.passL: "-llldWasm".} 18 | {.passL: "-llldMinGW".} 19 | {.passL: "-llldCommon".} 20 | {.passL: "-lz".} 21 | {.passL: "-lzstd".} 22 | 23 | when defined(staticLLVM): 24 | const LLVMOut = LLVMRoot & "sta/" 25 | 26 | {.passL: gorge(LLVMRoot & "sta/bin/llvm-config --libs all").} 27 | else: 28 | const LLVMOut = LLVMRoot & "sha/" 29 | 30 | {.passL: fmt"-lLLVM".} 31 | {.passL: "-Wl,'-rpath=$ORIGIN/" & LLVMOut & "lib/'".} 32 | 33 | {.passC: "-I" & LLVMOut & "include".} 34 | {.passC: "-I" & LLVMRoot & "include".} 35 | 36 | {.passC: "-I" & LLDRoot & "include".} 37 | 38 | {.passL: "-Wl,--as-needed".} 39 | {.passL: "-Wl,--export-dynamic".} 40 | {.passL: gorge(LLVMOut & "bin/llvm-config --ldflags").} 41 | {.passL: gorge(LLVMOut & "bin/llvm-config --system-libs").} 42 | 43 | {.compile("wrapper.cc", gorge(LLVMOut & "bin/llvm-config --cxxflags")).} 44 | 45 | # Includes and helpers for generated code 46 | type OpaqueMemoryBuffer = object 47 | 48 | type 49 | # Opaque handles to various things 50 | OpaqueAttributeRef {.pure, final.} = object 51 | OpaqueContext {.pure, final.} = object 52 | OpaqueModule {.pure, final.} = object 53 | OpaqueType {.pure, final.} = object 54 | OpaqueValue {.pure, final.} = object 55 | OpaqueBasicBlock {.pure, final.} = object 56 | OpaqueBuilder {.pure, final.} = object 57 | OpaqueModuleProvider {.pure, final.} = object 58 | OpaquePassManager {.pure, final.} = object 59 | OpaqueUse {.pure, final.} = object 60 | OpaqueDiagnosticInfo {.pure, final.} = object 61 | OpaqueTargetMachine {.pure, final.} = object 62 | OpaqueMetaData {.pure, final.} = object 63 | OpaqueDIBuilder {.pure, final.} = object 64 | target {.pure, final.} = object 65 | OpaqueJITEventListener {.pure, final.} = object 66 | OpaqueNamedMDNode {.pure, final.} = object 67 | opaqueValueMetadataEntry {.pure, final.} = object 68 | comdat {.pure, final.} = object 69 | opaqueModuleFlagEntry {.pure, final.} = object 70 | OpaqueBinary {.pure, final.} = object 71 | OpaqueDbgRecord {.pure, final.} = object 72 | OpaqueError {.pure, final.} = object 73 | OpaquePassBuilderOptions {.pure, final.} = object 74 | 75 | ## Orc.nim 76 | OrcOpaqueExecutionSession {.pure, final.} = object 77 | OrcOpaqueSymbolStringPool {.pure, final.} = object 78 | OrcOpaqueJITDylib {.pure, final.} = object 79 | OrcOpaqueSymbolStringPoolEntry {.pure, final.} = object 80 | OrcOpaqueMaterializationUnit {.pure, final.} = object 81 | OrcOpaqueMaterializationResponsibility {.pure, final.} = object 82 | OrcOpaqueResourceTracker {.pure, final.} = object 83 | OrcOpaqueDefinitionGenerator {.pure, final.} = object 84 | OrcOpaqueLookupState {.pure, final.} = object 85 | OrcOpaqueThreadSafeContext {.pure, final.} = object 86 | OrcOpaqueThreadSafeModule {.pure, final.} = object 87 | OrcOpaqueJITTargetMachineBuilder {.pure, final.} = object 88 | OrcOpaqueObjectLayer {.pure, final.} = object 89 | OrcOpaqueObjectLinkingLayer {.pure, final.} = object 90 | OrcOpaqueIRTransformLayer {.pure, final.} = object 91 | OrcOpaqueObjectTransformLayer {.pure, final.} = object 92 | OrcOpaqueIndirectStubsManager {.pure, final.} = object 93 | OrcOpaqueLazyCallThroughManager {.pure, final.} = object 94 | OrcOpaqueDumpObjects {.pure, final.} = object 95 | 96 | ## ExecutionEngine.nim 97 | OpaqueGenericValue {.pure, final.} = object 98 | OpaqueExecutionEngine {.pure, final.} = object 99 | OpaqueMCJITMemoryManager {.pure, final.} = object 100 | 101 | ## LLJIT.nim 102 | OrcOpaqueLLJITBuilder {.pure, final.} = object 103 | OrcOpaqueLLJIT {.pure, final.} = object 104 | 105 | OpaqueTargetData {.pure, final.} = object 106 | OpaqueTargetLibraryInfotData {.pure, final.} = object 107 | 108 | OpaqueOperandBundle {.pure, final.} = object 109 | OpaqueTargetMachineOptions {.pure, final.} = object 110 | 111 | Opcode* {.size: sizeof(cint).} = enum 112 | Ret = 1 113 | Br = 2 114 | Switch = 3 115 | IndirectBr = 4 116 | Invoke = 5 ## removed 6 due to API changes 117 | Unreachable = 7 118 | Add = 8 119 | FAdd = 9 120 | Sub = 10 121 | FSub = 11 122 | Mul = 12 123 | FMul = 13 124 | UDiv = 14 125 | SDiv = 15 126 | FDiv = 16 127 | URem = 17 128 | SRem = 18 129 | FRem = 19 ## Logical Operators 130 | Shl = 20 131 | LShr = 21 132 | AShr = 22 133 | And = 23 134 | Or = 24 135 | Xor = 25 ## Memory Operators 136 | Alloca = 26 137 | Load = 27 138 | Store = 28 139 | GetElementPtr = 29 ## Cast Operators 140 | Trunc = 30 141 | ZExt = 31 142 | SExt = 32 143 | FPToUI = 33 144 | FPToSI = 34 145 | UIToFP = 35 146 | SIToFP = 36 147 | FPTrunc = 37 148 | FPExt = 38 149 | PtrToInt = 39 150 | IntToPtr = 40 151 | BitCast = 41 152 | ICmp = 42 153 | FCmp = 43 154 | PHI = 44 155 | Call = 45 156 | Select = 46 157 | UserOp1 = 47 158 | UserOp2 = 48 159 | VAArg = 49 160 | ExtractElement = 50 161 | InsertElement = 51 162 | ShuffleVector = 52 163 | ExtractValue = 53 164 | InsertValue = 54 165 | Fence = 55 166 | AtomicCmpXchg = 56 167 | AtomicRMW = 57 ## Exception Handling Operators 168 | Resume = 58 169 | LandingPad = 59 170 | AddrSpaceCast = 60 ## Other Operators 171 | CleanupRet = 61 172 | CatchRet = 62 173 | CatchPad = 63 174 | CleanupPad = 64 175 | CatchSwitch = 65 176 | FNeg = 66 ## Standard Binary Operators 177 | CallBr = 67 ## Standard Unary Operators 178 | Freeze = 68 ## Atomic operators 179 | 180 | ByteOrdering* {.size: sizeof(cint).} = enum 181 | BigEndian 182 | LittleEndian 183 | 184 | include llvm/Types 185 | include llvm/Support 186 | 187 | include llvm/Analysis 188 | include llvm/Comdat 189 | include llvm/Core 190 | include llvm/DebugInfo 191 | include llvm/BitReader 192 | include llvm/BitWriter 193 | include llvm/Error 194 | include llvm/IRReader 195 | include llvm/Linker 196 | include llvm/Target 197 | include llvm/TargetMachine 198 | include llvm/Transforms/PassBuilder 199 | 200 | include llvm/ExecutionEngine 201 | include llvm/Orc 202 | include llvm/OrcEE 203 | include llvm/LLJIT 204 | 205 | include preprocessed 206 | 207 | # http://www.dwarfstd.org/doc/DWARF4.pdf 208 | const 209 | DW_ATE_address* = 0x01.cuint 210 | DW_ATE_boolean* = 0x02.cuint 211 | DW_ATE_complex_float* = 0x03.cuint 212 | DW_ATE_float* = 0x04.cuint 213 | DW_ATE_signed* = 0x05.cuint 214 | DW_ATE_signed_char* = 0x06.cuint 215 | DW_ATE_unsigned* = 0x07.cuint 216 | DW_ATE_unsigned_char* = 0x08.cuint 217 | DW_ATE_imaginary_float* = 0x09.cuint 218 | DW_ATE_packed_decimal* = 0x0a.cuint 219 | DW_ATE_numeric_string* = 0x0b.cuint 220 | DW_ATE_edited* = 0x0c.cuint 221 | DW_ATE_signed_fixed* = 0x0d.cuint 222 | DW_ATE_unsigned_fixed* = 0x0e.cuint 223 | DW_ATE_decimal_float* = 0x0f.cuint 224 | DW_ATE_UTF* = 0x10.cuint 225 | DW_ATE_lo_user* = 0x80.cuint 226 | DW_ATE_hi_user* = 0xff.cuint 227 | 228 | proc getModuleDataLayout*( 229 | m: ModuleRef 230 | ): TargetDataRef {.importc: "LLVMGetModuleDataLayout", dynlib: LLVMLib.} 231 | 232 | proc typeOfX*(val: ValueRef): TypeRef {.importc: "LLVMTypeOf", dynlib: LLVMLib.} 233 | 234 | template oaAddr(v: openArray): untyped = 235 | if v.len > 0: 236 | v[0].unsafeAddr 237 | else: 238 | nil 239 | 240 | template oaLen(v: openArray): cuint = 241 | v.len.uint32 242 | 243 | template clen(v: string | seq | openArray): csize_t = 244 | v.len.csize_t 245 | 246 | proc nimAddModuleFlag*( 247 | m: ModuleRef, name: cstring, value: uint32 248 | ) {.importc: "LLVMNimAddModuleFlag".} 249 | 250 | proc dIBuilderCreateSubroutineType*( 251 | d: DIBuilderRef, file: MetadataRef, parameterTypes: openArray[MetadataRef] 252 | ): MetadataRef = 253 | dIBuilderCreateSubroutineType( 254 | d, nil, parameterTypes.oaAddr, parameterTypes.oaLen, DIFlagZero 255 | ) 256 | 257 | proc dIBuilderCreateFunction*( 258 | d: DIBuilderRef, 259 | scope: MetadataRef, 260 | name: string, 261 | linkageName: string, 262 | file: MetadataRef, 263 | lineNo: cuint, 264 | ty: MetadataRef, 265 | isLocalToUnit: bool, 266 | isDefinition: bool, 267 | scopeLine: cuint, 268 | flags: cuint, 269 | isOptimized: bool, 270 | ): MetadataRef = 271 | dIBuilderCreateFunction( 272 | d, scope, name.cstring, name.clen, linkageName.cstring, linkageName.clen, file, 273 | lineNo, ty, isLocalToUnit.Bool, isDefinition.Bool, scopeLine, flags.DIFlags, 274 | isOptimized.Bool, 275 | ) 276 | 277 | proc dIBuilderCreateBasicType*( 278 | d: DIBuilderRef, 279 | name: string, 280 | bits: uint64, 281 | encoding: cuint, 282 | flags: DIFlags = DIFlagZero, 283 | ): MetadataRef = 284 | dIBuilderCreateBasicType(d, name.cstring, name.clen, bits, encoding, flags) 285 | 286 | proc dIBuilderCreatePointerType*( 287 | d: DIBuilderRef, pointeeTy: MetadataRef, bits: uint64, align: uint32, name: string 288 | ): MetadataRef = 289 | dIBuilderCreatePointerType(d, pointeeTy, bits, align, 0, name.cstring, name.clen) 290 | 291 | proc dIBuilderCreateStructType*( 292 | d: DIBuilderRef, 293 | scope: MetadataRef, 294 | name: string, 295 | file: MetadataRef, 296 | lineNumber: cuint, 297 | sizeBits: uint64, 298 | alignBits: uint32, 299 | flags: cuint, 300 | derivedFrom: MetadataRef, 301 | elements: openArray[MetadataRef], 302 | runtimeLang: cuint, 303 | vtableHolder: MetadataRef, 304 | uniqueId: string, 305 | ): MetadataRef = 306 | dIBuilderCreateStructType( 307 | d, scope, name.cstring, name.clen, file, lineNumber, sizeBits, alignBits, 308 | flags.DIFlags, derivedFrom, elements.oaAddr, elements.oaLen, runtimeLang, 309 | vtableHolder, uniqueId.cstring, uniqueId.clen, 310 | ) 311 | 312 | proc dIBuilderCreateMemberType*( 313 | d: DIBuilderRef, 314 | scope: MetadataRef, 315 | name: string, 316 | file: MetadataRef, 317 | lineNo: cuint, 318 | sizeBits: uint64, 319 | alignBits: uint32, 320 | offsetBits: uint64, 321 | flags: cuint, 322 | ty: MetadataRef, 323 | ): MetadataRef = 324 | dIBuilderCreateMemberType( 325 | d, scope, name.cstring, name.clen, file, lineNo, sizeBits, alignBits, offsetBits, 326 | flags.DIFlags, ty, 327 | ) 328 | 329 | proc dIBuilderCreateGlobalVariableExpression*( 330 | d: DIBuilderRef, 331 | context: MetadataRef, 332 | name: string, 333 | linkageName: string, 334 | file: MetadataRef, 335 | lineNo: cuint, 336 | ty: MetadataRef, 337 | isLocalToUnit: bool, 338 | exp: MetadataRef, 339 | decl: MetadataRef, 340 | alignBits: uint32, 341 | ): MetadataRef = 342 | dIBuilderCreateGlobalVariableExpression( 343 | d, context, name.cstring, name.clen, linkageName.cstring, linkageName.clen, file, 344 | lineNo, ty, isLocalToUnit.Bool, exp, decl, alignBits, 345 | ) 346 | 347 | proc dIBuilderCreateAutoVariable*( 348 | d: DIBuilderRef, 349 | scope: MetadataRef, 350 | name: string, 351 | file: MetadataRef, 352 | lineNo: cuint, 353 | ty: MetadataRef, 354 | alwaysPreserve: bool, 355 | flags: cuint, 356 | alignBits: uint32, 357 | ): MetadataRef = 358 | dIBuilderCreateAutoVariable( 359 | d, scope, name.cstring, name.clen, file, lineNo, ty, alwaysPreserve.Bool, 360 | flags.DIFlags, alignBits, 361 | ) 362 | 363 | proc dIBuilderCreateParameterVariable*( 364 | d: DIBuilderRef, 365 | scope: MetadataRef, 366 | name: string, 367 | argNo: cuint, 368 | file: MetadataRef, 369 | lineNo: cuint, 370 | ty: MetadataRef, 371 | alwaysPreserve: bool, 372 | flags: cuint, 373 | ): MetadataRef = 374 | dIBuilderCreateParameterVariable( 375 | d, scope, name.cstring, name.clen, argNo, file, lineNo, ty, alwaysPreserve.Bool, 376 | flags.DIFlags, 377 | ) 378 | 379 | proc dIBuilderCreateArrayType*( 380 | d: DIBuilderRef, 381 | size: uint64, 382 | alignBits: uint32, 383 | ty: MetadataRef, 384 | subscripts: openArray[MetadataRef], 385 | ): MetadataRef = 386 | dIBuilderCreateArrayType(d, size, alignBits, ty, subscripts.oaAddr, subscripts.oaLen) 387 | 388 | proc dIBuilderGetOrCreateArray*( 389 | d: DIBuilderRef, p: openArray[MetadataRef] 390 | ): MetadataRef = 391 | dIBuilderGetOrCreateArray(d, p.oaAddr, p.oaLen.csize_t) 392 | 393 | proc nimDICompositeTypeSetTypeArray*( 394 | d: DIBuilderRef, compositeTy: MetadataRef, tyArray: MetadataRef 395 | ) {.importc: "LLVMNimDICompositeTypeSetTypeArray".} 396 | 397 | proc addModuleFlag*( 398 | m: ModuleRef, behavior: ModuleFlagBehavior, key: string, val: MetadataRef 399 | ) = 400 | addModuleFlag(m, behavior, key.cstring, key.clen, val) 401 | 402 | proc nimSetMetadataGlobal*( 403 | val: ValueRef, kindID: cuint, node: ValueRef 404 | ) {.importc: "LLVMNimSetMetadataGlobal".} 405 | 406 | proc nimLLDLinkElf*( 407 | argv: cstringArray, argc: csize_t 408 | ): bool {.importc: "LLVMNimLLDLinkElf".} 409 | 410 | proc nimLLDLinkElf*(args: openArray[string]): bool = 411 | let argv = allocCStringArray(args) 412 | defer: 413 | deallocCStringArray(argv) 414 | 415 | nimLLDLinkElf(argv, args.len.csize_t) 416 | 417 | proc nimLLDLinkWasm*( 418 | argv: cstringArray, argc: csize_t 419 | ): bool {.importc: "LLVMNimLLDLinkWasm".} 420 | 421 | proc nimLLDLinkWasm*(args: openArray[string]): bool = 422 | let argv = allocCStringArray(args) 423 | defer: 424 | deallocCStringArray(argv) 425 | 426 | nimLLDLinkWasm(argv, args.len.csize_t) 427 | 428 | proc nimCreateTargetMachine*( 429 | t: TargetRef, 430 | triple: cstring, 431 | level: CodeGenOptLevel, 432 | reloc: RelocMode, 433 | codeModel: CodeModel, 434 | ): TargetMachineRef {.importc: "LLVMNimCreateTargetMachine".} 435 | 436 | proc nimSetFunctionAttributes*(F: ValueRef) {.importc: "LLVMNimSetFunctionAttributes".} 437 | 438 | # A few helpers to make things more smooth 439 | 440 | proc `$`*(v: ValueRef): string = 441 | let tmp = v.printValueToString() 442 | result = $tmp 443 | disposeMessage(tmp) 444 | 445 | proc `$`*(v: TypeRef): string = 446 | let tmp = v.printTypeToString() 447 | result = $tmp 448 | disposeMessage(tmp) 449 | 450 | const 451 | False*: Bool = 0 452 | True*: Bool = 1 453 | 454 | AllocFnKindAlloc* = 0x01'u64 455 | AllocFnKindRealloc* = 0x02'u64 456 | AllocFnKindFree* = 0x04'u64 457 | AllocFnKindUninitialized* = 0x08'u64 458 | AllocFnKindZeroed* = 0x10'u64 459 | AllocFnKindAligned* = 0x20'u64 460 | 461 | template checkErr(body: untyped) = 462 | var err: cstring 463 | let e {.inject.} = cast[cstringArray](addr(err)) 464 | let res = body 465 | if res != 0: 466 | echo err 467 | quit 1 468 | 469 | proc createMemoryBufferWithContentsOfFile(file: string): MemoryBufferRef = 470 | checkErr: 471 | createMemoryBufferWithContentsOfFile(file, addr(result), e) 472 | 473 | proc parseIRInContext*(contextRef: ContextRef, file: string): ModuleRef = 474 | let mb = createMemoryBufferWithContentsOfFile(file) 475 | 476 | checkErr: 477 | parseIRInContext(contextRef, mb, addr(result), e) 478 | 479 | proc getOrInsertFunction*(m: ModuleRef, name: cstring, functionTy: TypeRef): ValueRef = 480 | result = m.getNamedFunction(name) 481 | if result == nil: 482 | result = m.addFunction(name, functionTy) 483 | 484 | iterator params*(fn: ValueRef): ValueRef = 485 | var it = fn.getFirstParam() 486 | while it != nil: 487 | yield it 488 | it = it.getNextParam() 489 | 490 | # openArray -> pointer + len 491 | template asRaw(arr: untyped, body: untyped): untyped = 492 | var s = @arr 493 | let n {.inject.} = s.len.cuint 494 | let p {.inject.} = 495 | if s.len > 0: 496 | addr(s[0]) 497 | else: 498 | nil 499 | body 500 | 501 | proc functionType*( 502 | returnType: TypeRef, paramTypes: openArray[TypeRef], isVarArg = false 503 | ): TypeRef = 504 | asRaw( 505 | paramTypes, functionType(returnType, p, n, if isVarArg: llvm.True else: llvm.False) 506 | ) 507 | 508 | proc getParamTypes*(functionTy: TypeRef): seq[TypeRef] = 509 | result = newSeq[TypeRef](functionTy.countParamTypes()) 510 | if result.len > 0: 511 | functionTy.getParamTypes(addr(result[0])) 512 | 513 | proc structTypeInContext*( 514 | c: ContextRef, elementTypes: openArray[TypeRef], packed = False 515 | ): TypeRef = 516 | asRaw(elementTypes, structTypeInContext(c, p, n, packed)) 517 | 518 | proc structSetBody*( 519 | structTy: TypeRef, elementTypes: openArray[TypeRef], packed = False 520 | ) = 521 | asRaw(elementTypes, structSetBody(structTy, p, n, packed)) 522 | 523 | proc getStructElementTypes*(structTy: TypeRef): seq[TypeRef] = 524 | result = newSeq[TypeRef](structTy.countStructElementTypes()) 525 | if result.len > 0: 526 | structTy.getStructElementTypes(addr(result[0])) 527 | 528 | proc pointerType*(elementType: TypeRef): TypeRef = 529 | pointerType(elementType, 0) 530 | 531 | proc constStringInContext*( 532 | c: ContextRef, s: string, dontNullTerminate = False 533 | ): ValueRef = 534 | constStringInContext(c, s, s.len.cuint, dontNullTerminate) 535 | 536 | proc constStructInContext*( 537 | c: ContextRef, constantVals: openArray[ValueRef], packed = False 538 | ): ValueRef = 539 | asRaw(constantVals, constStructInContext(c, p, n, packed)) 540 | 541 | proc constArray*(t: TypeRef, constantVals: openArray[ValueRef]): ValueRef = 542 | asRaw(constantVals, constArray(t, p, n)) 543 | 544 | proc constNamedStruct*(structTy: TypeRef, constantVals: openArray[ValueRef]): ValueRef = 545 | asRaw(constantVals, constNamedStruct(structTy, p, n)) 546 | 547 | proc constGEP2*( 548 | ty: TypeRef, constantVal: ValueRef, constantIndices: openArray[ValueRef] 549 | ): ValueRef = 550 | asRaw(constantIndices, constGEP2(ty, constantVal, p, n)) 551 | 552 | proc addIncoming*( 553 | phiNode: ValueRef, 554 | incomingValues: openArray[ValueRef], 555 | incomingBlocks: openArray[BasicBlockRef], 556 | ) = 557 | var s0 = @incomingValues 558 | let n0 = s0.len.cuint 559 | let p0 = 560 | if s0.len > 0: 561 | addr(s0[0]) 562 | else: 563 | nil 564 | var s1 = @incomingBlocks 565 | let p1 = 566 | if s1.len > 0: 567 | addr(s1[0]) 568 | else: 569 | nil 570 | addIncoming(phiNode, p0, p1, n0) 571 | 572 | proc buildGEP2*( 573 | b: BuilderRef, 574 | ty: TypeRef, 575 | pointer: ValueRef, 576 | indices: openArray[ValueRef], 577 | name: cstring, 578 | ): ValueRef = 579 | asRaw(indices, buildGEP2(b, ty, pointer, p, n, name)) 580 | 581 | proc buildInBoundsGEP2*( 582 | b: BuilderRef, 583 | ty: TypeRef, 584 | pointer: ValueRef, 585 | indices: openArray[ValueRef], 586 | name: cstring, 587 | ): ValueRef = 588 | asRaw(indices, buildInBoundsGEP2(b, ty, pointer, p, n, name)) 589 | 590 | proc buildCall2*( 591 | b: BuilderRef, ty: TypeRef, fn: ValueRef, args: openArray[ValueRef], name: cstring 592 | ): ValueRef = 593 | asRaw(args, buildCall2(b, ty, fn, p, n, name)) 594 | 595 | proc buildInvoke2*( 596 | b: BuilderRef, 597 | ty: TypeRef, 598 | fn: ValueRef, 599 | args: openArray[ValueRef], 600 | then: BasicBlockRef, 601 | catch: BasicBlockRef, 602 | name: cstring = "", 603 | ): ValueRef = 604 | asRaw(args, buildInvoke2(b, ty, fn, p, n, then, catch, name)) 605 | 606 | proc diBuilderCreateFile*( 607 | builder: DIBuilderRef, filename: string, directory: string 608 | ): MetadataRef = 609 | diBuilderCreateFile( 610 | builder, filename.cstring, filename.len.csize_t, directory.cstring, 611 | directory.len.csize_t, 612 | ) 613 | 614 | template getEnumAttrKind(x: untyped): untyped = 615 | getEnumAttributeKindForName(x, x.len) 616 | 617 | let 618 | attrNoReturn* = getEnumAttrKind("noreturn") 619 | attrNoInline* = getEnumAttrKind("noinline") 620 | attrNoUnwind* = getEnumAttrKind("nounwind") 621 | attrCold* = getEnumAttrKind("cold") 622 | attrAllockind* = getEnumAttrKind("allockind") 623 | attrAllocsize* = getEnumAttrKind("allocsize") 624 | attrAllocptr* = getEnumAttrKind("allocptr") 625 | attrAllocalign* = getEnumAttrKind("allocalign") 626 | attrAlign* = getEnumAttrKind("align") 627 | attrNonnull* = getEnumAttrKind("nonnull") 628 | attrNoalias* = getEnumAttrKind("noalias") 629 | 630 | proc addFuncAttribute*(f: ValueRef, v: AttributeRef) = 631 | addAttributeAtIndex(f, cast[AttributeIndex](AttributeFunctionIndex), v) 632 | 633 | proc getMDKindIDInContext*(c: ContextRef, name: string): cuint = 634 | getMDKindIDInContext(c, name.cstring, name.len.cuint) 635 | 636 | proc createStringAttribute*(c: ContextRef, k, v: string): AttributeRef = 637 | createStringAttribute(c, k.cstring, k.len.cuint, v.cstring, v.len.cuint) 638 | 639 | proc appendBasicBlockInContext*( 640 | b: BuilderRef, c: ContextRef, name: cstring 641 | ): BasicBlockRef = 642 | let 643 | pre = b.getInsertBlock() 644 | f = pre.getBasicBlockParent() 645 | appendBasicBlockInContext(c, f, name) 646 | 647 | proc normalizeTargetTriple*(s: string): string = 648 | let tmp = normalizeTargetTriple(cstring(s)) 649 | result = $tmp 650 | disposeMessage(tmp) 651 | -------------------------------------------------------------------------------- /llvm/llvm.version: -------------------------------------------------------------------------------- 1 | 19.1.0 -------------------------------------------------------------------------------- /llvm/llvm/Analysis.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/Analysis.h - Analysis Library C Interface --------*- C++ -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header declares the C interface to libLLVMAnalysis.a, which *| 11 | ## |* implements various analyses of the LLVM IR. *| 12 | ## |* *| 13 | ## |* Many exotic languages can interoperate with C code but have a harder time *| 14 | ## |* with C++ due to name mangling. So in addition to C, this interface enables *| 15 | ## |* tools written in such languages. *| 16 | ## |* *| 17 | ## \*===----------------------------------------------------------------------=== 18 | 19 | ## 20 | ## @defgroup LLVMCAnalysis Analysis 21 | ## @ingroup LLVMC 22 | ## 23 | ## @{ 24 | ## 25 | 26 | type VerifierFailureAction* {.size: sizeof(cint).} = enum 27 | AbortProcessAction ## verifier will print to stderr and abort() 28 | PrintMessageAction ## verifier will print to stderr and return 1 29 | ReturnStatusAction ## verifier will just return 1 30 | 31 | ## Verifies that a module is valid, taking the specified action if not. 32 | ## Optionally returns a human-readable description of any invalid constructs. 33 | ## OutMessage must be disposed with LLVMDisposeMessage. 34 | 35 | proc verifyModule*( 36 | m: ModuleRef, action: VerifierFailureAction, outMessage: cstringArray 37 | ): Bool {.importc: "LLVMVerifyModule", dynlib: LLVMLib.} 38 | 39 | ## Verifies that a single function is valid, taking the specified action. Useful 40 | ## for debugging. 41 | 42 | proc verifyFunction*( 43 | fn: ValueRef, action: VerifierFailureAction 44 | ): Bool {.importc: "LLVMVerifyFunction", dynlib: LLVMLib.} 45 | 46 | ## Open up a ghostview window that displays the CFG of the current function. 47 | ## Useful for debugging. 48 | 49 | proc viewFunctionCFG*(fn: ValueRef) {.importc: "LLVMViewFunctionCFG", dynlib: LLVMLib.} 50 | proc viewFunctionCFGOnly*( 51 | fn: ValueRef 52 | ) {.importc: "LLVMViewFunctionCFGOnly", dynlib: LLVMLib.} 53 | 54 | ## 55 | ## @} 56 | ## 57 | -------------------------------------------------------------------------------- /llvm/llvm/BitReader.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/BitReader.h - BitReader Library C Interface ------*- C++ -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header declares the C interface to libLLVMBitReader.a, which *| 11 | ## |* implements input of the LLVM bitcode format. *| 12 | ## |* *| 13 | ## |* Many exotic languages can interoperate with C code but have a harder time *| 14 | ## |* with C++ due to name mangling. So in addition to C, this interface enables *| 15 | ## |* tools written in such languages. *| 16 | ## |* *| 17 | ## \*===----------------------------------------------------------------------=== 18 | 19 | ## 20 | ## @defgroup LLVMCBitReader Bit Reader 21 | ## @ingroup LLVMC 22 | ## 23 | ## @{ 24 | ## 25 | ## Builds a module from the bitcode in the specified memory buffer, returning a 26 | ## reference to the module via the OutModule parameter. Returns 0 on success. 27 | ## Optionally returns a human-readable error message via OutMessage. 28 | ## 29 | ## This is deprecated. Use LLVMParseBitcode2. 30 | 31 | proc parseBitcode*( 32 | memBuf: MemoryBufferRef, outModule: ptr ModuleRef, outMessage: cstringArray 33 | ): Bool {.importc: "LLVMParseBitcode", dynlib: LLVMLib.} 34 | 35 | ## Builds a module from the bitcode in the specified memory buffer, returning a 36 | ## reference to the module via the OutModule parameter. Returns 0 on success. 37 | 38 | proc parseBitcode2*( 39 | memBuf: MemoryBufferRef, outModule: ptr ModuleRef 40 | ): Bool {.importc: "LLVMParseBitcode2", dynlib: LLVMLib.} 41 | 42 | ## This is deprecated. Use LLVMParseBitcodeInContext2. 43 | 44 | proc parseBitcodeInContext*( 45 | contextRef: ContextRef, 46 | memBuf: MemoryBufferRef, 47 | outModule: ptr ModuleRef, 48 | outMessage: cstringArray, 49 | ): Bool {.importc: "LLVMParseBitcodeInContext", dynlib: LLVMLib.} 50 | 51 | proc parseBitcodeInContext2*( 52 | contextRef: ContextRef, memBuf: MemoryBufferRef, outModule: ptr ModuleRef 53 | ): Bool {.importc: "LLVMParseBitcodeInContext2", dynlib: LLVMLib.} 54 | 55 | ## Reads a module from the specified path, returning via the OutMP parameter 56 | ## a module provider which performs lazy deserialization. Returns 0 on success. 57 | ## Optionally returns a human-readable error message via OutMessage. 58 | ## This is deprecated. Use LLVMGetBitcodeModuleInContext2. 59 | 60 | proc getBitcodeModuleInContext*( 61 | contextRef: ContextRef, 62 | memBuf: MemoryBufferRef, 63 | outM: ptr ModuleRef, 64 | outMessage: cstringArray, 65 | ): Bool {.importc: "LLVMGetBitcodeModuleInContext", dynlib: LLVMLib.} 66 | 67 | ## Reads a module from the given memory buffer, returning via the OutMP 68 | ## parameter a module provider which performs lazy deserialization. 69 | ## 70 | ## Returns 0 on success. 71 | ## 72 | ## Takes ownership of \p MemBuf if (and only if) the module was read 73 | ## successfully. 74 | 75 | proc getBitcodeModuleInContext2*( 76 | contextRef: ContextRef, memBuf: MemoryBufferRef, outM: ptr ModuleRef 77 | ): Bool {.importc: "LLVMGetBitcodeModuleInContext2", dynlib: LLVMLib.} 78 | 79 | ## This is deprecated. Use LLVMGetBitcodeModule2. 80 | 81 | proc getBitcodeModule*( 82 | memBuf: MemoryBufferRef, outM: ptr ModuleRef, outMessage: cstringArray 83 | ): Bool {.importc: "LLVMGetBitcodeModule", dynlib: LLVMLib.} 84 | 85 | proc getBitcodeModule2*( 86 | memBuf: MemoryBufferRef, outM: ptr ModuleRef 87 | ): Bool {.importc: "LLVMGetBitcodeModule2", dynlib: LLVMLib.} 88 | 89 | ## 90 | ## @} 91 | ## 92 | -------------------------------------------------------------------------------- /llvm/llvm/BitWriter.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/BitWriter.h - BitWriter Library C Interface ------*- C++ -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header declares the C interface to libLLVMBitWriter.a, which *| 11 | ## |* implements output of the LLVM bitcode format. *| 12 | ## |* *| 13 | ## |* Many exotic languages can interoperate with C code but have a harder time *| 14 | ## |* with C++ due to name mangling. So in addition to C, this interface enables *| 15 | ## |* tools written in such languages. *| 16 | ## |* *| 17 | ## \*===----------------------------------------------------------------------=== 18 | 19 | ## 20 | ## @defgroup LLVMCBitWriter Bit Writer 21 | ## @ingroup LLVMC 22 | ## 23 | ## @{ 24 | ## 25 | ## ===-- Operations on modules ---------------------------------------------=== 26 | ## Writes a module to the specified path. Returns 0 on success. 27 | 28 | proc writeBitcodeToFile*( 29 | m: ModuleRef, path: cstring 30 | ): cint {.importc: "LLVMWriteBitcodeToFile", dynlib: LLVMLib.} 31 | 32 | ## Writes a module to an open file descriptor. Returns 0 on success. 33 | 34 | proc writeBitcodeToFD*( 35 | m: ModuleRef, fd: cint, shouldClose: cint, unbuffered: cint 36 | ): cint {.importc: "LLVMWriteBitcodeToFD", dynlib: LLVMLib.} 37 | 38 | ## Deprecated for LLVMWriteBitcodeToFD. Writes a module to an open file 39 | ## descriptor. Returns 0 on success. Closes the Handle. 40 | 41 | proc writeBitcodeToFileHandle*( 42 | m: ModuleRef, handle: cint 43 | ): cint {.importc: "LLVMWriteBitcodeToFileHandle", dynlib: LLVMLib.} 44 | 45 | ## Writes a module to a new memory buffer and returns it. 46 | 47 | proc writeBitcodeToMemoryBuffer*( 48 | m: ModuleRef 49 | ): MemoryBufferRef {.importc: "LLVMWriteBitcodeToMemoryBuffer", dynlib: LLVMLib.} 50 | 51 | ## 52 | ## @} 53 | ## 54 | -------------------------------------------------------------------------------- /llvm/llvm/Comdat.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/Comdat.h - Module Comdat C Interface -------------*- C++ -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This file defines the C interface to COMDAT. *| 11 | ## |* *| 12 | ## \*===----------------------------------------------------------------------=== 13 | 14 | ## 15 | ## @defgroup LLVMCCoreComdat Comdats 16 | ## @ingroup LLVMCCore 17 | ## 18 | ## @{ 19 | ## 20 | 21 | type ComdatSelectionKind* {.size: sizeof(cint).} = enum 22 | AnyComdatSelectionKind ## < The linker may choose any COMDAT. 23 | ExactMatchComdatSelectionKind 24 | ## < The data referenced by the COMDAT must 25 | ## < be the same. 26 | LargestComdatSelectionKind 27 | ## < The linker will choose the largest 28 | ## < COMDAT. 29 | NoDeduplicateComdatSelectionKind ## < No deduplication is performed. 30 | SameSizeComdatSelectionKind 31 | ## < The data referenced by the COMDAT must be 32 | ## < the same size. 33 | 34 | ## 35 | ## Return the Comdat in the module with the specified name. It is created 36 | ## if it didn't already exist. 37 | ## 38 | ## @see llvm::Module::getOrInsertComdat() 39 | ## 40 | 41 | proc getOrInsertComdat*( 42 | m: ModuleRef, name: cstring 43 | ): ComdatRef {.importc: "LLVMGetOrInsertComdat", dynlib: LLVMLib.} 44 | 45 | ## 46 | ## Get the Comdat assigned to the given global object. 47 | ## 48 | ## @see llvm::GlobalObject::getComdat() 49 | ## 50 | 51 | proc getComdat*(v: ValueRef): ComdatRef {.importc: "LLVMGetComdat", dynlib: LLVMLib.} 52 | ## 53 | ## Assign the Comdat to the given global object. 54 | ## 55 | ## @see llvm::GlobalObject::setComdat() 56 | ## 57 | 58 | proc setComdat*(v: ValueRef, c: ComdatRef) {.importc: "LLVMSetComdat", dynlib: LLVMLib.} 59 | ## 60 | ## Get the conflict resolution selection kind for the Comdat. 61 | ## 62 | ## @see llvm::Comdat::getSelectionKind() 63 | ## 64 | 65 | proc getComdatSelectionKind*( 66 | c: ComdatRef 67 | ): ComdatSelectionKind {.importc: "LLVMGetComdatSelectionKind", dynlib: LLVMLib.} 68 | 69 | ## 70 | ## Set the conflict resolution selection kind for the Comdat. 71 | ## 72 | ## @see llvm::Comdat::setSelectionKind() 73 | ## 74 | 75 | proc setComdatSelectionKind*( 76 | c: ComdatRef, kind: ComdatSelectionKind 77 | ) {.importc: "LLVMSetComdatSelectionKind", dynlib: LLVMLib.} 78 | 79 | ## 80 | ## @} 81 | ## 82 | -------------------------------------------------------------------------------- /llvm/llvm/Error.nim: -------------------------------------------------------------------------------- 1 | ## ===------- llvm-c/Error.h - llvm::Error class C Interface -------*- C -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This file defines the C interface to LLVM's Error class. *| 11 | ## |* *| 12 | ## \*===----------------------------------------------------------------------=== 13 | 14 | ## 15 | ## @defgroup LLVMCError Error Handling 16 | ## @ingroup LLVMC 17 | ## 18 | ## @{ 19 | ## 20 | 21 | const ErrorSuccess* = 0 22 | 23 | ## 24 | ## Opaque reference to an error instance. Null serves as the 'success' value. 25 | ## 26 | 27 | type ErrorRef* = ptr OpaqueError 28 | 29 | ## 30 | ## Error type identifier. 31 | ## 32 | 33 | type ErrorTypeId* = pointer 34 | 35 | ## 36 | ## Returns the type id for the given error instance, which must be a failure 37 | ## value (i.e. non-null). 38 | ## 39 | 40 | proc getErrorTypeId*( 41 | err: ErrorRef 42 | ): ErrorTypeId {.importc: "LLVMGetErrorTypeId", dynlib: LLVMLib.} 43 | 44 | ## 45 | ## Dispose of the given error without handling it. This operation consumes the 46 | ## error, and the given LLVMErrorRef value is not usable once this call returns. 47 | ## Note: This method *only* needs to be called if the error is not being passed 48 | ## to some other consuming operation, e.g. LLVMGetErrorMessage. 49 | ## 50 | 51 | proc consumeError*(err: ErrorRef) {.importc: "LLVMConsumeError", dynlib: LLVMLib.} 52 | ## 53 | ## Returns the given string's error message. This operation consumes the error, 54 | ## and the given LLVMErrorRef value is not usable once this call returns. 55 | ## The caller is responsible for disposing of the string by calling 56 | ## LLVMDisposeErrorMessage. 57 | ## 58 | 59 | proc getErrorMessage*( 60 | err: ErrorRef 61 | ): cstring {.importc: "LLVMGetErrorMessage", dynlib: LLVMLib.} 62 | 63 | ## 64 | ## Dispose of the given error message. 65 | ## 66 | 67 | proc disposeErrorMessage*( 68 | errMsg: cstring 69 | ) {.importc: "LLVMDisposeErrorMessage", dynlib: LLVMLib.} 70 | 71 | ## 72 | ## Returns the type id for llvm StringError. 73 | ## 74 | 75 | proc getStringErrorTypeId*(): ErrorTypeId {. 76 | importc: "LLVMGetStringErrorTypeId", dynlib: LLVMLib 77 | .} 78 | 79 | ## 80 | ## Create a StringError. 81 | ## 82 | 83 | proc createStringError*( 84 | errMsg: cstring 85 | ): ErrorRef {.importc: "LLVMCreateStringError", dynlib: LLVMLib.} 86 | 87 | ## 88 | ## @} 89 | ## 90 | -------------------------------------------------------------------------------- /llvm/llvm/ExecutionEngine.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/ExecutionEngine.h - ExecutionEngine Lib C Iface --*- C++ -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header declares the C interface to libLLVMExecutionEngine.o, which *| 11 | ## |* implements various analyses of the LLVM IR. *| 12 | ## |* *| 13 | ## |* Many exotic languages can interoperate with C code but have a harder time *| 14 | ## |* with C++ due to name mangling. So in addition to C, this interface enables *| 15 | ## |* tools written in such languages. *| 16 | ## |* *| 17 | ## \*===----------------------------------------------------------------------=== 18 | 19 | ## 20 | ## @defgroup LLVMCExecutionEngine Execution Engine 21 | ## @ingroup LLVMC 22 | ## 23 | ## @{ 24 | ## 25 | 26 | proc linkInMCJIT*() {.importc: "LLVMLinkInMCJIT", dynlib: LLVMLib.} 27 | proc linkInInterpreter*() {.importc: "LLVMLinkInInterpreter", dynlib: LLVMLib.} 28 | type 29 | GenericValueRef* = ptr OpaqueGenericValue 30 | ExecutionEngineRef* = ptr OpaqueExecutionEngine 31 | MCJITMemoryManagerRef* = ptr OpaqueMCJITMemoryManager 32 | MCJITCompilerOptions* {.bycopy.} = object 33 | optLevel*: cuint 34 | codeModel*: CodeModel 35 | noFramePointerElim*: Bool 36 | enableFastISel*: Bool 37 | mcjmm*: MCJITMemoryManagerRef 38 | 39 | ## ===-- Operations on generic values --------------------------------------=== 40 | 41 | proc createGenericValueOfInt*( 42 | ty: TypeRef, n: culonglong, isSigned: Bool 43 | ): GenericValueRef {.importc: "LLVMCreateGenericValueOfInt", dynlib: LLVMLib.} 44 | 45 | proc createGenericValueOfPointer*( 46 | p: pointer 47 | ): GenericValueRef {.importc: "LLVMCreateGenericValueOfPointer", dynlib: LLVMLib.} 48 | 49 | proc createGenericValueOfFloat*( 50 | ty: TypeRef, n: cdouble 51 | ): GenericValueRef {.importc: "LLVMCreateGenericValueOfFloat", dynlib: LLVMLib.} 52 | 53 | proc genericValueIntWidth*( 54 | genValRef: GenericValueRef 55 | ): cuint {.importc: "LLVMGenericValueIntWidth", dynlib: LLVMLib.} 56 | 57 | proc genericValueToInt*( 58 | genVal: GenericValueRef, isSigned: Bool 59 | ): culonglong {.importc: "LLVMGenericValueToInt", dynlib: LLVMLib.} 60 | 61 | proc genericValueToPointer*( 62 | genVal: GenericValueRef 63 | ): pointer {.importc: "LLVMGenericValueToPointer", dynlib: LLVMLib.} 64 | 65 | proc genericValueToFloat*( 66 | tyRef: TypeRef, genVal: GenericValueRef 67 | ): cdouble {.importc: "LLVMGenericValueToFloat", dynlib: LLVMLib.} 68 | 69 | proc disposeGenericValue*( 70 | genVal: GenericValueRef 71 | ) {.importc: "LLVMDisposeGenericValue", dynlib: LLVMLib.} 72 | 73 | ## ===-- Operations on execution engines -----------------------------------=== 74 | 75 | proc createExecutionEngineForModule*( 76 | outEE: ptr ExecutionEngineRef, m: ModuleRef, outError: cstringArray 77 | ): Bool {.importc: "LLVMCreateExecutionEngineForModule", dynlib: LLVMLib.} 78 | 79 | proc createInterpreterForModule*( 80 | outInterp: ptr ExecutionEngineRef, m: ModuleRef, outError: cstringArray 81 | ): Bool {.importc: "LLVMCreateInterpreterForModule", dynlib: LLVMLib.} 82 | 83 | proc createJITCompilerForModule*( 84 | outJIT: ptr ExecutionEngineRef, m: ModuleRef, optLevel: cuint, outError: cstringArray 85 | ): Bool {.importc: "LLVMCreateJITCompilerForModule", dynlib: LLVMLib.} 86 | 87 | proc initializeMCJITCompilerOptions*( 88 | options: ptr MCJITCompilerOptions, sizeOfXOptions: csize_t 89 | ) {.importc: "LLVMInitializeMCJITCompilerOptions", dynlib: LLVMLib.} 90 | 91 | ## 92 | ## Create an MCJIT execution engine for a module, with the given options. It is 93 | ## the responsibility of the caller to ensure that all fields in Options up to 94 | ## the given SizeOfOptions are initialized. It is correct to pass a smaller 95 | ## value of SizeOfOptions that omits some fields. The canonical way of using 96 | ## this is: 97 | ## 98 | ## LLVMMCJITCompilerOptions options; 99 | ## LLVMInitializeMCJITCompilerOptions(&options, sizeof(options)); 100 | ## ... fill in those options you care about 101 | ## LLVMCreateMCJITCompilerForModule(&jit, mod, &options, sizeof(options), 102 | ## &error); 103 | ## 104 | ## Note that this is also correct, though possibly suboptimal: 105 | ## 106 | ## LLVMCreateMCJITCompilerForModule(&jit, mod, 0, 0, &error); 107 | ## 108 | 109 | proc createMCJITCompilerForModule*( 110 | outJIT: ptr ExecutionEngineRef, 111 | m: ModuleRef, 112 | options: ptr MCJITCompilerOptions, 113 | sizeOfXOptions: csize_t, 114 | outError: cstringArray, 115 | ): Bool {.importc: "LLVMCreateMCJITCompilerForModule", dynlib: LLVMLib.} 116 | 117 | proc disposeExecutionEngine*( 118 | ee: ExecutionEngineRef 119 | ) {.importc: "LLVMDisposeExecutionEngine", dynlib: LLVMLib.} 120 | 121 | proc runStaticConstructors*( 122 | ee: ExecutionEngineRef 123 | ) {.importc: "LLVMRunStaticConstructors", dynlib: LLVMLib.} 124 | 125 | proc runStaticDestructors*( 126 | ee: ExecutionEngineRef 127 | ) {.importc: "LLVMRunStaticDestructors", dynlib: LLVMLib.} 128 | 129 | proc runFunctionAsMain*( 130 | ee: ExecutionEngineRef, 131 | f: ValueRef, 132 | argC: cuint, 133 | argV: cstringArray, 134 | envP: cstringArray, 135 | ): cint {.importc: "LLVMRunFunctionAsMain", dynlib: LLVMLib.} 136 | 137 | proc runFunction*( 138 | ee: ExecutionEngineRef, f: ValueRef, numArgs: cuint, args: ptr GenericValueRef 139 | ): GenericValueRef {.importc: "LLVMRunFunction", dynlib: LLVMLib.} 140 | 141 | proc freeMachineCodeForFunction*( 142 | ee: ExecutionEngineRef, f: ValueRef 143 | ) {.importc: "LLVMFreeMachineCodeForFunction", dynlib: LLVMLib.} 144 | 145 | proc addModule*( 146 | ee: ExecutionEngineRef, m: ModuleRef 147 | ) {.importc: "LLVMAddModule", dynlib: LLVMLib.} 148 | 149 | proc removeModule*( 150 | ee: ExecutionEngineRef, m: ModuleRef, outMod: ptr ModuleRef, outError: cstringArray 151 | ): Bool {.importc: "LLVMRemoveModule", dynlib: LLVMLib.} 152 | 153 | proc findFunction*( 154 | ee: ExecutionEngineRef, name: cstring, outFn: ptr ValueRef 155 | ): Bool {.importc: "LLVMFindFunction", dynlib: LLVMLib.} 156 | 157 | proc recompileAndRelinkFunction*( 158 | ee: ExecutionEngineRef, fn: ValueRef 159 | ): pointer {.importc: "LLVMRecompileAndRelinkFunction", dynlib: LLVMLib.} 160 | 161 | proc getExecutionEngineTargetData*( 162 | ee: ExecutionEngineRef 163 | ): TargetDataRef {.importc: "LLVMGetExecutionEngineTargetData", dynlib: LLVMLib.} 164 | 165 | proc getExecutionEngineTargetMachine*( 166 | ee: ExecutionEngineRef 167 | ): TargetMachineRef {.importc: "LLVMGetExecutionEngineTargetMachine", dynlib: LLVMLib.} 168 | 169 | proc addGlobalMapping*( 170 | ee: ExecutionEngineRef, global: ValueRef, `addr`: pointer 171 | ) {.importc: "LLVMAddGlobalMapping", dynlib: LLVMLib.} 172 | 173 | proc getPointerToGlobal*( 174 | ee: ExecutionEngineRef, global: ValueRef 175 | ): pointer {.importc: "LLVMGetPointerToGlobal", dynlib: LLVMLib.} 176 | 177 | proc getGlobalValueAddress*( 178 | ee: ExecutionEngineRef, name: cstring 179 | ): uint64 {.importc: "LLVMGetGlobalValueAddress", dynlib: LLVMLib.} 180 | 181 | proc getFunctionAddress*( 182 | ee: ExecutionEngineRef, name: cstring 183 | ): uint64 {.importc: "LLVMGetFunctionAddress", dynlib: LLVMLib.} 184 | 185 | ## Returns true on error, false on success. If true is returned then the error 186 | ## message is copied to OutStr and cleared in the ExecutionEngine instance. 187 | 188 | proc executionEngineGetErrMsg*( 189 | ee: ExecutionEngineRef, outError: cstringArray 190 | ): Bool {.importc: "LLVMExecutionEngineGetErrMsg", dynlib: LLVMLib.} 191 | 192 | ## ===-- Operations on memory managers -------------------------------------=== 193 | 194 | type 195 | MemoryManagerAllocateCodeSectionCallback* = proc( 196 | opaque: pointer, 197 | size: uint, 198 | alignment: cuint, 199 | sectionID: cuint, 200 | sectionName: cstring, 201 | ): ptr uint8 202 | MemoryManagerAllocateDataSectionCallback* = proc( 203 | opaque: pointer, 204 | size: uint, 205 | alignment: cuint, 206 | sectionID: cuint, 207 | sectionName: cstring, 208 | isReadOnly: Bool, 209 | ): ptr uint8 210 | MemoryManagerFinalizeMemoryCallback* = 211 | proc(opaque: pointer, errMsg: cstringArray): Bool 212 | MemoryManagerDestroyCallback* = proc(opaque: pointer) 213 | 214 | ## 215 | ## Create a simple custom MCJIT memory manager. This memory manager can 216 | ## intercept allocations in a module-oblivious way. This will return NULL 217 | ## if any of the passed functions are NULL. 218 | ## 219 | ## @param Opaque An opaque client object to pass back to the callbacks. 220 | ## @param AllocateCodeSection Allocate a block of memory for executable code. 221 | ## @param AllocateDataSection Allocate a block of memory for data. 222 | ## @param FinalizeMemory Set page permissions and flush cache. Return 0 on 223 | ## success, 1 on error. 224 | ## 225 | 226 | proc createSimpleMCJITMemoryManager*( 227 | opaque: pointer, 228 | allocateCodeSection: MemoryManagerAllocateCodeSectionCallback, 229 | allocateDataSection: MemoryManagerAllocateDataSectionCallback, 230 | finalizeMemory: MemoryManagerFinalizeMemoryCallback, 231 | destroy: MemoryManagerDestroyCallback, 232 | ): MCJITMemoryManagerRef {. 233 | importc: "LLVMCreateSimpleMCJITMemoryManager", dynlib: LLVMLib 234 | .} 235 | 236 | proc disposeMCJITMemoryManager*( 237 | mm: MCJITMemoryManagerRef 238 | ) {.importc: "LLVMDisposeMCJITMemoryManager", dynlib: LLVMLib.} 239 | 240 | ## ===-- JIT Event Listener functions -------------------------------------=== 241 | 242 | proc createGDBRegistrationListener*(): JITEventListenerRef {. 243 | importc: "LLVMCreateGDBRegistrationListener", dynlib: LLVMLib 244 | .} 245 | 246 | proc createIntelJITEventListener*(): JITEventListenerRef {. 247 | importc: "LLVMCreateIntelJITEventListener", dynlib: LLVMLib 248 | .} 249 | 250 | proc createOProfileJITEventListener*(): JITEventListenerRef {. 251 | importc: "LLVMCreateOProfileJITEventListener", dynlib: LLVMLib 252 | .} 253 | 254 | proc createPerfJITEventListener*(): JITEventListenerRef {. 255 | importc: "LLVMCreatePerfJITEventListener", dynlib: LLVMLib 256 | .} 257 | 258 | ## 259 | ## @} 260 | ## 261 | -------------------------------------------------------------------------------- /llvm/llvm/IRReader.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/IRReader.h - IR Reader C Interface -----------------*- C -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This file defines the C interface to the IR Reader. *| 11 | ## |* *| 12 | ## \*===----------------------------------------------------------------------=== 13 | 14 | ## 15 | ## @defgroup LLVMCCoreIRReader IR Reader 16 | ## @ingroup LLVMCCore 17 | ## 18 | ## @{ 19 | ## 20 | ## 21 | ## Read LLVM IR from a memory buffer and convert it into an in-memory Module 22 | ## object. Returns 0 on success. 23 | ## Optionally returns a human-readable description of any errors that 24 | ## occurred during parsing IR. OutMessage must be disposed with 25 | ## LLVMDisposeMessage. 26 | ## 27 | ## @see llvm::ParseIR() 28 | ## 29 | 30 | proc parseIRInContext*( 31 | contextRef: ContextRef, 32 | memBuf: MemoryBufferRef, 33 | outM: ptr ModuleRef, 34 | outMessage: cstringArray, 35 | ): Bool {.importc: "LLVMParseIRInContext", dynlib: LLVMLib.} 36 | 37 | ## 38 | ## @} 39 | ## 40 | -------------------------------------------------------------------------------- /llvm/llvm/LLJIT.nim: -------------------------------------------------------------------------------- 1 | ## ===----------- llvm-c/LLJIT.h - OrcV2 LLJIT C bindings ----------*- C -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header declares the C interface to the LLJIT class in *| 11 | ## |* libLLVMOrcJIT.a, which provides a simple MCJIT-like ORC JIT. *| 12 | ## |* *| 13 | ## |* Many exotic languages can interoperate with C code but have a harder time *| 14 | ## |* with C++ due to name mangling. So in addition to C, this interface enables *| 15 | ## |* tools written in such languages. *| 16 | ## |* *| 17 | ## |* Note: This interface is experimental. It is *NOT* stable, and may be *| 18 | ## |* changed without warning. Only C API usage documentation is *| 19 | ## |* provided. See the C++ documentation for all higher level ORC API *| 20 | ## |* details. *| 21 | ## |* *| 22 | ## \*===----------------------------------------------------------------------=== 23 | 24 | ## 25 | ## @defgroup LLVMCExecutionEngineLLJIT LLJIT 26 | ## @ingroup LLVMCExecutionEngine 27 | ## 28 | ## @{ 29 | ## 30 | ## 31 | ## A function for constructing an ObjectLinkingLayer instance to be used 32 | ## by an LLJIT instance. 33 | ## 34 | ## Clients can call LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator to 35 | ## set the creator function to use when constructing an LLJIT instance. 36 | ## This can be used to override the default linking layer implementation 37 | ## that would otherwise be chosen by LLJITBuilder. 38 | ## 39 | ## Object linking layers returned by this function will become owned by the 40 | ## LLJIT instance. The client is not responsible for managing their lifetimes 41 | ## after the function returns. 42 | ## 43 | 44 | type OrcLLJITBuilderObjectLinkingLayerCreatorFunction* = 45 | proc(ctx: pointer, es: OrcExecutionSessionRef, triple: cstring): OrcObjectLayerRef 46 | 47 | ## 48 | ## A reference to an orc::LLJITBuilder instance. 49 | ## 50 | 51 | type OrcLLJITBuilderRef* = ptr OrcOpaqueLLJITBuilder 52 | 53 | ## 54 | ## A reference to an orc::LLJIT instance. 55 | ## 56 | 57 | type OrcLLJITRef* = ptr OrcOpaqueLLJIT 58 | 59 | ## 60 | ## Create an LLVMOrcLLJITBuilder. 61 | ## 62 | ## The client owns the resulting LLJITBuilder and should dispose of it using 63 | ## LLVMOrcDisposeLLJITBuilder once they are done with it. 64 | ## 65 | 66 | proc orcCreateLLJITBuilder*(): OrcLLJITBuilderRef {. 67 | importc: "LLVMOrcCreateLLJITBuilder", dynlib: LLVMLib 68 | .} 69 | 70 | ## 71 | ## Dispose of an LLVMOrcLLJITBuilderRef. This should only be called if ownership 72 | ## has not been passed to LLVMOrcCreateLLJIT (e.g. because some error prevented 73 | ## that function from being called). 74 | ## 75 | 76 | proc orcDisposeLLJITBuilder*( 77 | builder: OrcLLJITBuilderRef 78 | ) {.importc: "LLVMOrcDisposeLLJITBuilder", dynlib: LLVMLib.} 79 | 80 | ## 81 | ## Set the JITTargetMachineBuilder to be used when constructing the LLJIT 82 | ## instance. Calling this function is optional: if it is not called then the 83 | ## LLJITBuilder will use JITTargeTMachineBuilder::detectHost to construct a 84 | ## JITTargetMachineBuilder. 85 | ## 86 | ## This function takes ownership of the JTMB argument: clients should not 87 | ## dispose of the JITTargetMachineBuilder after calling this function. 88 | ## 89 | 90 | proc orcLLJITBuilderSetJITTargetMachineBuilder*( 91 | builder: OrcLLJITBuilderRef, jtmb: OrcJITTargetMachineBuilderRef 92 | ) {.importc: "LLVMOrcLLJITBuilderSetJITTargetMachineBuilder", dynlib: LLVMLib.} 93 | 94 | ## 95 | ## Set an ObjectLinkingLayer creator function for this LLJIT instance. 96 | ## 97 | 98 | proc orcLLJITBuilderSetObjectLinkingLayerCreator*( 99 | builder: OrcLLJITBuilderRef, 100 | f: OrcLLJITBuilderObjectLinkingLayerCreatorFunction, 101 | ctx: pointer, 102 | ) {.importc: "LLVMOrcLLJITBuilderSetObjectLinkingLayerCreator", dynlib: LLVMLib.} 103 | 104 | ## 105 | ## Create an LLJIT instance from an LLJITBuilder. 106 | ## 107 | ## This operation takes ownership of the Builder argument: clients should not 108 | ## dispose of the builder after calling this function (even if the function 109 | ## returns an error). If a null Builder argument is provided then a 110 | ## default-constructed LLJITBuilder will be used. 111 | ## 112 | ## On success the resulting LLJIT instance is uniquely owned by the client and 113 | ## automatically manages the memory of all JIT'd code and all modules that are 114 | ## transferred to it (e.g. via LLVMOrcLLJITAddLLVMIRModule). Disposing of the 115 | ## LLJIT instance will free all memory managed by the JIT, including JIT'd code 116 | ## and not-yet compiled modules. 117 | ## 118 | 119 | proc orcCreateLLJIT*( 120 | result: ptr OrcLLJITRef, builder: OrcLLJITBuilderRef 121 | ): ErrorRef {.importc: "LLVMOrcCreateLLJIT", dynlib: LLVMLib.} 122 | 123 | ## 124 | ## Dispose of an LLJIT instance. 125 | ## 126 | 127 | proc orcDisposeLLJIT*( 128 | j: OrcLLJITRef 129 | ): ErrorRef {.importc: "LLVMOrcDisposeLLJIT", dynlib: LLVMLib.} 130 | 131 | ## 132 | ## Get a reference to the ExecutionSession for this LLJIT instance. 133 | ## 134 | ## The ExecutionSession is owned by the LLJIT instance. The client is not 135 | ## responsible for managing its memory. 136 | ## 137 | 138 | proc orcLLJITGetExecutionSession*( 139 | j: OrcLLJITRef 140 | ): OrcExecutionSessionRef {. 141 | importc: "LLVMOrcLLJITGetExecutionSession", dynlib: LLVMLib 142 | .} 143 | 144 | ## 145 | ## Return a reference to the Main JITDylib. 146 | ## 147 | ## The JITDylib is owned by the LLJIT instance. The client is not responsible 148 | ## for managing its memory. 149 | ## 150 | 151 | proc orcLLJITGetMainJITDylib*( 152 | j: OrcLLJITRef 153 | ): OrcJITDylibRef {.importc: "LLVMOrcLLJITGetMainJITDylib", dynlib: LLVMLib.} 154 | 155 | ## 156 | ## Return the target triple for this LLJIT instance. This string is owned by 157 | ## the LLJIT instance and should not be freed by the client. 158 | ## 159 | 160 | proc orcLLJITGetTripleString*( 161 | j: OrcLLJITRef 162 | ): cstring {.importc: "LLVMOrcLLJITGetTripleString", dynlib: LLVMLib.} 163 | 164 | ## 165 | ## Returns the global prefix character according to the LLJIT's DataLayout. 166 | ## 167 | 168 | proc orcLLJITGetGlobalPrefix*( 169 | j: OrcLLJITRef 170 | ): char {.importc: "LLVMOrcLLJITGetGlobalPrefix", dynlib: LLVMLib.} 171 | 172 | ## 173 | ## Mangles the given string according to the LLJIT instance's DataLayout, then 174 | ## interns the result in the SymbolStringPool and returns a reference to the 175 | ## pool entry. Clients should call LLVMOrcReleaseSymbolStringPoolEntry to 176 | ## decrement the ref-count on the pool entry once they are finished with this 177 | ## value. 178 | ## 179 | 180 | proc orcLLJITMangleAndIntern*( 181 | j: OrcLLJITRef, unmangledName: cstring 182 | ): OrcSymbolStringPoolEntryRef {. 183 | importc: "LLVMOrcLLJITMangleAndIntern", dynlib: LLVMLib 184 | .} 185 | 186 | ## 187 | ## Add a buffer representing an object file to the given JITDylib in the given 188 | ## LLJIT instance. This operation transfers ownership of the buffer to the 189 | ## LLJIT instance. The buffer should not be disposed of or referenced once this 190 | ## function returns. 191 | ## 192 | ## Resources associated with the given object will be tracked by the given 193 | ## JITDylib's default resource tracker. 194 | ## 195 | 196 | proc orcLLJITAddObjectFile*( 197 | j: OrcLLJITRef, jd: OrcJITDylibRef, objBuffer: MemoryBufferRef 198 | ): ErrorRef {.importc: "LLVMOrcLLJITAddObjectFile", dynlib: LLVMLib.} 199 | 200 | ## 201 | ## Add a buffer representing an object file to the given ResourceTracker's 202 | ## JITDylib in the given LLJIT instance. This operation transfers ownership of 203 | ## the buffer to the LLJIT instance. The buffer should not be disposed of or 204 | ## referenced once this function returns. 205 | ## 206 | ## Resources associated with the given object will be tracked by ResourceTracker 207 | ## RT. 208 | ## 209 | 210 | proc orcLLJITAddObjectFileWithRT*( 211 | j: OrcLLJITRef, rt: OrcResourceTrackerRef, objBuffer: MemoryBufferRef 212 | ): ErrorRef {.importc: "LLVMOrcLLJITAddObjectFileWithRT", dynlib: LLVMLib.} 213 | 214 | ## 215 | ## Add an IR module to the given JITDylib in the given LLJIT instance. This 216 | ## operation transfers ownership of the TSM argument to the LLJIT instance. 217 | ## The TSM argument should not be disposed of or referenced once this 218 | ## function returns. 219 | ## 220 | ## Resources associated with the given Module will be tracked by the given 221 | ## JITDylib's default resource tracker. 222 | ## 223 | 224 | proc orcLLJITAddLLVMIRModule*( 225 | j: OrcLLJITRef, jd: OrcJITDylibRef, tsm: OrcThreadSafeModuleRef 226 | ): ErrorRef {.importc: "LLVMOrcLLJITAddLLVMIRModule", dynlib: LLVMLib.} 227 | 228 | ## 229 | ## Add an IR module to the given ResourceTracker's JITDylib in the given LLJIT 230 | ## instance. This operation transfers ownership of the TSM argument to the LLJIT 231 | ## instance. The TSM argument should not be disposed of or referenced once this 232 | ## function returns. 233 | ## 234 | ## Resources associated with the given Module will be tracked by ResourceTracker 235 | ## RT. 236 | ## 237 | 238 | proc orcLLJITAddLLVMIRModuleWithRT*( 239 | j: OrcLLJITRef, jd: OrcResourceTrackerRef, tsm: OrcThreadSafeModuleRef 240 | ): ErrorRef {.importc: "LLVMOrcLLJITAddLLVMIRModuleWithRT", dynlib: LLVMLib.} 241 | 242 | ## 243 | ## Look up the given symbol in the main JITDylib of the given LLJIT instance. 244 | ## 245 | ## This operation does not take ownership of the Name argument. 246 | ## 247 | 248 | proc orcLLJITLookup*( 249 | j: OrcLLJITRef, result: ptr OrcExecutorAddress, name: cstring 250 | ): ErrorRef {.importc: "LLVMOrcLLJITLookup", dynlib: LLVMLib.} 251 | 252 | ## 253 | ## Returns a non-owning reference to the LLJIT instance's object linking layer. 254 | ## 255 | 256 | proc orcLLJITGetObjLinkingLayer*( 257 | j: OrcLLJITRef 258 | ): OrcObjectLayerRef {.importc: "LLVMOrcLLJITGetObjLinkingLayer", dynlib: LLVMLib.} 259 | 260 | ## 261 | ## Returns a non-owning reference to the LLJIT instance's object linking layer. 262 | ## 263 | 264 | proc orcLLJITGetObjTransformLayer*( 265 | j: OrcLLJITRef 266 | ): OrcObjectTransformLayerRef {. 267 | importc: "LLVMOrcLLJITGetObjTransformLayer", dynlib: LLVMLib 268 | .} 269 | 270 | ## 271 | ## Returns a non-owning reference to the LLJIT instance's IR transform layer. 272 | ## 273 | 274 | proc orcLLJITGetIRTransformLayer*( 275 | j: OrcLLJITRef 276 | ): OrcIRTransformLayerRef {. 277 | importc: "LLVMOrcLLJITGetIRTransformLayer", dynlib: LLVMLib 278 | .} 279 | 280 | ## 281 | ## Get the LLJIT instance's default data layout string. 282 | ## 283 | ## This string is owned by the LLJIT instance and does not need to be freed 284 | ## by the caller. 285 | ## 286 | 287 | proc orcLLJITGetDataLayoutStr*( 288 | j: OrcLLJITRef 289 | ): cstring {.importc: "LLVMOrcLLJITGetDataLayoutStr", dynlib: LLVMLib.} 290 | 291 | ## 292 | ## @} 293 | ## 294 | -------------------------------------------------------------------------------- /llvm/llvm/Linker.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/Linker.h - Module Linker C Interface -------------*- C++ -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This file defines the C interface to the module/file/archive linker. *| 11 | ## |* *| 12 | ## \*===----------------------------------------------------------------------=== 13 | 14 | ## 15 | ## @defgroup LLVMCCoreLinker Linker 16 | ## @ingroup LLVMCCore 17 | ## 18 | ## @{ 19 | ## 20 | ## This enum is provided for backwards-compatibility only. It has no effect. 21 | 22 | type LinkerMode* {.size: sizeof(cint).} = enum 23 | LinkerDestroySource = 0 ## This is the default behavior. 24 | LinkerPreserveSourceRemoved = 1 25 | ## This option has been deprecated and 26 | ## should not be used. 27 | 28 | ## Links the source module into the destination module. The source module is 29 | ## destroyed. 30 | ## The return value is true if an error occurred, false otherwise. 31 | ## Use the diagnostic handler to get any diagnostic message. 32 | ## 33 | 34 | proc linkModules2*( 35 | dest: ModuleRef, src: ModuleRef 36 | ): Bool {.importc: "LLVMLinkModules2", dynlib: LLVMLib.} 37 | 38 | ## 39 | ## @} 40 | ## 41 | -------------------------------------------------------------------------------- /llvm/llvm/OrcEE.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/OrcEE.h - OrcV2 C bindings ExecutionEngine utils -*- C++ -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header declares the C interface to ExecutionEngine based utils, e.g. *| 11 | ## |* RTDyldObjectLinkingLayer (based on RuntimeDyld) in Orc. *| 12 | ## |* *| 13 | ## |* Many exotic languages can interoperate with C code but have a harder time *| 14 | ## |* with C++ due to name mangling. So in addition to C, this interface enables *| 15 | ## |* tools written in such languages. *| 16 | ## |* *| 17 | ## |* Note: This interface is experimental. It is *NOT* stable, and may be *| 18 | ## |* changed without warning. Only C API usage documentation is *| 19 | ## |* provided. See the C++ documentation for all higher level ORC API *| 20 | ## |* details. *| 21 | ## |* *| 22 | ## \*===----------------------------------------------------------------------=== 23 | 24 | type 25 | MemoryManagerCreateContextCallback* = proc(ctxCtx: pointer): pointer 26 | MemoryManagerNotifyTerminatingCallback* = proc(ctxCtx: pointer) 27 | 28 | ## 29 | ## @defgroup LLVMCExecutionEngineORCEE ExecutionEngine-based ORC Utils 30 | ## @ingroup LLVMCExecutionEngine 31 | ## 32 | ## @{ 33 | ## 34 | ## 35 | ## Create a RTDyldObjectLinkingLayer instance using the standard 36 | ## SectionMemoryManager for memory management. 37 | ## 38 | 39 | proc orcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager*( 40 | es: OrcExecutionSessionRef 41 | ): OrcObjectLayerRef {. 42 | importc: "LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager", 43 | dynlib: LLVMLib 44 | .} 45 | 46 | ## 47 | ## Create a RTDyldObjectLinkingLayer instance using MCJIT-memory-manager-like 48 | ## callbacks. 49 | ## 50 | ## This is intended to simplify transitions for existing MCJIT clients. The 51 | ## callbacks used are similar (but not identical) to the callbacks for 52 | ## LLVMCreateSimpleMCJITMemoryManager: Unlike MCJIT, RTDyldObjectLinkingLayer 53 | ## will create a new memory manager for each object linked by calling the given 54 | ## CreateContext callback. This allows for code removal by destroying each 55 | ## allocator individually. Every allocator will be destroyed (if it has not been 56 | ## already) at RTDyldObjectLinkingLayer destruction time, and the 57 | ## NotifyTerminating callback will be called to indicate that no further 58 | ## allocation contexts will be created. 59 | ## 60 | ## To implement MCJIT-like behavior clients can implement CreateContext, 61 | ## NotifyTerminating, and Destroy as: 62 | ## 63 | ## void *CreateContext(void *CtxCtx) { return CtxCtx; } 64 | ## void NotifyTerminating(void *CtxCtx) { MyOriginalDestroy(CtxCtx); } 65 | ## void Destroy(void *Ctx) { } 66 | ## 67 | ## This scheme simply reuses the CreateContextCtx pointer as the one-and-only 68 | ## allocation context. 69 | ## 70 | 71 | proc orcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks*( 72 | es: OrcExecutionSessionRef, 73 | createContextCtx: pointer, 74 | createContext: MemoryManagerCreateContextCallback, 75 | notifyTerminating: MemoryManagerNotifyTerminatingCallback, 76 | allocateCodeSection: MemoryManagerAllocateCodeSectionCallback, 77 | allocateDataSection: MemoryManagerAllocateDataSectionCallback, 78 | finalizeMemory: MemoryManagerFinalizeMemoryCallback, 79 | destroy: MemoryManagerDestroyCallback, 80 | ): OrcObjectLayerRef {. 81 | importc: "LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks", 82 | dynlib: LLVMLib 83 | .} 84 | 85 | ## 86 | ## Add the given listener to the given RTDyldObjectLinkingLayer. 87 | ## 88 | ## Note: Layer must be an RTDyldObjectLinkingLayer instance or 89 | ## behavior is undefined. 90 | ## 91 | 92 | proc orcRTDyldObjectLinkingLayerRegisterJITEventListener*( 93 | rTDyldObjLinkingLayer: OrcObjectLayerRef, listener: JITEventListenerRef 94 | ) {. 95 | importc: "LLVMOrcRTDyldObjectLinkingLayerRegisterJITEventListener", dynlib: LLVMLib 96 | .} 97 | 98 | ## 99 | ## @} 100 | ## 101 | -------------------------------------------------------------------------------- /llvm/llvm/Support.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/Support.h - Support C Interface --------------------*- C -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This file defines the C interface to the LLVM support library. *| 11 | ## |* *| 12 | ## \*===----------------------------------------------------------------------=== 13 | 14 | ## 15 | ## @addtogroup LLVMCCore 16 | ## 17 | ## @{ 18 | ## 19 | ## 20 | ## This function permanently loads the dynamic library at the given path. 21 | ## It is safe to call this function multiple times for the same library. 22 | ## 23 | ## @see sys::DynamicLibrary::LoadLibraryPermanently() 24 | ## 25 | 26 | proc loadLibraryPermanently*( 27 | filename: cstring 28 | ): Bool {.importc: "LLVMLoadLibraryPermanently", dynlib: LLVMLib.} 29 | 30 | ## 31 | ## This function parses the given arguments using the LLVM command line parser. 32 | ## Note that the only stable thing about this function is its signature; you 33 | ## cannot rely on any particular set of command line arguments being interpreted 34 | ## the same way across LLVM versions. 35 | ## 36 | ## @see llvm::cl::ParseCommandLineOptions() 37 | ## 38 | 39 | proc parseCommandLineOptions*( 40 | argc: cint, argv: cstringArray, overview: cstring 41 | ) {.importc: "LLVMParseCommandLineOptions", dynlib: LLVMLib.} 42 | 43 | ## 44 | ## This function will search through all previously loaded dynamic 45 | ## libraries for the symbol \p symbolName. If it is found, the address of 46 | ## that symbol is returned. If not, null is returned. 47 | ## 48 | ## @see sys::DynamicLibrary::SearchForAddressOfSymbol() 49 | ## 50 | 51 | proc searchForAddressOfSymbol*( 52 | symbolName: cstring 53 | ): pointer {.importc: "LLVMSearchForAddressOfSymbol", dynlib: LLVMLib.} 54 | 55 | ## 56 | ## This functions permanently adds the symbol \p symbolName with the 57 | ## value \p symbolValue. These symbols are searched before any 58 | ## libraries. 59 | ## 60 | ## @see sys::DynamicLibrary::AddSymbol() 61 | ## 62 | 63 | proc addSymbol*( 64 | symbolName: cstring, symbolValue: pointer 65 | ) {.importc: "LLVMAddSymbol", dynlib: LLVMLib.} 66 | 67 | ## 68 | ## @} 69 | ## 70 | -------------------------------------------------------------------------------- /llvm/llvm/Target.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/Target.h - Target Lib C Iface --------------------*- C++ -*-=== 2 | ## 3 | ## Part of the LLVM Project, under the Apache License v2.0 with LLVM 4 | ## Exceptions. 5 | ## See https://llvm.org/LICENSE.txt for license information. 6 | ## SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 | ## 8 | ## ===----------------------------------------------------------------------=== 9 | ## 10 | ## This header declares the C interface to libLLVMTarget.a, which 11 | ## implements target information. 12 | ## 13 | ## Many exotic languages can interoperate with C code but have a harder time 14 | ## with C++ due to name mangling. So in addition to C, this interface enables 15 | ## tools written in such languages. 16 | ## 17 | ## ===----------------------------------------------------------------------=== 18 | 19 | ## !!!Ignored construct: # LLVM_C_TARGET_H [NewLine] # LLVM_C_TARGET_H [NewLine] # llvm-c/ExternC.h [NewLine] # llvm-c/Types.h [NewLine] # llvm/Config/llvm-config.h [NewLine] 20 | ## @defgroup LLVMCTarget Target information 21 | ## @ingroup LLVMC 22 | ## 23 | ## @{ 24 | ## enum LLVMByteOrdering { LLVMBigEndian , LLVMLittleEndian } ; 25 | ## Error: token expected: ; but got: ##!!! 26 | 27 | type 28 | TargetDataRef* = ptr OpaqueTargetData 29 | TargetLibraryInfoRef* = ptr OpaqueTargetLibraryInfotData 30 | 31 | ## Declare all of the target-initialization functions that are available. 32 | 33 | ## !!!Ignored construct: # LLVM_TARGET ( TargetName ) void LLVMInitialize ## TargetName ## TargetInfo ( void ) ; 34 | ## Error: token expected: ; but got: ##!!! 35 | 36 | ## !!!Ignored construct: [NewLine] # llvm/Config/Targets.def [NewLine] # LLVM_TARGET Explicit undef to make SWIG happier [NewLine] # LLVM_TARGET ( TargetName ) void LLVMInitialize ## TargetName ## Target ( void ) ; 37 | ## Error: did not expect [NewLine]!!! 38 | 39 | ## !!!Ignored construct: [NewLine] # llvm/Config/Targets.def [NewLine] # LLVM_TARGET Explicit undef to make SWIG happier [NewLine] # LLVM_TARGET ( TargetName ) void LLVMInitialize ## TargetName ## TargetMC ( void ) ; 40 | ## Error: did not expect [NewLine]!!! 41 | 42 | ## !!!Ignored construct: [NewLine] # llvm/Config/Targets.def [NewLine] # LLVM_TARGET Explicit undef to make SWIG happier [NewLine] Declare all of the available assembly printer initialization functions. # LLVM_ASM_PRINTER ( TargetName ) void LLVMInitialize ## TargetName ## AsmPrinter ( void ) ; 43 | ## Error: did not expect [NewLine]!!! 44 | 45 | ## !!!Ignored construct: [NewLine] # llvm/Config/AsmPrinters.def [NewLine] # LLVM_ASM_PRINTER Explicit undef to make SWIG happier [NewLine] Declare all of the available assembly parser initialization functions. # LLVM_ASM_PARSER ( TargetName ) void LLVMInitialize ## TargetName ## AsmParser ( void ) ; 46 | ## Error: did not expect [NewLine]!!! 47 | 48 | ## !!!Ignored construct: [NewLine] # llvm/Config/AsmParsers.def [NewLine] # LLVM_ASM_PARSER Explicit undef to make SWIG happier [NewLine] Declare all of the available disassembler initialization functions. # LLVM_DISASSEMBLER ( TargetName ) void LLVMInitialize ## TargetName ## Disassembler ( void ) ; 49 | ## Error: did not expect [NewLine]!!! 50 | 51 | ## !!!Ignored construct: [NewLine] # llvm/Config/Disassemblers.def [NewLine] # LLVM_DISASSEMBLER Explicit undef to make SWIG happier [NewLine] LLVMInitializeAllTargetInfos - The main program should call this function if 52 | ## it wants access to all available targets that LLVM is configured to 53 | ## support. static inline void LLVMInitializeAllTargetInfos ( void ) { # LLVM_TARGET ( TargetName ) LLVMInitialize ## TargetName ## TargetInfo ( ) ; [NewLine] # llvm/Config/Targets.def [NewLine] # LLVM_TARGET Explicit undef to make SWIG happier [NewLine] } LLVMInitializeAllTargets - The main program should call this function if it 54 | ## wants to link in all available targets that LLVM is configured to 55 | ## support. static inline void LLVMInitializeAllTargets ( void ) { # LLVM_TARGET ( TargetName ) LLVMInitialize ## TargetName ## Target ( ) ; [NewLine] # llvm/Config/Targets.def [NewLine] # LLVM_TARGET Explicit undef to make SWIG happier [NewLine] } LLVMInitializeAllTargetMCs - The main program should call this function if 56 | ## it wants access to all available target MC that LLVM is configured to 57 | ## support. static inline void LLVMInitializeAllTargetMCs ( void ) { # LLVM_TARGET ( TargetName ) LLVMInitialize ## TargetName ## TargetMC ( ) ; [NewLine] # llvm/Config/Targets.def [NewLine] # LLVM_TARGET Explicit undef to make SWIG happier [NewLine] } LLVMInitializeAllAsmPrinters - The main program should call this function if 58 | ## it wants all asm printers that LLVM is configured to support, to make them 59 | ## available via the TargetRegistry. static inline void LLVMInitializeAllAsmPrinters ( void ) { # LLVM_ASM_PRINTER ( TargetName ) LLVMInitialize ## TargetName ## AsmPrinter ( ) ; [NewLine] # llvm/Config/AsmPrinters.def [NewLine] # LLVM_ASM_PRINTER Explicit undef to make SWIG happier [NewLine] } LLVMInitializeAllAsmParsers - The main program should call this function if 60 | ## it wants all asm parsers that LLVM is configured to support, to make them 61 | ## available via the TargetRegistry. static inline void LLVMInitializeAllAsmParsers ( void ) { # LLVM_ASM_PARSER ( TargetName ) LLVMInitialize ## TargetName ## AsmParser ( ) ; [NewLine] # llvm/Config/AsmParsers.def [NewLine] # LLVM_ASM_PARSER Explicit undef to make SWIG happier [NewLine] } LLVMInitializeAllDisassemblers - The main program should call this function 62 | ## if it wants all disassemblers that LLVM is configured to support, to make 63 | ## them available via the TargetRegistry. static inline void LLVMInitializeAllDisassemblers ( void ) { # LLVM_DISASSEMBLER ( TargetName ) LLVMInitialize ## TargetName ## Disassembler ( ) ; [NewLine] # llvm/Config/Disassemblers.def [NewLine] # LLVM_DISASSEMBLER Explicit undef to make SWIG happier [NewLine] } LLVMInitializeNativeTarget - The main program should call this function to 64 | ## initialize the native target corresponding to the host. This is useful 65 | ## for JIT applications to ensure that the target gets linked in correctly. static inline LLVMBool LLVMInitializeNativeTarget ( void ) { If we have a native target, initialize it to ensure it is linked in. # LLVM_NATIVE_TARGET [NewLine] LLVM_NATIVE_TARGETINFO ( ) ; LLVM_NATIVE_TARGET ( ) ; LLVM_NATIVE_TARGETMC ( ) ; return 0 ; # [NewLine] return 1 ; # [NewLine] } LLVMInitializeNativeTargetAsmParser - The main program should call this 66 | ## function to initialize the parser for the native target corresponding to the 67 | ## host. static inline LLVMBool LLVMInitializeNativeAsmParser ( void ) { # LLVM_NATIVE_ASMPARSER [NewLine] LLVM_NATIVE_ASMPARSER ( ) ; return 0 ; # [NewLine] return 1 ; # [NewLine] } LLVMInitializeNativeTargetAsmPrinter - The main program should call this 68 | ## function to initialize the printer for the native target corresponding to 69 | ## the host. static inline LLVMBool LLVMInitializeNativeAsmPrinter ( void ) { # LLVM_NATIVE_ASMPRINTER [NewLine] LLVM_NATIVE_ASMPRINTER ( ) ; return 0 ; # [NewLine] return 1 ; # [NewLine] } LLVMInitializeNativeTargetDisassembler - The main program should call this 70 | ## function to initialize the disassembler for the native target corresponding 71 | ## to the host. static inline LLVMBool LLVMInitializeNativeDisassembler ( void ) { # LLVM_NATIVE_DISASSEMBLER [NewLine] LLVM_NATIVE_DISASSEMBLER ( ) ; return 0 ; # [NewLine] return 1 ; # [NewLine] } ===-- Target Data -------------------------------------------------------=== 72 | ## Obtain the data layout for a module. 73 | ## 74 | ## @see Module::getDataLayout() 75 | ## LLVMTargetDataRef LLVMGetModuleDataLayout ( LLVMModuleRef M ) ; 76 | ## Error: did not expect [NewLine]!!! 77 | 78 | ## 79 | ## Set the data layout for a module. 80 | ## 81 | ## @see Module::setDataLayout() 82 | ## 83 | 84 | proc setModuleDataLayout*( 85 | m: ModuleRef, dl: TargetDataRef 86 | ) {.importc: "LLVMSetModuleDataLayout", dynlib: LLVMLib.} 87 | 88 | ## Creates target data from a target layout string. 89 | ## See the constructor llvm::DataLayout::DataLayout. 90 | 91 | proc createTargetData*( 92 | stringRep: cstring 93 | ): TargetDataRef {.importc: "LLVMCreateTargetData", dynlib: LLVMLib.} 94 | 95 | ## Deallocates a TargetData. 96 | ## See the destructor llvm::DataLayout::~DataLayout. 97 | 98 | proc disposeTargetData*( 99 | td: TargetDataRef 100 | ) {.importc: "LLVMDisposeTargetData", dynlib: LLVMLib.} 101 | 102 | ## Adds target library information to a pass manager. This does not take 103 | ## ownership of the target library info. 104 | ## See the method llvm::PassManagerBase::add. 105 | 106 | proc addTargetLibraryInfo*( 107 | tli: TargetLibraryInfoRef, pm: PassManagerRef 108 | ) {.importc: "LLVMAddTargetLibraryInfo", dynlib: LLVMLib.} 109 | 110 | ## Converts target data to a target layout string. The string must be disposed 111 | ## with LLVMDisposeMessage. 112 | ## See the constructor llvm::DataLayout::DataLayout. 113 | 114 | proc copyStringRepOfTargetData*( 115 | td: TargetDataRef 116 | ): cstring {.importc: "LLVMCopyStringRepOfTargetData", dynlib: LLVMLib.} 117 | 118 | ## Returns the byte order of a target, either LLVMBigEndian or 119 | ## LLVMLittleEndian. 120 | ## See the method llvm::DataLayout::isLittleEndian. 121 | 122 | proc byteOrder*( 123 | td: TargetDataRef 124 | ): ByteOrdering {.importc: "LLVMByteOrder", dynlib: LLVMLib.} 125 | 126 | ## Returns the pointer size in bytes for a target. 127 | ## See the method llvm::DataLayout::getPointerSize. 128 | 129 | proc pointerSize*( 130 | td: TargetDataRef 131 | ): cuint {.importc: "LLVMPointerSize", dynlib: LLVMLib.} 132 | 133 | ## Returns the pointer size in bytes for a target for a specified 134 | ## address space. 135 | ## See the method llvm::DataLayout::getPointerSize. 136 | 137 | proc pointerSizeForAS*( 138 | td: TargetDataRef, `as`: cuint 139 | ): cuint {.importc: "LLVMPointerSizeForAS", dynlib: LLVMLib.} 140 | 141 | ## Returns the integer type that is the same size as a pointer on a target. 142 | ## See the method llvm::DataLayout::getIntPtrType. 143 | 144 | proc intPtrType*( 145 | td: TargetDataRef 146 | ): TypeRef {.importc: "LLVMIntPtrType", dynlib: LLVMLib.} 147 | 148 | ## Returns the integer type that is the same size as a pointer on a target. 149 | ## This version allows the address space to be specified. 150 | ## See the method llvm::DataLayout::getIntPtrType. 151 | 152 | proc intPtrTypeForAS*( 153 | td: TargetDataRef, `as`: cuint 154 | ): TypeRef {.importc: "LLVMIntPtrTypeForAS", dynlib: LLVMLib.} 155 | 156 | ## Returns the integer type that is the same size as a pointer on a target. 157 | ## See the method llvm::DataLayout::getIntPtrType. 158 | 159 | proc intPtrTypeInContext*( 160 | c: ContextRef, td: TargetDataRef 161 | ): TypeRef {.importc: "LLVMIntPtrTypeInContext", dynlib: LLVMLib.} 162 | 163 | ## Returns the integer type that is the same size as a pointer on a target. 164 | ## This version allows the address space to be specified. 165 | ## See the method llvm::DataLayout::getIntPtrType. 166 | 167 | proc intPtrTypeForASInContext*( 168 | c: ContextRef, td: TargetDataRef, `as`: cuint 169 | ): TypeRef {.importc: "LLVMIntPtrTypeForASInContext", dynlib: LLVMLib.} 170 | 171 | ## Computes the size of a type in bytes for a target. 172 | ## See the method llvm::DataLayout::getTypeSizeInBits. 173 | 174 | proc sizeOfXTypeInBits*( 175 | td: TargetDataRef, ty: TypeRef 176 | ): culonglong {.importc: "LLVMSizeOfTypeInBits", dynlib: LLVMLib.} 177 | 178 | ## Computes the storage size of a type in bytes for a target. 179 | ## See the method llvm::DataLayout::getTypeStoreSize. 180 | 181 | proc storeSizeOfType*( 182 | td: TargetDataRef, ty: TypeRef 183 | ): culonglong {.importc: "LLVMStoreSizeOfType", dynlib: LLVMLib.} 184 | 185 | ## Computes the ABI size of a type in bytes for a target. 186 | ## See the method llvm::DataLayout::getTypeAllocSize. 187 | 188 | proc aBISizeOfType*( 189 | td: TargetDataRef, ty: TypeRef 190 | ): culonglong {.importc: "LLVMABISizeOfType", dynlib: LLVMLib.} 191 | 192 | ## Computes the ABI alignment of a type in bytes for a target. 193 | ## See the method llvm::DataLayout::getTypeABISize. 194 | 195 | proc aBIAlignmentOfType*( 196 | td: TargetDataRef, ty: TypeRef 197 | ): cuint {.importc: "LLVMABIAlignmentOfType", dynlib: LLVMLib.} 198 | 199 | ## Computes the call frame alignment of a type in bytes for a target. 200 | ## See the method llvm::DataLayout::getTypeABISize. 201 | 202 | proc callFrameAlignmentOfType*( 203 | td: TargetDataRef, ty: TypeRef 204 | ): cuint {.importc: "LLVMCallFrameAlignmentOfType", dynlib: LLVMLib.} 205 | 206 | ## Computes the preferred alignment of a type in bytes for a target. 207 | ## See the method llvm::DataLayout::getTypeABISize. 208 | 209 | proc preferredAlignmentOfType*( 210 | td: TargetDataRef, ty: TypeRef 211 | ): cuint {.importc: "LLVMPreferredAlignmentOfType", dynlib: LLVMLib.} 212 | 213 | ## Computes the preferred alignment of a global variable in bytes for a target. 214 | ## See the method llvm::DataLayout::getPreferredAlignment. 215 | 216 | proc preferredAlignmentOfGlobal*( 217 | td: TargetDataRef, globalVar: ValueRef 218 | ): cuint {.importc: "LLVMPreferredAlignmentOfGlobal", dynlib: LLVMLib.} 219 | 220 | ## Computes the structure element that contains the byte offset for a target. 221 | ## See the method llvm::StructLayout::getElementContainingOffset. 222 | 223 | proc elementAtOffset*( 224 | td: TargetDataRef, structTy: TypeRef, offset: culonglong 225 | ): cuint {.importc: "LLVMElementAtOffset", dynlib: LLVMLib.} 226 | 227 | ## Computes the byte offset of the indexed struct element for a target. 228 | ## See the method llvm::StructLayout::getElementContainingOffset. 229 | 230 | proc offsetOfElement*( 231 | td: TargetDataRef, structTy: TypeRef, element: cuint 232 | ): culonglong {.importc: "LLVMOffsetOfElement", dynlib: LLVMLib.} 233 | 234 | ## 235 | ## @} 236 | ## 237 | -------------------------------------------------------------------------------- /llvm/llvm/TargetMachine.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/TargetMachine.h - Target Machine Library C Interface - C++ -*-=*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header declares the C interface to the Target and TargetMachine *| 11 | ## |* classes, which can be used to generate assembly or object files. *| 12 | ## |* *| 13 | ## |* Many exotic languages can interoperate with C code but have a harder time *| 14 | ## |* with C++ due to name mangling. So in addition to C, this interface enables *| 15 | ## |* tools written in such languages. *| 16 | ## |* *| 17 | ## \*===----------------------------------------------------------------------=== 18 | 19 | ## 20 | ## @addtogroup LLVMCTarget 21 | ## 22 | ## @{ 23 | ## 24 | 25 | type 26 | TargetMachineOptionsRef* = ptr OpaqueTargetMachineOptions 27 | TargetMachineRef* = ptr OpaqueTargetMachine 28 | TargetRef* = ptr target 29 | CodeGenOptLevel* {.size: sizeof(cint).} = enum 30 | CodeGenLevelNone 31 | CodeGenLevelLess 32 | CodeGenLevelDefault 33 | CodeGenLevelAggressive 34 | 35 | RelocMode* {.size: sizeof(cint).} = enum 36 | RelocDefault 37 | RelocStatic 38 | RelocPIC 39 | RelocDynamicNoPic 40 | RelocROPI 41 | RelocRWPI 42 | RelocROPI_RWPI 43 | 44 | CodeModel* {.size: sizeof(cint).} = enum 45 | CodeModelDefault 46 | CodeModelJITDefault 47 | CodeModelTiny 48 | CodeModelSmall 49 | CodeModelKernel 50 | CodeModelMedium 51 | CodeModelLarge 52 | 53 | CodeGenFileType* {.size: sizeof(cint).} = enum 54 | AssemblyFile 55 | ObjectFile 56 | 57 | GlobalISelAbortMode* {.size: sizeof(cint).} = enum 58 | GlobalISelAbortEnable 59 | GlobalISelAbortDisable 60 | GlobalISelAbortDisableWithDiag 61 | 62 | ## Returns the first llvm::Target in the registered targets list. 63 | 64 | proc getFirstTarget*(): TargetRef {.importc: "LLVMGetFirstTarget", dynlib: LLVMLib.} 65 | ## Returns the next llvm::Target given a previous one (or null if there's none) 66 | 67 | proc getNextTarget*( 68 | t: TargetRef 69 | ): TargetRef {.importc: "LLVMGetNextTarget", dynlib: LLVMLib.} 70 | 71 | ## ===-- Target ------------------------------------------------------------=== 72 | ## Finds the target corresponding to the given name and stores it in \p T. 73 | ## Returns 0 on success. 74 | 75 | proc getTargetFromName*( 76 | name: cstring 77 | ): TargetRef {.importc: "LLVMGetTargetFromName", dynlib: LLVMLib.} 78 | 79 | ## Finds the target corresponding to the given triple and stores it in \p T. 80 | ## Returns 0 on success. Optionally returns any error in ErrorMessage. 81 | ## Use LLVMDisposeMessage to dispose the message. 82 | 83 | proc getTargetFromTriple*( 84 | triple: cstring, t: ptr TargetRef, errorMessage: cstringArray 85 | ): Bool {.importc: "LLVMGetTargetFromTriple", dynlib: LLVMLib.} 86 | 87 | ## Returns the name of a target. See llvm::Target::getName 88 | 89 | proc getTargetName*( 90 | t: TargetRef 91 | ): cstring {.importc: "LLVMGetTargetName", dynlib: LLVMLib.} 92 | 93 | ## Returns the description of a target. See llvm::Target::getDescription 94 | 95 | proc getTargetDescription*( 96 | t: TargetRef 97 | ): cstring {.importc: "LLVMGetTargetDescription", dynlib: LLVMLib.} 98 | 99 | ## Returns if the target has a JIT 100 | 101 | proc targetHasJIT*(t: TargetRef): Bool {.importc: "LLVMTargetHasJIT", dynlib: LLVMLib.} 102 | ## Returns if the target has a TargetMachine associated 103 | 104 | proc targetHasTargetMachine*( 105 | t: TargetRef 106 | ): Bool {.importc: "LLVMTargetHasTargetMachine", dynlib: LLVMLib.} 107 | 108 | ## Returns if the target as an ASM backend (required for emitting output) 109 | 110 | proc targetHasAsmBackend*( 111 | t: TargetRef 112 | ): Bool {.importc: "LLVMTargetHasAsmBackend", dynlib: LLVMLib.} 113 | 114 | ## ===-- Target Machine ----------------------------------------------------=== 115 | ## 116 | ## Create a new set of options for an llvm::TargetMachine. 117 | ## 118 | ## The returned option structure must be released with 119 | ## LLVMDisposeTargetMachineOptions() after the call to 120 | ## LLVMCreateTargetMachineWithOptions(). 121 | ## 122 | 123 | proc createTargetMachineOptions*(): TargetMachineOptionsRef {. 124 | importc: "LLVMCreateTargetMachineOptions", dynlib: LLVMLib 125 | .} 126 | 127 | ## 128 | ## Dispose of an LLVMTargetMachineOptionsRef instance. 129 | ## 130 | 131 | proc disposeTargetMachineOptions*( 132 | options: TargetMachineOptionsRef 133 | ) {.importc: "LLVMDisposeTargetMachineOptions", dynlib: LLVMLib.} 134 | 135 | proc targetMachineOptionsSetCPU*( 136 | options: TargetMachineOptionsRef, cpu: cstring 137 | ) {.importc: "LLVMTargetMachineOptionsSetCPU", dynlib: LLVMLib.} 138 | 139 | ## 140 | ## Set the list of features for the target machine. 141 | ## 142 | ## \param Features a comma-separated list of features. 143 | ## 144 | 145 | proc targetMachineOptionsSetFeatures*( 146 | options: TargetMachineOptionsRef, features: cstring 147 | ) {.importc: "LLVMTargetMachineOptionsSetFeatures", dynlib: LLVMLib.} 148 | 149 | proc targetMachineOptionsSetABI*( 150 | options: TargetMachineOptionsRef, abi: cstring 151 | ) {.importc: "LLVMTargetMachineOptionsSetABI", dynlib: LLVMLib.} 152 | 153 | proc targetMachineOptionsSetCodeGenOptLevel*( 154 | options: TargetMachineOptionsRef, level: CodeGenOptLevel 155 | ) {.importc: "LLVMTargetMachineOptionsSetCodeGenOptLevel", dynlib: LLVMLib.} 156 | 157 | proc targetMachineOptionsSetRelocMode*( 158 | options: TargetMachineOptionsRef, reloc: RelocMode 159 | ) {.importc: "LLVMTargetMachineOptionsSetRelocMode", dynlib: LLVMLib.} 160 | 161 | proc targetMachineOptionsSetCodeModel*( 162 | options: TargetMachineOptionsRef, codeModel: CodeModel 163 | ) {.importc: "LLVMTargetMachineOptionsSetCodeModel", dynlib: LLVMLib.} 164 | 165 | ## 166 | ## Create a new llvm::TargetMachine. 167 | ## 168 | ## \param T the target to create a machine for. 169 | ## \param Triple a triple describing the target machine. 170 | ## \param Options additional configuration (see 171 | ## LLVMCreateTargetMachineOptions()). 172 | ## 173 | 174 | proc createTargetMachineWithOptions*( 175 | t: TargetRef, triple: cstring, options: TargetMachineOptionsRef 176 | ): TargetMachineRef {.importc: "LLVMCreateTargetMachineWithOptions", dynlib: LLVMLib.} 177 | 178 | ## Creates a new llvm::TargetMachine. See llvm::Target::createTargetMachine 179 | 180 | proc createTargetMachine*( 181 | t: TargetRef, 182 | triple: cstring, 183 | cpu: cstring, 184 | features: cstring, 185 | level: CodeGenOptLevel, 186 | reloc: RelocMode, 187 | codeModel: CodeModel, 188 | ): TargetMachineRef {.importc: "LLVMCreateTargetMachine", dynlib: LLVMLib.} 189 | 190 | ## Dispose the LLVMTargetMachineRef instance generated by 191 | ## LLVMCreateTargetMachine. 192 | 193 | proc disposeTargetMachine*( 194 | t: TargetMachineRef 195 | ) {.importc: "LLVMDisposeTargetMachine", dynlib: LLVMLib.} 196 | 197 | ## Returns the Target used in a TargetMachine 198 | 199 | proc getTargetMachineTarget*( 200 | t: TargetMachineRef 201 | ): TargetRef {.importc: "LLVMGetTargetMachineTarget", dynlib: LLVMLib.} 202 | 203 | ## Returns the triple used creating this target machine. See 204 | ## llvm::TargetMachine::getTriple. The result needs to be disposed with 205 | ## LLVMDisposeMessage. 206 | 207 | proc getTargetMachineTriple*( 208 | t: TargetMachineRef 209 | ): cstring {.importc: "LLVMGetTargetMachineTriple", dynlib: LLVMLib.} 210 | 211 | ## Returns the cpu used creating this target machine. See 212 | ## llvm::TargetMachine::getCPU. The result needs to be disposed with 213 | ## LLVMDisposeMessage. 214 | 215 | proc getTargetMachineCPU*( 216 | t: TargetMachineRef 217 | ): cstring {.importc: "LLVMGetTargetMachineCPU", dynlib: LLVMLib.} 218 | 219 | ## Returns the feature string used creating this target machine. See 220 | ## llvm::TargetMachine::getFeatureString. The result needs to be disposed with 221 | ## LLVMDisposeMessage. 222 | 223 | proc getTargetMachineFeatureString*( 224 | t: TargetMachineRef 225 | ): cstring {.importc: "LLVMGetTargetMachineFeatureString", dynlib: LLVMLib.} 226 | 227 | ## Create a DataLayout based on the targetMachine. 228 | 229 | proc createTargetDataLayout*( 230 | t: TargetMachineRef 231 | ): TargetDataRef {.importc: "LLVMCreateTargetDataLayout", dynlib: LLVMLib.} 232 | 233 | ## Set the target machine's ASM verbosity. 234 | 235 | proc setTargetMachineAsmVerbosity*( 236 | t: TargetMachineRef, verboseAsm: Bool 237 | ) {.importc: "LLVMSetTargetMachineAsmVerbosity", dynlib: LLVMLib.} 238 | 239 | ## Enable fast-path instruction selection. 240 | 241 | proc setTargetMachineFastISel*( 242 | t: TargetMachineRef, enable: Bool 243 | ) {.importc: "LLVMSetTargetMachineFastISel", dynlib: LLVMLib.} 244 | 245 | ## Enable global instruction selection. 246 | 247 | proc setTargetMachineGlobalISel*( 248 | t: TargetMachineRef, enable: Bool 249 | ) {.importc: "LLVMSetTargetMachineGlobalISel", dynlib: LLVMLib.} 250 | 251 | ## Set abort behaviour when global instruction selection fails to lower/select 252 | ## an instruction. 253 | 254 | proc setTargetMachineGlobalISelAbort*( 255 | t: TargetMachineRef, mode: GlobalISelAbortMode 256 | ) {.importc: "LLVMSetTargetMachineGlobalISelAbort", dynlib: LLVMLib.} 257 | 258 | ## Enable the MachineOutliner pass. 259 | 260 | proc setTargetMachineMachineOutliner*( 261 | t: TargetMachineRef, enable: Bool 262 | ) {.importc: "LLVMSetTargetMachineMachineOutliner", dynlib: LLVMLib.} 263 | 264 | ## Emits an asm or object file for the given module to the filename. This 265 | ## wraps several c++ only classes (among them a file stream). Returns any 266 | ## error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. 267 | 268 | proc targetMachineEmitToFile*( 269 | t: TargetMachineRef, 270 | m: ModuleRef, 271 | filename: cstring, 272 | codegen: CodeGenFileType, 273 | errorMessage: cstringArray, 274 | ): Bool {.importc: "LLVMTargetMachineEmitToFile", dynlib: LLVMLib.} 275 | 276 | ## Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf. 277 | 278 | proc targetMachineEmitToMemoryBuffer*( 279 | t: TargetMachineRef, 280 | m: ModuleRef, 281 | codegen: CodeGenFileType, 282 | errorMessage: cstringArray, 283 | outMemBuf: ptr MemoryBufferRef, 284 | ): Bool {.importc: "LLVMTargetMachineEmitToMemoryBuffer", dynlib: LLVMLib.} 285 | 286 | ## ===-- Triple ------------------------------------------------------------=== 287 | ## Get a triple for the host machine as a string. The result needs to be 288 | ## disposed with LLVMDisposeMessage. 289 | 290 | proc getDefaultTargetTriple*(): cstring {. 291 | importc: "LLVMGetDefaultTargetTriple", dynlib: LLVMLib 292 | .} 293 | 294 | ## Normalize a target triple. The result needs to be disposed with 295 | ## LLVMDisposeMessage. 296 | 297 | proc normalizeTargetTriple*( 298 | triple: cstring 299 | ): cstring {.importc: "LLVMNormalizeTargetTriple", dynlib: LLVMLib.} 300 | 301 | ## Get the host CPU as a string. The result needs to be disposed with 302 | ## LLVMDisposeMessage. 303 | 304 | proc getHostCPUName*(): cstring {.importc: "LLVMGetHostCPUName", dynlib: LLVMLib.} 305 | ## Get the host CPU's features as a string. The result needs to be disposed 306 | ## with LLVMDisposeMessage. 307 | 308 | proc getHostCPUFeatures*(): cstring {. 309 | importc: "LLVMGetHostCPUFeatures", dynlib: LLVMLib 310 | .} 311 | 312 | ## Adds the target-specific analysis passes to the pass manager. 313 | 314 | proc addAnalysisPasses*( 315 | t: TargetMachineRef, pm: PassManagerRef 316 | ) {.importc: "LLVMAddAnalysisPasses", dynlib: LLVMLib.} 317 | 318 | ## 319 | ## @} 320 | ## 321 | -------------------------------------------------------------------------------- /llvm/llvm/Transforms/PassBuilder.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/Transform/PassBuilder.h - PassBuilder for LLVM C ---*- C -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This header contains the LLVM-C interface into the new pass manager *| 11 | ## |* *| 12 | ## \*===----------------------------------------------------------------------=== 13 | 14 | ## 15 | ## @defgroup LLVMCCoreNewPM New Pass Manager 16 | ## @ingroup LLVMCCore 17 | ## 18 | ## @{ 19 | ## 20 | ## 21 | ## A set of options passed which are attached to the Pass Manager upon run. 22 | ## 23 | ## This corresponds to an llvm::LLVMPassBuilderOptions instance 24 | ## 25 | ## The details for how the different properties of this structure are used can 26 | ## be found in the source for LLVMRunPasses 27 | ## 28 | 29 | type PassBuilderOptionsRef* = ptr OpaquePassBuilderOptions 30 | 31 | ## 32 | ## Construct and run a set of passes over a module 33 | ## 34 | ## This function takes a string with the passes that should be used. The format 35 | ## of this string is the same as opt's -passes argument for the new pass 36 | ## manager. Individual passes may be specified, separated by commas. Full 37 | ## pipelines may also be invoked using `default` and friends. See opt for 38 | ## full reference of the Passes format. 39 | ## 40 | 41 | proc runPasses*( 42 | m: ModuleRef, passes: cstring, tm: TargetMachineRef, options: PassBuilderOptionsRef 43 | ): ErrorRef {.importc: "LLVMRunPasses", dynlib: LLVMLib.} 44 | 45 | ## 46 | ## Create a new set of options for a PassBuilder 47 | ## 48 | ## Ownership of the returned instance is given to the client, and they are 49 | ## responsible for it. The client should call LLVMDisposePassBuilderOptions 50 | ## to free the pass builder options. 51 | ## 52 | 53 | proc createPassBuilderOptions*(): PassBuilderOptionsRef {. 54 | importc: "LLVMCreatePassBuilderOptions", dynlib: LLVMLib 55 | .} 56 | 57 | ## 58 | ## Toggle adding the VerifierPass for the PassBuilder, ensuring all functions 59 | ## inside the module is valid. 60 | ## 61 | 62 | proc passBuilderOptionsSetVerifyEach*( 63 | options: PassBuilderOptionsRef, verifyEach: Bool 64 | ) {.importc: "LLVMPassBuilderOptionsSetVerifyEach", dynlib: LLVMLib.} 65 | 66 | ## 67 | ## Toggle debug logging when running the PassBuilder 68 | ## 69 | 70 | proc passBuilderOptionsSetDebugLogging*( 71 | options: PassBuilderOptionsRef, debugLogging: Bool 72 | ) {.importc: "LLVMPassBuilderOptionsSetDebugLogging", dynlib: LLVMLib.} 73 | 74 | proc passBuilderOptionsSetLoopInterleaving*( 75 | options: PassBuilderOptionsRef, loopInterleaving: Bool 76 | ) {.importc: "LLVMPassBuilderOptionsSetLoopInterleaving", dynlib: LLVMLib.} 77 | 78 | proc passBuilderOptionsSetLoopVectorization*( 79 | options: PassBuilderOptionsRef, loopVectorization: Bool 80 | ) {.importc: "LLVMPassBuilderOptionsSetLoopVectorization", dynlib: LLVMLib.} 81 | 82 | proc passBuilderOptionsSetSLPVectorization*( 83 | options: PassBuilderOptionsRef, sLPVectorization: Bool 84 | ) {.importc: "LLVMPassBuilderOptionsSetSLPVectorization", dynlib: LLVMLib.} 85 | 86 | proc passBuilderOptionsSetLoopUnrolling*( 87 | options: PassBuilderOptionsRef, loopUnrolling: Bool 88 | ) {.importc: "LLVMPassBuilderOptionsSetLoopUnrolling", dynlib: LLVMLib.} 89 | 90 | proc passBuilderOptionsSetForgetAllSCEVInLoopUnroll*( 91 | options: PassBuilderOptionsRef, forgetAllSCEVInLoopUnroll: Bool 92 | ) {.importc: "LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll", dynlib: LLVMLib.} 93 | 94 | proc passBuilderOptionsSetLicmMssaOptCap*( 95 | options: PassBuilderOptionsRef, licmMssaOptCap: cuint 96 | ) {.importc: "LLVMPassBuilderOptionsSetLicmMssaOptCap", dynlib: LLVMLib.} 97 | 98 | proc passBuilderOptionsSetLicmMssaNoAccForPromotionCap*( 99 | options: PassBuilderOptionsRef, licmMssaNoAccForPromotionCap: cuint 100 | ) {.importc: "LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap", dynlib: LLVMLib.} 101 | 102 | proc passBuilderOptionsSetCallGraphProfile*( 103 | options: PassBuilderOptionsRef, callGraphProfile: Bool 104 | ) {.importc: "LLVMPassBuilderOptionsSetCallGraphProfile", dynlib: LLVMLib.} 105 | 106 | proc passBuilderOptionsSetMergeFunctions*( 107 | options: PassBuilderOptionsRef, mergeFunctions: Bool 108 | ) {.importc: "LLVMPassBuilderOptionsSetMergeFunctions", dynlib: LLVMLib.} 109 | 110 | proc passBuilderOptionsSetInlinerThreshold*( 111 | options: PassBuilderOptionsRef, threshold: cint 112 | ) {.importc: "LLVMPassBuilderOptionsSetInlinerThreshold", dynlib: LLVMLib.} 113 | 114 | ## 115 | ## Dispose of a heap-allocated PassBuilderOptions instance 116 | ## 117 | 118 | proc disposePassBuilderOptions*( 119 | options: PassBuilderOptionsRef 120 | ) {.importc: "LLVMDisposePassBuilderOptions", dynlib: LLVMLib.} 121 | 122 | ## 123 | ## @} 124 | ## 125 | -------------------------------------------------------------------------------- /llvm/llvm/Types.nim: -------------------------------------------------------------------------------- 1 | ## ===-- llvm-c/Support.h - C Interface Types declarations ---------*- C -*-===*\ 2 | ## |* *| 3 | ## |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 4 | ## |* Exceptions. *| 5 | ## |* See https://llvm.org/LICENSE.txt for license information. *| 6 | ## |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 7 | ## |* *| 8 | ## |*===----------------------------------------------------------------------===*| 9 | ## |* *| 10 | ## |* This file defines types used by the C interface to LLVM. *| 11 | ## |* *| 12 | ## \*===----------------------------------------------------------------------=== 13 | 14 | ## 15 | ## @defgroup LLVMCSupportTypes Types and Enumerations 16 | ## 17 | ## @{ 18 | ## 19 | 20 | type Bool* = cint 21 | 22 | ## Opaque types. 23 | ## 24 | ## LLVM uses a polymorphic type hierarchy which C cannot represent, therefore 25 | ## parameters must be passed as base types. Despite the declared types, most 26 | ## of the functions provided operate only on branches of the type hierarchy. 27 | ## The declared parameter names are descriptive and specify which type is 28 | ## required. Additionally, each type hierarchy is documented along with the 29 | ## functions that operate upon it. For more detail, refer to LLVM's C++ code. 30 | ## If in doubt, refer to Core.cpp, which performs parameter downcasts in the 31 | ## form unwrap(Param). 32 | ## 33 | ## 34 | ## Used to pass regions of memory through LLVM interfaces. 35 | ## 36 | ## @see llvm::MemoryBuffer 37 | ## 38 | 39 | type MemoryBufferRef* = ptr OpaqueMemoryBuffer 40 | 41 | ## 42 | ## The top-level container for all LLVM global data. See the LLVMContext class. 43 | ## 44 | 45 | type ContextRef* = ptr OpaqueContext 46 | 47 | ## 48 | ## The top-level container for all other LLVM Intermediate Representation (IR) 49 | ## objects. 50 | ## 51 | ## @see llvm::Module 52 | ## 53 | 54 | type ModuleRef* = ptr OpaqueModule 55 | 56 | ## 57 | ## Each value in the LLVM IR has a type, an LLVMTypeRef. 58 | ## 59 | ## @see llvm::Type 60 | ## 61 | 62 | type TypeRef* = ptr OpaqueType 63 | 64 | ## 65 | ## Represents an individual value in LLVM IR. 66 | ## 67 | ## This models llvm::Value. 68 | ## 69 | 70 | type ValueRef* = ptr OpaqueValue 71 | 72 | ## 73 | ## Represents a basic block of instructions in LLVM IR. 74 | ## 75 | ## This models llvm::BasicBlock. 76 | ## 77 | 78 | type BasicBlockRef* = ptr OpaqueBasicBlock 79 | 80 | ## 81 | ## Represents an LLVM Metadata. 82 | ## 83 | ## This models llvm::Metadata. 84 | ## 85 | 86 | type MetadataRef* = ptr OpaqueMetadata 87 | 88 | ## 89 | ## Represents an LLVM Named Metadata Node. 90 | ## 91 | ## This models llvm::NamedMDNode. 92 | ## 93 | 94 | type NamedMDNodeRef* = ptr OpaqueNamedMDNode 95 | 96 | ## 97 | ## Represents an entry in a Global Object's metadata attachments. 98 | ## 99 | ## This models std::pair 100 | ## 101 | 102 | type ValueMetadataEntry* = opaqueValueMetadataEntry 103 | 104 | ## 105 | ## Represents an LLVM basic block builder. 106 | ## 107 | ## This models llvm::IRBuilder. 108 | ## 109 | 110 | type BuilderRef* = ptr OpaqueBuilder 111 | 112 | ## 113 | ## Represents an LLVM debug info builder. 114 | ## 115 | ## This models llvm::DIBuilder. 116 | ## 117 | 118 | type DIBuilderRef* = ptr OpaqueDIBuilder 119 | 120 | ## 121 | ## Interface used to provide a module to JIT or interpreter. 122 | ## This is now just a synonym for llvm::Module, but we have to keep using the 123 | ## different type to keep binary compatibility. 124 | ## 125 | 126 | type ModuleProviderRef* = ptr OpaqueModuleProvider 127 | 128 | ## @see llvm::PassManagerBase 129 | 130 | type PassManagerRef* = ptr OpaquePassManager 131 | 132 | ## 133 | ## Used to get the users and usees of a Value. 134 | ## 135 | ## @see llvm::Use 136 | 137 | type UseRef* = ptr OpaqueUse 138 | 139 | ## 140 | ## @see llvm::OperandBundleDef 141 | ## 142 | 143 | type OperandBundleRef* = ptr OpaqueOperandBundle 144 | 145 | ## 146 | ## Used to represent an attributes. 147 | ## 148 | ## @see llvm::Attribute 149 | ## 150 | 151 | type AttributeRef* = ptr OpaqueAttributeRef 152 | 153 | ## 154 | ## @see llvm::DiagnosticInfo 155 | ## 156 | 157 | type DiagnosticInfoRef* = ptr OpaqueDiagnosticInfo 158 | 159 | ## 160 | ## @see llvm::Comdat 161 | ## 162 | 163 | type ComdatRef* = ptr comdat 164 | 165 | ## 166 | ## @see llvm::Module::ModuleFlagEntry 167 | ## 168 | 169 | type ModuleFlagEntry* = opaqueModuleFlagEntry 170 | 171 | ## 172 | ## @see llvm::JITEventListener 173 | ## 174 | 175 | type JITEventListenerRef* = ptr OpaqueJITEventListener 176 | 177 | ## 178 | ## @see llvm::object::Binary 179 | ## 180 | 181 | type BinaryRef* = ptr OpaqueBinary 182 | 183 | ## 184 | ## @see llvm::DbgRecord 185 | ## 186 | 187 | type DbgRecordRef* = ptr OpaqueDbgRecord 188 | 189 | ## 190 | ## @} 191 | ## 192 | -------------------------------------------------------------------------------- /llvm/rebuild.sh: -------------------------------------------------------------------------------- 1 | LLVM_INC=../ext/llvm-$(cat llvm.version).src/include 2 | 3 | C2NIM="../../c2nim/c2nim" 4 | C2NIMFLAGS="--nep1 --skipinclude --prefix:LLVM --dynlib:LLVMLib --def:LLVM_C_EXTERN_C_BEGIN= --def:LLVM_C_EXTERN_C_END= --stdints" 5 | 6 | HEADERS="Analysis.h BitReader.h BitWriter.h Comdat.h Core.h Error.h ExecutionEngine.h DebugInfo.h IRReader.h Linker.h LLJIT.h OrcEE.h Orc.h Target.h TargetMachine.h Support.h Types.h Transforms/PassBuilder.h" 7 | 8 | for a in $HEADERS; do 9 | OUT="llvm/${a%.h}.nim" 10 | $C2NIM $C2NIMFLAGS $LLVM_INC/llvm-c/$a -o:$OUT 11 | 12 | # Seems to be no way to get just importc and not dynlib, but since 13 | # we'll be linking llvm statically, we'll need it just so 14 | # perl -i -p -e 's/",\s*/",/g' $OUT 15 | # perl -i -p -e 's/,\s*dynlib: LLVMLib//g' $OUT 16 | 17 | # workaround for upstream bug 18 | sed -i -e 's/ptr opaque/ptr Opaque/' $OUT 19 | sed -i -e 's/ptr orcOpaque/ptr OrcOpaque/' $OUT 20 | 21 | # workaround for reserved keword 22 | sed -i -e 's/sizeOf/sizeOfX/' $OUT 23 | # workaround for reserved keword 24 | sed -i -e 's/typeOf/typeOfX/' $OUT 25 | 26 | sed -i -e "s/uintptrT/uint/" $OUT 27 | 28 | nph llvm 29 | 30 | done 31 | -------------------------------------------------------------------------------- /llvm/wrapper.cc: -------------------------------------------------------------------------------- 1 | #include "llvm/IR/Constants.h" 2 | #include "llvm/IR/DIBuilder.h" 3 | #include "llvm/IR/DebugInfo.h" 4 | #include "llvm/IR/Module.h" 5 | 6 | #include "llvm/Support/CodeGen.h" 7 | 8 | #include "llvm/CodeGen/CommandFlags.h" 9 | #include "llvm/MC/TargetRegistry.h" 10 | #include "llvm/Target/CodeGenCWrappers.h" 11 | #include "llvm/Target/TargetMachine.h" 12 | 13 | #include "lld/Common/Driver.h" 14 | 15 | #include "llvm-c/Types.h" 16 | #include "llvm-c/Core.h" 17 | #include "llvm-c/TargetMachine.h" 18 | 19 | using namespace llvm; 20 | 21 | typedef DIBuilder *LLVMNimDIBuilderRef; 22 | 23 | template inline DIT *unwrapDIPtr(LLVMMetadataRef Ref) { 24 | return (DIT *)(Ref ? unwrap(Ref) : nullptr); 25 | } 26 | 27 | static MDNode *extractMDNode(MetadataAsValue *MAV) { 28 | Metadata *MD = MAV->getMetadata(); 29 | assert((isa(MD) || isa(MD)) && 30 | "Expected a metadata node or a canonicalized constant"); 31 | 32 | if (MDNode *N = dyn_cast(MD)) 33 | return N; 34 | 35 | return MDNode::get(MAV->getContext(), MD); 36 | } 37 | 38 | using LLVMNimDIFlags = uint32_t; 39 | 40 | extern "C" void LLVMNimDICompositeTypeSetTypeArray(LLVMNimDIBuilderRef Builder, 41 | LLVMMetadataRef CompositeTy, 42 | LLVMMetadataRef TyArray) { 43 | DICompositeType *Tmp = unwrapDIPtr(CompositeTy); 44 | Builder->replaceArrays(Tmp, DINodeArray(unwrap(TyArray))); 45 | } 46 | 47 | extern "C" void LLVMNimSetMetadataGlobal(LLVMValueRef Global, 48 | unsigned KindID, 49 | LLVMValueRef Val) { 50 | MDNode *N = Val ? extractMDNode(unwrap(Val)) : nullptr; 51 | 52 | unwrap(Global)->setMetadata(KindID, N); 53 | } 54 | 55 | LLD_HAS_DRIVER(elf) 56 | extern "C" bool LLVMNimLLDLinkElf(const char **args, size_t arg_count) { 57 | ArrayRef array_ref_args(args, arg_count); 58 | return lld::elf::link(array_ref_args, llvm::outs(), llvm::errs(), false, false); 59 | } 60 | 61 | LLD_HAS_DRIVER(wasm) 62 | extern "C" bool LLVMNimLLDLinkWasm(const char **args, size_t arg_count) { 63 | ArrayRef array_ref_args(args, arg_count); 64 | return lld::wasm::link(array_ref_args, llvm::outs(), llvm::errs(), false, false); 65 | } 66 | 67 | static codegen::RegisterCodeGenFlags CGF; 68 | 69 | static Target *unwrap(LLVMTargetRef P) { 70 | return reinterpret_cast(P); 71 | } 72 | static LLVMTargetMachineRef wrap(const TargetMachine *P) { 73 | return reinterpret_cast(const_cast(P)); 74 | } 75 | 76 | extern "C" LLVMTargetMachineRef LLVMNimCreateTargetMachine(LLVMTargetRef T, 77 | const char *TT, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, 78 | LLVMCodeModel CodeModel) { 79 | // This function is needed to register and use the common codegen flags - 80 | // in particular when using lld which doesn't support mixed `.ctors` and 81 | // `.init_array` sections and is made to work by using `.init_array` 82 | // alone 83 | 84 | std::optional RM; 85 | switch (Reloc){ 86 | case LLVMRelocStatic: 87 | RM = Reloc::Static; 88 | break; 89 | case LLVMRelocPIC: 90 | RM = Reloc::PIC_; 91 | break; 92 | case LLVMRelocDynamicNoPic: 93 | RM = Reloc::DynamicNoPIC; 94 | break; 95 | case LLVMRelocROPI: 96 | RM = Reloc::ROPI; 97 | break; 98 | case LLVMRelocRWPI: 99 | RM = Reloc::RWPI; 100 | break; 101 | case LLVMRelocROPI_RWPI: 102 | RM = Reloc::ROPI_RWPI; 103 | break; 104 | default: 105 | break; 106 | } 107 | 108 | bool JIT; 109 | std::optional CM = unwrap(CodeModel, JIT); 110 | 111 | CodeGenOptLevel OL; 112 | switch (Level) { 113 | case LLVMCodeGenLevelNone: 114 | OL = CodeGenOptLevel::None; 115 | break; 116 | case LLVMCodeGenLevelLess: 117 | OL = CodeGenOptLevel::Less; 118 | break; 119 | case LLVMCodeGenLevelAggressive: 120 | OL = CodeGenOptLevel::Aggressive; 121 | break; 122 | default: 123 | OL = CodeGenOptLevel::Default; 124 | break; 125 | } 126 | 127 | TargetOptions opt = codegen::InitTargetOptionsFromCodeGenFlags(Triple(TT)); 128 | return wrap(unwrap(T)->createTargetMachine(TT, codegen::getCPUStr(), 129 | codegen::getFeaturesStr(), opt, RM, 130 | CM, OL, JIT)); 131 | } 132 | 133 | extern "C" void LLVMNimSetFunctionAttributes(LLVMValueRef FV) { 134 | auto F = unwrap(FV); 135 | 136 | codegen::setFunctionAttributes( 137 | codegen::getCPUStr(), codegen::getFeaturesStr(), *F); 138 | } 139 | -------------------------------------------------------------------------------- /make-dist-docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Experimental release script 4 | 5 | set -e 6 | 7 | ROOT=nlvm-build-root 8 | 9 | rm -rf $ROOT 10 | 11 | # Make sure the nlvm binary is fresh 12 | rm -f nlvm/nlvmr 13 | make STATIC_LLVM=1 nlvm/nlvmr 14 | 15 | # Copy nlvm and library files 16 | # TODO these would go in /usr/{bin, share/Nim} normally 17 | mkdir -p $ROOT 18 | cp nlvm/nlvmr $ROOT/nlvm 19 | cp -r nlvm-lib $ROOT 20 | mkdir -p $ROOT/Nim 21 | cd Nim 22 | # avoid build junk 23 | git archive --format=tar HEAD lib config compiler doc | (cd ../$ROOT/Nim && tar xf -) 24 | cd .. 25 | mkdir -p /usr/lib/nlvm 26 | cp -av $ROOT/* /usr/lib/nlvm 27 | ln -s /usr/lib/nlvm/nlvm /usr/bin/nlvm 28 | -------------------------------------------------------------------------------- /make-dist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Experimental release script 4 | 5 | set -e 6 | 7 | ROOT=nlvm-$(git rev-parse --short HEAD) 8 | 9 | rm -rf $ROOT 10 | 11 | # Make sure the nlvm binary is fresh 12 | rm -f nlvm/nlvmr 13 | make STATIC_LLVM=1 nlvm/nlvmr 14 | 15 | # Copy nlvm and library files 16 | # TODO these would go in /usr/{bin, share/Nim} normally 17 | mkdir -p $ROOT 18 | cp nlvm/nlvmr $ROOT/nlvm 19 | cp -r nlvm-lib $ROOT 20 | mkdir -p $ROOT/Nim 21 | cd Nim 22 | # avoid build junk 23 | git archive --format=tar HEAD lib config | (cd ../$ROOT/Nim && tar xf -) 24 | cd .. 25 | 26 | rm -rf dist 27 | mkdir -p dist 28 | tar cvfJ dist/$ROOT.tar.xz $ROOT/ 29 | 30 | # AppImages have some more requirements - set these up now 31 | cd $ROOT 32 | ln -s nlvm AppRun 33 | echo "[Desktop Entry] 34 | Name=nlvm 35 | Exec=AppRun 36 | Icon=nlvm 37 | Type=Application 38 | Categories=Development; 39 | " > nlvm.desktop 40 | 41 | # TODO 42 | touch nlvm.png 43 | 44 | cd .. 45 | 46 | mkdir -p ext 47 | 48 | [ -f ext/appimagetool-x86_64.AppImage ] || { 49 | wget -P ext/ https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage 50 | chmod +x ext/appimagetool-x86_64.AppImage 51 | } 52 | 53 | ext/appimagetool-x86_64.AppImage $ROOT 54 | mv nlvm*.AppImage dist/ 55 | 56 | rm -rf $ROOT 57 | -------------------------------------------------------------------------------- /make-llvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Build llvm, as used in the Makefile 4 | # A bit broken because it doesn't track cmake options and deps correctly 5 | 6 | [ $# -gt 4 ] || { 7 | echo "$0 major minor patch output_dir cmake_options*" 8 | exit 1 9 | } 10 | 11 | set -e 12 | 13 | mkdir -p ext 14 | cd ext 15 | 16 | VER="$1.$2" 17 | VER2="$VER.$3" 18 | TGT="$4" 19 | 20 | LLVM_ROOT=llvm-$VER2.src 21 | LLD_ROOT=lld-$VER2.src 22 | CMAKE_ROOT=cmake-$VER2.src 23 | 24 | [ -f $LLVM_ROOT.tar.xz ] || { 25 | wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$VER2/$LLVM_ROOT.tar.xz 26 | } 27 | 28 | [ -f $LLVM_ROOT/CMakeLists.txt ] || { 29 | tar xf $LLVM_ROOT.tar.xz 30 | } 31 | 32 | [ -f $LLD_ROOT.tar.xz ] || { 33 | wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$VER2/$LLD_ROOT.tar.xz 34 | } 35 | 36 | [ -f $LLD_ROOT/CMakeLists.txt ] || { 37 | tar xf $LLD_ROOT.tar.xz 38 | } 39 | 40 | [ -d $LLVM_ROOT/projects/lld ] || { 41 | rm -rf $LLVM_ROOT/projects/lld 42 | cd $LLVM_ROOT/projects 43 | ln -sfr ../../$LLD_ROOT lld 44 | cd ../.. 45 | } 46 | 47 | [ -f $CMAKE_ROOT.tar.xz ] || { 48 | wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$VER2/$CMAKE_ROOT.tar.xz 49 | } 50 | 51 | [ -f $CMAKE_ROOT/README.rst ] || { 52 | tar xf $CMAKE_ROOT.tar.xz 53 | } 54 | 55 | rm -f cmake 56 | ln -s $CMAKE_ROOT cmake 57 | 58 | [ -f libunwind-$VER2.src.tar.xz ] || { 59 | wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$VER2/libunwind-$VER2.src.tar.xz 60 | } 61 | 62 | [ -f libunwind-$VER2/CMakeLists.txt ] || { 63 | tar xf libunwind-$VER2.src.tar.xz 64 | cp -ar libunwind-$VER2.src/include/mach-o $LLD_ROOT/include 65 | } 66 | 67 | cd $LLVM_ROOT 68 | 69 | mkdir -p $TGT 70 | cd $TGT 71 | 72 | shift 4 73 | cmake -GNinja -DLLVM_USE_LINKER=lld "$@" .. 74 | 75 | ninja 76 | -------------------------------------------------------------------------------- /nlvm-lib/nlvm_unwind.nim: -------------------------------------------------------------------------------- 1 | # Converted `unwind.h` from llvm libunwind - this _should_ be compatible 2 | # with other unwind libraries as well (?) 3 | # TODO investigate this further 4 | # TODO arm EH ABI 5 | # TODO sj/lj ABI 6 | # TODO SEH 7 | # TODO alignment! 8 | 9 | const 10 | # UnwindReasonCode 11 | URC_NO_REASON* = 0 12 | URC_FOREIGN_EXCEPTION_CAUGHT* = 1 13 | URC_FATAL_PHASE2_ERROR* = 2 14 | URC_FATAL_PHASE1_ERROR* = 3 15 | URC_NORMAL_STOP* = 4 16 | URC_END_OF_STACK* = 5 17 | URC_HANDLER_FOUND* = 6 18 | URC_INSTALL_CONTEXT* = 7 19 | URC_CONTINUE_UNWIND* = 8 20 | 21 | const 22 | # UnwindAction 23 | UA_SEARCH_PHASE* = 1 24 | UA_CLEANUP_PHASE* = 2 25 | UA_HANDLER_FRAME* = 4 26 | UA_FORCE_UNWIND* = 8 27 | UA_END_OF_STACK* = 16 28 | 29 | UNWIND_DATA_REG* = 30 | # see __builtin_eh_return_data / clang "getEHDataRegisterNumber" - this 31 | # list is incomplete 32 | when defined(x86): 33 | [0.cint, 2] 34 | else: 35 | [0.cint, 1] 36 | 37 | type 38 | # c(uintptr_t) == nim(uint) 39 | UnwindReasonCode* = cint # c enum 40 | UnwindAction* = cint # c enum 41 | UnwindContext* = distinct pointer 42 | UnwindExceptionCleanupFn* = 43 | proc(unwindCode: UnwindReasonCode, exception: ptr UnwindException) {.cdecl.} 44 | UnwindStopFn* = proc( 45 | version: cint, 46 | actions: UnwindAction, 47 | exceptionClass: uint64, 48 | exception: ptr UnwindException, 49 | ctx: UnwindContext, 50 | parameter: pointer, 51 | ) {.cdecl.} 52 | 53 | UnwindException* = object 54 | exceptionClass*: uint64 55 | exceptionCleanup*: UnwindExceptionCleanupFn 56 | private1, private2: uint 57 | 58 | when sizeof(pointer) == 4: 59 | reserved: array[3, uint32] 60 | 61 | proc raiseException*( 62 | exception: ptr UnwindException 63 | ): UnwindReasonCode {.importc: "_Unwind_RaiseException".} 64 | 65 | proc resume*(exception: ptr UnwindException) {.importc: "_Unwind_Resume".} 66 | proc deleteException*( 67 | exception: ptr UnwindException 68 | ) {.importc: "_Unwind_DeleteException".} 69 | 70 | func getGR*(ctx: UnwindContext, reg_index: cint): uint {.importc: "_Unwind_GetGR".} 71 | proc setGR*( 72 | ctx: UnwindContext, reg_index: cint, value: uint 73 | ) {.importc: "_Unwind_SetGR".} 74 | 75 | func getIP*(ctx: UnwindContext): uint {.importc: "_Unwind_GetIP".} 76 | proc setIP*(ctx: UnwindContext, value: uint) {.importc: "_Unwind_SetIP".} 77 | 78 | func getRegionStart*(ctx: UnwindContext): uint {.importc: "_Unwind_GetRegionStart".} 79 | func getLanguageSpecificData*( 80 | ctx: UnwindContext 81 | ): uint {.importc: "_Unwind_GetLanguageSpecificData".} 82 | proc forcedUnwind*( 83 | exception: ptr UnwindException, stop: UnwindStopFn, parameter: pointer 84 | ) {.importc: "_Unwind_ForcedUnwind".} 85 | 86 | proc resumeOrRethrow*( 87 | exception: ptr UnwindException 88 | ): UnwindReasonCode {.importc: "_Unwind_Resume_Or_Rethrow".} 89 | 90 | type UnwindTraceFn* = proc(ctx: UnwindContext, parameter: pointer) {.cdecl.} 91 | proc backtrace*( 92 | traceFn: UnwindTraceFn, parameter: pointer 93 | ) {.importc: "_Unwind_Backtrace".} 94 | 95 | func getCFA*(ctx: UnwindContext): uint {.importc: "_Unwind_GetCFA".} 96 | 97 | proc getIPInfo*( 98 | ctx: UnwindContext, ipBefore: ptr cint 99 | ): uint {.importc: "_Unwind_GetIPInfo".} 100 | 101 | type DwarfEhBases* = object 102 | tbase*: uint 103 | dbase*: uint 104 | fnc*: uint 105 | 106 | proc findFDE*( 107 | pc: pointer, bases: ptr DwarfEhBases 108 | ): pointer {.importc: "_Unwind_Find_FDE".} 109 | 110 | proc findEnclosingFunction*( 111 | pc: pointer 112 | ): pointer {.importc: "_Unwind_FindEnclosingFunction".} 113 | 114 | func getDataRelBase*(ctx: UnwindContext): uint {.importc: "_Unwind_GetDataRelBase".} 115 | func getTextRelBase*(ctx: UnwindContext): uint {.importc: "_Unwind_GetTextRelBase".} 116 | -------------------------------------------------------------------------------- /nlvm-lib/nlvmbase-amd64-Linux.ll: -------------------------------------------------------------------------------- 1 | ; Workarounds for: 2 | ; * bugs in nlvm 3 | ; * nim standard library including macros from header files 4 | ; * stuff in nimbase.h 5 | ; For this to go away, one would have to patch upstream to 6 | ; avoid depending on c headers in the stdlib, and fix some bugs 7 | ; in nlvm 8 | 9 | target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" 10 | target triple = "x86_64-unknown-linux-gnu" 11 | 12 | ; ioctls.h 13 | @FIONCLEX = linkonce_odr constant i32 21584 14 | @FIOCLEX = linkonce_odr constant i32 21585 15 | 16 | ; pthreads.h 17 | @PTHREAD_MUTEX_RECURSIVE = linkonce_odr constant i32 1 18 | @PTHREAD_BARRIER_SERIAL_THREAD = linkonce_odr constant i32 -1 19 | 20 | ; signal.h 21 | @SIG_IGN = linkonce_odr constant void (i32)* inttoptr (i64 1 to void (i32)*), align 8 22 | @SEGV_MAPERR = linkonce_odr constant i32 1 23 | 24 | ; stdio.h 25 | @_IOFBF = linkonce_odr constant i32 0 26 | @_IOLBF = linkonce_odr constant i32 1 27 | @_IONBF = linkonce_odr constant i32 2 28 | @L_ctermid = linkonce_odr constant i32 9 29 | 30 | ; syscall.h 31 | @SYS_getrandom = linkonce_odr constant i32 318 32 | 33 | ; sys/ioctl.h 34 | @TIOCGWINSZ = linkonce_odr constant i32 21523 35 | 36 | ; time.h 37 | @CLOCK_REALTIME = linkonce_odr constant i32 0 38 | @CLOCKS_PER_SEC = linkonce_odr constant i64 1000000 39 | 40 | ; termios.h 41 | @VINTR = linkonce_odr constant i32 0 42 | @VQUIT = linkonce_odr constant i32 1 43 | @VERASE = linkonce_odr constant i32 2 44 | @VKILL = linkonce_odr constant i32 3 45 | @VEOF = linkonce_odr constant i32 4 46 | @VTIME = linkonce_odr constant i32 5 47 | @VMIN = linkonce_odr constant i32 6 48 | @VSTART = linkonce_odr constant i32 8 49 | @VSTOP = linkonce_odr constant i32 9 50 | @VSUSP = linkonce_odr constant i32 10 51 | @VEOL = linkonce_odr constant i32 11 52 | @IGNBRK = linkonce_odr constant i32 1 53 | @BRKINT = linkonce_odr constant i32 2 54 | @IGNPAR = linkonce_odr constant i32 4 55 | @PARMRK = linkonce_odr constant i32 8 56 | @INPCK = linkonce_odr constant i32 16 57 | @ISTRIP = linkonce_odr constant i32 32 58 | @INLCR = linkonce_odr constant i32 64 59 | @IGNCR = linkonce_odr constant i32 128 60 | @ICRNL = linkonce_odr constant i32 256 61 | @IUCLC = linkonce_odr constant i32 512 62 | @IXON = linkonce_odr constant i32 1024 63 | @IXANY = linkonce_odr constant i32 2048 64 | @IXOFF = linkonce_odr constant i32 4096 65 | @OPOST = linkonce_odr constant i32 1 66 | @ONLCR = linkonce_odr constant i32 4 67 | @OCRNL = linkonce_odr constant i32 8 68 | @ONOCR = linkonce_odr constant i32 16 69 | @ONLRET = linkonce_odr constant i32 32 70 | @OFILL = linkonce_odr constant i32 64 71 | @OFDEL = linkonce_odr constant i32 128 72 | @NLDLY = linkonce_odr constant i32 256 73 | @NL0 = linkonce_odr constant i32 0 74 | @NL1 = linkonce_odr constant i32 256 75 | @CRDLY = linkonce_odr constant i32 1536 76 | @CR0 = linkonce_odr constant i32 0 77 | @CR1 = linkonce_odr constant i32 512 78 | @CR2 = linkonce_odr constant i32 1024 79 | @CR3 = linkonce_odr constant i32 1536 80 | @TABDLY = linkonce_odr constant i32 6144 81 | @TAB0 = linkonce_odr constant i32 0 82 | @TAB1 = linkonce_odr constant i32 2048 83 | @TAB2 = linkonce_odr constant i32 4096 84 | @TAB3 = linkonce_odr constant i32 6144 85 | @BSDLY = linkonce_odr constant i32 8192 86 | @BS0 = linkonce_odr constant i32 0 87 | @BS1 = linkonce_odr constant i32 8192 88 | @FFDLY = linkonce_odr constant i32 32768 89 | @FF0 = linkonce_odr constant i32 0 90 | @FF1 = linkonce_odr constant i32 32768 91 | @VTDLY = linkonce_odr constant i32 16384 92 | @VT0 = linkonce_odr constant i32 0 93 | @VT1 = linkonce_odr constant i32 16384 94 | @B0 = linkonce_odr constant i32 0 95 | @B50 = linkonce_odr constant i32 1 96 | @B75 = linkonce_odr constant i32 2 97 | @B110 = linkonce_odr constant i32 3 98 | @B134 = linkonce_odr constant i32 4 99 | @B150 = linkonce_odr constant i32 5 100 | @B200 = linkonce_odr constant i32 6 101 | @B300 = linkonce_odr constant i32 7 102 | @B600 = linkonce_odr constant i32 8 103 | @B1200 = linkonce_odr constant i32 9 104 | @B1800 = linkonce_odr constant i32 10 105 | @B2400 = linkonce_odr constant i32 11 106 | @B4800 = linkonce_odr constant i32 12 107 | @B9600 = linkonce_odr constant i32 13 108 | @B19200 = linkonce_odr constant i32 14 109 | @B38400 = linkonce_odr constant i32 15 110 | @EXTA = linkonce_odr constant i32 14 111 | @EXTB = linkonce_odr constant i32 15 112 | @CSIZE = linkonce_odr constant i32 48 113 | @CS5 = linkonce_odr constant i32 0 114 | @CS6 = linkonce_odr constant i32 16 115 | @CS7 = linkonce_odr constant i32 32 116 | @CS8 = linkonce_odr constant i32 48 117 | @CSTOPB = linkonce_odr constant i32 64 118 | @CREAD = linkonce_odr constant i32 128 119 | @PARENB = linkonce_odr constant i32 256 120 | @PARODD = linkonce_odr constant i32 512 121 | @HUPCL = linkonce_odr constant i32 1024 122 | @CLOCAL = linkonce_odr constant i32 2048 123 | @ISIG = linkonce_odr constant i32 1 124 | @ICANON = linkonce_odr constant i32 2 125 | @ECHO = linkonce_odr constant i32 8 126 | @ECHOE = linkonce_odr constant i32 16 127 | @ECHOK = linkonce_odr constant i32 32 128 | @ECHONL = linkonce_odr constant i32 64 129 | @NOFLSH = linkonce_odr constant i32 128 130 | @TOSTOP = linkonce_odr constant i32 256 131 | @IEXTEN = linkonce_odr constant i32 32768 132 | @TCOOFF = linkonce_odr constant i32 0 133 | @TCOON = linkonce_odr constant i32 1 134 | @TCIOFF = linkonce_odr constant i32 2 135 | @TCION = linkonce_odr constant i32 3 136 | @TCIFLUSH = linkonce_odr constant i32 0 137 | @TCOFLUSH = linkonce_odr constant i32 1 138 | @TCIOFLUSH = linkonce_odr constant i32 2 139 | @TCSANOW = linkonce_odr constant i32 0 140 | @TCSADRAIN = linkonce_odr constant i32 1 141 | @TCSAFLUSH = linkonce_odr constant i32 2 142 | @EINTR = linkonce_odr constant i32 4 143 | 144 | 145 | ; unistd.h 146 | define linkonce_odr i8 @S_ISDIR(i32 %m) { 147 | %1 = and i32 %m, 61440 148 | %2 = icmp eq i32 %1, 16384 149 | %3 = zext i1 %2 to i8 150 | ret i8 %3 151 | } 152 | define linkonce_odr i8 @S_ISCHR(i32 %m) { 153 | %1 = and i32 %m, 61440 154 | %2 = icmp eq i32 %1, 8192 155 | %3 = zext i1 %2 to i8 156 | ret i8 %3 157 | } 158 | define linkonce_odr i8 @S_ISBLK(i32 %m) { 159 | %1 = and i32 %m, 61440 160 | %2 = icmp eq i32 %1, 24576 161 | %3 = zext i1 %2 to i8 162 | ret i8 %3 163 | } 164 | define linkonce_odr i8 @S_ISREG(i32 %m) { 165 | %1 = and i32 %m, 61440 166 | %2 = icmp eq i32 %1, 32768 167 | %3 = zext i1 %2 to i8 168 | ret i8 %3 169 | } 170 | define linkonce_odr i8 @S_ISFIFO(i32 %m) { 171 | %1 = and i32 %m, 61440 172 | %2 = icmp eq i32 %1, 4096 173 | %3 = zext i1 %2 to i8 174 | ret i8 %3 175 | } 176 | define linkonce_odr i8 @S_ISLNK(i32 %m) { 177 | %1 = and i32 %m, 61440 178 | %2 = icmp eq i32 %1, 40960 179 | %3 = zext i1 %2 to i8 180 | ret i8 %3 181 | } 182 | define linkonce_odr i8 @S_ISSOCK(i32 %m) { 183 | %1 = and i32 %m, 61440 184 | %2 = icmp eq i32 %1, 49152 185 | %3 = zext i1 %2 to i8 186 | ret i8 %3 187 | } 188 | ; sys/select.h 189 | %fd_set = type { [16 x i64] } 190 | 191 | define linkonce_odr void @FD_ZERO(%fd_set* %0) { 192 | %2 = alloca %fd_set*, align 8 193 | %3 = alloca i32, align 4 194 | %4 = alloca %fd_set*, align 8 195 | store %fd_set* %0, %fd_set** %2, align 8 196 | br label %5 197 | 198 | 5: ; preds = %1 199 | %6 = load %fd_set*, %fd_set** %2, align 8 200 | store %fd_set* %6, %fd_set** %4, align 8 201 | store i32 0, i32* %3, align 4 202 | br label %7 203 | 204 | 7: ; preds = %17, %5 205 | %8 = load i32, i32* %3, align 4 206 | %9 = zext i32 %8 to i64 207 | %10 = icmp ult i64 %9, 16 208 | br i1 %10, label %11, label %20 209 | 210 | 11: ; preds = %7 211 | %12 = load %fd_set*, %fd_set** %4, align 8 212 | %13 = getelementptr inbounds %fd_set, %fd_set* %12, i32 0, i32 0 213 | %14 = load i32, i32* %3, align 4 214 | %15 = zext i32 %14 to i64 215 | %16 = getelementptr inbounds [16 x i64], [16 x i64]* %13, i64 0, i64 %15 216 | store i64 0, i64* %16, align 8 217 | br label %17 218 | 219 | 17: ; preds = %11 220 | %18 = load i32, i32* %3, align 4 221 | %19 = add i32 %18, 1 222 | store i32 %19, i32* %3, align 4 223 | br label %7 224 | 225 | 20: ; preds = %7 226 | br label %21 227 | 228 | 21: ; preds = %20 229 | ret void 230 | } 231 | 232 | define linkonce_odr void @FD_SET(i32 %0, %fd_set* %1) { 233 | %3 = alloca i32, align 4 234 | %4 = alloca %fd_set*, align 8 235 | store i32 %0, i32* %3, align 4 236 | store %fd_set* %1, %fd_set** %4, align 8 237 | %5 = load i32, i32* %3, align 4 238 | %6 = srem i32 %5, 64 239 | %7 = zext i32 %6 to i64 240 | %8 = shl i64 1, %7 241 | %9 = load %fd_set*, %fd_set** %4, align 8 242 | %10 = getelementptr inbounds %fd_set, %fd_set* %9, i32 0, i32 0 243 | %11 = load i32, i32* %3, align 4 244 | %12 = sdiv i32 %11, 64 245 | %13 = sext i32 %12 to i64 246 | %14 = getelementptr inbounds [16 x i64], [16 x i64]* %10, i64 0, i64 %13 247 | %15 = load i64, i64* %14, align 8 248 | %16 = or i64 %15, %8 249 | store i64 %16, i64* %14, align 8 250 | ret void 251 | } 252 | 253 | define linkonce_odr i32 @FD_ISSET(i32 %0, %fd_set* %1) { 254 | %3 = alloca i32, align 4 255 | %4 = alloca %fd_set*, align 8 256 | store i32 %0, i32* %3, align 4 257 | store %fd_set* %1, %fd_set** %4, align 8 258 | %5 = load %fd_set*, %fd_set** %4, align 8 259 | %6 = getelementptr inbounds %fd_set, %fd_set* %5, i32 0, i32 0 260 | %7 = load i32, i32* %3, align 4 261 | %8 = sdiv i32 %7, 64 262 | %9 = sext i32 %8 to i64 263 | %10 = getelementptr inbounds [16 x i64], [16 x i64]* %6, i64 0, i64 %9 264 | %11 = load i64, i64* %10, align 8 265 | %12 = load i32, i32* %3, align 4 266 | %13 = srem i32 %12, 64 267 | %14 = zext i32 %13 to i64 268 | %15 = shl i64 1, %14 269 | %16 = and i64 %11, %15 270 | %17 = icmp ne i64 %16, 0 271 | %18 = zext i1 %17 to i32 272 | ret i32 %18 273 | } 274 | 275 | define linkonce_odr i8 @WIFEXITED(i32 %m) { 276 | %1 = and i32 %m, 127 277 | %2 = icmp eq i32 %1, 0 278 | %3 = zext i1 %2 to i8 279 | ret i8 %3 280 | } 281 | 282 | define linkonce_odr i8 @WIFSIGNALED(i32 %m) { 283 | %1 = shl i32 %m, 24 284 | %2 = and i32 %1, 2130706432 285 | %3 = add nuw i32 %2, 16777216 286 | %4 = ashr i32 %3, 25 287 | %5 = icmp sgt i32 %4, 0 288 | %6 = zext i1 %5 to i8 289 | ret i8 %6 290 | } 291 | ; nimbase.h 292 | 293 | declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i32, i1) 294 | 295 | define linkonce_odr void @zeroMem(i8* %p, i64 %s) { 296 | call void @llvm.memset.p0i8.i64(i8* %p, i8 0, i64 %s, i32 0, i1 false) 297 | ret void 298 | } 299 | 300 | declare i32 @memcmp(i8*, i8*, i64) 301 | 302 | define linkonce_odr i8 @equalMem(i8* %a, i8* %b, i64 %l) { 303 | %1 = call i32 @memcmp(i8* %a, i8* %b, i64 %l) 304 | %2 = icmp eq i32 %1, 0 305 | %3 = zext i1 %2 to i8 306 | ret i8 %3 307 | } 308 | 309 | define linkonce_odr i1 @likely(i1 %a) { 310 | ret i1 %a 311 | } 312 | 313 | define linkonce_odr i1 @unlikely(i1 %a) { 314 | ret i1 %a 315 | } 316 | 317 | declare i32 @llvm.bswap.i32(i32) 318 | 319 | define linkonce_odr zeroext i8 @IN6_IS_ADDR_UNSPECIFIED(i8* nocapture readonly) local_unnamed_addr { 320 | %2 = bitcast i8* %0 to i32* 321 | %3 = load i32, i32* %2, align 4 322 | %4 = icmp eq i32 %3, 0 323 | br i1 %4, label %5, label %20 324 | 325 | ;