Fix of #862 where enums declarations where not regenerated. Updated @pool implementation.

This commit is contained in:
Christoffer Lerno
2023-07-18 22:28:43 +02:00
committed by Christoffer Lerno
parent 491c5ceec5
commit 4dcfb7a675
10 changed files with 164 additions and 116 deletions

View File

@@ -393,42 +393,69 @@ macro void @stack_pool(usz $size; @body) @builtin
};
}
macro void @pool(;@body) @builtin
macro void @pool(...; @body) @builtin
{
TempAllocator* allocator = temp();
usz mark = allocator.used;
defer allocator.reset(mark);
bool $has_arg = $vacount == 1;
assert($vacount <= 1);
TempAllocator* current = temp();
$if $has_arg:
TempAllocator* original = current;
if (current == $vaarg(0)) current = temp_allocator_next();
$endif
usz mark = current.used;
defer
{
current.reset(mark);
$if $has_arg:
thread_temp_allocator = original;
$endif;
}
@body();
}
macro void @allocating_pool(Allocator* using; @body(bool is_temp)) @builtin
{
TempAllocator* allocator = temp();
usz mark = allocator.used;
bool is_temp = allocator == using;
defer if (!is_temp) allocator.reset(mark);
@body(is_temp);
}
tlocal Allocator* thread_allocator @private = allocator::LIBC_ALLOCATOR;
tlocal TempAllocator* thread_temp_allocator @private = null;
tlocal TempAllocator*[2] temp_allocator_pair @private;
macro TempAllocator* temp_allocator() => temp();
macro TempAllocator* create_default_sized_temp_allocator() @local
{
$switch (env::MEMORY_ENV)
$case NORMAL:
return allocator::new_temp(1024 * 256, thread_allocator)!!;
$case SMALL:
return allocator::new_temp(1024 * 16, thread_allocator)!!;
$case TINY:
return allocator::new_temp(1024 * 2, thread_allocator)!!;
$case NONE:
unreachable("Temp allocator must explicitly created when memory-env is set to 'none'.");
$endswitch
}
fn TempAllocator *temp_allocator_next() @private
{
if (!thread_temp_allocator)
{
init_default_temp_allocators();
return thread_temp_allocator;
}
usz index = thread_temp_allocator == temp_allocator_pair[0] ? 1 : 0;
return thread_temp_allocator = temp_allocator_pair[index];
}
import libc;
fn void init_default_temp_allocators() @private
{
temp_allocator_pair[0] = create_default_sized_temp_allocator();
temp_allocator_pair[1] = create_default_sized_temp_allocator();
thread_temp_allocator = temp_allocator_pair[0];
}
macro TempAllocator* temp()
{
if (!thread_temp_allocator)
{
$switch (env::MEMORY_ENV)
$case NORMAL:
thread_temp_allocator = allocator::new_temp(1024 * 256, thread_allocator)!!;
$case SMALL:
thread_temp_allocator = allocator::new_temp(1024 * 16, thread_allocator)!!;
$case TINY:
thread_temp_allocator = allocator::new_temp(1024 * 2, thread_allocator)!!;
$case NONE:
unreachable("Temp allocator must explicitly created when memory-env is set to 'none'.");
$endswitch
init_default_temp_allocators();
}
return thread_temp_allocator;
}

View File

@@ -33,10 +33,10 @@ fault NumberConversion
macro String printf(String fmt, ..., Allocator* using = mem::heap())
{
@stack_mem(256; Allocator* mem)
@pool(using)
{
DString str;
str.init(.using = mem);
str.tinit();
str.printf(fmt, $vasplat());
return str.copy_str(using);
};

View File

@@ -146,9 +146,9 @@ fn Path! Path.append(self, String filename, Allocator* using = mem::heap())
if (!self.path_string.len) return new(filename, using, self.env)!;
assert(!is_separator(self.path_string[^1], self.env));
@stack_mem(256; Allocator* mem)
@pool(using)
{
DString dstr = dstring::new_with_capacity(self.path_string.len + 1 + filename.len, .using = mem);
DString dstr = dstring::tnew_with_capacity(self.path_string.len + 1 + filename.len);
dstr.append(self.path_string);
dstr.append(PREFERRED_SEPARATOR);
dstr.append(filename);

View File

@@ -1477,15 +1477,14 @@ AlignSize llvm_abi_alignment(GenContext *c, LLVMTypeRef type)
void llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len)
LLVMValueRef llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len)
{
assert(dest_align && src_align);
if (len <= UINT32_MAX)
{
LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_uint, len));
return;
return LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_uint, len));
}
LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_ulong, len));
return LLVMBuildMemCpy(c->builder, dest, dest_align, source, src_align, llvm_const_int(c, type_ulong, len));
}
void llvm_emit_memcpy_to_decl(GenContext *c, Decl *decl, LLVMValueRef source, unsigned source_alignment)

