> > I figured
> > it'd be better than doing GS_SEQP_FIRST(&non_pointer), but I can if you
> > prefer.
>
> I think I would, though without the "P".
Ok, everything fixed, except I haven't added the sequence iterators yet.
I am committing the patch below to the gimple-tuples-branch.
Thanks again.
* gimple-ir.c: New file.
* gimple-ir.h: New file.
* gsstruct.def: New file.
* gs.def: New file.
* gengtype.c (open_base_files): Add gimple-ir.h.
* tree-gimple.h: Include gimple-ir.h.
Add sequence to gimplify_expr and gimplify_body prototypes.
* gimplify.c: Include gimple-ir.h.
(gimplify_and_add): Adjust for gimple IR.
(gimplify_return_expr): Same.
(gimplify_stmt): Add seq_p argument.
(gimplify_expr): Add seq_p sequence and adjust accordingly.
(gimplify_body): Same.
* coretypes.h: Add gimple_statement_d and gimple definitions.
* Makefile.in (GIMPLE_IR_H): New.
(TREE_GIMPLE_H): Add gimple-ir.h.
(OBJS-common): Add gimple-ir.o.
(gimplify.o): Add GIMPLE_IR_H.
(gimple-ir.o): New.
(build/gencheck.o): Add gs.def.
Index: gimple-ir.c
===================================================================
--- gimple-ir.c (revision 0)
+++ gimple-ir.c (revision 0)
@@ -0,0 +1,154 @@
+/* Gimple IR support functions.
+
+ Copyright 2007 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <[EMAIL PROTECTED]>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "ggc.h"
+#include "errors.h"
+#include "tree-gimple.h"
+#include "gimple-ir.h"
+
+#define DEFGSCODE(SYM, NAME) NAME,
+static const char *gs_code_name[] = {
+#include "gs.def"
+};
+#undef DEFGSCODE
+
+/* Gimple tuple constructors. */
+
+/* Construct a GS_RETURN statement. */
+
+gimple
+gs_build_return (bool result_decl_p, tree retval)
+{
+ gimple p = ggc_alloc_cleared (sizeof (struct gimple_statement_return));
+
+ GS_CODE (p) = GS_RETURN;
+ GS_SUBCODE_FLAGS (p) = (int) result_decl_p;
+ GS_RETURN_OPERAND_RETVAL (p) = retval;
+ return p;
+}
+
+/* Return which gimple structure is used by T. The enums here are defined
+ in gsstruct.def. */
+
+enum gimple_statement_structure_enum
+gimple_statement_structure (gimple gs)
+{
+ unsigned int code = GS_CODE (gs);
+ unsigned int subcode = GS_SUBCODE_FLAGS (gs);
+
+ switch (code)
+ {
+ case GS_ASSIGN:
+ {
+ enum tree_code_class class = TREE_CODE_CLASS (subcode);
+
+ if (class == tcc_binary
+ || class == tcc_comparison)
+ return GSS_ASSIGN_BINARY;
+ else
+ {
+ /* 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 || subcode == SSA_NAME)
+ return GSS_ASSIGN_UNARY_REG;
+
+ /* Must be class == tcc_unary. */
+ return GSS_ASSIGN_UNARY_MEM;
+ }
+ }
+ case GS_ASM: return GSS_ASM;
+ case GS_BIND: return GSS_BIND;
+ case GS_CALL: return GSS_CALL;
+ case GS_CATCH: return GSS_CATCH;
+ case GS_COND: return GSS_COND;
+ case GS_EH_FILTER: return GSS_EH_FILTER;
+ case GS_GOTO: return GSS_GOTO;
+ case GS_LABEL: return GSS_LABEL;
+ case GS_NOP: return GSS_BASE;
+ case GS_PHI: return GSS_PHI;
+ case GS_RESX: return GSS_RESX;
+ case GS_RETURN: return GSS_RETURN;
+ case GS_SWITCH: return GSS_SWITCH;
+ case GS_TRY: return GSS_TRY;
+ case GS_OMP_CRITICAL: return GSS_OMP_CRITICAL;
+ case GS_OMP_FOR: return GSS_OMP_FOR;
+ case GS_OMP_CONTINUE:
+ case GS_OMP_MASTER:
+ case GS_OMP_ORDERED:
+ case GS_OMP_RETURN:
+ case GS_OMP_SECTION:
+ return GSS_OMP;
+ case GS_OMP_PARALLEL: return GSS_OMP_PARALLEL;
+ case GS_OMP_SECTIONS: return GSS_OMP_SECTIONS;
+ case GS_OMP_SINGLE: return GSS_OMP_SINGLE;
+ default: ;
+ }
+ gcc_unreachable ();
+ return GSS_BASE;
+}
+
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+/* Complain of a gimple type mismatch and die. */
+
+void
+gs_check_failed (const gimple gs, const char *file, int line,
+ const char *function, unsigned int code,
+ unsigned int subcode)
+{
+ internal_error ("gimple check: expected %s(%s), have %s(%s) in %s, at %s:%d",
+ gs_code_name[code],
+ tree_code_name[subcode],
+ gs_code_name[GS_CODE (gs)],
+ tree_code_name[GS_SUBCODE_FLAGS (gs)],
+ function, trim_filename (file), line);
+}
+#endif /* ENABLE_TREE_CHECKING */
+
+/* Link a gimple statement(s) to the end of the sequence SEQ. */
+
+void
+gs_add (gimple gs, gs_seq seq)
+{
+ /* Make sure this stmt is not part of another chain. */
+ gcc_assert (GS_PREV (gs) == NULL);
+
+ if (GS_SEQ_FIRST (seq) == NULL)
+ {
+ GS_SEQ_FIRST (seq) = gs;
+ GS_SEQ_LAST (seq) = gs;
+ }
+ else
+ {
+ GS_PREV (gs) = GS_SEQ_LAST (seq);
+ GS_NEXT (GS_SEQ_LAST (seq)) = gs;
+ GS_SEQ_LAST (seq) = gs;
+ }
+}
Index: gimple-ir.h
===================================================================
--- gimple-ir.h (revision 0)
+++ gimple-ir.h (revision 0)
@@ -0,0 +1,392 @@
+/* Gimple IR definitions.
+
+ Copyright 2007 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <[EMAIL PROTECTED]>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+#ifndef GCC_GIMPLE_IR_H
+#define GCC_GIMPLE_IR_H
+
+enum gs_code {
+#define DEFGSCODE(SYM, STRING) SYM,
+#include "gs.def"
+#undef DEFGSCODE
+ LAST_AND_UNUSED_GS_CODE
+};
+
+#define GS_CODE(G) ((G)->base.code)
+#define GS_SUBCODE_FLAGS(G) ((G)->base.subcode_flags)
+#define GS_NEXT(G) ((G)->base.next)
+#define GS_PREV(G) ((G)->base.prev)
+
+/* A sequences of gimple statements. */
+#define GS_SEQ_FIRST(S) (S)->first
+#define GS_SEQ_LAST(S) (S)->last
+#define GS_SEQ_INIT {0, 0}
+struct gs_sequence
+{
+ gimple first;
+ gimple last;
+};
+typedef struct gs_sequence *gs_seq;
+
+struct gimple_statement_base GTY(())
+{
+ unsigned int code : 16;
+ unsigned int subcode_flags : 16;
+ gimple next;
+ gimple prev;
+ struct basic_block_def *bb;
+ source_locus locus;
+ tree block;
+};
+
+struct gimple_statement_with_ops GTY(())
+{
+ struct gimple_statement_base base;
+ unsigned modified : 1;
+ bitmap address_taken;
+ struct def_optype_d GTY((skip)) *def_ops;
+ struct use_optype_d GTY((skip)) *use_ops;
+};
+
+struct gimple_statement_with_memory_ops GTY(())
+{
+ struct gimple_statement_with_ops with_ops;
+ unsigned has_volatile_ops : 1;
+ struct voptype_d GTY((skip)) *vdef_ops;
+ struct voptype_d GTY((skip)) *vuse_ops;
+ bitmap stores;
+ bitmap loads;
+};
+
+struct gimple_statement_omp GTY(())
+{
+ struct gimple_statement_base base;
+ struct gs_sequence body;
+};
+
+/* Gimple tuples. */
+
+/* GS_BIND */
+struct gimple_statement_bind GTY(())
+{
+ struct gimple_statement_base base;
+ tree vars;
+ struct gs_sequence body;
+};
+
+/* GS_CATCH */
+struct gimple_statement_catch GTY(())
+{
+ struct gimple_statement_base base;
+ tree types;
+ gimple handler;
+};
+
+/* GS_EH_FILTER */
+struct gimple_statement_eh_filter GTY(())
+{
+ struct gimple_statement_base base;
+ /* Filter types. */
+ tree types;
+ /* Failure actions. */
+ gimple failure;
+};
+
+/* GS_LABEL */
+struct gimple_statement_label GTY(())
+{
+ struct gimple_statement_base base;
+ tree label;
+};
+
+/* GS_PHI */
+struct gimple_statement_phi GTY(())
+{
+ struct gimple_statement_base base;
+ unsigned capacity;
+ unsigned nargs;
+ tree result;
+ struct phi_arg_d GTY ((length ("%h.nargs"))) args[1];
+};
+
+/* GS_RESX */
+struct gimple_statement_resx GTY(())
+{
+ struct gimple_statement_base base;
+ /* Exception region number. */
+ int region;
+};
+
+/* GS_TRY */
+struct gimple_statement_try GTY(())
+{
+ struct gimple_statement_base base;
+ /* Expression to evaluate. */
+ gimple eval;
+ /* Cleanup expression. */
+ gimple cleanup;
+};
+
+/* GS_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];
+};
+
+/* GS_COND */
+struct gimple_statement_cond GTY(())
+{
+ struct gimple_statement_with_ops with_ops;
+ tree op[2];
+ struct gimple_statement_label *label_true;
+ struct gimple_statement_label *label_false;
+};
+
+/* GS_GOTO */
+struct gimple_statement_goto GTY(())
+{
+ struct gimple_statement_with_ops with_ops;
+ tree dest;
+};
+
+/* GS_SWITCH */
+struct gimple_statement_switch GTY(())
+{
+ struct gimple_statement_with_ops with_ops;
+ unsigned int nlabels;
+ tree index;
+ tree default_label;
+ tree GTY ((length ("%h.nlabels + 1"))) labels[1];
+};
+
+/* GS_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"))) op[1];
+};
+
+/* GS_CALL */
+struct gimple_statement_call GTY(())
+{
+ struct gimple_statement_with_memory_ops with_mem_ops;
+ tree lhs;
+ tree fn;
+ tree chain;
+ unsigned long nargs;
+ tree GTY ((length ("%h.nargs"))) args[1];
+};
+
+/* GS_RETURN */
+struct gimple_statement_return GTY(())
+{
+ struct gimple_statement_with_memory_ops with_mem_ops;
+ tree retval;
+};
+
+/* GS_OMP_CRITICAL */
+struct gimple_statement_omp_critical GTY(())
+{
+ struct gimple_statement_omp omp;
+ /* Critical section name. */
+ tree name;
+};
+
+/* GS_OMP_FOR */
+struct gimple_statement_omp_for GTY(())
+{
+ struct gimple_statement_omp omp;
+ tree clauses;
+ /* Index variable. */
+ tree index;
+ /* Initial value. */
+ tree initial;
+ /* Final value. */
+ tree final;
+ /* Increment. */
+ tree incr;
+ /* Pre-body evaluated before the loop body begins. */
+ struct gs_sequence pre_body;
+};
+
+/* GS_OMP_PARALLEL */
+struct gimple_statement_omp_parallel GTY(())
+{
+ struct gimple_statement_omp omp;
+ tree clauses;
+ tree child_fn;
+ /* Shared data argument. */
+ tree data_arg;
+};
+
+/* GS_OMP_SECTION */
+/* Uses struct gimple_statement_omp. */
+
+/* GS_OMP_SECTIONS */
+struct gimple_statement_omp_sections GTY(())
+{
+ struct gimple_statement_omp omp;
+ tree clauses;
+};
+
+/* GS_OMP_SINGLE */
+struct gimple_statement_omp_single GTY(())
+{
+ struct gimple_statement_omp omp;
+ tree clauses;
+};
+
+enum gimple_statement_structure_enum {
+#define DEFGSSTRUCT(SYM, STRING) SYM,
+#include "gsstruct.def"
+#undef DEFGSSTRUCT
+ 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_omp GTY ((tag ("GSS_OMP"))) omp;
+
+ struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gs_bind;
+ struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gs_catch;
+ struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER"))) gs_eh_filter;
+ struct gimple_statement_label GTY ((tag ("GSS_LABEL"))) gs_label;
+ struct gimple_statement_phi GTY ((tag ("GSS_PHI"))) gs_phi;
+ struct gimple_statement_resx GTY ((tag ("GSS_RESX"))) gs_resx;
+ struct gimple_statement_try GTY ((tag ("GSS_TRY"))) gs_try;
+ struct gimple_statement_assign_binary GTY ((tag ("GSS_ASSIGN_BINARY")))
gs_assign_binary;
+ struct gimple_statement_assign_unary_reg GTY ((tag
("GSS_ASSIGN_UNARY_REG"))) gs_assign_unary_reg;
+ struct gimple_statement_assign_unary_mem GTY ((tag
("GSS_ASSIGN_UNARY_MEM"))) gs_assign_unary_mem;
+ struct gimple_statement_cond GTY ((tag ("GSS_COND"))) gs_cond;
+ struct gimple_statement_goto GTY ((tag ("GSS_GOTO"))) gs_goto;
+ struct gimple_statement_switch GTY ((tag ("GSS_SWITCH"))) gs_switch;
+ struct gimple_statement_asm GTY ((tag ("GSS_ASM"))) gs_asm;
+ struct gimple_statement_call GTY ((tag ("GSS_CALL"))) gs_call;
+ struct gimple_statement_return GTY ((tag ("GSS_RETURN"))) gs_return;
+ struct gimple_statement_omp_critical GTY ((tag ("GSS_OMP_CRITICAL")))
gs_omp_critical;
+ struct gimple_statement_omp_for GTY ((tag ("GSS_OMP_FOR"))) gs_omp_for;
+ struct gimple_statement_omp_parallel GTY ((tag ("GSS_OMP_PARALLEL")))
gs_omp_parallel;
+ struct gimple_statement_omp_sections GTY ((tag ("GSS_OMP_SECTIONS")))
gs_omp_sections;
+ struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE")))
gs_omp_single;
+};
+
+/* Error out if a gimple tuple is addressed incorrectly. */
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+
+extern void gs_check_failed (const gimple, const char *, int, const char *, \
+ unsigned int, unsigned int) ATTRIBUTE_NORETURN;
+
+#define GS_CHECK(GS, CODE) __extension__ \
+ ({ const gimple __gs = (GS);
\
+ if (GS_CODE (__gs) != (CODE)) \
+ gs_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE), 0); \
+ __gs; })
+
+#define GS_CHECK2(GS, CODE1, CODE2) __extension__ \
+ ({ const gimple __gs = (GS);
\
+ if (GS_CODE (__gs) != (CODE1) \
+ || GS_SUBCODE_FLAGS (__gs) != (CODE2)) \
+ gs_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE1), (CODE2)); \
+ __gs; })
+#else /* not ENABLE_TREE_CHECKING, or not gcc */
+#define GS_CHECK(GS, CODE) (GS)
+#define GS_CHECK2(GS, C1, C2) (GS)
+#endif
+
+/* GIMPLE IR accessor functions. */
+
+/* GS_ASSIGN accessors. */
+static inline tree
+gs_assign_operand (gimple gs, int opno)
+{
+ enum gimple_statement_structure gss;
+
+ GS_CHECK (gs, GS_ASSIGN);
+
+ gss = gimple_statement_structure (gs);
+ if (gss == GSS_ASSIGN_BINARY)
+ return gs->gs_assign_binary.op[opno];
+ else if (gss == GSS_ASSIGN_UNARY_REG)
+ return gs->gs_assign_unary_reg[opno];
+ else if (gss == GSS_ASSIGN_UNARY_MEM)
+ return gs->gs_assign_unary_mem[opno];
+
+ gcc_unreachable ();
+ return NULL;
+}
+
+static inline tree
+gs_assign_operand_lhs (gimple gs)
+{
+ return gs_assign_operand (gs, 0);
+}
+
+static inline tree
+gs_assign_operand_rhs (gimple gs)
+{
+ return gs_assign_operand (gs, 1);
+}
+
+/* GS_RETURN accessors. */
+static inline tree *
+gs_return_operand_retval (gimple gs)
+{
+ return &GS_CHECK (gs, GS_RETURN)->gs_return.retval;
+}
+
+#define GS_RETURN_OPERAND_RETVAL(G) (*gs_return_operand_retval ((G)))
+
+#endif /* GCC_GIMPLE_IR_H */
+
+extern gimple gs_build_return (bool, tree);
+extern enum gimple_statement_structure_enum gimple_statement_structure
(gimple);
+extern void gs_add (gimple, gs_seq);
Index: gsstruct.def
===================================================================
--- gsstruct.def (revision 0)
+++ gsstruct.def (revision 0)
@@ -0,0 +1,55 @@
+/* This file contains the definitions for the gimple IR structure
+ enumeration used in GCC.
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <[EMAIL PROTECTED]>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (GSS_at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+/* 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.
+ */
+
+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")
+DEFGSSTRUCT(GSS_OMP_SECTIONS, "sections")
+DEFGSSTRUCT(GSS_OMP_SINGLE, "single")
Index: gs.def
===================================================================
--- gs.def (revision 0)
+++ gs.def (revision 0)
@@ -0,0 +1,58 @@
+/* This file contains the definitions in the gimple IR tuples used in GCC.
+
+ Copyright (GS_C) 2007 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <[EMAIL PROTECTED]>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (GS_at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+/* The format of this file is
+ DEFGSCODE(GS_symbol, printable name).
+
+ Where symbol is the enumeration name without the ``GS_''.
+ */
+
+DEFGSCODE(GS_BASE, "gs_base")
+DEFGSCODE(GS_WITH_OPS, "gs_with_ops")
+DEFGSCODE(GS_WITH_MEM_OPS, "gs_with_mem_ops")
+DEFGSCODE(GS_OMP, "gs_omp")
+
+DEFGSCODE(GS_BIND, "gs_bind")
+DEFGSCODE(GS_CATCH, "gs_catch")
+DEFGSCODE(GS_EH_FILTER, "gs_eh_filter")
+DEFGSCODE(GS_LABEL, "gs_label")
+DEFGSCODE(GS_PHI, "gs_phi")
+DEFGSCODE(GS_RESX, "gs_resx")
+DEFGSCODE(GS_TRY, "gs_try")
+DEFGSCODE(GS_ASSIGN, "gs_assign")
+DEFGSCODE(GS_COND, "gs_cond")
+DEFGSCODE(GS_GOTO, "gs_goto")
+DEFGSCODE(GS_SWITCH, "gs_switch")
+DEFGSCODE(GS_ASM, "gs_asm")
+DEFGSCODE(GS_CALL, "gs_call")
+DEFGSCODE(GS_NOP, "gs_nop")
+DEFGSCODE(GS_RETURN, "gs_return")
+DEFGSCODE(GS_OMP_CONTINUE, "gs_omp_continue")
+DEFGSCODE(GS_OMP_CRITICAL, "gs_omp_critical")
+DEFGSCODE(GS_OMP_FOR, "gs_omp_for")
+DEFGSCODE(GS_OMP_MASTER, "gs_omp_master")
+DEFGSCODE(GS_OMP_ORDERED, "gs_omp_ordered")
+DEFGSCODE(GS_OMP_PARALLEL, "gs_omp_parallel")
+DEFGSCODE(GS_OMP_RETURN, "gs_omp_return")
+DEFGSCODE(GS_OMP_SECTION, "gs_omp_section")
+DEFGSCODE(GS_OMP_SECTIONS, "gs_omp_sections")
+DEFGSCODE(GS_OMP_SINGLE, "gs_omp_single")
Index: gengtype.c
===================================================================
--- gengtype.c (revision 124007)
+++ gengtype.c (working copy)
@@ -1534,7 +1534,7 @@ open_base_files (void)
"hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
"tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
- "cfglayout.h", "except.h", "output.h", NULL
+ "cfglayout.h", "except.h", "output.h", "gimple-ir.h", NULL
};
const char *const *ifp;
outf_p gtype_desc_c;
Index: tree-gimple.h
===================================================================
--- tree-gimple.h (revision 124007)
+++ tree-gimple.h (working copy)
@@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA. */
#include "tree-iterator.h"
+#include "gimple-ir.h"
extern tree create_tmp_var_raw (tree, const char *);
extern tree create_tmp_var_name (const char *);
@@ -110,13 +111,13 @@ enum gimplify_status {
GS_ALL_DONE = 1 /* The expression is fully gimplified. */
};
-extern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
+extern enum gimplify_status gimplify_expr (tree *, gs_seq, tree *, tree *,
bool (*) (tree), fallback_t);
extern void gimplify_type_sizes (tree, tree *);
extern void gimplify_one_sizepos (tree *, tree *);
extern void gimplify_stmt (tree *);
extern void gimplify_to_stmt_list (tree *);
-extern void gimplify_body (tree *, tree, bool);
+extern void gimplify_body (tree *, gs_seq, tree, bool);
extern void push_gimplify_context (void);
extern void pop_gimplify_context (tree);
extern void gimplify_and_add (tree, tree *);
Index: gimplify.c
===================================================================
--- gimplify.c (revision 124007)
+++ gimplify.c (working copy)
@@ -50,6 +50,7 @@ Software Foundation, 51 Franklin Street,
#include "optabs.h"
#include "pointer-set.h"
#include "splay-tree.h"
+#include "gimple-ir.h"
enum gimplify_omp_var_data
@@ -335,10 +336,13 @@ append_to_statement_list_force (tree t,
/* Both gimplify the statement T and append it to LIST_P. */
void
-gimplify_and_add (tree t, tree *list_p)
+gimplify_and_add (tree t, gs_seq seq)
{
- gimplify_stmt (&t);
- append_to_statement_list (t, list_p);
+ struct gs_sequence tseq = GS_SEQ_INIT;
+
+ gimplify_stmt (&t, &tseq);
+ if (TREE_SIDE_EFFECTS (GS_SEQ_FIRST (*tseq)))
+ gs_add (GS_SEQ_FIRST (*tseq), seq);
}
/* Strip off a legitimate source ending from the input string NAME of
@@ -1129,18 +1133,22 @@ gimplify_bind_expr (tree *expr_p, tree *
GIMPLE value, it is assigned to a new temporary and the statement is
re-written to return the temporary.
- PRE_P points to the list where side effects that must happen before
+ PRE_P points to the sequence where side effects that must happen before
STMT should be stored. */
static enum gimplify_status
-gimplify_return_expr (tree stmt, tree *pre_p)
+gimplify_return_expr (tree stmt, gs_seq seq_p, gs_seq pre_p)
{
tree ret_expr = TREE_OPERAND (stmt, 0);
tree result_decl, result;
if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL
|| ret_expr == error_mark_node)
- return GS_ALL_DONE;
+ {
+ gs_add (gs_build_return (TREE_CODE (ret_expr) == RESULT_DECL, ret_expr),
+ seq_p);
+ return GS_ALL_DONE;
+ }
if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
result_decl = NULL_TREE;
@@ -1199,7 +1207,7 @@ gimplify_return_expr (tree stmt, tree *p
ret_expr = result;
else
ret_expr = build_gimple_modify_stmt (result_decl, result);
- TREE_OPERAND (stmt, 0) = ret_expr;
+ gs_add (gs_build_return (result == result_decl, ret_expr), seq_p);
return GS_ALL_DONE;
}
@@ -4325,13 +4333,12 @@ gimplify_target_expr (tree *expr_p, tree
/* Gimplification of expression trees. */
-/* Gimplify an expression which appears at statement context; usually, this
- means replacing it with a suitably gimple STATEMENT_LIST. */
+/* Gimplify an expression which appears at statement context. */; usually,
this
void
-gimplify_stmt (tree *stmt_p)
+gimplify_stmt (tree *stmt_p, gs_seq seq_p)
{
- gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none);
+ gimplify_expr (stmt_p, seq_p, NULL, NULL, is_gimple_stmt, fb_none);
}
/* Similarly, but force the result to be a STATEMENT_LIST. */
@@ -5387,8 +5394,8 @@ gimplify_omp_atomic (tree *expr_p, tree
return gimplify_omp_atomic_mutex (expr_p, pre_p, addr, rhs);
}
-/* Gimplifies the expression tree pointed to by EXPR_P. Return 0 if
- gimplification failed.
+/* Gimplifies the expression tree pointed to by EXPR_P into SEQ_P.
+ Return 0 if gimplification failed.
PRE_P points to the list where side effects that must happen before
EXPR should be stored.
@@ -5417,7 +5424,7 @@ gimplify_omp_atomic (tree *expr_p, tree
iterates until solution. */
enum gimplify_status
-gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
+gimplify_expr (tree *expr_p, gs_seq seq_p, gs_seq pre_p, gs_seq post_p,
bool (* gimple_test_f) (tree), fallback_t fallback)
{
tree tmp;
@@ -5565,7 +5572,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
case TRUTH_NOT_EXPR:
TREE_OPERAND (*expr_p, 0)
= gimple_boolify (TREE_OPERAND (*expr_p, 0));
- ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p, post_p,
is_gimple_val, fb_rvalue);
recalculate_side_effects (*expr_p);
break;
@@ -5604,7 +5611,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
case FIX_TRUNC_EXPR:
/* unary_expr: ... | '(' cast ')' val | ... */
- ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p, post_p,
is_gimple_val, fb_rvalue);
recalculate_side_effects (*expr_p);
break;
@@ -5616,7 +5623,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
/* else fall through. */
case ALIGN_INDIRECT_REF:
case MISALIGNED_INDIRECT_REF:
- ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p, post_p,
is_gimple_reg, fb_rvalue);
recalculate_side_effects (*expr_p);
break;
@@ -5670,7 +5677,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
/* If the target is not LABEL, then it is a computed jump
and the target needs to be gimplified. */
if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
- ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
+ ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), seq_p, pre_p,
NULL, is_gimple_val, fb_rvalue);
break;
@@ -5685,7 +5692,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
break;
case RETURN_EXPR:
- ret = gimplify_return_expr (*expr_p, pre_p);
+ ret = gimplify_return_expr (*expr_p, seq_p, pre_p);
break;
case CONSTRUCTOR:
@@ -5733,12 +5740,12 @@ gimplify_expr (tree *expr_p, tree *pre_p
{
enum gimplify_status r0, r1, r2;
- r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
- is_gimple_lvalue, fb_either);
- r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
- is_gimple_val, fb_rvalue);
- r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p,
- is_gimple_val, fb_rvalue);
+ r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p,
+ pre_p, post_p, is_gimple_lvalue, fb_either);
+ r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), seq_p,
+ pre_p, post_p, is_gimple_val, fb_rvalue);
+ r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), seq_p,
+ pre_p, post_p, is_gimple_val, fb_rvalue);
recalculate_side_effects (*expr_p);
ret = MIN (r0, MIN (r1, r2));
@@ -5781,10 +5788,10 @@ gimplify_expr (tree *expr_p, tree *pre_p
case OBJ_TYPE_REF:
{
enum gimplify_status r0, r1;
- r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p,
- is_gimple_val, fb_rvalue);
- r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
- is_gimple_val, fb_rvalue);
+ r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), seq_p,
+ pre_p, post_p, is_gimple_val, fb_rvalue);
+ r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), seq_p,
+ pre_p, post_p, is_gimple_val, fb_rvalue);
ret = MIN (r0, r1);
}
break;
@@ -5803,10 +5810,10 @@ gimplify_expr (tree *expr_p, tree *pre_p
case WITH_SIZE_EXPR:
{
- gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p,
post_p == &internal_post ? NULL : post_p,
gimple_test_f, fallback);
- gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
+ gimplify_expr (&TREE_OPERAND (*expr_p, 1), seq_p, pre_p, post_p,
is_gimple_val, fb_rvalue);
}
break;
@@ -5887,7 +5894,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
/* If *EXPR_P does not need to be special-cased, handle it
according to its class. */
case tcc_unary:
- ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p,
post_p, is_gimple_val, fb_rvalue);
break;
@@ -5896,9 +5903,9 @@ gimplify_expr (tree *expr_p, tree *pre_p
{
enum gimplify_status r0, r1;
- r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p,
post_p, is_gimple_val, fb_rvalue);
- r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
+ r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), seq_p, pre_p,
post_p, is_gimple_val, fb_rvalue);
ret = MIN (r0, r1);
@@ -5959,15 +5966,15 @@ gimplify_expr (tree *expr_p, tree *pre_p
case REALPART_EXPR:
case IMAGPART_EXPR:
case VIEW_CONVERT_EXPR:
- gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p, post_p,
gimple_test_f, fallback);
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
- gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ gimplify_expr (&TREE_OPERAND (*expr_p, 0), seq_p, pre_p, post_p,
gimple_test_f, fallback);
- gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
+ gimplify_expr (&TREE_OPERAND (*expr_p, 1), seq_p, pre_p, post_p,
gimple_test_f, fallback);
break;
@@ -6049,7 +6056,7 @@ gimplify_expr (tree *expr_p, tree *pre_p
in a temporary, and replace the expression with an INDIRECT_REF of
that temporary. */
tmp = build_fold_addr_expr (*expr_p);
- gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
+ gimplify_expr (&tmp, seq_p, pre_p, post_p, is_gimple_reg, fb_rvalue);
*expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
}
else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p))
@@ -6209,7 +6216,7 @@ gimplify_one_sizepos (tree *expr_p, tree
type = TREE_TYPE (expr);
*expr_p = unshare_expr (expr);
- gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
+ gimplify_expr (expr_p, seq_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
expr = *expr_p;
/* Verify that we've an exact type match with the original expression.
@@ -6319,7 +6326,7 @@ check_pointer_types_r (tree *tp, int *wa
function decl containing BODY. */
void
-gimplify_body (tree *body_p, tree fndecl, bool do_parms)
+gimplify_body (tree *body_p, gs_seq seq_p, tree fndecl, bool do_parms)
{
location_t saved_location = input_location;
tree body, parm_stmts;
@@ -6397,6 +6404,7 @@ void
gimplify_function_tree (tree fndecl)
{
tree oldfn, parm, ret;
+ struct gs_sequence seq = GS_SEQ_INIT;
oldfn = current_function_decl;
current_function_decl = fndecl;
@@ -6422,7 +6430,7 @@ gimplify_function_tree (tree fndecl)
&& !needs_to_live_in_memory (ret))
DECL_GIMPLE_REG_P (ret) = 1;
- gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
+ gimplify_body (&DECL_SAVED_TREE (fndecl), &seq, fndecl, true);
/* If we're instrumenting function entry/exit, then prepend the call to
the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
Index: coretypes.h
===================================================================
--- coretypes.h (revision 124007)
+++ coretypes.h (working copy)
@@ -45,6 +45,8 @@ struct rtvec_def;
typedef struct rtvec_def *rtvec;
union tree_node;
typedef union tree_node *tree;
+union gimple_statement_d;
+typedef union gimple_statement_d *gimple;
union section;
typedef union section section;
Index: Makefile.in
===================================================================
--- Makefile.in (revision 124007)
+++ Makefile.in (working copy)
@@ -734,6 +734,7 @@ PARAMS_H = params.h params.def
BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
input.h statistics.h vec.h treestruct.def $(HASHTAB_H)
+GIMPLE_IR_H = gimple-ir.h gs.def gsstruct.def
BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
hard-reg-set.h cfghooks.h $(OBSTACK_H)
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
@@ -775,7 +776,7 @@ MKDEPS_H = $(srcdir)/../libcpp/include/m
SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h
CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
-TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
+TREE_GIMPLE_H = tree-gimple.h tree-iterator.h gimple-ir.h
TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h $(TREE_GIMPLE_H) \
$(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H)
@@ -1004,6 +1005,7 @@ OBJS-common = \
gcse.o \
genrtl.o \
ggc-common.o \
+ gimple-ir.o \
gimple-low.o \
gimplify.o \
global.o \
@@ -2125,7 +2127,7 @@ c-gimplify.o : c-gimplify.c $(CONFIG_H)
$(FLAGS_H) langhooks.h toplev.h $(RTL_H) $(TREE_FLOW_H) $(LANGHOOKS_DEF_H) \
$(TM_H) coretypes.h $(C_PRETTY_PRINT_H) $(CGRAPH_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(TREE_DUMP_H) $(TREE_INLINE_H)
-gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
+gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_IR_H) \
$(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
$(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
@@ -2189,6 +2191,8 @@ tree-object-size.o: tree-object-size.c $
tree-gimple.o : tree-gimple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
$(RTL_H) $(TREE_GIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H) \
output.h $(TREE_FLOW_H)
+gimple-ir.o : gimple-ir.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
+ $(GGC_H) $(TREE_GIMPLE_H) $(GIMPLE_IR_H)
tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
$(TREE_GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(CGRAPH_H) $(GGC_H) \
@@ -3041,7 +3045,7 @@ build/genautomata.o : genautomata.c $(RT
$(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h vec.h \
$(HASHTAB_H) gensupport.h
build/gencheck.o : gencheck.c gencheck.h tree.def $(BCONFIG_H) $(GTM_H)
\
- $(SYSTEM_H) coretypes.h $(lang_tree_files)
+ $(SYSTEM_H) coretypes.h $(lang_tree_files) gs.def
build/genchecksum.o : genchecksum.c $(BCONFIG_H) $(SYSTEM_H) $(MD5_H)
build/gencodes.o : gencodes.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h gensupport.h