Skip to content

Commit 84e1b90

Browse files
authored
Allow compilation to other target triples (#109)
1 parent b1240f0 commit 84e1b90

4 files changed

Lines changed: 27 additions & 6 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ Hello, world!
6565
```
6666
This latter approach comes with substantially more limitations, as you cannot rely on `libjulia` (see, e.g., [StaticTools.jl](https://github.com/brenhinkeller/StaticTools.jl) for some ways to work around these limitations).
6767

68+
The low-level function `StaticCompiler.generate_obj` (not exported) generates object files. This can be used for more control of compilation. This can be used to cross-compile to other targets.
69+
6870
### Mixtape
6971

7072
This feature allows one to change functionality when statically compiling. This uses code and API from [Mixtape](https://github.com/JuliaCompilerPlugins/Mixtape.jl) to transform lowered code much like [Cassette](https://github.com/JuliaLabs/Cassette.jl).

src/StaticCompiler.jl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,24 @@ end
115115
"""
116116
```julia
117117
generate_obj(f, tt, path::String = tempname(), name = GPUCompiler.safe_name(repr(f)), filenamebase::String="obj";
118+
\tmixtape = NoContext(),
118119
\tstrip_llvm = false,
119120
\tstrip_asm = true,
121+
\ttarget = (),
120122
\topt_level=3,
121123
\tkwargs...)
122124
```
123125
Low level interface for compiling object code (`.o`) for for function `f` given
124126
a tuple type `tt` characterizing the types of the arguments for which the
125127
function will be compiled.
126128
129+
`mixtape` defines a context that can be used to transform IR prior to compilation using
130+
[Mixtape](https://github.com/JuliaCompilerPlugins/Mixtape.jl) features.
131+
132+
`target` can be used to change the output target. This is useful for compiling to WebAssembly and embedded targets.
133+
This is a named tuple with fields `triple`, `cpu`, and `features` (each of these are strings).
134+
The defaults compile to the native target.
135+
127136
### Examples
128137
```julia
129138
julia> fib(n) = n <= 1 ? n : fib(n - 1) + fib(n - 2)
@@ -144,12 +153,12 @@ function generate_obj(f, tt, external = true, path::String = tempname(), name =
144153
strip_llvm = false,
145154
strip_asm = true,
146155
opt_level=3,
156+
target = (),
147157
kwargs...)
148158
mkpath(path)
149159
obj_path = joinpath(path, "$filenamebase.o")
150-
tm = GPUCompiler.llvm_machine(external ? ExternalNativeCompilerTarget() : NativeCompilerTarget())
151160
#Get LLVM to generated a module of code for us. We don't want GPUCompiler's optimization passes.
152-
job = CompilerJob(NativeCompilerTarget(),
161+
job = CompilerJob(NativeCompilerTarget(target...),
153162
FunctionSpec(f, tt, false, name),
154163
StaticCompilerParams(;
155164
opt = true,
@@ -162,6 +171,7 @@ function generate_obj(f, tt, external = true, path::String = tempname(), name =
162171

163172
# Use Enzyme's annotation and optimization pipeline
164173
annotate!(mod)
174+
tm = GPUCompiler.llvm_machine(external ? ExternalNativeCompilerTarget(target...) : NativeCompilerTarget(target...))
165175
optimize!(mod, tm)
166176

167177
# Scoop up all the pointers in the optimized module, and replace them with unitialized global variables.

src/target.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ macro device_override(ex)
3636
end
3737

3838
Base.@kwdef struct NativeCompilerTarget <: GPUCompiler.AbstractCompilerTarget
39+
triple::String=Sys.MACHINE
3940
cpu::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUName())
4041
features::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUFeatures())
4142
end
4243

4344
Base.@kwdef struct ExternalNativeCompilerTarget <: GPUCompiler.AbstractCompilerTarget
45+
triple::String=Sys.MACHINE
4446
cpu::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUName())
4547
features::String=(LLVM.version() < v"8") ? "" : unsafe_string(LLVM.API.LLVMGetHostCPUFeatures())
4648
end
@@ -57,7 +59,7 @@ end
5759

5860
for target in (:NativeCompilerTarget, :ExternalNativeCompilerTarget)
5961
@eval begin
60-
GPUCompiler.llvm_triple(::$target) = Sys.MACHINE
62+
GPUCompiler.llvm_triple(target::$target) = target.triple
6163

6264
function GPUCompiler.llvm_machine(target::$target)
6365
triple = GPUCompiler.llvm_triple(target)
@@ -94,17 +96,18 @@ function native_job(@nospecialize(func::Function), @nospecialize(types::Type), e
9496
mixtape = NoContext(),
9597
name = GPUCompiler.safe_name(repr(func)),
9698
kernel::Bool = false,
99+
target = (),
97100
kwargs...
98101
)
99102
source = GPUCompiler.FunctionSpec(func, types, kernel, name)
100-
target = external ? ExternalNativeCompilerTarget() : NativeCompilerTarget()
103+
target = external ? ExternalNativeCompilerTarget(;target...) : NativeCompilerTarget(;target...)
101104
params = StaticCompilerParams(mixtape = mixtape)
102105
StaticCompiler.CompilerJob(target, source, params), kwargs
103106
end
104107

105-
function native_job(@nospecialize(func), @nospecialize(types), external; mixtape = NoContext(), kernel::Bool=false, name=GPUCompiler.safe_name(repr(func)), kwargs...)
108+
function native_job(@nospecialize(func), @nospecialize(types), external; mixtape = NoContext(), kernel::Bool=false, name=GPUCompiler.safe_name(repr(func)), target = (), kwargs...)
106109
source = GPUCompiler.FunctionSpec(func, Base.to_tuple_type(types), kernel, name)
107-
target = external ? ExternalNativeCompilerTarget() : NativeCompilerTarget()
110+
target = external ? ExternalNativeCompilerTarget(;target...) : NativeCompilerTarget(;target...)
108111
params = StaticCompilerParams(mixtape = mixtape)
109112
GPUCompiler.CompilerJob(target, source, params), kwargs
110113
end

test/testintegration.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,9 @@ struct MyMix <: CompilationContext end
383383

384384
end
385385

386+
@testset "Cross compiling" begin
387+
388+
x, obj_path = StaticCompiler.generate_obj(x -> 2x, Tuple{Float64}, true, tempname(); target = (triple = "wasm32-unknown-wasi", cpu = "", features = ""))
389+
390+
end
391+

0 commit comments

Comments
 (0)