View File

@@ -1162,7 +1162,7 @@ static inline void llvm_emit_access_addr(GenContext *c, BEValue *be_value, Expr
if (flat_type->type_kind == TYPE_ENUM)
{
llvm_value_rvalue(c, be_value);
if (!member->backend_ref) llvm_get_typeid(c, parent->type);
if (!flat_type->decl->backend_ref) llvm_get_typeid(c, parent->type);
assert(member->backend_ref);
LLVMTypeRef value_type = llvm_get_type(c, type_get_array(member->type, vec_size(flat_type->decl->enums.values)));
AlignSize align = LLVMGetAlignment(member->backend_ref);

View File

@@ -445,7 +445,7 @@ INLINE LLVMValueRef llvm_emit_or_raw(GenContext *c, LLVMValueRef lhs, LLVMValueR
// -- Mem ops --
LLVMValueRef llvm_emit_memclear_size_align(GenContext *c, LLVMValueRef ptr, uint64_t size, AlignSize align);
void llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len);
LLVMValueRef llvm_emit_memcpy(GenContext *c, LLVMValueRef dest, unsigned dest_align, LLVMValueRef source, unsigned src_align, uint64_t len);
void llvm_emit_memcpy_to_decl(GenContext *c, Decl *decl, LLVMValueRef source, unsigned source_alignment);
// -- ABI --

View File

@@ -43,18 +43,7 @@ LLVMValueRef llvm_store_to_ptr_aligned(GenContext *c, LLVMValueRef destination,
case BE_ADDRESS_OPTIONAL:
UNREACHABLE
case BE_ADDRESS:
{
// Here we do an optimized(?) memcopy.
ByteSize size = type_size(value->type);
LLVMValueRef copy_size = llvm_const_int(c, size <= UINT32_MAX ? type_uint : type_usz, size);
LLVMValueRef copy = LLVMBuildMemCpy(c->builder,
destination,
alignment,
value->value,
value->alignment ? value->alignment : type_abi_alignment(value->type),
copy_size);
return copy;
}
return llvm_emit_memcpy(c, destination, alignment, value->value, value->alignment ? value->alignment : type_abi_alignment(value->type), type_size(value->type));
}
UNREACHABLE
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.571"
#define COMPILER_VERSION "0.4.572"

View File

@@ -79,7 +79,6 @@ entry:
%14 = load { ptr, i64 }, ptr %result, align 8
ret { ptr, i64 } %14
}
; Function Attrs: nounwind
define void @test.main() #0 {
entry:
@@ -118,18 +117,14 @@ entry:
%retparam44 = alloca i64, align 8
%varargslots45 = alloca [1 x %any], align 16
%result46 = alloca %"double[]", align 8
%allocator = alloca ptr, align 8
%error_var = alloca i64, align 8
%retparam49 = alloca ptr, align 8
%varargslots52 = alloca [1 x %any], align 16
%indirectarg = alloca %"any[]", align 8
%current = alloca ptr, align 8
%mark = alloca i64, align 8
%map3 = alloca %HashMap.0, align 8
%retparam53 = alloca i64, align 8
%varargslots54 = alloca [1 x %any], align 16
%result55 = alloca %"int[]", align 8
%mark58 = alloca i64, align 8
%retparam59 = alloca ptr, align 8
%retparam49 = alloca i64, align 8
%varargslots50 = alloca [1 x %any], align 16
%result51 = alloca %"int[]", align 8
%mark54 = alloca i64, align 8
%retparam55 = alloca ptr, align 8
call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 40, i1 false)
%0 = load ptr, ptr @std.core.mem.thread_allocator, align 8
call void @"std.collections.map$int$test.Foo$.HashMap.init"(ptr %map, i32 16, float 7.500000e-01, ptr %0)
@@ -173,7 +168,6 @@ entry:
%not_err = icmp eq i64 %26, 0
%27 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
br i1 %27, label %after_check, label %after_check12
after_check: ; preds = %entry
%28 = getelementptr inbounds %Foo, ptr %retparam10, i32 0, i32 0
%29 = insertvalue %any undef, ptr %28, 0
@@ -184,7 +178,6 @@ after_check: ; preds = %entry
%not_err11 = icmp eq i64 %32, 0
%33 = call i1 @llvm.expect.i1(i1 %not_err11, i1 true)
br i1 %33, label %after_check12, label %after_check12
after_check12: ; preds = %entry, %after_check, %after_check
%34 = call i8 @"std.collections.map$int$test.Foo$.HashMap.has_key"(ptr %map, i32 1)
store i8 %34, ptr %taddr, align 1
@@ -255,65 +248,37 @@ after_check12: ; preds = %entry, %after_check
%80 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
%not = icmp eq ptr %80, null
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %after_check12
%81 = load ptr, ptr @std.core.mem.thread_allocator, align 8
%82 = call i64 @std.core.mem.allocator.new_temp(ptr %retparam49, i64 262144, ptr %81)
%not_err50 = icmp eq i64 %82, 0
%83 = call i1 @llvm.expect.i1(i1 %not_err50, i1 true)
br i1 %83, label %after_check51, label %assign_optional
assign_optional: ; preds = %if.then
store i64 %82, ptr %error_var, align 8
br label %panic_block
after_check51: ; preds = %if.then
%84 = load ptr, ptr %retparam49, align 8
br label %noerr_block
panic_block: ; preds = %assign_optional
%85 = insertvalue %any undef, ptr %error_var, 0
%86 = insertvalue %any %85, i64 ptrtoint (ptr @"$ct.anyfault" to i64), 1
%87 = getelementptr inbounds [1 x %any], ptr %varargslots52, i64 0, i64 0
store %any %86, ptr %87, align 16
%88 = insertvalue %"any[]" undef, ptr %varargslots52, 0
%89 = insertvalue %"any[]" %88, i64 1, 1
store %"any[]" %89, ptr %indirectarg, align 8
call void @std.core.builtin.panicf(ptr @.panic_msg, i64 36, ptr @.file, i64 6, ptr @.func, i64 4, i32 424, ptr byval(%"any[]") align 8 %indirectarg)
unreachable
noerr_block: ; preds = %after_check51
store ptr %84, ptr @std.core.mem.thread_temp_allocator, align 8
call void @std.core.mem.init_default_temp_allocators()
br label %if.exit
if.exit: ; preds = %noerr_block, %after_check12
%90 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
store ptr %90, ptr %allocator, align 8
%91 = load ptr, ptr %allocator, align 8
%92 = getelementptr inbounds %TempAllocator, ptr %91, i32 0, i32 3
%93 = load i64, ptr %92, align 8
store i64 %93, ptr %mark, align 8
if.exit: ; preds = %if.then, %after_check12
%81 = load ptr, ptr @std.core.mem.thread_temp_allocator, align 8
store ptr %81, ptr %current, align 8
%82 = load ptr, ptr %current, align 8
%83 = getelementptr inbounds %TempAllocator, ptr %82, i32 0, i32 3
%84 = load i64, ptr %83, align 8
store i64 %84, ptr %mark, align 8
call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 40, i1 false)
%94 = load ptr, ptr @std.core.mem.thread_allocator, align 8
call void @"std.collections.map$int$double$.HashMap.init"(ptr %map3, i32 16, float 7.500000e-01, ptr %94)
%95 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00)
%96 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00)
%97 = load ptr, ptr @std.core.mem.thread_allocator, align 8
%98 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_list"(ptr %map3, ptr %97)
store { ptr, i64 } %98, ptr %result55, align 8
%99 = insertvalue %any undef, ptr %result55, 0
%100 = insertvalue %any %99, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
%101 = getelementptr inbounds [1 x %any], ptr %varargslots54, i64 0, i64 0
store %any %100, ptr %101, align 16
%102 = call i64 @std.io.printfn(ptr %retparam53, ptr @.str.11, i64 2, ptr %varargslots54, i64 1)
%103 = load ptr, ptr %allocator, align 8
%104 = getelementptr inbounds %TempAllocator, ptr %103, i32 0, i32 0
%105 = load i64, ptr %mark, align 8
store i64 %105, ptr %mark58, align 8
%106 = getelementptr inbounds %Allocator, ptr %104, i32 0, i32 0
%107 = load ptr, ptr %106, align 8
%108 = load i64, ptr %mark58, align 8
%109 = call i64 %107(ptr %retparam59, ptr %104, i64 %108, i64 0, i64 0, ptr null, i32 8)
%85 = load ptr, ptr @std.core.mem.thread_allocator, align 8
call void @"std.collections.map$int$double$.HashMap.init"(ptr %map3, i32 16, float 7.500000e-01, ptr %85)
%86 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00)
%87 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00)
%88 = load ptr, ptr @std.core.mem.thread_allocator, align 8
%89 = call { ptr, i64 } @"std.collections.map$int$double$.HashMap.key_list"(ptr %map3, ptr %88)
store { ptr, i64 } %89, ptr %result51, align 8
%90 = insertvalue %any undef, ptr %result51, 0
%91 = insertvalue %any %90, i64 ptrtoint (ptr @"$ct.sa$int" to i64), 1
%92 = getelementptr inbounds [1 x %any], ptr %varargslots50, i64 0, i64 0
store %any %91, ptr %92, align 16
%93 = call i64 @std.io.printfn(ptr %retparam49, ptr @.str.11, i64 2, ptr %varargslots50, i64 1)
%94 = load ptr, ptr %current, align 8
%95 = getelementptr inbounds %TempAllocator, ptr %94, i32 0, i32 0
%96 = load i64, ptr %mark, align 8
store i64 %96, ptr %mark54, align 8
%97 = getelementptr inbounds %Allocator, ptr %95, i32 0, i32 0
%98 = load ptr, ptr %97, align 8
%99 = load i64, ptr %mark54, align 8
%100 = call i64 %98(ptr %retparam55, ptr %95, i64 %99, i64 0, i64 0, ptr null, i32 8)
ret void
}
define internal void @.static_initialize.0() {

View File

@@ -0,0 +1,68 @@
module test;
fn String add(String s, Allocator* a, int x)
{
if (x < 0) return s.copy(a);
String tmp;
@pool(a)
{
tmp = "foo".tconcat(s);
tmp = add(tmp, a, x - 1);
};
ulong* y = malloc(ulong, .using = mem::temp());
*y = 0xAAAA_AAAA_AAAA_AAAA;
return tmp.concat("a", .using = a);
}
fn String breakit(String s, Allocator* a)
{
@pool(a)
{
return inner2("foo".concat(s, mem::temp()), a);
};
}
fn String inner2(String s, Allocator* a)
{
@pool(a)
{
ulong* z1 = tmalloc(ulong);
*z1 = 0xAAAA_AAAA_AAAA_AAAA;
String y = inner3(s, a);
ulong* z = tmalloc(ulong);
*z = 0xAAAA_AAAA_AAAA_AAAA;
return y;
};
}
fn String inner3(String s, Allocator* a)
{
@pool(a)
{
ulong* z1 = tmalloc(ulong);
*z1 = 0xAAAA_AAAA_AAAA_AAAA;
String y = inner4(s, a);
ulong* z = tmalloc(ulong);
*z = 0xAAAA_AAAA_AAAA_AAAA;
return y;
};
}
fn String inner4(String s, Allocator* a)
{
@pool(a)
{
String y = s.concat("xy**********", mem::temp()).copy(a);
return y;
};
}
fn void! test_temp_allocator() @test
{
assert("foofoofoofoofoofooabcaaaaaa" == add("abc", mem::temp(), 5), "was %s", add("abc", mem::temp(), 5));
}
fn void! test_temp_allocator2() @test
{
assert("fooxyz0123456789xy**********" == breakit("xyz0123456789", mem::temp()));
}