mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-06-01 09:02:08 +00:00
Strip aliases off daglabel operands.
However, the original type of the operand, as seen by the statement, is kept. Mostly works, but has some problems with plistmenu.r
This commit is contained in:
parent
c1a5c1a7b2
commit
012a521dc5
2 changed files with 110 additions and 30 deletions
|
@ -35,6 +35,8 @@
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
#include "QF/pr_comp.h"
|
||||||
|
|
||||||
struct dstring_s;
|
struct dstring_s;
|
||||||
struct flownode_s;
|
struct flownode_s;
|
||||||
struct sblock_s;
|
struct sblock_s;
|
||||||
|
@ -57,6 +59,7 @@ typedef struct dagnode_s {
|
||||||
int is_child; ///< true if a child node
|
int is_child; ///< true if a child node
|
||||||
int cost; ///< cost of this node in temp vars
|
int cost; ///< cost of this node in temp vars
|
||||||
daglabel_t *label; ///< ident/const if leaf node, or operator
|
daglabel_t *label; ///< ident/const if leaf node, or operator
|
||||||
|
struct statement_s *statement; ///< statement generating this node
|
||||||
/// \name child nodes
|
/// \name child nodes
|
||||||
/// All three child nodes will be null if this node is a leaf
|
/// All three child nodes will be null if this node is a leaf
|
||||||
/// If \a a is null, both \a b and \a c must also be null. If \a is not
|
/// If \a a is null, both \a b and \a c must also be null. If \a is not
|
||||||
|
@ -66,9 +69,8 @@ typedef struct dagnode_s {
|
||||||
/// \a b and \a c are used to help keep track of the original statement
|
/// \a b and \a c are used to help keep track of the original statement
|
||||||
/// operands
|
/// operands
|
||||||
//@{
|
//@{
|
||||||
struct dagnode_s *a;
|
struct dagnode_s *a, *b, *c;
|
||||||
struct dagnode_s *b;
|
etype_t ta, tb, tc; ///< desired type of each operand (to alias)
|
||||||
struct dagnode_s *c;
|
|
||||||
//@}
|
//@}
|
||||||
daglabel_t *identifiers; ///< list of identifiers with value of this node
|
daglabel_t *identifiers; ///< list of identifiers with value of this node
|
||||||
} dagnode_t;
|
} dagnode_t;
|
||||||
|
|
|
@ -125,39 +125,37 @@ opcode_label (const char *opcode)
|
||||||
static daglabel_t *
|
static daglabel_t *
|
||||||
operand_label (operand_t *op)
|
operand_label (operand_t *op)
|
||||||
{
|
{
|
||||||
operand_t *o;
|
|
||||||
symbol_t *sym = 0;
|
symbol_t *sym = 0;
|
||||||
ex_value_t *val = 0;
|
ex_value_t *val = 0;
|
||||||
daglabel_t *label;
|
daglabel_t *label;
|
||||||
|
|
||||||
if (!op)
|
if (!op)
|
||||||
return 0;
|
return 0;
|
||||||
o = op;
|
while (op->op_type == op_alias)
|
||||||
while (o->op_type == op_alias)
|
op = op->o.alias;
|
||||||
o = o->o.alias;
|
|
||||||
|
|
||||||
if (o->op_type == op_temp) {
|
if (op->op_type == op_temp) {
|
||||||
if (o->o.tempop.daglabel)
|
if (op->o.tempop.daglabel)
|
||||||
return o->o.tempop.daglabel;
|
return op->o.tempop.daglabel;
|
||||||
label = new_label ();
|
label = new_label ();
|
||||||
label->op = op;
|
label->op = op;
|
||||||
o->o.tempop.daglabel = label;
|
op->o.tempop.daglabel = label;
|
||||||
} else if (o->op_type == op_symbol) {
|
} else if (op->op_type == op_symbol) {
|
||||||
sym = o->o.symbol;
|
sym = op->o.symbol;
|
||||||
if (sym->daglabel)
|
if (sym->daglabel)
|
||||||
return sym->daglabel;
|
return sym->daglabel;
|
||||||
label = new_label ();
|
label = new_label ();
|
||||||
label->op = op;
|
label->op = op;
|
||||||
sym->daglabel = label;
|
sym->daglabel = label;
|
||||||
} else if (o->op_type == op_value || o->op_type == op_pointer) {
|
} else if (op->op_type == op_value || op->op_type == op_pointer) {
|
||||||
val = o->o.value;
|
val = op->o.value;
|
||||||
if (val->daglabel)
|
if (val->daglabel)
|
||||||
return val->daglabel;
|
return val->daglabel;
|
||||||
label = new_label ();
|
label = new_label ();
|
||||||
label->op = op;
|
label->op = op;
|
||||||
val->daglabel = label;
|
val->daglabel = label;
|
||||||
} else {
|
} else {
|
||||||
internal_error (0, "unexpected operand type: %d", o->op_type);
|
internal_error (0, "unexpected operand type: %d", op->op_type);
|
||||||
}
|
}
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
@ -180,23 +178,21 @@ leaf_node (operand_t *op)
|
||||||
static dagnode_t *
|
static dagnode_t *
|
||||||
node (operand_t *op)
|
node (operand_t *op)
|
||||||
{
|
{
|
||||||
operand_t *o;
|
|
||||||
symbol_t *sym;
|
symbol_t *sym;
|
||||||
|
|
||||||
if (!op)
|
if (!op)
|
||||||
return 0;
|
return 0;
|
||||||
o = op;
|
while (op->op_type == op_alias)
|
||||||
while (o->op_type == op_alias)
|
op = op->o.alias;
|
||||||
o = o->o.alias;
|
if (op->op_type == op_symbol) {
|
||||||
if (o->op_type == op_symbol) {
|
sym = op->o.symbol;
|
||||||
sym = o->o.symbol;
|
|
||||||
if (sym->sy_type == sy_const)
|
if (sym->sy_type == sy_const)
|
||||||
return 0;
|
return 0;
|
||||||
if (sym->daglabel)
|
if (sym->daglabel)
|
||||||
return sym->daglabel->dagnode;
|
return sym->daglabel->dagnode;
|
||||||
} else if (o->op_type == op_temp) {
|
} else if (op->op_type == op_temp) {
|
||||||
if (o->o.tempop.daglabel)
|
if (op->o.tempop.daglabel)
|
||||||
return o->o.tempop.daglabel->dagnode;
|
return op->o.tempop.daglabel->dagnode;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -264,6 +260,19 @@ daglabel_detatch (daglabel_t *l)
|
||||||
l->dagnode = 0;
|
l->dagnode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static statement_t *
|
||||||
|
build_statement (const char *opcode, operand_t *a, operand_t *b, operand_t *c,
|
||||||
|
expr_t *expr)
|
||||||
|
{
|
||||||
|
if ((!a && (b || c)) || (a && !b && c))
|
||||||
|
internal_error (0, "invalid operand combo");
|
||||||
|
statement_t *st = new_statement (opcode, expr);
|
||||||
|
st->opa = a;
|
||||||
|
st->opb = b;
|
||||||
|
st->opc = c;
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
dagnode_t *
|
dagnode_t *
|
||||||
dag_create (const flownode_t *flownode)
|
dag_create (const flownode_t *flownode)
|
||||||
{
|
{
|
||||||
|
@ -303,16 +312,23 @@ dag_create (const flownode_t *flownode)
|
||||||
}
|
}
|
||||||
if (!n) {
|
if (!n) {
|
||||||
n = new_node ();
|
n = new_node ();
|
||||||
|
n->statement = s;
|
||||||
n->label = op;
|
n->label = op;
|
||||||
n->a = ny;
|
n->a = ny;
|
||||||
n->b = nz;
|
n->b = nz;
|
||||||
n->c = nw;
|
n->c = nw;
|
||||||
if (ny)
|
if (ny) {
|
||||||
ny->is_child = 1;
|
ny->is_child = 1;
|
||||||
if (nz)
|
n->ta = y->type;
|
||||||
|
}
|
||||||
|
if (nz) {
|
||||||
nz->is_child = 1;
|
nz->is_child = 1;
|
||||||
if (nw)
|
n->tb = z->type;
|
||||||
|
}
|
||||||
|
if (nw) {
|
||||||
nw->is_child = 1;
|
nw->is_child = 1;
|
||||||
|
n->tc = w->type;
|
||||||
|
}
|
||||||
*dagtail = n;
|
*dagtail = n;
|
||||||
dagtail = &n->next;
|
dagtail = &n->next;
|
||||||
}
|
}
|
||||||
|
@ -419,6 +435,68 @@ dag_calc_node_costs (dagnode_t *dagnode)
|
||||||
static operand_t *
|
static operand_t *
|
||||||
dag_gencode (sblock_t *block, const dagnode_t *dagnode)
|
dag_gencode (sblock_t *block, const dagnode_t *dagnode)
|
||||||
{
|
{
|
||||||
|
if (!dagnode->a) {
|
||||||
|
statement_t *st;
|
||||||
|
daglabel_t *var = 0;
|
||||||
|
operand_t *op = dagnode->label->op;
|
||||||
|
|
||||||
|
if (dagnode->identifiers) {
|
||||||
|
var = dagnode->identifiers;
|
||||||
|
}
|
||||||
|
for (var = dagnode->identifiers; var; var = var->next) {
|
||||||
|
st = build_statement ("=", op, var->op, 0, 0);
|
||||||
|
sblock_add_statement (block, st);
|
||||||
|
}
|
||||||
|
return op;
|
||||||
|
} else {
|
||||||
|
statement_t *st;
|
||||||
|
daglabel_t *var = 0;
|
||||||
|
operand_t *op_a = 0;
|
||||||
|
operand_t *op_b = 0;
|
||||||
|
operand_t *op_c = 0;
|
||||||
|
|
||||||
|
if (flow_is_cond (dagnode->statement))
|
||||||
|
op_b = dagnode->statement->opb;
|
||||||
|
|
||||||
|
if (dagnode->b && dagnode->c) {
|
||||||
|
op_a = dag_gencode (block, dagnode->a);
|
||||||
|
op_b = dag_gencode (block, dagnode->b);
|
||||||
|
op_c = dag_gencode (block, dagnode->c);
|
||||||
|
} else if (dagnode->b) {
|
||||||
|
if (dagnode->a->cost < dagnode->b->cost) {
|
||||||
|
op_b = dag_gencode (block, dagnode->b);
|
||||||
|
op_a = dag_gencode (block, dagnode->a);
|
||||||
|
} else {
|
||||||
|
op_a = dag_gencode (block, dagnode->a);
|
||||||
|
op_b = dag_gencode (block, dagnode->b);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
op_a = dag_gencode (block, dagnode->a);
|
||||||
|
}
|
||||||
|
if (op_a && op_b && get_type (dagnode->statement->expr)) {
|
||||||
|
if (dagnode->identifiers) {
|
||||||
|
op_c = dagnode->identifiers->op;
|
||||||
|
var = dagnode->identifiers->next;
|
||||||
|
} else {
|
||||||
|
op_c = temp_operand (get_type (dagnode->statement->expr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (op_a && op_a->op_type != op_label && op_a->type != dagnode->ta)
|
||||||
|
op_a = alias_operand (op_a, dagnode->ta);
|
||||||
|
if (op_b && op_b->op_type != op_label && op_b->type != dagnode->tb)
|
||||||
|
op_b = alias_operand (op_b, dagnode->tb);
|
||||||
|
if (op_c && op_c->op_type != op_label && op_c->type != dagnode->tc)
|
||||||
|
op_c = alias_operand (op_c, dagnode->tc);
|
||||||
|
st = build_statement (dagnode->label->opcode, op_a, op_b, op_c,
|
||||||
|
dagnode->statement->expr);
|
||||||
|
sblock_add_statement (block, st);
|
||||||
|
while (var) {
|
||||||
|
st = build_statement ("=", op_c, var->op, 0, 0);
|
||||||
|
sblock_add_statement (block, st);
|
||||||
|
var = var->next;
|
||||||
|
}
|
||||||
|
return op_c;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,8 +507,8 @@ dag_generate (sblock_t *block, const flownode_t *flownode)
|
||||||
|
|
||||||
dag_calc_node_costs (flownode->dag);
|
dag_calc_node_costs (flownode->dag);
|
||||||
for (dag = flownode->dag; dag; dag = dag->next) {
|
for (dag = flownode->dag; dag; dag = dag->next) {
|
||||||
//if (!dag->a || (strcmp (dag->label->opcode, ".=") && !dag->identifiers))
|
if (!dag->a || (strcmp (dag->label->opcode, ".=") && !dag->identifiers))
|
||||||
// continue;
|
continue;
|
||||||
dag_gencode (block, dag);
|
dag_gencode (block, dag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue