Compare commits

...

10 Commits

Author SHA1 Message Date
60a73dc1c4 nac3ld: support shortened address retrieval for memory access 2025-02-21 16:46:15 +08:00
683daae31e msys2: regenerate packages 2025-02-20 19:01:24 +08:00
b565211df6 msys2: add inkwell hash 2025-02-20 18:48:16 +08:00
1e5fd99a88 flake: add inkwell hash 2025-02-20 18:31:56 +08:00
2df4a5e9bd [core] Update to use custom inkwell
For LLVM 16 support with typed pointers.
2025-02-20 13:29:16 +08:00
b006bdd96b llvm: update to 16, simplify nix files 2025-02-20 13:29:16 +08:00
fffdaf36d3 [meta] Apply clippy suggestions 2025-02-20 11:27:46 +08:00
acb47154dc nac3core: support custom context managers 2025-02-19 22:25:48 +08:00
e917c57339 [core] codegen: Fixup generate_linalg_extern_fn macro
- Use `ident` for `extern_fn` name
- Fixup formatting
2025-02-19 12:48:52 +08:00
eb6f0a1abc [core] codegen/irrt: Migrate compiler builtin functions to IRRT
Saves us from having to manually declare functions and their
corresponding attributes.
2025-02-19 12:14:40 +08:00
25 changed files with 822 additions and 611 deletions

18
Cargo.lock generated
View File

