mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-27 14:12:36 +00:00
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:
parent
d70fcdec42
commit
23e0637e85
3 changed files with 31 additions and 27 deletions
52
ast.c
52
ast.c
|
@ -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
4
ir.c
|
@ -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
2
ir.h
|
@ -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*,...));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue