mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Struct and typedef subtypes inherit dynamic functions.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
- Add `@safeinfer` to allow `var` to be used locally.
|
||||
- Types converts to typeid implicitly.
|
||||
- Allow `$defined` take declarations: `$defined(int x = y)`
|
||||
- Struct and typedef subtypes inherit dynamic functions.
|
||||
|
||||
### Fixes
|
||||
- List.remove_at would incorrectly trigger ASAN.
|
||||
|
||||
@@ -5519,15 +5519,29 @@ static LLVMValueRef llvm_emit_dynamic_search(GenContext *c, LLVMValueRef type_id
|
||||
LLVMBasicBlockRef entry;
|
||||
LLVMBuilderRef builder = llvm_create_function_entry(c, func, &entry);
|
||||
|
||||
LLVMValueRef dtable_ptr_in = LLVMGetParam(func, 0);
|
||||
LLVMValueRef typeid_ptr_in = LLVMGetParam(func, 0);
|
||||
LLVMValueRef func_ref = LLVMGetParam(func, 1);
|
||||
|
||||
LLVMBasicBlockRef get_dtable = llvm_basic_block_new(c, "get_dtable");
|
||||
LLVMBasicBlockRef check = llvm_basic_block_new(c, "check");
|
||||
LLVMBasicBlockRef next_parent = llvm_basic_block_new(c, "next_parent");
|
||||
LLVMBasicBlockRef missing_function = llvm_basic_block_new(c, "missing_function");
|
||||
LLVMBasicBlockRef compare = llvm_basic_block_new(c, "compare");
|
||||
LLVMBasicBlockRef match = llvm_basic_block_new(c, "match");
|
||||
LLVMBasicBlockRef no_match = llvm_basic_block_new(c, "no_match");
|
||||
|
||||
LLVMBuildBr(builder, get_dtable);
|
||||
|
||||
LLVMAppendExistingBasicBlock(func, get_dtable);
|
||||
LLVMPositionBuilderAtEnd(builder, get_dtable);
|
||||
|
||||
LLVMValueRef typeid = LLVMBuildPhi(builder, c->ptr_type, "typeid");
|
||||
LLVMAddIncoming(typeid, &typeid_ptr_in, &entry, 1);
|
||||
|
||||
LLVMValueRef dtable_ref = LLVMBuildStructGEP2(builder, c->introspect_type, typeid, INTROSPECT_INDEX_DTABLE, "dtable_ref");
|
||||
LLVMValueRef dtable_ptr_start = LLVMBuildLoad2(builder, c->ptr_type, dtable_ref, "dtable");
|
||||
LLVMSetAlignment(dtable_ptr_start, type_abi_alignment(type_voidptr));
|
||||
|
||||
LLVMBuildBr(builder, check);
|
||||
|
||||
// check: dtable_ptr = phi
|
||||
@@ -5538,12 +5552,27 @@ static LLVMValueRef llvm_emit_dynamic_search(GenContext *c, LLVMValueRef type_id
|
||||
// dtable_ptr == null
|
||||
LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntEQ, dtable_ptr, LLVMConstNull(c->ptr_type), "");
|
||||
|
||||
// if (cmp) goto missing_function else compare
|
||||
LLVMBuildCondBr(builder, cmp, missing_function, compare);
|
||||
// if (cmp) goto next_parent else compare
|
||||
LLVMBuildCondBr(builder, cmp, next_parent, compare);
|
||||
|
||||
LLVMAppendExistingBasicBlock(func, next_parent);
|
||||
LLVMPositionBuilderAtEnd(builder, next_parent);
|
||||
|
||||
LLVMValueRef parent_ref = LLVMBuildStructGEP2(builder, c->introspect_type, typeid, INTROSPECT_INDEX_PARENTOF, "parent_ref");
|
||||
LLVMValueRef parent_ptr = LLVMBuildLoad2(builder, c->typeid_type, parent_ref, "parent");
|
||||
LLVMSetAlignment(parent_ptr, type_abi_alignment(type_voidptr));
|
||||
parent_ptr = LLVMBuildIntToPtr(builder, parent_ptr, c->ptr_type, "parent_ptr");
|
||||
|
||||
LLVMValueRef cmp2 = LLVMBuildICmp(builder, LLVMIntEQ, parent_ptr, LLVMConstNull(c->ptr_type), "");
|
||||
|
||||
// if (cmp) goto missing_function else get_dtable
|
||||
LLVMAddIncoming(typeid, &parent_ptr, &next_parent, 1);
|
||||
LLVMBuildCondBr(builder, cmp2, missing_function, get_dtable);
|
||||
|
||||
// missing_function: return null
|
||||
LLVMAppendExistingBasicBlock(func, missing_function);
|
||||
LLVMPositionBuilderAtEnd(builder, missing_function);
|
||||
|
||||
LLVMBuildRet(builder, LLVMConstNull(c->ptr_type));
|
||||
|
||||
// function_type = dtable_ptr.function_type
|
||||
@@ -5579,7 +5608,7 @@ static LLVMValueRef llvm_emit_dynamic_search(GenContext *c, LLVMValueRef type_id
|
||||
// goto check
|
||||
LLVMBuildBr(builder, check);
|
||||
|
||||
llvm_set_phi(dtable_ptr, dtable_ptr_in, entry, next, no_match);
|
||||
llvm_set_phi(dtable_ptr, dtable_ptr_start, get_dtable, next, no_match);
|
||||
LLVMDisposeBuilder(builder);
|
||||
}
|
||||
// Insert cache.
|
||||
@@ -5604,15 +5633,7 @@ static LLVMValueRef llvm_emit_dynamic_search(GenContext *c, LLVMValueRef type_id
|
||||
LLVMValueRef compare = LLVMBuildICmp(c->builder, LLVMIntEQ, type_id_ptr, cached_type_id, "");
|
||||
llvm_emit_cond_br_raw(c, compare, cache_hit, cache_miss);
|
||||
llvm_emit_block(c, cache_miss);
|
||||
AlignSize align;
|
||||
LLVMValueRef dtable_ref = llvm_emit_struct_gep_raw(c,
|
||||
type_id_ptr,
|
||||
c->introspect_type,
|
||||
INTROSPECT_INDEX_DTABLE,
|
||||
llvm_abi_alignment(c, c->introspect_type),
|
||||
&align);
|
||||
LLVMValueRef dtable_ptr = llvm_load(c, c->ptr_type, dtable_ref, align, "");
|
||||
LLVMValueRef params[2] = { dtable_ptr, selector };
|
||||
LLVMValueRef params[2] = { type_id_ptr, selector };
|
||||
LLVMValueRef call = LLVMBuildCall2(c->builder, type, func, params, 2, "");
|
||||
// Store in cache.
|
||||
llvm_store_to_ptr_raw(c, cache_fn_ptr, call, type_voidptr);
|
||||
|
||||
@@ -1187,14 +1187,20 @@ RETRY:;
|
||||
if (result != BOOL_FALSE) return result == BOOL_TRUE;
|
||||
if (!decl->is_substruct) return false;
|
||||
Type *inner;
|
||||
if (decl->decl_kind == DECL_DISTINCT)
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
inner = decl->distinct->type->canonical;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(decl->decl_kind == DECL_STRUCT);
|
||||
inner = decl->strukt.members[0]->type->canonical;
|
||||
case DECL_DISTINCT:
|
||||
inner = decl->distinct->type->canonical;
|
||||
break;
|
||||
case DECL_STRUCT:
|
||||
inner = decl->strukt.members[0]->type->canonical;
|
||||
break;
|
||||
case DECL_ENUM:
|
||||
case DECL_CONST_ENUM:
|
||||
// Could be made to work.
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE
|
||||
}
|
||||
if (!type_may_implement_interface(inner)) return false;
|
||||
decl = inner->decl;
|
||||
|
||||
@@ -608,9 +608,15 @@ RETRY:
|
||||
FALLTHROUGH;
|
||||
case DECL_CONST_ENUM:
|
||||
case DECL_BITSTRUCT:
|
||||
case DECL_STRUCT:
|
||||
case DECL_UNION:
|
||||
case DECL_INTERFACE:
|
||||
case DECL_UNION:
|
||||
sema_trace_decl_dynamic_methods(decl);
|
||||
return;
|
||||
case DECL_STRUCT:
|
||||
if (decl->is_substruct)
|
||||
{
|
||||
sema_trace_type_liveness(decl->strukt.members[0]->type);
|
||||
}
|
||||
sema_trace_decl_dynamic_methods(decl);
|
||||
return;
|
||||
case DECL_ENUM_CONSTANT:
|
||||
|
||||
@@ -74,31 +74,29 @@ after_check2: ; preds = %after_assign
|
||||
br i1 %6, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %after_check2
|
||||
%ptradd = getelementptr inbounds i8, ptr %5, i64 16
|
||||
%7 = load ptr, ptr %ptradd, align 8
|
||||
%8 = call ptr @.dyn_search(ptr %7, ptr @"$sel.do_something")
|
||||
store ptr %8, ptr %.inlinecache, align 8
|
||||
%7 = call ptr @.dyn_search(ptr %5, ptr @"$sel.do_something")
|
||||
store ptr %7, ptr %.inlinecache, align 8
|
||||
store ptr %5, ptr %.cachedtype, align 8
|
||||
br label %9
|
||||
br label %8
|
||||
|
||||
cache_hit: ; preds = %after_check2
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %9
|
||||
br label %8
|
||||
|
||||
9: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %8, %cache_miss ]
|
||||
8: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ]
|
||||
store ptr %fn_phi, ptr %x, align 8
|
||||
br label %phi_try_catch
|
||||
|
||||
catch_landing: ; preds = %after_assign
|
||||
br label %phi_try_catch
|
||||
|
||||
phi_try_catch: ; preds = %catch_landing, %9
|
||||
%val = phi i1 [ true, %9 ], [ false, %catch_landing ]
|
||||
phi_try_catch: ; preds = %catch_landing, %8
|
||||
%val = phi i1 [ true, %8 ], [ false, %catch_landing ]
|
||||
br i1 %val, label %if.exit, label %if.else
|
||||
|
||||
if.else: ; preds = %phi_try_catch
|
||||
%10 = call i64 @std.io.printfn(ptr %retparam3, ptr @.str.1, i64 39, ptr null, i64 0)
|
||||
%9 = call i64 @std.io.printfn(ptr %retparam3, ptr @.str.1, i64 39, ptr null, i64 0)
|
||||
br label %if.exit
|
||||
|
||||
if.exit: ; preds = %if.else, %phi_try_catch
|
||||
|
||||
@@ -379,7 +379,7 @@ entry:
|
||||
%arg = alloca ptr, align 8
|
||||
%len = alloca i64, align 8
|
||||
%ptr = alloca ptr, align 8
|
||||
%len16 = alloca i64, align 8
|
||||
%len15 = alloca i64, align 8
|
||||
store ptr null, ptr %.cachedtype, align 8
|
||||
store i32 %0, ptr %.anon, align 4
|
||||
|
||||
@@ -426,132 +426,130 @@ if.exit: ; preds = %entry
|
||||
br i1 %14, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %if.exit
|
||||
%ptradd12 = getelementptr inbounds i8, ptr %13, i64 16
|
||||
%15 = load ptr, ptr %ptradd12, align 8
|
||||
%16 = call ptr @.dyn_search(ptr %15, ptr @"$sel.acquire")
|
||||
store ptr %16, ptr %.inlinecache, align 8
|
||||
%15 = call ptr @.dyn_search(ptr %13, ptr @"$sel.acquire")
|
||||
store ptr %15, ptr %.inlinecache, align 8
|
||||
store ptr %13, ptr %.cachedtype, align 8
|
||||
br label %17
|
||||
br label %16
|
||||
|
||||
cache_hit: ; preds = %if.exit
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %17
|
||||
br label %16
|
||||
|
||||
17: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %16, %cache_miss ]
|
||||
%18 = icmp eq ptr %fn_phi, null
|
||||
br i1 %18, label %missing_function, label %match
|
||||
16: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %15, %cache_miss ]
|
||||
%17 = icmp eq ptr %fn_phi, null
|
||||
br i1 %17, label %missing_function, label %match
|
||||
|
||||
missing_function: ; preds = %17
|
||||
%19 = load ptr, ptr @std.core.builtin.panic, align 8, !dbg !167
|
||||
call void %19(ptr @.panic_msg, i64 44, ptr @.file,
|
||||
missing_function: ; preds = %16
|
||||
%18 = load ptr, ptr @std.core.builtin.panic, align 8, !dbg !167
|
||||
call void %18(ptr @.panic_msg, i64 44, ptr @.file,
|
||||
unreachable, !dbg !167
|
||||
|
||||
match: ; preds = %17
|
||||
%20 = load ptr, ptr %allocator10, align 8
|
||||
%21 = load i64, ptr %size, align 8
|
||||
%22 = call i64 %fn_phi(ptr %retparam, ptr %20, i64 %21, i32 0, i64 0), !dbg !167
|
||||
%not_err = icmp eq i64 %22, 0, !dbg !167
|
||||
%23 = call i1 @llvm.expect.i1(i1 %not_err, i1 true), !dbg !167
|
||||
br i1 %23, label %after_check, label %assign_optional, !dbg !167
|
||||
match: ; preds = %16
|
||||
%19 = load ptr, ptr %allocator10, align 8
|
||||
%20 = load i64, ptr %size, align 8
|
||||
%21 = call i64 %fn_phi(ptr %retparam, ptr %19, i64 %20, i32 0, i64 0), !dbg !167
|
||||
%not_err = icmp eq i64 %21, 0, !dbg !167
|
||||
%22 = call i1 @llvm.expect.i1(i1 %not_err, i1 true), !dbg !167
|
||||
br i1 %22, label %after_check, label %assign_optional, !dbg !167
|
||||
|
||||
assign_optional: ; preds = %match
|
||||
store i64 %22, ptr %error_var, align 8, !dbg !167
|
||||
store i64 %21, ptr %error_var, align 8, !dbg !167
|
||||
br label %panic_block, !dbg !167
|
||||
|
||||
after_check: ; preds = %match
|
||||
%24 = load ptr, ptr %retparam, align 8, !dbg !167
|
||||
store ptr %24, ptr %blockret11, align 8, !dbg !167
|
||||
%23 = load ptr, ptr %retparam, align 8, !dbg !167
|
||||
store ptr %23, ptr %blockret11, align 8, !dbg !167
|
||||
br label %expr_block.exit, !dbg !167
|
||||
|
||||
expr_block.exit: ; preds = %after_check, %if.then
|
||||
%25 = load ptr, ptr %blockret11, align 8, !dbg !167
|
||||
%26 = load i64, ptr %elements8, align 8, !dbg !168
|
||||
%add = add i64 0, %26, !dbg !168
|
||||
%size13 = sub i64 %add, 0, !dbg !168
|
||||
%27 = insertvalue %"char[][]" undef, ptr %25, 0, !dbg !168
|
||||
%28 = insertvalue %"char[][]" %27, i64 %size13, 1, !dbg !168
|
||||
%24 = load ptr, ptr %blockret11, align 8, !dbg !167
|
||||
%25 = load i64, ptr %elements8, align 8, !dbg !168
|
||||
%add = add i64 0, %25, !dbg !168
|
||||
%size12 = sub i64 %add, 0, !dbg !168
|
||||
%26 = insertvalue %"char[][]" undef, ptr %24, 0, !dbg !168
|
||||
%27 = insertvalue %"char[][]" %26, i64 %size12, 1, !dbg !168
|
||||
br label %noerr_block, !dbg !168
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
%29 = insertvalue %any undef, ptr %error_var, 0, !dbg !168
|
||||
%30 = insertvalue %any %29, i64 ptrtoint (ptr @"$ct.fault" to i64), 1, !dbg !168
|
||||
store %any %30, ptr %varargslots, align 16
|
||||
%31 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %31, i64 1, 1
|
||||
%28 = insertvalue %any undef, ptr %error_var, 0, !dbg !168
|
||||
%29 = insertvalue %any %28, i64 ptrtoint (ptr @"$ct.fault" to i64), 1, !dbg !168
|
||||
store %any %29, ptr %varargslots, align 16
|
||||
%30 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %30, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %indirectarg, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36, ptr @.file, i64 16, ptr @.func, i64 6, i32 287, ptr byval(%"any[]") align 8 %indirectarg) #5, !dbg !157
|
||||
unreachable, !dbg !157
|
||||
|
||||
noerr_block: ; preds = %expr_block.exit
|
||||
store %"char[][]" %28, ptr %list5, align 8, !dbg !157
|
||||
store %"char[][]" %27, ptr %list5, align 8, !dbg !157
|
||||
store i32 0, ptr %i, align 4, !dbg !172
|
||||
br label %loop.cond, !dbg !172
|
||||
|
||||
loop.cond: ; preds = %loop.exit, %noerr_block
|
||||
%32 = load i32, ptr %i, align 4, !dbg !173
|
||||
%33 = load i32, ptr %argc2, align 4, !dbg !174
|
||||
%lt = icmp slt i32 %32, %33, !dbg !173
|
||||
br i1 %lt, label %loop.body, label %loop.exit26, !dbg !173
|
||||
%31 = load i32, ptr %i, align 4, !dbg !173
|
||||
%32 = load i32, ptr %argc2, align 4, !dbg !174
|
||||
%lt = icmp slt i32 %31, %32, !dbg !173
|
||||
br i1 %lt, label %loop.body, label %loop.exit25, !dbg !173
|
||||
|
||||
loop.body: ; preds = %loop.cond
|
||||
%34 = load ptr, ptr %argv3, align 8, !dbg !178
|
||||
%35 = load i32, ptr %i, align 4, !dbg !179
|
||||
%sext14 = sext i32 %35 to i64, !dbg !179
|
||||
%ptroffset = getelementptr inbounds [8 x i8], ptr %34, i64 %sext14, !dbg !179
|
||||
%36 = load ptr, ptr %ptroffset, align 8, !dbg !179
|
||||
store ptr %36, ptr %arg, align 8, !dbg !179
|
||||
%33 = load ptr, ptr %argv3, align 8, !dbg !178
|
||||
%34 = load i32, ptr %i, align 4, !dbg !179
|
||||
%sext13 = sext i32 %34 to i64, !dbg !179
|
||||
%ptroffset = getelementptr inbounds [8 x i8], ptr %33, i64 %sext13, !dbg !179
|
||||
%35 = load ptr, ptr %ptroffset, align 8, !dbg !179
|
||||
store ptr %35, ptr %arg, align 8, !dbg !179
|
||||
store i64 0, ptr %len, align 8, !dbg !182
|
||||
%37 = load ptr, ptr %arg, align 8, !dbg !183
|
||||
%38 = load ptr, ptr %arg, align 8
|
||||
store ptr %38, ptr %ptr, align 8
|
||||
store i64 0, ptr %len16, align 8, !dbg !188
|
||||
br label %loop.cond17, !dbg !189
|
||||
%36 = load ptr, ptr %arg, align 8, !dbg !183
|
||||
%37 = load ptr, ptr %arg, align 8
|
||||
store ptr %37, ptr %ptr, align 8
|
||||
store i64 0, ptr %len15, align 8, !dbg !188
|
||||
br label %loop.cond16, !dbg !189
|
||||
|
||||
loop.cond17: ; preds = %loop.body19, %loop.body
|
||||
%39 = load ptr, ptr %ptr, align 8, !dbg !190
|
||||
%40 = load i64, ptr %len16, align 8, !dbg !192
|
||||
%ptradd18 = getelementptr inbounds i8, ptr %39, i64 %40, !dbg !192
|
||||
%41 = load i8, ptr %ptradd18, align 1, !dbg !192
|
||||
%i2b = icmp ne i8 %41, 0, !dbg !192
|
||||
br i1 %i2b, label %loop.body19, label %loop.exit, !dbg !192
|
||||
loop.cond16: ; preds = %loop.body18, %loop.body
|
||||
%38 = load ptr, ptr %ptr, align 8, !dbg !190
|
||||
%39 = load i64, ptr %len15, align 8, !dbg !192
|
||||
%ptradd17 = getelementptr inbounds i8, ptr %38, i64 %39, !dbg !192
|
||||
%40 = load i8, ptr %ptradd17, align 1, !dbg !192
|
||||
%i2b = icmp ne i8 %40, 0, !dbg !192
|
||||
br i1 %i2b, label %loop.body18, label %loop.exit, !dbg !192
|
||||
|
||||
loop.body19: ; preds = %loop.cond17
|
||||
%42 = load i64, ptr %len16, align 8, !dbg !193
|
||||
%add20 = add i64 %42, 1, !dbg !193
|
||||
store i64 %add20, ptr %len16, align 8, !dbg !193
|
||||
br label %loop.cond17, !dbg !193
|
||||
loop.body18: ; preds = %loop.cond16
|
||||
%41 = load i64, ptr %len15, align 8, !dbg !193
|
||||
%add19 = add i64 %41, 1, !dbg !193
|
||||
store i64 %add19, ptr %len15, align 8, !dbg !193
|
||||
br label %loop.cond16, !dbg !193
|
||||
|
||||
loop.exit: ; preds = %loop.cond17
|
||||
%43 = load i64, ptr %len16, align 8, !dbg !194
|
||||
%add21 = add i64 0, %43, !dbg !194
|
||||
%size22 = sub i64 %add21, 0, !dbg !194
|
||||
%44 = insertvalue %"char[]" undef, ptr %37, 0, !dbg !194
|
||||
%45 = insertvalue %"char[]" %44, i64 %size22, 1, !dbg !194
|
||||
%46 = load ptr, ptr %list5, align 8, !dbg !195
|
||||
%47 = load i32, ptr %i, align 4, !dbg !196
|
||||
%sext23 = sext i32 %47 to i64, !dbg !196
|
||||
%ptroffset24 = getelementptr inbounds [16 x i8], ptr %46, i64 %sext23, !dbg !196
|
||||
store %"char[]" %45, ptr %ptroffset24, align 8, !dbg !196
|
||||
%48 = load i32, ptr %i, align 4, !dbg !197
|
||||
%add25 = add i32 %48, 1, !dbg !197
|
||||
store i32 %add25, ptr %i, align 4, !dbg !197
|
||||
loop.exit: ; preds = %loop.cond16
|
||||
%42 = load i64, ptr %len15, align 8, !dbg !194
|
||||
%add20 = add i64 0, %42, !dbg !194
|
||||
%size21 = sub i64 %add20, 0, !dbg !194
|
||||
%43 = insertvalue %"char[]" undef, ptr %36, 0, !dbg !194
|
||||
%44 = insertvalue %"char[]" %43, i64 %size21, 1, !dbg !194
|
||||
%45 = load ptr, ptr %list5, align 8, !dbg !195
|
||||
%46 = load i32, ptr %i, align 4, !dbg !196
|
||||
%sext22 = sext i32 %46 to i64, !dbg !196
|
||||
%ptroffset23 = getelementptr inbounds [16 x i8], ptr %45, i64 %sext22, !dbg !196
|
||||
store %"char[]" %44, ptr %ptroffset23, align 8, !dbg !196
|
||||
%47 = load i32, ptr %i, align 4, !dbg !197
|
||||
%add24 = add i32 %47, 1, !dbg !197
|
||||
store i32 %add24, ptr %i, align 4, !dbg !197
|
||||
br label %loop.cond, !dbg !197
|
||||
|
||||
loop.exit26: ; preds = %loop.cond
|
||||
loop.exit25: ; preds = %loop.cond
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %list, ptr align 8 %list5, i32 16, i1 false), !dbg !198
|
||||
%lo = load ptr, ptr %list, align 8, !dbg !199
|
||||
%ptradd27 = getelementptr inbounds i8, ptr %list, i64 8, !dbg !199
|
||||
%hi = load i64, ptr %ptradd27, align 8, !dbg !199
|
||||
%49 = call i32 @test.main(ptr %lo, i64 %hi), !dbg !200
|
||||
store i32 %49, ptr %blockret, align 4, !dbg !200
|
||||
%50 = load ptr, ptr %list, align 8, !dbg !201
|
||||
call void @std.core.mem.free(ptr %50) #4, !dbg !203
|
||||
br label %expr_block.exit28, !dbg !203
|
||||
%ptradd26 = getelementptr inbounds i8, ptr %list, i64 8, !dbg !199
|
||||
%hi = load i64, ptr %ptradd26, align 8, !dbg !199
|
||||
%48 = call i32 @test.main(ptr %lo, i64 %hi), !dbg !200
|
||||
store i32 %48, ptr %blockret, align 4, !dbg !200
|
||||
%49 = load ptr, ptr %list, align 8, !dbg !201
|
||||
call void @std.core.mem.free(ptr %49) #4, !dbg !203
|
||||
br label %expr_block.exit27, !dbg !203
|
||||
|
||||
expr_block.exit28: ; preds = %loop.exit26
|
||||
%51 = load i32, ptr %blockret, align 4, !dbg !203
|
||||
ret i32 %51, !dbg !203
|
||||
expr_block.exit27: ; preds = %loop.exit25
|
||||
%50 = load i32, ptr %blockret, align 4, !dbg !203
|
||||
ret i32 %50, !dbg !203
|
||||
}
|
||||
|
||||
declare { i32, ptr } @attach.to_scope() #0
|
||||
@@ -572,29 +570,42 @@ declare void @arena_scratch_end(ptr, i64) #0
|
||||
|
||||
define weak ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr {
|
||||
entry:
|
||||
br label %get_dtable
|
||||
|
||||
get_dtable: ; preds = %next_parent, %entry
|
||||
%typeid = phi ptr [ %0, %entry ], [ %parent_ptr, %next_parent ]
|
||||
%dtable_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 2
|
||||
%dtable = load ptr, ptr %dtable_ref, align 8
|
||||
br label %check
|
||||
|
||||
check: ; preds = %no_match, %entry
|
||||
%2 = phi ptr [ %0, %entry ], [ %9, %no_match ]
|
||||
check: ; preds = %no_match, %get_dtable
|
||||
%2 = phi ptr [ %dtable, %get_dtable ], [ %10, %no_match ]
|
||||
%3 = icmp eq ptr %2, null
|
||||
br i1 %3, label %missing_function, label %compare
|
||||
br i1 %3, label %next_parent, label %compare
|
||||
|
||||
missing_function: ; preds = %check
|
||||
next_parent: ; preds = %check
|
||||
%parent_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 1
|
||||
%parent = load i64, ptr %parent_ref, align 8
|
||||
%parent_ptr = inttoptr i64 %parent to ptr
|
||||
%4 = icmp eq ptr %parent_ptr, null
|
||||
br i1 %4, label %missing_function, label %get_dtable
|
||||
|
||||
missing_function: ; preds = %next_parent
|
||||
ret ptr null
|
||||
|
||||
compare: ; preds = %check
|
||||
%4 = getelementptr inbounds
|
||||
%5 = load ptr, ptr %4, align 8
|
||||
%6 = icmp eq ptr %5, %1
|
||||
br i1 %6, label %match, label %no_match
|
||||
%5 = getelementptr inbounds
|
||||
%6 = load ptr, ptr %5, align 8
|
||||
%7 = icmp eq ptr %6, %1
|
||||
br i1 %7, label %match, label %no_match
|
||||
|
||||
match: ; preds = %compare
|
||||
%7 = load ptr, ptr %2, align 8
|
||||
ret ptr %7
|
||||
%8 = load ptr, ptr %2, align 8
|
||||
ret ptr %8
|
||||
|
||||
no_match: ; preds = %compare
|
||||
%8 = getelementptr inbounds
|
||||
%9 = load ptr, ptr %8, align 8
|
||||
%9 = getelementptr inbounds
|
||||
%10 = load ptr, ptr %9, align 8
|
||||
br label %check
|
||||
}
|
||||
|
||||
|
||||
@@ -292,16 +292,16 @@ entry:
|
||||
%.inlinecache = alloca ptr, align 8
|
||||
%.cachedtype = alloca ptr, align 8
|
||||
%taddr = alloca %"char[]", align 8
|
||||
%taddr3 = alloca %"char[]", align 8
|
||||
%taddr4 = alloca %"char[]", align 8
|
||||
%taddr5 = alloca %"char[]", align 8
|
||||
%retparam = alloca ptr, align 8
|
||||
%taddr5 = alloca %"char[]", align 8
|
||||
%taddr6 = alloca %"char[]", align 8
|
||||
%taddr7 = alloca %"char[]", align 8
|
||||
%taddr8 = alloca %"char[]", align 8
|
||||
%varargslots = alloca [1 x %any], align 8
|
||||
%taddr9 = alloca %"any[]", align 8
|
||||
%retparam13 = alloca %"char[]", align 8
|
||||
%taddr14 = alloca %"char[]", align 8
|
||||
%taddr8 = alloca %"any[]", align 8
|
||||
%retparam12 = alloca %"char[]", align 8
|
||||
%taddr13 = alloca %"char[]", align 8
|
||||
store ptr null, ptr %.cachedtype, align 8
|
||||
%0 = call ptr @llvm.threadlocal.address.p0(ptr @std.core.mem.allocator.thread_allocator)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %allocator, ptr align 8 %0, i32 16, i1 false)
|
||||
@@ -318,98 +318,96 @@ if.exit: ; preds = %entry
|
||||
br i1 %3, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %if.exit
|
||||
%ptradd3 = getelementptr inbounds i8, ptr %2, i64 16
|
||||
%4 = load ptr, ptr %ptradd3, align 8
|
||||
%5 = call ptr @.dyn_search(ptr %4, ptr @"$sel.acquire")
|
||||
store ptr %5, ptr %.inlinecache, align 8
|
||||
%4 = call ptr @.dyn_search(ptr %2, ptr @"$sel.acquire")
|
||||
store ptr %4, ptr %.inlinecache, align 8
|
||||
store ptr %2, ptr %.cachedtype, align 8
|
||||
br label %6
|
||||
br label %5
|
||||
|
||||
cache_hit: ; preds = %if.exit
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %6
|
||||
br label %5
|
||||
|
||||
6: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %5, %cache_miss ]
|
||||
%7 = icmp eq ptr %fn_phi, null
|
||||
br i1 %7, label %missing_function, label %match
|
||||
5: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %4, %cache_miss ]
|
||||
%6 = icmp eq ptr %fn_phi, null
|
||||
br i1 %6, label %missing_function, label %match
|
||||
|
||||
missing_function: ; preds = %6
|
||||
missing_function: ; preds = %5
|
||||
store %"char[]" { ptr @.panic_msg, i64 44 }, ptr %taddr, align 8
|
||||
%8 = load [2 x i64], ptr %taddr, align 8
|
||||
store %"char[]" { ptr @.file, i64 16 }, ptr %taddr4, align 8
|
||||
%7 = load [2 x i64], ptr %taddr, align 8
|
||||
store %"char[]" { ptr @.file, i64 16 }, ptr %taddr3, align 8
|
||||
%8 = load [2 x i64], ptr %taddr3, align 8
|
||||
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr4, align 8
|
||||
%9 = load [2 x i64], ptr %taddr4, align 8
|
||||
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr5, align 8
|
||||
%10 = load [2 x i64], ptr %taddr5, align 8
|
||||
%11 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %11([2 x i64] %8, [2 x i64] %9, [2 x i64] %10, i32 98) #4
|
||||
%10 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %10([2 x i64] %7, [2 x i64] %8, [2 x i64] %9, i32 98) #4
|
||||
unreachable
|
||||
|
||||
match: ; preds = %6
|
||||
%12 = load ptr, ptr %allocator2, align 8
|
||||
%13 = call i64 %fn_phi(ptr %retparam, ptr %12, i64 12, i32 1, i64 0)
|
||||
%not_err = icmp eq i64 %13, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %14, label %after_check, label %assign_optional
|
||||
match: ; preds = %5
|
||||
%11 = load ptr, ptr %allocator2, align 8
|
||||
%12 = call i64 %fn_phi(ptr %retparam, ptr %11, i64 12, i32 1, i64 0)
|
||||
%not_err = icmp eq i64 %12, 0
|
||||
%13 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %13, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %match
|
||||
store i64 %13, ptr %error_var, align 8
|
||||
store i64 %12, ptr %error_var, align 8
|
||||
br label %panic_block
|
||||
|
||||
after_check: ; preds = %match
|
||||
%15 = load ptr, ptr %retparam, align 8
|
||||
%16 = insertvalue %"char[]" undef, ptr %15, 0
|
||||
%17 = insertvalue %"char[]" %16, i64 12, 1
|
||||
%14 = load ptr, ptr %retparam, align 8
|
||||
%15 = insertvalue %"char[]" undef, ptr %14, 0
|
||||
%16 = insertvalue %"char[]" %15, i64 12, 1
|
||||
br label %noerr_block
|
||||
|
||||
panic_block: ; preds = %assign_optional
|
||||
%18 = insertvalue %any undef, ptr %error_var, 0
|
||||
%19 = insertvalue %any %18, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %"char[]" { ptr @.panic_msg.4, i64 36 }, ptr %taddr6, align 8
|
||||
%17 = insertvalue %any undef, ptr %error_var, 0
|
||||
%18 = insertvalue %any %17, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %"char[]" { ptr @.panic_msg.4, i64 36 }, ptr %taddr5, align 8
|
||||
%19 = load [2 x i64], ptr %taddr5, align 8
|
||||
store %"char[]" { ptr @.file, i64 16 }, ptr %taddr6, align 8
|
||||
%20 = load [2 x i64], ptr %taddr6, align 8
|
||||
store %"char[]" { ptr @.file, i64 16 }, ptr %taddr7, align 8
|
||||
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr7, align 8
|
||||
%21 = load [2 x i64], ptr %taddr7, align 8
|
||||
store %"char[]" { ptr @.func, i64 4 }, ptr %taddr8, align 8
|
||||
%22 = load [2 x i64], ptr %taddr8, align 8
|
||||
store %any %19, ptr %varargslots, align 8
|
||||
%23 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %23, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %taddr9, align 8
|
||||
%24 = load [2 x i64], ptr %taddr9, align 8
|
||||
call void @std.core.builtin.panicf([2 x i64] %20, [2 x i64] %21, [2 x i64] %22, i32 262, [2 x i64] %24) #4
|
||||
store %any %18, ptr %varargslots, align 8
|
||||
%22 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %22, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %taddr8, align 8
|
||||
%23 = load [2 x i64], ptr %taddr8, align 8
|
||||
call void @std.core.builtin.panicf([2 x i64] %19, [2 x i64] %20, [2 x i64] %21, i32 262, [2 x i64] %23) #4
|
||||
unreachable
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
store %"char[]" %17, ptr %buffer, align 8
|
||||
store %"char[]" %16, ptr %buffer, align 8
|
||||
store i64 0, ptr %buffer.f, align 8
|
||||
%optval = load i64, ptr %buffer.f, align 8
|
||||
%not_err10 = icmp eq i64 %optval, 0
|
||||
%25 = call i1 @llvm.expect.i1(i1 %not_err10, i1 true)
|
||||
br i1 %25, label %after_check12, label %assign_optional11
|
||||
%not_err9 = icmp eq i64 %optval, 0
|
||||
%24 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true)
|
||||
br i1 %24, label %after_check11, label %assign_optional10
|
||||
|
||||
assign_optional11: ; preds = %noerr_block
|
||||
assign_optional10: ; preds = %noerr_block
|
||||
store i64 %optval, ptr %buffer.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_check12: ; preds = %noerr_block
|
||||
store %"char[]" { ptr @.str.5, i64 13 }, ptr %taddr14, align 8
|
||||
%26 = load [2 x i64], ptr %taddr14, align 8
|
||||
%27 = load [2 x i64], ptr %buffer, align 8
|
||||
%28 = call i64 @test.fileReader(ptr %retparam13, [2 x i64] %26, [2 x i64] %27)
|
||||
%not_err15 = icmp eq i64 %28, 0
|
||||
%29 = call i1 @llvm.expect.i1(i1 %not_err15, i1 true)
|
||||
br i1 %29, label %after_check17, label %assign_optional16
|
||||
after_check11: ; preds = %noerr_block
|
||||
store %"char[]" { ptr @.str.5, i64 13 }, ptr %taddr13, align 8
|
||||
%25 = load [2 x i64], ptr %taddr13, align 8
|
||||
%26 = load [2 x i64], ptr %buffer, align 8
|
||||
%27 = call i64 @test.fileReader(ptr %retparam12, [2 x i64] %25, [2 x i64] %26)
|
||||
%not_err14 = icmp eq i64 %27, 0
|
||||
%28 = call i1 @llvm.expect.i1(i1 %not_err14, i1 true)
|
||||
br i1 %28, label %after_check16, label %assign_optional15
|
||||
|
||||
assign_optional16: ; preds = %after_check12
|
||||
store i64 %28, ptr %buffer.f, align 8
|
||||
assign_optional15: ; preds = %after_check11
|
||||
store i64 %27, ptr %buffer.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_check17: ; preds = %after_check12
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %buffer, ptr align 8 %retparam13, i32 16, i1 false)
|
||||
after_check16: ; preds = %after_check11
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %buffer, ptr align 8 %retparam12, i32 16, i1 false)
|
||||
store i64 0, ptr %buffer.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_assign: ; preds = %after_check17, %assign_optional16, %assign_optional11
|
||||
after_assign: ; preds = %after_check16, %assign_optional15, %assign_optional10
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ entry:
|
||||
%.inlinecache = alloca ptr, align 8
|
||||
%.cachedtype = alloca ptr, align 8
|
||||
%w = alloca %any, align 8
|
||||
%.inlinecache3 = alloca ptr, align 8
|
||||
%.cachedtype4 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype4, align 8
|
||||
%.inlinecache2 = alloca ptr, align 8
|
||||
%.cachedtype3 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype3, align 8
|
||||
store ptr null, ptr %.cachedtype, align 8
|
||||
%0 = call ptr @std.core.mem.malloc(i64 8) #1
|
||||
%1 = insertvalue %any undef, ptr %0, 0
|
||||
@@ -83,56 +83,62 @@ entry:
|
||||
%type = load ptr, ptr %.cachedtype, align 8
|
||||
%5 = icmp eq ptr %4, %type
|
||||
br i1 %5, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %entry
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %4, i64 16
|
||||
%6 = load ptr, ptr %ptradd1, align 8
|
||||
%7 = call ptr @.dyn_search(ptr %6, ptr @"$sel.tesT")
|
||||
store ptr %7, ptr %.inlinecache, align 8
|
||||
%6 = call ptr @.dyn_search(ptr %4, ptr @"$sel.tesT")
|
||||
store ptr %6, ptr %.inlinecache, align 8
|
||||
store ptr %4, ptr %.cachedtype, align 8
|
||||
br label %8
|
||||
br label %7
|
||||
|
||||
cache_hit: ; preds = %entry
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %8
|
||||
8: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ]
|
||||
%9 = icmp eq ptr %fn_phi, null
|
||||
br i1 %9, label %missing_function, label %match
|
||||
missing_function: ; preds = %8
|
||||
%10 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %10(ptr @.panic_msg, i64 41, ptr @.file
|
||||
br label %7
|
||||
|
||||
7: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %6, %cache_miss ]
|
||||
%8 = icmp eq ptr %fn_phi, null
|
||||
br i1 %8, label %missing_function, label %match
|
||||
|
||||
missing_function: ; preds = %7
|
||||
%9 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %9(ptr @.panic_msg, i64 41, ptr @.file
|
||||
unreachable
|
||||
match: ; preds = %8
|
||||
%11 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %11)
|
||||
%12 = load %any, ptr %z, align 8
|
||||
store %any %12, ptr %w, align 8
|
||||
%ptradd2 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%13 = load i64, ptr %ptradd2, align 8
|
||||
%14 = inttoptr i64 %13 to ptr
|
||||
%type5 = load ptr, ptr %.cachedtype4, align 8
|
||||
%15 = icmp eq ptr %14, %type5
|
||||
br i1 %15, label %cache_hit8, label %cache_miss6
|
||||
cache_miss6: ; preds = %match
|
||||
%ptradd7 = getelementptr inbounds i8, ptr %14, i64 16
|
||||
%16 = load ptr, ptr %ptradd7, align 8
|
||||
%17 = call ptr @.dyn_search(ptr %16, ptr @"$sel.tesT")
|
||||
store ptr %17, ptr %.inlinecache3, align 8
|
||||
store ptr %14, ptr %.cachedtype4, align 8
|
||||
br label %18
|
||||
cache_hit8: ; preds = %match
|
||||
%cache_hit_fn9 = load ptr, ptr %.inlinecache3, align 8
|
||||
br label %18
|
||||
18: ; preds = %cache_hit8, %cache_miss6
|
||||
%fn_phi10 = phi ptr [ %cache_hit_fn9, %cache_hit8 ], [ %17, %cache_miss6 ]
|
||||
%19 = icmp eq ptr %fn_phi10, null
|
||||
br i1 %19, label %missing_function11, label %match12
|
||||
missing_function11: ; preds = %18
|
||||
%20 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %20(ptr @.panic_msg, i64 41, ptr @.file, i64 16, ptr @.func, i64 4, i32 36)
|
||||
|
||||
match: ; preds = %7
|
||||
%10 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %10)
|
||||
%11 = load %any, ptr %z, align 8
|
||||
store %any %11, ptr %w, align 8
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%12 = load i64, ptr %ptradd1, align 8
|
||||
%13 = inttoptr i64 %12 to ptr
|
||||
%type4 = load ptr, ptr %.cachedtype3, align 8
|
||||
%14 = icmp eq ptr %13, %type4
|
||||
br i1 %14, label %cache_hit6, label %cache_miss5
|
||||
|
||||
cache_miss5: ; preds = %match
|
||||
%15 = call ptr @.dyn_search(ptr %13, ptr @"$sel.tesT")
|
||||
store ptr %15, ptr %.inlinecache2, align 8
|
||||
store ptr %13, ptr %.cachedtype3, align 8
|
||||
br label %16
|
||||
|
||||
cache_hit6: ; preds = %match
|
||||
%cache_hit_fn7 = load ptr, ptr %.inlinecache2, align 8
|
||||
br label %16
|
||||
|
||||
16: ; preds = %cache_hit6, %cache_miss5
|
||||
%fn_phi8 = phi ptr [ %cache_hit_fn7, %cache_hit6 ], [ %15, %cache_miss5 ]
|
||||
%17 = icmp eq ptr %fn_phi8, null
|
||||
br i1 %17, label %missing_function9, label %match10
|
||||
|
||||
missing_function9: ; preds = %16
|
||||
%18 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %18(ptr @.panic_msg, i64 41, ptr @.file, i64 16, ptr @.func, i64 4, i32 36) #2
|
||||
unreachable
|
||||
match12: ; preds = %18
|
||||
%21 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi10(ptr %21)
|
||||
|
||||
match10: ; preds = %16
|
||||
%19 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi8(ptr %19)
|
||||
ret void
|
||||
}
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
@@ -143,55 +149,80 @@ entry:
|
||||
|
||||
define weak ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr comdat {
|
||||
entry:
|
||||
br label %get_dtable
|
||||
|
||||
get_dtable: ; preds = %next_parent, %entry
|
||||
%typeid = phi ptr [ %0, %entry ], [ %parent_ptr, %next_parent ]
|
||||
%dtable_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 2
|
||||
%dtable = load ptr, ptr %dtable_ref, align 8
|
||||
br label %check
|
||||
check: ; preds = %no_match, %entry
|
||||
%2 = phi ptr [ %0, %entry ], [ %9, %no_match ]
|
||||
|
||||
check: ; preds = %no_match, %get_dtable
|
||||
%2 = phi ptr [ %dtable, %get_dtable ], [ %10, %no_match ]
|
||||
%3 = icmp eq ptr %2, null
|
||||
br i1 %3, label %missing_function, label %compare
|
||||
missing_function: ; preds = %check
|
||||
br i1 %3, label %next_parent, label %compare
|
||||
|
||||
next_parent: ; preds = %check
|
||||
%parent_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 1
|
||||
%parent = load i64, ptr %parent_ref, align 8
|
||||
%parent_ptr = inttoptr i64 %parent to ptr
|
||||
%4 = icmp eq ptr %parent_ptr, null
|
||||
br i1 %4, label %missing_function, label %get_dtable
|
||||
|
||||
missing_function: ; preds = %next_parent
|
||||
ret ptr null
|
||||
|
||||
compare: ; preds = %check
|
||||
%4 = getelementptr inbounds
|
||||
%5 = load ptr, ptr %4, align 8
|
||||
%6 = icmp eq ptr %5, %1
|
||||
br i1 %6, label %match, label %no_match
|
||||
%5 = getelementptr inbounds
|
||||
%6 = load ptr, ptr %5, align 8
|
||||
%7 = icmp eq ptr %6, %1
|
||||
br i1 %7, label %match, label %no_match
|
||||
|
||||
match: ; preds = %compare
|
||||
%7 = load ptr, ptr %2, align 8
|
||||
ret ptr %7
|
||||
%8 = load ptr, ptr %2, align 8
|
||||
ret ptr %8
|
||||
|
||||
no_match: ; preds = %compare
|
||||
%8 = getelementptr inbounds
|
||||
%9 = load ptr, ptr %8, align 8
|
||||
%9 = getelementptr inbounds
|
||||
%10 = load ptr, ptr %9, align 8
|
||||
br label %check
|
||||
}
|
||||
|
||||
define internal void @.c3_dynamic_register() align 8 {
|
||||
entry:
|
||||
%next_val = load ptr, ptr getelementptr inbounds
|
||||
%0 = icmp eq ptr %next_val, inttoptr (i64 -1 to ptr)
|
||||
br i1 %0, label %dtable_check, label %dtable_skip
|
||||
|
||||
dtable_check: ; preds = %dtable_check, %entry
|
||||
%dtable_ref = phi ptr [ getelementptr inbounds
|
||||
%dtable_ptr = load ptr, ptr %dtable_ref, align 8
|
||||
%1 = icmp eq ptr %dtable_ptr, null
|
||||
%next_dtable_ref = getelementptr inbounds
|
||||
br i1 %1, label %dtable_found, label %dtable_check
|
||||
|
||||
dtable_found: ; preds = %dtable_check
|
||||
store ptr @"$ct.dyn.inherit.Test.tesT", ptr %dtable_ref, align 8
|
||||
store ptr null, ptr getelementptr inbounds
|
||||
br label %dtable_skip
|
||||
|
||||
dtable_skip: ; preds = %dtable_found, %entry
|
||||
%next_val1 = load ptr, ptr getelementptr inbounds
|
||||
%2 = icmp eq ptr %next_val1, inttoptr (i64 -1 to ptr)
|
||||
br i1 %2, label %dtable_check2, label %dtable_skip7
|
||||
|
||||
dtable_check2: ; preds = %dtable_check2, %dtable_skip
|
||||
%dtable_ref3 = phi ptr [ getelementptr inbounds
|
||||
%dtable_ptr4 = load ptr, ptr %dtable_ref3, align 8
|
||||
%3 = icmp eq ptr %dtable_ptr4, null
|
||||
%next_dtable_ref5 = getelementptr inbounds
|
||||
br i1 %3, label %dtable_found6, label %dtable_check2
|
||||
|
||||
dtable_found6: ; preds = %dtable_check2
|
||||
store ptr @"$ct.dyn.inherit.Test.hello", ptr %dtable_ref3, align 8
|
||||
store ptr null, ptr getelementptr inbounds
|
||||
br label %dtable_skip7
|
||||
|
||||
dtable_skip7: ; preds = %dtable_found6, %dtable_skip
|
||||
ret void
|
||||
}
|
||||
@@ -66,9 +66,9 @@ entry:
|
||||
%.inlinecache = alloca ptr, align 8
|
||||
%.cachedtype = alloca ptr, align 8
|
||||
%w = alloca %any, align 8
|
||||
%.inlinecache3 = alloca ptr, align 8
|
||||
%.cachedtype4 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype4, align 8
|
||||
%.inlinecache2 = alloca ptr, align 8
|
||||
%.cachedtype3 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype3, align 8
|
||||
store ptr null, ptr %.cachedtype, align 8
|
||||
%0 = call ptr @std.core.mem.malloc(i64 8) #1
|
||||
%1 = insertvalue %any undef, ptr %0, 0
|
||||
@@ -82,64 +82,60 @@ entry:
|
||||
br i1 %5, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %entry
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %4, i64 16
|
||||
%6 = load ptr, ptr %ptradd1, align 8
|
||||
%7 = call ptr @.dyn_search(ptr %6, ptr @"$sel.tesT")
|
||||
store ptr %7, ptr %.inlinecache, align 8
|
||||
%6 = call ptr @.dyn_search(ptr %4, ptr @"$sel.tesT")
|
||||
store ptr %6, ptr %.inlinecache, align 8
|
||||
store ptr %4, ptr %.cachedtype, align 8
|
||||
br label %8
|
||||
br label %7
|
||||
|
||||
cache_hit: ; preds = %entry
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %8
|
||||
br label %7
|
||||
|
||||
8: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ]
|
||||
%9 = icmp eq ptr %fn_phi, null
|
||||
br i1 %9, label %missing_function, label %match
|
||||
7: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %6, %cache_miss ]
|
||||
%8 = icmp eq ptr %fn_phi, null
|
||||
br i1 %8, label %missing_function, label %match
|
||||
|
||||
missing_function: ; preds = %8
|
||||
%10 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %10(ptr @.panic_msg, i64 41,
|
||||
missing_function: ; preds = %7
|
||||
%9 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %9(ptr @.panic_msg, i64 41,
|
||||
unreachable
|
||||
|
||||
match: ; preds = %8
|
||||
%11 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %11)
|
||||
%12 = load %any, ptr %z, align 8
|
||||
store %any %12, ptr %w, align 8
|
||||
%ptradd2 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%13 = load i64, ptr %ptradd2, align 8
|
||||
%14 = inttoptr i64 %13 to ptr
|
||||
%type5 = load ptr, ptr %.cachedtype4, align 8
|
||||
%15 = icmp eq ptr %14, %type5
|
||||
br i1 %15, label %cache_hit8, label %cache_miss6
|
||||
match: ; preds = %7
|
||||
%10 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %10)
|
||||
%11 = load %any, ptr %z, align 8
|
||||
store %any %11, ptr %w, align 8
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%12 = load i64, ptr %ptradd1, align 8
|
||||
%13 = inttoptr i64 %12 to ptr
|
||||
%type4 = load ptr, ptr %.cachedtype3, align 8
|
||||
%14 = icmp eq ptr %13, %type4
|
||||
br i1 %14, label %cache_hit6, label %cache_miss5
|
||||
|
||||
cache_miss6: ; preds = %match
|
||||
%ptradd7 = getelementptr inbounds i8, ptr %14, i64 16
|
||||
%16 = load ptr, ptr %ptradd7, align 8
|
||||
%17 = call ptr @.dyn_search(ptr %16, ptr @"$sel.tesT")
|
||||
store ptr %17, ptr %.inlinecache3, align 8
|
||||
store ptr %14, ptr %.cachedtype4, align 8
|
||||
br label %18
|
||||
cache_miss5: ; preds = %match
|
||||
%15 = call ptr @.dyn_search(ptr %13, ptr @"$sel.tesT")
|
||||
store ptr %15, ptr %.inlinecache2, align 8
|
||||
store ptr %13, ptr %.cachedtype3, align 8
|
||||
br label %16
|
||||
|
||||
cache_hit8: ; preds = %match
|
||||
%cache_hit_fn9 = load ptr, ptr %.inlinecache3, align 8
|
||||
br label %18
|
||||
cache_hit6: ; preds = %match
|
||||
%cache_hit_fn7 = load ptr, ptr %.inlinecache2, align 8
|
||||
br label %16
|
||||
|
||||
18: ; preds = %cache_hit8, %cache_miss6
|
||||
%fn_phi10 = phi ptr [ %cache_hit_fn9, %cache_hit8 ], [ %17, %cache_miss6 ]
|
||||
%19 = icmp eq ptr %fn_phi10, null
|
||||
br i1 %19, label %missing_function11, label %match12
|
||||
16: ; preds = %cache_hit6, %cache_miss5
|
||||
%fn_phi8 = phi ptr [ %cache_hit_fn7, %cache_hit6 ], [ %15, %cache_miss5 ]
|
||||
%17 = icmp eq ptr %fn_phi8, null
|
||||
br i1 %17, label %missing_function9, label %match10
|
||||
|
||||
missing_function11: ; preds = %18
|
||||
%20 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %20(ptr @.panic_msg, i64 41
|
||||
missing_function9: ; preds = %16
|
||||
%18 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %18(ptr @.panic_msg, i64 41
|
||||
unreachable
|
||||
|
||||
match12: ; preds = %18
|
||||
%21 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi10(ptr %21)
|
||||
match10: ; preds = %16
|
||||
%19 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi8(ptr %19)
|
||||
ret void
|
||||
}
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
@@ -149,28 +145,41 @@ entry:
|
||||
}
|
||||
define weak ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr {
|
||||
entry:
|
||||
br label %get_dtable
|
||||
|
||||
get_dtable: ; preds = %next_parent, %entry
|
||||
%typeid = phi ptr [ %0, %entry ], [ %parent_ptr, %next_parent ]
|
||||
%dtable_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 2
|
||||
%dtable = load ptr, ptr %dtable_ref, align 8
|
||||
br label %check
|
||||
|
||||
check: ; preds = %no_match, %entry
|
||||
%2 = phi ptr [ %0, %entry ], [ %9, %no_match ]
|
||||
check: ; preds = %no_match, %get_dtable
|
||||
%2 = phi ptr [ %dtable, %get_dtable ], [ %10, %no_match ]
|
||||
%3 = icmp eq ptr %2, null
|
||||
br i1 %3, label %missing_function, label %compare
|
||||
br i1 %3, label %next_parent, label %compare
|
||||
|
||||
missing_function: ; preds = %check
|
||||
next_parent: ; preds = %check
|
||||
%parent_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 1
|
||||
%parent = load i64, ptr %parent_ref, align 8
|
||||
%parent_ptr = inttoptr i64 %parent to ptr
|
||||
%4 = icmp eq ptr %parent_ptr, null
|
||||
br i1 %4, label %missing_function, label %get_dtable
|
||||
|
||||
missing_function: ; preds = %next_parent
|
||||
ret ptr null
|
||||
|
||||
compare: ; preds = %check
|
||||
%4 = getelementptr inbounds
|
||||
%5 = load ptr, ptr %4, align 8
|
||||
%6 = icmp eq ptr %5, %1
|
||||
br i1 %6, label %match, label %no_match
|
||||
%5 = getelementptr inbounds
|
||||
%6 = load ptr, ptr %5, align 8
|
||||
%7 = icmp eq ptr %6, %1
|
||||
br i1 %7, label %match, label %no_match
|
||||
|
||||
match: ; preds = %compare
|
||||
%7 = load ptr, ptr %2, align 8
|
||||
ret ptr %7
|
||||
%8 = load ptr, ptr %2, align 8
|
||||
ret ptr %8
|
||||
|
||||
no_match: ; preds = %compare
|
||||
%8 = getelementptr inbounds
|
||||
%9 = load ptr, ptr %8, align 8
|
||||
%9 = getelementptr inbounds
|
||||
%10 = load ptr, ptr %9, align 8
|
||||
br label %check
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ fn void main()
|
||||
@"$ct.dyn.overlap.Test.foo" = weak global { ptr, ptr, ptr } { ptr @overlap.Test.foo, ptr @"$sel.foo", ptr inttoptr (i64 -1 to ptr) }, comdat, align 8
|
||||
@"$sel.foo" = linkonce_odr constant [4 x i8] c"foo\00", comdat, align 1
|
||||
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.c3_dynamic_register, ptr null }]
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @overlap.Test.tesT(ptr %0) #0 {
|
||||
entry:
|
||||
@@ -63,9 +64,9 @@ entry:
|
||||
%.inlinecache = alloca ptr, align 8
|
||||
%.cachedtype = alloca ptr, align 8
|
||||
%w = alloca %any, align 8
|
||||
%.inlinecache3 = alloca ptr, align 8
|
||||
%.cachedtype4 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype4, align 8
|
||||
%.inlinecache2 = alloca ptr, align 8
|
||||
%.cachedtype3 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype3, align 8
|
||||
store ptr null, ptr %.cachedtype, align 8
|
||||
%0 = call ptr @std.core.mem.malloc(i64 8) #1
|
||||
%1 = insertvalue %any undef, ptr %0, 0
|
||||
@@ -77,56 +78,62 @@ entry:
|
||||
%type = load ptr, ptr %.cachedtype, align 8
|
||||
%5 = icmp eq ptr %4, %type
|
||||
br i1 %5, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %entry
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %4, i64 16
|
||||
%6 = load ptr, ptr %ptradd1, align 8
|
||||
%7 = call ptr @.dyn_search(ptr %6, ptr @"$sel.tesT")
|
||||
store ptr %7, ptr %.inlinecache, align 8
|
||||
%6 = call ptr @.dyn_search(ptr %4, ptr @"$sel.tesT")
|
||||
store ptr %6, ptr %.inlinecache, align 8
|
||||
store ptr %4, ptr %.cachedtype, align 8
|
||||
br label %8
|
||||
br label %7
|
||||
|
||||
cache_hit: ; preds = %entry
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %8
|
||||
8: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ]
|
||||
%9 = icmp eq ptr %fn_phi, null
|
||||
br i1 %9, label %missing_function, label %match
|
||||
missing_function: ; preds = %8
|
||||
%10 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %10(ptr @.panic_msg, i64 41, ptr @.file
|
||||
br label %7
|
||||
|
||||
7: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %6, %cache_miss ]
|
||||
%8 = icmp eq ptr %fn_phi, null
|
||||
br i1 %8, label %missing_function, label %match
|
||||
|
||||
missing_function: ; preds = %7
|
||||
%9 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %9(ptr @.panic_msg, i64 41, ptr @.file
|
||||
unreachable
|
||||
match: ; preds = %8
|
||||
%11 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %11)
|
||||
%12 = load %any, ptr %z, align 8
|
||||
store %any %12, ptr %w, align 8
|
||||
%ptradd2 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%13 = load i64, ptr %ptradd2, align 8
|
||||
%14 = inttoptr i64 %13 to ptr
|
||||
%type5 = load ptr, ptr %.cachedtype4, align 8
|
||||
%15 = icmp eq ptr %14, %type5
|
||||
br i1 %15, label %cache_hit8, label %cache_miss6
|
||||
cache_miss6: ; preds = %match
|
||||
%ptradd7 = getelementptr inbounds i8, ptr %14, i64 16
|
||||
%16 = load ptr, ptr %ptradd7, align 8
|
||||
%17 = call ptr @.dyn_search(ptr %16, ptr @"$sel.tesT")
|
||||
store ptr %17, ptr %.inlinecache3, align 8
|
||||
store ptr %14, ptr %.cachedtype4, align 8
|
||||
br label %18
|
||||
cache_hit8: ; preds = %match
|
||||
%cache_hit_fn9 = load ptr, ptr %.inlinecache3, align 8
|
||||
br label %18
|
||||
18: ; preds = %cache_hit8, %cache_miss6
|
||||
%fn_phi10 = phi ptr [ %cache_hit_fn9, %cache_hit8 ], [ %17, %cache_miss6 ]
|
||||
%19 = icmp eq ptr %fn_phi10, null
|
||||
br i1 %19, label %missing_function11, label %match12
|
||||
missing_function11: ; preds = %18
|
||||
%20 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %20(ptr @.panic_msg, i64 41, ptr @.file
|
||||
|
||||
match: ; preds = %7
|
||||
%10 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %10)
|
||||
%11 = load %any, ptr %z, align 8
|
||||
store %any %11, ptr %w, align 8
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%12 = load i64, ptr %ptradd1, align 8
|
||||
%13 = inttoptr i64 %12 to ptr
|
||||
%type4 = load ptr, ptr %.cachedtype3, align 8
|
||||
%14 = icmp eq ptr %13, %type4
|
||||
br i1 %14, label %cache_hit6, label %cache_miss5
|
||||
|
||||
cache_miss5: ; preds = %match
|
||||
%15 = call ptr @.dyn_search(ptr %13, ptr @"$sel.tesT")
|
||||
store ptr %15, ptr %.inlinecache2, align 8
|
||||
store ptr %13, ptr %.cachedtype3, align 8
|
||||
br label %16
|
||||
|
||||
cache_hit6: ; preds = %match
|
||||
%cache_hit_fn7 = load ptr, ptr %.inlinecache2, align 8
|
||||
br label %16
|
||||
|
||||
16: ; preds = %cache_hit6, %cache_miss5
|
||||
%fn_phi8 = phi ptr [ %cache_hit_fn7, %cache_hit6 ], [ %15, %cache_miss5 ]
|
||||
%17 = icmp eq ptr %fn_phi8, null
|
||||
br i1 %17, label %missing_function9, label %match10
|
||||
|
||||
missing_function9: ; preds = %16
|
||||
%18 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %18(ptr @.panic_msg, i64 41, ptr @.file
|
||||
unreachable
|
||||
match12: ; preds = %18
|
||||
%21 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi10(ptr %21)
|
||||
|
||||
match10: ; preds = %16
|
||||
%19 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi8(ptr %19)
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -137,26 +144,45 @@ entry:
|
||||
}
|
||||
define weak ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr comdat {
|
||||
entry:
|
||||
br label %get_dtable
|
||||
|
||||
get_dtable: ; preds = %next_parent, %entry
|
||||
%typeid = phi ptr [ %0, %entry ], [ %parent_ptr, %next_parent ]
|
||||
%dtable_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 2
|
||||
%dtable = load ptr, ptr %dtable_ref, align 8
|
||||
br label %check
|
||||
check: ; preds = %no_match, %entry
|
||||
%2 = phi ptr [ %0, %entry ], [ %9, %no_match ]
|
||||
|
||||
check: ; preds = %no_match, %get_dtable
|
||||
%2 = phi ptr [ %dtable, %get_dtable ], [ %10, %no_match ]
|
||||
%3 = icmp eq ptr %2, null
|
||||
br i1 %3, label %missing_function, label %compare
|
||||
missing_function: ; preds = %check
|
||||
br i1 %3, label %next_parent, label %compare
|
||||
|
||||
next_parent: ; preds = %check
|
||||
%parent_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 1
|
||||
%parent = load i64, ptr %parent_ref, align 8
|
||||
%parent_ptr = inttoptr i64 %parent to ptr
|
||||
%4 = icmp eq ptr %parent_ptr, null
|
||||
br i1 %4, label %missing_function, label %get_dtable
|
||||
|
||||
missing_function: ; preds = %next_parent
|
||||
ret ptr null
|
||||
|
||||
compare: ; preds = %check
|
||||
%4 = getelementptr inbounds
|
||||
%5 = load ptr, ptr %4, align 8
|
||||
%6 = icmp eq ptr %5, %1
|
||||
br i1 %6, label %match, label %no_match
|
||||
%5 = getelementptr inbounds
|
||||
%6 = load ptr, ptr %5, align 8
|
||||
%7 = icmp eq ptr %6, %1
|
||||
br i1 %7, label %match, label %no_match
|
||||
|
||||
match: ; preds = %compare
|
||||
%7 = load ptr, ptr %2, align 8
|
||||
ret ptr %7
|
||||
%8 = load ptr, ptr %2, align 8
|
||||
ret ptr %8
|
||||
|
||||
no_match: ; preds = %compare
|
||||
%8 = getelementptr inbounds
|
||||
%9 = load ptr, ptr %8, align 8
|
||||
%9 = getelementptr inbounds
|
||||
%10 = load ptr, ptr %9, align 8
|
||||
br label %check
|
||||
}
|
||||
|
||||
define internal void @.c3_dynamic_register() align 8 {
|
||||
entry:
|
||||
%next_val = load ptr, ptr getelementptr inbounds
|
||||
|
||||
@@ -61,9 +61,9 @@ entry:
|
||||
%.inlinecache = alloca ptr, align 8
|
||||
%.cachedtype = alloca ptr, align 8
|
||||
%w = alloca %any, align 8
|
||||
%.inlinecache3 = alloca ptr, align 8
|
||||
%.cachedtype4 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype4, align 8
|
||||
%.inlinecache2 = alloca ptr, align 8
|
||||
%.cachedtype3 = alloca ptr, align 8
|
||||
store ptr null, ptr %.cachedtype3, align 8
|
||||
store ptr null, ptr %.cachedtype, align 8
|
||||
%0 = call ptr @std.core.mem.malloc(i64 8) #1
|
||||
%1 = insertvalue %any undef, ptr %0, 0
|
||||
@@ -77,68 +77,64 @@ entry:
|
||||
br i1 %5, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %entry
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %4, i64 16
|
||||
%6 = load ptr, ptr %ptradd1, align 8
|
||||
%7 = call ptr @.dyn_search(ptr %6, ptr @"$sel.tesT")
|
||||
store ptr %7, ptr %.inlinecache, align 8
|
||||
%6 = call ptr @.dyn_search(ptr %4, ptr @"$sel.tesT")
|
||||
store ptr %6, ptr %.inlinecache, align 8
|
||||
store ptr %4, ptr %.cachedtype, align 8
|
||||
br label %8
|
||||
br label %7
|
||||
|
||||
cache_hit: ; preds = %entry
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %8
|
||||
br label %7
|
||||
|
||||
8: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %7, %cache_miss ]
|
||||
%9 = icmp eq ptr %fn_phi, null
|
||||
br i1 %9, label %missing_function, label %match
|
||||
7: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %6, %cache_miss ]
|
||||
%8 = icmp eq ptr %fn_phi, null
|
||||
br i1 %8, label %missing_function, label %match
|
||||
|
||||
missing_function: ; preds = %8
|
||||
%10 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %10(ptr @.panic_msg, i64 41, ptr @.file
|
||||
missing_function: ; preds = %7
|
||||
%9 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %9(ptr @.panic_msg, i64 41, ptr @.file
|
||||
unreachable
|
||||
|
||||
match: ; preds = %8
|
||||
%11 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %11)
|
||||
%12 = load %any, ptr %z, align 8
|
||||
store %any %12, ptr %w, align 8
|
||||
%ptradd2 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%13 = load i64, ptr %ptradd2, align 8
|
||||
%14 = inttoptr i64 %13 to ptr
|
||||
%type5 = load ptr, ptr %.cachedtype4, align 8
|
||||
%15 = icmp eq ptr %14, %type5
|
||||
br i1 %15, label %cache_hit8, label %cache_miss6
|
||||
match: ; preds = %7
|
||||
%10 = load ptr, ptr %z, align 8
|
||||
call void %fn_phi(ptr %10)
|
||||
%11 = load %any, ptr %z, align 8
|
||||
store %any %11, ptr %w, align 8
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %w, i64 8
|
||||
%12 = load i64, ptr %ptradd1, align 8
|
||||
%13 = inttoptr i64 %12 to ptr
|
||||
%type4 = load ptr, ptr %.cachedtype3, align 8
|
||||
%14 = icmp eq ptr %13, %type4
|
||||
br i1 %14, label %cache_hit6, label %cache_miss5
|
||||
|
||||
cache_miss6: ; preds = %match
|
||||
%ptradd7 = getelementptr inbounds i8, ptr %14, i64 16
|
||||
%16 = load ptr, ptr %ptradd7, align 8
|
||||
%17 = call ptr @.dyn_search(ptr %16, ptr @"$sel.tesT")
|
||||
store ptr %17, ptr %.inlinecache3, align 8
|
||||
store ptr %14, ptr %.cachedtype4, align 8
|
||||
br label %18
|
||||
cache_miss5: ; preds = %match
|
||||
%15 = call ptr @.dyn_search(ptr %13, ptr @"$sel.tesT")
|
||||
store ptr %15, ptr %.inlinecache2, align 8
|
||||
store ptr %13, ptr %.cachedtype3, align 8
|
||||
br label %16
|
||||
|
||||
cache_hit8: ; preds = %match
|
||||
%cache_hit_fn9 = load ptr, ptr %.inlinecache3, align 8
|
||||
br label %18
|
||||
cache_hit6: ; preds = %match
|
||||
%cache_hit_fn7 = load ptr, ptr %.inlinecache2, align 8
|
||||
br label %16
|
||||
|
||||
18: ; preds = %cache_hit8, %cache_miss6
|
||||
%fn_phi10 = phi ptr [ %cache_hit_fn9, %cache_hit8 ], [ %17, %cache_miss6 ]
|
||||
%19 = icmp eq ptr %fn_phi10, null
|
||||
br i1 %19, label %missing_function11, label %match12
|
||||
16: ; preds = %cache_hit6, %cache_miss5
|
||||
%fn_phi8 = phi ptr [ %cache_hit_fn7, %cache_hit6 ], [ %15, %cache_miss5 ]
|
||||
%17 = icmp eq ptr %fn_phi8, null
|
||||
br i1 %17, label %missing_function9, label %match10
|
||||
|
||||
missing_function11: ; preds = %18
|
||||
%20 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %20(ptr @.panic_msg, i64 41, ptr @.file
|
||||
missing_function9: ; preds = %16
|
||||
%18 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %18(ptr @.panic_msg, i64 41, ptr @.file
|
||||
unreachable
|
||||
|
||||
match12: ; preds = %18
|
||||
%21 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi10(ptr %21)
|
||||
match10: ; preds = %16
|
||||
%19 = load ptr, ptr %w, align 8
|
||||
call void %fn_phi8(ptr %19)
|
||||
ret void
|
||||
}
|
||||
|
||||
; Function Attrs:
|
||||
|
||||
define i32 @main(i32 %0, ptr %1) #0 {
|
||||
entry:
|
||||
call void @overlap.main()
|
||||
@@ -147,28 +143,41 @@ entry:
|
||||
|
||||
define weak ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr {
|
||||
entry:
|
||||
br label %get_dtable
|
||||
|
||||
get_dtable: ; preds = %next_parent, %entry
|
||||
%typeid = phi ptr [ %0, %entry ], [ %parent_ptr, %next_parent ]
|
||||
%dtable_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 2
|
||||
%dtable = load ptr, ptr %dtable_ref, align 8
|
||||
br label %check
|
||||
|
||||
check: ; preds = %no_match, %entry
|
||||
%2 = phi ptr [ %0, %entry ], [ %9, %no_match ]
|
||||
check: ; preds = %no_match, %get_dtable
|
||||
%2 = phi ptr [ %dtable, %get_dtable ], [ %10, %no_match ]
|
||||
%3 = icmp eq ptr %2, null
|
||||
br i1 %3, label %missing_function, label %compare
|
||||
br i1 %3, label %next_parent, label %compare
|
||||
|
||||
missing_function: ; preds = %check
|
||||
next_parent: ; preds = %check
|
||||
%parent_ref = getelementptr inbounds %.introspect, ptr %typeid, i32 0, i32 1
|
||||
%parent = load i64, ptr %parent_ref, align 8
|
||||
%parent_ptr = inttoptr i64 %parent to ptr
|
||||
%4 = icmp eq ptr %parent_ptr, null
|
||||
br i1 %4, label %missing_function, label %get_dtable
|
||||
|
||||
missing_function: ; preds = %next_parent
|
||||
ret ptr null
|
||||
|
||||
compare: ; preds = %check
|
||||
%4 = getelementptr inbounds
|
||||
%5 = load ptr, ptr %4, align 8
|
||||
%6 = icmp eq ptr %5, %1
|
||||
br i1 %6, label %match, label %no_match
|
||||
%5 = getelementptr inbounds
|
||||
%6 = load ptr, ptr %5, align 8
|
||||
%7 = icmp eq ptr %6, %1
|
||||
br i1 %7, label %match, label %no_match
|
||||
|
||||
match: ; preds = %compare
|
||||
%7 = load ptr, ptr %2, align 8
|
||||
ret ptr %7
|
||||
%8 = load ptr, ptr %2, align 8
|
||||
ret ptr %8
|
||||
|
||||
no_match: ; preds = %compare
|
||||
%8 = getelementptr inbounds
|
||||
%9 = load ptr, ptr %8, align 8
|
||||
%9 = getelementptr inbounds
|
||||
%10 = load ptr, ptr %9, align 8
|
||||
br label %check
|
||||
}
|
||||
|
||||
26
test/test_suite/enumerations/enum_const_inline_interface.c3
Normal file
26
test/test_suite/enumerations/enum_const_inline_interface.c3
Normal file
@@ -0,0 +1,26 @@
|
||||
module foo;
|
||||
import std;
|
||||
interface Test
|
||||
{
|
||||
fn void x();
|
||||
}
|
||||
|
||||
typedef Foo (Test) = int;
|
||||
|
||||
fn void Foo.x(&self) @dynamic
|
||||
{
|
||||
io::printn("Foo!");
|
||||
}
|
||||
|
||||
enum Tester : const inline Foo
|
||||
{
|
||||
ABC = 1
|
||||
}
|
||||
|
||||
fn int main()
|
||||
{
|
||||
Tester x;
|
||||
Test t = &x; // #error: but you can use an explicit cast to
|
||||
t.x();
|
||||
return 0;
|
||||
}
|
||||
27
test/test_suite/enumerations/enum_inline_interface.c3
Normal file
27
test/test_suite/enumerations/enum_inline_interface.c3
Normal file
@@ -0,0 +1,27 @@
|
||||
module foo;
|
||||
import std;
|
||||
interface Test
|
||||
{
|
||||
fn void x();
|
||||
}
|
||||
|
||||
typedef Foo (Test) = int;
|
||||
|
||||
fn void Foo.x(&self) @dynamic
|
||||
{
|
||||
io::printn("Foo!");
|
||||
}
|
||||
|
||||
enum Tester : inline Foo
|
||||
{
|
||||
ABC
|
||||
}
|
||||
|
||||
fn int main()
|
||||
{
|
||||
Tester x;
|
||||
Test t = &x; // #error: but you can use an explicit cast to
|
||||
t.x();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,70 +46,84 @@ entry:
|
||||
%type = load ptr, ptr %.cachedtype, align 8
|
||||
%4 = icmp eq ptr %3, %type
|
||||
br i1 %4, label %cache_hit, label %cache_miss
|
||||
|
||||
cache_miss: ; preds = %entry
|
||||
%ptradd1 = getelementptr inbounds i8, ptr %3, i64 16
|
||||
%5 = load ptr, ptr %ptradd1, align 8
|
||||
%6 = call ptr @.dyn_search(ptr %5, ptr @"$sel.read_byte")
|
||||
store ptr %6, ptr %.inlinecache, align 8
|
||||
%5 = call ptr @.dyn_search(ptr %3, ptr @"$sel.read_byte")
|
||||
store ptr %5, ptr %.inlinecache, align 8
|
||||
store ptr %3, ptr %.cachedtype, align 8
|
||||
br label %7
|
||||
br label %6
|
||||
|
||||
cache_hit: ; preds = %entry
|
||||
%cache_hit_fn = load ptr, ptr %.inlinecache, align 8
|
||||
br label %7
|
||||
7: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %6, %cache_miss ]
|
||||
%8 = icmp eq ptr %fn_phi, null
|
||||
br i1 %8, label %missing_function, label %match
|
||||
missing_function: ; preds = %7
|
||||
%9 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %9(ptr @.panic_msg, i64 46, ptr @.file, i64 25, ptr @.func, i64 4, i32 13)
|
||||
br label %6
|
||||
|
||||
6: ; preds = %cache_hit, %cache_miss
|
||||
%fn_phi = phi ptr [ %cache_hit_fn, %cache_hit ], [ %5, %cache_miss ]
|
||||
%7 = icmp eq ptr %fn_phi, null
|
||||
br i1 %7, label %missing_function, label %match
|
||||
|
||||
missing_function: ; preds = %6
|
||||
%8 = load ptr, ptr @std.core.builtin.panic, align 8
|
||||
call void %8(ptr @.panic_msg, i64 46, ptr @.file, i64 25, ptr @.func, i64 4, i32 13) #4
|
||||
unreachable
|
||||
match: ; preds = %7
|
||||
%10 = load ptr, ptr %s, align 8
|
||||
%11 = call i64 %fn_phi(ptr %retparam, ptr %10)
|
||||
%not_err = icmp eq i64 %11, 0
|
||||
%12 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %12, label %after_check, label %assign_optional
|
||||
|
||||
match: ; preds = %6
|
||||
%9 = load ptr, ptr %s, align 8
|
||||
%10 = call i64 %fn_phi(ptr %retparam, ptr %9)
|
||||
%not_err = icmp eq i64 %10, 0
|
||||
%11 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %11, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %match
|
||||
store i64 %11, ptr %c.f, align 8
|
||||
store i64 %10, ptr %c.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_check: ; preds = %match
|
||||
%13 = load i8, ptr %retparam, align 1
|
||||
store i8 %13, ptr %c, align 1
|
||||
%12 = load i8, ptr %retparam, align 1
|
||||
store i8 %12, ptr %c, align 1
|
||||
store i64 0, ptr %c.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_assign: ; preds = %after_check, %assign_optional
|
||||
br label %testblock
|
||||
|
||||
testblock: ; preds = %after_assign
|
||||
%optval = load i64, ptr %c.f, align 8
|
||||
%not_err2 = icmp eq i64 %optval, 0
|
||||
%14 = call i1 @llvm.expect.i1(i1 %not_err2, i1 true)
|
||||
br i1 %14, label %after_check4, label %assign_optional3
|
||||
assign_optional3: ; preds = %testblock
|
||||
%not_err1 = icmp eq i64 %optval, 0
|
||||
%13 = call i1 @llvm.expect.i1(i1 %not_err1, i1 true)
|
||||
br i1 %13, label %after_check3, label %assign_optional2
|
||||
|
||||
assign_optional2: ; preds = %testblock
|
||||
store i64 %optval, ptr %err, align 8
|
||||
br label %end_block
|
||||
after_check4: ; preds = %testblock
|
||||
|
||||
after_check3: ; preds = %testblock
|
||||
store i64 0, ptr %err, align 8
|
||||
br label %end_block
|
||||
end_block: ; preds = %after_check4, %assign_optional3
|
||||
%15 = load i64, ptr %err, align 8
|
||||
%i2b = icmp ne i64 %15, 0
|
||||
|
||||
end_block: ; preds = %after_check3, %assign_optional2
|
||||
%14 = load i64, ptr %err, align 8
|
||||
%i2b = icmp ne i64 %14, 0
|
||||
br i1 %i2b, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %end_block
|
||||
%16 = load i64, ptr %err, align 8
|
||||
store i64 %16, ptr %error_var, align 8
|
||||
%15 = load i64, ptr %err, align 8
|
||||
store i64 %15, ptr %error_var, align 8
|
||||
br label %panic_block
|
||||
|
||||
if.exit: ; preds = %end_block
|
||||
br label %noerr_block
|
||||
|
||||
panic_block: ; preds = %if.then
|
||||
%17 = insertvalue %any undef, ptr %error_var, 0
|
||||
%18 = insertvalue %any %17, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %any %18, ptr %varargslots, align 16
|
||||
%19 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %19, i64 1, 1
|
||||
%16 = insertvalue %any undef, ptr %error_var, 0
|
||||
%17 = insertvalue %any %16, i64 ptrtoint (ptr @"$ct.fault" to i64), 1
|
||||
store %any %17, ptr %varargslots, align 16
|
||||
%18 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %18, i64 1, 1
|
||||
store %"any[]" %"$$temp", ptr %indirectarg, align 8
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36, ptr @.file, i64 25, ptr @.func, i64 4, i32 8, ptr byval(%"any[]") align 8 %indirectarg)
|
||||
call void @std.core.builtin.panicf(ptr @.panic_msg.1, i64 36,
|
||||
unreachable
|
||||
|
||||
noerr_block: ; preds = %if.exit
|
||||
ret void
|
||||
}
|
||||
33
test/unit/regression/interface_inheritance.c3
Normal file
33
test/unit/regression/interface_inheritance.c3
Normal file
@@ -0,0 +1,33 @@
|
||||
module inherit_interface;
|
||||
import std;
|
||||
interface Test
|
||||
{
|
||||
fn int x();
|
||||
}
|
||||
|
||||
struct Foo (Test)
|
||||
{
|
||||
int z;
|
||||
}
|
||||
|
||||
fn int Foo.x(&self) @dynamic
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
struct Baz
|
||||
{
|
||||
inline Bar b;
|
||||
}
|
||||
|
||||
struct Bar
|
||||
{
|
||||
inline Foo f;
|
||||
}
|
||||
|
||||
fn void test_inheritance() @test
|
||||
{
|
||||
Baz x;
|
||||
Test t = &x;
|
||||
test::eq(t.x(), 42);
|
||||
}
|
||||
Reference in New Issue
Block a user