ir_function_create_block now takes a lex_ctx instead of copying from the function; ast_ternary: need to remember the _end_ block of the 2 expressions because that's where the jump is actually supposed to be

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-25 23:48:29 +01:00
parent d70fcdec42
commit 23e0637e85
3 changed files with 31 additions and 27 deletions

52
ast.c
View file

@ -1437,7 +1437,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
return false; return false;
} }
self->curblock = ir_function_create_block(irf, "entry"); self->curblock = ir_function_create_block(ast_ctx(self), irf, "entry");
if (!self->curblock) { if (!self->curblock) {
asterror(ast_ctx(self), "failed to allocate entry block for `%s`", self->name); asterror(ast_ctx(self), "failed to allocate entry block for `%s`", self->name);
return false; return false;
@ -1662,7 +1662,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
*/ */
merge_id = vec_size(func->ir_func->blocks); merge_id = vec_size(func->ir_func->blocks);
merge = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_merge")); merge = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_merge"));
cgen = self->left->expression.codegen; cgen = self->left->expression.codegen;
if (!(*cgen)((ast_expression*)(self->left), func, false, &left)) if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
@ -1680,7 +1680,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
} }
from_left = func->curblock; from_left = func->curblock;
other = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_other")); other = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_other"));
if ( !(self->op == INSTR_OR) != !OPTS_FLAG(PERL_LOGIC) ) { if ( !(self->op == INSTR_OR) != !OPTS_FLAG(PERL_LOGIC) ) {
if (!ir_block_create_if(func->curblock, left, other, merge)) if (!ir_block_create_if(func->curblock, left, other, merge))
return false; return false;
@ -2108,7 +2108,7 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va
if (self->on_true) { if (self->on_true) {
/* create on-true block */ /* create on-true block */
ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "ontrue")); ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "ontrue"));
if (!ontrue) if (!ontrue)
return false; return false;
@ -2128,7 +2128,7 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va
/* on-false path */ /* on-false path */
if (self->on_false) { if (self->on_false) {
/* create on-false block */ /* create on-false block */
onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "onfalse")); onfalse = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "onfalse"));
if (!onfalse) if (!onfalse)
return false; return false;
@ -2146,7 +2146,7 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va
onfalse = NULL; onfalse = NULL;
/* Merge block were they all merge in to */ /* Merge block were they all merge in to */
merge = ir_function_create_block(func->ir_func, ast_function_label(func, "endif")); merge = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "endif"));
if (!merge) if (!merge)
return false; return false;
/* add jumps ot the merge block */ /* add jumps ot the merge block */
@ -2179,8 +2179,8 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
ir_instr *phi; ir_instr *phi;
ir_block *cond = func->curblock; ir_block *cond = func->curblock;
ir_block *ontrue; ir_block *ontrue, *ontrue_out = NULL;
ir_block *onfalse; ir_block *onfalse, *onfalse_out = NULL;
ir_block *merge; ir_block *merge;
/* Ternary can never create an lvalue... */ /* Ternary can never create an lvalue... */
@ -2206,7 +2206,7 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
return false; return false;
/* create on-true block */ /* create on-true block */
ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_T")); ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_T"));
if (!ontrue) if (!ontrue)
return false; return false;
else else
@ -2218,10 +2218,12 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
cgen = self->on_true->expression.codegen; cgen = self->on_true->expression.codegen;
if (!(*cgen)((ast_expression*)(self->on_true), func, false, &trueval)) if (!(*cgen)((ast_expression*)(self->on_true), func, false, &trueval))
return false; return false;
ontrue_out = func->curblock;
} }
/* create on-false block */ /* create on-false block */
onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_F")); onfalse = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_F"));
if (!onfalse) if (!onfalse)
return false; return false;
else else
@ -2233,16 +2235,18 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
cgen = self->on_false->expression.codegen; cgen = self->on_false->expression.codegen;
if (!(*cgen)((ast_expression*)(self->on_false), func, false, &falseval)) if (!(*cgen)((ast_expression*)(self->on_false), func, false, &falseval))
return false; return false;
onfalse_out = func->curblock;
} }
/* create merge block */ /* create merge block */
merge = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_out")); merge = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_out"));
if (!merge) if (!merge)
return false; return false;
/* jump to merge block */ /* jump to merge block */
if (!ir_block_create_jump(ontrue, merge)) if (!ir_block_create_jump(ontrue_out, merge))
return false; return false;
if (!ir_block_create_jump(onfalse, merge)) if (!ir_block_create_jump(onfalse_out, merge))
return false; return false;
/* create if instruction */ /* create if instruction */
@ -2264,8 +2268,8 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype); phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype);
if (!phi) if (!phi)
return false; return false;
ir_phi_add(phi, ontrue, trueval); ir_phi_add(phi, ontrue_out, trueval);
ir_phi_add(phi, onfalse, falseval); ir_phi_add(phi, onfalse_out, falseval);
self->expression.outr = ir_phi_value(phi); self->expression.outr = ir_phi_value(phi);
*out = self->expression.outr; *out = self->expression.outr;
@ -2336,7 +2340,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
*/ */
if (self->precond) if (self->precond)
{ {
bprecond = ir_function_create_block(func->ir_func, ast_function_label(func, "pre_loop_cond")); bprecond = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "pre_loop_cond"));
if (!bprecond) if (!bprecond)
return false; return false;
@ -2360,7 +2364,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
* generate them this early for 'break' and 'continue'. * generate them this early for 'break' and 'continue'.
*/ */
if (self->increment) { if (self->increment) {
bincrement = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_increment")); bincrement = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "loop_increment"));
if (!bincrement) if (!bincrement)
return false; return false;
bcontinue = bincrement; /* increment comes before the pre-loop-condition */ bcontinue = bincrement; /* increment comes before the pre-loop-condition */
@ -2369,7 +2373,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
} }
if (self->postcond) { if (self->postcond) {
bpostcond = ir_function_create_block(func->ir_func, ast_function_label(func, "post_loop_cond")); bpostcond = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "post_loop_cond"));
if (!bpostcond) if (!bpostcond)
return false; return false;
bcontinue = bpostcond; /* postcond comes before the increment */ bcontinue = bpostcond; /* postcond comes before the increment */
@ -2378,7 +2382,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
} }
bout_id = vec_size(func->ir_func->blocks); bout_id = vec_size(func->ir_func->blocks);
bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_loop")); bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_loop"));
if (!bout) if (!bout)
return false; return false;
bbreak = bout; bbreak = bout;
@ -2386,7 +2390,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
/* The loop body... */ /* The loop body... */
if (self->body) if (self->body)
{ {
bbody = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_body")); bbody = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "loop_body"));
if (!bbody) if (!bbody)
return false; return false;
@ -2577,7 +2581,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
} }
bout_id = vec_size(func->ir_func->blocks); bout_id = vec_size(func->ir_func->blocks);
bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_switch")); bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_switch"));
if (!bout) if (!bout)
return false; return false;
@ -2604,9 +2608,9 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
if (!cond) if (!cond)
return false; return false;
bcase = ir_function_create_block(func->ir_func, ast_function_label(func, "case")); bcase = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "case"));
bnot_id = vec_size(func->ir_func->blocks); bnot_id = vec_size(func->ir_func->blocks);
bnot = ir_function_create_block(func->ir_func, ast_function_label(func, "not_case")); bnot = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "not_case"));
if (!bcase || !bnot) if (!bcase || !bnot)
return false; return false;
if (!ir_block_create_if(func->curblock, cond, bcase, bnot)) if (!ir_block_create_if(func->curblock, cond, bcase, bnot))
@ -2696,7 +2700,7 @@ bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_valu
} }
/* simply create a new block and jump to it */ /* simply create a new block and jump to it */
self->irblock = ir_function_create_block(func->ir_func, self->name); self->irblock = ir_function_create_block(ast_ctx(self), func->ir_func, self->name);
if (!self->irblock) { if (!self->irblock) {
asterror(ast_ctx(self), "failed to allocate label block `%s`", self->name); asterror(ast_ctx(self), "failed to allocate label block `%s`", self->name);
return false; return false;

4
ir.c
View file

@ -516,10 +516,10 @@ void ir_function_collect_value(ir_function *self, ir_value *v)
vec_push(self->values, v); vec_push(self->values, v);
} }
ir_block* ir_function_create_block(ir_function *self, const char *label) ir_block* ir_function_create_block(lex_ctx ctx, ir_function *self, const char *label)
{ {
ir_block* bn = ir_block_new(self, label); ir_block* bn = ir_block_new(self, label);
memcpy(&bn->context, &self->context, sizeof(self->context)); bn->context = ctx;
vec_push(self->blocks, bn); vec_push(self->blocks, bn);
return bn; return bn;
} }

2
ir.h
View file

@ -280,7 +280,7 @@ bool ir_function_enumerate(ir_function*);
bool ir_function_calculate_liferanges(ir_function*); bool ir_function_calculate_liferanges(ir_function*);
*/ */
ir_block* ir_function_create_block(ir_function*, const char *label); ir_block* ir_function_create_block(lex_ctx ctx, ir_function*, const char *label);
void ir_function_dump(ir_function*, char *ind, int (*oprintf)(const char*,...)); void ir_function_dump(ir_function*, char *ind, int (*oprintf)(const char*,...));