@ -465,8 +465,7 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
[[package]]
name = "inkwell"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40fb405537710d51f6bdbc8471365ddd4cd6d3a3c3ad6e0c8291691031ba94b2"
source = "git+https://github.com/Derppening/inkwell?tag=0.5.0_llvm15-typed-ptr#9c70145c6aaa29be79715fc4998df9da67575ecf"
dependencies = [
"either",
"inkwell_internals",
@ -479,8 +478,7 @@ dependencies = [
[[package]]
name = "inkwell_internals"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd28cfd4cfba665d47d31c08a6ba637eed16770abca2eccbbc3ca831fef1e44"
source = "git+https://github.com/Derppening/inkwell?tag=0.5.0_llvm15-typed-ptr#9c70145c6aaa29be79715fc4998df9da67575ecf"
dependencies = [
"proc-macro2",
"quote",
@ -598,9 +596,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "llvm-sys"
version = "140.1.3"
version = "160.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3dc78e9857c0231ec11e3bdccf63870493fdc7d0570b0ea7d50bf5df0cb1a0c"
checksum = "e73861901245d32e1c3d8b35b639cf100859b4cd0c9da56fe0273040acbb3ea4"
dependencies = [
"cc",
"lazy_static",
@ -1389,9 +1387,9 @@ dependencies = [
[[package]]
name = "typenum"
version = "1.17.0"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "unic-char-property"
@ -1447,9 +1445,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.16"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
[[package]]
name = "unicode-width"

View File

@ -13,8 +13,8 @@
llvm-tools-irrt = pkgs.runCommandNoCC "llvm-tools-irrt" {}
''
mkdir -p $out/bin
ln -s ${pkgs.llvmPackages_14.clang-unwrapped}/bin/clang $out/bin/clang-irrt
ln -s ${pkgs.llvmPackages_14.llvm.out}/bin/llvm-as $out/bin/llvm-as-irrt
ln -s ${pkgs.llvmPackages_16.clang-unwrapped}/bin/clang $out/bin/clang-irrt
ln -s ${pkgs.llvmPackages_16.llvm.out}/bin/llvm-as $out/bin/llvm-as-irrt
'';
demo-linalg-stub = pkgs.rustPlatform.buildRustPackage {
name = "demo-linalg-stub";
@ -39,9 +39,12 @@
src = self;
cargoLock = {
lockFile = ./Cargo.lock;
outputHashes = {
"inkwell-0.5.0" = "sha256-Qsqy/fhD/qK0rKBeXetE99vW9G9XAePxlXv0An3Yeuo=";
};
};
passthru.cargoLock = cargoLock;
nativeBuildInputs = [ pkgs.python3 (pkgs.wrapClangMulti pkgs.llvmPackages_14.clang) llvm-tools-irrt pkgs.llvmPackages_14.llvm.out pkgs.llvmPackages_14.bintools llvm-nac3 ];
nativeBuildInputs = [ pkgs.python3 (pkgs.wrapClangMulti pkgs.llvmPackages_16.clang) llvm-tools-irrt pkgs.llvmPackages_16.llvm.out pkgs.llvmPackages_16.bintools llvm-nac3 ];
buildInputs = [ pkgs.python3 llvm-nac3 ];
checkInputs = [ (pkgs.python3.withPackages(ps: [ ps.numpy ps.scipy ])) ];
checkPhase =
@ -77,7 +80,7 @@
# LLVM PGO support
llvm-nac3-instrumented = pkgs.callPackage ./nix/llvm {
stdenv = pkgs.llvmPackages_14.stdenv;
stdenv = pkgs.llvmPackages_16.stdenv;
extraCmakeFlags = [ "-DLLVM_BUILD_INSTRUMENTED=IR" ];
};
nac3artiq-instrumented = pkgs.python3Packages.toPythonModule (
@ -85,13 +88,13 @@
name = "nac3artiq-instrumented";
src = self;
inherit (nac3artiq) cargoLock;
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt pkgs.llvmPackages_14.bintools llvm-nac3-instrumented ];
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt pkgs.llvmPackages_16.bintools llvm-nac3-instrumented ];
buildInputs = [ pkgs.python3 llvm-nac3-instrumented ];
cargoBuildFlags = [ "--package" "nac3artiq" "--features" "init-llvm-profile" ];
doCheck = false;
configurePhase =
''
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=-L${pkgs.llvmPackages_14.compiler-rt}/lib/linux -C link-arg=-lclang_rt.profile-x86_64"
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=-L${pkgs.llvmPackages_16.compiler-rt}/lib/linux -C link-arg=-lclang_rt.profile-x86_64"
'';
installPhase =
''
@ -119,8 +122,8 @@
];
buildInputs = [
(python3-mimalloc.withPackages(ps: [ ps.numpy ps.scipy ps.jsonschema ps.lmdb ps.platformdirs nac3artiq-instrumented ]))
pkgs.llvmPackages_14.llvm.out
pkgs.llvmPackages_14.bintools
pkgs.llvmPackages_16.llvm.out
pkgs.llvmPackages_16.bintools
];
phases = [ "buildPhase" "installPhase" ];
buildPhase =
@ -140,7 +143,7 @@
'';
};
llvm-nac3-pgo = pkgs.callPackage ./nix/llvm {
stdenv = pkgs.llvmPackages_14.stdenv;
stdenv = pkgs.llvmPackages_16.stdenv;
extraCmakeFlags = [ "-DLLVM_PROFDATA_FILE=${nac3artiq-profile}/llvm.profdata" ];
};
nac3artiq-pgo = pkgs.python3Packages.toPythonModule (
@ -148,7 +151,7 @@
name = "nac3artiq-pgo";
src = self;
inherit (nac3artiq) cargoLock;
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt pkgs.llvmPackages_14.bintools llvm-nac3-pgo ];
nativeBuildInputs = [ pkgs.python3 packages.x86_64-linux.llvm-tools-irrt pkgs.llvmPackages_16.bintools llvm-nac3-pgo ];
buildInputs = [ pkgs.python3 llvm-nac3-pgo ];
cargoBuildFlags = [ "--package" "nac3artiq" ];
cargoTestFlags = [ "--package" "nac3ast" "--package" "nac3parser" "--package" "nac3core" "--package" "nac3artiq" ];
@ -169,12 +172,12 @@
buildInputs = with pkgs; [
# build dependencies
packages.x86_64-linux.llvm-nac3
(pkgs.wrapClangMulti llvmPackages_14.clang) llvmPackages_14.llvm.out llvmPackages_14.bintools # for running nac3standalone demos
(pkgs.wrapClangMulti llvmPackages_16.clang) llvmPackages_16.llvm.out llvmPackages_16.bintools # for running nac3standalone demos
packages.x86_64-linux.llvm-tools-irrt
cargo
rustc
# runtime dependencies
lld_14 # for running kernels on the host
lld_16 # for running kernels on the host
(packages.x86_64-linux.python3-mimalloc.withPackages(ps: [ ps.numpy ps.scipy ]))
# development tools
cargo-insta

View File

@ -0,0 +1,84 @@
from numpy import int32
from min_artiq import *
@nac3
class PassContextManager:
@kernel
def __init__(self):
pass
@kernel
def __enter__(self):
pass
@kernel
def __exit__(self):
pass
@nac3
class CustomDataContextManager:
a: Kernel[int32]
b: Kernel[int32]
@kernel
def __init__(self, a: int32, b: int32):
self.a = a
self.b = b
@kernel
def __enter__(self):
self.a += 1
print_int32(self.a)
@kernel
def __exit__(self):
self.b += 1
print_int32(self.b)
@nac3
class WithAsContextManager:
a: Kernel[int32]
@kernel
def __init__(self, val: int32):
self.a = val
@kernel
def __enter__(self) -> int32:
print_int32(self.a)
return self.a
@kernel
def __exit__(self):
print_int32(self.a)
@nac3
class CtxMgrTest:
core: KernelInvariant[Core]
def __init__(self):
self.core = Core()
@kernel
def run(self):
x = 0
a = PassContextManager()
with a:
x += 1
h = CustomDataContextManager(1, 2)
with h:
x += h.a + h.b
with WithAsContextManager(15) as num:
x += num
with WithAsContextManager(10) as c, WithAsContextManager(5) as d:
e: int32 = c + d
x += e
print_int32(x)
return
if __name__ == "__main__":
CtxMgrTest().run()

View File

@ -20,9 +20,10 @@ strum = "0.27"
strum_macros = "0.27"
[dependencies.inkwell]
version = "0.5"
git = "https://github.com/Derppening/inkwell"
tag = "0.5.0_llvm15-typed-ptr"
default-features = false
features = ["llvm14-0-prefer-dynamic", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"]
features = ["llvm16-0-prefer-dynamic", "target-x86", "target-arm", "target-riscv", "no-libffi-linking", "typed-pointers"]
[dev-dependencies]
test-case = "3.3"

View File

@ -28,6 +28,8 @@ fn main() {
"-fno-exceptions",
"-fno-rtti",
"-emit-llvm",
"-Xclang",
"-no-opaque-pointers",
"-S",
"-Wall",
"-Wextra",
@ -100,6 +102,7 @@ fn main() {
let mut llvm_as = Command::new("llvm-as-irrt")
.stdin(Stdio::piped())
.arg("-opaque-pointers=0")
.arg("-o")
.arg(out_dir.join("irrt.bc"))
.spawn()

View File

@ -1,3 +1,4 @@
#include "irrt/cc-builtins.hpp"
#include "irrt/exception.hpp"
#include "irrt/list.hpp"
#include "irrt/math.hpp"

View File

@ -0,0 +1,30 @@
#pragma once
extern "C" {
#define DEF_builtin_unary(RET, NAME, TY) \
RET __nac3_##NAME(TY v) { return __builtin_##NAME(v); }
#define DEF_builtin_binary(RET, NAME, TY1, TY2) \
RET __nac3_##NAME(TY1 v1, TY2 v2) { return __builtin_##NAME(v1, v2); }
DEF_builtin_unary(bool, isinf, double);
DEF_builtin_unary(bool, isnan, double);
DEF_builtin_unary(double, tan, double);
DEF_builtin_unary(double, asin, double);
DEF_builtin_unary(double, acos, double);
DEF_builtin_unary(double, atan, double);
DEF_builtin_unary(double, sinh, double);
DEF_builtin_unary(double, cosh, double);
DEF_builtin_unary(double, tanh, double);
DEF_builtin_unary(double, asinh, double);
DEF_builtin_unary(double, acosh, double);
DEF_builtin_unary(double, atanh, double);
DEF_builtin_unary(double, expm1, double);
DEF_builtin_unary(double, cbrt, double);
DEF_builtin_unary(double, erf, double);
DEF_builtin_unary(double, erfc, double);
DEF_builtin_binary(double, atan2, double, double);
DEF_builtin_binary(double, hypot, double, double);
DEF_builtin_binary(double, nextafter, double, double);
DEF_builtin_binary(double, ldexp, double, int);
}

View File

@ -34,16 +34,6 @@ DEF_nac3_int_exp_(int64_t);
DEF_nac3_int_exp_(uint32_t);
DEF_nac3_int_exp_(uint64_t);
int32_t __nac3_isinf(double x) {
return __builtin_isinf(x);
}
int32_t __nac3_isnan(double x) {
return __builtin_isnan(x);
}
double tgamma(double arg);
double __nac3_gamma(double z) {
// Handling for denormals
// | x | Python gamma(x) | C tgamma(x) |
@ -59,14 +49,12 @@ double __nac3_gamma(double z) {
return z;
}
double v = tgamma(z);
double v = __builtin_tgamma(z);
// (4)-(5)
return __builtin_isinf(v) || __builtin_isnan(v) ? __builtin_inf() : v;
}
double lgamma(double arg);
double __nac3_gammaln(double x) {
// libm's handling of value overflows differs from scipy:
// - scipy: gammaln(-inf) -> -inf
@ -76,7 +64,7 @@ double __nac3_gammaln(double x) {
return x;
}
return lgamma(x);
return __builtin_lgamma(x);
}
double j0(double x);

View File

@ -1194,7 +1194,7 @@ macro_rules! create_helper_call_numpy_unary_elementwise_float_to_bool {
BasicValueEnum::FloatValue(n) => {
debug_assert!(ctx.unifier.unioned(n_ty, ctx.primitives.float));
let ret = $on_scalar(generator, ctx, n);
let ret = $on_scalar(ctx, n, Option::<&str>::None);
Some(generator.bool_to_i8(ctx, ret).into())
}
_ => None,
@ -1263,55 +1263,55 @@ create_helper_call_numpy_unary_elementwise_float_to_float!(
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_tan,
"np_tan",
extern_fns::call_tan
irrt::call_tan
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_arcsin,
"np_arcsin",
extern_fns::call_asin
irrt::call_asin
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_arccos,
"np_arccos",
extern_fns::call_acos
irrt::call_acos
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_arctan,
"np_arctan",
extern_fns::call_atan
irrt::call_atan
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_sinh,
"np_sinh",
extern_fns::call_sinh
irrt::call_sinh
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_cosh,
"np_cosh",
extern_fns::call_cosh
irrt::call_cosh
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_tanh,
"np_tanh",
extern_fns::call_tanh
irrt::call_tanh
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_arcsinh,
"np_arcsinh",
extern_fns::call_asinh
irrt::call_asinh
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_arccosh,
"np_arccosh",
extern_fns::call_acosh
irrt::call_acosh
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_arctanh,
"np_arctanh",
extern_fns::call_atanh
irrt::call_atanh
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
@ -1327,7 +1327,7 @@ create_helper_call_numpy_unary_elementwise_float_to_float!(
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_expm1,
"np_expm1",
extern_fns::call_expm1
irrt::call_expm1
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
@ -1354,7 +1354,7 @@ create_helper_call_numpy_unary_elementwise_float_to_float!(
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_numpy_cbrt,
"np_cbrt",
extern_fns::call_cbrt
irrt::call_cbrt
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
@ -1371,12 +1371,12 @@ create_helper_call_numpy_unary_elementwise_float_to_float!(
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_scipy_special_erf,
"sp_spec_erf",
extern_fns::call_erf
irrt::call_erf
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_scipy_special_erfc,
"sp_spec_erfc",
extern_fns::call_erfc
irrt::call_erfc
);
create_helper_call_numpy_unary_elementwise_float_to_float!(
call_scipy_special_gamma,
@ -1422,7 +1422,7 @@ pub fn call_numpy_arctan2<'ctx, G: CodeGenerator + ?Sized>(
match (x1_scalar, x2_scalar) {
(BasicValueEnum::FloatValue(x1), BasicValueEnum::FloatValue(x2)) => {
Ok(extern_fns::call_atan2(ctx, x1, x2, None).into())
Ok(irrt::call_atan2(ctx, x1, x2, None).into())
}
_ => unsupported_type(ctx, FN_NAME, &[x1_ty, x2_ty]),
}
@ -1560,7 +1560,7 @@ pub fn call_numpy_ldexp<'ctx, G: CodeGenerator + ?Sized>(
(BasicValueEnum::FloatValue(x1_scalar), BasicValueEnum::IntValue(x2_scalar)) => {
debug_assert_eq!(x1.get_dtype(), ctx.ctx.f64_type().into());
debug_assert_eq!(x2.get_dtype(), ctx.ctx.i32_type().into());
Ok(extern_fns::call_ldexp(ctx, x1_scalar, x2_scalar, None).into())
Ok(irrt::call_ldexp(ctx, x1_scalar, x2_scalar, None).into())
}
_ => unsupported_type(ctx, FN_NAME, &[x1_ty, x2_ty]),
}
@ -1594,7 +1594,7 @@ pub fn call_numpy_hypot<'ctx, G: CodeGenerator + ?Sized>(
match (x1_scalar, x2_scalar) {
(BasicValueEnum::FloatValue(x1), BasicValueEnum::FloatValue(x2)) => {
Ok(extern_fns::call_hypot(ctx, x1, x2, None).into())
Ok(irrt::call_hypot(ctx, x1, x2, None).into())
}
_ => unsupported_type(ctx, FN_NAME, &[x1_ty, x2_ty]),
}
@ -1628,7 +1628,7 @@ pub fn call_numpy_nextafter<'ctx, G: CodeGenerator + ?Sized>(
match (x1_scalar, x2_scalar) {
(BasicValueEnum::FloatValue(x1), BasicValueEnum::FloatValue(x2)) => {
Ok(extern_fns::call_nextafter(ctx, x1, x2, None).into())
Ok(irrt::call_nextafter(ctx, x1, x2, None).into())
}
_ => unsupported_type(ctx, FN_NAME, &[x1_ty, x2_ty]),
}

View File

@ -1,6 +1,6 @@
use inkwell::{
attributes::{Attribute, AttributeLoc},
values::{BasicValueEnum, FloatValue, IntValue},
values::{BasicValueEnum, FloatValue},
};
use super::{expr::infer_and_call_function, CodeGenContext};
@ -66,75 +66,14 @@ macro_rules! generate_extern_fn {
};
}
generate_extern_fn!("unary", call_tan, "tan");
generate_extern_fn!("unary", call_asin, "asin");
generate_extern_fn!("unary", call_acos, "acos");
generate_extern_fn!("unary", call_atan, "atan");
generate_extern_fn!("unary", call_sinh, "sinh");
generate_extern_fn!("unary", call_cosh, "cosh");
generate_extern_fn!("unary", call_tanh, "tanh");
generate_extern_fn!("unary", call_asinh, "asinh");
generate_extern_fn!("unary", call_acosh, "acosh");
generate_extern_fn!("unary", call_atanh, "atanh");
generate_extern_fn!("unary", call_expm1, "expm1");
generate_extern_fn!(
"unary",
call_cbrt,
"cbrt",
"mustprogress",
"nofree",
"nosync",
"nounwind",
"readonly",
"willreturn"
);
generate_extern_fn!("unary", call_erf, "erf", "nounwind");
generate_extern_fn!("unary", call_erfc, "erfc", "nounwind");
generate_extern_fn!("unary", call_j1, "j1", "nounwind");
generate_extern_fn!("binary", call_atan2, "atan2");
generate_extern_fn!("binary", call_hypot, "hypot", "nounwind");
generate_extern_fn!("binary", call_nextafter, "nextafter", "nounwind");
/// Invokes the [`ldexp`](https://en.cppreference.com/w/c/numeric/math/ldexp) function.
pub fn call_ldexp<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
arg: FloatValue<'ctx>,
exp: IntValue<'ctx>,
name: Option<&str>,
) -> FloatValue<'ctx> {
const FN_NAME: &str = "ldexp";
let llvm_f64 = ctx.ctx.f64_type();
let llvm_i32 = ctx.ctx.i32_type();
debug_assert_eq!(arg.get_type(), llvm_f64);
debug_assert_eq!(exp.get_type(), llvm_i32);
infer_and_call_function(
ctx,
FN_NAME,
Some(llvm_f64.into()),
&[arg.into(), exp.into()],
name,
Some(&|func| {
for attr in ["mustprogress", "nofree", "nounwind", "willreturn"] {
func.add_attribute(
AttributeLoc::Function,
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0),
);
}
}),
)
.map(BasicValueEnum::into_float_value)
.unwrap()
}
/// Macro to generate `np_linalg` and `sp_linalg` functions
/// The function takes as input `NDArray` and returns ()
///
/// Arguments:
/// * `$fn_name:ident`: The identifier of the rust function to be generated
/// * `$extern_fn:literal`: Name of underlying extern function
/// * `$extern_fn:ident`: Name of underlying extern function
/// * (2/3/4): Number of `NDArray` that function takes as input
///
/// Note:
@ -142,23 +81,23 @@ pub fn call_ldexp<'ctx>(
/// It is the responsibility of caller to ensure that output `NDArray` is properly allocated on stack
/// The function changes the content of the output `NDArray` in-place
macro_rules! generate_linalg_extern_fn {
($fn_name:ident, $extern_fn:literal, 2) => {
($fn_name:ident, $extern_fn:ident, 2) => {
generate_linalg_extern_fn!($fn_name, $extern_fn, mat1, mat2);
};
($fn_name:ident, $extern_fn:literal, 3) => {
($fn_name:ident, $extern_fn:ident, 3) => {
generate_linalg_extern_fn!($fn_name, $extern_fn, mat1, mat2, mat3);
};
($fn_name:ident, $extern_fn:literal, 4) => {
($fn_name:ident, $extern_fn:ident, 4) => {
generate_linalg_extern_fn!($fn_name, $extern_fn, mat1, mat2, mat3, mat4);
};
($fn_name:ident, $extern_fn:literal $(,$input_matrix:ident)*) => {
#[doc = concat!("Invokes the linalg `", stringify!($extern_fn), " function." )]
($fn_name:ident, $extern_fn:ident $(,$input_matrix:ident)*) => {
#[doc = concat!("Invokes the linalg `", stringify!($extern_fn), "` function." )]
pub fn $fn_name<'ctx>(
ctx: &mut CodeGenContext<'ctx, '_>,
$($input_matrix: BasicValueEnum<'ctx>,)*
name: Option<&str>,
){
const FN_NAME: &str = $extern_fn;
) {
const FN_NAME: &str = stringify!($extern_fn);
infer_and_call_function(
ctx,
@ -167,25 +106,26 @@ macro_rules! generate_linalg_extern_fn {
&[$($input_matrix.into(),)*],
name,
Some(&|func| {
for attr in ["mustprogress", "nofree", "nounwind", "willreturn", "writeonly"] {
func.add_attribute(
AttributeLoc::Function,
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id(attr), 0),
);
}
func.add_attribute(
AttributeLoc::Function,
ctx.ctx.create_enum_attribute(
Attribute::get_named_enum_kind_id("nounwind"),
0,
),
)
}),
);
}
};
}
generate_linalg_extern_fn!(call_np_linalg_cholesky, "np_linalg_cholesky", 2);
generate_linalg_extern_fn!(call_np_linalg_qr, "np_linalg_qr", 3);
generate_linalg_extern_fn!(call_np_linalg_svd, "np_linalg_svd", 4);
generate_linalg_extern_fn!(call_np_linalg_inv, "np_linalg_inv", 2);
generate_linalg_extern_fn!(call_np_linalg_pinv, "np_linalg_pinv", 2);
generate_linalg_extern_fn!(call_np_linalg_matrix_power, "np_linalg_matrix_power", 3);
generate_linalg_extern_fn!(call_np_linalg_det, "np_linalg_det", 2);
generate_linalg_extern_fn!(call_sp_linalg_lu, "sp_linalg_lu", 3);
generate_linalg_extern_fn!(call_sp_linalg_schur, "sp_linalg_schur", 3);
generate_linalg_extern_fn!(call_sp_linalg_hessenberg, "sp_linalg_hessenberg", 3);
generate_linalg_extern_fn!(call_np_linalg_cholesky, np_linalg_cholesky, 2);
generate_linalg_extern_fn!(call_np_linalg_qr, np_linalg_qr, 3);
generate_linalg_extern_fn!(call_np_linalg_svd, np_linalg_svd, 4);
generate_linalg_extern_fn!(call_np_linalg_inv, np_linalg_inv, 2);
generate_linalg_extern_fn!(call_np_linalg_pinv, np_linalg_pinv, 2);
generate_linalg_extern_fn!(call_np_linalg_matrix_power, np_linalg_matrix_power, 3);
generate_linalg_extern_fn!(call_np_linalg_det, np_linalg_det, 2);
generate_linalg_extern_fn!(call_sp_linalg_lu, sp_linalg_lu, 3);
generate_linalg_extern_fn!(call_sp_linalg_schur, sp_linalg_schur, 3);
generate_linalg_extern_fn!(call_sp_linalg_hessenberg, sp_linalg_hessenberg, 3);

View File

@ -0,0 +1,130 @@
use inkwell::{
attributes::{Attribute, AttributeLoc},
values::{BasicValueEnum, FloatValue, IntValue},
};
use crate::codegen::{expr::infer_and_call_function, CodeGenContext};
/// Generates a call to [`isinf`](https://en.cppreference.com/w/c/numeric/math/isinf) in IR. Returns
/// an `i1` representing the result.
pub fn call_isinf<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
v: FloatValue<'ctx>,
name: Option<&str>,
) -> IntValue<'ctx> {
let llvm_i1 = ctx.ctx.bool_type();
let llvm_f64 = ctx.ctx.f64_type();
assert_eq!(v.get_type(), llvm_f64);
infer_and_call_function(ctx, "__nac3_isinf", Some(llvm_i1.into()), &[v.into()], name, None)
.map(BasicValueEnum::into_int_value)
.unwrap()
}
/// Generates a call to [`isnan`](https://en.cppreference.com/w/c/numeric/math/isnan) in IR. Returns
/// an `i1` representing the result.
pub fn call_isnan<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
v: FloatValue<'ctx>,
name: Option<&str>,
) -> IntValue<'ctx> {
let llvm_i1 = ctx.ctx.bool_type();
let llvm_f64 = ctx.ctx.f64_type();
assert_eq!(v.get_type(), llvm_f64);
infer_and_call_function(ctx, "__nac3_isnan", Some(llvm_i1.into()), &[v.into()], name, None)
.map(BasicValueEnum::into_int_value)
.unwrap()
}
/// Macro to generate N-ary functions accepting an arbitrary number of `f64` as arguments and
/// returning `f64`.
///
/// Arguments:
///
/// - `$fn_name:ident`: The name of the Rust function to be generated.
/// - `$builtin_fn:ident`: The name of the builtin function to be invoked in the body of the
/// generated function. The corresponding function in IRRT must be prefixed with `__nac3_`.
/// - `$(,$args:ident)*`: The parameter name(s) to the IRRT function.
macro_rules! generate_f64_nary_fn {
($fn_name:ident, $builtin_fn:ident $(,$args:ident)* $(,)?) => {
#[doc = concat!("Generates a call to [`", stringify!($builtin_fn), "`](https://en.cppreference.com/w/c/numeric/math/", stringify!($builtin_fn), ") in IR." )]
pub fn $fn_name<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
$($args: FloatValue<'ctx>,)*
name: Option<&str>,
) -> FloatValue<'ctx> {
const FN_NAME: &str = concat!("__nac3_", stringify!($builtin_fn));
let llvm_f64 = ctx.ctx.f64_type();
$(debug_assert_eq!($args.get_type(), llvm_f64);)*
infer_and_call_function(
ctx,
FN_NAME,
Some(llvm_f64.into()),
&[$($args.into()),*],
name,
Some(&|func| {
func.add_attribute(
AttributeLoc::Function,
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("nounwind"), 0)
);
}),
)
.map(BasicValueEnum::into_float_value)
.unwrap()
}
};
}
generate_f64_nary_fn!(call_tan, tan, arg);
generate_f64_nary_fn!(call_asin, asin, arg);
generate_f64_nary_fn!(call_acos, acos, arg);
generate_f64_nary_fn!(call_atan, atan, arg);
generate_f64_nary_fn!(call_sinh, sinh, arg);
generate_f64_nary_fn!(call_cosh, cosh, arg);
generate_f64_nary_fn!(call_tanh, tanh, arg);
generate_f64_nary_fn!(call_asinh, asinh, arg);
generate_f64_nary_fn!(call_acosh, acosh, arg);
generate_f64_nary_fn!(call_atanh, atanh, arg);
generate_f64_nary_fn!(call_expm1, expm1, arg);
generate_f64_nary_fn!(call_cbrt, cbrt, arg);
generate_f64_nary_fn!(call_erf, erf, arg);
generate_f64_nary_fn!(call_erfc, erfc, arg);
generate_f64_nary_fn!(call_atan2, atan2, y, x);
generate_f64_nary_fn!(call_hypot, hypot, x, y);
generate_f64_nary_fn!(call_nextafter, nextafter, from, to);
/// Invokes the [`ldexp`](https://en.cppreference.com/w/c/numeric/math/ldexp) function.
pub fn call_ldexp<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
arg: FloatValue<'ctx>,
exp: IntValue<'ctx>,
name: Option<&str>,
) -> FloatValue<'ctx> {
const FN_NAME: &str = "__nac3_ldexp";
let llvm_f64 = ctx.ctx.f64_type();
let llvm_i32 = ctx.ctx.i32_type();
debug_assert_eq!(arg.get_type(), llvm_f64);
debug_assert_eq!(exp.get_type(), llvm_i32);
infer_and_call_function(
ctx,
FN_NAME,
Some(llvm_f64.into()),
&[arg.into(), exp.into()],
name,
Some(&|func| {
func.add_attribute(
AttributeLoc::Function,
ctx.ctx.create_enum_attribute(Attribute::get_named_enum_kind_id("nounwind"), 0),
);
}),
)
.map(BasicValueEnum::into_float_value)
.unwrap()
}

View File

@ -59,54 +59,6 @@ pub fn integer_power<'ctx, G: CodeGenerator + ?Sized>(
.unwrap()
}
/// Generates a call to `isinf` in IR. Returns an `i1` representing the result.
pub fn call_isinf<'ctx, G: CodeGenerator + ?Sized>(
generator: &mut G,
ctx: &CodeGenContext<'ctx, '_>,
v: FloatValue<'ctx>,
) -> IntValue<'ctx> {
let llvm_i32 = ctx.ctx.i32_type();
let llvm_f64 = ctx.ctx.f64_type();
assert_eq!(v.get_type(), llvm_f64);
infer_and_call_function(
ctx,
"__nac3_isinf",
Some(llvm_i32.into()),
&[v.into()],
Some("isinf"),
None,
)
.map(BasicValueEnum::into_int_value)
.map(|ret| generator.bool_to_i1(ctx, ret))
.unwrap()
}
/// Generates a call to `isnan` in IR. Returns an `i1` representing the result.
pub fn call_isnan<'ctx, G: CodeGenerator + ?Sized>(
generator: &mut G,
ctx: &CodeGenContext<'ctx, '_>,
v: FloatValue<'ctx>,
) -> IntValue<'ctx> {
let llvm_i32 = ctx.ctx.i32_type();
let llvm_f64 = ctx.ctx.f64_type();
assert_eq!(v.get_type(), llvm_f64);
infer_and_call_function(
ctx,
"__nac3_isnan",
Some(llvm_i32.into()),
&[v.into()],
Some("isnan"),
None,
)
.map(BasicValueEnum::into_int_value)
.map(|ret| generator.bool_to_i1(ctx, ret))
.unwrap()
}
/// Generates a call to `gamma` in IR. Returns an `f64` representing the result.
pub fn call_gamma<'ctx>(ctx: &CodeGenContext<'ctx, '_>, v: FloatValue<'ctx>) -> FloatValue<'ctx> {
let llvm_f64 = ctx.ctx.f64_type();

