Make a start on regenerating code from dags.

Some parts are a lot messier than I thought, so the actual codegen in the
dags code is just a minimal stub for now.
This commit is contained in:
Bill Currie 2012-11-07 14:11:26 +09:00
parent 802e1981bb
commit d76e2a8423
5 changed files with 96 additions and 3 deletions

View file

@ -35,6 +35,10 @@
*/
//@{
struct dstring_s;
struct flownode_s;
struct sblock_s;
typedef struct daglabel_s {
/// \name attached identifer linked list
//@{
@ -51,6 +55,7 @@ typedef struct dagnode_s {
struct dagnode_s *next;
int print_count; ///< used to avoid double printing nodes
int is_child; ///< true if a child node
int cost; ///< cost of this node in temp vars
daglabel_t *label; ///< ident/const if leaf node, or operator
/// \name child nodes
/// All three child nodes will be null if this node is a leaf
@ -69,9 +74,7 @@ typedef struct dagnode_s {
} dagnode_t;
const char *daglabel_string (daglabel_t *label);
struct dstring_s;
void print_dag (struct dstring_s *dstr, dagnode_t *node);
struct flownode_s;
/** Make a dag for a single basic block.
@ -80,7 +83,9 @@ struct flownode_s;
variable information already computed.
\return The dag representing the basic block.
*/
dagnode_t *dag_create (const struct flownode_s *node);
dagnode_t *dag_create (const struct flownode_s *flownode);
void dag_generate (struct sblock_s *block, const struct flownode_s *flownode);
//@}

View file

@ -102,6 +102,7 @@ void flow_build_vars (struct function_s *func);
flowgraph_t *flow_build_graph (struct sblock_s *func);
void flow_del_graph (flowgraph_t *graph);
void flow_data_flow (flowgraph_t *graph);
struct sblock_s *flow_generate (flowgraph_t *graph);
void print_flowgraph (flowgraph_t *graph, const char *filename);

View file

@ -40,6 +40,7 @@
#include <stdlib.h>
#include "QF/dstring.h"
#include "QF/mathlib.h"
#include "dags.h"
#include "diagnostic.h"
@ -376,3 +377,60 @@ dag_create (const flownode_t *flownode)
}
return dagnodes;
}
static void
dag_calc_node_costs (dagnode_t *dagnode)
{
if ((!dagnode->a && (dagnode->b || dagnode->c))
|| (dagnode->a && !dagnode->b && dagnode->c))
internal_error (0, "bad dag node");
if (dagnode->a)
dag_calc_node_costs (dagnode->a);
if (dagnode->b)
dag_calc_node_costs (dagnode->b);
if (dagnode->c)
dag_calc_node_costs (dagnode->c);
// if dagnode->a is null, then this is a leaf (as b and c are guaranted to
// be null)
if (!dagnode->a) {
// Because qc vm statements don't mix source and destination operands,
// leaves never need temporary variables.
dagnode->cost = 0;
} else {
int different = 0;
// a non-leaf is guaranteed to have a valid "a"
dagnode->cost = dagnode->a->cost;
if (dagnode->b && dagnode->b->cost != dagnode->cost) {
dagnode->cost = max (dagnode->cost, dagnode->b->cost);
different = 1;
}
if (dagnode->c && (different || dagnode->c->cost != dagnode->cost)) {
dagnode->cost = max (dagnode->cost, dagnode->c->cost);
different = 1;
}
if (!different)
dagnode->cost += 1;
}
}
static operand_t *
dag_gencode (sblock_t *block, const dagnode_t *dagnode)
{
return 0;
}
void
dag_generate (sblock_t *block, const flownode_t *flownode)
{
const dagnode_t *dag;
dag_calc_node_costs (flownode->dag);
for (dag = flownode->dag; dag; dag = dag->next) {
//if (!dag->a || (strcmp (dag->label->opcode, ".=") && !dag->identifiers))
// continue;
dag_gencode (block, dag);
}
}

View file

@ -362,6 +362,34 @@ flow_data_flow (flowgraph_t *graph)
dump_dot ("flow", graph, dump_dot_flow);
}
sblock_t *
flow_generate (flowgraph_t *graph)
{
int i;
sblock_t *code = 0;
sblock_t **tail = &code;
for (i = 0; i < graph->num_nodes; i++) {
ex_label_t *label;
sblock_t *block;
flownode_t *node = graph->nodes[i];
*tail = block = new_sblock ();
tail = &(*tail)->next;
// first, transfer any labels on the old node to the new
while ((label = node->sblock->labels)) {
node->sblock->labels = label->next;
label->next = block->labels;
block->labels = label;
label->dest = block;
}
// generate new statements from the dag;
dag_generate (block, node);
}
dump_dot ("post", code, dump_dot_sblock);
return code;
}
int
flow_is_cond (statement_t *s)
{

View file

@ -647,6 +647,7 @@ emit_function (function_t *f, expr_t *e)
f->graph = flow_build_graph (f->sblock);
f->graph->func = f;
flow_data_flow (f->graph);
f->sblock = flow_generate (f->graph);
emit_statements (f->sblock);
}