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, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
#include "config.h"
#include "system.h"
static bool
is_sra_candidate_decl (tree decl)
{
- return DECL_P (decl) && bitmap_bit_p (sra_candidates, var_ann (decl)->uid);
+ return DECL_P (decl) && bitmap_bit_p (sra_candidates, DECL_UID (decl));
}
/* Return true if TYPE is a scalar type. */
instantiated, just that if we decide to break up the type into
separate pieces that it can be done. */
-static bool
-type_can_be_decomposed_p (tree type)
+bool
+sra_type_can_be_decomposed_p (tree type)
{
unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
tree t;
}
/* We must be able to decompose the variable's type. */
- if (!type_can_be_decomposed_p (TREE_TYPE (var)))
+ if (!sra_type_can_be_decomposed_p (TREE_TYPE (var)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
{
if (is_sra_scalar_type (type))
return true;
- if (!type_can_be_decomposed_p (type))
+ if (!sra_type_can_be_decomposed_p (type))
return false;
switch (TREE_CODE (type))
if (TREE_CODE (child) == PARM_DECL)
{
elt->n_copies = 1;
- bitmap_set_bit (needs_copy_in, var_ann (child)->uid);
+ bitmap_set_bit (needs_copy_in, DECL_UID (child));
}
}
goto use_all;
case ARRAY_RANGE_REF:
- /* Similarly, an subrange reference is used to modify indexing. Which
+ /* Similarly, a subrange reference is used to modify indexing. Which
means that the canonical element names that we have won't work. */
goto use_all;
static bool
find_candidates_for_sra (void)
{
- size_t i;
bool any_set = false;
+ tree var;
+ referenced_var_iterator rvi;
- for (i = 0; i < num_referenced_vars; i++)
+ FOR_EACH_REFERENCED_VAR (var, rvi)
{
- tree var = referenced_var (i);
if (decl_can_be_decomposed_p (var))
{
- bitmap_set_bit (sra_candidates, var_ann (var)->uid);
+ bitmap_set_bit (sra_candidates, DECL_UID (var));
any_set = true;
}
}
{
build_element_name_1 (elt);
obstack_1grow (&sra_obstack, '\0');
- return obstack_finish (&sra_obstack);
+ return XOBFINISH (&sra_obstack, char *);
}
/* Instantiate an element as an independent variable. */
else if (host_integerp (size_tree, 1))
{
unsigned HOST_WIDE_INT full_size, inst_size = 0;
- unsigned int max_size;
+ unsigned int max_size, max_count, inst_count, full_count;
/* If the sra-max-structure-size parameter is 0, then the
user has not overridden the parameter and we can choose a
max_size = SRA_MAX_STRUCTURE_SIZE
? SRA_MAX_STRUCTURE_SIZE
: MOVE_RATIO * UNITS_PER_WORD;
+ max_count = SRA_MAX_STRUCTURE_COUNT
+ ? SRA_MAX_STRUCTURE_COUNT
+ : MOVE_RATIO;
full_size = tree_low_cst (size_tree, 1);
+ full_count = count_type_elements (elt->type, false);
+ inst_count = sum_instantiated_sizes (elt, &inst_size);
/* ??? What to do here. If there are two fields, and we've only
instantiated one, then instantiating the other is clearly a win.
/* If the structure is small, and we've made copies, go ahead
and instantiate, hoping that the copies will go away. */
if (full_size <= max_size
+ && (full_count - inst_count) <= max_count
&& elt->n_copies > elt->n_uses)
use_block_copy = false;
- else
- {
- sum_instantiated_sizes (elt, &inst_size);
-
- if (inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
- use_block_copy = false;
- }
+ else if (inst_count * 100 >= full_count * SRA_FIELD_STRUCTURE_RATIO
+ && inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
+ use_block_copy = false;
/* In order to avoid block copy, we have to be able to instantiate
all elements of the type. See if this is possible. */
struct sra_elt *c;
tree t;
- if (elt->replacement)
+ if (!copy_out && TREE_CODE (expr) == SSA_NAME
+ && TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
+ {
+ tree r, i;
+
+ c = lookup_element (elt, integer_zero_node, NULL, NO_INSERT);
+ r = c->replacement;
+ c = lookup_element (elt, integer_one_node, NULL, NO_INSERT);
+ i = c->replacement;
+
+ t = build (COMPLEX_EXPR, elt->type, r, i);
+ t = build (MODIFY_EXPR, void_type_node, expr, t);
+ SSA_NAME_DEF_STMT (expr) = t;
+ append_to_statement_list (t, list_p);
+ }
+ else if (elt->replacement)
{
if (copy_out)
t = build (MODIFY_EXPR, void_type_node, elt->replacement, expr);
enum tree_code init_code;
struct sra_elt *sub;
tree t;
+ unsigned HOST_WIDE_INT idx;
+ tree value, purpose;
/* We can be passed DECL_INITIAL of a static variable. It might have a
conversion, which we strip off here. */
break;
case CONSTRUCTOR:
- for (t = CONSTRUCTOR_ELTS (init); t ; t = TREE_CHAIN (t))
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, purpose, value)
{
- tree purpose = TREE_PURPOSE (t);
- tree value = TREE_VALUE (t);
-
if (TREE_CODE (purpose) == RANGE_EXPR)
{
tree lower = TREE_OPERAND (purpose, 0);
if (ret && *list_p)
{
tree_stmt_iterator i;
- size_t old, new, j;
-
- old = num_referenced_vars;
for (i = tsi_start (*list_p); !tsi_end_p (i); tsi_next (&i))
find_new_referenced_vars (tsi_stmt_ptr (i));
-
- new = num_referenced_vars;
- for (j = old; j < new; ++j)
- mark_sym_for_renaming (referenced_var (j));
}
return ret;
/* Helper function to insert LIST before BSI, and set up line number info. */
-static void
+void
sra_insert_before (block_stmt_iterator *bsi, tree list)
{
tree stmt = bsi_stmt (*bsi);
/* Similarly, but insert after BSI. Handles insertion onto edges as well. */
-static void
+void
sra_insert_after (block_stmt_iterator *bsi, tree list)
{
tree stmt = bsi_stmt (*bsi);
fputc ('\n', stderr);
}
+void
+sra_init_cache (void)
+{
+ if (sra_type_decomp_cache)
+ return;
+
+ sra_type_decomp_cache = BITMAP_ALLOC (NULL);
+ sra_type_inst_cache = BITMAP_ALLOC (NULL);
+}
+
/* Main entry point. */
static void
gcc_obstack_init (&sra_obstack);
sra_candidates = BITMAP_ALLOC (NULL);
needs_copy_in = BITMAP_ALLOC (NULL);
- sra_type_decomp_cache = BITMAP_ALLOC (NULL);
- sra_type_inst_cache = BITMAP_ALLOC (NULL);
+ sra_init_cache ();
sra_map = htab_create (101, sra_elt_hash, sra_elt_eq, NULL);
/* Scan. If we find anything, instantiate and scalarize. */