mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 15:01:41 +00:00
Give labels a usage count to detect unused labels.
This commit is contained in:
parent
90640614ef
commit
c5ecc170b6
5 changed files with 41 additions and 17 deletions
|
@ -74,6 +74,7 @@ typedef struct ex_label_s {
|
|||
struct reloc_s *refs; ///< relocations associated with this label
|
||||
struct sblock_s *dest; ///< the location of this label if known
|
||||
const char *name; ///< the name of this label
|
||||
int used; ///< label is used as a target
|
||||
} ex_label_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -548,6 +549,8 @@ expr_t *build_function_call (expr_t *fexpr, struct type_s *ftype,
|
|||
expr_t *params);
|
||||
expr_t *function_expr (expr_t *e1, expr_t *e2);
|
||||
struct function_s;
|
||||
expr_t *branch_expr (int op, expr_t *test, expr_t *label);
|
||||
expr_t *goto_expr (expr_t *label);
|
||||
expr_t *return_expr (struct function_s *f, expr_t *e);
|
||||
expr_t *conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2);
|
||||
expr_t *incop_expr (int op, expr_t *e, int postop);
|
||||
|
|
|
@ -1081,15 +1081,15 @@ convert_bool (expr_t *e, int block)
|
|||
if (e->type == ex_error)
|
||||
return e;
|
||||
if (is_integer_val (e)) {
|
||||
b = new_unary_expr ('g', 0);
|
||||
b = goto_expr (0);
|
||||
if (expr_integer (e))
|
||||
e = new_bool_expr (make_list (b), 0, b);
|
||||
else
|
||||
e = new_bool_expr (0, make_list (b), b);
|
||||
} else {
|
||||
b = new_block_expr ();
|
||||
append_expr (b, new_binary_expr ('i', e, 0));
|
||||
append_expr (b, new_unary_expr ('g', 0));
|
||||
append_expr (b, branch_expr ('i', e, 0));
|
||||
append_expr (b, goto_expr (0));
|
||||
e = new_bool_expr (make_list (b->e.block.head),
|
||||
make_list (b->e.block.head->next), b);
|
||||
}
|
||||
|
@ -1818,6 +1818,26 @@ function_expr (expr_t *fexpr, expr_t *params)
|
|||
return build_function_call (fexpr, ftype, params);
|
||||
}
|
||||
|
||||
expr_t *
|
||||
branch_expr (int op, expr_t *test, expr_t *label)
|
||||
{
|
||||
if (label && label->type != ex_label)
|
||||
internal_error (label, "not a label");
|
||||
if (label)
|
||||
label->e.label.used++;
|
||||
return new_binary_expr (op, test, label);
|
||||
}
|
||||
|
||||
expr_t *
|
||||
goto_expr (expr_t *label)
|
||||
{
|
||||
if (label && label->type != ex_label)
|
||||
internal_error (label, "not a label");
|
||||
if (label)
|
||||
label->e.label.used++;
|
||||
return new_unary_expr ('g', label);
|
||||
}
|
||||
|
||||
expr_t *
|
||||
return_expr (function_t *f, expr_t *e)
|
||||
{
|
||||
|
@ -1913,7 +1933,7 @@ conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2)
|
|||
append_expr (block, assign_expr (block->e.block.result, e2));
|
||||
else
|
||||
append_expr (block, e2);
|
||||
append_expr (block, new_unary_expr ('g', elabel));
|
||||
append_expr (block, goto_expr (elabel));
|
||||
append_expr (block, tlabel);
|
||||
if (block->e.block.result)
|
||||
append_expr (block, assign_expr (block->e.block.result, e1));
|
||||
|
@ -2124,7 +2144,7 @@ build_if_statement (expr_t *test, expr_t *s1, expr_t *s2)
|
|||
|
||||
if (s2) {
|
||||
expr_t *nl = new_label_expr ();
|
||||
append_expr (if_expr, new_unary_expr ('g', nl));
|
||||
append_expr (if_expr, goto_expr (nl));
|
||||
|
||||
append_expr (if_expr, fl);
|
||||
append_expr (if_expr, s2);
|
||||
|
@ -2154,7 +2174,7 @@ build_while_statement (expr_t *test, expr_t *statement,
|
|||
|
||||
while_expr = new_block_expr ();
|
||||
|
||||
append_expr (while_expr, new_unary_expr ('g', continue_label));
|
||||
append_expr (while_expr, goto_expr (continue_label));
|
||||
append_expr (while_expr, l1);
|
||||
append_expr (while_expr, statement);
|
||||
append_expr (while_expr, continue_label);
|
||||
|
@ -2234,7 +2254,7 @@ build_for_statement (expr_t *init, expr_t *test, expr_t *next,
|
|||
append_expr (for_expr, init);
|
||||
if (test) {
|
||||
l1 = new_label_expr ();
|
||||
append_expr (for_expr, new_unary_expr ('g', l1));
|
||||
append_expr (for_expr, goto_expr (l1));
|
||||
}
|
||||
append_expr (for_expr, tl);
|
||||
append_expr (for_expr, statement);
|
||||
|
@ -2250,7 +2270,7 @@ build_for_statement (expr_t *init, expr_t *test, expr_t *next,
|
|||
append_expr (for_expr, test);
|
||||
}
|
||||
} else {
|
||||
append_expr (for_expr, new_unary_expr ('g', tl));
|
||||
append_expr (for_expr, goto_expr (tl));
|
||||
append_expr (for_expr, fl);
|
||||
}
|
||||
|
||||
|
|
|
@ -1000,7 +1000,7 @@ statement
|
|||
{
|
||||
$$ = 0;
|
||||
if (break_label)
|
||||
$$ = new_unary_expr ('g', break_label);
|
||||
$$ = goto_expr (break_label);
|
||||
else
|
||||
error (0, "break outside of loop or switch");
|
||||
}
|
||||
|
@ -1008,7 +1008,7 @@ statement
|
|||
{
|
||||
$$ = 0;
|
||||
if (continue_label)
|
||||
$$ = new_unary_expr ('g', continue_label);
|
||||
$$ = goto_expr (continue_label);
|
||||
else
|
||||
error (0, "continue outside of loop");
|
||||
}
|
||||
|
|
|
@ -1054,6 +1054,7 @@ make_statements (expr_t *e)
|
|||
statement_slist (sblock, e);
|
||||
// print_flow (sblock);
|
||||
remove_dead_blocks (sblock);
|
||||
// print_flow (sblock);
|
||||
check_final_block (sblock);
|
||||
// print_flow (sblock);
|
||||
return sblock;
|
||||
|
|
|
@ -271,7 +271,7 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
|
|||
expr_t *low_label = default_label;
|
||||
|
||||
if (!tree) {
|
||||
branch = new_unary_expr ('g', default_label);
|
||||
branch = goto_expr (default_label);
|
||||
append_expr (sw, branch);
|
||||
return;
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
|
|||
append_expr (sw, test);
|
||||
|
||||
if (tree->low == tree->high) {
|
||||
branch = new_binary_expr ('n', temp, tree->labels[0]);
|
||||
branch = branch_expr ('n', temp, tree->labels[0]);
|
||||
append_expr (sw, branch);
|
||||
|
||||
if (tree->left) {
|
||||
|
@ -326,7 +326,7 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
|
|||
}
|
||||
//FIXME unsigned int
|
||||
test = binary_expr (GT, cast_expr (&type_integer, temp), range);
|
||||
branch = new_binary_expr ('i', test, high_label);
|
||||
branch = branch_expr ('i', test, high_label);
|
||||
append_expr (sw, branch);
|
||||
branch = new_binary_expr ('g', table, temp);
|
||||
append_expr (sw, branch);
|
||||
|
@ -342,6 +342,7 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
|
|||
def_t loc;
|
||||
loc.space = sym->s.def->space;
|
||||
loc.offset = sym->s.def->offset + i;
|
||||
tree->labels[i]->e.label.used++;
|
||||
reloc_def_op (&tree->labels[i]->e.label, &loc);
|
||||
}
|
||||
}
|
||||
|
@ -373,7 +374,7 @@ switch_expr (switch_block_t *switch_block, expr_t *break_label,
|
|||
default_label = &_default_label;
|
||||
default_label->label = break_label;
|
||||
}
|
||||
default_expr = new_unary_expr ('g', default_label->label);
|
||||
default_expr = goto_expr (default_label->label);
|
||||
|
||||
append_expr (sw, assign_expr (sw_val, switch_block->test));
|
||||
|
||||
|
@ -385,9 +386,8 @@ switch_expr (switch_block_t *switch_block, expr_t *break_label,
|
|||
|| num_labels < 8) {
|
||||
for (l = labels; *l; l++) {
|
||||
expr_t *cmp = binary_expr (EQ, sw_val, (*l)->value);
|
||||
expr_t *test = new_binary_expr ('i',
|
||||
test_expr (cmp),
|
||||
(*l)->label);
|
||||
expr_t *test = branch_expr ('i', test_expr (cmp),
|
||||
(*l)->label);
|
||||
|
||||
append_expr (sw, test);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue