Aldy Hernandez wrote: > Hi folks. > > Under Diego's loving whip, I've been taking a look at GIMPLE tuples, and > have come up with a possible layout for the data structures representing > the tuples. It's a mix between what Mark and Diego's originally suggested > along with a few other things ;-). > > Still missing are labels and gimple temporaries, but this should get the > ball going. > > I'm anxious to see what people think and suggest. > > Cheers. > Aldy > > > /* All tree structures, including the gimple IL, derive from this base > structure. */ > struct tree_base GTY(()) > { > ENUM_BITFIELD(tree_code) code : 8; > > unsigned side_effects_flag : 1; > unsigned constant_flag : 1; > unsigned addressable_flag : 1; > unsigned volatile_flag : 1; > unsigned readonly_flag : 1; > unsigned unsigned_flag : 1; > unsigned asm_written_flag: 1; > unsigned nowarning_flag : 1; > > unsigned used_flag : 1; > unsigned nothrow_flag : 1; > unsigned static_flag : 1; > unsigned public_flag : 1; > unsigned private_flag : 1; > unsigned protected_flag : 1; > unsigned deprecated_flag : 1; > unsigned invariant_flag : 1; > > unsigned lang_flag_0 : 1; > unsigned lang_flag_1 : 1; > unsigned lang_flag_2 : 1; > unsigned lang_flag_3 : 1; > unsigned lang_flag_4 : 1; > unsigned lang_flag_5 : 1; > unsigned lang_flag_6 : 1; > unsigned visited : 1; > }; >
You should note that the flags are only there because otherwies you are wasting padding. They don't really belong here, but it's understandable why they are there. > /* This structure is for generic trees. */ > struct tree_common GTY(()) > { > struct tree_base base; > tree chain; > tree type; > union tree_ann_d *ann; > }; Why is there a chain in tree_common? > > /* Gimple statements. > > This includes modify statements (what GENERIC calls MODIFY_EXPR), > labels, calls, gotos, etc, as well as OpenMP directives. */ > struct gimple_stmt GTY(()) > { > struct tree_base base; > source_locus locus; > struct tree_base *operands[1]; > }; > > /* Gimple expressions. > > This includes binary and unary expressions, and conditional > expressions. */ > struct gimple_expr GTY(()) > { > struct tree_base base; > tree type; > struct gimple_expr *operands[1]; > }; > > /* OpenMP clauses (error, private, shared, etc). */ > struct gimple_omp_clause GTY(()) > { > struct tree_base base; > enum omp_clause_code code; > union omp_clause_subcode { > enum omp_clause_default_kind default_kind; > enum omp_clause_schedule_kind schedule_kind; > enum tree_code reduction_code; > } GTY ((skip)) subcode; > struct tree_base ops[1]; > }; > > /* Gimple SSA names. > > This is the similar to ``tree_ssa_name'' in GENERIC except > we save a `tree_ann_d', and a `type'. We also move `ptr_info' > and `value_handle' to on-the-side arrays indexed by SSA names > (or hash tables). */ > struct gimple_ssa_name > { > struct tree_base base; > tree var; > /* `type' is in TREE_TYPE (var) */ > struct gimple_stmt def_stmt; > unsigned int version; > struct ssa_use_operand_d imm_uses; > }; > The last time i moved value handle to a hash table, FRE/PRE got like 20% slower. So if you are going to move it, you should probably take careful measurements before using a hash table, *or* use an indexed array (either is fine by me). I assume nothing has been done about array accesses or indirect refs yet due to no true consensus yet? Also, one thing to throw on your todo list about gimple temporaries/ssa_names is that a *lot* of places create one var per ssa_name for no good reason. IE foo = create_tmp_var (type); fooname = make_ssa_name (foo); This is a waste of time and VAR_DECL's unless type is always different, which in most of these cases, it's not. I stopped PRE from doing this and it helped memory usage a small amount. --Dan