mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-23 10:50:58 +00:00
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:
parent
3897142038
commit
0c3aeb30aa
9 changed files with 46 additions and 7 deletions
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue