> > 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