Hi! I think 2/3 operand GIMPLE_ASSIGN is the most widely used gimple type, and 128 bytes + 16/24 bytes in separate allocation for it is a lot (though, we'd need a separate extra_order_size_table for such GIMPLE_ASSIGNs if we decrease it a little bit). The low hanging fruit on 64-bit arches is moving uid right after plf (saves 8 bytes), moving modified:1 bit from gimple_statement_with_ops to gimple_statement_base (I think all users just use the accessor inlines, so where exactly it lives is gimple.h implementation detail, can have comment etc.; saves another 8 bytes) and moving has_volatile_ops:1 and references_memory_p:1 to base too (saves another 8 bytes). All this needs just minimal changes in gimple.h. To get rid of the separate with_ops.op allocation, we can either keep the current num_ops/op fields and just special case allocation, GC and gimple_copy of the 2/3 operand GIMPLE_ASSIGN - put the 16/24 byte op array into the place we just freed, so GIMPLE_ASSIGN will be back to 128 bytes, but without a separate allocation for the ops. Or, if gimple_ops, gimple_op, gimple_op_ptr, gimple_set_op and gimple_num_ops are special cased, then 16 further bytes can be saved by eliminating num_ops and the tree *op; pointer by putting the 3 operands inline - tree op[3];. This is complicated by gimple_statement_with_memory_ops containing with_ops as first field - the 4 above inlines would then need to handle GIMPLE_{COND,GOTO,LABEL,SWITCH} as one case, GIMPLE_ASSIGN (and possible GIMPLE_RETURN) as another case and GIMPLE_CALL as yet another case.
BTW, we still need just 3 flag bits and there are 3 unused bits, so that for now we are ok, but in the future gimple_statement_base has still 32 bits hole on 64-bit arches. If all code uses inline accessors, then perhaps gimple.h could use #ifdefs to differentiate between 32-bit and 64-bit hosts, use 32-bits of flags in gimple_statement_base for 64-bit hosts and for 32-bit hosts put a flag word wherever they will be actually used. I know that's ugly, but if it is all hidden in gimple.h and not otherwise exposed, then memory savings could be more important, if we still care about 32-bit hosts. struct gimple_statement_base { enum gimple_code code:16; /* 0:16 4 */ unsigned int subcode:8; /* 0: 8 4 */ unsigned int no_warning:1; /* 0: 7 4 */ unsigned int visited:1; /* 0: 6 4 */ unsigned int nontemporal_move:1; /* 0: 5 4 */ unsigned int unused_1:1; /* 0: 4 4 */ unsigned int unused_2:1; /* 0: 3 4 */ unsigned int unused_3:1; /* 0: 2 4 */ unsigned int plf:2; /* 0: 0 4 */ /* XXX 4 bytes hole, try to pack */ struct basic_block_def * bb; /* 8 8 */ location_t location; /* 16 4 */ /* XXX 4 bytes hole, try to pack */ tree block; /* 24 8 */ unsigned int uid; /* 32 4 */ /* size: 40, cachelines: 1 */ /* sum members: 28, holes: 2, sum holes: 8 */ /* padding: 4 */ /* last cacheline: 40 bytes */ }; /* definitions: 1 */ struct gimple_statement_with_ops { struct gimple_statement_base gsbase; /* 0 40 */ /* XXX last struct has 4 bytes of padding */ unsigned int modified:1; /* 40:31 4 */ /* XXX 31 bits hole, try to pack */ /* XXX 4 bytes hole, try to pack */ bitmap addresses_taken; /* 48 8 */ struct def_optype_d * def_ops; /* 56 8 */ /* --- cacheline 1 boundary (64 bytes) --- */ struct use_optype_d * use_ops; /* 64 8 */ size_t num_ops; /* 72 8 */ tree * op; /* 80 8 */ /* size: 88, cachelines: 2 */ /* sum members: 84, holes: 1, sum holes: 4 */ /* bit holes: 1, sum bit holes: 31 bits */ /* paddings: 1, sum paddings: 4 */ /* last cacheline: 24 bytes */ }; /* definitions: 1 */ struct gimple_statement_with_memory_ops { struct gimple_statement_with_ops with_ops; /* 0 88 */ /* --- cacheline 1 boundary (64 bytes) was 24 bytes ago --- */ unsigned int has_volatile_ops:1; /* 88:31 4 */ unsigned int references_memory_p:1; /* 88:30 4 */ /* XXX 30 bits hole, try to pack */ /* XXX 4 bytes hole, try to pack */ struct voptype_d * vdef_ops; /* 96 8 */ struct voptype_d * vuse_ops; /* 104 8 */ bitmap stores; /* 112 8 */ bitmap loads; /* 120 8 */ /* --- cacheline 2 boundary (128 bytes) --- */ /* size: 128, cachelines: 2 */ /* sum members: 124, holes: 1, sum holes: 4 */ /* bit holes: 1, sum bit holes: 30 bits */ }; /* definitions: 1 */ Jakub