This makes the linked list of dependent stmts a vector instead. Saves separate allocation / free of list entries and overall some memory (overhead for vecs is less than 50%).
Bootstrap and regtest on x86_64-unknown-linux-gnu running. Richard. 2013-03-13 Richard Biener <rguent...@suse.de> * tree-ssa-loop-im.c (struct depend): Remove. (struct lim_aux_data): Make depends a vec of gimples. (free_lim_aux_data): Adjust. (add_dependency): Likewise. (set_level): Likewise. Index: trunk/gcc/tree-ssa-loop-im.c =================================================================== *** trunk.orig/gcc/tree-ssa-loop-im.c 2013-03-13 14:19:17.000000000 +0100 --- trunk/gcc/tree-ssa-loop-im.c 2013-03-13 15:38:55.835709837 +0100 *************** along with GCC; see the file COPYING3. *** 58,72 **** something; } */ - /* A type for the list of statements that have to be moved in order to be able - to hoist an invariant computation. */ - - struct depend - { - gimple stmt; - struct depend *next; - }; - /* The auxiliary data kept for each statement. */ struct lim_aux_data --- 58,63 ---- *************** struct lim_aux_data *** 85,95 **** unsigned cost; /* Cost of the computation performed by the statement. */ ! struct depend *depends; /* List of statements that must be also hoisted ! out of the loop when this statement is ! hoisted; i.e. those that define the operands ! of the statement and are inside of the ! MAX_LOOP loop. */ }; /* Maps statements to their lim_aux_data. */ --- 76,86 ---- unsigned cost; /* Cost of the computation performed by the statement. */ ! vec<gimple> depends; /* Vector of statements that must be also ! hoisted out of the loop when this statement ! is hoisted; i.e. those that define the ! operands of the statement and are inside of ! the MAX_LOOP loop. */ }; /* Maps statements to their lim_aux_data. */ *************** get_lim_data (gimple stmt) *** 204,216 **** static void free_lim_aux_data (struct lim_aux_data *data) { ! struct depend *dep, *next; ! ! for (dep = data->depends; dep; dep = next) ! { ! next = dep->next; ! free (dep); ! } free (data); } --- 195,201 ---- static void free_lim_aux_data (struct lim_aux_data *data) { ! data->depends.release(); free (data); } *************** add_dependency (tree def, struct lim_aux *** 475,481 **** gimple def_stmt = SSA_NAME_DEF_STMT (def); basic_block def_bb = gimple_bb (def_stmt); struct loop *max_loop; - struct depend *dep; struct lim_aux_data *def_data; if (!def_bb) --- 460,465 ---- *************** add_dependency (tree def, struct lim_aux *** 500,509 **** && def_bb->loop_father == loop) data->cost += def_data->cost; ! dep = XNEW (struct depend); ! dep->stmt = def_stmt; ! dep->next = data->depends; ! data->depends = dep; return true; } --- 484,490 ---- && def_bb->loop_father == loop) data->cost += def_data->cost; ! data->depends.safe_push (def_stmt); return true; } *************** static void *** 866,873 **** set_level (gimple stmt, struct loop *orig_loop, struct loop *level) { struct loop *stmt_loop = gimple_bb (stmt)->loop_father; - struct depend *dep; struct lim_aux_data *lim_data; stmt_loop = find_common_loop (orig_loop, stmt_loop); lim_data = get_lim_data (stmt); --- 847,855 ---- set_level (gimple stmt, struct loop *orig_loop, struct loop *level) { struct loop *stmt_loop = gimple_bb (stmt)->loop_father; struct lim_aux_data *lim_data; + gimple dep_stmt; + unsigned i; stmt_loop = find_common_loop (orig_loop, stmt_loop); lim_data = get_lim_data (stmt); *************** set_level (gimple stmt, struct loop *ori *** 881,888 **** || flow_loop_nested_p (lim_data->max_loop, level)); lim_data->tgt_loop = level; ! for (dep = lim_data->depends; dep; dep = dep->next) ! set_level (dep->stmt, orig_loop, level); } /* Determines an outermost loop from that we want to hoist the statement STMT. --- 863,870 ---- || flow_loop_nested_p (lim_data->max_loop, level)); lim_data->tgt_loop = level; ! FOR_EACH_VEC_ELT (lim_data->depends, i, dep_stmt) ! set_level (dep_stmt, orig_loop, level); } /* Determines an outermost loop from that we want to hoist the statement STMT.