View File

@ -11,12 +11,14 @@ use nac3parser::ast::Expr;
use super::{CodeGenContext, CodeGenerator};
use crate::{symbol_resolver::SymbolResolver, typecheck::typedef::Type};
pub use cc_builtins::*;
pub use list::*;
pub use math::*;
pub use range::*;
pub use slice::*;
pub use string::*;
mod cc_builtins;
mod list;
mod math;
pub mod ndarray;

View File

@ -7,7 +7,7 @@ source_filename = "test"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define i32 @testing(i32 %0, i32 %1) local_unnamed_addr #0 !dbg !4 {
init:
%add = add i32 %1, %0, !dbg !9
@ -16,7 +16,7 @@ init:
ret i32 %., !dbg !12
}
attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn }
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
!llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!2}
@ -32,5 +32,5 @@ attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willret
!8 = !{}
!9 = !DILocation(line: 1, column: 9, scope: !4)
!10 = !DILocation(line: 2, column: 15, scope: !4)
!11 = !DILocation(line: 0, scope: !4)
!11 = !DILocation(line: 2, scope: !4)
!12 = !DILocation(line: 3, column: 8, scope: !4)

View File

@ -7,7 +7,7 @@ source_filename = "test"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define i32 @testing(i32 %0) local_unnamed_addr #0 !dbg !5 {
init:
%add.i = shl i32 %0, 1, !dbg !10
@ -15,14 +15,14 @@ init:
ret i32 %mul, !dbg !10
}
; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define i32 @foo.0(i32 %0) local_unnamed_addr #0 !dbg !11 {
init:
%add = add i32 %0, 1, !dbg !12
ret i32 %add, !dbg !12
}
attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn }
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
!llvm.module.flags = !{!0, !1}
!llvm.dbg.cu = !{!2, !4}

View File

@ -1688,13 +1688,259 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
}
/// See [`CodeGenerator::gen_with`].
pub fn gen_with<G: CodeGenerator>(
_: &mut G,
_: &mut CodeGenContext<'_, '_>,
pub fn gen_with<'ctx, 'a, G: CodeGenerator>(
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, 'a>,
stmt: &Stmt<Option<Type>>,
) -> Result<(), String> {
// TODO: Implement with statement after finishing exceptions
Err(format!("With statement with custom types is not yet supported (at {})", stmt.location))
let StmtKind::With { items, body, .. } = &stmt.node else { codegen_unreachable!(ctx) };
let mut exits = vec![];
let mut enters = vec![];
// prepare enters and exits
for item in items {
// evaluate the expression first
let expr_ty = item.context_expr.custom.unwrap();
let expr = generator.gen_expr(ctx, &item.context_expr)?.unwrap();
// get the __enter__ method signature and ID
let TypeEnum::TObj { obj_id, fields, .. } = &*ctx.unifier.get_ty(expr_ty) else {
codegen_unreachable!(ctx)
};
let top_level_defs = ctx.top_level.definitions.read();
let def = top_level_defs[obj_id.0].read();
let TopLevelDef::Class { methods, .. } = &*def else { codegen_unreachable!(ctx) };
let enter_fun_id = methods
.iter()
.find(|method| method.0 == "__enter__".into())
.map(|method| method.2)
.unwrap();
let enter = fields.get(&"__enter__".into()).copied().unwrap();
let TypeEnum::TFunc(enter_signature) = &*ctx.unifier.get_ty(enter.0) else {
codegen_unreachable!(ctx)
};
enters.push((
expr_ty,
expr.clone(),
enter_signature.clone(),
enter_fun_id,
item.optional_vars.clone(),
));
// save __exit__() data to be called later in final stage
let exit_fun_id = methods
.iter()
.find(|method| method.0 == "__exit__".into())
.map(|method| method.2)
.unwrap();
let exit = fields.get(&"__exit__".into()).copied().unwrap();
let TypeEnum::TFunc(exit_signature) = &*ctx.unifier.get_ty(exit.0) else {
codegen_unreachable!(ctx)
};
// stack the exits as the exit order is opposite of enter
// would be best to reuse try...finally but re-building Stmt vec seems infeasible
exits.push((expr_ty, expr, exit_signature.clone(), exit_fun_id));
}
let body_gen_lambda = |ctx: &mut CodeGenContext<'ctx, 'a>,
generator: &mut G|
-> Result<(), String> {
for enter in &enters {
// call __enter__()
let enter_ret = generator.gen_call(
ctx,
Some((enter.0, enter.1.clone())),
(&enter.2, enter.3),
Vec::default(),
)?;
// deal with assignments (`as`)
if let Some(optional_vars) = &enter.4 {
generator.gen_assign(ctx, optional_vars, enter_ret.unwrap().into(), enter.2.ret)?;
}
}
// generate the `with` body
generator.gen_block(ctx, body.iter())
};
let exit_gen_lambda =
|ctx: &mut CodeGenContext<'ctx, 'a>, generator: &mut G| -> Result<(), String> {
// call __exit__()s in the reverse order
for exit in exits.iter().rev() {
generator.gen_call(
ctx,
Some((exit.0, exit.1.clone())),
(&exit.2, exit.3),
Vec::default(),
)?;
}
Ok(())
};
// copied and trimmed from gen_try, to cover try (setup, enter)..finally (exit)
let personality_symbol = ctx.top_level.personality_symbol.as_ref().unwrap();
let personality = ctx.module.get_function(personality_symbol).unwrap_or_else(|| {
let ty = ctx.ctx.i32_type().fn_type(&[], true);
ctx.module.add_function(personality_symbol, ty, None)
});
let exception_type = ctx.get_llvm_type(generator, ctx.primitives.exception);
let ptr_type = ctx.ctx.i8_type().ptr_type(inkwell::AddressSpace::default());
let current_block = ctx.builder.get_insert_block().unwrap();
let current_fun = current_block.get_parent().unwrap();
let landingpad = ctx.ctx.append_basic_block(current_fun, "with.landingpad");
let dispatcher = ctx.ctx.append_basic_block(current_fun, "with.dispatch");
let dispatcher_end = dispatcher;
ctx.builder.position_at_end(dispatcher);
let exn = ctx.builder.build_phi(exception_type, "exn").unwrap();
ctx.builder.position_at_end(current_block);
let mut old_loop_target = None;
let final_state =
generator.gen_var_alloc(ctx, ptr_type.into(), Some("with.final_state.addr"))?;
let mut final_data = Some((final_state, Vec::new(), Vec::new()));
if let Some((continue_target, break_target)) = ctx.loop_target {
let break_proxy = ctx.ctx.append_basic_block(current_fun, "with.break");
let continue_proxy = ctx.ctx.append_basic_block(current_fun, "with.continue");
final_proxy(ctx, break_target, break_proxy, final_data.as_mut().unwrap());
final_proxy(ctx, continue_target, continue_proxy, final_data.as_mut().unwrap());
old_loop_target = ctx.loop_target.replace((continue_proxy, break_proxy));
}
let return_proxy = ctx.ctx.append_basic_block(current_fun, "with.return");
if let Some(return_target) = ctx.return_target {
final_proxy(ctx, return_target, return_proxy, final_data.as_mut().unwrap());
} else {
let return_target = ctx.ctx.append_basic_block(current_fun, "with.return_target");
ctx.builder.position_at_end(return_target);
let return_value = ctx.return_buffer.map(|v| ctx.builder.build_load(v, "$ret").unwrap());
ctx.builder.build_return(return_value.as_ref().map(|v| v as &dyn BasicValue)).unwrap();
ctx.builder.position_at_end(current_block);
final_proxy(ctx, return_target, return_proxy, final_data.as_mut().unwrap());
}
let old_return = ctx.return_target.replace(return_proxy);
let cleanup = ctx.ctx.append_basic_block(current_fun, "with.cleanup");
// replace unwind target, clauses stay the same
let old_unwind = ctx.unwind_target.replace(landingpad);
body_gen_lambda(ctx, generator)?;
let body = ctx.builder.get_insert_block().unwrap();
// reset old_unwind
ctx.unwind_target = old_unwind;
ctx.return_target = old_return;
ctx.loop_target = old_loop_target.or(ctx.loop_target).take();
let final_landingpad = ctx.ctx.append_basic_block(current_fun, "with.catch.final");
ctx.builder.position_at_end(final_landingpad);
ctx.builder
.build_landing_pad(
ctx.ctx.struct_type(&[ptr_type.into(), exception_type], false),
personality,
&[],
true,
"with.catch.final",
)
.unwrap();
ctx.builder.build_unconditional_branch(cleanup).unwrap();
ctx.builder.position_at_end(body);
let old_unwind = ctx.unwind_target.replace(final_landingpad);
let mut final_proxy_lambda =
|ctx: &mut CodeGenContext<'ctx, 'a>, target: BasicBlock<'ctx>, block: BasicBlock<'ctx>| {
final_proxy(ctx, target, block, final_data.as_mut().unwrap());
};
let redirect = &mut final_proxy_lambda
as &mut dyn FnMut(&mut CodeGenContext<'ctx, 'a>, BasicBlock<'ctx>, BasicBlock<'ctx>);
let resume = get_builtins(generator, ctx, "__nac3_resume");
let end_catch = get_builtins(generator, ctx, "__nac3_end_catch");
if let Some((continue_target, break_target)) = ctx.loop_target.take() {
let break_proxy = ctx.ctx.append_basic_block(current_fun, "with.break");
let continue_proxy = ctx.ctx.append_basic_block(current_fun, "with.continue");
ctx.builder.position_at_end(break_proxy);
ctx.builder.build_call(end_catch, &[], "end_catch").unwrap();
ctx.builder.position_at_end(continue_proxy);
ctx.builder.build_call(end_catch, &[], "end_catch").unwrap();
ctx.builder.position_at_end(body);
redirect(ctx, break_target, break_proxy);
redirect(ctx, continue_target, continue_proxy);
ctx.loop_target = Some((continue_proxy, break_proxy));
old_loop_target = Some((continue_target, break_target));
}
let return_proxy = ctx.ctx.append_basic_block(current_fun, "with.return");
ctx.builder.position_at_end(return_proxy);
ctx.builder.build_call(end_catch, &[], "end_catch").unwrap();
let return_target = ctx.return_target.take().unwrap_or_else(|| {
let doreturn = ctx.ctx.append_basic_block(current_fun, "with.doreturn");
ctx.builder.position_at_end(doreturn);
let return_value = ctx.return_buffer.map(|v| ctx.builder.build_load(v, "$ret").unwrap());
ctx.builder.build_return(return_value.as_ref().map(|v| v as &dyn BasicValue)).unwrap();
doreturn
});
redirect(ctx, return_target, return_proxy);
ctx.return_target = Some(return_proxy);
let old_return = Some(return_target);
ctx.unwind_target = old_unwind;
ctx.loop_target = old_loop_target.or(ctx.loop_target).take();
ctx.return_target = old_return;
ctx.builder.position_at_end(landingpad);
let landingpad_value = ctx
.builder
.build_landing_pad(
ctx.ctx.struct_type(&[ptr_type.into(), exception_type], false),
personality,
&Vec::new(),
true,
"try.landingpad",
)
.map(BasicValueEnum::into_struct_value)
.unwrap();
let exn_val = ctx.builder.build_extract_value(landingpad_value, 1, "exn").unwrap();
ctx.builder.build_unconditional_branch(dispatcher).unwrap();
exn.add_incoming(&[(&exn_val, landingpad)]);
if dispatcher_end.get_terminator().is_none() {
ctx.builder.position_at_end(dispatcher_end);
ctx.builder.build_unconditional_branch(cleanup).unwrap();
}
// exception path
ctx.builder.position_at_end(cleanup);
exit_gen_lambda(ctx, generator)?;
ctx.build_call_or_invoke(resume, &[], "resume");
ctx.builder.build_unreachable().unwrap();
// normal path
let (final_state, mut final_targets, final_paths) = final_data.unwrap();
let tail = ctx.ctx.append_basic_block(current_fun, "with.tail");
final_targets.push(tail);
let finalizer = ctx.ctx.append_basic_block(current_fun, "with.exits");
ctx.builder.position_at_end(finalizer);
exit_gen_lambda(ctx, generator)?;
let dest = ctx.builder.build_load(final_state, "final_dest").unwrap();
ctx.builder.build_indirect_branch(dest, &final_targets).unwrap();
for block in &final_paths {
if block.get_terminator().is_none() {
ctx.builder.position_at_end(*block);
ctx.builder.build_unconditional_branch(finalizer).unwrap();
}
}
for block in &[body] {
if block.get_terminator().is_none() {
ctx.builder.position_at_end(*block);
unsafe {
ctx.builder.build_store(final_state, tail.get_address().unwrap()).unwrap();
}
ctx.builder.build_unconditional_branch(finalizer).unwrap();
}
}
ctx.builder.position_at_end(tail);
Ok(())
}
/// Generates IR for a `return` statement.

View File

@ -218,7 +218,7 @@ impl<'a> Linker<'a> {
relocs: &[R],
target_section: Elf32_Word,
) -> Result<(), Error> {
type RelocateFn = dyn Fn(&mut [u8], Elf32_Word);
type RelocateFn = fn(&mut [u8], Elf32_Word);
struct RelocInfo<'a, R> {
pub defined_val: bool,
@ -329,16 +329,11 @@ impl<'a> Linker<'a> {
let expected_offset = sym_option.map_or(0, |sym| sym.st_value);
let indirect_reloc =
relocs.iter().find(|reloc| reloc.offset() == expected_offset)?;
Some(RelocInfo {
defined_val: {
let indirect_sym =
self.symtab[indirect_reloc.sym_info() as usize];
indirect_sym.st_shndx != SHN_UNDEF
|| ELF32_ST_BIND(indirect_sym.st_info) == STB_LOCAL
},
indirect_reloc: Some(indirect_reloc),
pc_relative: true,
relocate: Some(Box::new(|target_word, value| {
let indir_type_info = indirect_reloc.type_info();
let indirect_addressing = (indir_type_info == R_RISCV_CALL_PLT)
|| (indir_type_info == R_RISCV_GOT_HI20);
let relocate = Some(Box::new(if indirect_addressing {
|target_word: &mut [u8], value: u32| {
// Here, we convert to direct addressing
// GOT reloc (indirect) -> lw + addi
// PCREL reloc (direct) -> addi
@ -350,6 +345,46 @@ impl<'a> Linker<'a> {
| ((value & 0xFFF) << 20);
LittleEndian::write_u32(target_word, addi_insn);
}
} else {
|target_word: &mut [u8], value: u32| {
let i_raw = LittleEndian::read_u32(target_word);
let i_insn = (i_raw & 0xFFFFF) | ((value & 0xFFF) << 20);
LittleEndian::write_u32(target_word, i_insn);
}
}));
Some(RelocInfo {
defined_val: {
let indirect_sym =
self.symtab[indirect_reloc.sym_info() as usize];
indirect_sym.st_shndx != SHN_UNDEF
|| ELF32_ST_BIND(indirect_sym.st_info) == STB_LOCAL
},
indirect_reloc: Some(indirect_reloc),
pc_relative: true,
relocate,
})
}
R_RISCV_PCREL_LO12_S => {
let expected_offset = sym_option.map_or(0, |sym| sym.st_value);
let indirect_reloc =
relocs.iter().find(|reloc| reloc.offset() == expected_offset)?;
Some(RelocInfo {
defined_val: {
let indirect_sym =
self.symtab[indirect_reloc.sym_info() as usize];
indirect_sym.st_shndx != SHN_UNDEF
|| ELF32_ST_BIND(indirect_sym.st_info) == STB_LOCAL
},
indirect_reloc: Some(indirect_reloc),
pc_relative: true,
relocate: Some(Box::new(|target_word: &mut [u8], value: u32| {
let store_raw = LittleEndian::read_u32(target_word);
let store_insn = ((value & 0x1F) << 7)
| ((value & 0xFE0) << 20)
| (store_raw & 0x1FFF07F);
LittleEndian::write_u32(target_word, store_insn);
})),
})
}
@ -620,7 +655,7 @@ impl<'a> Linker<'a> {
// RISC-V: Lower 12-bits relocations
// If the upper 20-bits relocation cannot be resolved,
// this relocation will be relayed to the runtime linker.
(Isa::RiscV32, R_RISCV_PCREL_LO12_I) => {
(Isa::RiscV32, R_RISCV_PCREL_LO12_I) | (Isa::RiscV32, R_RISCV_PCREL_LO12_S) => {
// Find the HI20 relocation
let indirect_reloc = relocs
.iter()

View File

@ -1,35 +0,0 @@
From 5c571082fdaf61f6df19d9b7137dc26d71334058 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Thu, 18 Feb 2016 10:33:04 +0100
Subject: [PATCH 2/3] Fix build with musl libc
On musl libc the fopen64 and fopen are the same thing, but for
compatibility they have a `#define fopen64 fopen`. Same applies for
fseek64, fstat64, fstatvfs64, ftello64, lstat64, stat64 and tmpfile64.
---
include/llvm/Analysis/TargetLibraryInfo.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h
index 7becdf0..7f14427 100644
--- a/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/include/llvm/Analysis/TargetLibraryInfo.h
@@ -18,6 +18,15 @@
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
+#undef fopen64
+#undef fseeko64
+#undef fstat64
+#undef fstatvfs64
+#undef ftello64
+#undef lstat64
+#undef stat64
+#undef tmpfile64
+
namespace llvm {
/// VecDesc - Describes a possible vectorization of a function.
/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
--
2.7.3

View File

@ -9,43 +9,29 @@
, zlib
, which
, debugVersion ? false
, enableManpages ? false
, enableSharedLibraries ? false
, extraCmakeFlags ? []
}:
let
inherit (lib) optional optionals optionalString;
release_version = "14.0.6";
candidate = ""; # empty or "rcN"
dash-candidate = lib.optionalString (candidate != "") "-${candidate}";
version = "${release_version}${dash-candidate}"; # differentiating these (variables) is important for RCs
fetch = name: sha256: fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/${name}-${release_version}${candidate}.src.tar.xz";
inherit sha256;
};
# Used when creating a version-suffixed symlink of libLLVM.dylib
shortVersion = with lib;
concatStringsSep "." (take 1 (splitString "." release_version));
in stdenv.mkDerivation (rec {
sources = import ../llvm/sources.nix { inherit fetchurl; };
in stdenv.mkDerivation rec {
pname = "llvm";
inherit version;
src = fetch pname "sha256-BQki7KrKV4H99mMeqSvHFRg/IC+dLxUUcibwI0FPYZo=";
inherit (sources) version;
unpackPhase = ''
unpackFile $src
mv llvm-${release_version}* llvm
mkdir llvm
tar xf ${sources.llvm} -C llvm --strip-components=1
tar xf ${sources.cmake} -C llvm/cmake --strip-components=2
mkdir cmake
ln -s $PWD/llvm/cmake cmake/Modules
sourceRoot=$PWD/llvm
'';
outputs = [ "out" "lib" "dev" "python" ];
nativeBuildInputs = [ cmake python3 ]
++ optionals enableManpages [ python3.pkgs.sphinx python3.pkgs.recommonmark ];
nativeBuildInputs = [ cmake python3 ];
buildInputs = [ ];
@ -55,44 +41,18 @@ in stdenv.mkDerivation (rec {
patches = [
./gnu-install-dirs.patch
./llvm-future-riscv-abi.diff
];
postPatch = optionalString stdenv.isDarwin ''
substituteInPlace cmake/modules/AddLLVM.cmake \
--replace 'set(_install_name_dir INSTALL_NAME_DIR "@rpath")' "set(_install_name_dir)" \
--replace 'set(_install_rpath "@loader_path/../''${CMAKE_INSTALL_LIBDIR}''${LLVM_LIBDIR_SUFFIX}" ''${extra_libdir})' ""
''
# Patch llvm-config to return correct library path based on --link-{shared,static}.
+ ''
substitute '${./outputs.patch}' ./outputs.patch --subst-var lib
patch -p1 < ./outputs.patch
'' + ''
postPatch =
''
# FileSystem permissions tests fail with various special bits
substituteInPlace unittests/Support/CMakeLists.txt \
--replace "Path.cpp" ""
--replace-fail "Path.cpp" ""
rm unittests/Support/Path.cpp
substituteInPlace unittests/IR/CMakeLists.txt \
--replace "PassBuilderCallbacksTest.cpp" ""
--replace-fail "PassBuilderCallbacksTest.cpp" ""
rm unittests/IR/PassBuilderCallbacksTest.cpp
rm test/tools/llvm-objcopy/ELF/mirror-permissions-unix.test
'' + optionalString stdenv.hostPlatform.isMusl ''
patch -p1 -i ${./TLI-musl.patch}
substituteInPlace unittests/Support/CMakeLists.txt \
--replace "add_subdirectory(DynamicLibrary)" ""
rm unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
# valgrind unhappy with musl or glibc, but fails w/musl only
rm test/CodeGen/AArch64/wineh4.mir
'' + optionalString stdenv.hostPlatform.isAarch32 ''
# skip failing X86 test cases on 32-bit ARM
rm test/DebugInfo/X86/convert-debugloc.ll
rm test/DebugInfo/X86/convert-inlined.ll
rm test/DebugInfo/X86/convert-linked.ll
rm test/tools/dsymutil/X86/op-convert.test
'' + optionalString (stdenv.hostPlatform.system == "armv6l-linux") ''
# Seems to require certain floating point hardware (NEON?)
rm test/ExecutionEngine/frem.ll
'' + ''
patchShebangs test/BugPoint/compile-custom.ll.py
'';
@ -103,12 +63,12 @@ in stdenv.mkDerivation (rec {
'';
# E.g. mesa.drivers use the build-id as a cache key (see #93946):
LDFLAGS = optionalString (enableSharedLibraries && !stdenv.isDarwin) "-Wl,--build-id=sha1";
LDFLAGS = optionalString enableSharedLibraries "-Wl,--build-id=sha1";
cmakeFlags = with stdenv; [
"-DLLVM_INSTALL_CMAKE_DIR=${placeholder "dev"}/lib/cmake/llvm/"
"-DLLVM_INSTALL_PACKAGE_DIR=${placeholder "dev"}/lib/cmake/llvm"
"-DCMAKE_BUILD_TYPE=${if debugVersion then "Debug" else "Release"}"
"-DLLVM_BUILD_TESTS=${if stdenv.targetPlatform.isMinGW then "OFF" else "ON"}"
"-DLLVM_INCLUDE_TESTS=OFF"
"-DLLVM_HOST_TRIPLE=${stdenv.hostPlatform.config}"
"-DLLVM_DEFAULT_TARGET_TRIPLE=${stdenv.hostPlatform.config}"
"-DLLVM_ENABLE_UNWIND_TABLES=OFF"
@ -118,17 +78,8 @@ in stdenv.mkDerivation (rec {
"-DLLVM_TARGETS_TO_BUILD=X86;ARM;RISCV"
] ++ optionals enableSharedLibraries [
"-DLLVM_LINK_LLVM_DYLIB=ON"
] ++ optionals enableManpages [
"-DLLVM_BUILD_DOCS=ON"
"-DLLVM_ENABLE_SPHINX=ON"
"-DSPHINX_OUTPUT_MAN=ON"
"-DSPHINX_OUTPUT_HTML=OFF"
"-DSPHINX_WARNINGS_AS_ERRORS=OFF"
] ++ optionals (!isDarwin && !stdenv.targetPlatform.isMinGW) [
"-DLLVM_BINUTILS_INCDIR=${libbfd.dev}/include"
] ++ optionals isDarwin [
"-DLLVM_ENABLE_LIBCXX=ON"
"-DCAN_TARGET_i386=false"
] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
"-DCMAKE_CROSSCOMPILING=True"
(
@ -166,10 +117,6 @@ in stdenv.mkDerivation (rec {
substituteInPlace "$dev/lib/cmake/llvm/LLVMConfig.cmake" \
--replace 'set(LLVM_BINARY_DIR "''${LLVM_INSTALL_PREFIX}")' 'set(LLVM_BINARY_DIR "''${LLVM_INSTALL_PREFIX}'"$lib"'")'
''
+ optionalString (stdenv.isDarwin && enableSharedLibraries) ''
ln -s $lib/lib/libLLVM.dylib $lib/lib/libLLVM-${shortVersion}.dylib
ln -s $lib/lib/libLLVM.dylib $lib/lib/libLLVM-${release_version}.dylib
''
+ optionalString (stdenv.buildPlatform != stdenv.hostPlatform) ''
cp NATIVE/bin/llvm-config $dev/bin/llvm-config-native
'';
@ -197,27 +144,4 @@ in stdenv.mkDerivation (rec {
under the "Apache 2.0 License with LLVM exceptions".
'';
};
} // lib.optionalAttrs enableManpages {
pname = "llvm-manpages";
buildPhase = ''
make docs-llvm-man
'';
propagatedBuildInputs = [];
installPhase = ''
make -C docs install
'';
postPatch = null;
postInstall = null;
outputs = [ "out" ];
doCheck = false;
meta = {
description = "man pages for LLVM ${version}";
};
})
}

View File

@ -1,22 +1,21 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fec956091cd5..5a766f5c5d7c 100644
index 7e25e0407db2..72f031a82b75 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -303,6 +303,9 @@ set(LLVM_EXAMPLES_INSTALL_DIR "examples" CACHE STRING
"Path for examples subdirectory (enabled by LLVM_BUILD_EXAMPLES=ON) (defaults to 'examples')")
mark_as_advanced(LLVM_EXAMPLES_INSTALL_DIR)
+set(LLVM_INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}/cmake/llvm" CACHE STRING
+ "Path for CMake subdirectory (defaults to lib/cmake/llvm)" )
+
# They are used as destination of target generators.
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
@@ -995,7 +995,7 @@ if (NOT TENSORFLOW_AOT_PATH STREQUAL "")
add_subdirectory(${TENSORFLOW_AOT_PATH}/xla_aot_runtime_src
${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/tf_runtime)
install(TARGETS tf_xla_runtime EXPORT LLVMExports
- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT tf_xla_runtime)
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} COMPONENT tf_xla_runtime)
set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS tf_xla_runtime)
# Once we add more modules, we should handle this more automatically.
if (DEFINED LLVM_OVERRIDE_MODEL_HEADER_INLINERSIZEMODEL)
diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake
index fed1fec7d72e..4baed19b9e98 100644
index 93e6d67551de..8d367457af5a 100644
--- a/cmake/modules/AddLLVM.cmake
+++ b/cmake/modules/AddLLVM.cmake
@@ -838,8 +838,8 @@ macro(add_llvm_library name)
@@ -874,8 +874,8 @@ macro(add_llvm_library name)
get_target_export_arg(${name} LLVM export_to_llvmexports ${umbrella})
install(TARGETS ${name}
${export_to_llvmexports}
@ -25,62 +24,55 @@ index fed1fec7d72e..4baed19b9e98 100644
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" COMPONENT ${name}
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" COMPONENT ${name}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT ${name})
if (NOT LLVM_ENABLE_IDE)
@@ -1056,7 +1056,7 @@ function(process_llvm_pass_plugins)
"set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})")
install(FILES
${llvm_cmake_builddir}/LLVMConfigExtensions.cmake
- DESTINATION ${LLVM_INSTALL_PACKAGE_DIR}
+ DESTINATION ${LLVM_INSTALL_CMAKE_DIR}
COMPONENT cmake-exports)
set(ExtensionDef "${LLVM_BINARY_DIR}/include/llvm/Support/Extension.def")
@@ -1902,7 +1902,7 @@ function(llvm_install_library_symlink name dest type)
@@ -2043,7 +2043,7 @@ function(llvm_install_library_symlink name dest type)
set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX})
set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX})
- set(output_dir lib${LLVM_LIBDIR_SUFFIX})
+ set(output_dir ${CMAKE_INSTALL_FULL_LIBDIR}${LLVM_LIBDIR_SUFFIX})
if(WIN32 AND "${type}" STREQUAL "SHARED")
set(output_dir bin)
set(output_dir "${CMAKE_INSTALL_BINDIR}")
endif()
@@ -1913,7 +1913,7 @@ function(llvm_install_library_symlink name dest type)
endfunction()
-function(llvm_install_symlink name dest)
+function(llvm_install_symlink name dest output_dir)
cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN})
foreach(path ${CMAKE_MODULE_PATH})
if(EXISTS ${path}/LLVMInstallSymlink.cmake)
@@ -1936,7 +1936,7 @@ function(llvm_install_symlink name dest)
set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX})
install(SCRIPT ${INSTALL_SYMLINK}
- CODE "install_symlink(${full_name} ${full_dest} ${LLVM_TOOLS_INSTALL_DIR})"
+ CODE "install_symlink(${full_name} ${full_dest} ${output_dir})"
COMPONENT ${component})
if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE)
@@ -2019,7 +2019,8 @@ function(add_llvm_tool_symlink link_name target)
endif()
if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS)
- llvm_install_symlink(${link_name} ${target})
+ GNUInstallDirs_get_absolute_install_dir(output_dir LLVM_TOOLS_INSTALL_DIR)
+ llvm_install_symlink(${link_name} ${target} ${output_dir})
endif()
endif()
endfunction()
@@ -2148,9 +2149,9 @@ function(llvm_setup_rpath name)
@@ -2312,16 +2312,37 @@ function(llvm_setup_rpath name)
if (APPLE)
set(_install_name_dir INSTALL_NAME_DIR "@rpath")
- set(_install_rpath "@loader_path/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
+ set(_install_rpath "@loader_path/../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
elseif(${CMAKE_SYSTEM_NAME} MATCHES "AIX" AND BUILD_SHARED_LIBS)
# $ORIGIN is not interpreted at link time by aix ld.
# Since BUILD_SHARED_LIBS is only recommended for use by developers,
# hardcode the rpath to build/install lib dir first in this mode.
# FIXME: update this when there is better solution.
- set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
+ set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
+ set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_FULL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
elseif(UNIX)
- set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
- set(_build_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
- set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}")
+ # Note that we add `extra_libdir` (aka `LLVM_LIBRARY_DIR` in our case) back
+ # to `_install_rpath` here.
+ #
+ # In nixpkgs we do not build and install LLVM alongside rdeps of LLVM (i.e.
+ # clang); instead LLVM is its own package and thus lands at its own nix
+ # store path. This makes it so that the default relative rpath (`../lib/`)
+ # does not point at the LLVM shared objects.
+ #
+ # More discussion here:
+ # - https://github.com/NixOS/nixpkgs/pull/235624#discussion_r1220150329
+ # - https://reviews.llvm.org/D146918 (16.0.5+)
+ #
+ # Note that we leave `extra_libdir` in `_build_rpath`: without FHS there is
+ # no potential that this will result in us pulling in the "wrong" LLVM.
+ # Adding this to the build rpath means we aren't forced to use
+ # `installCheckPhase` instead of `checkPhase` (i.e. binaries in the build
+ # dir, pre-install, will have the right rpath for LLVM).
+ #
+ # As noted in the differential above, an alternative solution is to have
+ # all rdeps of nixpkgs' LLVM (that use the AddLLVM.cmake machinery) set
+ # `CMAKE_INSTALL_RPATH`.
+ set(_build_rpath "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
+ set(_install_rpath "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir})
if(${CMAKE_SYSTEM_NAME} MATCHES "(FreeBSD|DragonFly)")
set_property(TARGET ${name} APPEND_STRING PROPERTY
@ -91,7 +83,7 @@ index 891c9e6d618c..8d963f3b0069 100644
+++ b/cmake/modules/AddOCaml.cmake
@@ -147,9 +147,9 @@ function(add_ocaml_library name)
endforeach()
if( APPLE )
- set(ocaml_rpath "@executable_path/../../../lib${LLVM_LIBDIR_SUFFIX}")
+ set(ocaml_rpath "@executable_path/../../../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}")
@ -100,121 +92,70 @@ index 891c9e6d618c..8d963f3b0069 100644
+ set(ocaml_rpath "\\$ORIGIN/../../../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}")
endif()
list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}")
diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt
index cea0c1df0a14..eedcd9450312 100644
index d99af79aa38e..21e794224b99 100644
--- a/cmake/modules/CMakeLists.txt
+++ b/cmake/modules/CMakeLists.txt
@@ -2,7 +2,7 @@ include(ExtendPath)
include(LLVMDistributionSupport)
include(FindPrefixFromConfig)
-set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm)
+set(LLVM_INSTALL_PACKAGE_DIR ${LLVM_INSTALL_CMAKE_DIR} CACHE STRING "Path for CMake subdirectory (defaults to 'cmake/llvm')")
set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}")
# First for users who use an installed LLVM, create the LLVMExports.cmake file.
@@ -122,7 +122,7 @@ set(LLVM_CONFIG_INCLUDE_DIRS
@@ -127,7 +127,7 @@ set(LLVM_CONFIG_INCLUDE_DIRS
)
list(REMOVE_DUPLICATES LLVM_CONFIG_INCLUDE_DIRS)
-extend_path(LLVM_CONFIG_LIBRARY_DIR "\${LLVM_INSTALL_PREFIX}" "lib\${LLVM_LIBDIR_SUFFIX}")
+extend_path(LLVM_CONFIG_LIBRARY_DIR "\${LLVM_INSTALL_PREFIX}" "${CMAKE_INSTALL_LIBDIR}\${LLVM_LIBDIR_SUFFIX}")
set(LLVM_CONFIG_LIBRARY_DIRS
"${LLVM_CONFIG_LIBRARY_DIR}"
# FIXME: Should there be other entries here?
diff --git a/cmake/modules/LLVMInstallSymlink.cmake b/cmake/modules/LLVMInstallSymlink.cmake
index b5c35f706cb7..9261ab797de6 100644
--- a/cmake/modules/LLVMInstallSymlink.cmake
+++ b/cmake/modules/LLVMInstallSymlink.cmake
@@ -6,7 +6,7 @@ include(GNUInstallDirs)
function(install_symlink name target outdir)
set(DESTDIR $ENV{DESTDIR})
- set(bindir "${DESTDIR}${CMAKE_INSTALL_PREFIX}/${outdir}")
+ set(bindir "${DESTDIR}${outdir}/")
message(STATUS "Creating ${name}")
diff --git a/docs/CMake.rst b/docs/CMake.rst
index 044ec8a4d39d..504d0eac3ade 100644
index 7926de258ec8..5ae01adc3905 100644
--- a/docs/CMake.rst
+++ b/docs/CMake.rst
@@ -224,7 +224,7 @@ description is in `LLVM-related variables`_ below.
@@ -250,7 +250,7 @@ description is in `LLVM-related variables`_ below.
**LLVM_LIBDIR_SUFFIX**:STRING
Extra suffix to append to the directory where libraries are to be
installed. On a 64-bit architecture, one could use ``-DLLVM_LIBDIR_SUFFIX=64``
- to install libraries to ``/usr/lib64``.
+ to install libraries to ``/usr/lib64``. See also ``CMAKE_INSTALL_LIBDIR``.
**LLVM_PARALLEL_{COMPILE,LINK}_JOBS**:STRING
Building the llvm toolchain can use a lot of resources, particularly
@@ -910,9 +910,11 @@ the ``cmake`` command or by setting it directly in ``ccmake`` or ``cmake-gui``).
This file is available in two different locations.
-* ``<INSTALL_PREFIX>/lib/cmake/llvm/LLVMConfig.cmake`` where
- ``<INSTALL_PREFIX>`` is the install prefix of an installed version of LLVM.
- On Linux typically this is ``/usr/lib/cmake/llvm/LLVMConfig.cmake``.
+* ``<LLVM_INSTALL_PACKAGE_DIR>LLVMConfig.cmake`` where
+ ``<LLVM_INSTALL_PACKAGE_DIR>`` is the location where LLVM CMake modules are
+ installed as part of an installed version of LLVM. This is typically
+ ``cmake/llvm/`` within the lib directory. On Linux, this is typically
+ ``/usr/lib/cmake/llvm/LLVMConfig.cmake``.
* ``<LLVM_BUILD_ROOT>/lib/cmake/llvm/LLVMConfig.cmake`` where
``<LLVM_BUILD_ROOT>`` is the root of the LLVM build tree. **Note: this is only
diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt
index b46319f24fc8..2feabd1954e4 100644
--- a/include/llvm/CMakeLists.txt
+++ b/include/llvm/CMakeLists.txt
@@ -5,5 +5,5 @@ add_subdirectory(Frontend)
# If we're doing an out-of-tree build, copy a module map for generated
# header files into the build area.
if (NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
- configure_file(module.modulemap.build module.modulemap COPYONLY)
+ configure_file(module.modulemap.build ${LLVM_INCLUDE_DIR}/module.modulemap COPYONLY)
endif (NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
@@ -284,6 +284,10 @@ manual, or execute ``cmake --help-variable VARIABLE_NAME``.
The path to install executables, relative to the *CMAKE_INSTALL_PREFIX*.
Defaults to "bin".
+**CMAKE_INSTALL_LIBDIR**:PATH
+ The path to install libraries, relative to the *CMAKE_INSTALL_PREFIX*.
+ Defaults to "lib".
+
**CMAKE_INSTALL_INCLUDEDIR**:PATH
The path to install header files, relative to the *CMAKE_INSTALL_PREFIX*.
Defaults to "include".
diff --git a/tools/llvm-config/BuildVariables.inc.in b/tools/llvm-config/BuildVariables.inc.in
index abbb8a450da6..70c497be12f5 100644
index 370005cd8d7d..7e790bc52111 100644
--- a/tools/llvm-config/BuildVariables.inc.in
+++ b/tools/llvm-config/BuildVariables.inc.in
@@ -23,7 +23,10 @@
@@ -23,6 +23,7 @@
#define LLVM_CXXFLAGS "@LLVM_CXXFLAGS@"
#define LLVM_BUILDMODE "@LLVM_BUILDMODE@"
#define LLVM_LIBDIR_SUFFIX "@LLVM_LIBDIR_SUFFIX@"
+#define LLVM_INSTALL_BINDIR "@CMAKE_INSTALL_BINDIR@"
+#define LLVM_INSTALL_LIBDIR "@CMAKE_INSTALL_LIBDIR@"
#define LLVM_INSTALL_INCLUDEDIR "@CMAKE_INSTALL_INCLUDEDIR@"
+#define LLVM_INSTALL_CMAKEDIR "@LLVM_INSTALL_CMAKE_DIR@"
#define LLVM_INSTALL_PACKAGE_DIR "@LLVM_INSTALL_PACKAGE_DIR@"
#define LLVM_TARGETS_BUILT "@LLVM_TARGETS_BUILT@"
#define LLVM_SYSTEM_LIBS "@LLVM_SYSTEM_LIBS@"
#define LLVM_BUILD_SYSTEM "@LLVM_BUILD_SYSTEM@"
diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp
index 8ed88f33ead4..5e7184bab90d 100644
index b1d795a0a349..de6cb1514f05 100644
--- a/tools/llvm-config/llvm-config.cpp
+++ b/tools/llvm-config/llvm-config.cpp
@@ -363,12 +363,20 @@ int main(int argc, char **argv) {
ActiveIncludeDir = std::string(Path.str());
}
{
- SmallString<256> Path(LLVM_TOOLS_INSTALL_DIR);
+ SmallString<256> Path(LLVM_INSTALL_BINDIR);
@@ -366,7 +366,11 @@ int main(int argc, char **argv) {
sys::fs::make_absolute(ActivePrefix, Path);
ActiveBinDir = std::string(Path.str());
}
- ActiveLibDir = ActivePrefix + "/lib" + LLVM_LIBDIR_SUFFIX;
- ActiveCMakeDir = ActiveLibDir + "/cmake/llvm";
+ {
+ SmallString<256> Path(LLVM_INSTALL_LIBDIR LLVM_LIBDIR_SUFFIX);
+ sys::fs::make_absolute(ActivePrefix, Path);
+ ActiveLibDir = std::string(Path.str());
+ }
+ {
+ SmallString<256> Path(LLVM_INSTALL_CMAKEDIR);
+ sys::fs::make_absolute(ActivePrefix, Path);
+ ActiveCMakeDir = std::string(Path.str());
+ }
ActiveIncludeOption = "-I" + ActiveIncludeDir;
}
{
SmallString<256> Path(LLVM_INSTALL_PACKAGE_DIR);
sys::fs::make_absolute(ActivePrefix, Path);

View File

@ -1,28 +0,0 @@
diff --git a/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
index 0aba18b20..9bb75e7f4 100644
--- a/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
+++ b/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
@@ -33,6 +33,8 @@ ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
auto TargetABI = getTargetABI(ABIName);
bool IsRV64 = TT.isArch64Bit();
bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
+ bool IsRV32D = FeatureBits[RISCV::FeatureStdExtD];
+ bool IsRV32F = FeatureBits[RISCV::FeatureStdExtF];
if (!ABIName.empty() && TargetABI == ABI_Unknown) {
errs()
@@ -56,10 +58,10 @@ ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
if (TargetABI != ABI_Unknown)
return TargetABI;
- // For now, default to the ilp32/ilp32e/lp64 ABI if no explicit ABI is given
- // or an invalid/unrecognised string is given. In the future, it might be
- // worth changing this to default to ilp32f/lp64f and ilp32d/lp64d when
- // hardware support for floating point is present.
+ if (IsRV32D)
+ return ABI_ILP32D;
+ if (IsRV32F)
+ return ABI_ILP32F;
if (IsRV32E)
return ABI_ILP32E;
if (IsRV64)

View File

@ -1,16 +0,0 @@
diff --git a/tools/llvm-config/llvm-config.cpp b/tools/llvm-config/llvm-config.cpp
index 94d426b..37f7794 100644
--- a/tools/llvm-config/llvm-config.cpp
+++ b/tools/llvm-config/llvm-config.cpp
@@ -333,6 +333,11 @@ int main(int argc, char **argv) {
ActiveIncludeOption = "-I" + ActiveIncludeDir;
}
+ /// Nix-specific multiple-output handling: override ActiveLibDir
+ if (!IsInDevelopmentTree) {
+ ActiveLibDir = std::string("@lib@") + "/lib" + LLVM_LIBDIR_SUFFIX;
+ }
+
/// We only use `shared library` mode in cases where the static library form
/// of the components provided are not available; note however that this is
/// skipped if we're run from within the build dir. However, once installed,

15
nix/llvm/sources.nix Normal file
View File

@ -0,0 +1,15 @@
{ fetchurl }: rec {
version = "16.0.6";
cmake = fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/cmake-${version}.src.tar.xz";
sha256 = "sha256-OdNCpBYQldLyj7ElPkWFl4rFBSERfaZm4rH28oti9RQ=";
};
llvm = fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-${version}.src.tar.xz";
sha256 = "sha256-6R20TRs7scM/zqmn0fJCO4g+qpFj09VsoqptLwcRvCk=";
};
clang = fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/clang-${version}.src.tar.xz";
sha256 = "sha256-EYa25u7+rdCZEu1zs3KehbWfBDckuygYqVouwCRXGEA=";
};
}

View File

@ -31,32 +31,26 @@ let
suppress_build_script_link_lines=false
'';
};
sources = import ../llvm/sources.nix { inherit (pkgs) fetchurl; };
in rec {
llvm-nac3 = pkgs.stdenvNoCC.mkDerivation rec {
pname = "llvm-nac3-msys2";
version = "14.0.6";
src-llvm = pkgs.fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/llvm-${version}.src.tar.xz";
sha256 = "sha256-BQki7KrKV4H99mMeqSvHFRg/IC+dLxUUcibwI0FPYZo=";
};
src-clang = pkgs.fetchurl {
url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-${version}/clang-${version}.src.tar.xz";
sha256 = "sha256-K1hHtqYxGLnv5chVSDY8gf/glrZsOzZ16VPiY0KuQDE=";
};
version = "16.0.6";
buildInputs = [ pkgs.wineWowPackages.stable ];
phases = [ "unpackPhase" "patchPhase" "configurePhase" "buildPhase" "installPhase" ];
unpackPhase =
''
mkdir llvm
tar xf ${src-llvm} -C llvm --strip-components=1
mv llvm/Modules/* llvm/cmake/modules # work around https://github.com/llvm/llvm-project/issues/53281
tar xf ${sources.llvm} -C llvm --strip-components=1
tar xf ${sources.cmake} -C llvm/cmake --strip-components=2
mkdir clang
tar xf ${src-clang} -C clang --strip-components=1
tar xf ${sources.clang} -C clang --strip-components=1
mkdir cmake
ln -s $PWD/llvm/cmake cmake/Modules
cd llvm
# build of llvm-lto fails and -DLLVM_BUILD_TOOLS=OFF does not disable it reliably because cmake
rm -rf tools/lto
'';
patches = [ ../llvm/llvm-future-riscv-abi.diff ];
configurePhase =
''
export HOME=`mktemp -d`
@ -65,7 +59,7 @@ in rec {
${silenceFontconfig}
mkdir build
cd build
wine64 cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_UNWIND_TABLES=OFF -DLLVM_ENABLE_THREADS=ON -DLLVM_TARGETS_TO_BUILD=X86\;ARM\;RISCV -DLLVM_LINK_LLVM_DYLIB=OFF -DLLVM_ENABLE_FFI=OFF -DFFI_INCLUDE_DIR=fck-cmake -DFFI_LIBRARY_DIR=fck-cmake -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_INSTALL_PREFIX=Z:$out
wine64 cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_UNWIND_TABLES=OFF -DLLVM_ENABLE_THREADS=ON -DLLVM_TARGETS_TO_BUILD=X86\;ARM\;RISCV -DLLVM_LINK_LLVM_DYLIB=OFF -DLLVM_ENABLE_FFI=OFF -DFFI_INCLUDE_DIR=fck-cmake -DFFI_LIBRARY_DIR=fck-cmake -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_INSTALL_PREFIX=Z:$out
'';
buildPhase =
''
@ -88,6 +82,9 @@ in rec {
src = ../../.;
cargoLock = {
lockFile = ../../Cargo.lock;
outputHashes = {
"inkwell-0.5.0" = "sha256-Qsqy/fhD/qK0rKBeXetE99vW9G9XAePxlXv0An3Yeuo=";
};
};
nativeBuildInputs = [ pkgs.wineWowPackages.stable ];
buildPhase =
@ -98,7 +95,7 @@ in rec {
${silenceFontconfig}
export PYO3_CONFIG_FILE=Z:${pyo3-mingw-config}
export CC=clang
export LLVM_SYS_140_PREFIX=Z:${llvm-nac3}
export LLVM_SYS_160_PREFIX=Z:${llvm-nac3}
wine64 cargo build --release -p nac3artiq
'';
installPhase =

View File

@ -1,21 +1,21 @@
{ pkgs } : [
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libunwind-19.1.6-1-any.pkg.tar.zst";
sha256 = "1gv6hbqvfgjzirpljql1shlchldmf5ww3rfsspg90pq1frnwavjl";
name = "mingw-w64-clang-x86_64-libunwind-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libunwind-19.1.7-1-any.pkg.tar.zst";
sha256 = "0yhxd3hix069gy2gh69vbyg95m6x5nar1r9rm3rb8459nlhqxid5";
name = "mingw-w64-clang-x86_64-libunwind-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libc++-19.1.6-1-any.pkg.tar.zst";
sha256 = "1wbkvrx14ahc04cgkydvlxwmsl8jfnqwhy9sy4kn4wkdzmlcp1ax";
name = "mingw-w64-clang-x86_64-libc++-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libc++-19.1.7-1-any.pkg.tar.zst";
sha256 = "09gbfk91j07a7pxqmama9rjnqdzr3nw9v92b865mrgbn3lz8p5a3";
name = "mingw-w64-clang-x86_64-libc++-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libffi-3.4.6-1-any.pkg.tar.zst";
sha256 = "1q6gms980985bp087rnnpvz2fwfakgm5266izfk3b1mbp620s1yv";
name = "mingw-w64-clang-x86_64-libffi-3.4.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libffi-3.4.7-1-any.pkg.tar.zst";
sha256 = "0yi36mq6gzf4bdmx19fh9wzq7592q2c0zq0zj6rc0zn0bglcnm0r";
name = "mingw-w64-clang-x86_64-libffi-3.4.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -31,9 +31,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-xz-5.6.3-3-any.pkg.tar.zst";
sha256 = "1a7gc462gnrjy5qb0zfkr9qm8bsnnf02y6wp3c59n618dhsq7rcf";
name = "mingw-w64-clang-x86_64-xz-5.6.3-3-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-xz-5.6.4-1-any.pkg.tar.zst";
sha256 = "121srzvczq16aq0ki6yyym17lnjp6i4hka5wmydjvgrr7nbgik64";
name = "mingw-w64-clang-x86_64-xz-5.6.4-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -43,9 +43,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libxml2-2.12.9-2-any.pkg.tar.zst";
sha256 = "1b1r5llgqv88id8iwhqh23qwqmn5ic9hdamdc8xzij9hmcvdmmci";
name = "mingw-w64-clang-x86_64-libxml2-2.12.9-2-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libxml2-2.12.10-1-any.pkg.tar.zst";
sha256 = "1dch932lvsjfwp13cjm5d8sv84ql22c3gfjdrd4vayr8cpykfw4y";
name = "mingw-w64-clang-x86_64-libxml2-2.12.10-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -55,69 +55,69 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-libs-19.1.6-1-any.pkg.tar.zst";
sha256 = "0fpsnfyf0bg39a4ygzga06sr4wv4jp1jnc8lk6sr3z0nim0nlhjn";
name = "mingw-w64-clang-x86_64-llvm-libs-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-libs-19.1.7-1-any.pkg.tar.zst";
sha256 = "1688sknvlk8qy3zxh717pzdy882l5cmpbhyq8bg950hzvf1lpg79";
name = "mingw-w64-clang-x86_64-llvm-libs-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-19.1.6-1-any.pkg.tar.zst";
sha256 = "0whqs9nvfmgxj3c83px6dipcdw9zi858kgd8130201fy1mbnafp1";
name = "mingw-w64-clang-x86_64-llvm-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-19.1.7-1-any.pkg.tar.zst";
sha256 = "0c02mphj003s6k92nxkcvih3m7lj16wi0hwf17qr6m69b0dv691p";
name = "mingw-w64-clang-x86_64-llvm-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-clang-libs-19.1.6-1-any.pkg.tar.zst";
sha256 = "0rmzri7h043i73jy3c2jcrg3hy40dr5s9n96kmxgaghfhvlpilps";
name = "mingw-w64-clang-x86_64-clang-libs-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-clang-libs-19.1.7-1-any.pkg.tar.zst";
sha256 = "08ksr9jvbqb3shrixgjazrq0v3ag3g9ysqc93miwj57z7g75z8j4";
name = "mingw-w64-clang-x86_64-clang-libs-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-compiler-rt-19.1.6-1-any.pkg.tar.zst";
sha256 = "04cqlh35asvlh06nmhwnx9h0yrqk8zxd9lpzxmm1xh64kvm9maxn";
name = "mingw-w64-clang-x86_64-compiler-rt-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-compiler-rt-19.1.7-1-any.pkg.tar.zst";
sha256 = "04icdns7wydlagc2h9m587859x0pad62gkqg12vcc2nwgl485lz0";
name = "mingw-w64-clang-x86_64-compiler-rt-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-headers-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
sha256 = "05zsqgq8zwdcfacyqdxdjcf80447bgnrz71xv5cds0y135yziy7l";
name = "mingw-w64-clang-x86_64-headers-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-headers-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
sha256 = "0zmwqbmdhgkr8qpyxad64ks9p8lxw9mkr2hj7v5fnqcnsswlj8c6";
name = "mingw-w64-clang-x86_64-headers-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-crt-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
sha256 = "12fkxpk7rwy36snvvc7sdivx81pd4ckzh5ilyh7gl6ly4qayppp6";
name = "mingw-w64-clang-x86_64-crt-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-crt-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
sha256 = "14nmaw2rjs1818b8gi0n227ifcwi9s4sg9d6kv5yivpvn6pxyrvl";
name = "mingw-w64-clang-x86_64-crt-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-lld-19.1.6-1-any.pkg.tar.zst";
sha256 = "102bbv5acq1fvrfn8bp1x3503cb8hvcxmlpr86qsba4vm11l0wrw";
name = "mingw-w64-clang-x86_64-lld-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-lld-19.1.7-1-any.pkg.tar.zst";
sha256 = "1z1h40yfllns0n679j9s98r0hvg7i67kmhhf7iw97kz66jc1dkfy";
name = "mingw-w64-clang-x86_64-lld-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libwinpthread-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
sha256 = "1sris0qczxk5px9xy85976hbmqrpg49ns7yyzd9p455ckf740cid";
name = "mingw-w64-clang-x86_64-libwinpthread-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libwinpthread-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
sha256 = "0bk73xy9hgffc2pvainwvnprcxngx8y7af8w72i279cdd5f9xx1f";
name = "mingw-w64-clang-x86_64-libwinpthread-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-winpthreads-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
sha256 = "1r0m5xpsxdl00a2daj4p0wgl6037700pvw6p6zl91h1dr092r6pa";
name = "mingw-w64-clang-x86_64-winpthreads-git-12.0.0.r473.gce0d0bfb7-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-winpthreads-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
sha256 = "18y196l9dhqdqmjvs7g2jzdm8rrbrr5rqff7l30a9hpgwmra2xgv";
name = "mingw-w64-clang-x86_64-winpthreads-git-12.0.0.r509.g079e6092b-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-clang-19.1.6-1-any.pkg.tar.zst";
sha256 = "0j4a642fpnvqs79chhinc8r5q53q1wllmc1bzb01a4y7w9rqg4hw";
name = "mingw-w64-clang-x86_64-clang-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-clang-19.1.7-1-any.pkg.tar.zst";
sha256 = "1cgm8mdlfi18494zqz88gkgxagqhb82ls5hlgn07r3xldcwz4dma";
name = "mingw-w64-clang-x86_64-clang-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-rust-1.84.0-1-any.pkg.tar.zst";
sha256 = "0nrz9788grl50nkbhxswry143rrwpdnc6pk6f0k30kcp19qq6y2d";
name = "mingw-w64-clang-x86_64-rust-1.84.0-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-rust-1.84.1-1-any.pkg.tar.zst";
sha256 = "064l3kxrmx2fj19ljq0xv3cpb24spg2a33lk13z90fzymivwxsab";
name = "mingw-w64-clang-x86_64-rust-1.84.1-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -157,9 +157,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libtasn1-4.19.0-1-any.pkg.tar.zst";
sha256 = "19m59mjxww26ah2gk9c0i512fmqpyaj6r5na564kmg6wpwvkihcj";
name = "mingw-w64-clang-x86_64-libtasn1-4.19.0-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libtasn1-4.20.0-1-any.pkg.tar.zst";
sha256 = "0hv0xayhzhpwp8bdcs2r4xdvimk6266h68ki8abnii0pqiwfi86r";
name = "mingw-w64-clang-x86_64-libtasn1-4.20.0-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -175,9 +175,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-openssl-3.4.0-1-any.pkg.tar.zst";
sha256 = "0cgiqjmgdnwnv9r88z634dmqrzh06dmsfncyzymw0s16nnv2k7k2";
name = "mingw-w64-clang-x86_64-openssl-3.4.0-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-openssl-3.4.1-1-any.pkg.tar.zst";
sha256 = "0c5n7pib853xpgqxs0lb9gdaz4lbia94nf2jps1j7rispspclwwk";
name = "mingw-w64-clang-x86_64-openssl-3.4.1-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -199,9 +199,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-curl-8.11.1-1-any.pkg.tar.zst";
sha256 = "16yvyqjzxyzawgv26r1g145wphvhjil2b0pyhy4nj7v5d19n6wvh";
name = "mingw-w64-clang-x86_64-curl-8.11.1-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-curl-8.12.1-1-any.pkg.tar.zst";
sha256 = "05hq63qibshgar42vi6dsrcph3m1i0khnr2xdkvdqjjys7badrvp";
name = "mingw-w64-clang-x86_64-curl-8.12.1-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -253,9 +253,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libuv-1.49.2-1-any.pkg.tar.zst";
sha256 = "1b9slshbcprxjaj2qqypaywr0f2pgajg1bgspjk83hk65sx6sklb";
name = "mingw-w64-clang-x86_64-libuv-1.49.2-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-libuv-1.50.0-1-any.pkg.tar.zst";
sha256 = "1qwds9kl6x1afqwpqkha1my7xzwh39q5v0rrkj997i2wa1xgpr5c";
name = "mingw-w64-clang-x86_64-libuv-1.50.0-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -277,9 +277,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-cmake-3.31.4-1-any.pkg.tar.zst";
sha256 = "1xjjwgkqf2j97pcx0yd6j0lgmzgbgqjjf0s7j29mc03g89fhdhw0";
name = "mingw-w64-clang-x86_64-cmake-3.31.4-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-cmake-3.31.5-1-any.pkg.tar.zst";
sha256 = "04zyhhi3a58y5fy8l9nnsmn1qh5h1n02czh9d81f4fcnjs9fs4rj";
name = "mingw-w64-clang-x86_64-cmake-3.31.5-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -325,21 +325,21 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-tzdata-2024b-1-any.pkg.tar.zst";
sha256 = "0jihnr1i7vyzczxz60ds1x3gcm3p4ad2pq9d5vvpwjdwrxkvxmkc";
name = "mingw-w64-clang-x86_64-tzdata-2024b-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-tzdata-2025a-1-any.pkg.tar.zst";
sha256 = "1q09i8lj96m1kwkxh0qs96ssam8a6vpiylrlf4i55zrazrj9kvk1";
name = "mingw-w64-clang-x86_64-tzdata-2025a-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-python-3.12.8-2-any.pkg.tar.zst";
sha256 = "0lksgrmylvpr7yyjcc1szm30pnag7ixrj7vhdql1ryi4k9309v8s";
name = "mingw-w64-clang-x86_64-python-3.12.8-2-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-python-3.12.9-3-any.pkg.tar.zst";
sha256 = "054v2fw5rbj9n264alpav50573npa706lsmlxilcyc4xxc87k9v9";
name = "mingw-w64-clang-x86_64-python-3.12.9-3-any.pkg.tar.zst";
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-openmp-19.1.6-1-any.pkg.tar.zst";
sha256 = "0d3mm26hnw716n0ppzqhydxcgm4im081hiiy6l4zp267ad3kfg93";
name = "mingw-w64-clang-x86_64-llvm-openmp-19.1.6-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-llvm-openmp-19.1.7-1-any.pkg.tar.zst";
sha256 = "05qz2niykj5azx3n3wr2h48152ahcfcj9xsdpdqqvada1hh4c6cx";
name = "mingw-w64-clang-x86_64-llvm-openmp-19.1.7-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {
@ -349,9 +349,9 @@
})
(pkgs.fetchurl {
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-python-numpy-2.2.1-1-any.pkg.tar.zst";
sha256 = "0sgkhax9cwmkkrfrir45l91h6pgg339gaw6147gsayf8h8ag4brg";
name = "mingw-w64-clang-x86_64-python-numpy-2.2.1-1-any.pkg.tar.zst";
url = "https://mirror.msys2.org/mingw/clang64/mingw-w64-clang-x86_64-python-numpy-2.2.3-1-any.pkg.tar.zst";
sha256 = "0jzx828gb3d1pw7w4asv4jhp4yi802qdllkvb1c58msmn43pp76b";
name = "mingw-w64-clang-x86_64-python-numpy-2.2.3-1-any.pkg.tar.zst";
})
(pkgs.fetchurl {