Compare commits
17 Commits
ded31e64ef
...
ad1f0abb55
Author | SHA1 | Date |
---|---|---|
|
ad1f0abb55 | |
|
c780cf849b | |
|
82453c78e8 | |
|
d111ed8104 | |
|
33e40db0f0 | |
|
d76709e092 | |
|
3ed60d8518 | |
|
1897c175c4 | |
|
a13686d4b3 | |
|
e9295b9d1a | |
|
73500c9081 | |
|
9ca34c714e | |
|
7fc2a30c14 | |
|
950f431483 | |
|
a50c690428 | |
|
48eb64403f | |
|
2c44b58bb8 |
|
@ -673,7 +673,6 @@ dependencies = [
|
|||
"inkwell",
|
||||
"insta",
|
||||
"itertools 0.11.0",
|
||||
"lazy_static",
|
||||
"nac3parser",
|
||||
"parking_lot",
|
||||
"rayon",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
passthru.cargoLock = cargoLock;
|
||||
nativeBuildInputs = [ pkgs.python3 pkgs.llvmPackages_14.clang packages.x86_64-linux.clang-unwrapped pkgs.llvmPackages_14.llvm.out llvm-nac3 ];
|
||||
buildInputs = [ pkgs.python3 llvm-nac3 ];
|
||||
checkInputs = [ (pkgs.python3.withPackages(ps: [ ps.numpy ])) ];
|
||||
checkInputs = [ (pkgs.python3.withPackages(ps: [ ps.numpy ps.scipy ])) ];
|
||||
checkPhase =
|
||||
''
|
||||
echo "Checking nac3standalone demos..."
|
||||
|
@ -94,7 +94,7 @@
|
|||
})
|
||||
];
|
||||
buildInputs = [
|
||||
(python3-mimalloc.withPackages(ps: [ ps.numpy ps.jsonschema nac3artiq-instrumented ]))
|
||||
(python3-mimalloc.withPackages(ps: [ ps.numpy ps.scipy ps.jsonschema nac3artiq-instrumented ]))
|
||||
pkgs.llvmPackages_14.llvm.out
|
||||
];
|
||||
phases = [ "buildPhase" "installPhase" ];
|
||||
|
@ -151,7 +151,7 @@
|
|||
rustc
|
||||
# runtime dependencies
|
||||
lld_14 # for running kernels on the host
|
||||
(packages.x86_64-linux.python3-mimalloc.withPackages(ps: [ ps.numpy ]))
|
||||
(packages.x86_64-linux.python3-mimalloc.withPackages(ps: [ ps.numpy ps.scipy ]))
|
||||
# development tools
|
||||
cargo-insta
|
||||
clippy
|
||||
|
|
|
@ -9,6 +9,7 @@ use inkwell::{
|
|||
memory_buffer::MemoryBuffer,
|
||||
module::{Linkage, Module},
|
||||
passes::PassBuilderOptions,
|
||||
support::is_multithreaded,
|
||||
targets::*,
|
||||
OptimizationLevel,
|
||||
};
|
||||
|
@ -582,7 +583,8 @@ impl Nac3 {
|
|||
membuffer.lock().push(buffer);
|
||||
})));
|
||||
let size_t = if self.isa == Isa::Host { 64 } else { 32 };
|
||||
let thread_names: Vec<String> = (0..4).map(|_| "main".to_string()).collect();
|
||||
let num_threads = if is_multithreaded() { 4 } else { 1 };
|
||||
let thread_names: Vec<String> = (0..num_threads).map(|_| "main".to_string()).collect();
|
||||
let threads: Vec<_> = thread_names
|
||||
.iter()
|
||||
.map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns)))
|
||||
|
|
|
@ -10,7 +10,6 @@ crossbeam = "0.8"
|
|||
parking_lot = "0.12"
|
||||
rayon = "1.5"
|
||||
nac3parser = { path = "../nac3parser" }
|
||||
lazy_static = "1.4"
|
||||
|
||||
[dependencies.inkwell]
|
||||
version = "0.2"
|
||||
|
|
|
@ -137,4 +137,12 @@ int32_t __nac3_list_slice_assign_var_size(
|
|||
return dest_arr_len - (dest_end - dest_ind) - 1;
|
||||
}
|
||||
return dest_arr_len;
|
||||
}
|
||||
|
||||
int32_t __nac3_isinf(double x) {
|
||||
return __builtin_isinf(x);
|
||||
}
|
||||
|
||||
int32_t __nac3_isnan(double x) {
|
||||
return __builtin_isnan(x);
|
||||
}
|
|
@ -7,7 +7,7 @@ use inkwell::{
|
|||
memory_buffer::MemoryBuffer,
|
||||
module::Module,
|
||||
types::BasicTypeEnum,
|
||||
values::{IntValue, PointerValue},
|
||||
values::{FloatValue, IntValue, PointerValue},
|
||||
AddressSpace, IntPredicate,
|
||||
};
|
||||
use nac3parser::ast::Expr;
|
||||
|
@ -432,3 +432,53 @@ pub fn list_slice_assignment<'ctx, 'a>(
|
|||
ctx.builder.build_unconditional_branch(cont_bb);
|
||||
ctx.builder.position_at_end(cont_bb);
|
||||
}
|
||||
|
||||
/// Generates a call to `isinf` in IR. Returns either an `i32` or `i1` representing the result,
|
||||
/// depending on the value of `to_i1`.
|
||||
pub fn call_isinf<'ctx, 'a>(
|
||||
generator: &dyn CodeGenerator,
|
||||
ctx: &CodeGenContext<'ctx, 'a>,
|
||||
v: FloatValue<'ctx>,
|
||||
to_i1: bool,
|
||||
) -> IntValue<'ctx> {
|
||||
let intrinsic_fn = ctx.module.get_function("__nac3_isinf").unwrap_or_else(|| {
|
||||
let fn_type = ctx.ctx.i32_type().fn_type(&[ctx.ctx.f64_type().into()], false);
|
||||
ctx.module.add_function("__nac3_isinf", fn_type, None)
|
||||
});
|
||||
|
||||
let val = ctx.builder
|
||||
.build_call(intrinsic_fn, &[v.into()], "isinf")
|
||||
.try_as_basic_value()
|
||||
.unwrap_left()
|
||||
.into_int_value();
|
||||
if to_i1 {
|
||||
generator.bool_to_i1(ctx, val)
|
||||
} else {
|
||||
val
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates a call to `isnan` in IR. Returns either an `i32` or `i1` representing the result,
|
||||
/// depending on the value of `to_i1`.
|
||||
pub fn call_isnan<'ctx, 'a>(
|
||||
generator: &dyn CodeGenerator,
|
||||
ctx: &CodeGenContext<'ctx, 'a>,
|
||||
v: FloatValue<'ctx>,
|
||||
to_i1: bool,
|
||||
) -> IntValue<'ctx> {
|
||||
let intrinsic_fn = ctx.module.get_function("__nac3_isnan").unwrap_or_else(|| {
|
||||
let fn_type = ctx.ctx.i32_type().fn_type(&[ctx.ctx.f64_type().into()], false);
|
||||
ctx.module.add_function("__nac3_isnan", fn_type, None)
|
||||
});
|
||||
|
||||
let val = ctx.builder
|
||||
.build_call(intrinsic_fn, &[v.into()], "isnan")
|
||||
.try_as_basic_value()
|
||||
.unwrap_left()
|
||||
.into_int_value();
|
||||
if to_i1 {
|
||||
generator.bool_to_i1(ctx, val)
|
||||
} else {
|
||||
val
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -82,51 +82,55 @@ pub struct FunInstance {
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum TopLevelDef {
|
||||
Class {
|
||||
// name for error messages and symbols
|
||||
/// Name for error messages and symbols.
|
||||
name: StrRef,
|
||||
// object ID used for TypeEnum
|
||||
/// Object ID used for [TypeEnum].
|
||||
object_id: DefinitionId,
|
||||
/// type variables bounded to the class.
|
||||
type_vars: Vec<Type>,
|
||||
// class fields
|
||||
// name, type, is mutable
|
||||
/// Class fields.
|
||||
///
|
||||
/// Name and type is mutable.
|
||||
fields: Vec<(StrRef, Type, bool)>,
|
||||
// class methods, pointing to the corresponding function definition.
|
||||
/// Class methods, pointing to the corresponding function definition.
|
||||
methods: Vec<(StrRef, Type, DefinitionId)>,
|
||||
// ancestor classes, including itself.
|
||||
/// Ancestor classes, including itself.
|
||||
ancestors: Vec<TypeAnnotation>,
|
||||
// symbol resolver of the module defined the class, none if it is built-in type
|
||||
/// Symbol resolver of the module defined the class; [None] if it is built-in type.
|
||||
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
||||
// constructor type
|
||||
/// Constructor type.
|
||||
constructor: Option<Type>,
|
||||
// definition location
|
||||
/// Definition location.
|
||||
loc: Option<Location>,
|
||||
},
|
||||
Function {
|
||||
// prefix for symbol, should be unique globally
|
||||
/// Prefix for symbol, should be unique globally.
|
||||
name: String,
|
||||
// simple name, the same as in method/function definition
|
||||
/// Simple name, the same as in method/function definition.
|
||||
simple_name: StrRef,
|
||||
// function signature.
|
||||
/// Function signature.
|
||||
signature: Type,
|
||||
// instantiated type variable IDs
|
||||
/// Instantiated type variable IDs.
|
||||
var_id: Vec<u32>,
|
||||
/// Function instance to symbol mapping
|
||||
/// Key: string representation of type variable values, sorted by variable ID in ascending
|
||||
///
|
||||
/// * Key: String representation of type variable values, sorted by variable ID in ascending
|
||||
/// order, including type variables associated with the class.
|
||||
/// Value: function symbol name.
|
||||
/// * Value: Function symbol name.
|
||||
instance_to_symbol: HashMap<String, String>,
|
||||
/// Function instances to annotated AST mapping
|
||||
/// Key: string representation of type variable values, sorted by variable ID in ascending
|
||||
///
|
||||
/// * Key: String representation of type variable values, sorted by variable ID in ascending
|
||||
/// order, including type variables associated with the class. Excluding rigid type
|
||||
/// variables.
|
||||
/// rigid type variables that would be substituted when the function is instantiated.
|
||||
///
|
||||
/// Rigid type variables that would be substituted when the function is instantiated.
|
||||
instance_to_stmt: HashMap<String, FunInstance>,
|
||||
// symbol resolver of the module defined the class
|
||||
/// Symbol resolver of the module defined the class.
|
||||
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
||||
// custom codegen callback
|
||||
/// Custom code generation callback.
|
||||
codegen_callback: Option<Arc<GenCall>>,
|
||||
// definition location
|
||||
/// Definition location.
|
||||
loc: Option<Location>,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
@ -12,6 +13,14 @@
|
|||
#error "Unsupported platform - Platform is not 32-bit or 64-bit"
|
||||
#endif
|
||||
|
||||
double dbl_nan(void) {
|
||||
return NAN;
|
||||
}
|
||||
|
||||
double dbl_inf(void) {
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
void output_bool(bool x) {
|
||||
puts(x ? "True" : "False");
|
||||
}
|
||||
|
@ -33,7 +42,11 @@ void output_uint64(uint64_t x) {
|
|||
}
|
||||
|
||||
void output_float64(double x) {
|
||||
printf("%f\n", x);
|
||||
if (isnan(x)) {
|
||||
puts("nan");
|
||||
} else {
|
||||
printf("%f\n", x);
|
||||
}
|
||||
}
|
||||
|
||||
void output_asciiart(int32_t x) {
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
import sys
|
||||
import importlib.util
|
||||
import importlib.machinery
|
||||
import numpy as np
|
||||
import pathlib
|
||||
import scipy
|
||||
|
||||
from numpy import int32, int64, uint32, uint64
|
||||
from typing import TypeVar, Generic
|
||||
|
@ -42,6 +44,12 @@ def Some(v: T) -> Option[T]:
|
|||
none = Option(None)
|
||||
|
||||
def patch(module):
|
||||
def dbl_nan():
|
||||
return np.nan
|
||||
|
||||
def dbl_inf():
|
||||
return np.inf
|
||||
|
||||
def output_asciiart(x):
|
||||
if x < 0:
|
||||
sys.stdout.write("\n")
|
||||
|
@ -56,7 +64,11 @@ def patch(module):
|
|||
|
||||
def extern(fun):
|
||||
name = fun.__name__
|
||||
if name == "output_asciiart":
|
||||
if name == "dbl_nan":
|
||||
return dbl_nan
|
||||
elif name == "dbl_inf":
|
||||
return dbl_inf
|
||||
elif name == "output_asciiart":
|
||||
return output_asciiart
|
||||
elif name == "output_float64":
|
||||
return output_float
|
||||
|
@ -86,6 +98,48 @@ def patch(module):
|
|||
module.Some = Some
|
||||
module.none = none
|
||||
|
||||
# NumPy math functions
|
||||
module.isnan = np.isnan
|
||||
module.isinf = np.isinf
|
||||
module.sin = np.sin
|
||||
module.cos = np.cos
|
||||
module.exp = np.exp
|
||||
module.exp2 = np.exp2
|
||||
module.log = np.log
|
||||
module.log10 = np.log10
|
||||
module.log2 = np.log2
|
||||
module.fabs = np.fabs
|
||||
module.floor = np.floor
|
||||
module.ceil = np.ceil
|
||||
module.trunc = np.trunc
|
||||
module.sqrt = np.sqrt
|
||||
module.rint = np.rint
|
||||
module.tan = np.tan
|
||||
module.arcsin = np.arcsin
|
||||
module.arccos = np.arccos
|
||||
module.arctan = np.arctan
|
||||
module.sinh = np.sinh
|
||||
module.cosh = np.cosh
|
||||
module.tanh = np.tanh
|
||||
module.arcsinh = np.arcsinh
|
||||
module.arccosh = np.arccosh
|
||||
module.arctanh = np.arctanh
|
||||
module.expm1 = np.expm1
|
||||
module.cbrt = np.cbrt
|
||||
module.erf = scipy.special.erf
|
||||
module.erfc = scipy.special.erfc
|
||||
module.gamma = scipy.special.gamma
|
||||
module.gammaln = scipy.special.gammaln
|
||||
module.j0 = scipy.special.j0
|
||||
module.j1 = scipy.special.j1
|
||||
module.arctan2 = np.arctan2
|
||||
module.copysign = np.copysign
|
||||
module.fmax = np.fmax
|
||||
module.fmin = np.fmin
|
||||
module.ldexp = np.ldexp
|
||||
module.hypot = np.hypot
|
||||
module.nextafter = np.nextafter
|
||||
|
||||
|
||||
def file_import(filename, prefix="file_import_"):
|
||||
filename = pathlib.Path(filename)
|
||||
|
|
|
@ -31,9 +31,8 @@ else
|
|||
nac3standalone=../../target/x86_64-unknown-linux-gnu/release/nac3standalone
|
||||
fi
|
||||
|
||||
rm -f ./*.o ./*.bc demo
|
||||
if [ -z "$use_lli" ]; then
|
||||
rm -f "*.o" demo
|
||||
|
||||
$nac3standalone "${nac3args[@]}"
|
||||
|
||||
clang -c -std=gnu11 -Wall -Wextra -O3 -o demo.o demo.c
|
||||
|
@ -45,15 +44,17 @@ if [ -z "$use_lli" ]; then
|
|||
./demo > "$outfile"
|
||||
fi
|
||||
else
|
||||
rm -f "*.o" "*.bc" demo
|
||||
|
||||
$nac3standalone --emit-llvm "${nac3args[@]}"
|
||||
|
||||
clang -c -std=gnu11 -Wall -Wextra -O3 -emit-llvm -o demo.bc demo.c
|
||||
|
||||
shopt -s nullglob
|
||||
llvm-link -o nac3out.bc module*.bc main.bc
|
||||
shopt -u nullglob
|
||||
|
||||
if [ -z "$outfile" ]; then
|
||||
lli --extra-module demo.bc --extra-module irrt.bc main.bc
|
||||
lli --extra-module demo.bc --extra-module irrt.bc nac3out.bc
|
||||
else
|
||||
lli --extra-module demo.bc --extra-module irrt.bc main.bc > "$outfile"
|
||||
lli --extra-module demo.bc --extra-module irrt.bc nac3out.bc > "$outfile"
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
@extern
|
||||
def output_bool(x: bool):
|
||||
...
|
||||
|
||||
@extern
|
||||
def output_float64(x: float):
|
||||
...
|
||||
|
||||
@extern
|
||||
def dbl_nan() -> float:
|
||||
...
|
||||
|
||||
@extern
|
||||
def dbl_inf() -> float:
|
||||
...
|
||||
|
||||
def dbl_pi() -> float:
|
||||
return 3.1415926535897932384626433
|
||||
|
||||
def dbl_e() -> float:
|
||||
return 2.71828182845904523536028747135266249775724709369995
|
||||
|
||||
def test_isnan():
|
||||
for x in [dbl_nan(), 0.0, dbl_inf()]:
|
||||
output_bool(isnan(x))
|
||||
|
||||
def test_isinf():
|
||||
for x in [dbl_inf(), -dbl_inf(), 0.0, dbl_nan()]:
|
||||
output_bool(isinf(x))
|
||||
|
||||
def test_sin():
|
||||
pi = dbl_pi()
|
||||
for x in [-pi, -pi / 2.0, -pi / 4.0, 0.0, pi / 4.0, pi / 2.0, pi, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(sin(x))
|
||||
|
||||
def test_cos():
|
||||
pi = dbl_pi()
|
||||
for x in [-pi, -pi / 2.0, -pi / 4.0, 0.0, pi / 4.0, pi / 2.0, pi, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(cos(x))
|
||||
|
||||
def test_exp():
|
||||
for x in [0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(exp(x))
|
||||
|
||||
def test_exp2():
|
||||
for x in [0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(exp2(x))
|
||||
|
||||
def test_log():
|
||||
e = dbl_e()
|
||||
for x in [1.0, e, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(log(x))
|
||||
|
||||
def test_log10():
|
||||
for x in [1.0, 10.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(log10(x))
|
||||
|
||||
def test_log2():
|
||||
for x in [1.0, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(log2(x))
|
||||
|
||||
def test_fabs():
|
||||
for x in [-1.0, 0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(fabs(x))
|
||||
|
||||
def test_floor():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(floor(x))
|
||||
|
||||
def test_ceil():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(ceil(x))
|
||||
|
||||
def test_trunc():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(trunc(x))
|
||||
|
||||
def test_sqrt():
|
||||
for x in [1.0, 2.0, 4.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(sqrt(x))
|
||||
|
||||
def test_rint():
|
||||
for x in [-1.5, -0.5, 0.5, 1.5, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(rint(x))
|
||||
|
||||
def test_tan():
|
||||
pi = dbl_pi()
|
||||
for x in [-pi, -pi / 2.0, -pi / 4.0, 0.0, pi / 4.0, pi / 2.0, pi, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(tan(x))
|
||||
|
||||
def test_arcsin():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arcsin(x))
|
||||
|
||||
def test_arccos():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arccos(x))
|
||||
|
||||
def test_arctan():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arctan(x))
|
||||
|
||||
def test_sinh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(sinh(x))
|
||||
|
||||
def test_cosh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(cosh(x))
|
||||
|
||||
def test_tanh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(tanh(x))
|
||||
|
||||
def test_arcsinh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arcsinh(x))
|
||||
|
||||
def test_arccosh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arccosh(x))
|
||||
|
||||
def test_arctanh():
|
||||
for x in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arctanh(x))
|
||||
|
||||
def test_expm1():
|
||||
for x in [0.0, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(expm1(x))
|
||||
|
||||
def test_cbrt():
|
||||
for x in [1.0, 8.0, 27.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(expm1(x))
|
||||
|
||||
def test_erf():
|
||||
for x in [-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(erf(x))
|
||||
|
||||
def test_erfc():
|
||||
for x in [-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(erfc(x))
|
||||
|
||||
def test_gamma():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(gamma(x))
|
||||
|
||||
def test_gammaln():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(gammaln(x))
|
||||
|
||||
def test_j0():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(j0(x))
|
||||
|
||||
def test_j1():
|
||||
for x in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0]:
|
||||
output_float64(j1(x))
|
||||
|
||||
def test_arctan2():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(arctan2(x1, x2))
|
||||
|
||||
def test_copysign():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(copysign(x1, x2))
|
||||
|
||||
def test_fmax():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(fmax(x1, x2))
|
||||
|
||||
def test_fmin():
|
||||
for x1 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-1.0, -0.5, 0.0, 0.5, 1.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(fmin(x1, x2))
|
||||
|
||||
def test_ldexp():
|
||||
for x1 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-2, -1, 0, 1, 2]:
|
||||
output_float64(ldexp(x1, x2))
|
||||
|
||||
def test_hypot():
|
||||
for x1 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(hypot(x1, x2))
|
||||
|
||||
def test_nextafter():
|
||||
for x1 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
for x2 in [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, dbl_inf(), -dbl_inf(), dbl_nan()]:
|
||||
output_float64(nextafter(x1, x2))
|
||||
|
||||
def run() -> int32:
|
||||
test_isnan()
|
||||
test_isinf()
|
||||
test_sin()
|
||||
test_cos()
|
||||
test_exp()
|
||||
test_exp2()
|
||||
test_log()
|
||||
test_log10()
|
||||
test_log2()
|
||||
test_fabs()
|
||||
test_floor()
|
||||
test_ceil()
|
||||
test_trunc()
|
||||
test_sqrt()
|
||||
test_rint()
|
||||
test_tan()
|
||||
test_arcsin()
|
||||
test_arccos()
|
||||
test_arctan()
|
||||
test_sinh()
|
||||
test_cosh()
|
||||
test_tanh()
|
||||
test_arcsinh()
|
||||
test_arccosh()
|
||||
test_arctanh()
|
||||
test_expm1()
|
||||
test_cbrt()
|
||||
test_erf()
|
||||
test_erfc()
|
||||
test_gamma()
|
||||
test_gammaln()
|
||||
test_j0()
|
||||
test_j1()
|
||||
test_arctan2()
|
||||
test_copysign()
|
||||
test_fmax()
|
||||
test_fmin()
|
||||
test_ldexp()
|
||||
test_hypot()
|
||||
test_nextafter()
|
||||
|
||||
return 0
|
|
@ -2,6 +2,7 @@ use clap::Parser;
|
|||
use inkwell::{
|
||||
memory_buffer::MemoryBuffer,
|
||||
passes::PassBuilderOptions,
|
||||
support::is_multithreaded,
|
||||
targets::*,
|
||||
OptimizationLevel,
|
||||
};
|
||||
|
@ -38,8 +39,9 @@ struct CommandLineArgs {
|
|||
/// The name of the input file.
|
||||
file_name: String,
|
||||
|
||||
/// The number of threads allocated to processing the source file.
|
||||
#[arg(default_value_t = 1)]
|
||||
/// The number of threads allocated to processing the source file. If 0 is passed to this
|
||||
/// parameter, all available threads will be used for compilation.
|
||||
#[arg(short = 'T', default_value_t = 1)]
|
||||
threads: u32,
|
||||
|
||||
/// The level to optimize the LLVM IR.
|
||||
|
@ -47,6 +49,8 @@ struct CommandLineArgs {
|
|||
opt_level: u32,
|
||||
|
||||
/// Whether to emit LLVM IR at the end of every module.
|
||||
///
|
||||
/// If multithreaded compilation is also enabled, each thread will emit its own module.
|
||||
#[arg(long, default_value_t = false)]
|
||||
emit_llvm: bool,
|
||||
|
||||
|
@ -207,6 +211,20 @@ fn main() {
|
|||
.map(|arg| if arg == "native" { host_target_machine.cpu.clone() } else { arg })
|
||||
.unwrap_or_default();
|
||||
let target_features = target_features.unwrap_or_default();
|
||||
let threads = if is_multithreaded() {
|
||||
if threads == 0 {
|
||||
std::thread::available_parallelism()
|
||||
.map(|threads| threads.get() as u32)
|
||||
.unwrap_or(1u32)
|
||||
} else {
|
||||
threads
|
||||
}
|
||||
} else {
|
||||
if threads != 1 {
|
||||
println!("Warning: Number of threads specified in command-line but multithreading is disabled in LLVM at build time! Defaulting to single-threaded compilation")
|
||||
}
|
||||
1
|
||||
};
|
||||
let opt_level = match opt_level {
|
||||
0 => OptimizationLevel::None,
|
||||
1 => OptimizationLevel::Less,
|
||||
|
|
|
@ -112,7 +112,7 @@ in stdenv.mkDerivation (rec {
|
|||
"-DLLVM_HOST_TRIPLE=${stdenv.hostPlatform.config}"
|
||||
"-DLLVM_DEFAULT_TARGET_TRIPLE=${stdenv.hostPlatform.config}"
|
||||
"-DLLVM_ENABLE_UNWIND_TABLES=OFF"
|
||||
"-DLLVM_ENABLE_THREADS=OFF"
|
||||
"-DLLVM_ENABLE_THREADS=ON"
|
||||
"-DLLVM_INCLUDE_BENCHMARKS=OFF"
|
||||
"-DLLVM_BUILD_TOOLS=OFF"
|
||||
"-DLLVM_TARGETS_TO_BUILD=X86;ARM;RISCV"
|
||||
|
|
|
@ -65,7 +65,7 @@ in rec {
|
|||
${silenceFontconfig}
|
||||
mkdir build
|
||||
cd build
|
||||
wine64 cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_UNWIND_TABLES=OFF -DLLVM_ENABLE_THREADS=OFF -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_BENCHMARKS=OFF -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_INSTALL_PREFIX=Z:$out
|
||||
'';
|
||||
buildPhase =
|
||||
''
|
||||
|
|
Loading…
Reference in New Issue