Reuse tempary variables.

Now that I've got nice code, it was worth doing. Unfortunatly, bsearch
style switch statements have problems.
switch.r:14: BUG: temp users went negative: <tmp 0x21b6840:-1>
switch.r:14: BUG: temp users went negative: <tmp 0x21b6840:-2>
switch.r:14: BUG: temp users went negative: <tmp 0x21b6840:-3>
switch.r:14: BUG: temp users went negative: <tmp 0x21b67d0:-1>
This commit is contained in:
Bill Currie 2012-11-18 19:08:16 +09:00
parent 3897142038
commit 0c3aeb30aa
9 changed files with 46 additions and 7 deletions

View file

@ -77,6 +77,7 @@ def_t *new_def (const char *name, struct type_s *type,
struct defspace_s *space, storage_class_t storage);
def_t *alias_def (def_t *def, struct type_s *type);
def_t *temp_def (etype_t type, int size);
void free_temp_def (def_t *temp);
void free_def (def_t *def);
void def_to_ddef (def_t *def, ddef_t *ddef, int aux);

View file

@ -67,6 +67,7 @@ typedef struct function_s {
string_t s_file; ///< source file with definition
string_t s_name; ///< name of function in output
int temp_num; ///< number for next temp var
struct def_s *temp_defs[4]; ///< freed temp vars (by size)
struct def_s *def; ///< output def holding function number
struct symbol_s *sym; ///< internal symbol for this function
/** Root scope symbol table of the function.

View file

@ -45,6 +45,7 @@ typedef struct {
struct def_s *def;
struct flowvar_s *flowvar;
struct daglabel_s *daglabel;
int users;
} tempop_t;
typedef struct operand_s {

View file

@ -498,6 +498,10 @@ make_operand (dag_t *dag, sblock_t *block, const dagnode_t *dagnode, int index)
operand_t *op;
op = dagnode->children[index]->value;
while (op->op_type == op_alias)
op = op->o.alias;
if (op->op_type == op_temp)
op->o.tempop.users++;
op = fix_op_type (op, dagnode->types[index]);
return op;
}
@ -525,6 +529,7 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
operands[1] = make_operand (dag, block, dagnode, 1);
if (!(var_iter = set_first (dagnode->identifiers))) {
operands[2] = temp_operand (get_type (dagnode->label->expr));
operands[2]->o.tempop.users++;
} else {
daglabel_t *var = dag->labels[var_iter->member];
etype_t type = extract_type (dagnode->label->expr);

View file

@ -162,6 +162,11 @@ temp_def (etype_t type, int size)
def_t *temp;
defspace_t *space = current_func->symtab->space;
if ((temp = current_func->temp_defs[size - 1])) {
current_func->temp_defs[size - 1] = temp->next;
temp->next = 0;
return temp;
}
ALLOC (16384, def_t, defs, temp);
temp->return_addr = __builtin_return_address (0);
temp->name = save_string (va (".tmp%d", current_func->temp_num++));
@ -176,6 +181,14 @@ temp_def (etype_t type, int size)
return temp;
}
void
free_temp_def (def_t *temp)
{
int size = type_size (temp->type) - 1;
temp->next = current_func->temp_defs[size];
current_func->temp_defs[size] = temp;
}
void
free_def (def_t *def)
{

View file

@ -46,6 +46,7 @@
#include "dags.h"
#include "set.h"
#include "statements.h"
#include "strpool.h"
#include "symtab.h"
#include "type.h"
@ -123,7 +124,7 @@ print_node (dstring_t *dstr, dag_t *dag, dagnode_t *node)
for (id_iter = set_first (node->identifiers); id_iter;
id_iter = set_next (id_iter)) {
id = dag->labels[id_iter->member];
dasprintf (dstr, " %s", daglabel_string(id));
dasprintf (dstr, " %s", html_string (daglabel_string(id)));
}
dasprintf (dstr, " </td>");
dasprintf (dstr, " </tr>\n");

View file

@ -171,16 +171,33 @@ add_statement_op_ref (operand_t *op, dstatement_t *st, int field)
}
}
static void
use_tempop (operand_t *op)
{
if (!op || op->op_type != op_temp)
return;
if (--op->o.tempop.users == 0)
free_temp_def (op->o.tempop.def);
if (op->o.tempop.users <= -1)
bug (0, "temp users went negative: %s", operand_string (op));
}
static void
emit_statement (statement_t *statement)
{
const char *opcode = statement->opcode;
def_t *def_a = get_operand_def (statement->expr, statement->opa);
def_t *def_b = get_operand_def (statement->expr, statement->opb);
def_t *def_c = get_operand_def (statement->expr, statement->opc);
opcode_t *op = opcode_find (opcode, def_a, def_b, def_c);
def_t *def_a, *def_b, *def_c;
opcode_t *op;
dstatement_t *s;
def_a = get_operand_def (statement->expr, statement->opa);
use_tempop (statement->opa);
def_b = get_operand_def (statement->expr, statement->opb);
use_tempop (statement->opb);
def_c = get_operand_def (statement->expr, statement->opc);
use_tempop (statement->opc);
op = opcode_find (opcode, def_a, def_b, def_c);
if (!op) {
print_expr (statement->expr);
print_statement (statement);

View file

@ -435,7 +435,7 @@ flow_generate (flowgraph_t *graph)
// generate new statements from the dag;
dag_generate (node->dag, block);
}
//dump_dot ("post", code, dump_dot_sblock);
dump_dot ("post", code, dump_dot_sblock);
return code;
}

View file

@ -108,7 +108,7 @@ operand_string (operand_t *op)
case op_label:
return op->o.label->name;
case op_temp:
return va ("tmp %p", op);
return va ("<tmp %p:%d>", op, op->o.tempop.users);
case op_pointer:
type = op->o.value->v.pointer.type;
if (op->o.value->v.pointer.def)