Skip to content

Commit

Permalink
Refactor GC trace generation in the compiler
Browse files Browse the repository at this point in the history
- Add a new trace pattern, static tracing. This is used when tracing a
nominal type in order to trace it in the most efficient way possible
(type in the sending context and capability in the receiving context).
- Enhance dynamic tracing of nominal types with that same
type/capability logic.
- Trace boxed tuples correctly.
  • Loading branch information
Benoit Vey committed Feb 15, 2017
1 parent ab41349 commit 05bf6e4
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 116 deletions.
18 changes: 11 additions & 7 deletions src/libponyc/codegen/gencall.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,8 @@ LLVMValueRef gen_funptr(compile_t* c, ast_t* ast)
return funptr;
}

void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[],
ast_t* args_ast)
void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef orig_args[],
LLVMValueRef cast_args[], ast_t* args_ast)
{
// Allocate the message, setting its size and ID.
size_t msg_size = (size_t)LLVMABISizeOfType(c->target_data, m->msg_type);
Expand All @@ -376,7 +376,7 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[],
for(unsigned int i = 0; i < m->param_count; i++)
{
LLVMValueRef arg_ptr = LLVMBuildStructGEP(c->builder, msg_ptr, i + 3, "");
LLVMBuildStore(c->builder, args[i+1], arg_ptr);
LLVMBuildStore(c->builder, cast_args[i+1], arg_ptr);
}

// Trace while populating the message contents.
Expand Down Expand Up @@ -407,7 +407,8 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[],

for(size_t i = 0; i < m->param_count; i++)
{
gentrace(c, ctx, args[i+1], ast_type(arg_ast), ast_type(param));
gentrace(c, ctx, orig_args[i+1], cast_args[i+1], ast_type(arg_ast),
ast_type(param));
param = ast_sibling(param);
arg_ast = ast_sibling(arg_ast);
}
Expand All @@ -417,7 +418,7 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[],

// Send the message.
msg_args[0] = ctx;
msg_args[1] = LLVMBuildBitCast(c->builder, args[0], c->object_ptr, "");
msg_args[1] = LLVMBuildBitCast(c->builder, cast_args[0], c->object_ptr, "");
msg_args[2] = msg;
gencall_runtime(c, "pony_sendv", msg_args, 3, "");
}
Expand Down Expand Up @@ -688,9 +689,11 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast)
{
// If we're sending a message, trace and send here instead of calling the
// sender to trace the most specific types possible.
LLVMValueRef* cast_args = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size);
cast_args[0] = args[0];
while(arg != NULL)
{
args[i] = gen_assign_cast(c, params[i], args[i], ast_type(arg));
cast_args[i] = gen_assign_cast(c, params[i], args[i], ast_type(arg));
arg = ast_sibling(arg);
i++;
}
Expand All @@ -699,7 +702,7 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast)
reach_method_t* m = reach_method(t, cap, method_name, typeargs);

codegen_debugloc(c, ast);
gen_send_message(c, m, args, positional);
gen_send_message(c, m, args, cast_args, positional);
codegen_debugloc(c, NULL);
switch(ast_id(postfix))
{
Expand All @@ -712,6 +715,7 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast)
r = c->none_instance;
break;
}
ponyint_pool_free_size(buf_size, cast_args);
} else {
while(arg != NULL)
{
Expand Down
4 changes: 2 additions & 2 deletions src/libponyc/codegen/gencall.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

PONY_EXTERN_C_BEGIN

void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[],
ast_t* args_ast);
void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef orig_args[],
LLVMValueRef cast_args[], ast_t* args_ast);

LLVMValueRef gen_funptr(compile_t* c, ast_t* ast);

Expand Down
10 changes: 6 additions & 4 deletions src/libponyc/codegen/genfun.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params,

while(param != NULL)
{
if(gentrace_needed(c, ast_type(param), NULL))
ast_t* param_type = ast_type(param);
if(gentrace_needed(c, param_type, param_type))
{
need_trace = true;
break;
Expand All @@ -273,7 +274,8 @@ static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params,

for(int i = 1; i < count; i++)
{
gentrace(c, ctx, args[i], ast_type(param), NULL);
ast_t* param_type = ast_type(param);
gentrace(c, ctx, args[i], args[i], param_type, param_type);
param = ast_sibling(param);
}

Expand Down Expand Up @@ -387,7 +389,7 @@ static bool genfun_be(compile_t* c, reach_type_t* t, reach_method_t* m)
LLVMGetParams(m->func, param_vals);

// Send the arguments in a message to 'this'.
gen_send_message(c, m, param_vals, params);
gen_send_message(c, m, param_vals, param_vals, params);

// Return None.
LLVMBuildRet(c->builder, c->none_instance);
Expand Down Expand Up @@ -462,7 +464,7 @@ static bool genfun_newbe(compile_t* c, reach_type_t* t, reach_method_t* m)
LLVMGetParams(m->func, param_vals);

// Send the arguments in a message to 'this'.
gen_send_message(c, m, param_vals, params);
gen_send_message(c, m, param_vals, param_vals, params);

// Return 'this'.
LLVMBuildRet(c->builder, param_vals[0]);
Expand Down
4 changes: 2 additions & 2 deletions src/libponyc/codegen/genprim.c
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ static void trace_array_elements(compile_t* c, reach_type_t* t,
ast_t* typeargs = ast_childidx(t->ast, 2);
ast_t* typearg = ast_child(typeargs);

if(!gentrace_needed(c, typearg, NULL))
if(!gentrace_needed(c, typearg, typearg))
return;

reach_type_t* t_elem = reach_type(c->reach, typearg);
Expand Down Expand Up @@ -695,7 +695,7 @@ static void trace_array_elements(compile_t* c, reach_type_t* t,
LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(c->builder, pointer, &phi, 1,
"");
LLVMValueRef elem = LLVMBuildLoad(c->builder, elem_ptr, "");
gentrace(c, ctx, elem, typearg, NULL);
gentrace(c, ctx, elem, elem, typearg, typearg);

// Add one to the phi node and branch back to the cond block.
LLVMValueRef one = LLVMConstInt(c->intptr, 1, false);
Expand Down
Loading

0 comments on commit 05bf6e4

Please sign in to comment.