Version bump. Updated printf using "Formatter". Fix to initializers.

This commit is contained in:
Christoffer Lerno
2022-10-03 12:12:51 +02:00
committed by Christoffer Lerno
parent 9f7ed00f04
commit 4783946476
11 changed files with 850 additions and 739 deletions

View File

@@ -128,7 +128,7 @@ fn void test()
### Current status ### Current status
The current version of the compiler is alpha release 0.2. The current version of the compiler is alpha release 0.3.
It's possible to try out the current C3 compiler in the browser: https://ide.judge0.com/ this is courtesy of the It's possible to try out the current C3 compiler in the browser: https://ide.judge0.com/ this is courtesy of the
developer of Judge0. developer of Judge0.

View File

@@ -0,0 +1,572 @@
module std::io;
private fn void! Formatter.left_adjust(Formatter* this, usize len)
{
if (!this.flags.left) return;
for (usize l = len; l < this.width; l++) this.out(' ')?;
}
private fn void! Formatter.right_adjust(Formatter* this, usize len)
{
if (this.flags.left) return;
for (usize l = len; l < this.width; l++) this.out(' ')?;
}
private fn NtoaType int_from_variant(variant arg, bool *is_neg)
{
*is_neg = false;
$if (NtoaType.typeid == uint128.typeid):
switch (arg)
{
case int128:
int128 val = *arg;
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : val;
case uint128:
return *arg;
}
$endif;
if (arg.type.kind == TypeKind.POINTER)
{
return (NtoaType)(uptr)*(void**)arg.ptr;
}
switch (arg)
{
case bool:
return (NtoaType)*arg;
case ichar:
int val = *arg;
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
case short:
int val = *arg;
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
case int:
int val = *arg;
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
case long:
long val = *arg;
return (*is_neg = val < 0) ? (~(NtoaType)val) + 1 : (NtoaType)val;
case char:
return *arg;
case ushort:
return *arg;
case uint:
return *arg;
case ulong:
return *arg;
case float:
float f = *arg;
return (NtoaType)((*is_neg = f < 0) ? -f : f);
case double:
double d = *arg;
return (NtoaType)((*is_neg = d < 0) ? -d : d);
default:
return 0;
}
}
private fn FloatType float_from_variant(variant arg)
{
$if (env::I128_SUPPORT):
switch (arg)
{
case int128:
return *arg;
case uint128:
return *arg;
}
$endif;
$if (env::F128_SUPPORT):
if (arg.type == float128.typeid) return *((float128*)arg.ptr);
$endif;
$if (env::F16_SUPPORT):
if (arg.type == float16.typeid) return *((float16*)arg.ptr);
$endif;
if (arg.type.kind == TypeKind.POINTER)
{
return (FloatType)(uptr)(void*)arg.ptr;
}
switch (arg)
{
case bool:
return (FloatType)*arg;
case ichar:
return *arg;
case short:
return *arg;
case int:
return *arg;
case long:
return *arg;
case char:
return *arg;
case ushort:
return *arg;
case uint:
return *arg;
case ulong:
return *arg;
case float:
return (FloatType)*arg;
case double:
return (FloatType)*arg;
default:
return 0;
}
}
/**
* Read a simple integer value, typically for formatting.
*
* @param [inout] len_ptr "the length remaining."
* @param [in] buf "the buf to read from."
* @param maxlen "the maximum len that can be read."
* @return "The result of the atoi."
**/
private fn uint simple_atoi(char* buf, usize maxlen, usize* len_ptr) @inline
{
uint i = 0;
usize len = *len_ptr;
while (len < maxlen)
{
char c = buf[len];
if (c < '0' || c > '9') break;
i = i * 10 + c - '0';
len++;
}
*len_ptr = len;
return i;
}
private fn void! Formatter.out_substr(Formatter *this, char[] str)
{
usize l = conv::utf8_codepoints(str);
uint prec = this.prec;
if (this.flags.precision && l < prec) l = prec;
this.right_adjust(' ')?;
usize index = 0;
usize chars = str.len;
char* ptr = str.ptr;
while (index < chars)
{
char c = ptr[index];
// Break if we have precision set and we ran out...
if (c & 0xC0 != 0x80 && this.flags.precision && !prec--) break;
this.out(c)?;
index++;
}
return this.left_adjust(l);
}
union ConvUnion
{
ulong u;
double f;
}
private fn void! Formatter.etoa(Formatter* this, FloatType value)
{
// check for NaN and special values
if (value != value || value < FloatType.min || value > FloatType.max)
{
return this.ftoa(value);
}
// determine the sign
bool negative = value < 0;
if (negative) value = -value;
// default precision
if (!this.flags.precision)
{
this.prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// determine the decimal exponent
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
ConvUnion conv;
conv.f = (double)value;
int exp2 = (int)(conv.u >> 52 & 0x7FF) - 1023; // effectively log2
conv.u = (conv.u & (1u64 << 52 - 1)) | (1023u64 << 52); // drop the exponent so conv.F is now in [1,2)
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.f - 1.5) * 0.289529654602168);
// now we want to compute 10^expval but we want to be sure it won't overflow
exp2 = (int)(expval * 3.321928094887362 + 0.5);
double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
double z2 = z * z;
conv.u = (ulong)(exp2 + 1023) << 52;
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
conv.f *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
// correct for rounding errors
if (value < conv.f)
{
expval--;
conv.f /= 10;
}
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
uint minwidth = ((expval < 100) && (expval > -100)) ? 4 : 5;
// in "%g" mode, "prec" is the number of *significant figures* not decimals
if (this.flags.adapt_exp)
{
// do we want to fall-back to "%f" mode?
if (value >= 1e-4 && value < 1e6)
{
this.prec = this.prec > expval ? this.prec - expval - 1 : 0;
this.flags.precision = true; // make sure ftoa respects precision
// no characters in exponent
minwidth = 0;
expval = 0;
}
else
{
// we use one sigfig for the whole part
if (this.prec > 0 && this.flags.precision) this.prec--;
}
}
// Adjust width
uint fwidth = this.width > minwidth ? this.width - minwidth : 0;
// if we're padding on the right, DON'T pad the floating part
if (this.flags.left && minwidth) fwidth = 0;
// rescale the float value
if (expval) value /= conv.f;
// output the floating part
usize start_idx = this.idx;
PrintFlags old = this.flags;
this.flags.adapt_exp = false;
this.width = fwidth;
this.ftoa(negative ? -value : value)?;
this.flags = old;
// output the exponent part
if (minwidth)
{
// output the exponential symbol
this.out(this.flags.uppercase ? 'E' : 'e')?;
// output the exponent value
this.flags = { .zeropad = true, .plus = true };
this.width = minwidth - 1;
this.prec = 0;
this.ntoa((NtoaType)(expval < 0 ? -expval : expval), expval < 0, 10)?;
this.flags = old;
// might need to right-pad spaces
this.left_adjust(this.idx - start_idx)?;
}
}
// internal ftoa for fixed decimal floating point
private fn void! Formatter.ftoa(Formatter* this, FloatType value)
{
char[PRINTF_FTOA_BUFFER_SIZE] buf = void;
usize len = 0;
const FloatType[] POW10 = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
FloatType diff = 0.0;
// powers of 10
// test for special values
if (value != value)
{
return this.out_reverse("nan");
}
if (value < -FloatType.max)
{
return this.out_reverse("fni-");
}
if (value > FloatType.max)
{
if (this.flags.plus)
{
return this.out_reverse("fni+");
}
return this.out_reverse("fni");
}
// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
if (value > PRINTF_MAX_FLOAT || value < -PRINTF_MAX_FLOAT)
{
return this.etoa(value);
}
// test for negative
bool negative = value < 0;
if (negative) value = 0 - value;
// set default precision, if not set explicitly
if (!this.flags.precision) this.prec = PRINTF_DEFAULT_FLOAT_PRECISION;
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
while (this.prec > 9)
{
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = '0';
this.prec--;
}
// Safe due to 1e9 limit.
int whole = (int)value;
FloatType tmp = (value - whole) * POW10[this.prec];
ulong frac = (ulong)tmp;
diff = tmp - frac;
switch (true)
{
case diff > 0.5:
++frac;
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
if (frac >= POW10[this.prec])
{
frac = 0;
++whole;
}
case diff < 0.5:
break;
case !frac && (frac & 1):
// if halfway, round up if odd OR if last digit is 0
++frac;
}
if (!this.prec)
{
diff = value - (FloatType)whole;
if ((!(diff < 0.5) || diff > 0.5) && (whole & 1))
{
// exactly 0.5 and ODD, then round up
// 1.5 -> 2, but 2.5 -> 2
++whole;
}
}
else
{
uint count = this.prec;
// now do fractional part, as an unsigned number
do
{
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
--count;
buf[len++] = (char)(48 + (frac % 10));
}
while (frac /= 10);
// add extra 0s
while (count-- > 0)
{
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = '0';
}
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
// add decimal
buf[len++] = '.';
}
// do whole part, number is reversed
do
{
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = (char)(48 + (whole % 10));
}
while (whole /= 10);
// pad leading zeros
if (!this.flags.left && this.flags.zeropad)
{
if (this.width && (negative || this.flags.plus || this.flags.space)) this.width--;
while (len < this.width)
{
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = '0';
}
}
char next = {|
if (negative) return '-';
if (this.flags.plus) return '+';
if (this.flags.space) return ' ';
return 0;
|};
if (next)
{
if (len >= PRINTF_FTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = next;
}
return this.out_reverse(buf[:len]);
}
private fn void! Formatter.ntoa(Formatter* this, NtoaType value, bool negative, uint base)
{
char[PRINTF_NTOA_BUFFER_SIZE] buf = void;
usize len = 0;
// no hash for 0 values
if (!value) this.flags.hash = false;
// write if precision != 0 or value is != 0
if (!this.flags.precision || value)
{
char past_10 = (this.flags.uppercase ? 'A' : 'a') - 10;
do
{
if (len >= PRINTF_NTOA_BUFFER_SIZE) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
char digit = (char)(value % base);
buf[len++] = digit + (digit < 10 ? '0' : past_10);
value /= base;
}
while (value);
}
return this.ntoa_format(buf[:PRINTF_NTOA_BUFFER_SIZE], len, negative, base);
}
private fn void! Formatter.ntoa_format(Formatter* this, char[] buf, usize len, bool negative, uint base)
{
// pad leading zeros
if (!this.flags.left)
{
if (this.width && this.flags.zeropad && (negative || this.flags.plus || this.flags.space)) this.width--;
while (len < this.prec)
{
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = '0';
}
while (this.flags.zeropad && len < this.width)
{
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = '0';
}
}
// handle hash
if (this.flags.hash && base != 10)
{
if (!this.flags.precision && len && len == this.prec && len == this.width)
{
len--;
if (len) len--;
}
if (base != 10)
{
if (len + 1 >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
switch (base)
{
case 16:
buf[len++] = this.flags.uppercase ? 'X' : 'x';
case 8:
buf[len++] = this.flags.uppercase ? 'O' : 'o';
case 2:
buf[len++] = this.flags.uppercase ? 'B' : 'b';
default:
unreachable();
}
buf[len++] = '0';
}
}
switch (true)
{
case negative:
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = '-';
case this.flags.plus:
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = '+';
case this.flags.space:
if (len >= buf.len) return PrintFault.INTERNAL_BUFFER_EXCEEDED!;
buf[len++] = ' ';
}
if (!len) return;
return this.out_reverse(buf[:len]);
}
$if (env::I128_SUPPORT):
define NtoaType = uint128;
$else:
define NtoaType = ulong;
$endif;
private fn void! Formatter.ntoa_variant(Formatter* this, variant arg, uint base)
{
bool is_neg;
NtoaType val = int_from_variant(arg, &is_neg);
return this.ntoa(val, is_neg, base) @inline;
}
private fn void! Formatter.out_char(Formatter* this, variant arg)
{
uint l = 1;
// pre padding
this.right_adjust(l)?;
// char output
Char32 c = types::variant_to_int(arg, uint) ?? 0xFFFD;
switch (true)
{
case c < 0x7f:
this.out((char)c)?;
case c < 0x7ff:
this.out((char)(0xC0 | c >> 6))?;
this.out((char)(0x80 | (c & 0x3F)))?;
case c < 0xffff:
this.out((char)(0xE0 | c >> 12))?;
this.out((char)(0x80 | (c >> 6 & 0x3F)))?;
this.out((char)(0x80 | (c & 0x3F)))?;
default:
this.out((char)(0xF0 | c >> 18))?;
this.out((char)(0x80 | (c >> 12 & 0x3F)))?;
this.out((char)(0x80 | (c >> 6 & 0x3F)))?;
this.out((char)(0x80 | (c & 0x3F)))?;
}
return this.left_adjust(l);
}
private fn void! Formatter.out_reverse(Formatter* this, char[] buf)
{
usize buffer_start_idx = this.idx;
usize len = buf.len;
// pad spaces up to given width
if (!this.flags.left && !this.flags.zeropad)
{
for (usize i = len; i < this.width; i++)
{
this.out(' ')?;
}
}
// reverse string
while (len) this.out(buf[--len])?;
// append pad spaces up to given width
return this.left_adjust(this.idx - buffer_start_idx);
}
private fn void! printf_advance_format(usize format_len, usize *index_ptr) @inline
{
usize val = ++(*index_ptr);
if (val >= format_len) return FormattingFault.UNTERMINATED_FORMAT!;
}
private fn variant! next_variant(variant* args_ptr, usize args_len, usize* arg_index_ptr) @inline
{
if (*arg_index_ptr >= args_len) return FormattingFault.MISSING_ARG!;
return args_ptr[(*arg_index_ptr)++];
}
private fn int! printf_parse_format_field(variant* args_ptr, usize args_len, usize* args_index_ptr, char* format_ptr, usize format_len, usize* index_ptr) @inline
{
char c = format_ptr[*index_ptr];
if (c >= '0' && c <= '9') return simple_atoi(format_ptr, format_len, index_ptr);
if (c != '*') return 0;
printf_advance_format(format_len, index_ptr)?;
variant val = next_variant(args_ptr, args_len, args_index_ptr)?;
if (!val.type.kind.is_int()) return FormattingFault.INVALID_WIDTH_ARG!;
uint! intval = types::variant_to_int(val, int);
if (catch intval) return FormattingFault.INVALID_WIDTH_ARG!;
return intval;
}

File diff suppressed because it is too large Load Diff

View File

@@ -642,6 +642,7 @@ void llvm_emit_xxlizer(GenContext *c, Decl *decl)
scratch_buffer_clear(); scratch_buffer_clear();
scratch_buffer_printf(is_finalizer ? ".static_finalize.%u" : ".static_initialize.%u", vec_size(*array_ref)); scratch_buffer_printf(is_finalizer ? ".static_finalize.%u" : ".static_initialize.%u", vec_size(*array_ref));
LLVMValueRef function = LLVMAddFunction(c->module, scratch_buffer_to_string(), initializer_type); LLVMValueRef function = LLVMAddFunction(c->module, scratch_buffer_to_string(), initializer_type);
LLVMSetLinkage(function, LLVMInternalLinkage);
if (llvm_use_debug(c)) if (llvm_use_debug(c))
{ {
uint32_t row = decl->span.row; uint32_t row = decl->span.row;

View File

@@ -1761,6 +1761,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
call_expr->type = type_add_optional(sum_returns, failable); call_expr->type = type_add_optional(sum_returns, failable);
} }
assert(call_expr->type);
if (call_expr->call_expr.result_unused) if (call_expr->call_expr.result_unused)
{ {
Type *type = call_expr->type; Type *type = call_expr->type;
@@ -3275,6 +3276,7 @@ CHECK_DEEPER:
return false; return false;
} }
assert(member->type);
if (member->decl_kind == DECL_VAR) if (member->decl_kind == DECL_VAR)
{ {
if (member->var.kind == VARDECL_BITMEMBER) if (member->var.kind == VARDECL_BITMEMBER)

View File

@@ -404,10 +404,6 @@ void sema_analysis_pass_decls(Module *module)
{ {
sema_analyse_decl(&context, unit->generic_defines[i]); sema_analyse_decl(&context, unit->generic_defines[i]);
} }
VECEACH(unit->xxlizers, i)
{
sema_analyse_decl(&context, unit->xxlizers[i]);
}
sema_context_destroy(&context); sema_context_destroy(&context);
} }
DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found); DEBUG_LOG("Pass finished with %d error(s).", global_context.errors_found);
@@ -417,11 +413,16 @@ void sema_analysis_pass_functions(Module *module)
{ {
DEBUG_LOG("Pass: Function analysis %s", module->name->module); DEBUG_LOG("Pass: Function analysis %s", module->name->module);
VECEACH(module->units, index) VECEACH(module->units, index)
{ {
CompilationUnit *unit = module->units[index]; CompilationUnit *unit = module->units[index];
SemaContext context; SemaContext context;
sema_context_init(&context, unit); sema_context_init(&context, unit);
VECEACH(unit->xxlizers, i)
{
sema_analyse_decl(&context, unit->xxlizers[i]);
}
VECEACH(unit->methods, i) VECEACH(unit->methods, i)
{ {
analyse_func_body(&context, unit->methods[i]); analyse_func_body(&context, unit->methods[i]);

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.65" #define COMPILER_VERSION "0.3.66"

View File

@@ -34,7 +34,7 @@ static finalize
@llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 300, void ()* @.static_initialize.0, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @.static_initialize.1, i8* null }, { i32, void ()*, i8* } { i32 200, void ()* @.static_initialize.2, i8* null }] @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 300, void ()* @.static_initialize.0, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @.static_initialize.1, i8* null }, { i32, void ()*, i8* } { i32 200, void ()* @.static_initialize.2, i8* null }]
@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.static_finalize.0, i8* null }] @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.static_finalize.0, i8* null }]
define void @.static_initialize.0() { define internal void @.static_initialize.0() {
entry: entry:
call void @puts(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i32 0, i32 0)) call void @puts(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i32 0, i32 0))
ret void ret void
@@ -43,19 +43,19 @@ entry:
; Function Attrs: nounwind ; Function Attrs: nounwind
declare void @puts(i8*) #0 declare void @puts(i8*) #0
define void @.static_initialize.1() { define internal void @.static_initialize.1() {
entry: entry:
call void @puts(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i32 0, i32 0)) call void @puts(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i32 0, i32 0))
ret void ret void
} }
define void @.static_initialize.2() { define internal void @.static_initialize.2() {
entry: entry:
call void @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i32 0, i32 0)) call void @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i32 0, i32 0))
ret void ret void
} }
define void @.static_finalize.0() { define internal void @.static_finalize.0() {
entry: entry:
call void @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i32 0, i32 0)) call void @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i32 0, i32 0))
ret void ret void

