From 40d7cd0fd78fe2004e2a53c4618c148339b02733 Mon Sep 17 00:00:00 2001 From: Jing Yu Date: Mon, 19 Dec 2011 16:56:54 -0800 Subject: Add gcc-4.6. Synced to @180989 Change-Id: Ie3676586e1d8e3c8cd9f07d022f450d05fa08439 svn://gcc.gnu.org/svn/gcc/branches/google/gcc-4_6-mobile --- gcc-4.6/gcc/tree-ssa-ter.c | 796 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 796 insertions(+) create mode 100644 gcc-4.6/gcc/tree-ssa-ter.c (limited to 'gcc-4.6/gcc/tree-ssa-ter.c') diff --git a/gcc-4.6/gcc/tree-ssa-ter.c b/gcc-4.6/gcc/tree-ssa-ter.c new file mode 100644 index 000000000..af8aae04a --- /dev/null +++ b/gcc-4.6/gcc/tree-ssa-ter.c @@ -0,0 +1,796 @@ +/* Routines for performing Temporary Expression Replacement (TER) in SSA trees. + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. + Contributed by Andrew MacLeod + +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 3, 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 COPYING3. If not see +. */ + + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "tree-pretty-print.h" +#include "gimple-pretty-print.h" +#include "bitmap.h" +#include "tree-flow.h" +#include "tree-dump.h" +#include "tree-ssa-live.h" +#include "flags.h" + + +/* Temporary Expression Replacement (TER) + + Replace SSA version variables during out-of-ssa with their defining + expression if there is only one use of the variable. + + This pass is required in order for the RTL expansion pass to see larger + chunks of code. This allows it to make better choices on RTL pattern + selection. When expand is rewritten and merged with out-of-ssa, and + understands SSA, this should be eliminated. + + A pass is made through the function, one block at a time. No cross block + information is tracked. + + Variables which only have one use, and whose defining stmt is considered + a replaceable expression (see is_replaceable_p) are tracked to see whether + they can be replaced at their use location. + + n_12 = C * 10 + a_2 = b_5 + 6 + v_9 = a_2 * n_12 + + if there are the only use of n_12 and a_2, TER will substitute in their + expressions in v_9, and end up with: + + v_9 = (b_5 + 6) * (C * 10) + + which will then have the ssa_name assigned to regular variables, and the + resulting code which will be passed to the expander looks something like: + + v = (b + 6) * (C * 10) + + + This requires ensuring that none of the variables used by the expression + change between the def point and where it is used. Furthermore, if any + of the ssa_names used in this expression are themselves replaceable, we + have to ensure none of that expressions' arguments change either. + Although SSA_NAMES themselves don't change, this pass is performed after + coalescing has coalesced different SSA_NAMES together, so there could be a + definition of an SSA_NAME which is coalesced with a use that causes a + problem, i.e., + + PHI b_5 = + <...> + a_2 = b_5 + 6 + b_8 = c_4 + 4 + v_9 = a_2 * n_12 + <...> + + If b_5, b_8 and b_14 are all coalesced together... + The expression b_5 + 6 CANNOT replace the use in the statement defining v_9 + because b_8 is in fact killing the value of b_5 since they share a partition + and will be assigned the same memory or register location. + + TER implements this but stepping through the instructions in a block and + tracking potential expressions for replacement, and the partitions they are + dependent on. Expressions are represented by the SSA_NAME_VERSION of the + DEF on the LHS of a GIMPLE_ASSIGN and the expression is the RHS. + + When a stmt is determined to be a possible replacement expression, the + following steps are taken: + + EXPR_DECL_UID bitmap is allocated and set to the base variable UID of the + def and any uses in the expression. non-NULL means the expression is being + tracked. The UID's themselves are used to prevent TER substitution into + accumulating sequences, i.e., + + x = x + y + x = x + z + x = x + w + etc. + this can result in very large expressions which don't accomplish anything + see PR tree-optimization/17549. + + PARTITION_DEPENDENCIES is another bitmap array, and it has a bit set for any + partition which is used in the expression. This is primarily used to remove + an expression from the partition kill lists when a decision is made whether + to replace it or not. This is indexed by ssa version number as well, and + indicates a partition number. virtual operands are not tracked individually, + but they are summarized by an artificial partition called VIRTUAL_PARTITION. + This means a MAY or MUST def will kill *ALL* expressions that are dependent + on a virtual operand. + Note that the EXPR_DECL_UID and this bitmap represent very similar + information, but the info in one is not easy to obtain from the other. + + KILL_LIST is yet another bitmap array, this time it is indexed by partition + number, and represents a list of active expressions which will will no + longer be valid if a definition into this partition takes place. + + PARTITION_IN_USE is simply a bitmap which is used to track which partitions + currently have something in their kill list. This is used at the end of + a block to clear out the KILL_LIST bitmaps at the end of each block. + + NEW_REPLACEABLE_DEPENDENCIES is used as a temporary place to store + dependencies which will be reused by the current definition. All the uses + on an expression are processed before anything else is done. If a use is + determined to be a replaceable expression AND the current stmt is also going + to be replaceable, all the dependencies of this replaceable use will be + picked up by the current stmt's expression. Rather than recreate them, they + are simply copied here and then copied into the new expression when it is + processed. + + a_2 = b_5 + 6 + v_8 = a_2 + c_4 + + a_2's expression 'b_5 + 6' is determined to be replaceable at the use + location. It is dependent on the partition 'b_5' is in. This is cached into + the NEW_REPLACEABLE_DEPENDENCIES bitmap, and when v_8 is examined for + replaceability, it is a candidate, and it is dependent on the partition + b_5 is in *NOT* a_2, as well as c_4's partition. + + if v_8 is also replaceable: + + x_9 = v_8 * 5 + + x_9 is dependent on partitions b_5, and c_4 + + if a statement is found which has either of those partitions written to + before x_9 is used, then x_9 itself is NOT replaceable. */ + + +/* Temporary Expression Replacement (TER) table information. */ + +typedef struct temp_expr_table_d +{ + var_map map; + bitmap *partition_dependencies; /* Partitions expr is dependent on. */ + bitmap replaceable_expressions; /* Replacement expression table. */ + bitmap *expr_decl_uids; /* Base uids of exprs. */ + bitmap *kill_list; /* Expr's killed by a partition. */ + int virtual_partition; /* Pseudo partition for virtual ops. */ + bitmap partition_in_use; /* Partitions with kill entries. */ + bitmap new_replaceable_dependencies; /* Holding place for pending dep's. */ + int *num_in_part; /* # of ssa_names in a partition. */ + int *call_cnt; /* Call count at definition. */ +} *temp_expr_table_p; + +/* Used to indicate a dependency on VDEFs. */ +#define VIRTUAL_PARTITION(table) (table->virtual_partition) + +#ifdef ENABLE_CHECKING +extern void debug_ter (FILE *, temp_expr_table_p); +#endif + + +/* Create a new TER table for MAP. */ + +static temp_expr_table_p +new_temp_expr_table (var_map map) +{ + temp_expr_table_p t; + unsigned x; + + t = XNEW (struct temp_expr_table_d); + t->map = map; + + t->partition_dependencies = XCNEWVEC (bitmap, num_ssa_names + 1); + t->expr_decl_uids = XCNEWVEC (bitmap, num_ssa_names + 1); + t->kill_list = XCNEWVEC (bitmap, num_var_partitions (map) + 1); + + t->partition_in_use = BITMAP_ALLOC (NULL); + + t->virtual_partition = num_var_partitions (map); + t->new_replaceable_dependencies = BITMAP_ALLOC (NULL); + + t->replaceable_expressions = NULL; + t->num_in_part = XCNEWVEC (int, num_var_partitions (map)); + for (x = 1; x < num_ssa_names; x++) + { + int p; + tree name = ssa_name (x); + if (!name) + continue; + p = var_to_partition (map, name); + if (p != NO_PARTITION) + t->num_in_part[p]++; + } + t->call_cnt = XCNEWVEC (int, num_ssa_names + 1); + + return t; +} + + +/* Free TER table T. If there are valid replacements, return the expression + vector. */ + +static bitmap +free_temp_expr_table (temp_expr_table_p t) +{ + bitmap ret = NULL; + +#ifdef ENABLE_CHECKING + unsigned x; + for (x = 0; x <= num_var_partitions (t->map); x++) + gcc_assert (!t->kill_list[x]); + for (x = 0; x < num_ssa_names; x++) + { + gcc_assert (t->expr_decl_uids[x] == NULL); + gcc_assert (t->partition_dependencies[x] == NULL); + } +#endif + + BITMAP_FREE (t->partition_in_use); + BITMAP_FREE (t->new_replaceable_dependencies); + + free (t->expr_decl_uids); + free (t->kill_list); + free (t->partition_dependencies); + free (t->num_in_part); + free (t->call_cnt); + + if (t->replaceable_expressions) + ret = t->replaceable_expressions; + + free (t); + return ret; +} + + +/* Return TRUE if VERSION is to be replaced by an expression in TAB. */ + +static inline bool +version_to_be_replaced_p (temp_expr_table_p tab, int version) +{ + if (!tab->replaceable_expressions) + return false; + return bitmap_bit_p (tab->replaceable_expressions, version); +} + + +/* Add partition P to the list if partitions VERSION is dependent on. TAB is + the expression table */ + +static inline void +make_dependent_on_partition (temp_expr_table_p tab, int version, int p) +{ + if (!tab->partition_dependencies[version]) + tab->partition_dependencies[version] = BITMAP_ALLOC (NULL); + + bitmap_set_bit (tab->partition_dependencies[version], p); +} + + +/* Add VER to the kill list for P. TAB is the expression table */ + +static inline void +add_to_partition_kill_list (temp_expr_table_p tab, int p, int ver) +{ + if (!tab->kill_list[p]) + { + tab->kill_list[p] = BITMAP_ALLOC (NULL); + bitmap_set_bit (tab->partition_in_use, p); + } + bitmap_set_bit (tab->kill_list[p], ver); +} + + +/* Remove VER from the partition kill list for P. TAB is the expression + table. */ + +static inline void +remove_from_partition_kill_list (temp_expr_table_p tab, int p, int version) +{ + gcc_checking_assert (tab->kill_list[p]); + bitmap_clear_bit (tab->kill_list[p], version); + if (bitmap_empty_p (tab->kill_list[p])) + { + bitmap_clear_bit (tab->partition_in_use, p); + BITMAP_FREE (tab->kill_list[p]); + } +} + + +/* Add a dependency between the def of ssa VERSION and VAR. If VAR is + replaceable by an expression, add a dependence each of the elements of the + expression. These are contained in the new_replaceable list. TAB is the + expression table. */ + +static void +add_dependence (temp_expr_table_p tab, int version, tree var) +{ + int i; + bitmap_iterator bi; + unsigned x; + + i = SSA_NAME_VERSION (var); + if (version_to_be_replaced_p (tab, i)) + { + if (!bitmap_empty_p (tab->new_replaceable_dependencies)) + { + /* Version will now be killed by a write to any partition the + substituted expression would have been killed by. */ + EXECUTE_IF_SET_IN_BITMAP (tab->new_replaceable_dependencies, 0, x, bi) + add_to_partition_kill_list (tab, x, version); + + /* Rather than set partition_dependencies and in_use lists bit by + bit, simply OR in the new_replaceable_dependencies bits. */ + if (!tab->partition_dependencies[version]) + tab->partition_dependencies[version] = BITMAP_ALLOC (NULL); + bitmap_ior_into (tab->partition_dependencies[version], + tab->new_replaceable_dependencies); + bitmap_ior_into (tab->partition_in_use, + tab->new_replaceable_dependencies); + /* It is only necessary to add these once. */ + bitmap_clear (tab->new_replaceable_dependencies); + } + } + else + { + i = var_to_partition (tab->map, var); + gcc_checking_assert (i != NO_PARTITION); + gcc_checking_assert (tab->num_in_part[i] != 0); + /* Only dependencies on ssa_names which are coalesced with something need + to be tracked. Partitions with containing only a single SSA_NAME + *cannot* have their value changed. */ + if (tab->num_in_part[i] > 1) + { + add_to_partition_kill_list (tab, i, version); + make_dependent_on_partition (tab, version, i); + } + } +} + + +/* Return TRUE if expression STMT is suitable for replacement. + TER is true if is_replaceable_p is called from within TER, false + when used from within stmt_is_replaceable_p, i.e. EXPAND_INITIALIZER + expansion. The differences are that with !TER some tests are skipped + to make it more aggressive (doesn't require the same bb, or for -O0 + same locus and same BLOCK), on the other side never considers memory + loads as replaceable, because those don't ever lead into constant + expressions. */ + +static inline bool +is_replaceable_p (gimple stmt, bool ter) +{ + use_operand_p use_p; + tree def; + gimple use_stmt; + location_t locus1, locus2; + tree block1, block2; + + /* Only consider modify stmts. */ + if (!is_gimple_assign (stmt)) + return false; + + /* If the statement may throw an exception, it cannot be replaced. */ + if (stmt_could_throw_p (stmt)) + return false; + + /* Punt if there is more than 1 def. */ + def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); + if (!def) + return false; + + /* Only consider definitions which have a single use. */ + if (!single_imm_use (def, &use_p, &use_stmt)) + return false; + + /* If the use isn't in this block, it wont be replaced either. */ + if (ter && gimple_bb (use_stmt) != gimple_bb (stmt)) + return false; + + locus1 = gimple_location (stmt); + block1 = gimple_block (stmt); + + if (gimple_code (use_stmt) == GIMPLE_PHI) + { + locus2 = 0; + block2 = NULL_TREE; + } + else + { + locus2 = gimple_location (use_stmt); + block2 = gimple_block (use_stmt); + } + + if (!optimize + && ter + && ((locus1 && locus1 != locus2) || (block1 && block1 != block2))) + return false; + + /* Used in this block, but at the TOP of the block, not the end. */ + if (gimple_code (use_stmt) == GIMPLE_PHI) + return false; + + /* There must be no VDEFs. */ + if (gimple_vdef (stmt)) + return false; + + /* Without alias info we can't move around loads. */ + if ((!optimize || !ter) + && gimple_assign_single_p (stmt) + && !is_gimple_val (gimple_assign_rhs1 (stmt))) + return false; + + /* Float expressions must go through memory if float-store is on. */ + if (flag_float_store + && FLOAT_TYPE_P (gimple_expr_type (stmt))) + return false; + + /* An assignment with a register variable on the RHS is not + replaceable. */ + if (gimple_assign_rhs_code (stmt) == VAR_DECL + && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))) + return false; + + /* No function calls can be replaced. */ + if (is_gimple_call (stmt)) + return false; + + /* Leave any stmt with volatile operands alone as well. */ + if (gimple_has_volatile_ops (stmt)) + return false; + + return true; +} + + +/* Variant of is_replaceable_p test for use in EXPAND_INITIALIZER + expansion. */ + +bool +stmt_is_replaceable_p (gimple stmt) +{ + return is_replaceable_p (stmt, false); +} + + +/* This function will remove the expression for VERSION from replacement + consideration in table TAB. If FREE_EXPR is true, then remove the + expression from consideration as well by freeing the decl uid bitmap. */ + +static void +finished_with_expr (temp_expr_table_p tab, int version, bool free_expr) +{ + unsigned i; + bitmap_iterator bi; + + /* Remove this expression from its dependent lists. The partition dependence + list is retained and transfered later to whomever uses this version. */ + if (tab->partition_dependencies[version]) + { + EXECUTE_IF_SET_IN_BITMAP (tab->partition_dependencies[version], 0, i, bi) + remove_from_partition_kill_list (tab, i, version); + BITMAP_FREE (tab->partition_dependencies[version]); + } + if (free_expr) + BITMAP_FREE (tab->expr_decl_uids[version]); +} + + +/* Create an expression entry for a replaceable expression. */ + +static void +process_replaceable (temp_expr_table_p tab, gimple stmt, int call_cnt) +{ + tree var, def, basevar; + int version; + ssa_op_iter iter; + bitmap def_vars, use_vars; + + gcc_checking_assert (is_replaceable_p (stmt, true)); + + def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); + version = SSA_NAME_VERSION (def); + basevar = SSA_NAME_VAR (def); + def_vars = BITMAP_ALLOC (NULL); + + bitmap_set_bit (def_vars, DECL_UID (basevar)); + + /* Add this expression to the dependency list for each use partition. */ + FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE) + { + int var_version = SSA_NAME_VERSION (var); + + use_vars = tab->expr_decl_uids[var_version]; + add_dependence (tab, version, var); + if (use_vars) + { + bitmap_ior_into (def_vars, use_vars); + BITMAP_FREE (tab->expr_decl_uids[var_version]); + } + else + bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var))); + } + tab->expr_decl_uids[version] = def_vars; + + /* If there are VUSES, add a dependence on virtual defs. */ + if (gimple_vuse (stmt)) + { + make_dependent_on_partition (tab, version, VIRTUAL_PARTITION (tab)); + add_to_partition_kill_list (tab, VIRTUAL_PARTITION (tab), version); + } + + tab->call_cnt[version] = call_cnt; +} + + +/* This function removes any expression in TAB which is dependent on PARTITION + from consideration, making it not replaceable. */ + +static inline void +kill_expr (temp_expr_table_p tab, int partition) +{ + unsigned version; + + /* Mark every active expr dependent on this var as not replaceable. + finished_with_expr can modify the bitmap, so we can't execute over it. */ + while (tab->kill_list[partition]) + { + version = bitmap_first_set_bit (tab->kill_list[partition]); + finished_with_expr (tab, version, true); + } + + gcc_checking_assert (!tab->kill_list[partition]); +} + + +/* This function kills all expressions in TAB which are dependent on virtual + partitions. */ + +static inline void +kill_virtual_exprs (temp_expr_table_p tab) +{ + kill_expr (tab, VIRTUAL_PARTITION (tab)); +} + + +/* Mark the expression associated with VAR as replaceable, and enter + the defining stmt into the partition_dependencies table TAB. If + MORE_REPLACING is true, accumulate the pending partition dependencies. */ + +static void +mark_replaceable (temp_expr_table_p tab, tree var, bool more_replacing) +{ + int version = SSA_NAME_VERSION (var); + + /* Move the dependence list to the pending listpending. */ + if (more_replacing && tab->partition_dependencies[version]) + bitmap_ior_into (tab->new_replaceable_dependencies, + tab->partition_dependencies[version]); + + finished_with_expr (tab, version, !more_replacing); + + /* Set the replaceable expression. */ + if (!tab->replaceable_expressions) + tab->replaceable_expressions = BITMAP_ALLOC (NULL); + bitmap_set_bit (tab->replaceable_expressions, version); +} + + +/* This function processes basic block BB, and looks for variables which can + be replaced by their expressions. Results are stored in the table TAB. */ + +static void +find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb) +{ + gimple_stmt_iterator bsi; + gimple stmt; + tree def, use, fndecl; + int partition; + var_map map = tab->map; + ssa_op_iter iter; + bool stmt_replaceable; + int cur_call_cnt = 0; + + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + stmt = gsi_stmt (bsi); + + if (is_gimple_debug (stmt)) + continue; + + stmt_replaceable = is_replaceable_p (stmt, true); + + /* Determine if this stmt finishes an existing expression. */ + FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) + { + unsigned ver = SSA_NAME_VERSION (use); + + /* If this use is a potential replacement variable, process it. */ + if (tab->expr_decl_uids[ver]) + { + bool same_root_var = false; + ssa_op_iter iter2; + bitmap vars = tab->expr_decl_uids[ver]; + + /* See if the root variables are the same. If they are, we + do not want to do the replacement to avoid problems with + code size, see PR tree-optimization/17549. */ + if (!bitmap_empty_p (vars)) + FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF) + { + if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def)))) + { + same_root_var = true; + break; + } + } + + /* If the stmt does a memory store and the replacement + is a load aliasing it avoid creating overlapping + assignments which we cannot expand correctly. */ + if (gimple_vdef (stmt) + && gimple_assign_single_p (stmt)) + { + gimple def_stmt = SSA_NAME_DEF_STMT (use); + while (is_gimple_assign (def_stmt) + && gimple_assign_rhs_code (def_stmt) == SSA_NAME) + def_stmt + = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt)); + if (gimple_vuse (def_stmt) + && gimple_assign_single_p (def_stmt) + && refs_may_alias_p (gimple_assign_lhs (stmt), + gimple_assign_rhs1 (def_stmt))) + same_root_var = true; + } + + /* Mark expression as replaceable unless stmt is volatile, or the + def variable has the same root variable as something in the + substitution list, or the def and use span a call such that + we'll expand lifetimes across a call. */ + if (gimple_has_volatile_ops (stmt) || same_root_var + || (tab->call_cnt[ver] != cur_call_cnt + && SINGLE_SSA_USE_OPERAND (SSA_NAME_DEF_STMT (use), SSA_OP_USE) + == NULL_USE_OPERAND_P)) + finished_with_expr (tab, ver, true); + else + mark_replaceable (tab, use, stmt_replaceable); + } + } + + /* Next, see if this stmt kills off an active expression. */ + FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF) + { + partition = var_to_partition (map, def); + if (partition != NO_PARTITION && tab->kill_list[partition]) + kill_expr (tab, partition); + } + + /* Increment counter if this is a non BUILT_IN call. We allow + replacement over BUILT_IN calls since many will expand to inline + insns instead of a true call. */ + if (is_gimple_call (stmt) + && !((fndecl = gimple_call_fndecl (stmt)) + && DECL_BUILT_IN (fndecl))) + cur_call_cnt++; + + /* Now see if we are creating a new expression or not. */ + if (stmt_replaceable) + process_replaceable (tab, stmt, cur_call_cnt); + + /* Free any unused dependency lists. */ + bitmap_clear (tab->new_replaceable_dependencies); + + /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand, + including the current stmt. */ + if (gimple_vdef (stmt)) + kill_virtual_exprs (tab); + } +} + + +/* This function is the driver routine for replacement of temporary expressions + in the SSA->normal phase, operating on MAP. If there are replaceable + expressions, a table is returned which maps SSA versions to the + expressions they should be replaced with. A NULL_TREE indicates no + replacement should take place. If there are no replacements at all, + NULL is returned by the function, otherwise an expression vector indexed + by SSA_NAME version numbers. */ + +extern bitmap +find_replaceable_exprs (var_map map) +{ + basic_block bb; + temp_expr_table_p table; + bitmap ret; + + table = new_temp_expr_table (map); + FOR_EACH_BB (bb) + { + find_replaceable_in_bb (table, bb); + gcc_checking_assert (bitmap_empty_p (table->partition_in_use)); + } + + ret = free_temp_expr_table (table); + return ret; +} + +/* Dump TER expression table EXPR to file F. */ + +void +dump_replaceable_exprs (FILE *f, bitmap expr) +{ + tree var; + unsigned x; + + fprintf (f, "\nReplacing Expressions\n"); + for (x = 0; x < num_ssa_names; x++) + if (bitmap_bit_p (expr, x)) + { + var = ssa_name (x); + print_generic_expr (f, var, TDF_SLIM); + fprintf (f, " replace with --> "); + print_gimple_stmt (f, SSA_NAME_DEF_STMT (var), 0, TDF_SLIM); + fprintf (f, "\n"); + } + fprintf (f, "\n"); +} + + +#ifdef ENABLE_CHECKING +/* Dump the status of the various tables in the expression table. This is used + exclusively to debug TER. F is the place to send debug info and T is the + table being debugged. */ + +DEBUG_FUNCTION void +debug_ter (FILE *f, temp_expr_table_p t) +{ + unsigned x, y; + bitmap_iterator bi; + + fprintf (f, "\nDumping current state of TER\n virtual partition = %d\n", + VIRTUAL_PARTITION (t)); + if (t->replaceable_expressions) + dump_replaceable_exprs (f, t->replaceable_expressions); + fprintf (f, "Currently tracking the following expressions:\n"); + + for (x = 1; x < num_ssa_names; x++) + if (t->expr_decl_uids[x]) + { + print_generic_expr (f, ssa_name (x), TDF_SLIM); + fprintf (f, " dep-parts : "); + if (t->partition_dependencies[x] + && !bitmap_empty_p (t->partition_dependencies[x])) + { + EXECUTE_IF_SET_IN_BITMAP (t->partition_dependencies[x], 0, y, bi) + fprintf (f, "P%d ",y); + } + fprintf (f, " basedecls: "); + EXECUTE_IF_SET_IN_BITMAP (t->expr_decl_uids[x], 0, y, bi) + fprintf (f, "%d ",y); + fprintf (f, " call_cnt : %d",t->call_cnt[x]); + fprintf (f, "\n"); + } + + bitmap_print (f, t->partition_in_use, "Partitions in use ", + "\npartition KILL lists:\n"); + + for (x = 0; x <= num_var_partitions (t->map); x++) + if (t->kill_list[x]) + { + fprintf (f, "Partition %d : ", x); + EXECUTE_IF_SET_IN_BITMAP (t->kill_list[x], 0, y, bi) + fprintf (f, "_%d ",y); + } + + fprintf (f, "\n----------\n"); +} +#endif -- cgit v1.2.3