Mercurial > hg > CbC > CbC_gcc
diff gcc/tree-dfa.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/tree-dfa.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/tree-dfa.c Tue Mar 22 17:18:12 2011 +0900 @@ -30,12 +30,10 @@ #include "basic-block.h" #include "output.h" #include "timevar.h" -#include "expr.h" #include "ggc.h" #include "langhooks.h" #include "flags.h" #include "function.h" -#include "diagnostic.h" #include "tree-pretty-print.h" #include "tree-dump.h" #include "gimple.h" @@ -136,7 +134,7 @@ || TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL); - ann = GGC_CNEW (struct var_ann_d); + ann = ggc_alloc_cleared_var_ann_d (); *DECL_VAR_ANN_PTR (t) = ann; return ann; @@ -220,7 +218,7 @@ fprintf (file, "\nReferenced variables in %s: %u\n\n", get_name (current_function_decl), (unsigned) num_referenced_vars); - FOR_EACH_REFERENCED_VAR (var, rvi) + FOR_EACH_REFERENCED_VAR (cfun, var, rvi) { fprintf (file, "Variable: "); dump_variable (file, var); @@ -232,7 +230,7 @@ /* Dump the list of all the referenced variables to stderr. */ -void +DEBUG_FUNCTION void debug_referenced_vars (void) { dump_referenced_vars (stderr); @@ -244,8 +242,6 @@ void dump_variable (FILE *file, tree var) { - var_ann_t ann; - if (TREE_CODE (var) == SSA_NAME) { if (POINTER_TYPE_P (TREE_TYPE (var))) @@ -261,8 +257,6 @@ print_generic_expr (file, var, dump_flags); - ann = var_ann (var); - fprintf (file, ", UID D.%u", (unsigned) DECL_UID (var)); if (DECL_PT_UID (var) != DECL_UID (var)) fprintf (file, ", PT-UID D.%u", (unsigned) DECL_PT_UID (var)); @@ -279,14 +273,6 @@ if (TREE_THIS_VOLATILE (var)) fprintf (file, ", is volatile"); - if (ann && ann->noalias_state == NO_ALIAS) - fprintf (file, ", NO_ALIAS (does not alias other NO_ALIAS symbols)"); - else if (ann && ann->noalias_state == NO_ALIAS_GLOBAL) - fprintf (file, ", NO_ALIAS_GLOBAL (does not alias other NO_ALIAS symbols" - " and global vars)"); - else if (ann && ann->noalias_state == NO_ALIAS_ANYTHING) - fprintf (file, ", NO_ALIAS_ANYTHING (does not alias any other symbols)"); - if (cfun && gimple_default_def (cfun, var)) { fprintf (file, ", default def: "); @@ -305,7 +291,7 @@ /* Dump variable VAR and its may-aliases to stderr. */ -void +DEBUG_FUNCTION void debug_variable (tree var) { dump_variable (stderr, var); @@ -392,7 +378,7 @@ /* Dump DFA statistics on stderr. */ -void +DEBUG_FUNCTION void debug_dfa_stats (void) { dump_dfa_stats (stderr); @@ -414,7 +400,7 @@ memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d)); /* Count all the variable annotations. */ - FOR_EACH_REFERENCED_VAR (var, vi) + FOR_EACH_REFERENCED_VAR (cfun, var, vi) if (var_ann (var)) dfa_stats_p->num_var_anns++; @@ -502,13 +488,12 @@ variable. */ tree -referenced_var_lookup (unsigned int uid) +referenced_var_lookup (struct function *fn, unsigned int uid) { tree h; struct tree_decl_minimal in; in.uid = uid; - h = (tree) htab_find_with_hash (gimple_referenced_vars (cfun), &in, uid); - gcc_assert (h || uid == 0); + h = (tree) htab_find_with_hash (gimple_referenced_vars (fn), &in, uid); return h; } @@ -783,9 +768,9 @@ && maxsize != -1) { tree stype = TREE_TYPE (TREE_OPERAND (exp, 0)); - tree next = TREE_CHAIN (field); + tree next = DECL_CHAIN (field); while (next && TREE_CODE (next) != FIELD_DECL) - next = TREE_CHAIN (next); + next = DECL_CHAIN (next); if (!next || TREE_CODE (stype) != RECORD_TYPE) { @@ -869,6 +854,61 @@ case VIEW_CONVERT_EXPR: break; + case MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR) + { + if (integer_zerop (TREE_OPERAND (exp, 1))) + exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + else + { + double_int off = mem_ref_offset (exp); + off = double_int_lshift (off, + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); + off = double_int_add (off, shwi_to_double_int (bit_offset)); + if (double_int_fits_in_shwi_p (off)) + { + bit_offset = double_int_to_shwi (off); + exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + } + } + } + goto done; + + case TARGET_MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR) + { + /* Via the variable index or index2 we can reach the + whole object. */ + if (TMR_INDEX (exp) || TMR_INDEX2 (exp)) + { + exp = TREE_OPERAND (TMR_BASE (exp), 0); + bit_offset = 0; + maxsize = -1; + goto done; + } + if (integer_zerop (TMR_OFFSET (exp))) + exp = TREE_OPERAND (TMR_BASE (exp), 0); + else + { + double_int off = mem_ref_offset (exp); + off = double_int_lshift (off, + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); + off = double_int_add (off, shwi_to_double_int (bit_offset)); + if (double_int_fits_in_shwi_p (off)) + { + bit_offset = double_int_to_shwi (off); + exp = TREE_OPERAND (TMR_BASE (exp), 0); + } + } + } + goto done; + default: goto done; } @@ -915,6 +955,120 @@ return exp; } +/* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that + denotes the starting address of the memory access EXP. + Returns NULL_TREE if the offset is not constant or any component + is not BITS_PER_UNIT-aligned. */ + +tree +get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset) +{ + HOST_WIDE_INT byte_offset = 0; + + /* Compute cumulative byte-offset for nested component-refs and array-refs, + and find the ultimate containing object. */ + while (1) + { + switch (TREE_CODE (exp)) + { + case BIT_FIELD_REF: + return NULL_TREE; + + case COMPONENT_REF: + { + tree field = TREE_OPERAND (exp, 1); + tree this_offset = component_ref_field_offset (exp); + HOST_WIDE_INT hthis_offset; + + if (!this_offset + || TREE_CODE (this_offset) != INTEGER_CST + || (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)) + % BITS_PER_UNIT)) + return NULL_TREE; + + hthis_offset = TREE_INT_CST_LOW (this_offset); + hthis_offset += (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)) + / BITS_PER_UNIT); + byte_offset += hthis_offset; + } + break; + + case ARRAY_REF: + case ARRAY_RANGE_REF: + { + tree index = TREE_OPERAND (exp, 1); + tree low_bound, unit_size; + + /* If the resulting bit-offset is constant, track it. */ + if (TREE_CODE (index) == INTEGER_CST + && (low_bound = array_ref_low_bound (exp), + TREE_CODE (low_bound) == INTEGER_CST) + && (unit_size = array_ref_element_size (exp), + TREE_CODE (unit_size) == INTEGER_CST)) + { + HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index); + + hindex -= TREE_INT_CST_LOW (low_bound); + hindex *= TREE_INT_CST_LOW (unit_size); + byte_offset += hindex; + } + else + return NULL_TREE; + } + break; + + case REALPART_EXPR: + break; + + case IMAGPART_EXPR: + byte_offset += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (exp))); + break; + + case VIEW_CONVERT_EXPR: + break; + + case MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR) + { + if (!integer_zerop (TREE_OPERAND (exp, 1))) + { + double_int off = mem_ref_offset (exp); + gcc_assert (off.high == -1 || off.high == 0); + byte_offset += double_int_to_shwi (off); + } + exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + } + goto done; + + case TARGET_MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR) + { + if (TMR_INDEX (exp) || TMR_INDEX2 (exp)) + return NULL_TREE; + if (!integer_zerop (TMR_OFFSET (exp))) + { + double_int off = mem_ref_offset (exp); + gcc_assert (off.high == -1 || off.high == 0); + byte_offset += double_int_to_shwi (off); + } + exp = TREE_OPERAND (TMR_BASE (exp), 0); + } + goto done; + + default: + goto done; + } + + exp = TREE_OPERAND (exp, 0); + } +done: + + *poffset = byte_offset; + return exp; +} + /* Returns true if STMT references an SSA_NAME that has SSA_NAME_OCCURS_IN_ABNORMAL_PHI set, otherwise false. */