X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree.c;h=33ab8b7078bda38c3c5978034b7688ae4efc0ba1;hb=e4cdb4c6a9fe30297ea553e9724a836fd46fe331;hp=0af1189388392dadacce4c4e58f2b6bb8d0ed0fd;hpb=46f8e3b0dc1cbb88c7dde984d0f0c2ce8935011d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree.c b/gcc/tree.c index 0af11893883..33ab8b7078b 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -105,8 +105,7 @@ const char *const tree_code_class_strings[] = "binary", "statement", "vl_exp", - "expression", - "gimple_stmt" + "expression" }; /* obstack.[ch] explicitly declined to prototype this. */ @@ -132,14 +131,12 @@ static const char * const tree_node_kind_names[] = { "temp_tree_lists", "vecs", "binfos", - "phi_nodes", "ssa names", "constructors", "random kinds", "lang_decl kinds", "lang_type kinds", "omp clauses", - "gimple statements" }; #endif /* GATHER_STATISTICS */ @@ -346,6 +343,8 @@ init_ttree (void) tree_contains_struct[CONST_DECL][TS_CONST_DECL] = 1; tree_contains_struct[TYPE_DECL][TS_TYPE_DECL] = 1; tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL] = 1; + tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL] = 1; + tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON] = 1; lang_hooks.init_ts (); } @@ -440,7 +439,7 @@ decl_assembler_name_hash (const_tree asmname) /* Compute the number of bytes occupied by a tree with code CODE. This function cannot be used for nodes that have variable sizes, - including TREE_VEC, PHI_NODE, STRING_CST, and CALL_EXPR. */ + including TREE_VEC, STRING_CST, and CALL_EXPR. */ size_t tree_code_size (enum tree_code code) { @@ -488,10 +487,6 @@ tree_code_size (enum tree_code code) return (sizeof (struct tree_exp) + (TREE_CODE_LENGTH (code) - 1) * sizeof (tree)); - case tcc_gimple_stmt: - return (sizeof (struct gimple_stmt) - + (TREE_CODE_LENGTH (code) - 1) * sizeof (char *)); - case tcc_constant: /* a constant */ switch (code) { @@ -515,8 +510,7 @@ tree_code_size (enum tree_code code) case PLACEHOLDER_EXPR: return sizeof (struct tree_common); case TREE_VEC: - case OMP_CLAUSE: - case PHI_NODE: gcc_unreachable (); + case OMP_CLAUSE: gcc_unreachable (); case SSA_NAME: return sizeof (struct tree_ssa_name); @@ -543,10 +537,6 @@ tree_size (const_tree node) const enum tree_code code = TREE_CODE (node); switch (code) { - case PHI_NODE: - return (sizeof (struct tree_phi_node) - + (PHI_ARG_CAPACITY (node) - 1) * sizeof (struct phi_arg_d)); - case TREE_BINFO: return (offsetof (struct tree_binfo, base_binfos) + VEC_embedded_size (tree, BINFO_N_BASE_BINFOS (node))); @@ -574,9 +564,8 @@ tree_size (const_tree node) /* Return a newly allocated node of code CODE. For decl and type nodes, some other fields are initialized. The rest of the node is - initialized to zero. This function cannot be used for PHI_NODE, - TREE_VEC or OMP_CLAUSE nodes, which is enforced by asserts in - tree_code_size. + initialized to zero. This function cannot be used for TREE_VEC or + OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size. Achoo! I got a code in the node. */ @@ -618,10 +607,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) kind = c_kind; break; - case tcc_gimple_stmt: - kind = gimple_stmt_kind; - break; - case tcc_exceptional: /* something random, like an identifier. */ switch (code) { @@ -637,10 +622,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) kind = binfo_kind; break; - case PHI_NODE: - kind = phi_kind; - break; - case SSA_NAME: kind = ssa_name_kind; break; @@ -739,17 +720,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) } break; - case tcc_gimple_stmt: - switch (code) - { - case GIMPLE_MODIFY_STMT: - TREE_SIDE_EFFECTS (t) = 1; - break; - - default: - break; - } - default: /* Other classes need no special treatment. */ break; @@ -774,8 +744,7 @@ copy_node_stat (tree node MEM_STAT_DECL) t = (tree) ggc_alloc_zone_pass_stat (length, &tree_zone); memcpy (t, node, length); - if (!GIMPLE_TUPLE_P (node)) - TREE_CHAIN (t) = 0; + TREE_CHAIN (t) = 0; TREE_ASM_WRITTEN (t) = 0; TREE_VISITED (t) = 0; t->base.ann = 0; @@ -2043,10 +2012,6 @@ expr_align (const_tree t) align1 = TYPE_ALIGN (TREE_TYPE (t)); return MAX (align0, align1); - case GIMPLE_MODIFY_STMT: - /* We should never ask for the alignment of a gimple statement. */ - gcc_unreachable (); - case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR: case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR: case CLEANUP_POINT_EXPR: @@ -2209,6 +2174,40 @@ decl_address_invariant_p (const_tree op) return false; } +/* Return whether OP is a DECL whose address is interprocedural-invariant. */ + +bool +decl_address_ip_invariant_p (const_tree op) +{ + /* The conditions below are slightly less strict than the one in + staticp. */ + + switch (TREE_CODE (op)) + { + case LABEL_DECL: + case FUNCTION_DECL: + case STRING_CST: + return true; + + case VAR_DECL: + if (((TREE_STATIC (op) || DECL_EXTERNAL (op)) + && !DECL_DLLIMPORT_P (op)) + || DECL_THREAD_LOCAL_P (op)) + return true; + break; + + case CONST_DECL: + if ((TREE_STATIC (op) || DECL_EXTERNAL (op))) + return true; + break; + + default: + break; + } + + return false; +} + /* Return true if T is function-invariant (internal function, does not handle arithmetic; that's handled in skip_simple_arithmetic and @@ -2418,8 +2417,6 @@ tree_node_structure (const_tree t) case tcc_statement: case tcc_vl_exp: return TS_EXP; - case tcc_gimple_stmt: - return TS_GIMPLE_STATEMENT; default: /* tcc_constant and tcc_exceptional */ break; } @@ -2433,13 +2430,10 @@ tree_node_structure (const_tree t) case VECTOR_CST: return TS_VECTOR; case STRING_CST: return TS_STRING; /* tcc_exceptional cases. */ - /* FIXME tuples: eventually this should be TS_BASE. For now, nothing - returns TS_BASE. */ case ERROR_MARK: return TS_COMMON; case IDENTIFIER_NODE: return TS_IDENTIFIER; case TREE_LIST: return TS_LIST; case TREE_VEC: return TS_VEC; - case PHI_NODE: return TS_PHI_NODE; case SSA_NAME: return TS_SSA_NAME; case PLACEHOLDER_EXPR: return TS_COMMON; case STATEMENT_LIST: return TS_STATEMENT_LIST; @@ -2500,6 +2494,11 @@ contains_placeholder_p (const_tree exp) || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)) || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2))); + case SAVE_EXPR: + /* The save_expr function never wraps anything containing + a PLACEHOLDER_EXPR. */ + return 0; + default: break; } @@ -2636,7 +2635,7 @@ substitute_in_expr (tree exp, tree f, tree r) { enum tree_code code = TREE_CODE (exp); tree op0, op1, op2, op3; - tree new, inner; + tree new_tree, inner; /* We handle TREE_LIST and COMPONENT_REF separately. */ if (code == TREE_LIST) @@ -2668,7 +2667,7 @@ substitute_in_expr (tree exp, tree f, tree r) if (op0 == TREE_OPERAND (exp, 0)) return exp; - new = fold_build3 (COMPONENT_REF, TREE_TYPE (exp), + new_tree = fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1), NULL_TREE); } else @@ -2694,7 +2693,7 @@ substitute_in_expr (tree exp, tree f, tree r) if (op0 == TREE_OPERAND (exp, 0)) return exp; - new = fold_build1 (code, TREE_TYPE (exp), op0); + new_tree = fold_build1 (code, TREE_TYPE (exp), op0); break; case 2: @@ -2704,7 +2703,7 @@ substitute_in_expr (tree exp, tree f, tree r) if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)) return exp; - new = fold_build2 (code, TREE_TYPE (exp), op0, op1); + new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1); break; case 3: @@ -2716,7 +2715,7 @@ substitute_in_expr (tree exp, tree f, tree r) && op2 == TREE_OPERAND (exp, 2)) return exp; - new = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2); + new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2); break; case 4: @@ -2730,7 +2729,7 @@ substitute_in_expr (tree exp, tree f, tree r) && op3 == TREE_OPERAND (exp, 3)) return exp; - new = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3)); + new_tree = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3)); break; default: @@ -2756,7 +2755,7 @@ substitute_in_expr (tree exp, tree f, tree r) } if (copy) - new = fold (copy); + new_tree = fold (copy); else return exp; } @@ -2766,8 +2765,8 @@ substitute_in_expr (tree exp, tree f, tree r) gcc_unreachable (); } - TREE_READONLY (new) = TREE_READONLY (exp); - return new; + TREE_READONLY (new_tree) = TREE_READONLY (exp); + return new_tree; } /* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement @@ -3289,15 +3288,6 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) gcc_assert (TREE_CODE_LENGTH (code) == 2); -#if 1 - /* FIXME tuples: Statement's aren't expressions! */ - if (code == GIMPLE_MODIFY_STMT) - return build_gimple_modify_stmt_stat (arg0, arg1 PASS_MEM_STAT); -#else - /* Must use build_gimple_modify_stmt to construct GIMPLE_MODIFY_STMTs. */ - gcc_assert (code != GIMPLE_MODIFY_STMT); -#endif - if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR) && arg0 && arg1 && tt && POINTER_TYPE_P (tt)) gcc_assert (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST); @@ -3336,21 +3326,6 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) } -/* Build a GIMPLE_MODIFY_STMT node. This tree code doesn't have a - type, so we can't use build2 (a.k.a. build2_stat). */ - -tree -build_gimple_modify_stmt_stat (tree arg0, tree arg1 MEM_STAT_DECL) -{ - tree t; - - t = make_node_stat (GIMPLE_MODIFY_STMT PASS_MEM_STAT); - /* ?? We don't care about setting flags for tuples... */ - GIMPLE_STMT_OPERAND (t, 0) = arg0; - GIMPLE_STMT_OPERAND (t, 1) = arg1; - return t; -} - tree build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1, tree arg2 MEM_STAT_DECL) @@ -3601,79 +3576,24 @@ expand_location (source_location loc) /* Source location accessor functions. */ -/* The source location of this expression. Non-tree_exp nodes such as - decls and constants can be shared among multiple locations, so - return nothing. */ -location_t -expr_location (const_tree node) -{ - if (GIMPLE_STMT_P (node)) - return GIMPLE_STMT_LOCUS (node); - return EXPR_P (node) ? node->exp.locus : UNKNOWN_LOCATION; -} - -void -set_expr_location (tree node, location_t locus) -{ - if (GIMPLE_STMT_P (node)) - GIMPLE_STMT_LOCUS (node) = locus; - else - EXPR_CHECK (node)->exp.locus = locus; -} - -bool -expr_has_location (const_tree node) -{ - return expr_location (node) != UNKNOWN_LOCATION; -} - -source_location * -expr_locus (const_tree node) -{ - if (GIMPLE_STMT_P (node)) - return CONST_CAST (source_location *, &GIMPLE_STMT_LOCUS (node)); - return (EXPR_P (node) - ? CONST_CAST (source_location *, &node->exp.locus) - : (source_location *) NULL); -} - void set_expr_locus (tree node, source_location *loc) { if (loc == NULL) - { - if (GIMPLE_STMT_P (node)) - GIMPLE_STMT_LOCUS (node) = UNKNOWN_LOCATION; - else - EXPR_CHECK (node)->exp.locus = UNKNOWN_LOCATION; - } + EXPR_CHECK (node)->exp.locus = UNKNOWN_LOCATION; else - { - if (GIMPLE_STMT_P (node)) - GIMPLE_STMT_LOCUS (node) = *loc; - else - EXPR_CHECK (node)->exp.locus = *loc; - } + EXPR_CHECK (node)->exp.locus = *loc; } -/* Return the file name of the location of NODE. */ -const char * -expr_filename (const_tree node) -{ - if (GIMPLE_STMT_P (node)) - return LOCATION_FILE (GIMPLE_STMT_LOCUS (node)); - return LOCATION_FILE (EXPR_CHECK (node)->exp.locus); -} +/* Like SET_EXPR_LOCATION, but make sure the tree can have a location. -/* Return the line number of the location of NODE. */ -int -expr_lineno (const_tree node) + LOC is the location to use in tree T. */ + +void protected_set_expr_location (tree t, location_t loc) { - if (GIMPLE_STMT_P (node)) - return LOCATION_LINE (GIMPLE_STMT_LOCUS (node)); - return LOCATION_LINE (EXPR_CHECK (node)->exp.locus); + if (t && CAN_HAVE_LOCATION_P (t)) + SET_EXPR_LOCATION (t, loc); } - /* Return a declaration like DDECL except that its DECL_ATTRIBUTES is ATTRIBUTE. */ @@ -4046,7 +3966,7 @@ merge_decl_attributes (tree olddecl, tree newdecl) The second instance of `foo' nullifies the dllimport. */ tree -merge_dllimport_decl_attributes (tree old, tree new) +merge_dllimport_decl_attributes (tree old, tree new_tree) { tree a; int delete_dllimport_p = 1; @@ -4057,16 +3977,16 @@ merge_dllimport_decl_attributes (tree old, tree new) is not dllimport'd. We also remove a `new' dllimport if the old list contains dllexport: dllexport always overrides dllimport, regardless of the order of declaration. */ - if (!VAR_OR_FUNCTION_DECL_P (new)) + if (!VAR_OR_FUNCTION_DECL_P (new_tree)) delete_dllimport_p = 0; - else if (DECL_DLLIMPORT_P (new) + else if (DECL_DLLIMPORT_P (new_tree) && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old))) { - DECL_DLLIMPORT_P (new) = 0; + DECL_DLLIMPORT_P (new_tree) = 0; warning (OPT_Wattributes, "%q+D already declared with dllexport attribute: " - "dllimport ignored", new); + "dllimport ignored", new_tree); } - else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new)) + else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new_tree)) { /* Warn about overriding a symbol that has already been used, e.g.: extern int __attribute__ ((dllimport)) foo; @@ -4076,27 +3996,27 @@ merge_dllimport_decl_attributes (tree old, tree new) if (TREE_USED (old)) { warning (0, "%q+D redeclared without dllimport attribute " - "after being referenced with dll linkage", new); + "after being referenced with dll linkage", new_tree); /* If we have used a variable's address with dllimport linkage, keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the decl may already have had TREE_CONSTANT computed. We still remove the attribute so that assembler code refers to '&foo rather than '_imp__foo'. */ if (TREE_CODE (old) == VAR_DECL && TREE_ADDRESSABLE (old)) - DECL_DLLIMPORT_P (new) = 1; + DECL_DLLIMPORT_P (new_tree) = 1; } /* Let an inline definition silently override the external reference, but otherwise warn about attribute inconsistency. */ - else if (TREE_CODE (new) == VAR_DECL - || !DECL_DECLARED_INLINE_P (new)) + else if (TREE_CODE (new_tree) == VAR_DECL + || !DECL_DECLARED_INLINE_P (new_tree)) warning (OPT_Wattributes, "%q+D redeclared without dllimport attribute: " - "previous dllimport ignored", new); + "previous dllimport ignored", new_tree); } else delete_dllimport_p = 0; - a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new)); + a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree)); if (delete_dllimport_p) { @@ -5153,16 +5073,16 @@ simple_cst_equal (const_tree t1, const_tree t2) code1 = TREE_CODE (t1); code2 = TREE_CODE (t2); - if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR) + if (CONVERT_EXPR_CODE_P (code1) || code1 == NON_LVALUE_EXPR) { - if (code2 == NOP_EXPR || code2 == CONVERT_EXPR + if (CONVERT_EXPR_CODE_P (code2) || code2 == NON_LVALUE_EXPR) return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); else return simple_cst_equal (TREE_OPERAND (t1, 0), t2); } - else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR + else if (CONVERT_EXPR_CODE_P (code2) || code2 == NON_LVALUE_EXPR) return simple_cst_equal (t1, TREE_OPERAND (t2, 0)); @@ -5374,7 +5294,7 @@ commutative_tree_code (enum tree_code code) } /* Generate a hash value for an expression. This can be used iteratively - by passing a previous result as the "val" argument. + by passing a previous result as the VAL argument. This function is intended to produce the same hash for expressions which would compare equal using operand_equal_p. */ @@ -5384,7 +5304,7 @@ iterative_hash_expr (const_tree t, hashval_t val) { int i; enum tree_code code; - char class; + char tclass; if (t == NULL_TREE) return iterative_hash_pointer (t, val); @@ -5453,24 +5373,23 @@ iterative_hash_expr (const_tree t, hashval_t val) } /* else FALL THROUGH */ default: - class = TREE_CODE_CLASS (code); + tclass = TREE_CODE_CLASS (code); - if (class == tcc_declaration) + if (tclass == tcc_declaration) { /* DECL's have a unique ID */ val = iterative_hash_host_wide_int (DECL_UID (t), val); } else { - gcc_assert (IS_EXPR_CODE_CLASS (class)); + gcc_assert (IS_EXPR_CODE_CLASS (tclass)); val = iterative_hash_object (code, val); /* Don't hash the type, that can lead to having nodes which compare equal according to operand_equal_p, but which have different hash codes. */ - if (code == NOP_EXPR - || code == CONVERT_EXPR + if (CONVERT_EXPR_CODE_P (code) || code == NON_LVALUE_EXPR) { /* Make sure to include signness in the hash computation. */ @@ -5502,6 +5421,29 @@ iterative_hash_expr (const_tree t, hashval_t val) break; } } + +/* Generate a hash value for a pair of expressions. This can be used + iteratively by passing a previous result as the VAL argument. + + The same hash value is always returned for a given pair of expressions, + regardless of the order in which they are presented. This is useful in + hashing the operands of commutative functions. */ + +hashval_t +iterative_hash_exprs_commutative (const_tree t1, + const_tree t2, hashval_t val) +{ + hashval_t one = iterative_hash_expr (t1, 0); + hashval_t two = iterative_hash_expr (t2, 0); + hashval_t t; + + if (one > two) + t = one, one = two, two = t; + val = iterative_hash_hashval_t (one, val); + val = iterative_hash_hashval_t (two, val); + + return val; +} /* Constructors for pointer, array and function types. (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are @@ -5953,6 +5895,91 @@ build_function_type (tree value_type, tree arg_types) return t; } +/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP. */ + +tree +build_function_type_skip_args (tree orig_type, bitmap args_to_skip) +{ + tree new_type = NULL; + tree args, new_args = NULL, t; + tree new_reversed; + int i = 0; + + for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node; + args = TREE_CHAIN (args), i++) + if (!bitmap_bit_p (args_to_skip, i)) + new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args); + + new_reversed = nreverse (new_args); + if (args) + { + if (new_reversed) + TREE_CHAIN (new_args) = void_list_node; + else + new_reversed = void_list_node; + } + gcc_assert (new_reversed); + + /* Use copy_node to preserve as much as possible from original type + (debug info, attribute lists etc.) + Exception is METHOD_TYPEs must have THIS argument. + When we are asked to remove it, we need to build new FUNCTION_TYPE + instead. */ + if (TREE_CODE (orig_type) != METHOD_TYPE + || !bitmap_bit_p (args_to_skip, 0)) + { + new_type = copy_node (orig_type); + TYPE_ARG_TYPES (new_type) = new_reversed; + } + else + { + new_type + = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type), + new_reversed)); + TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type); + } + + /* This is a new type, not a copy of an old type. Need to reassociate + variants. We can handle everything except the main variant lazily. */ + t = TYPE_MAIN_VARIANT (orig_type); + if (orig_type != t) + { + TYPE_MAIN_VARIANT (new_type) = t; + TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t); + TYPE_NEXT_VARIANT (t) = new_type; + } + else + { + TYPE_MAIN_VARIANT (new_type) = new_type; + TYPE_NEXT_VARIANT (new_type) = NULL; + } + return new_type; +} + +/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP. + + Arguments from DECL_ARGUMENTS list can't be removed now, since they are + linked by TREE_CHAIN directly. It is caller responsibility to eliminate + them when they are being duplicated (i.e. copy_arguments_for_versioning). */ + +tree +build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip) +{ + tree new_decl = copy_node (orig_decl); + tree new_type; + + new_type = TREE_TYPE (orig_decl); + if (prototype_p (new_type)) + new_type = build_function_type_skip_args (new_type, args_to_skip); + TREE_TYPE (new_decl) = new_type; + + /* For declarations setting DECL_VINDEX (i.e. methods) + we expect first argument to be THIS pointer. */ + if (bitmap_bit_p (args_to_skip, 0)) + DECL_VINDEX (new_decl) = NULL_TREE; + return new_decl; +} + /* Build a function type. The RETURN_TYPE is the type returned by the function. If VAARGS is set, no void_type_node is appended to the the list. ARGP muse be alway be terminated be a NULL_TREE. */ @@ -5968,9 +5995,9 @@ build_function_type_list_1 (bool vaargs, tree return_type, va_list argp) if (vaargs) { - last = args; - if (args != NULL_TREE) - args = nreverse (args); + last = args; + if (args != NULL_TREE) + args = nreverse (args); gcc_assert (args != NULL_TREE && last != void_list_node); } else if (args == NULL_TREE) @@ -6394,6 +6421,21 @@ int_fits_type_p (const_tree c, const_tree type) for "unknown if constant fits", 0 for "constant known *not* to fit" and 1 for "constant known to fit". */ + if (TREE_TYPE (c) == sizetype + && TYPE_UNSIGNED (TREE_TYPE (c)) + && TREE_INT_CST_HIGH (c) == -1 + && !TREE_OVERFLOW (c)) + /* So c is an unsigned integer which type is sizetype. + sizetype'd integers are sign extended even though they are + unsigned. If the integer value fits in the lower end word of c, + and if the higher end word has all its bits set to 1, that + means the higher end bits are set to 1 only for sign extension. + So let's convert c into an equivalent zero extended unsigned + integer. */ + c = force_fit_type_double (size_type_node, + TREE_INT_CST_LOW (c), + TREE_INT_CST_HIGH (c), + false, false); /* Check if C >= type_low_bound. */ if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST) { @@ -6489,8 +6531,7 @@ get_type_static_bounds (const_tree type, mpz_t min, mpz_t max) } } -/* auto_var_in_fn_p is called to determine whether VAR is an automatic - variable defined in function FN. */ +/* Return true if VAR is an automatic variable defined in function FN. */ bool auto_var_in_fn_p (const_tree var, const_tree fn) @@ -6736,9 +6777,8 @@ get_callee_fndecl (const_tree call) && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL) return TREE_OPERAND (addr, 0); - /* We couldn't figure out what was being called. Maybe the front - end has some idea. */ - return lang_hooks.lang_get_callee_fndecl (call); + /* We couldn't figure out what was being called. */ + return NULL_TREE; } /* Print debugging information about tree nodes generated during the compile, @@ -7128,18 +7168,6 @@ tree_vec_elt_check_failed (int idx, int len, const char *file, int line, idx + 1, len, function, trim_filename (file), line); } -/* Similar to above, except that the check is for the bounds of a PHI_NODE's - (dynamically sized) vector. */ - -void -phi_node_elt_check_failed (int idx, int len, const char *file, int line, - const char *function) -{ - internal_error - ("tree check: accessed elt %d of phi_node with %d elts in %s, at %s:%d", - idx + 1, len, function, trim_filename (file), line); -} - /* Similar to above, except that the check is for the bounds of the operand vector of an expression node EXP. */ @@ -8690,6 +8718,10 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len)); } + case CHANGE_DYNAMIC_TYPE_EXPR: + WALK_SUBTREE (CHANGE_DYNAMIC_TYPE_NEW_TYPE (*tp)); + WALK_SUBTREE_TAIL (CHANGE_DYNAMIC_TYPE_LOCATION (*tp)); + case DECL_EXPR: /* If this is a TYPE_DECL, walk into the fields of the type that it's defining. We only want to walk into these fields of a type in this @@ -8761,8 +8793,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, /* FALLTHRU */ default: - if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)) - || IS_GIMPLE_STMT_CODE_CLASS (TREE_CODE_CLASS (code))) + if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))) { int i, len; @@ -8774,8 +8805,8 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, if (len) { for (i = 0; i < len - 1; ++i) - WALK_SUBTREE (GENERIC_TREE_OPERAND (*tp, i)); - WALK_SUBTREE_TAIL (GENERIC_TREE_OPERAND (*tp, len - 1)); + WALK_SUBTREE (TREE_OPERAND (*tp, i)); + WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1)); } } /* If this is a type, walk the needed fields in the type. */ @@ -8807,31 +8838,6 @@ walk_tree_without_duplicates_1 (tree *tp, walk_tree_fn func, void *data, } -/* Return true if STMT is an empty statement or contains nothing but - empty statements. */ - -bool -empty_body_p (tree stmt) -{ - tree_stmt_iterator i; - tree body; - - if (IS_EMPTY_STMT (stmt)) - return true; - else if (TREE_CODE (stmt) == BIND_EXPR) - body = BIND_EXPR_BODY (stmt); - else if (TREE_CODE (stmt) == STATEMENT_LIST) - body = stmt; - else - return false; - - for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i)) - if (!empty_body_p (tsi_stmt (i))) - return false; - - return true; -} - tree * tree_block (tree t) { @@ -8839,28 +8845,10 @@ tree_block (tree t) if (IS_EXPR_CODE_CLASS (c)) return &t->exp.block; - else if (IS_GIMPLE_STMT_CODE_CLASS (c)) - return &GIMPLE_STMT_BLOCK (t); gcc_unreachable (); return NULL; } -tree * -generic_tree_operand (tree node, int i) -{ - if (GIMPLE_STMT_P (node)) - return &GIMPLE_STMT_OPERAND (node, i); - return &TREE_OPERAND (node, i); -} - -tree * -generic_tree_type (tree node) -{ - if (GIMPLE_STMT_P (node)) - return &void_type_node; - return &TREE_TYPE (node); -} - /* Build and return a TREE_LIST of arguments in the CALL_EXPR exp. FIXME: don't use this function. It exists for compatibility with the old representation of CALL_EXPRs where a list was used to hold the @@ -8876,6 +8864,46 @@ call_expr_arglist (tree exp) return arglist; } + +/* Create a nameless artificial label and put it in the current function + context. Returns the newly created label. */ + +tree +create_artificial_label (void) +{ + tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node); + + DECL_ARTIFICIAL (lab) = 1; + DECL_IGNORED_P (lab) = 1; + DECL_CONTEXT (lab) = current_function_decl; + return lab; +} + +/* Given a tree, try to return a useful variable name that we can use + to prefix a temporary that is being assigned the value of the tree. + I.E. given = &A, return A. */ + +const char * +get_name (tree t) +{ + tree stripped_decl; + + stripped_decl = t; + STRIP_NOPS (stripped_decl); + if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl)) + return IDENTIFIER_POINTER (DECL_NAME (stripped_decl)); + else + { + switch (TREE_CODE (stripped_decl)) + { + case ADDR_EXPR: + return get_name (TREE_OPERAND (stripped_decl, 0)); + default: + return NULL; + } + } +} + /* Return true if TYPE has a variable argument list. */ bool @@ -8941,7 +8969,9 @@ block_nonartificial_location (tree block) { tree ao = BLOCK_ABSTRACT_ORIGIN (block); - while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao)) + while (TREE_CODE (ao) == BLOCK + && BLOCK_ABSTRACT_ORIGIN (ao) + && BLOCK_ABSTRACT_ORIGIN (ao) != ao) ao = BLOCK_ABSTRACT_ORIGIN (ao); if (TREE_CODE (ao) == FUNCTION_DECL)