[qfcc] Add more statement types for move/memset

They ease the statement checks between assign/move/memset and the
pointer versions (don't need all those strcmps)
This commit is contained in:
Bill Currie 2020-03-17 21:39:49 +09:00
parent 3c2f6c8447
commit 16bda66785
4 changed files with 40 additions and 13 deletions

View file

@ -73,17 +73,20 @@ typedef struct operand_s {
Statement types are broken down into expressions (binary and unary, Statement types are broken down into expressions (binary and unary,
includes address and pointer dereferencing (read)), assignment, pointer includes address and pointer dereferencing (read)), assignment, pointer
assignment (write to dereference pointer), move (special case of pointer assignment (write to dereference pointer), move (special case of
assignment), state, function related (call, rcall, return and done), and assignment), pointer move (special case of pointer assignment), state,
flow control (conditional branches, goto, jump (single pointer and jump function related (call, rcall, return and done), and flow control
table)). (conditional branches, goto, jump (single pointer and jump table)).
*/ */
typedef enum { typedef enum {
st_none, ///< not a (valid) statement. Used in dags. st_none, ///< not a (valid) statement. Used in dags.
st_expr, ///< c = a op b; or c = op a; st_expr, ///< c = a op b; or c = op a;
st_assign, ///< b = a st_assign, ///< b = a
st_ptrassign, ///< *b = a; or *(b + c) = a; st_ptrassign, ///< *b = a; or *(b + c) = a;
st_move, ///< memcpy (c, a, b); st_move, ///< memcpy (c, a, b); c and a are direct def references
st_ptrmove, ///< memcpy (c, a, b); c and a are pointers
st_memset, ///< memset (c, a, b); c is direct def reference
st_ptrmemset, ///< memset (c, a, b); c is pointer
st_state, ///< state (a, b); or state (a, b, c) st_state, ///< state (a, b); or state (a, b, c)
st_func, ///< call, rcall or return/done st_func, ///< call, rcall or return/done
st_flow, ///< if/ifa/ifae/ifb/ifbe/ifnot or goto or jump/jumpb st_flow, ///< if/ifa/ifae/ifb/ifbe/ifnot or goto or jump/jumpb

View file

@ -49,8 +49,10 @@
#include "dags.h" #include "dags.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "dot.h"
#include "flow.h" #include "flow.h"
#include "function.h" #include "function.h"
#include "options.h"
#include "qfcc.h" #include "qfcc.h"
#include "statements.h" #include "statements.h"
#include "strpool.h" #include "strpool.h"
@ -133,6 +135,11 @@ daglabel_string (daglabel_t *label)
// operand_string might use quote_string, which returns a pointer to // operand_string might use quote_string, which returns a pointer to
// a static variable. // a static variable.
dstring_copystr (str, operand_string (label->op)); dstring_copystr (str, operand_string (label->op));
#if 0
if (label->op->type) {
dstring_appendstr (str, label->op->type->encoding);
}
#endif
return quote_string (str->str); return quote_string (str->str);
} }
@ -730,10 +737,13 @@ dag_create (flownode_t *flownode)
int i; int i;
dag_make_children (dag, s, operands, children); dag_make_children (dag, s, operands, children);
if (s->type == st_flow || s->type == st_func) if (s->type == st_flow || s->type == st_func) {
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++) {
if (children[i]) if (children[i]) {
dag_make_var_live (live_vars, operands[i + 1]); dag_make_var_live (live_vars, operands[i + 1]);
}
}
}
op = opcode_label (dag, s->opcode, s->expr); op = opcode_label (dag, s->opcode, s->expr);
n = children[0]; n = children[0];
if (s->type != st_assign if (s->type != st_assign
@ -759,7 +769,12 @@ dag_create (flownode_t *flownode)
labels = malloc (dag->num_labels * sizeof (daglabel_t *)); labels = malloc (dag->num_labels * sizeof (daglabel_t *));
memcpy (labels, dag->labels, dag->num_labels * sizeof (daglabel_t *)); memcpy (labels, dag->labels, dag->num_labels * sizeof (daglabel_t *));
dag->labels = labels; dag->labels = labels;
#if 0
if (options.block_dot.dags) {
flownode->dag = dag;
dump_dot ("raw-dags", flownode->graph, dump_dot_flow_dags);
}
#endif
dag_remove_dead_vars (dag, live_vars); dag_remove_dead_vars (dag, live_vars);
dag_sort_nodes (dag); dag_sort_nodes (dag);
set_delete (live_vars); set_delete (live_vars);
@ -972,6 +987,9 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
dst = operands[0]; dst = operands[0];
break; break;
case st_move: case st_move:
case st_ptrmove:
case st_memset:
case st_ptrmemset:
if (!strcmp (dagnode->label->opcode, "<MOVE>")) { if (!strcmp (dagnode->label->opcode, "<MOVE>")) {
dst = generate_moves (dag, block, dagnode); dst = generate_moves (dag, block, dagnode);
break; break;

View file

@ -1116,6 +1116,9 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
break; break;
case st_ptrassign: case st_ptrassign:
case st_move: case st_move:
case st_ptrmove:
case st_memset:
case st_ptrmemset:
flow_add_op_var (use, s->opa, 1); flow_add_op_var (use, s->opa, 1);
flow_add_op_var (use, s->opb, 1); flow_add_op_var (use, s->opb, 1);
if (!strcmp (s->opcode, "<MOVE>") if (!strcmp (s->opcode, "<MOVE>")

View file

@ -758,7 +758,7 @@ expr_assign_copy (sblock_t *sblock, expr_t *e, operand_t **op, operand_t *src)
const char **opcode_set = opcode_sets[0]; const char **opcode_set = opcode_sets[0];
const char *opcode; const char *opcode;
int need_ptr = 0; int need_ptr = 0;
//operand_t *dummy; st_type_t type = st_move;
if ((src && src->op_type == op_nil) || src_expr->type == ex_nil) { if ((src && src->op_type == op_nil) || src_expr->type == ex_nil) {
// switch to memset because nil is type agnostic 0 and structures // switch to memset because nil is type agnostic 0 and structures
@ -769,6 +769,7 @@ expr_assign_copy (sblock_t *sblock, expr_t *e, operand_t **op, operand_t *src)
if (op) { if (op) {
*op = nil_operand (dst_type, src_expr); *op = nil_operand (dst_type, src_expr);
} }
type = st_memset;
if (is_indirect (dst_expr)) { if (is_indirect (dst_expr)) {
goto dereference_dst; goto dereference_dst;
} }
@ -815,9 +816,10 @@ dereference_dst:
opcode = opcode_set[0]; opcode = opcode_set[0];
} else { } else {
opcode = opcode_set[1]; opcode = opcode_set[1];
type++; // from st_move/st_memset to st_ptrmove/st_ptrmemset
} }
s = new_statement (st_move, opcode, e); s = new_statement (type, opcode, e);
s->opa = src; s->opa = src;
s->opb = size; s->opb = size;
s->opc = dst; s->opc = dst;
@ -932,7 +934,8 @@ expr_move (sblock_t *sblock, expr_t *e, operand_t **op)
dst = *op; dst = *op;
sblock = statement_subexpr (sblock, src_expr, &src); sblock = statement_subexpr (sblock, src_expr, &src);
sblock = statement_subexpr (sblock, size_expr, &size); sblock = statement_subexpr (sblock, size_expr, &size);
s = new_statement (st_move, convert_op (e->e.expr.op), e); s = new_statement (e->e.expr.op == 'm' ? st_move : st_ptrmove,
convert_op (e->e.expr.op), e);
s->opa = src; s->opa = src;
s->opb = size; s->opb = size;
s->opc = dst; s->opc = dst;
@ -1068,7 +1071,7 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
dst_addr = operand_address (*op, e); dst_addr = operand_address (*op, e);
s = new_statement (st_move, "<MOVEP>", deref); s = new_statement (st_ptrmove, "<MOVEP>", deref);
s->opa = src_addr; s->opa = src_addr;
//FIXME large types //FIXME large types
s->opb = short_operand (type_size (type), e); s->opb = short_operand (type_size (type), e);