* [tuples] Refactor some data structures
@ 2007-07-25 0:24 Diego Novillo
0 siblings, 0 replies; only message in thread
From: Diego Novillo @ 2007-07-25 0:24 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 745 bytes --]
Data structures with register and memory operands do not need to be
defined separately. Instead of being separate fields, the operands can
just be static slots into an array of operands.
This patch removes the data structures used to represent GIMPLE_ASSIGN,
GIMPLE_CALL, GIMPLE_RETURN, GIMPLE_COND, GIMPLE_GOTO, GIMPLE_LABEL and
GIMPLE_SWITCH. The operands are now an array of trees in the base
structure gimple_statement_with_ops. This also allow us to treat these
tuples in a more uniform way, useful for cases when we don't care/know
what kind of statement we are dealing with.
It may be possible to convert others, but I would rather make these
changes incrementally.
Updated the design document and tested against gimple.exp tests.
[-- Attachment #2: 20070724-consolidate-tuples-with-ops.diff --]
[-- Type: text/x-patch, Size: 55467 bytes --]
2007-07-24 Diego Novillo <dnovillo@google.com>
* gimple.def: Re-organize codes that take tree operands so
they are consecutive.
* gsstruct.def (GSS_LABEL, GSS_ASSIGN_BINARY, GSS_ASSIGN_UNARY_REG,
GSS_ASSIGN_UNARY_MEM, GSS_COND, GSS_GOTO, GSS_SWITCH, GSS_CALL,
GSS_RETURN): Remove. Update al users.
* gimple.c (gss_for_code): New.
(gimple_statement_structure): Call it.
(get_num_ops_for): New.
(gimple_build_with_ops): New.
(gimple_build_return, gimple_build_call_1, gimple_build_assign,
gimple_build_cond, gimple_build_label, gimple_build_goto,
gimple_build_switch_1, ): Call it.
(gss_for_assign): Remove. Update all users.
(gimple_check_failed): Do not assume that subcode is a valid tree
code.
(gimple_range_check_failed): New.
(walk_tuple_ops): Implement in terms of gimple_num_ops and
gimple_op when dealing with GSS_WITH_OPS and GSS_WITH_MEM_OPS
statements.
* gimple.h (struct gimple_statement_with_ops): Add fields 'num_ops'
and 'op'.
(struct gimple_statement_label, gimple_statement_assign_binary,
gimple_statement_assign_unary_reg, gimple_statement_assign_unary_mem,
gimple_statement_cond, gimple_statement_goto, gimple_statement_switch,
gimple_statement_call, gimple_statement_return): Remove.
Update all users.
(gimple_range_check_failed): Declare.
(GIMPLE_RANGE_CHECK): Define.
(gimple_num_ops): New.
(gimple_op): New.
(gimple_set_op): New.
(gimple_assign_rhs1): Rename from gimple_assign_binary_rhs1.
(gimple_assign_set_rhs1): Rename from gimple_assign_binary_set_rhs1.
(gimple_assign_rhs2): Rename from gimple_assign_binary_rhs2.
(gimple_assign_set_rhs2): Rename from gimple_assign_binary_set_rhs2.
(gimple_assign_unary_rhs): Remove. Update all users.
(gimple_assign_unary_set_rhs): Likewise.
(gimple_switch_num_labels): Rename from gimple_switch_nlabels.
(gimple_call_fn, gimple_call_lhs, gimple_call_chain,
gimple_call_set_chain, gimple_call_nargs, gimple_call_arg,
gimple_call_set_arg, gimple_cond_lhs, gimple_cond_set_lhs,
gimple_cond_rhs, gimple_cond_set_rhs, gimple_cond_true_label,
gimple_cond_false_label, gimple_cond_set_true_label,
gimple_cond_set_false_label, gimple_label_label,
gimple_label_set_label, gimple_goto_dest,
gimple_goto_set_dest, gimple_asm_input_op,
gimple_asm_set_input_op, gimple_asm_output_op,
gimple_asm_set_output_op, gimple_asm_clobber_op,
gimple_asm_set_clobber_op, gimple_switch_num_labels,
gimple_switch_index, gimple_switch_set_index,
gimple_switch_default_label, gimple_switch_set_default_label,
gimple_switch_label, gimple_switch_set_label,
gimple_return_retval, gimple_return_set_retval): Implement
using the array of operands in field 'with_ops'.
(gimple_asm_set_ninputs, gimple_asm_set_noutputs,
gimple_asm_set_nclobbered, gimple_asm_set_string): Remove.
Update all users.
Index: gimple.def
===================================================================
--- gimple.def (revision 126888)
+++ gimple.def (working copy)
@@ -1,4 +1,4 @@
-/* This file contains the definitions in the gimple IR tuples used in GCC.
+/* This file contains the definitions of the GIMPLE IR tuples used in GCC.
Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>
@@ -23,29 +23,36 @@ Software Foundation, 51 Franklin Street,
/* The format of this file is
DEFGSCODE(GIMPLE_symbol, printable name).
- Where symbol is the enumeration name without the ``GIMPLE_''.
- */
+ Where symbol is the enumeration name without the ``GIMPLE_''. */
DEFGSCODE(GIMPLE_BASE, "gimple_base")
DEFGSCODE(GIMPLE_WITH_OPS, "gimple_with_ops")
+
+/* Do not rearrange the codes between GIMPLE_ASSIGN and GIMPLE_RETURN. It's
+ exposed by GIMPLE_RANGE_CHECK calls. These are all the GIMPLE
+ statements with register operands. */
+DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign")
+DEFGSCODE(GIMPLE_COND, "gimple_cond")
+DEFGSCODE(GIMPLE_GOTO, "gimple_goto")
+DEFGSCODE(GIMPLE_LABEL, "gimple_label")
+DEFGSCODE(GIMPLE_SWITCH, "gimple_switch")
+
+/* Do not rearrange the codes between GIMPLE_ASM and GIMPLE_RETURN. It's
+ exposed by GIMPLE_RANGE_CHECK calls. These are all the GIMPLE
+ statements with memory and register operands. */
+DEFGSCODE(GIMPLE_ASM, "gimple_asm")
+DEFGSCODE(GIMPLE_CALL, "gimple_call")
+DEFGSCODE(GIMPLE_RETURN, "gimple_return")
+
DEFGSCODE(GIMPLE_WITH_MEM_OPS, "gimple_with_mem_ops")
DEFGSCODE(GIMPLE_OMP, "gimple_omp")
-
DEFGSCODE(GIMPLE_BIND, "gimple_bind")
DEFGSCODE(GIMPLE_CATCH, "gimple_catch")
DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter")
-DEFGSCODE(GIMPLE_LABEL, "gimple_label")
DEFGSCODE(GIMPLE_PHI, "gimple_phi")
DEFGSCODE(GIMPLE_RESX, "gimple_resx")
DEFGSCODE(GIMPLE_TRY, "gimple_try")
-DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign")
-DEFGSCODE(GIMPLE_COND, "gimple_cond")
-DEFGSCODE(GIMPLE_GOTO, "gimple_goto")
-DEFGSCODE(GIMPLE_SWITCH, "gimple_switch")
-DEFGSCODE(GIMPLE_ASM, "gimple_asm")
-DEFGSCODE(GIMPLE_CALL, "gimple_call")
DEFGSCODE(GIMPLE_NOP, "gimple_nop")
-DEFGSCODE(GIMPLE_RETURN, "gimple_return")
DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue")
DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical")
DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for")
Index: gsstruct.def
===================================================================
--- gsstruct.def (revision 126888)
+++ gsstruct.def (working copy)
@@ -24,30 +24,19 @@ Software Foundation, 51 Franklin Street,
/* The format of this file is
DEFGSSTRUCT(GSS_enumeration value, printable name).
Each enum value should correspond with a single member of the union
- gimple_statement_d.
- */
+ gimple_statement_d. */
DEFGSSTRUCT(GSS_BASE, "base")
DEFGSSTRUCT(GSS_WITH_OPS, "with_ops")
DEFGSSTRUCT(GSS_WITH_MEM_OPS, "with_mem_ops")
DEFGSSTRUCT(GSS_OMP, "omp")
-
DEFGSSTRUCT(GSS_BIND, "bind")
DEFGSSTRUCT(GSS_CATCH, "catch")
DEFGSSTRUCT(GSS_EH_FILTER, "eh_filter")
-DEFGSSTRUCT(GSS_LABEL, "label")
DEFGSSTRUCT(GSS_PHI, "phi")
DEFGSSTRUCT(GSS_RESX, "resx")
DEFGSSTRUCT(GSS_TRY, "try")
-DEFGSSTRUCT(GSS_ASSIGN_BINARY, "assign_binary")
-DEFGSSTRUCT(GSS_ASSIGN_UNARY_REG, "assign_unary_reg")
-DEFGSSTRUCT(GSS_ASSIGN_UNARY_MEM, "assign_unary_mem")
-DEFGSSTRUCT(GSS_COND, "cond")
-DEFGSSTRUCT(GSS_GOTO, "goto")
-DEFGSSTRUCT(GSS_SWITCH, "switch")
DEFGSSTRUCT(GSS_ASM, "asm")
-DEFGSSTRUCT(GSS_CALL, "call")
-DEFGSSTRUCT(GSS_RETURN, "return")
DEFGSSTRUCT(GSS_OMP_CRITICAL, "omp_critical")
DEFGSSTRUCT(GSS_OMP_FOR, "omp_for")
DEFGSSTRUCT(GSS_OMP_PARALLEL, "omp_parallel")
Index: gimple-pretty-print.c
===================================================================
--- gimple-pretty-print.c (revision 126888)
+++ gimple-pretty-print.c (working copy)
@@ -146,34 +146,23 @@ debug_gimple_seq (gimple_seq seq)
static void
dump_gimple_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
{
- enum gimple_statement_structure_enum gss;
-
dump_generic_node (buffer, gimple_assign_lhs (gs), spc, flags, false);
pp_space (buffer);
pp_character (buffer, '=');
pp_space (buffer);
- gss = gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs));
- switch (gss)
+ if (gimple_num_ops (gs) == 2)
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+ else if (gimple_num_ops (gs) == 3)
{
- case GSS_ASSIGN_BINARY:
- dump_generic_node (buffer, gimple_assign_binary_rhs1 (gs), spc,
- flags, false);
- pp_space (buffer);
- pp_string (buffer, op_symbol_code (GIMPLE_SUBCODE_FLAGS (gs)));
- pp_space (buffer);
- dump_generic_node (buffer, gimple_assign_binary_rhs2 (gs), spc,
- flags, false);
- break;
-
- case GSS_ASSIGN_UNARY_REG:
- case GSS_ASSIGN_UNARY_MEM:
- dump_generic_node (buffer, gimple_assign_unary_rhs (gs), spc, flags, false);
- break;
-
- default:
- gcc_unreachable ();
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+ pp_space (buffer);
+ pp_string (buffer, op_symbol_code (GIMPLE_SUBCODE_FLAGS (gs)));
+ pp_space (buffer);
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
}
+ else
+ gcc_unreachable ();
}
@@ -239,10 +228,10 @@ dump_gimple_switch (pretty_printer *buff
pp_string (buffer, "switch (");
dump_generic_node (buffer, gimple_switch_index (gs), spc, flags, true);
pp_string (buffer, ") <");
- for (i = 0; i < gimple_switch_nlabels (gs); i++)
+ for (i = 0; i < gimple_switch_num_labels (gs); i++)
{
dump_generic_node (buffer, gimple_switch_label (gs, i), spc, flags, false);
- if (i < gimple_switch_nlabels (gs) - 1)
+ if (i < gimple_switch_num_labels (gs) - 1)
pp_string (buffer, ", ");
}
pp_string (buffer, ">");
Index: gimple.c
===================================================================
--- gimple.c (revision 126888)
+++ gimple.c (working copy)
@@ -42,10 +42,73 @@ const char *const gimple_code_name[] = {
gimple_body (FN). */
static struct pointer_map_t *gimple_bodies = NULL;
-/* Gimple tuple constructors. */
+/* Gimple tuple constructors.
+ Note: Any constructor taking a ``gimple_seq'' as a parameter, can
+ be passed a NULL to start with an empty sequence. */
+
+
+/* Return the GSS_* identifier for the given GIMPLE statement CODE. */
+
+static enum gimple_statement_structure_enum
+gss_for_code (enum gimple_code code)
+{
+ switch (code)
+ {
+ case GIMPLE_ASSIGN:
+ case GIMPLE_CALL:
+ case GIMPLE_RETURN: return GSS_WITH_MEM_OPS;
+ case GIMPLE_COND:
+ case GIMPLE_GOTO:
+ case GIMPLE_LABEL:
+ case GIMPLE_SWITCH: return GSS_WITH_OPS;
+ case GIMPLE_ASM: return GSS_ASM;
+ case GIMPLE_BIND: return GSS_BIND;
+ case GIMPLE_CATCH: return GSS_CATCH;
+ case GIMPLE_EH_FILTER: return GSS_EH_FILTER;
+ case GIMPLE_NOP: return GSS_BASE;
+ case GIMPLE_PHI: return GSS_PHI;
+ case GIMPLE_RESX: return GSS_RESX;
+ case GIMPLE_TRY: return GSS_TRY;
+ case GIMPLE_OMP_CRITICAL: return GSS_OMP_CRITICAL;
+ case GIMPLE_OMP_FOR: return GSS_OMP_FOR;
+ case GIMPLE_OMP_CONTINUE:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_OMP_SECTION: return GSS_OMP;
+ case GIMPLE_OMP_PARALLEL: return GSS_OMP_PARALLEL;
+ case GIMPLE_OMP_SECTIONS: return GSS_OMP_SECTIONS;
+ case GIMPLE_OMP_SINGLE: return GSS_OMP_SINGLE;
+ default: gcc_unreachable ();
+ }
+}
+
+
+/* Build a tuple with operands. CODE is the statement to build (which
+ must be one of the GIMPLE_WITH_OPS tuples). SUBCODE is the sub-code
+ for the new tuple. NUM_OPS is the number of operands to allocate. */
+
+static gimple
+gimple_build_with_ops (enum gimple_code code, unsigned subcode, size_t num_ops)
+{
+ gimple s;
+ enum gimple_statement_structure_enum gss = gss_for_code (code);
+
+ if (gss == GSS_WITH_OPS)
+ s = ggc_alloc_cleared (sizeof (struct gimple_statement_with_ops));
+ else if (gss == GSS_WITH_MEM_OPS)
+ s = ggc_alloc_cleared (sizeof (struct gimple_statement_with_memory_ops));
+ else
+ gcc_unreachable ();
+
+ GIMPLE_CODE (s) = code;
+ GIMPLE_SUBCODE_FLAGS (s) = subcode;
+ s->with_ops.num_ops = num_ops;
+ s->with_ops.op = ggc_alloc_cleared (sizeof (tree) * num_ops);
+
+ return s;
+}
-/* Note: Any constructor taking a ``gimple_seq'' as a parameter, can be passed
- a NULL to start with an empty sequence. */
/* Construct a GIMPLE_RETURN statement.
@@ -55,12 +118,9 @@ static struct pointer_map_t *gimple_bodi
gimple
gimple_build_return (bool result_decl_p, tree retval)
{
- gimple p = ggc_alloc_cleared (sizeof (struct gimple_statement_return));
-
- GIMPLE_CODE (p) = GIMPLE_RETURN;
- GIMPLE_SUBCODE_FLAGS (p) = (int) result_decl_p;
- gimple_return_set_retval (p, retval);
- return p;
+ gimple s = gimple_build_with_ops (GIMPLE_RETURN, (int) result_decl_p, 1);
+ gimple_return_set_retval (s, retval);
+ return s;
}
/* Helper for gimple_build_call and gimple_build_call_vec. Build the basic
@@ -70,15 +130,9 @@ gimple_build_return (bool result_decl_p,
static inline gimple
gimple_build_call_1 (tree fn, size_t nargs)
{
- gimple gs = ggc_alloc_cleared (sizeof (struct gimple_statement_call)
- + sizeof (tree) * (nargs - 1));
-
- GIMPLE_CODE (gs) = GIMPLE_CALL;
- GIMPLE_SUBCODE_FLAGS (gs) = 0;
- gs->gimple_call.nargs = nargs;
- gs->gimple_call.fn = fn;
-
- return gs;
+ gimple s = gimple_build_with_ops (GIMPLE_CALL, 0, nargs + 3);
+ s->with_ops.op[1] = fn;
+ return s;
}
@@ -119,6 +173,17 @@ gimple_build_call (tree fn, size_t nargs
return call;
}
+
+/* Given a CODE for the RHS of a GIMPLE_ASSIGN, return the number of operands
+ it needs. */
+
+static inline size_t
+get_num_ops_for (enum tree_code code)
+{
+ enum tree_code_class class = TREE_CODE_CLASS (code);
+ return (class == tcc_binary || class == tcc_comparison) ? 2 : 1;
+}
+
/* Construct a GIMPLE_ASSIGN statement.
LHS of the assignment.
@@ -128,76 +193,38 @@ gimple
gimple_build_assign (tree lhs, tree rhs)
{
gimple p;
- enum gimple_statement_structure_enum gss;
-
- gss = gss_for_assign (TREE_CODE (rhs));
- switch (gss)
- {
- case GSS_ASSIGN_BINARY:
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_assign_binary));
- GIMPLE_CODE (p) = GIMPLE_ASSIGN;
- GIMPLE_SUBCODE_FLAGS (p) = TREE_CODE (rhs);
- gimple_assign_set_lhs (p, lhs);
- gimple_assign_binary_set_rhs1 (p, TREE_OPERAND (rhs, 0));
- gimple_assign_binary_set_rhs2 (p, TREE_OPERAND (rhs, 1));
- break;
-
- case GSS_ASSIGN_UNARY_REG:
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_assign_unary_reg));
- GIMPLE_CODE (p) = GIMPLE_ASSIGN;
- GIMPLE_SUBCODE_FLAGS (p) = TREE_CODE (rhs);
- gimple_assign_set_lhs (p, lhs);
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (rhs))))
- gimple_assign_unary_set_rhs (p, TREE_OPERAND (rhs, 0));
- else
- gimple_assign_unary_set_rhs (p, rhs);
- break;
+ size_t num_ops;
+ enum tree_code subcode = TREE_CODE (rhs);
+ enum tree_code_class class = TREE_CODE_CLASS (subcode);
- case GSS_ASSIGN_UNARY_MEM:
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_assign_unary_mem));
- GIMPLE_CODE (p) = GIMPLE_ASSIGN;
- GIMPLE_SUBCODE_FLAGS (p) = TREE_CODE (rhs);
- gimple_assign_set_lhs (p, lhs);
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (rhs))))
- gimple_assign_unary_set_rhs (p, TREE_OPERAND (rhs, 0));
- else
- gimple_assign_unary_set_rhs (p, rhs);
+ /* Make sure the RHS is a valid GIMPLE RHS. */
+ gcc_assert (is_gimple_formal_tmp_rhs (rhs));
- break;
+ /* Need 1 operand for LHS and 1 or 2 for the RHS (depending on the
+ code). */
+ num_ops = get_num_ops_for (subcode) + 1;
+
+ p = gimple_build_with_ops (GIMPLE_ASSIGN, subcode, num_ops);
+ gimple_assign_set_lhs (p, lhs);
- default:
- gcc_unreachable ();
+ if (class == tcc_binary || class == tcc_comparison)
+ {
+ gimple_assign_set_rhs1 (p, TREE_OPERAND (rhs, 0));
+ gimple_assign_set_rhs2 (p, TREE_OPERAND (rhs, 1));
}
+ else if (class == tcc_unary)
+ gimple_assign_set_rhs1 (p, TREE_OPERAND (rhs, 0));
+ else if (class == tcc_constant
+ || class == tcc_declaration
+ || subcode == SSA_NAME)
+ gimple_assign_set_rhs1 (p, rhs);
+ else
+ gcc_unreachable ();
return p;
}
-/* Given a CODE for the RHS of a GIMPLE_ASSIGN, return the GSS enum for it. */
-
-enum gimple_statement_structure_enum
-gss_for_assign (enum tree_code code)
-{
- enum tree_code_class class = TREE_CODE_CLASS (code);
-
- if (class == tcc_binary || class == tcc_comparison)
- return GSS_ASSIGN_BINARY;
-
- /* There can be 3 types of unary operations:
-
- SYM = <constant> <== GSS_ASSIGN_UNARY_REG
- SYM = SSA_NAME <== GSS_ASSIGN_UNARY_REG
- SYM = SYM2 <== GSS_ASSIGN_UNARY_MEM
- SYM = UNARY_OP SYM2 <== GSS_ASSIGN_UNARY_MEM
- */
-
- if (class == tcc_constant || code == SSA_NAME)
- return GSS_ASSIGN_UNARY_REG;
-
- /* Must be class == tcc_unary. */
- return GSS_ASSIGN_UNARY_MEM;
-}
-
/* Construct a GIMPLE_COND statement.
PRED is the condition used to compare LHS and the RHS.
@@ -208,16 +235,11 @@ gimple
gimple_build_cond (enum gimple_cond pred, tree lhs, tree rhs,
tree t_label, tree f_label)
{
- gimple p;
-
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_cond));
- GIMPLE_CODE (p) = GIMPLE_COND;
- GIMPLE_SUBCODE_FLAGS (p) = pred;
+ gimple p = gimple_build_with_ops (GIMPLE_COND, pred, 4);
gimple_cond_set_lhs (p, lhs);
gimple_cond_set_rhs (p, rhs);
gimple_cond_set_true_label (p, t_label);
gimple_cond_set_false_label (p, f_label);
-
return p;
}
@@ -238,12 +260,8 @@ gimple_cond_invert (gimple g)
gimple
gimple_build_label (tree label)
{
- gimple p;
-
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_label));
- GIMPLE_CODE (p) = GIMPLE_LABEL;
+ gimple p = gimple_build_with_ops (GIMPLE_LABEL, 0, 1);
gimple_label_set_label (p, label);
-
return p;
}
@@ -252,12 +270,8 @@ gimple_build_label (tree label)
gimple
gimple_build_goto (tree dest)
{
- gimple p;
-
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_goto));
- GIMPLE_CODE (p) = GIMPLE_GOTO;
+ gimple p = gimple_build_with_ops (GIMPLE_GOTO, 0, 1);
gimple_goto_set_dest (p, dest);
-
return p;
}
@@ -266,11 +280,8 @@ gimple_build_goto (tree dest)
gimple
gimple_build_nop (void)
{
- gimple p;
-
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_base));
+ gimple p = ggc_alloc_cleared (sizeof (struct gimple_statement_base));
GIMPLE_CODE (p) = GIMPLE_NOP;
-
return p;
}
@@ -281,14 +292,11 @@ gimple_build_nop (void)
gimple
gimple_build_bind (tree vars, gimple_seq body)
{
- gimple p;
-
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_bind));
+ gimple p = ggc_alloc_cleared (sizeof (struct gimple_statement_bind));
GIMPLE_CODE (p) = GIMPLE_BIND;
gimple_bind_set_vars (p, vars);
if (body)
gimple_bind_set_body (p, body);
-
return p;
}
@@ -297,32 +305,36 @@ gimple_build_bind (tree vars, gimple_seq
STRING is the assembly code.
NINPUT is the number of register inputs.
NOUTPUT is the number of register outputs.
- NCLOBBERED is the number of clobbered registers.
+ NCLOBBERS is the number of clobbered registers.
... are trees for each input, output and clobbered register. */
gimple
gimple_build_asm (const char *string, unsigned ninputs, unsigned noutputs,
- unsigned nclobbered, ...)
+ unsigned nclobbers, ...)
{
gimple p;
unsigned i;
va_list ap;
p = ggc_alloc_cleared (sizeof (struct gimple_statement_asm)
- + sizeof (tree) * (ninputs + noutputs + nclobbered - 1));
+ + sizeof (tree) * (ninputs + noutputs + nclobbers - 1));
GIMPLE_CODE (p) = GIMPLE_ASM;
- gimple_asm_set_ninputs (p, ninputs);
- gimple_asm_set_noutputs (p, noutputs);
- gimple_asm_set_nclobbered (p, nclobbered);
- gimple_asm_set_string (p, string);
+ p->gimple_asm.ni = ninputs;
+ p->gimple_asm.no = noutputs;
+ p->gimple_asm.nc = nclobbers;
+ p->gimple_asm.string = string;
- va_start (ap, nclobbered);
+ va_start (ap, nclobbers);
+
for (i = 0; i < ninputs; i++)
gimple_asm_set_input_op (p, i, va_arg (ap, tree));
+
for (i = 0; i < noutputs; i++)
gimple_asm_set_output_op (p, i, va_arg (ap, tree));
- for (i = 0; i < nclobbered; i++)
+
+ for (i = 0; i < nclobbers; i++)
gimple_asm_set_clobber_op (p, i, va_arg (ap, tree));
+
va_end (ap);
return p;
@@ -407,7 +419,7 @@ gimple_build_phi (unsigned capacity, uns
unsigned int i;
va_list va;
p = ggc_alloc_cleared (sizeof (struct gimple_statement_phi)
- + (sizeof (struct phi_arg_d) * (nargs - 1)) );
+ + (sizeof (struct phi_arg_d) * (nargs - 1)) );
GIMPLE_CODE (p) = GIMPLE_PHI;
gimple_phi_set_capacity (p, capacity);
@@ -450,19 +462,10 @@ gimple_build_resx (int region)
static inline gimple
gimple_build_switch_1 (unsigned int nlabels, tree index, tree default_label)
{
- gimple p;
- unsigned int n_all_labels;
- /* We count the default in the number of labels. */
- n_all_labels = nlabels + 1;
- /* total labels - 1 extra from struct. */
- p = ggc_alloc_cleared (sizeof (struct gimple_statement_switch)
- + sizeof (tree) * (n_all_labels - 1));
- GIMPLE_CODE (p) = GIMPLE_SWITCH;
-
- gimple_switch_set_nlabels (p, n_all_labels);
+ /* nlabels + 1 default label + 1 index. */
+ gimple p = gimple_build_with_ops (GIMPLE_SWITCH, 0, nlabels + 1 + 1);
gimple_switch_set_index (p, index);
gimple_switch_set_default_label (p, default_label);
-
return p;
}
@@ -478,10 +481,11 @@ gimple_build_switch (unsigned int nlabel
{
va_list al;
unsigned int i;
+ gimple p;
+
+ p = gimple_build_switch_1 (nlabels, index, default_label);
- gimple p = gimple_build_switch_1 (nlabels, index, default_label);
- /* Put labels in labels[1 - (nlables + 1)].
- Default label is in labels[0]. */
+ /* Store the rest of the labels. */
va_start (al, default_label);
for (i = 1; i <= nlabels; i++)
gimple_switch_set_label (p, i, va_arg (al, tree));
@@ -504,7 +508,7 @@ gimple_build_switch_vec (tree index, tre
size_t nlabels = VEC_length (tree, args);
gimple p = gimple_build_switch_1 (nlabels, index, default_label);
- /* Put labels in labels[1 - (nlables + 1)].
+ /* Put labels in labels[1 - (nlabels + 1)].
Default label is in labels[0]. */
for (i = 1; i <= nlabels; i++)
gimple_switch_set_label (p, i, VEC_index (tree, args, i - 1));
@@ -719,40 +723,7 @@ gimple_omp_build_single (gimple_seq body
enum gimple_statement_structure_enum
gimple_statement_structure (gimple gs)
{
- unsigned int code = GIMPLE_CODE (gs);
- unsigned int subcode = GIMPLE_SUBCODE_FLAGS (gs);
-
- switch (code)
- {
- case GIMPLE_ASSIGN: return gss_for_assign (subcode);
- case GIMPLE_ASM: return GSS_ASM;
- case GIMPLE_BIND: return GSS_BIND;
- case GIMPLE_CALL: return GSS_CALL;
- case GIMPLE_CATCH: return GSS_CATCH;
- case GIMPLE_COND: return GSS_COND;
- case GIMPLE_EH_FILTER: return GSS_EH_FILTER;
- case GIMPLE_GOTO: return GSS_GOTO;
- case GIMPLE_LABEL: return GSS_LABEL;
- case GIMPLE_NOP: return GSS_BASE;
- case GIMPLE_PHI: return GSS_PHI;
- case GIMPLE_RESX: return GSS_RESX;
- case GIMPLE_RETURN: return GSS_RETURN;
- case GIMPLE_SWITCH: return GSS_SWITCH;
- case GIMPLE_TRY: return GSS_TRY;
- case GIMPLE_OMP_CRITICAL: return GSS_OMP_CRITICAL;
- case GIMPLE_OMP_FOR: return GSS_OMP_FOR;
- case GIMPLE_OMP_CONTINUE:
- case GIMPLE_OMP_MASTER:
- case GIMPLE_OMP_ORDERED:
- case GIMPLE_OMP_RETURN:
- case GIMPLE_OMP_SECTION:
- return GSS_OMP;
- case GIMPLE_OMP_PARALLEL: return GSS_OMP_PARALLEL;
- case GIMPLE_OMP_SECTIONS: return GSS_OMP_SECTIONS;
- case GIMPLE_OMP_SINGLE: return GSS_OMP_SINGLE;
- default:
- gcc_unreachable ();
- }
+ return gss_for_code (GIMPLE_CODE (gs));
}
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
@@ -760,14 +731,48 @@ gimple_statement_structure (gimple gs)
void
gimple_check_failed (const gimple gs, const char *file, int line,
- const char *function, unsigned int code,
+ const char *function, enum gimple_code code,
unsigned int subcode)
{
- internal_error ("gimple check: expected %s(%s), have %s(%s) in %s, at %s:%d",
+ internal_error ("gimple check: expected %s(%u), have %s(%u) in %s, at %s:%d",
gimple_code_name[code],
- tree_code_name[subcode],
+ subcode,
gimple_code_name[GIMPLE_CODE (gs)],
- tree_code_name[GIMPLE_SUBCODE_FLAGS (gs)],
+ GIMPLE_SUBCODE_FLAGS (gs),
+ function, trim_filename (file), line);
+}
+
+/* Similar to gimple_check_failed, except that instead of specifying a
+ dozen codes, use the knowledge that they're all sequential. */
+
+void
+gimple_range_check_failed (const gimple gs, const char *file, int line,
+ const char *function, enum gimple_code c1,
+ enum gimple_code c2)
+{
+ char *buffer;
+ unsigned length = 0;
+ enum gimple_code c;
+
+ for (c = c1; c <= c2; ++c)
+ length += 4 + strlen (gimple_code_name[c]);
+
+ length += strlen ("expected ");
+ buffer = alloca (length);
+ length = 0;
+
+ for (c = c1; c <= c2; ++c)
+ {
+ const char *prefix = length ? " or " : "expected ";
+
+ strcpy (buffer + length, prefix);
+ length += strlen (prefix);
+ strcpy (buffer + length, gimple_code_name[c]);
+ length += strlen (gimple_code_name[c]);
+ }
+
+ internal_error ("gimple check: %s, have %s in %s, at %s:%d",
+ buffer, gimple_code_name[GIMPLE_CODE (gs)],
function, trim_filename (file), line);
}
#endif /* ENABLE_TREE_CHECKING */
@@ -830,136 +835,90 @@ walk_tuple_ops (gimple gs, walk_tree_fn
{
unsigned int i;
tree leaf;
+ enum gimple_statement_structure_enum gss;
- switch (GIMPLE_CODE (gs))
- {
- case GIMPLE_ASM:
- for (i = 0; i < gimple_asm_ninputs (gs); ++i)
- WALKIT (gimple_asm_input_op (gs, i));
-
- for (i = 0; i < gimple_asm_noutputs (gs); ++i)
- WALKIT (gimple_asm_output_op (gs, i));
-
- for (i = 0; i < gimple_asm_nclobbered (gs); ++i)
- WALKIT (gimple_asm_clobber_op (gs, i));
- break;
-
- case GIMPLE_ASSIGN:
- WALKIT (gimple_assign_operand (gs, 0));
- WALKIT (gimple_assign_operand (gs, 1));
-
- if (gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs)) == GSS_ASSIGN_BINARY)
- WALKIT (gimple_assign_operand (gs, 2));
- break;
-
- case GIMPLE_BIND:
- WALKIT (gimple_bind_vars (gs));
- walk_seq_ops (gimple_bind_body (gs), func, data, pset);
- break;
-
- case GIMPLE_CALL:
- WALKIT (gimple_call_lhs (gs));
- WALKIT (gimple_call_fn (gs));
- WALKIT (gimple_call_chain (gs));
- for (i = 0; i < gimple_call_nargs (gs); ++i)
- WALKIT (gimple_call_arg (gs, i));
- break;
-
- case GIMPLE_CATCH:
- WALKIT (gimple_catch_types (gs));
- walk_seq_ops (gimple_catch_handler (gs), func, data, pset);
- break;
-
- case GIMPLE_COND:
- WALKIT (gimple_cond_lhs (gs));
- WALKIT (gimple_cond_rhs (gs));
- WALKIT (gimple_cond_true_label (gs));
- WALKIT (gimple_cond_false_label (gs));
- break;
-
- case GIMPLE_EH_FILTER:
- WALKIT (gimple_eh_filter_types (gs));
- walk_seq_ops (gimple_eh_filter_failure (gs), func, data, pset);
- break;
-
- case GIMPLE_GOTO:
- WALKIT (gimple_goto_dest (gs));
- break;
-
- case GIMPLE_LABEL:
- WALKIT (gimple_label_label (gs));
- break;
+ gss = gimple_statement_structure (gs);
+ if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS)
+ for (i = 0; i < gimple_num_ops (gs); i++)
+ WALKIT (gimple_op (gs, i));
+ else
+ switch (GIMPLE_CODE (gs))
+ {
+ case GIMPLE_BIND:
+ WALKIT (gimple_bind_vars (gs));
+ walk_seq_ops (gimple_bind_body (gs), func, data, pset);
+ break;
- case GIMPLE_PHI:
- WALKIT (gimple_phi_result (gs));
- break;
+ case GIMPLE_CATCH:
+ WALKIT (gimple_catch_types (gs));
+ walk_seq_ops (gimple_catch_handler (gs), func, data, pset);
+ break;
- case GIMPLE_RETURN:
- WALKIT (gimple_return_retval (gs));
- break;
+ case GIMPLE_EH_FILTER:
+ WALKIT (gimple_eh_filter_types (gs));
+ walk_seq_ops (gimple_eh_filter_failure (gs), func, data, pset);
+ break;
- case GIMPLE_SWITCH:
- WALKIT (gimple_switch_index (gs));
- for (i = 0; i < gimple_switch_nlabels (gs); ++i)
- WALKIT (gimple_switch_label (gs, i));
- break;
+ case GIMPLE_PHI:
+ WALKIT (gimple_phi_result (gs));
+ break;
- case GIMPLE_TRY:
- walk_seq_ops (gimple_try_eval (gs), func, data, pset);
- walk_seq_ops (gimple_try_cleanup (gs), func, data, pset);
- break;
+ case GIMPLE_TRY:
+ walk_seq_ops (gimple_try_eval (gs), func, data, pset);
+ walk_seq_ops (gimple_try_cleanup (gs), func, data, pset);
+ break;
- case GIMPLE_OMP_CRITICAL:
- walk_seq_ops (gimple_omp_body (gs), func, data, pset);
- WALKIT (gimple_omp_critical_name (gs));
- break;
+ case GIMPLE_OMP_CRITICAL:
+ walk_seq_ops (gimple_omp_body (gs), func, data, pset);
+ WALKIT (gimple_omp_critical_name (gs));
+ break;
- /* Just a body. */
- case GIMPLE_OMP_CONTINUE:
- case GIMPLE_OMP_MASTER:
- case GIMPLE_OMP_ORDERED:
- case GIMPLE_OMP_SECTION:
- walk_seq_ops (gimple_omp_body (gs), func, data, pset);
- break;
+ /* Just a body. */
+ case GIMPLE_OMP_CONTINUE:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ walk_seq_ops (gimple_omp_body (gs), func, data, pset);
+ break;
- case GIMPLE_OMP_FOR:
- walk_seq_ops (gimple_omp_body (gs), func, data, pset);
- WALKIT (gimple_omp_for_clauses (gs));
- WALKIT (gimple_omp_for_index (gs));
- WALKIT (gimple_omp_for_initial (gs));
- WALKIT (gimple_omp_for_final (gs));
- WALKIT (gimple_omp_for_incr (gs));
- walk_seq_ops (gimple_omp_for_pre_body (gs), func, data, pset);
- break;
+ case GIMPLE_OMP_FOR:
+ walk_seq_ops (gimple_omp_body (gs), func, data, pset);
+ WALKIT (gimple_omp_for_clauses (gs));
+ WALKIT (gimple_omp_for_index (gs));
+ WALKIT (gimple_omp_for_initial (gs));
+ WALKIT (gimple_omp_for_final (gs));
+ WALKIT (gimple_omp_for_incr (gs));
+ walk_seq_ops (gimple_omp_for_pre_body (gs), func, data, pset);
+ break;
- case GIMPLE_OMP_PARALLEL:
- walk_seq_ops (gimple_omp_body (gs), func, data, pset);
- WALKIT (gimple_omp_parallel_clauses (gs));
- WALKIT (gimple_omp_parallel_child_fn (gs));
- WALKIT (gimple_omp_parallel_data_arg (gs));
- break;
+ case GIMPLE_OMP_PARALLEL:
+ walk_seq_ops (gimple_omp_body (gs), func, data, pset);
+ WALKIT (gimple_omp_parallel_clauses (gs));
+ WALKIT (gimple_omp_parallel_child_fn (gs));
+ WALKIT (gimple_omp_parallel_data_arg (gs));
+ break;
- case GIMPLE_OMP_SECTIONS:
- walk_seq_ops (gimple_omp_body (gs), func, data, pset);
- WALKIT (gimple_omp_sections_clauses (gs));
- break;
+ case GIMPLE_OMP_SECTIONS:
+ walk_seq_ops (gimple_omp_body (gs), func, data, pset);
+ WALKIT (gimple_omp_sections_clauses (gs));
+ break;
- case GIMPLE_OMP_SINGLE:
- walk_seq_ops (gimple_omp_body (gs), func, data, pset);
- WALKIT (gimple_omp_single_clauses (gs));
- break;
+ case GIMPLE_OMP_SINGLE:
+ walk_seq_ops (gimple_omp_body (gs), func, data, pset);
+ WALKIT (gimple_omp_single_clauses (gs));
+ break;
- /* Tuples that do not have trees. */
- case GIMPLE_NOP:
- case GIMPLE_RESX:
- case GIMPLE_OMP_RETURN:
- break;
+ /* Tuples that do not have trees. */
+ case GIMPLE_NOP:
+ case GIMPLE_RESX:
+ case GIMPLE_OMP_RETURN:
+ break;
- default:
- debug_gimple_stmt (gs);
- gcc_unreachable ();
- break;
- }
+ default:
+ debug_gimple_stmt (gs);
+ gcc_unreachable ();
+ break;
+ }
}
Index: gimple.h
===================================================================
--- gimple.h (revision 126888)
+++ gimple.h (working copy)
@@ -115,8 +115,16 @@ struct gimple_statement_with_ops GTY(())
{
struct gimple_statement_base base;
unsigned modified : 1;
+
+ /* FIXME tuples. OP should be amalgamated with DEF_OPS and USE_OPS.
+ This duplication is unnecessary. */
struct def_optype_d GTY((skip)) *def_ops;
struct use_optype_d GTY((skip)) *use_ops;
+
+ /* FIXME tuples. For many tuples, the number of operands can
+ be deduced from the code. */
+ size_t num_ops;
+ tree * GTY((length ("%h.num_ops"))) op;
};
struct gimple_statement_with_memory_ops GTY(())
@@ -131,8 +139,8 @@ struct gimple_statement_with_memory_ops
struct gimple_statement_omp GTY(())
{
- struct gimple_statement_base base;
- struct gimple_sequence body;
+ struct gimple_statement_base base;
+ struct gimple_sequence body;
};
/* GIMPLE_BIND */
@@ -161,13 +169,6 @@ struct gimple_statement_eh_filter GTY(()
gimple_seq failure;
};
-/* GIMPLE_LABEL */
-struct gimple_statement_label GTY(())
-{
- struct gimple_statement_base base;
- tree label;
-};
-
/* GIMPLE_PHI */
struct gimple_statement_phi GTY(())
{
@@ -182,6 +183,7 @@ struct gimple_statement_phi GTY(())
struct gimple_statement_resx GTY(())
{
struct gimple_statement_base base;
+
/* Exception region number. */
int region;
};
@@ -190,8 +192,10 @@ struct gimple_statement_resx GTY(())
struct gimple_statement_try GTY(())
{
struct gimple_statement_base base;
+
/* Expression to evaluate. */
struct gimple_sequence eval;
+
/* Cleanup expression. */
struct gimple_sequence cleanup;
};
@@ -200,81 +204,17 @@ struct gimple_statement_try GTY(())
#define GIMPLE_TRY_CATCH 1 << 0
#define GIMPLE_TRY_FINALLY 1 << 1
-/* GIMPLE_ASSIGN */
-struct gimple_statement_assign_binary GTY(())
-{
- struct gimple_statement_with_ops with_ops;
- tree op[3];
-};
-
-struct gimple_statement_assign_unary_reg GTY(())
-{
- struct gimple_statement_with_ops with_ops;
- tree op[2];
-};
-
-struct gimple_statement_assign_unary_mem GTY(())
-{
- struct gimple_statement_with_memory_ops with_mem_ops;
- tree op[2];
-};
-
-/* GIMPLE_COND */
-struct gimple_statement_cond GTY(())
-{
- struct gimple_statement_with_ops with_ops;
- tree op[2];
- tree label_true;
- tree label_false;
-};
-
-/* GIMPLE_GOTO */
-struct gimple_statement_goto GTY(())
-{
- struct gimple_statement_with_ops with_ops;
- tree dest;
-};
-
-/* GIMPLE_SWITCH */
-struct gimple_statement_switch GTY(())
-{
- struct gimple_statement_with_ops with_ops;
- unsigned int nlabels;
- tree index;
- tree GTY ((length ("%h.nlabels + 1"))) labels[1];
-};
/* GIMPLE_ASM */
struct gimple_statement_asm GTY(())
{
struct gimple_statement_with_memory_ops with_mem_ops;
const char *string;
- /* Number of inputs. */
- unsigned ni;
- /* Number of outputs. */
- unsigned no;
- /* Number of clobbers. */
- unsigned nc;
- tree GTY ((length ("%h.ni+%h.no+%h.nc"))) op[1];
-};
-
-/* GIMPLE_CALL */
-struct gimple_statement_call GTY(())
-{
- struct gimple_statement_with_memory_ops with_mem_ops;
- tree lhs;
- tree fn;
- tree chain;
- size_t nargs;
- tree GTY ((length ("%h.nargs"))) args[1];
+ unsigned ni; /* Number of inputs. */
+ unsigned no; /* Number of outputs. */
+ unsigned nc; /* Number of clobbers. */
};
-/* GIMPLE_RETURN */
-struct gimple_statement_return GTY(())
-{
- struct gimple_statement_with_memory_ops with_mem_ops;
- tree retval;
-};
/* GIMPLE_OMP_CRITICAL */
struct gimple_statement_omp_critical GTY(())
@@ -301,6 +241,7 @@ struct gimple_statement_omp_for GTY(())
struct gimple_sequence pre_body;
};
+
/* Predicate for conds. */
enum gimple_cond {
/* These must be in sync with op_gimple_cond(). */
@@ -346,53 +287,32 @@ enum gimple_statement_structure_enum {
LAST_GSS_ENUM
};
+
/* Define the overall contents of a gimple tuple. It may be any of the
structures declared above for various types of tuples. */
union gimple_statement_d GTY ((desc ("gimple_statement_structure (&%h)")))
{
struct gimple_statement_base GTY ((tag ("GSS_BASE"))) base;
- /* We never really return GSS_WITH_OPS or GSS_WITH_MEM_OPS in
- gimple_statement_structure() since they're subsumed by the other
- tuples. We only include the tags for completeness. */
struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) with_ops;
- struct gimple_statement_with_memory_ops GTY ((tag ("GSS_WITH_MEM_OPS")))
- with_mem_ops;
+ struct gimple_statement_with_memory_ops GTY ((tag ("GSS_WITH_MEM_OPS"))) with_mem_ops;
struct gimple_statement_omp GTY ((tag ("GSS_OMP"))) omp;
-
struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gimple_bind;
struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gimple_catch;
- struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER")))
- gimple_eh_filter;
- struct gimple_statement_label GTY ((tag ("GSS_LABEL"))) gimple_label;
+ struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER"))) gimple_eh_filter;
struct gimple_statement_phi GTY ((tag ("GSS_PHI"))) gimple_phi;
struct gimple_statement_resx GTY ((tag ("GSS_RESX"))) gimple_resx;
struct gimple_statement_try GTY ((tag ("GSS_TRY"))) gimple_try;
- struct gimple_statement_assign_binary GTY ((tag ("GSS_ASSIGN_BINARY")))
- gimple_assign_binary;
- struct gimple_statement_assign_unary_reg GTY ((tag ("GSS_ASSIGN_UNARY_REG")))
- gimple_assign_unary_reg;
- struct gimple_statement_assign_unary_mem GTY ((tag ("GSS_ASSIGN_UNARY_MEM")))
- gimple_assign_unary_mem;
- struct gimple_statement_cond GTY ((tag ("GSS_COND"))) gimple_cond;
- struct gimple_statement_goto GTY ((tag ("GSS_GOTO"))) gimple_goto;
- struct gimple_statement_switch GTY ((tag ("GSS_SWITCH"))) gimple_switch;
struct gimple_statement_asm GTY ((tag ("GSS_ASM"))) gimple_asm;
- struct gimple_statement_call GTY ((tag ("GSS_CALL"))) gimple_call;
- struct gimple_statement_return GTY ((tag ("GSS_RETURN"))) gimple_return;
- struct gimple_statement_omp_critical GTY ((tag ("GSS_OMP_CRITICAL")))
- gimple_omp_critical;
+ struct gimple_statement_omp_critical GTY ((tag ("GSS_OMP_CRITICAL"))) gimple_omp_critical;
struct gimple_statement_omp_for GTY ((tag ("GSS_OMP_FOR"))) gimple_omp_for;
- struct gimple_statement_omp_parallel GTY ((tag ("GSS_OMP_PARALLEL")))
- gimple_omp_parallel;
- struct gimple_statement_omp_sections GTY ((tag ("GSS_OMP_SECTIONS")))
- gimple_omp_sections;
- struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE")))
- gimple_omp_single;
+ struct gimple_statement_omp_parallel GTY ((tag ("GSS_OMP_PARALLEL"))) gimple_omp_parallel;
+ struct gimple_statement_omp_sections GTY ((tag ("GSS_OMP_SECTIONS"))) gimple_omp_sections;
+ struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE"))) gimple_omp_single;
};
-\f
-/* Prototypes. */
+
+/* In gimple.c. */
extern gimple gimple_build_return (bool, tree);
extern gimple gimple_build_assign (tree, tree);
extern gimple gimple_build_call_vec (tree, VEC(tree, gc) *);
@@ -435,13 +355,16 @@ extern void set_gimple_body (tree, gimpl
extern gimple_seq gimple_body (tree);
extern const char *const gimple_code_name[];
-\f
+
+
/* Error out if a gimple tuple is addressed incorrectly. */
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-
extern void gimple_check_failed (const gimple, const char *, int, \
const char *, unsigned int, unsigned int) \
ATTRIBUTE_NORETURN; \
+extern void gimple_range_check_failed (const gimple, const char *, int, \
+ const char *, unsigned int, \
+ unsigned int) ATTRIBUTE_NORETURN;
#define GIMPLE_CHECK(GS, CODE) __extension__ \
({ const gimple __gs = (GS); \
@@ -457,72 +380,63 @@ extern void gimple_check_failed (const g
gimple_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \
(CODE1), (CODE2)); \
__gs; })
+#define GIMPLE_RANGE_CHECK(GS, CODE1, CODE2) __extension__ \
+ ({ const gimple __gs = (GS); \
+ if (GIMPLE_CODE (__gs) < (CODE1) || GIMPLE_CODE (__gs) > (CODE2)) \
+ gimple_range_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE1), (CODE2)); \
+ __gs; })
#else /* not ENABLE_TREE_CHECKING, or not gcc */
-#define GIMPLE_CHECK(GS, CODE) (GS)
-#define GIMPLE_CHECK2(GS, C1, C2) (GS)
+#define GIMPLE_CHECK(GS, CODE) (GS)
+#define GIMPLE_CHECK2(GS, C1, C2) (GS)
+#define GIMPLE_RANGE_CHECK(GS, CODE1, CODE2) (GS)
#endif
-\f
-/* GIMPLE IR accessor functions. */
-/* GIMPLE_ASSIGN accessors. */
-/* Get an operand in a GIMPLE_ASSIGN.
+/* GIMPLE IR accessor functions. */
- OPNO is the number of the operand to get.
- GS is a GIMPLE_ASSIGN statement. */
+/* GIMPLE_WITH_OPS and GIMPLE_WITH_MEM_OPS accessors. */
-static inline tree
-gimple_assign_operand (gimple gs, size_t opno)
+static inline size_t
+gimple_num_ops (gimple gs)
{
- enum gimple_statement_structure_enum gss;
-
- GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ GIMPLE_RANGE_CHECK (gs, GIMPLE_ASSIGN, GIMPLE_RETURN);
+ return gs->with_ops.num_ops;
+}
- gss = gimple_statement_structure (gs);
- if (gss == GSS_ASSIGN_BINARY)
- return gs->gimple_assign_binary.op[opno];
- else if (gss == GSS_ASSIGN_UNARY_REG)
- return gs->gimple_assign_unary_reg.op[opno];
- else if (gss == GSS_ASSIGN_UNARY_MEM)
- return gs->gimple_assign_unary_mem.op[opno];
+static inline tree
+gimple_op (gimple gs, size_t i)
+{
+ GIMPLE_RANGE_CHECK (gs, GIMPLE_ASSIGN, GIMPLE_RETURN);
+ gcc_assert (i < gs->with_ops.num_ops);
+ return gs->with_ops.op[i];
+}
- gcc_unreachable ();
+static inline void
+gimple_set_op (gimple gs, size_t i, tree op)
+{
+ GIMPLE_RANGE_CHECK (gs, GIMPLE_ASSIGN, GIMPLE_RETURN);
+ gcc_assert (i < gs->with_ops.num_ops);
+ gs->with_ops.op[i] = op;
}
-/* Set an operand in a GIMPLE_ASSIGN.
- OPNO is the number of the operand to set.
- GS is a GIMPLE_ASSIGN statement.
- OP is the tree to set the operand to. */
+/* GIMPLE_ASSIGN accessors. */
+
+static inline tree
+gimple_assign_operand (gimple gs, size_t opno)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ gcc_assert (gs->with_ops.num_ops > opno);
+ return gs->with_ops.op[opno];
+}
static inline void
gimple_assign_set_operand (gimple gs, size_t opno, tree op)
{
- enum gimple_statement_structure_enum gss;
-
GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
-
- gss = gimple_statement_structure (gs);
- if (gss == GSS_ASSIGN_BINARY)
- {
- gcc_assert (opno <= 2);
- gs->gimple_assign_binary.op[opno] = op;
- return;
- }
- else if (gss == GSS_ASSIGN_UNARY_REG)
- {
- gcc_assert (opno <= 1);
- gs->gimple_assign_unary_reg.op[opno] = op;
- return;
- }
- else if (gss == GSS_ASSIGN_UNARY_MEM)
- {
- gcc_assert (opno <= 1);
- gs->gimple_assign_unary_mem.op[opno] = op;
- return;
- }
-
- gcc_unreachable ();
+ gcc_assert (gs->with_ops.num_ops > opno);
+ gs->with_ops.op[opno] = op;
}
static inline tree
@@ -538,128 +452,91 @@ gimple_assign_set_lhs (gimple gs, tree l
}
static inline tree
-gimple_assign_binary_rhs1 (gimple gs)
+gimple_assign_rhs1 (gimple gs)
{
-#if defined ENABLE_CHECKING
- enum gimple_statement_structure_enum gss;
- gss = gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs));
- gcc_assert (gss == GSS_ASSIGN_BINARY);
-#endif
return gimple_assign_operand (gs, 1);
}
static inline void
-gimple_assign_binary_set_rhs1 (gimple gs, tree rhs)
+gimple_assign_set_rhs1 (gimple gs, tree rhs)
{
-#if defined ENABLE_CHECKING
- enum gimple_statement_structure_enum gss;
- gss = gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs));
- gcc_assert (gss == GSS_ASSIGN_BINARY);
-#endif
gimple_assign_set_operand (gs, 1, rhs);
}
static inline tree
-gimple_assign_binary_rhs2 (gimple gs)
+gimple_assign_rhs2 (gimple gs)
{
-#if defined ENABLE_CHECKING
- enum gimple_statement_structure_enum gss;
- gss = gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs));
- gcc_assert (gss == GSS_ASSIGN_BINARY);
-#endif
return gimple_assign_operand (gs, 2);
}
static inline void
-gimple_assign_binary_set_rhs2 (gimple gs, tree rhs)
+gimple_assign_set_rhs2 (gimple gs, tree rhs)
{
-#if defined ENABLE_CHECKING
- enum gimple_statement_structure_enum gss;
- gss = gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs));
- gcc_assert (gss == GSS_ASSIGN_BINARY);
-#endif
gimple_assign_set_operand (gs, 2, rhs);
}
-static inline tree
-gimple_assign_unary_rhs (gimple gs)
-{
-#if defined ENABLE_CHECKING
- enum gimple_statement_structure_enum gss;
- gss = gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs));
- gcc_assert (gss == GSS_ASSIGN_UNARY_REG || gss == GSS_ASSIGN_UNARY_MEM);
-#endif
- return gimple_assign_operand (gs, 1);
-}
-
-static inline void
-gimple_assign_unary_set_rhs (gimple gs, tree rhs)
-{
-#if defined ENABLE_CHECKING
- enum gimple_statement_structure_enum gss;
- gss = gss_for_assign (GIMPLE_SUBCODE_FLAGS (gs));
- gcc_assert (gss == GSS_ASSIGN_UNARY_REG || gss == GSS_ASSIGN_UNARY_MEM);
-#endif
- gimple_assign_set_operand (gs, 1, rhs);
-}
-
-
/* GIMPLE_CALL accessors. */
static inline tree
-gimple_call_fn (gimple gs)
+gimple_call_lhs (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- return gs->gimple_call.fn;
+ return gs->with_ops.op[0];
}
-static inline tree
-gimple_call_lhs (gimple gs)
+static inline void
+gimple_call_set_lhs (gimple gs, tree lhs)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- return gs->gimple_call.lhs;
+ gs->with_ops.op[0] = lhs;
}
-static inline void
-gimple_call_set_lhs (gimple gs, tree lhs)
+static inline tree
+gimple_call_fn (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- gs->gimple_call.lhs = lhs;
+ gcc_assert (gs->with_ops.num_ops > 1);
+ return gs->with_ops.op[1];
}
static inline tree
gimple_call_chain (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- return gs->gimple_call.chain;
+ gcc_assert (gs->with_ops.num_ops > 2);
+ return gs->with_ops.op[2];
}
static inline void
gimple_call_set_chain (gimple gs, tree chain)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- gs->gimple_call.chain = chain;
+ gcc_assert (gs->with_ops.num_ops > 2);
+ gs->with_ops.op[2] = chain;
}
static inline unsigned long
gimple_call_nargs (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- return gs->gimple_call.nargs;
+ gcc_assert (gs->with_ops.num_ops >= 3);
+ return gs->with_ops.num_ops - 3;
}
static inline tree
-gimple_call_arg (gimple gs, int index)
+gimple_call_arg (gimple gs, size_t index)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- return gs->gimple_call.args[index];
+ gcc_assert (gs->with_ops.num_ops > index + 3);
+ return gs->with_ops.op[index + 3];
}
static inline void
-gimple_call_set_arg (gimple gs, int index, tree arg)
+gimple_call_set_arg (gimple gs, size_t index, tree arg)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
- gs->gimple_call.args[index] = arg;
+ gcc_assert (gs->with_ops.num_ops > index + 3);
+ gs->with_ops.op[index + 3] = arg;
}
@@ -669,88 +546,105 @@ static inline tree
gimple_cond_lhs (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- return gs->gimple_cond.op[0];
+ gcc_assert (gs->with_ops.num_ops == 4);
+ return gs->with_ops.op[0];
}
static inline void
gimple_cond_set_lhs (gimple gs, tree lhs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- gs->gimple_cond.op[0] = lhs;
+ gcc_assert (gs->with_ops.num_ops == 4);
+ gs->with_ops.op[0] = lhs;
}
static inline tree
gimple_cond_rhs (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- return gs->gimple_cond.op[1];
+ gcc_assert (gs->with_ops.num_ops == 4);
+ return gs->with_ops.op[1];
}
static inline void
gimple_cond_set_rhs (gimple gs, tree rhs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- gs->gimple_cond.op[1] = rhs;
+ gcc_assert (gs->with_ops.num_ops == 4);
+ gs->with_ops.op[1] = rhs;
}
static inline tree
gimple_cond_true_label (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- return gs->gimple_cond.label_true;
+ gcc_assert (gs->with_ops.num_ops == 4);
+ return gs->with_ops.op[2];
}
static inline void
gimple_cond_set_true_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- gs->gimple_cond.label_true = label;
+ gcc_assert (gs->with_ops.num_ops == 4);
+ gs->with_ops.op[2] = label;
}
static inline void
gimple_cond_set_false_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- gs->gimple_cond.label_false = label;
+ gcc_assert (gs->with_ops.num_ops == 4);
+ gs->with_ops.op[3] = label;
}
static inline tree
gimple_cond_false_label (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
- return gs->gimple_cond.label_false;
+ gcc_assert (gs->with_ops.num_ops == 4);
+ return gs->with_ops.op[3];
}
+
/* GIMPLE_LABEL accessors. */
static inline tree
gimple_label_label (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_LABEL);
- return gs->gimple_label.label;
+ gcc_assert (gs->with_ops.num_ops == 1);
+ return gs->with_ops.op[0];
}
+
static inline void
gimple_label_set_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_LABEL);
- gs->gimple_label.label = label;
+ gcc_assert (gs->with_ops.num_ops == 1);
+ gs->with_ops.op[0] = label;
}
+
/* GIMPLE_GOTO accessors. */
static inline tree
gimple_goto_dest (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_GOTO);
- return gs->gimple_goto.dest;
+ gcc_assert (gs->with_ops.num_ops == 1);
+ return gs->with_ops.op[0];
}
+
static inline void
gimple_goto_set_dest (gimple gs, tree dest)
{
GIMPLE_CHECK (gs, GIMPLE_GOTO);
- gs->gimple_goto.dest = dest;
+ gcc_assert (gs->with_ops.num_ops == 1);
+ gs->with_ops.op[0] = dest;
}
+
/* GIMPLE_BIND accessors. */
static inline tree
@@ -768,7 +662,8 @@ gimple_bind_set_vars (gimple gs, tree va
}
static inline gimple_seq
-gimple_bind_body (gimple gs) {
+gimple_bind_body (gimple gs)
+{
GIMPLE_CHECK (gs, GIMPLE_BIND);
return &(gs->gimple_bind.body);
}
@@ -780,7 +675,9 @@ gimple_bind_set_body (gimple gs, gimple_
gimple_seq_copy (&(gs->gimple_bind.body), seq);
}
+
/* GIMPLE_ASM accessors. */
+
static inline unsigned int
gimple_asm_ninputs (gimple gs)
{
@@ -788,13 +685,6 @@ gimple_asm_ninputs (gimple gs)
return gs->gimple_asm.ni;
}
-static inline void
-gimple_asm_set_ninputs (gimple gs, unsigned ni)
-{
- GIMPLE_CHECK (gs, GIMPLE_ASM);
- gs->gimple_asm.ni = ni;
-}
-
static inline unsigned int
gimple_asm_noutputs (gimple gs)
{
@@ -802,13 +692,6 @@ gimple_asm_noutputs (gimple gs)
return gs->gimple_asm.no;
}
-static inline void
-gimple_asm_set_noutputs (gimple gs, unsigned no)
-{
- GIMPLE_CHECK (gs, GIMPLE_ASM);
- gs->gimple_asm.no = no;
-}
-
static inline unsigned int
gimple_asm_nclobbered (gimple gs)
{
@@ -816,19 +699,12 @@ gimple_asm_nclobbered (gimple gs)
return gs->gimple_asm.nc;
}
-static inline void
-gimple_asm_set_nclobbered (gimple gs, unsigned nc)
-{
- GIMPLE_CHECK (gs, GIMPLE_ASM);
- gs->gimple_asm.nc = nc;
-}
-
static inline tree
gimple_asm_input_op (gimple gs, unsigned int index)
{
GIMPLE_CHECK (gs, GIMPLE_ASM);
gcc_assert (index <= gs->gimple_asm.ni);
- return gs->gimple_asm.op[index];
+ return gs->with_ops.op[index];
}
static inline void
@@ -836,7 +712,7 @@ gimple_asm_set_input_op (gimple gs, unsi
{
GIMPLE_CHECK (gs, GIMPLE_ASM);
gcc_assert (index <= gs->gimple_asm.ni);
- gs->gimple_asm.op[index] = in_op;
+ gs->with_ops.op[index] = in_op;
}
static inline tree
@@ -844,7 +720,7 @@ gimple_asm_output_op (gimple gs, unsigne
{
GIMPLE_CHECK (gs, GIMPLE_ASM);
gcc_assert (index <= gs->gimple_asm.no);
- return gs->gimple_asm.op[index + gs->gimple_asm.ni];
+ return gs->with_ops.op[index + gs->gimple_asm.ni];
}
static inline void
@@ -852,7 +728,7 @@ gimple_asm_set_output_op (gimple gs, uns
{
GIMPLE_CHECK (gs, GIMPLE_ASM);
gcc_assert (index <= gs->gimple_asm.no);
- gs->gimple_asm.op[index + gs->gimple_asm.ni] = out_op;
+ gs->with_ops.op[index + gs->gimple_asm.ni] = out_op;
}
static inline tree
@@ -860,7 +736,7 @@ gimple_asm_clobber_op (gimple gs, unsign
{
GIMPLE_CHECK (gs, GIMPLE_ASM);
gcc_assert (index <= gs->gimple_asm.nc);
- return gs->gimple_asm.op[index + gs->gimple_asm.ni + gs->gimple_asm.no];
+ return gs->with_ops.op[index + gs->gimple_asm.ni + gs->gimple_asm.no];
}
static inline void
@@ -868,7 +744,7 @@ gimple_asm_set_clobber_op (gimple gs, un
{
GIMPLE_CHECK (gs, GIMPLE_ASM);
gcc_assert (index <= gs->gimple_asm.nc);
- gs->gimple_asm.op[index + gs->gimple_asm.ni + gs->gimple_asm.no] = clobber_op;
+ gs->with_ops.op[index + gs->gimple_asm.ni + gs->gimple_asm.no] = clobber_op;
}
static inline const char *
@@ -878,12 +754,6 @@ gimple_asm_string (gimple gs)
return gs->gimple_asm.string;
}
-static inline void
-gimple_asm_set_string (gimple gs, const char* string)
-{
- GIMPLE_CHECK (gs, GIMPLE_ASM);
- gs->gimple_asm.string = string;
-}
/* GIMPLE_CATCH accessors. */
@@ -915,6 +785,7 @@ gimple_catch_set_handler (gimple gs, gim
gs->gimple_catch.handler = handler;
}
+
/* GIMPLE_EH_FILTER accessors. */
static inline tree
@@ -976,6 +847,7 @@ gimple_try_set_cleanup (gimple gs, gimpl
gimple_seq_copy (gimple_try_cleanup (gs), cleanup);
}
+
/* GIMPLE_PHI accessors. */
static inline unsigned int
@@ -1036,6 +908,7 @@ gimple_phi_set_arg (gimple gs, unsigned
memcpy (gs->gimple_phi.args + index, phiarg, sizeof (struct phi_arg_d));
}
+
/* GIMPLE_RESX accessors. */
static inline int
@@ -1052,71 +925,69 @@ gimple_resx_set_region (gimple gs, int r
gs->gimple_resx.region = region;
}
-/* GIMPLE_SWITCH accessors. */
-static inline unsigned int
-gimple_switch_nlabels (gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- return gs->gimple_switch.nlabels;
-}
+/* GIMPLE_SWITCH accessors. */
-static inline void
-gimple_switch_set_nlabels (gimple gs, unsigned int nlabels)
+static inline size_t
+gimple_switch_num_labels (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- gs->gimple_switch.nlabels = nlabels;
+ gcc_assert (gs->with_ops.num_ops > 1);
+ return gs->with_ops.num_ops - 1;
}
static inline tree
gimple_switch_index (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- return gs->gimple_switch.index;
+ return gs->with_ops.op[0];
}
static inline void
gimple_switch_set_index (gimple gs, tree index)
{
GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- gs->gimple_switch.index = index;
+ gs->with_ops.op[0] = index;
}
static inline tree
gimple_switch_default_label (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- return gs->gimple_switch.labels[0];
+ gcc_assert (gs->with_ops.num_ops > 1);
+ return gs->with_ops.op[1];
}
static inline void
gimple_switch_set_default_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- gs->gimple_switch.labels[0] = label;
+ gcc_assert (gs->with_ops.num_ops > 1);
+ gs->with_ops.op[1] = label;
}
/* Return the label numbered INDEX. The default label is 0, followed by any
labels in a switch statement. */
static inline tree
-gimple_switch_label (gimple gs, int index)
+gimple_switch_label (gimple gs, size_t index)
{
GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- gcc_assert ((unsigned)index <= gs->gimple_switch.nlabels);
- return gs->gimple_switch.labels[index];
+ gcc_assert (gs->with_ops.num_ops > index + 1);
+ return gs->with_ops.op[index + 1];
}
/* Set the label number INDEX to LABEL. 0 is always the default label. */
static inline void
-gimple_switch_set_label (gimple gs, int index, tree label)
+gimple_switch_set_label (gimple gs, size_t index, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_SWITCH);
- gcc_assert ((unsigned)index <= gs->gimple_switch.nlabels);
- gs->gimple_switch.labels[index] = label;
+ gcc_assert (gs->with_ops.num_ops > index + 1);
+ gs->with_ops.op[index + 1] = label;
}
+
/* GIMPLE_OMP_* accessors. */
static inline gimple_seq
@@ -1332,14 +1203,16 @@ static inline tree
gimple_return_retval (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_RETURN);
- return gs->gimple_return.retval;
+ gcc_assert (gs->with_ops.num_ops == 1);
+ return gs->with_ops.op[0];
}
static inline void
gimple_return_set_retval (gimple gs, tree retval)
{
GIMPLE_CHECK (gs, GIMPLE_RETURN);
- gs->gimple_return.retval = retval;
+ gcc_assert (gs->with_ops.num_ops == 1);
+ gs->with_ops.op[0] = retval;
}
/* Append sequence SRC to the end of sequence DST. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-07-24 23:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-25 0:24 [tuples] Refactor some data structures Diego Novillo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).