View File

@@ -18,7 +18,7 @@ fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator(
static initialize static initialize
{ {
io::printf_register_to_string(Foo); io::formatter_register_type(Foo);
} }
fn void main() fn void main()
@@ -58,9 +58,19 @@ fn void main()
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.static_initialize.0, i8* null }] @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.static_initialize.0, i8* null }]
define void @.static_initialize.0() { define internal void @.static_initialize.0() {
entry: entry:
call void @std_io_printf_register(i64 ptrtoint (%.introspect* @"ct$test_Foo" to i64), { i8*, i64 } (i8*, %Allocator*)* bitcast ({ i8*, i64 } (%Foo*, %Allocator*)* @test_Foo_to_string to { i8*, i64 } (i8*, %Allocator*)*)) %0 = load i64, i64* getelementptr inbounds (%HashMap, %HashMap* @std_io_tostring_functions, i32 0, i32 0, i32 1), align 8
%not = icmp eq i64 %0, 0
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %entry
%1 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
call void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(%HashMap* @std_io_tostring_functions, i32 512, float 7.500000e-01, %Allocator* %1)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%2 = call i8 @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(%HashMap* @std_io_tostring_functions, i64 ptrtoint (%.introspect* @"ct$test_Foo" to i64), { i8*, i64 } (i8*, %Allocator*)* bitcast ({ i8*, i64 } (%Foo*, %Allocator*)* @test_Foo_to_string to { i8*, i64 } (i8*, %Allocator*)*))
ret void ret void
} }
@@ -125,7 +135,7 @@ voiderr: ; preds = %after_check, %entry
; Function Attrs: nounwind ; Function Attrs: nounwind
define void @test_main() #0 { define void @test_main() #0 {
entry: entry:
%map = alloca %HashMap, align 8 %map = alloca %HashMap.0, align 8
%retparam = alloca i64, align 8 %retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8 %taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8 %vararg = alloca %"variant[]", align 8
@@ -161,7 +171,7 @@ entry:
%vararg75 = alloca %"variant[]", align 8 %vararg75 = alloca %"variant[]", align 8
%varargslots76 = alloca [1 x %variant], align 16 %varargslots76 = alloca [1 x %variant], align 16
%result = alloca %"Foo[]", align 8 %result = alloca %"Foo[]", align 8
%map2 = alloca %HashMap.0, align 8 %map2 = alloca %HashMap.3, align 8
%retparam82 = alloca i64, align 8 %retparam82 = alloca i64, align 8
%taddr83 = alloca %"char[]", align 8 %taddr83 = alloca %"char[]", align 8
%vararg86 = alloca %"variant[]", align 8 %vararg86 = alloca %"variant[]", align 8
@@ -186,7 +196,7 @@ entry:
%error_var = alloca i64, align 8 %error_var = alloca i64, align 8
%retparam130 = alloca %TempAllocator*, align 8 %retparam130 = alloca %TempAllocator*, align 8
%mark = alloca i64, align 8 %mark = alloca i64, align 8
%map3 = alloca %HashMap.0, align 8 %map3 = alloca %HashMap.3, align 8
%error_var135 = alloca i64, align 8 %error_var135 = alloca i64, align 8
%retparam136 = alloca %TempAllocator*, align 8 %retparam136 = alloca %TempAllocator*, align 8
%retparam143 = alloca i64, align 8 %retparam143 = alloca i64, align 8
@@ -194,17 +204,17 @@ entry:
%vararg147 = alloca %"variant[]", align 8 %vararg147 = alloca %"variant[]", align 8
%varargslots148 = alloca [1 x %variant], align 16 %varargslots148 = alloca [1 x %variant], align 16
%result149 = alloca %"int[]", align 8 %result149 = alloca %"int[]", align 8
%0 = bitcast %HashMap* %map to i8* %0 = bitcast %HashMap.0* %map to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 40, i1 false) call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 40, i1 false)
%1 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8 %1 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.test_Foo_HashMap_init"(%HashMap* %map, i32 16, float 7.500000e-01, %Allocator* %1) call void @"std_map$$int.test_Foo_HashMap_init"(%HashMap.0* %map, i32 16, float 7.500000e-01, %Allocator* %1)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0), i64 12 }, %"char[]"* %taddr, align 8 store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0), i64 12 }, %"char[]"* %taddr, align 8
%2 = bitcast %"char[]"* %taddr to { i8*, i64 }* %2 = bitcast %"char[]"* %taddr to { i8*, i64 }*
%3 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 0 %3 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 0
%lo = load i8*, i8** %3, align 8 %lo = load i8*, i8** %3, align 8
%4 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 1 %4 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 1
%hi = load i64, i64* %4, align 8 %hi = load i64, i64* %4, align 8
%5 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2 %5 = getelementptr inbounds %HashMap.0, %HashMap.0* %map, i32 0, i32 2
%6 = bitcast i32* %5 to i8* %6 = bitcast i32* %5 to i8*
%7 = insertvalue %variant undef, i8* %6, 0 %7 = insertvalue %variant undef, i8* %6, 0
%8 = insertvalue %variant %7, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1 %8 = insertvalue %variant %7, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
@@ -237,14 +247,14 @@ voiderr: ; preds = %after_check, %entry
%lo3 = load i64, i64* %20, align 8 %lo3 = load i64, i64* %20, align 8
%21 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %19, i32 0, i32 1 %21 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %19, i32 0, i32 1
%hi4 = load i8*, i8** %21, align 8 %hi4 = load i8*, i8** %21, align 8
%22 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 1, i64 %lo3, i8* %hi4) %22 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0* %map, i32 1, i64 %lo3, i8* %hi4)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i64 12 }, %"char[]"* %taddr6, align 8 store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i64 12 }, %"char[]"* %taddr6, align 8
%23 = bitcast %"char[]"* %taddr6 to { i8*, i64 }* %23 = bitcast %"char[]"* %taddr6 to { i8*, i64 }*
%24 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 0 %24 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 0
%lo7 = load i8*, i8** %24, align 8 %lo7 = load i8*, i8** %24, align 8
%25 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 1 %25 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 1
%hi8 = load i64, i64* %25, align 8 %hi8 = load i64, i64* %25, align 8
%26 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2 %26 = getelementptr inbounds %HashMap.0, %HashMap.0* %map, i32 0, i32 2
%27 = bitcast i32* %26 to i8* %27 = bitcast i32* %26 to i8*
%28 = insertvalue %variant undef, i8* %27, 0 %28 = insertvalue %variant undef, i8* %27, 0
%29 = insertvalue %variant %28, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1 %29 = insertvalue %variant %28, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
@@ -277,14 +287,14 @@ voiderr15: ; preds = %after_check14, %voi
%lo17 = load i64, i64* %41, align 8 %lo17 = load i64, i64* %41, align 8
%42 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %40, i32 0, i32 1 %42 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %40, i32 0, i32 1
%hi18 = load i8*, i8** %42, align 8 %hi18 = load i8*, i8** %42, align 8
%43 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 1, i64 %lo17, i8* %hi18) %43 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0* %map, i32 1, i64 %lo17, i8* %hi18)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i32 0, i32 0), i64 12 }, %"char[]"* %taddr20, align 8 store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i32 0, i32 0), i64 12 }, %"char[]"* %taddr20, align 8
%44 = bitcast %"char[]"* %taddr20 to { i8*, i64 }* %44 = bitcast %"char[]"* %taddr20 to { i8*, i64 }*
%45 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 0 %45 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 0
%lo21 = load i8*, i8** %45, align 8 %lo21 = load i8*, i8** %45, align 8
%46 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 1 %46 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 1
%hi22 = load i64, i64* %46, align 8 %hi22 = load i64, i64* %46, align 8
%47 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2 %47 = getelementptr inbounds %HashMap.0, %HashMap.0* %map, i32 0, i32 2
%48 = bitcast i32* %47 to i8* %48 = bitcast i32* %47 to i8*
%49 = insertvalue %variant undef, i8* %48, 0 %49 = insertvalue %variant undef, i8* %48, 0
%50 = insertvalue %variant %49, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1 %50 = insertvalue %variant %49, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
@@ -314,7 +324,7 @@ voiderr29: ; preds = %after_check28, %voi
%lo32 = load i8*, i8** %60, align 8 %lo32 = load i8*, i8** %60, align 8
%61 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %59, i32 0, i32 1 %61 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %59, i32 0, i32 1
%hi33 = load i64, i64* %61, align 8 %hi33 = load i64, i64* %61, align 8
%62 = call i64 @"std_map$$int.test_Foo_HashMap_get"(%Foo* %retparam36, %HashMap* %map, i32 1) %62 = call i64 @"std_map$$int.test_Foo_HashMap_get"(%Foo* %retparam36, %HashMap.0* %map, i32 1)
%not_err37 = icmp eq i64 %62, 0 %not_err37 = icmp eq i64 %62, 0
br i1 %not_err37, label %after_check38, label %voiderr43 br i1 %not_err37, label %after_check38, label %voiderr43
@@ -349,7 +359,7 @@ voiderr43: ; preds = %after_check42, %aft
%lo46 = load i8*, i8** %76, align 8 %lo46 = load i8*, i8** %76, align 8
%77 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %75, i32 0, i32 1 %77 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %75, i32 0, i32 1
%hi47 = load i64, i64* %77, align 8 %hi47 = load i64, i64* %77, align 8
%78 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap* %map, i32 1) %78 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap.0* %map, i32 1)
store i8 %78, i8* %taddr50, align 1 store i8 %78, i8* %taddr50, align 1
%79 = insertvalue %variant undef, i8* %taddr50, 0 %79 = insertvalue %variant undef, i8* %taddr50, 0
%80 = insertvalue %variant %79, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1 %80 = insertvalue %variant %79, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
@@ -379,7 +389,7 @@ voiderr55: ; preds = %after_check54, %voi
%lo58 = load i8*, i8** %90, align 8 %lo58 = load i8*, i8** %90, align 8
%91 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %89, i32 0, i32 1 %91 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %89, i32 0, i32 1
%hi59 = load i64, i64* %91, align 8 %hi59 = load i64, i64* %91, align 8
%92 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap* %map, i32 2) %92 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap.0* %map, i32 2)
store i8 %92, i8* %taddr62, align 1 store i8 %92, i8* %taddr62, align 1
%93 = insertvalue %variant undef, i8* %taddr62, 0 %93 = insertvalue %variant undef, i8* %taddr62, 0
%94 = insertvalue %variant %93, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1 %94 = insertvalue %variant %93, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
@@ -412,14 +422,14 @@ voiderr67: ; preds = %after_check66, %voi
%lo69 = load i64, i64* %106, align 8 %lo69 = load i64, i64* %106, align 8
%107 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %105, i32 0, i32 1 %107 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %105, i32 0, i32 1
%hi70 = load i8*, i8** %107, align 8 %hi70 = load i8*, i8** %107, align 8
%108 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 7, i64 %lo69, i8* %hi70) %108 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap.0* %map, i32 7, i64 %lo69, i8* %hi70)
store %"char[]" { i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.6, i32 0, i32 0), i64 10 }, %"char[]"* %taddr72, align 8 store %"char[]" { i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.6, i32 0, i32 0), i64 10 }, %"char[]"* %taddr72, align 8
%109 = bitcast %"char[]"* %taddr72 to { i8*, i64 }* %109 = bitcast %"char[]"* %taddr72 to { i8*, i64 }*
%110 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 0 %110 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 0
%lo73 = load i8*, i8** %110, align 8 %lo73 = load i8*, i8** %110, align 8
%111 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 1 %111 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 1
%hi74 = load i64, i64* %111, align 8 %hi74 = load i64, i64* %111, align 8
%112 = call { i8*, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(%HashMap* %map, %Allocator* null) %112 = call { i8*, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(%HashMap.0* %map, %Allocator* null)
%113 = bitcast %"Foo[]"* %result to { i8*, i64 }* %113 = bitcast %"Foo[]"* %result to { i8*, i64 }*
store { i8*, i64 } %112, { i8*, i64 }* %113, align 8 store { i8*, i64 } %112, { i8*, i64 }* %113, align 8
%114 = bitcast %"Foo[]"* %result to i8* %114 = bitcast %"Foo[]"* %result to i8*
@@ -445,18 +455,18 @@ after_check80: ; preds = %voiderr67
br label %voiderr81 br label %voiderr81
voiderr81: ; preds = %after_check80, %voiderr67 voiderr81: ; preds = %after_check80, %voiderr67
%125 = bitcast %HashMap.0* %map2 to i8* %125 = bitcast %HashMap.3* %map2 to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %125, i8 0, i64 40, i1 false) call void @llvm.memset.p0i8.i64(i8* align 8 %125, i8 0, i64 40, i1 false)
%126 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8 %126 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.double_HashMap_init"(%HashMap.0* %map2, i32 16, float 7.500000e-01, %Allocator* %126) call void @"std_map$$int.double_HashMap_init"(%HashMap.3* %map2, i32 16, float 7.500000e-01, %Allocator* %126)
%127 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map2, i32 4, double 1.300000e+00) %127 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map2, i32 4, double 1.300000e+00)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.7, i32 0, i32 0), i64 12 }, %"char[]"* %taddr83, align 8 store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.7, i32 0, i32 0), i64 12 }, %"char[]"* %taddr83, align 8
%128 = bitcast %"char[]"* %taddr83 to { i8*, i64 }* %128 = bitcast %"char[]"* %taddr83 to { i8*, i64 }*
%129 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 0 %129 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 0
%lo84 = load i8*, i8** %129, align 8 %lo84 = load i8*, i8** %129, align 8
%130 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 1 %130 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 1
%hi85 = load i64, i64* %130, align 8 %hi85 = load i64, i64* %130, align 8
%131 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.0* %map2, double 1.300000e+00) %131 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.3* %map2, double 1.300000e+00)
store i8 %131, i8* %taddr88, align 1 store i8 %131, i8* %taddr88, align 1
%132 = insertvalue %variant undef, i8* %taddr88, 0 %132 = insertvalue %variant undef, i8* %taddr88, 0
%133 = insertvalue %variant %132, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1 %133 = insertvalue %variant %132, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
@@ -486,7 +496,7 @@ voiderr93: ; preds = %after_check92, %voi
%lo96 = load i8*, i8** %143, align 8 %lo96 = load i8*, i8** %143, align 8
%144 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %142, i32 0, i32 1 %144 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %142, i32 0, i32 1
%hi97 = load i64, i64* %144, align 8 %hi97 = load i64, i64* %144, align 8
%145 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.0* %map2, double 1.200000e+00) %145 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.3* %map2, double 1.200000e+00)
store i8 %145, i8* %taddr100, align 1 store i8 %145, i8* %taddr100, align 1
%146 = insertvalue %variant undef, i8* %taddr100, 0 %146 = insertvalue %variant undef, i8* %taddr100, 0
%147 = insertvalue %variant %146, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1 %147 = insertvalue %variant %146, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
@@ -510,14 +520,14 @@ after_check104: ; preds = %voiderr93
br label %voiderr105 br label %voiderr105
voiderr105: ; preds = %after_check104, %voiderr93 voiderr105: ; preds = %after_check104, %voiderr93
%156 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map2, i32 100, double 3.400000e+00) %156 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map2, i32 100, double 3.400000e+00)
store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.9, i32 0, i32 0), i64 2 }, %"char[]"* %taddr107, align 8 store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.9, i32 0, i32 0), i64 2 }, %"char[]"* %taddr107, align 8
%157 = bitcast %"char[]"* %taddr107 to { i8*, i64 }* %157 = bitcast %"char[]"* %taddr107 to { i8*, i64 }*
%158 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 0 %158 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 0
%lo108 = load i8*, i8** %158, align 8 %lo108 = load i8*, i8** %158, align 8
%159 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 1 %159 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 1
%hi109 = load i64, i64* %159, align 8 %hi109 = load i64, i64* %159, align 8
%160 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_list"(%HashMap.0* %map2, %Allocator* null) %160 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_list"(%HashMap.3* %map2, %Allocator* null)
%161 = bitcast %"int[]"* %result112 to { i8*, i64 }* %161 = bitcast %"int[]"* %result112 to { i8*, i64 }*
store { i8*, i64 } %160, { i8*, i64 }* %161, align 8 store { i8*, i64 } %160, { i8*, i64 }* %161, align 8
%162 = bitcast %"int[]"* %result112 to i8* %162 = bitcast %"int[]"* %result112 to i8*
@@ -549,7 +559,7 @@ voiderr117: ; preds = %after_check116, %vo
%lo120 = load i8*, i8** %174, align 8 %lo120 = load i8*, i8** %174, align 8
%175 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %173, i32 0, i32 1 %175 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %173, i32 0, i32 1
%hi121 = load i64, i64* %175, align 8 %hi121 = load i64, i64* %175, align 8
%176 = call { i8*, i64 } @"std_map$$int.double_HashMap_value_list"(%HashMap.0* %map2, %Allocator* null) %176 = call { i8*, i64 } @"std_map$$int.double_HashMap_value_list"(%HashMap.3* %map2, %Allocator* null)
%177 = bitcast %"double[]"* %result124 to { i8*, i64 }* %177 = bitcast %"double[]"* %result124 to { i8*, i64 }*
store { i8*, i64 } %176, { i8*, i64 }* %177, align 8 store { i8*, i64 } %176, { i8*, i64 }* %177, align 8
%178 = bitcast %"double[]"* %result124 to i8* %178 = bitcast %"double[]"* %result124 to i8*
@@ -607,7 +617,7 @@ if.exit: ; preds = %noerr_block, %voide
%194 = getelementptr inbounds %TempAllocator, %TempAllocator* %193, i32 0, i32 3 %194 = getelementptr inbounds %TempAllocator, %TempAllocator* %193, i32 0, i32 3
%195 = load i64, i64* %194, align 8 %195 = load i64, i64* %194, align 8
store i64 %195, i64* %mark, align 8 store i64 %195, i64* %mark, align 8
%196 = bitcast %HashMap.0* %map3 to i8* %196 = bitcast %HashMap.3* %map3 to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %196, i8 0, i64 40, i1 false) call void @llvm.memset.p0i8.i64(i8* align 8 %196, i8 0, i64 40, i1 false)
%197 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8 %197 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
%not133 = icmp eq %TempAllocator* %197, null %not133 = icmp eq %TempAllocator* %197, null
@@ -637,16 +647,16 @@ noerr_block141: ; preds = %after_check139
if.exit142: ; preds = %noerr_block141, %if.exit if.exit142: ; preds = %noerr_block141, %if.exit
%200 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8 %200 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
%ptrptr = bitcast %TempAllocator* %200 to %Allocator* %ptrptr = bitcast %TempAllocator* %200 to %Allocator*
call void @"std_map$$int.double_HashMap_init"(%HashMap.0* %map3, i32 16, float 7.500000e-01, %Allocator* %ptrptr) call void @"std_map$$int.double_HashMap_init"(%HashMap.3* %map3, i32 16, float 7.500000e-01, %Allocator* %ptrptr)
%201 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map3, i32 5, double 3.200000e+00) %201 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map3, i32 5, double 3.200000e+00)
%202 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map3, i32 7, double 5.200000e+00) %202 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.3* %map3, i32 7, double 5.200000e+00)
store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.16, i32 0, i32 0), i64 2 }, %"char[]"* %taddr144, align 8 store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.16, i32 0, i32 0), i64 2 }, %"char[]"* %taddr144, align 8
%203 = bitcast %"char[]"* %taddr144 to { i8*, i64 }* %203 = bitcast %"char[]"* %taddr144 to { i8*, i64 }*
%204 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 0 %204 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 0
%lo145 = load i8*, i8** %204, align 8 %lo145 = load i8*, i8** %204, align 8
%205 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 1 %205 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 1
%hi146 = load i64, i64* %205, align 8 %hi146 = load i64, i64* %205, align 8
%206 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_tlist"(%HashMap.0* %map3) %206 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_tlist"(%HashMap.3* %map3)
%207 = bitcast %"int[]"* %result149 to { i8*, i64 }* %207 = bitcast %"int[]"* %result149 to { i8*, i64 }*
store { i8*, i64 } %206, { i8*, i64 }* %207, align 8 store { i8*, i64 } %206, { i8*, i64 }* %207, align 8
%208 = bitcast %"int[]"* %result149 to i8* %208 = bitcast %"int[]"* %result149 to i8*

View File

@@ -34,7 +34,7 @@ static finalize
@llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 300, ptr @.static_initialize.0, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @.static_initialize.1, ptr null }, { i32, ptr, ptr } { i32 200, ptr @.static_initialize.2, ptr null }] @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 300, ptr @.static_initialize.0, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @.static_initialize.1, ptr null }, { i32, ptr, ptr } { i32 200, ptr @.static_initialize.2, ptr null }]
@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @.static_finalize.0, ptr null }] @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @.static_finalize.0, ptr null }]
define void @.static_initialize.0() { define internal void @.static_initialize.0() {
entry: entry:
call void @puts(ptr @.str) call void @puts(ptr @.str)
ret void ret void
@@ -43,19 +43,19 @@ entry:
; Function Attrs: nounwind ; Function Attrs: nounwind
declare void @puts(ptr) #0 declare void @puts(ptr) #0
define void @.static_initialize.1() { define internal void @.static_initialize.1() {
entry: entry:
call void @puts(ptr @.str.1) call void @puts(ptr @.str.1)
ret void ret void
} }
define void @.static_initialize.2() { define internal void @.static_initialize.2() {
entry: entry:
call void @puts(ptr @.str.2) call void @puts(ptr @.str.2)
ret void ret void
} }
define void @.static_finalize.0() { define internal void @.static_finalize.0() {
entry: entry:
call void @puts(ptr @.str.3) call void @puts(ptr @.str.3)
ret void ret void

View File

@@ -18,7 +18,7 @@ fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator(
static initialize static initialize
{ {
io::printf_register_to_string(Foo); io::formatter_register_type(Foo);
} }
fn void main() fn void main()
@@ -54,13 +54,21 @@ fn void main()
} }
/* #expect: test.ll /* #expect: test.ll
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @.static_initialize.0, ptr null }] @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @.static_initialize.0, ptr null }]
define void @.static_initialize.0() { define internal void @.static_initialize.0() {
entry: entry:
call void @std_io_printf_register(i64 ptrtoint (ptr @"ct$test_Foo" to i64), ptr @test_Foo_to_string) %0 = load i64, ptr getelementptr inbounds (%"Entry*[]", ptr @std_io_tostring_functions, i32 0, i32 1), align 8
%not = icmp eq i64 %0, 0
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %entry
%1 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_init"(ptr @std_io_tostring_functions, i32 512, float 7.500000e-01, ptr %1)
br label %if.exit
if.exit: ; preds = %if.then, %entry
%2 = call i8 @"std_map$$typeid.p$std_io$ToStringFunction_HashMap_set"(ptr @std_io_tostring_functions, i64 ptrtoint (ptr @"ct$test_Foo" to i64), ptr @test_Foo_to_string)
ret void ret void
} }
@@ -117,7 +125,7 @@ voiderr: ; preds = %after_check, %entry
; Function Attrs: nounwind ; Function Attrs: nounwind
define void @test_main() #0 { define void @test_main() #0 {
entry: entry:
%map = alloca %HashMap, align 8 %map = alloca %HashMap.0, align 8
%retparam = alloca i64, align 8 %retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8 %taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8 %vararg = alloca %"variant[]", align 8
@@ -153,7 +161,7 @@ entry:
%vararg75 = alloca %"variant[]", align 8 %vararg75 = alloca %"variant[]", align 8
%varargslots76 = alloca [1 x %variant], align 16 %varargslots76 = alloca [1 x %variant], align 16
%result = alloca %"Foo[]", align 8 %result = alloca %"Foo[]", align 8
%map2 = alloca %HashMap.0, align 8 %map2 = alloca %HashMap.3, align 8
%retparam82 = alloca i64, align 8 %retparam82 = alloca i64, align 8
%taddr83 = alloca %"char[]", align 8 %taddr83 = alloca %"char[]", align 8
%vararg86 = alloca %"variant[]", align 8 %vararg86 = alloca %"variant[]", align 8
@@ -178,7 +186,7 @@ entry:
%error_var = alloca i64, align 8 %error_var = alloca i64, align 8
%retparam130 = alloca ptr, align 8 %retparam130 = alloca ptr, align 8
%mark = alloca i64, align 8 %mark = alloca i64, align 8
%map3 = alloca %HashMap.0, align 8 %map3 = alloca %HashMap.3, align 8
%error_var135 = alloca i64, align 8 %error_var135 = alloca i64, align 8
%retparam136 = alloca ptr, align 8 %retparam136 = alloca ptr, align 8
%retparam143 = alloca i64, align 8 %retparam143 = alloca i64, align 8
@@ -194,7 +202,7 @@ entry:
%lo = load ptr, ptr %1, align 8 %lo = load ptr, ptr %1, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1 %2 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1
%hi = load i64, ptr %2, align 8 %hi = load i64, ptr %2, align 8
%3 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2 %3 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
%4 = insertvalue %variant undef, ptr %3, 0 %4 = insertvalue %variant undef, ptr %3, 0
%5 = insertvalue %variant %4, i64 ptrtoint (ptr @"ct$uint" to i64), 1 %5 = insertvalue %variant %4, i64 ptrtoint (ptr @"ct$uint" to i64), 1
%6 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0 %6 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0
@@ -229,7 +237,7 @@ voiderr: ; preds = %after_check, %entry
%lo7 = load ptr, ptr %17, align 8 %lo7 = load ptr, ptr %17, align 8
%18 = getelementptr inbounds { ptr, i64 }, ptr %taddr6, i32 0, i32 1 %18 = getelementptr inbounds { ptr, i64 }, ptr %taddr6, i32 0, i32 1
%hi8 = load i64, ptr %18, align 8 %hi8 = load i64, ptr %18, align 8
%19 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2 %19 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
%20 = insertvalue %variant undef, ptr %19, 0 %20 = insertvalue %variant undef, ptr %19, 0
%21 = insertvalue %variant %20, i64 ptrtoint (ptr @"ct$uint" to i64), 1 %21 = insertvalue %variant %20, i64 ptrtoint (ptr @"ct$uint" to i64), 1
%22 = getelementptr inbounds [1 x %variant], ptr %varargslots10, i64 0, i64 0 %22 = getelementptr inbounds [1 x %variant], ptr %varargslots10, i64 0, i64 0
@@ -264,7 +272,7 @@ voiderr15: ; preds = %after_check14, %voi
%lo21 = load ptr, ptr %33, align 8 %lo21 = load ptr, ptr %33, align 8
%34 = getelementptr inbounds { ptr, i64 }, ptr %taddr20, i32 0, i32 1 %34 = getelementptr inbounds { ptr, i64 }, ptr %taddr20, i32 0, i32 1
%hi22 = load i64, ptr %34, align 8 %hi22 = load i64, ptr %34, align 8
%35 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2 %35 = getelementptr inbounds %HashMap.0, ptr %map, i32 0, i32 2
%36 = insertvalue %variant undef, ptr %35, 0 %36 = insertvalue %variant undef, ptr %35, 0
%37 = insertvalue %variant %36, i64 ptrtoint (ptr @"ct$uint" to i64), 1 %37 = insertvalue %variant %36, i64 ptrtoint (ptr @"ct$uint" to i64), 1
%38 = getelementptr inbounds [1 x %variant], ptr %varargslots24, i64 0, i64 0 %38 = getelementptr inbounds [1 x %variant], ptr %varargslots24, i64 0, i64 0