mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
Merge pull request #3556 from rtfeldman/gen-dev/quicksort
Gen dev/quicksort
This commit is contained in:
commit
9ba188d534
3 changed files with 70 additions and 20 deletions
|
@ -734,7 +734,11 @@ impl<
|
||||||
ASM::mov_base32_freg64(buf, to_offset, reg);
|
ASM::mov_base32_freg64(buf, to_offset, reg);
|
||||||
}
|
}
|
||||||
_ if layout.stack_size(self.target_info) == 0 => {}
|
_ if layout.stack_size(self.target_info) == 0 => {}
|
||||||
_ if layout.safe_to_memcpy() && layout.stack_size(self.target_info) > 8 => {
|
// TODO: Verify this is always true.
|
||||||
|
// The dev backend does not deal with refcounting and does not care about if data is safe to memcpy.
|
||||||
|
// It is just temporarily storing the value due to needing to free registers.
|
||||||
|
// Later, it will be reloaded and stored in refcounted as needed.
|
||||||
|
_ if layout.stack_size(self.target_info) > 8 => {
|
||||||
let (from_offset, size) = self.stack_offset_and_size(sym);
|
let (from_offset, size) = self.stack_offset_and_size(sym);
|
||||||
debug_assert!(from_offset % 8 == 0);
|
debug_assert!(from_offset % 8 == 0);
|
||||||
debug_assert!(size % 8 == 0);
|
debug_assert!(size % 8 == 0);
|
||||||
|
|
|
@ -3845,8 +3845,9 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx, 'env>(
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
c_function_name: &str,
|
c_function_name: &str,
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let it = arguments.iter().map(|l| basic_type_from_layout(env, l));
|
let it = arguments.iter().map(|l| to_cc_type(env, l));
|
||||||
let argument_types = Vec::from_iter_in(it, env.arena);
|
let argument_types = Vec::from_iter_in(it, env.arena);
|
||||||
|
|
||||||
let return_type = basic_type_from_layout(env, &return_layout);
|
let return_type = basic_type_from_layout(env, &return_layout);
|
||||||
|
|
||||||
let cc_return = to_cc_return(env, &return_layout);
|
let cc_return = to_cc_return(env, &return_layout);
|
||||||
|
@ -3897,14 +3898,57 @@ fn expose_function_to_host_help_c_abi_v2<'a, 'ctx, 'env>(
|
||||||
param_types.len()
|
param_types.len()
|
||||||
);
|
);
|
||||||
|
|
||||||
let it = params.iter().zip(param_types).map(|(arg, fastcc_type)| {
|
let it = params
|
||||||
|
.iter()
|
||||||
|
.zip(param_types)
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, (arg, fastcc_type))| {
|
||||||
let arg_type = arg.get_type();
|
let arg_type = arg.get_type();
|
||||||
if arg_type == *fastcc_type {
|
if arg_type == *fastcc_type {
|
||||||
// the C and Fast calling conventions agree
|
// the C and Fast calling conventions agree
|
||||||
*arg
|
*arg
|
||||||
|
} else {
|
||||||
|
// not pretty, but seems to cover all our current cases
|
||||||
|
if arg_type.is_pointer_type() && !fastcc_type.is_pointer_type() {
|
||||||
|
// On x86_*, Modify the argument to specify it is passed by value and nonnull
|
||||||
|
// Aarch*, just passes in the pointer directly.
|
||||||
|
if matches!(
|
||||||
|
env.target_info.architecture,
|
||||||
|
roc_target::Architecture::X86_32 | roc_target::Architecture::X86_64
|
||||||
|
) {
|
||||||
|
let byval = context.create_type_attribute(
|
||||||
|
Attribute::get_named_enum_kind_id("byval"),
|
||||||
|
arg_type.into_pointer_type().get_element_type(),
|
||||||
|
);
|
||||||
|
let nonnull = context.create_type_attribute(
|
||||||
|
Attribute::get_named_enum_kind_id("nonnull"),
|
||||||
|
arg_type.into_pointer_type().get_element_type(),
|
||||||
|
);
|
||||||
|
// C return pointer goes at the beginning of params, and we must skip it if it exists.
|
||||||
|
let param_index = (i
|
||||||
|
+ (if matches!(cc_return, CCReturn::ByPointer) {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
})) as u32;
|
||||||
|
c_function.add_attribute(AttributeLoc::Param(param_index), byval);
|
||||||
|
c_function.add_attribute(AttributeLoc::Param(param_index), nonnull);
|
||||||
|
}
|
||||||
|
// bitcast the ptr
|
||||||
|
let fastcc_ptr = env
|
||||||
|
.builder
|
||||||
|
.build_bitcast(
|
||||||
|
*arg,
|
||||||
|
fastcc_type.ptr_type(AddressSpace::Generic),
|
||||||
|
"bitcast_arg",
|
||||||
|
)
|
||||||
|
.into_pointer_value();
|
||||||
|
|
||||||
|
env.builder.build_load(fastcc_ptr, "load_arg")
|
||||||
} else {
|
} else {
|
||||||
complex_bitcast_check_size(env, *arg, *fastcc_type, "to_fastcc_type_2")
|
complex_bitcast_check_size(env, *arg, *fastcc_type, "to_fastcc_type_2")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let arguments = Vec::from_iter_in(it, env.arena);
|
let arguments = Vec::from_iter_in(it, env.arena);
|
||||||
|
@ -6433,8 +6477,13 @@ impl<'ctx> FunctionSpec<'ctx> {
|
||||||
let sret_attribute_id = Attribute::get_named_enum_kind_id("sret");
|
let sret_attribute_id = Attribute::get_named_enum_kind_id("sret");
|
||||||
debug_assert!(sret_attribute_id > 0);
|
debug_assert!(sret_attribute_id > 0);
|
||||||
let ret_typ = self.typ.get_param_types()[param_index as usize];
|
let ret_typ = self.typ.get_param_types()[param_index as usize];
|
||||||
let sret_attribute =
|
// if ret_typ is a pointer type. We need the base type here.
|
||||||
ctx.create_type_attribute(sret_attribute_id, ret_typ.as_any_type_enum());
|
let ret_base_typ = if ret_typ.is_pointer_type() {
|
||||||
|
ret_typ.into_pointer_type().get_element_type()
|
||||||
|
} else {
|
||||||
|
ret_typ.as_any_type_enum()
|
||||||
|
};
|
||||||
|
let sret_attribute = ctx.create_type_attribute(sret_attribute_id, ret_base_typ);
|
||||||
fn_val.add_attribute(AttributeLoc::Param(0), sret_attribute);
|
fn_val.add_attribute(AttributeLoc::Param(0), sret_attribute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ comptime {
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
|
|
||||||
extern fn roc__mainForHost_1_exposed_generic(output: *RocList, input: *RocList) void;
|
extern fn roc__mainForHost_1_exposed(input: RocList) callconv(.C) RocList;
|
||||||
|
|
||||||
const Align = 2 * @alignOf(usize);
|
const Align = 2 * @alignOf(usize);
|
||||||
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
|
||||||
|
@ -83,7 +83,7 @@ export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
|
||||||
// warning! the array is currently stack-allocated so don't make this too big
|
// warning! the array is currently stack-allocated so don't make this too big
|
||||||
const NUM_NUMS = 100;
|
const NUM_NUMS = 100;
|
||||||
|
|
||||||
const RocList = extern struct { elements: [*]i64, length: usize };
|
const RocList = extern struct { elements: [*]i64, length: usize, capacity: usize };
|
||||||
|
|
||||||
const Unit = extern struct {};
|
const Unit = extern struct {};
|
||||||
|
|
||||||
|
@ -101,17 +101,14 @@ pub export fn main() u8 {
|
||||||
numbers[i] = @mod(@intCast(i64, i), 12);
|
numbers[i] = @mod(@intCast(i64, i), 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
var roc_list = RocList{ .elements = numbers, .length = NUM_NUMS };
|
var roc_list = RocList{ .elements = numbers, .length = NUM_NUMS, .capacity = NUM_NUMS };
|
||||||
|
|
||||||
// start time
|
// start time
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
std.os.clock_gettime(std.os.CLOCK.REALTIME, &ts1) catch unreachable;
|
||||||
|
|
||||||
// actually call roc to populate the callresult
|
// actually call roc to populate the callresult
|
||||||
var callresult: RocList = undefined;
|
const callresult: RocList = roc__mainForHost_1_exposed(roc_list);
|
||||||
roc__mainForHost_1_exposed_generic(&callresult, &roc_list);
|
|
||||||
|
|
||||||
// const callresult: RocList = roc__mainForHost_1_exposed_generic(&roc_list);
|
|
||||||
|
|
||||||
// stdout the result
|
// stdout the result
|
||||||
const length = std.math.min(20, callresult.length);
|
const length = std.math.min(20, callresult.length);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue