[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,
includes address and pointer dereferencing (read)), assignment, pointer
assignment (write to dereference pointer), move (special case of pointer
assignment), state, function related (call, rcall, return and done), and
flow control (conditional branches, goto, jump (single pointer and jump
table)).
assignment (write to dereference pointer), move (special case of
assignment), pointer move (special case of pointer assignment), state,
function related (call, rcall, return and done), and flow control
(conditional branches, goto, jump (single pointer and jump table)).
*/
typedef enum {
st_none, ///< not a (valid) statement. Used in dags.
st_expr, ///< c = a op b; or c = op a;
st_assign, ///< b = 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_func, ///< call, rcall or return/done
st_flow, ///< if/ifa/ifae/ifb/ifbe/ifnot or goto or jump/jumpb

View file

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

View file

@ -1116,6 +1116,9 @@ flow_analyze_statement (statement_t *s, set_t *use, set_t *def, set_t *kill,
break;
case st_ptrassign:
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->opb, 1);
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;
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) {
// 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) {
*op = nil_operand (dst_type, src_expr);
}
type = st_memset;
if (is_indirect (dst_expr)) {
goto dereference_dst;
}
@ -815,9 +816,10 @@ dereference_dst:
opcode = opcode_set[0];
} else {
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->opb = size;
s->opc = dst;
@ -932,7 +934,8 @@ expr_move (sblock_t *sblock, expr_t *e, operand_t **op)
dst = *op;
sblock = statement_subexpr (sblock, src_expr, &src);
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->opb = size;
s->opc = dst;
@ -1068,7 +1071,7 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
dst_addr = operand_address (*op, e);
s = new_statement (st_move, "<MOVEP>", deref);
s = new_statement (st_ptrmove, "<MOVEP>", deref);
s->opa = src_addr;
//FIXME large types
s->opb = short_operand (type_size (type), e);