]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorAndrew Pinski <pinskia@gcc.gnu.org>
Sat, 16 Jun 2007 05:42:36 +0000 (22:42 -0700)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Sat, 16 Jun 2007 05:42:36 +0000 (22:42 -0700)
2007-06-15  Andrew Pinski <andrew_pinski@playstation.sony.com>
            Zdenek Dvorak <dvorakz@suse.cz>
            Richard Guenther  <rguenther@suse.de>
            Kaz Kojima  <kkojima@gcc.gnu.org>

* tree-vrp.c (compare_values_warnv): Convert val2 to
the type of val1.
(extract_range_from_assert): Create
POINTER_PLUS_EXPR for pointer types.
(extract_range_from_binary_expr): Handle
only POINTER_PLUS_EXPR, MIN_EXPR, and MAX_EXPR
for pointer types.
* doc/c-tree.texi (POINTER_PLUS_EXPR): Document.
* tree-ssa-loop-niter.c (split_to_var_and_offset): Handle
POINTER_PLUS_EXPR as PLUS_EXPR.
(number_of_iterations_lt_to_ne):
For pointer types, use sizetype when
creating MINUS_EXPR/PLUS_EXPRs.
(assert_loop_rolls_lt): For pointer types, use sizetype when
creating MINUS_EXPR/PLUS_EXPRs.
(number_of_iterations_le): Likewise.
(expand_simple_operations): POINTER_PLUS_EXPR are simple also.
(derive_constant_upper_bound): Handle POINTER_PLUS_EXPR just
like PLUS_EXPR and MINUS_EXPR.
* tree-pretty-print.c (dump_generic_node): Handle
POINTER_PLUS_EXPR.
(op_prio): Likewise.
(op_symbol_1): Likewise.
* optabs.c (optab_for_tree_code): Likewise.
* tree-ssa-loop-manip.c (create_iv): Handle pointer base
specially.
* tree-tailcall.c (process_assignment): Mention
POINTER_PLUS_EXPR in a TODO comment.
* tree.c (build2_stat): Assert when trying to use PLUS_EXPR or
MINUS_EXPR with a pointer. Also assert for POINTER_PLUS_EXPR
not used with a pointer and an integer type.
* tree-scalar-evolution.c (add_to_evolution_1): Convert the
increment using chrec_convert_rhs instead of chrec_convert.
(follow_ssa_edge_in_rhs): Handle POINTER_PLUS_EXPR like
PLUS_EXPR except for the right hand side's type will be
sizetype.
(interpret_rhs_modify_stmt): Handle POINTER_PLUS_EXPR.
(fold_used_pointer_cast): Kill.
(pointer_offset_p): Kill.
(fold_used_pointer): Kill.
(pointer_used_p): Kill.
(analyze_scalar_evolution_1 <case GIMPLE_MODIFY_STMT>): Don't
call fold_used_pointer.
(instantiate_parameters_1): Convert the increment
using chrec_convert_rhs instead of chrec_convert.
Handle POINTER_PLUS_EXPR as PLUS_EXPR.
* builtins.c (get_pointer_alignment): Handle POINTER_PLUS_EXPR
instead of PLUS_EXPR.
(expand_builtin_strcat): Create a POINTER_PLUS_EXPR instead of
PLUS_EXPR for pointers.
(std_gimplify_va_arg_expr): Likewise.
(fold_builtin_memory_op): Likewise.
(fold_builtin_strstr): Likewise.
(fold_builtin_strchr): Likewise.
(fold_builtin_strrchr): Likewise.
(fold_builtin_strpbrk): Likewise.
(expand_builtin_memory_chk): Likewise.
(fold_builtin_memory_chk): Likewise.
(std_expand_builtin_va_start): Use
sizetype for the call to make_tree and then convert
to the pointer type.
(fold_builtin_memchr): Use POINTER_PLUS_EXPR
instead of PLUS_EXPR for adding to a pointer.
(std_gimplify_va_arg_expr): Use fold_build2 for
the creating of POINTER_PLUS_EXPR.  For the BIT_AND_EXPR, cast
the operands to sizetype first and then cast the BIT_AND_EXPR
back to the pointer type.
* fold-const.c (build_range_check): Handle pointer types
specially.
(extract_array_ref): Look for POINTER_PLUS_EXPR instead
of PLUS_EXPR's. Make sure the offset is converted to
sizetype.
(try_move_mult_to_index): Strip the NOPs from the offset.
Remove code argument and replace all uses with PLUS_EXPR.
(fold_to_nonsharp_ineq_using_bound): Handle pointer types
specially. Don't use a pointer type for MINUS_EXPR.
(fold_unary): Handle for (T1)(X op Y),
only p+ as that is the only as that can be handled for
binary operators now.
(fold_binary <case POINTER_PLUS_EXPR>): Add folding of
POINTER_PLUS_EXPR.
<case PLUS_EXPR>: Add folding of PTR+INT into
PTR p+ INT.
Don't call try_move_mult_to_index.
<case MINUS_EXPR>: Fold (PTR0 p+ A) - (PTR1 p+ B)
into (PTR0 - PTR1) + (A - B). Fold (PTR0 p+ A) - PTR1 into
(PTR0 - PTR1) + A iff (PTR0 - PTR1) simplifies.
Don't call try_move_mult_to_index.
(tree_expr_nonnegative_warnv_p): Handle POINTER_PLUS_EXPR.
(tree_expr_nonzero_p): Likewise.
(fold_indirect_ref_1): Look at POINTER_PLUS_EXPR instead
of PLUS_EXPR for the complex expression folding.
* tree-chrec.c (chrec_fold_plus_poly_poly): If the
first chrec is a pointer type, then the second should
be sizetype and not the first's type.
For POINTER_PLUS_EXPR, use a different right hand side type.
Handle POINTER_PLUS_EXPR like PLUS_EXPR.
(chrec_fold_plus_1): For POINTER_PLUS_EXPR, use a
different right hand side type.
Handle POINTER_PLUS_EXPR like PLUS_EXPR.
(chrec_fold_plus): For pointer types, use POINTER_PLUS_EXPR
instead of PLUS_EXPR.
When either operand is zero, convert the other operand.
(chrec_apply): Use chrec_convert_rhs
on the argument x instead of chrec_convert.
(reset_evolution_in_loop): For pointer types, the new_evol
should be sizetype.
(convert_affine_scev): For POINTER_PLUS_EXPR, use a
different right hand side type.
Handle POINTER_PLUS_EXPR like PLUS_EXPR.
(chrec_convert_rhs): New function.
(chrec_convert_aggressive): For POINTER_PLUS_EXPR, use a
different right hand side type.
Handle POINTER_PLUS_EXPR like PLUS_EXPR.
* tree-chrec.h (chrec_convert_rhs): New prototype.
(build_polynomial_chrec): For pointer types, the right hand
* tree-ssa-ccp.c (maybe_fold_stmt_indirect): Look for
POINTER_PLUS_EXPR instead of PLUS_EXPR's.
Remove subtraction case as it is always addition now.
Make sure the offset is converted to sizetype.
(fold_stmt_r): Don't handle PLUS_EXPR/MINUS_EXPR specially.
Handle POINTER_PLUS_EXPR like PLUS_EXPR was handled before.
* tree-ssa-loop-ivopts.c (determine_base_object): Abort for
PLUS_EXPR in pointer type.
Handle POINTER_PLUS_EXPR.
(tree_to_aff_combination): Likewise.
(force_expr_to_var_cost): Likewise.
(force_expr_to_var_cost): Likewise. Create a POINTER_PLUS_EXPR
instead of PLUS_EXPR for pointers.
* c-format.c (check_format_arg): Handle POINTER_PLUS_EXPR
instead of PLUS_EXPR of pointer types.
* tree-stdarg.c (va_list_counter_bump): Handle POINTER_PLUS_EXPR
as PLUS_EXPR.
(check_va_list_escapes): Likewise.
(check_all_va_list_escapes): Likewise.
* dwarf2out.c (loc_descriptor_from_tree_1):
Handle POINT_PLUS_EXPR as a PLUS_EXPR.
* expr.c (expand_expr_real_1): Handle POINTER_PLUS_EXPR.
(string_constant): Likewise.
* tree-ssa-address.c (tree_mem_ref_addr): When adding
the offset to the base, use POINTER_PLUS_EXPR.
(add_to_parts): Convert the index to sizetype.
(create_mem_ref): Create A POINTER_PLUS_EXPR for the one case.
* matrix-reorg.c (collect_data_for_malloc_call): Stmt
will now only be either INDIRECT_REF and POINTER_PLUS_EXPR.
Offset only holds something for PLUS_EXPR.
(ssa_accessed_in_tree): Handle POINTER_PLUS_EXPR just as
a PLUS_EXPR.
(analyze_transpose): POINTER_PLUS_EXPR will only show up now
and not PLUS_EXPR.
(analyze_accesses_for_modify_stmt): Likewise.
Remove comment about the type being integral type as it is
wrong now.
(can_calculate_expr_before_stmt): Handle POINTER_PLUS_EXPR as
PLUS_EXPR.
(transform_access_sites): POINTER_PLUS_EXPR will only show up now
and not PLUS_EXPR.
Correct the type which the artimentic is done in (is now
sizetype).
Reindent one loop.
* tree-data-ref.c (split_constant_offset): Handle
POINTER_PLUS_EXPR
* tree-affine.c (tree_to_aff_combination): Likewise.
* c-typeck.c (build_unary_op): For pointers create the increment
as a sizetype. Create a POINTER_PLUS_EXPR instead of PLUS_EXPR
for pointers.
* gimplify.c (gimplify_self_mod_expr): Create a
POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
(gimplify_omp_atomic_fetch_op): Handle POINTER_PLUS_EXPR.
* tree.def (POINTER_PLUS_EXPR): New tree code.
* tree-predcom.c (ref_at_iteration): If we have a pointer
type do the multiplication in sizetype.
* tree-mudflap.c (mf_xform_derefs_1): Create a
POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
* tree-ssa-forwprop.c
(forward_propagate_addr_into_variable_array_index):
Don't expect there to be a cast for the index as that
does not exist anymore.
(forward_propagate_addr_expr_1): Check for POINTER_PLUS_EXPR
instead of PLUS_EXPR.
Don't check for the first operand of the POINTER_PLUS_EXPR
was the index as it cannot be.
Call forward_propagate_addr_into_variable_array_index with
the SSA_NAME instead of the statement.
* varasm.c (const_hash_1): Handle POINTER_PLUS_EXPR.
(compare_constant): Likewise.
(copy_constant): Likewise.
(compute_reloc_for_constant): Likewise.
(output_addressed_constants): Likewise.
(initializer_constant_valid_p): Likewise.
* tree-ssa.c (tree_ssa_useless_type_conversion_1):
Convert the MIN/MAX of the inner type to the outer
type before comparing them.
* tree-ssa-loop-prefetch.c (idx_analyze_ref):  Handle
POINTER_PLUS_EXPR instead of PLUS_EXPR.
(issue_prefetch_ref): Create a POINTER_PLUS_EXPR instead
of PLUS_EXPR for pointers.
* tree-inline.c (estimate_num_insns_1): Handle
POINTER_PLUS_EXPR.
* tree-vect-transform.c (vect_create_addr_base_for_vector_ref):
Create a POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
(bump_vector_ptr): Create a POINTER_PLUS_EXPR
instead of PLUS_EXPR for the pointer increment statement.
(vect_update_ivs_after_vectorizer): For pointer types, create
POINTER_PLUS_EXPR instead of PLUS_EXPR and also create
MULT_EXPR in sizetype.
(vect_gen_niters_for_prolog_loop): Add a cast when creating
byte_misalign.
* tree-object-size.c (plus_expr_object_size): Handle
POINTER_PLUS_EXPR instead of PLUS_EXPR.  Removing all the extra
code which is trying to figure out which side is a pointer and
is the index.
(check_for_plus_in_loops_1): Likewise.
(check_for_plus_in_loops): Likewise.
* c-common.c (pointer_int_sum): Create a
POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
* tree-ssa-structalias.c (handle_ptr_arith): Handle
only POINTER_PLUS_EXPR.  Removing all the extra
code which is trying to figure out which side is a pointer and
is the index.
* tree-cfg.c (verify_expr): Add extra checking for pointers and
PLUS_EXPR and MINUS_EXPR.
Also add checking to make sure the operands of POINTER_PLUS_EXPR
are correct.
* config/frv/frv.c (frv_expand_builtin_va_start): Use sizetype
with make_tree, instead of a pointer type.
* config/s390/s390.c (s390_va_start): Use POINTER_PLUS_EXPR
for pointers instead of PLUS_EXPR.
(s390_gimplify_va_arg): Likewise.
* config/spu/spu.c (spu_va_start): Create POINTER_PLUS_EXPR
instead of PLUS_EXPR when doing addition on pointer
types.  Use sizetype for the second operand.
(spu_gimplify_va_arg_expr): Likewise.
* config/sparc/sparc.c (sparc_gimplify_va_arg): Use
POINTER_PLUS_EXPR instead of PLUS_EXPR when the operand was
a pointer.  Don't create a BIT_AND_EXPR for pointer types.
* config/i386/i386.c (ix86_va_start): Use POINTER_PLUS_EXPR
for the pointer addition and also use size_int/sizetype
for the offset.
(ix86_gimplify_va_arg): Likewise.
Perform BIT_AND_EXPR on sizetype arguments.
* config/sh/sh.c (sh_va_start): Call make_tree with sizetype
and convert its result to a pointer type.  Use POINTER_PLUS_EXPR
for the pointer additions and also use size_int for the offsets.
(sh_gimplify_va_arg_expr): Use POINTER_PLUS_EXPR for the pointer
additions and also use size_int for the offsets.  Perform
BIT_AND_EXPR on sizetype arguments.
* config/ia64/ia64.c (ia64_gimplify_va_arg): Use
POINTER_PLUS_EXPR for pointers and create the
BIT_AND_EXPR in sizetype.
* config/rs6000/rs6000.c (rs6000_va_start): Use POINTER_PLUS_EXPR
instead of PLUS_EXPR for pointer addition.
(rs6000_va_start): Likewise.
Also use sizetype for the offset.
* config/pa/pa.c (reloc_needed): Handle POINTER_PLUS_EXPR
as PLUS_EXPR/MINUS_EXPR.
(hppa_gimplify_va_arg_expr): Don't create MINUS_EXPR or
PLUS_EXPR for pointers, instead use POINTER_PLUS_EXPR.
Don't use BIT_AND_EXPR on a pointer type, convert the
expression to sizetype first.
* config/mips/mips.c (mips_va_start): Use POINTER_PLUS_EXPR
for pointers.
(mips_gimplify_va_arg_expr): Likewise.
Don't create BIT_AND_EXPR in a pointer type.

2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>

        * trans-intrinsic.c (gfc_conv_intrinsic_repeat): Use
        POINTER_PLUS_EXPR instead of PLUS_EXPR for pointer addition.
        * trans-expr.c (gfc_trans_string_copy): Create
        POINTER_PLUS_EXPR instead of a PLUS_EXPR
        for pointer types.

2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>

* typeck.c (build_binary_op): For templates build the
expression in pieces to avoid the assert in build2_stat.
(get_member_function_from_ptrfunc):
Change over to using POINTER_PLUS_EXPR and convert
the second operand to sizetype.
* typeck2.c (build_m_component_ref):  Likewise.
* init.c (expand_virtual_init): Create a POINTER_PLUS_EXPR
instead of PLUS_EXPR for pointers.
(build_new_1): Likewise.
(build_vec_delete_1): Likewise.
(build_vec_delete): Likewise.
* class.c (build_base_path): Likewise.
(build_base_path): Likewise.
(convert_to_base_statically): Likewise.
(fixed_type_or_null): Handle POINTER_PLUS_EXPR.
(get_vtbl_decl_for_binfo): Handle POINTER_PLUS_EXPR
instead of PLUS_EXPR.
(dfs_accumulate_vtbl_inits): Create a POINTER_PLUS_EXPR
instead of PLUS_EXPR for pointers.
* call.c (build_special_member_call): Likewise.
* rtti.c (build_headof): Likewise.
Use sizetype instead of ptrdiff_type_node.
(tinfo_base_init): Create a POINTER_PLUS_EXPR
instead of PLUS_EXPR for pointers.
* except.c (expand_start_catch_block):  Do a
NEGATIVE and then a POINTER_PLUS_EXPR instead
of a MINUS_EXPR.
* cp-gimplify.c (cxx_omp_clause_apply_fn): Convert
PLUS_EXPR on pointer types over to use
POINTER_PLUS_EXPR and remove the conversion
to the pointer types.
* method.c (thunk_adjust): Use POINTER_PLUS_EXPR for
adding to a pointer type. Use size_int instead of
ssize_int. Convert the index to sizetype before
adding it to the pointer.

2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>

        * trans.c (Attribute_to_gnu): When subtracting an
        offset from a pointer, use POINTER_PLUS_EXPR with
        NEGATE_EXPR instead of MINUS_EXPR.
        (gnat_to_gnu): Likewise.
        * utils.c (convert): When converting between
        thin pointers, use POINTER_PLUS_EXPR and sizetype
        for the offset.
        * utils2.c (known_alignment): POINTER_PLUS_EXPR
        have the same semantics as PLUS_EXPR for alignment.
        (build_binary_op): Add support for the semantics of
        POINTER_PLUS_EXPR's operands.
        When adding an offset to a pointer, use POINTER_PLUS_EXPR.

2007-06-15 Andrew Pinski  <andrew_pinski@playstation.sony.com>

        * class.c (make_class_data): Build the index in sizetype.
        Use POINTER_PLUS_EXPR instead of PLUS_EXPR when
        adding to a pointer type.
        (build_symbol_entry): Likewise.
        * expr.c (build_java_arrayaccess): Likewise.
        (build_field_ref): Likewise.
        (build_known_method_ref): Likewise.
        (build_invokevirtual): Likewise.
        * except.c (build_exception_object_ref): Do a
        NEGATIVE and then a POINTER_PLUS_EXPR instead
        of a MINUS_EXPR.

2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>

PR tree-opt/32225
* gcc.c-torture/compile/20070605-1.c: New test.

* gcc.c-torture/compile/20070603-1.c: New testcase.
* gcc.c-torture/compile/20070603-2.c: New testcase.

* gcc.c-torture/compile/20070531-1.c: New test.

PR tree-opt/32167
* gcc.c-torture/compile/20070531-2.c: New test.

PR tree-opt/32144
* gcc.c-torture/compile/20070529-1.c: New test.

PR tree-opt/32145
* gcc.c-torture/compile/20070529-2.c: New test.

PR tree-opt/32015
* gcc.c-torture/compile/20070520-1.c: New test.

* g++.dg/ext/java-1.C: New test.

* gcc.dg/vect/vect-106.c: We are now able to vectorize two
loops instead of one. Remove the "can't determine dependence"
check.
* gcc.dg/tree-ssa/20030815-1.c: Remove testcase which is no longer
needed as the cast is gone in the first place.
* gcc.dg/max-1.c: Change local variable a to be a global one.
* gcc.dg/tree-ssa/ssa-pre-8.c: Update testcase since we don't
have a cast which is PREd.

From-SVN: r125755

90 files changed:
gcc/ChangeLog
gcc/ChangeLog.ptr [new file with mode: 0644]
gcc/ada/ChangeLog
gcc/ada/ChangeLog.ptr [new file with mode: 0644]
gcc/ada/trans.c
gcc/ada/utils.c
gcc/ada/utils2.c
gcc/builtins.c
gcc/c-common.c
gcc/c-format.c
gcc/c-typeck.c
gcc/config/frv/frv.c
gcc/config/i386/i386.c
gcc/config/ia64/ia64.c
gcc/config/mips/mips.c
gcc/config/pa/pa.c
gcc/config/rs6000/rs6000.c
gcc/config/s390/s390.c
gcc/config/sh/sh.c
gcc/config/sparc/sparc.c
gcc/config/spu/spu.c
gcc/cp/ChangeLog
gcc/cp/ChangeLog.ptr [new file with mode: 0644]
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-gimplify.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/rtti.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/doc/c-tree.texi
gcc/dwarf2out.c
gcc/expr.c
gcc/fold-const.c
gcc/fortran/ChangeLog
gcc/fortran/ChangeLog.ptr [new file with mode: 0644]
gcc/fortran/trans-expr.c
gcc/fortran/trans-intrinsic.c
gcc/gimplify.c
gcc/java/ChangeLog
gcc/java/ChangeLog.ptr [new file with mode: 0644]
gcc/java/class.c
gcc/java/except.c
gcc/java/expr.c
gcc/matrix-reorg.c
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/ChangeLog.ptr [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/java-1.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070520-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070529-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070529-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070531-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070531-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070603-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070603-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/20070605-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/max-1.c
gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c [deleted file]
gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c
gcc/testsuite/gcc.dg/vect/vect-106.c
gcc/tree-affine.c
gcc/tree-cfg.c
gcc/tree-chrec.c
gcc/tree-chrec.h
gcc/tree-data-ref.c
gcc/tree-inline.c
gcc/tree-mudflap.c
gcc/tree-object-size.c
gcc/tree-predcom.c
gcc/tree-pretty-print.c
gcc/tree-scalar-evolution.c
gcc/tree-ssa-address.c
gcc/tree-ssa-ccp.c
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssa-loop-manip.c
gcc/tree-ssa-loop-niter.c
gcc/tree-ssa-loop-prefetch.c
gcc/tree-ssa-structalias.c
gcc/tree-ssa.c
gcc/tree-stdarg.c
gcc/tree-tailcall.c
gcc/tree-vect-transform.c
gcc/tree-vrp.c
gcc/tree.c
gcc/tree.def
gcc/varasm.c

index 8c8fc500692f08ce338965eb252b9df3214f035a..abe28d49f4574755c810420f9165614f03a498b1 100644 (file)
@@ -1,3 +1,273 @@
+2007-06-15  Andrew Pinski <andrew_pinski@playstation.sony.com>
+            Zdenek Dvorak <dvorakz@suse.cz>
+            Richard Guenther  <rguenther@suse.de>
+            Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       * tree-vrp.c (compare_values_warnv): Convert val2 to
+       the type of val1.
+       (extract_range_from_assert): Create
+       POINTER_PLUS_EXPR for pointer types.
+       (extract_range_from_binary_expr): Handle
+       only POINTER_PLUS_EXPR, MIN_EXPR, and MAX_EXPR
+       for pointer types.
+       * doc/c-tree.texi (POINTER_PLUS_EXPR): Document.
+       * tree-ssa-loop-niter.c (split_to_var_and_offset): Handle
+       POINTER_PLUS_EXPR as PLUS_EXPR.
+       (number_of_iterations_lt_to_ne):
+       For pointer types, use sizetype when
+       creating MINUS_EXPR/PLUS_EXPRs.
+       (assert_loop_rolls_lt): For pointer types, use sizetype when
+       creating MINUS_EXPR/PLUS_EXPRs.
+       (number_of_iterations_le): Likewise.
+       (expand_simple_operations): POINTER_PLUS_EXPR are simple also.
+       (derive_constant_upper_bound): Handle POINTER_PLUS_EXPR just
+       like PLUS_EXPR and MINUS_EXPR.
+       * tree-pretty-print.c (dump_generic_node): Handle
+       POINTER_PLUS_EXPR.
+       (op_prio): Likewise.
+       (op_symbol_1): Likewise.
+       * optabs.c (optab_for_tree_code): Likewise.
+       * tree-ssa-loop-manip.c (create_iv): Handle pointer base
+       specially.
+       * tree-tailcall.c (process_assignment): Mention
+       POINTER_PLUS_EXPR in a TODO comment.
+       * tree.c (build2_stat): Assert when trying to use PLUS_EXPR or 
+       MINUS_EXPR with a pointer. Also assert for POINTER_PLUS_EXPR
+       not used with a pointer and an integer type.
+       * tree-scalar-evolution.c (add_to_evolution_1): Convert the
+       increment using chrec_convert_rhs instead of chrec_convert.
+       (follow_ssa_edge_in_rhs): Handle POINTER_PLUS_EXPR like
+       PLUS_EXPR except for the right hand side's type will be
+       sizetype.
+       (interpret_rhs_modify_stmt): Handle POINTER_PLUS_EXPR.
+       (fold_used_pointer_cast): Kill.
+       (pointer_offset_p): Kill.
+       (fold_used_pointer): Kill.
+       (pointer_used_p): Kill.
+       (analyze_scalar_evolution_1 <case GIMPLE_MODIFY_STMT>): Don't
+       call fold_used_pointer.
+       (instantiate_parameters_1): Convert the increment
+       using chrec_convert_rhs instead of chrec_convert.
+       Handle POINTER_PLUS_EXPR as PLUS_EXPR.
+       * builtins.c (get_pointer_alignment): Handle POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       (expand_builtin_strcat): Create a POINTER_PLUS_EXPR instead of
+       PLUS_EXPR for pointers.
+       (std_gimplify_va_arg_expr): Likewise.
+       (fold_builtin_memory_op): Likewise.
+       (fold_builtin_strstr): Likewise.
+       (fold_builtin_strchr): Likewise.
+       (fold_builtin_strrchr): Likewise.
+       (fold_builtin_strpbrk): Likewise.
+       (expand_builtin_memory_chk): Likewise.
+       (fold_builtin_memory_chk): Likewise.
+       (std_expand_builtin_va_start): Use
+       sizetype for the call to make_tree and then convert
+       to the pointer type.
+       (fold_builtin_memchr): Use POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for adding to a pointer.
+       (std_gimplify_va_arg_expr): Use fold_build2 for
+       the creating of POINTER_PLUS_EXPR.  For the BIT_AND_EXPR, cast
+       the operands to sizetype first and then cast the BIT_AND_EXPR
+       back to the pointer type.
+       * fold-const.c (build_range_check): Handle pointer types
+       specially.
+       (extract_array_ref): Look for POINTER_PLUS_EXPR instead
+       of PLUS_EXPR's. Make sure the offset is converted to
+       sizetype.
+       (try_move_mult_to_index): Strip the NOPs from the offset.
+       Remove code argument and replace all uses with PLUS_EXPR.
+       (fold_to_nonsharp_ineq_using_bound): Handle pointer types
+       specially. Don't use a pointer type for MINUS_EXPR.
+       (fold_unary): Handle for (T1)(X op Y),
+       only p+ as that is the only as that can be handled for
+       binary operators now.
+       (fold_binary <case POINTER_PLUS_EXPR>): Add folding of
+       POINTER_PLUS_EXPR.
+       <case PLUS_EXPR>: Add folding of PTR+INT into
+       PTR p+ INT.
+       Don't call try_move_mult_to_index.
+       <case MINUS_EXPR>: Fold (PTR0 p+ A) - (PTR1 p+ B)
+       into (PTR0 - PTR1) + (A - B). Fold (PTR0 p+ A) - PTR1 into
+       (PTR0 - PTR1) + A iff (PTR0 - PTR1) simplifies.
+       Don't call try_move_mult_to_index.
+       (tree_expr_nonnegative_warnv_p): Handle POINTER_PLUS_EXPR.
+       (tree_expr_nonzero_p): Likewise.
+       (fold_indirect_ref_1): Look at POINTER_PLUS_EXPR instead
+       of PLUS_EXPR for the complex expression folding.
+       * tree-chrec.c (chrec_fold_plus_poly_poly): If the
+       first chrec is a pointer type, then the second should
+       be sizetype and not the first's type.
+       For POINTER_PLUS_EXPR, use a different right hand side type.
+       Handle POINTER_PLUS_EXPR like PLUS_EXPR.
+       (chrec_fold_plus_1): For POINTER_PLUS_EXPR, use a
+       different right hand side type.
+       Handle POINTER_PLUS_EXPR like PLUS_EXPR.
+       (chrec_fold_plus): For pointer types, use POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       When either operand is zero, convert the other operand.
+       (chrec_apply): Use chrec_convert_rhs
+       on the argument x instead of chrec_convert.
+       (reset_evolution_in_loop): For pointer types, the new_evol
+       should be sizetype.
+       (convert_affine_scev): For POINTER_PLUS_EXPR, use a
+       different right hand side type.
+       Handle POINTER_PLUS_EXPR like PLUS_EXPR.
+       (chrec_convert_rhs): New function.
+       (chrec_convert_aggressive): For POINTER_PLUS_EXPR, use a
+       different right hand side type.
+       Handle POINTER_PLUS_EXPR like PLUS_EXPR.
+       * tree-chrec.h (chrec_convert_rhs): New prototype.
+       (build_polynomial_chrec): For pointer types, the right hand
+       * tree-ssa-ccp.c (maybe_fold_stmt_indirect): Look for
+       POINTER_PLUS_EXPR instead of PLUS_EXPR's.
+       Remove subtraction case as it is always addition now.
+       Make sure the offset is converted to sizetype.
+       (fold_stmt_r): Don't handle PLUS_EXPR/MINUS_EXPR specially.
+       Handle POINTER_PLUS_EXPR like PLUS_EXPR was handled before.
+       * tree-ssa-loop-ivopts.c (determine_base_object): Abort for 
+       PLUS_EXPR in pointer type.
+       Handle POINTER_PLUS_EXPR.
+       (tree_to_aff_combination): Likewise.
+       (force_expr_to_var_cost): Likewise.
+       (force_expr_to_var_cost): Likewise. Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       * c-format.c (check_format_arg): Handle POINTER_PLUS_EXPR
+       instead of PLUS_EXPR of pointer types.
+       * tree-stdarg.c (va_list_counter_bump): Handle POINTER_PLUS_EXPR
+       as PLUS_EXPR.
+       (check_va_list_escapes): Likewise.
+       (check_all_va_list_escapes): Likewise.
+       * dwarf2out.c (loc_descriptor_from_tree_1):
+       Handle POINT_PLUS_EXPR as a PLUS_EXPR.
+       * expr.c (expand_expr_real_1): Handle POINTER_PLUS_EXPR.
+       (string_constant): Likewise.
+       * tree-ssa-address.c (tree_mem_ref_addr): When adding
+       the offset to the base, use POINTER_PLUS_EXPR.
+       (add_to_parts): Convert the index to sizetype.
+       (create_mem_ref): Create A POINTER_PLUS_EXPR for the one case.
+       * matrix-reorg.c (collect_data_for_malloc_call): Stmt
+       will now only be either INDIRECT_REF and POINTER_PLUS_EXPR.
+       Offset only holds something for PLUS_EXPR.
+       (ssa_accessed_in_tree): Handle POINTER_PLUS_EXPR just as
+       a PLUS_EXPR.
+       (analyze_transpose): POINTER_PLUS_EXPR will only show up now
+       and not PLUS_EXPR.
+       (analyze_accesses_for_modify_stmt): Likewise.
+       Remove comment about the type being integral type as it is
+       wrong now.
+       (can_calculate_expr_before_stmt): Handle POINTER_PLUS_EXPR as
+       PLUS_EXPR.
+       (transform_access_sites): POINTER_PLUS_EXPR will only show up now
+       and not PLUS_EXPR.
+       Correct the type which the artimentic is done in (is now
+       sizetype).
+       Reindent one loop.
+       * tree-data-ref.c (split_constant_offset): Handle
+       POINTER_PLUS_EXPR
+       * tree-affine.c (tree_to_aff_combination): Likewise.
+       * c-typeck.c (build_unary_op): For pointers create the increment
+       as a sizetype. Create a POINTER_PLUS_EXPR instead of PLUS_EXPR
+       for pointers.
+       * gimplify.c (gimplify_self_mod_expr): Create a
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
+       (gimplify_omp_atomic_fetch_op): Handle POINTER_PLUS_EXPR.
+       * tree.def (POINTER_PLUS_EXPR): New tree code.
+       * tree-predcom.c (ref_at_iteration): If we have a pointer
+       type do the multiplication in sizetype.
+       * tree-mudflap.c (mf_xform_derefs_1): Create a
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
+       * tree-ssa-forwprop.c 
+       (forward_propagate_addr_into_variable_array_index):
+       Don't expect there to be a cast for the index as that
+       does not exist anymore.
+       (forward_propagate_addr_expr_1): Check for POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       Don't check for the first operand of the POINTER_PLUS_EXPR
+       was the index as it cannot be.
+       Call forward_propagate_addr_into_variable_array_index with
+       the SSA_NAME instead of the statement.
+       * varasm.c (const_hash_1): Handle POINTER_PLUS_EXPR.
+       (compare_constant): Likewise.
+       (copy_constant): Likewise.
+       (compute_reloc_for_constant): Likewise.
+       (output_addressed_constants): Likewise.
+       (initializer_constant_valid_p): Likewise.
+       * tree-ssa.c (tree_ssa_useless_type_conversion_1):
+       Convert the MIN/MAX of the inner type to the outer
+       type before comparing them.
+       * tree-ssa-loop-prefetch.c (idx_analyze_ref):  Handle
+       POINTER_PLUS_EXPR instead of PLUS_EXPR.
+       (issue_prefetch_ref): Create a POINTER_PLUS_EXPR instead
+       of PLUS_EXPR for pointers.
+       * tree-inline.c (estimate_num_insns_1): Handle
+       POINTER_PLUS_EXPR.
+       * tree-vect-transform.c (vect_create_addr_base_for_vector_ref): 
+       Create a POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
+       (bump_vector_ptr): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for the pointer increment statement.
+       (vect_update_ivs_after_vectorizer): For pointer types, create
+       POINTER_PLUS_EXPR instead of PLUS_EXPR and also create
+       MULT_EXPR in sizetype.
+       (vect_gen_niters_for_prolog_loop): Add a cast when creating
+       byte_misalign.
+       * tree-object-size.c (plus_expr_object_size): Handle
+       POINTER_PLUS_EXPR instead of PLUS_EXPR.  Removing all the extra
+       code which is trying to figure out which side is a pointer and 
+       is the index.
+       (check_for_plus_in_loops_1): Likewise.
+       (check_for_plus_in_loops): Likewise.
+       * c-common.c (pointer_int_sum): Create a
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
+       * tree-ssa-structalias.c (handle_ptr_arith): Handle
+       only POINTER_PLUS_EXPR.  Removing all the extra
+       code which is trying to figure out which side is a pointer and 
+       is the index.
+       * tree-cfg.c (verify_expr): Add extra checking for pointers and
+       PLUS_EXPR and MINUS_EXPR.
+       Also add checking to make sure the operands of POINTER_PLUS_EXPR
+       are correct.
+       * config/frv/frv.c (frv_expand_builtin_va_start): Use sizetype
+       with make_tree, instead of a pointer type.
+       * config/s390/s390.c (s390_va_start): Use POINTER_PLUS_EXPR
+       for pointers instead of PLUS_EXPR.
+       (s390_gimplify_va_arg): Likewise.
+       * config/spu/spu.c (spu_va_start): Create POINTER_PLUS_EXPR
+       instead of PLUS_EXPR when doing addition on pointer
+       types.  Use sizetype for the second operand.
+       (spu_gimplify_va_arg_expr): Likewise.
+       * config/sparc/sparc.c (sparc_gimplify_va_arg): Use 
+       POINTER_PLUS_EXPR instead of PLUS_EXPR when the operand was
+       a pointer.  Don't create a BIT_AND_EXPR for pointer types.
+       * config/i386/i386.c (ix86_va_start): Use POINTER_PLUS_EXPR
+       for the pointer addition and also use size_int/sizetype
+       for the offset.
+       (ix86_gimplify_va_arg): Likewise.
+       Perform BIT_AND_EXPR on sizetype arguments.
+       * config/sh/sh.c (sh_va_start): Call make_tree with sizetype
+       and convert its result to a pointer type.  Use POINTER_PLUS_EXPR
+       for the pointer additions and also use size_int for the offsets.
+       (sh_gimplify_va_arg_expr): Use POINTER_PLUS_EXPR for the pointer
+       additions and also use size_int for the offsets.  Perform
+       BIT_AND_EXPR on sizetype arguments.
+       * config/ia64/ia64.c (ia64_gimplify_va_arg): Use
+       POINTER_PLUS_EXPR for pointers and create the
+       BIT_AND_EXPR in sizetype.
+       * config/rs6000/rs6000.c (rs6000_va_start): Use POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointer addition.
+       (rs6000_va_start): Likewise.
+       Also use sizetype for the offset.
+       * config/pa/pa.c (reloc_needed): Handle POINTER_PLUS_EXPR
+       as PLUS_EXPR/MINUS_EXPR.
+       (hppa_gimplify_va_arg_expr): Don't create MINUS_EXPR or
+       PLUS_EXPR for pointers, instead use POINTER_PLUS_EXPR.
+       Don't use BIT_AND_EXPR on a pointer type, convert the
+       expression to sizetype first.
+       * config/mips/mips.c (mips_va_start): Use POINTER_PLUS_EXPR
+       for pointers.
+       (mips_gimplify_va_arg_expr): Likewise.
+       Don't create BIT_AND_EXPR in a pointer type.
+
 2007-06-15  Eric Christopher  <echristo@apple.com>
 
        * config.gcc (i?86-*-darwin*): Add t-crtfm and t-crtpc.
diff --git a/gcc/ChangeLog.ptr b/gcc/ChangeLog.ptr
new file mode 100644 (file)
index 0000000..5c7380d
--- /dev/null
@@ -0,0 +1,539 @@
+2007-06-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 125733
+
+2007-06-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-vrp.c (compare_values_warnv): Fix spelling/grammer
+       mistakes
+       (extract_range_from_binary_expr): Likewise.
+       * doc/c-tree.texi (POINTER_PLUS_EXPR): Likewise.
+       * tree-ssa-loop-niter.c (assert_loop_rolls_lt): Add vertical
+       whitespace.
+       * tree-pretty-print.c (op_symbol_code <case POINTER_PLUS_EXPR>):
+       Change print out to "+".
+       * tree-scalar-evolution.c (instantiate_parameters_1):
+       Use chrec_type instead of TREE_TYPE.
+       * builtins.c (expand_builtin_strcat): Fix vertical whitespace.
+       (std_expand_builtin_va_start): Fix whitespace.
+       (fold_builtin_strstr): Use size_int instead of build_int_cst (sizetype.
+       (fold_builtin_strchr): Likewise.
+       (fold_builtin_strrchr): Likewise.
+       (fold_builtin_strpbrk): Likewise.
+       * fold-const.c (try_move_mult_to_index): Fix spelling/grammer
+       mistakes.
+       (fold_to_nonsharp_ineq_using_bound): Merge the two ifs at the end.
+       (fold_binary): Fix spelling/grammer mistakes.
+       * tree-ssa-ccp.c (maybe_fold_stmt_addition): Assert that only
+       a POINTER_PLUS_EXPR is passed in.
+       * tree-ssa-loop-ivopts.c (determine_base_object):
+       Fix spelling/grammer mistakes.
+       * expr.c (expand_expr_real_1): Likewise.
+       * tree-data-ref.c (split_constant_offset): Likewise.
+       * c-typeck.c (build_unary_op): Use fold_convert instead of convert
+       for converting to sizetype.
+       * tree.def (POINTER_PLUS_EXPR): Fix comment.
+       * tree-ssa-forwprop.c (forward_propagate_addr_expr_1):
+       Fix spelling/grammer mistakes.
+       (phiprop_insert_phi): Likewise.
+       * c-common.c (pointer_int_sum): Remove FIXME about
+       POINTER_MINUS_EXPR.
+
+2007-06-13  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * expr.c (expand_expr_real_1 <case POINTER_PLUS_EXPR>): Remove assert
+       for checking the modes of the operands are the same.
+
+2007-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * config/sparc/sparc.c (sparc_gimplify_va_arg): Use POINTER_PLUS_EXPR
+       instead of PLUS_EXPR when the operand was a pointer.  Don't create a
+       BIT_AND_EXPR for pointer types.
+
+2007-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * config/mips/mips.c (mips_va_start): Use POINTER_PLUS_EXPR
+       for pointers.
+       (mips_gimplify_va_arg_expr): Likewise.
+       Don't create BIT_AND_EXPR in a pointer type.
+
+2007-06-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 125658 
+
+2007-06-11  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 125611
+
+2007-06-07  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * matrix-reorg.c (collect_data_for_malloc_call): Stmt
+       will now only be either INDIRECT_REF and POINTER_PLUS_EXPR.
+       Offset only holds something for PLUS_EXPR.
+       (ssa_accessed_in_tree): Handle POINTER_PLUS_EXPR just as
+       a PLUS_EXPR.
+       (analyze_transpose): POINTER_PLUS_EXPR will only show up now
+       and not PLUS_EXPR.
+       (analyze_accesses_for_modify_stmt): Likewise.
+       Remove comment about the type being integral type as it is
+       wrong now.
+       (analyze_matrix_accesses): Handle POINTER_PLUS_EXPR as
+       PLUS_EXPR.
+       (transform_access_sites): POINTER_PLUS_EXPR will only show up now
+       and not PLUS_EXPR.
+       Correct the type which the artimentic is done in (is now
+       sizetype).
+       Reindent one loop.
+
+2007-06-07  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * config/ia64/ia64.c (ia64_gimplify_va_arg): Use
+       POINTER_PLUS_EXPR for pointers and create the
+       BIT_AND_EXPR in sizetype.
+       * config/s390/s390.c (s390_va_start): Use POINTER_PLUS_EXPR
+       for pointers instead of PLUS_EXPR.
+       (s390_gimplify_va_arg): Likewise.
+
+2007-06-07  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * config/frv/frv.c (frv_expand_builtin_va_start): Use sizetype
+       with make_tree, instead of a pointer type.
+       * config/pa/pa.c (reloc_needed): Handle POINTER_PLUS_EXPR
+       as PLUS_EXPR/MINUS_EXPR.
+       (hppa_gimplify_va_arg_expr): Don't create MINUS_EXPR or
+       PLUS_EXPR for pointers, instead use POINTER_PLUS_EXPR.
+       Don't use BIT_AND_EXPR on a pointer type, convert the
+       expression to sizetype first.
+
+2007-06-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-ssa-forwprop.c
+       (forward_propagate_addr_into_variable_array_index):
+       Don't expect a statement for the size 1 case.
+       Use the offset variable for the size 1 case.
+       Look through use-def chains to find the mutliply
+       for the non size 1 case.
+       (forward_propagate_addr_expr_1): Call
+       forward_propagate_addr_into_variable_array_index with
+       the SSA_NAME instead of the statement.
+
+2007-06-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       PR tree-opt/32225
+       * tree-scalar-evolution.c (follow_ssa_edge_in_rhs <case
+       POINTER_PLUS_EXPR>): Do not change type_rhs.
+       (follow_ssa_edge_in_rhs <case POINTER_PLUS_EXPR, case PLUS_EXPR>):
+       Use the code of the orginal expression instead of just PLUS_EXPR.
+       Also use type_rhs where TREE_TYPE (rhs) was used (reverting back
+       to the trunk).
+
+2007-06-03  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-predcom.c (ref_at_iteration): If we have a pointer
+       type do the multiplication in sizetype.
+
+2007-06-01  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 125285
+
+2007-05-31  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-vrp.c (extract_range_from_binary_expr): Handle
+       MIN_EXPR/MAX_EXPR for pointers type.
+
+       PR tree-opt/32167
+       * tree-chrec.c (chrec_fold_plus): When either
+       operand is zero, convert the other operand.
+
+2007-05-30  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * builtins.c (std_expand_builtin_va_start): Use
+       sizetype for the call to make_tree and then convert
+       to the pointer type.
+
+2007-05-30  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       PR tree-op/32145
+       * tree-vrp.c (extract_range_from_assert): Create
+       POINTER_PLUS_EXPR for pointer types.
+
+       PR tree-opt/32144
+       * tree-chrec.c (chrec_fold_plus_poly_poly): If the
+       first chrec is a pointer type, then the second should
+       be sizetype and not the first's type.   
+
+2007-05-28  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * fold-const.c (try_move_mult_to_index):
+       Say why we strip the nops.
+       (fold_unary <case NOP_EXPR>): Remove
+       TODO as we cannot get that case.
+       * tree-chrec.c (chrec_fold_plus):
+       Cleanup the code to chose which
+       tree code is used.
+       (chrec_convert_rhs): Add comment on
+       why the increment is sizetype for
+       pointers.
+       * tree-mudflap.c (mf_xform_derefs_1):
+       Use size_int instead of build_int_cst.
+       * tree-ssa-loop-prefetch.c (issue_prefetch_ref): Likewise.
+
+2007-05-21  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       PR tree-opt/32015
+       * tree.c (build2_stat): Make sure that
+       MULT_EXPR is not used with pointers.
+       * tree-chrec.c (chrec_apply): Use chrec_convert_rhs
+       on the argument x instead of chrec_convert.
+
+2007-05-20  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       * config/sh/sh.c (sh_va_start): Call make_tree with sizetype
+       and convert its result to a pointer type.  Use POINTER_PLUS_EXPR
+       for the pointer additions and also use size_int for the offsets.
+       (sh_gimplify_va_arg_expr): Use POINTER_PLUS_EXPR for the pointer
+       additions and also use size_int for the offsets.  Perform
+       BIT_AND_EXPR on sizetype arguments.
+
+2007-05-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-ssa-forwprop (forward_propagate_addr_into_variable_array_index):
+       Don't expect there to be a cast for the index as that
+       does not exist anymore.
+       (forward_propagate_addr_expr_1): Check for
+       POINTER_PLUS_EXPR instead of PLUS_EXPR.
+       Don't check for the first operand of the
+       POINTER_PLUS_EXPR was the index as it
+       cannot be.
+
+2007-05-15  Richard Guenther  <rguenther@suse.de>
+
+       * config/i386/i386.c (ix86_gimplify_va_arg): Use POINTER_PLUS_EXPR,
+       perform BIT_AND_EXPR on sizetype arguments.
+
+2007-05-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * config/rs6000/rs6000.c (rs6000_va_start): Use POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointer addition.
+       (rs6000_va_start): Likewise.
+       Also use sizetype for the offset.
+       * tree-stdarg.c (va_list_counter_bump): Check for PLUS_EXPR
+       and POINTER_PLUS_EXPR.
+       (check_va_list_escapes): Likewise.
+
+2007-05-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * config/i386/i386.c (ix86_va_start): Use POINTER_PLUS_EXPR
+       for the pointer addition and also use size_int/sizetype
+       for the offset.
+       (ix86_gimplify_va_arg): Likewise.
+
+2007-05-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 124657
+       * tree-data-ref.c (split_constant_offset): Handle
+       POINTER_PLUS_EXPR
+       exactly the same as PLUS_EXPR/MINUS_EXPR except for the offset
+       needs to be calcuated using PLUS_EXPR instead of
+       POINTER_PLUS_EXPR.
+       * builtins.c (fold_builtin_memchr): Use POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for adding to a pointer.
+
+2006-05-15  Zdenek Dvorak <dvorakz@suse.cz>
+
+       * tree-ssa-loop-ivopts.c (determine_base_object): Abort for PLUS_EXPR
+       in pointer type.
+
+2007-05-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-ssa-address.c (tree_mem_ref_addr): When adding
+       the offset to the base, use POINTER_PLUS_EXPR.
+
+2007-05-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * expr.c (expand_expr_addr_expr_1): Call expand_expr
+       for the offset with the modifier as EXPAND_INITIALIZER
+       if the modifier is EXPAND_INITIALIZER.
+       (expand_expr_real_1 <case INTEGER_CST>): Don't force to
+       a register if we had an overflow.
+
+2007-05-10  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 124602.
+
+       * fold-const.c  (extract_array_ref): Make sure the offset
+       is converted to sizetype.
+       (try_move_mult_to_index): Strip the NOPs from the offset.
+       (fold_binary <case POINTER_PLUS_EXPR>): Convert the second
+       operand to sizetype before calling try_move_mult_to_index.
+       * tree-ssa-loop-niter.c (number_of_iterations_lt_to_ne):
+       For pointer types, use sizetype when
+       creating MINUS_EXPR/PLUS_EXPRs.
+       * tree-ssa-ccp.c (maybe_fold_stmt_indirect): Make sure
+       the offset is converted to sizetype.
+
+2007-05-11  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * config/spu/spu.c (spu_va_start): Create POINTER_PLUS_EXPR
+       instead of PLUS_EXPR when doing addition on pointer
+       types.  Use sizetype for the second operand.
+       (spu_gimplify_va_arg_expr): Likewise.
+       * tree-ssa.c (tree_ssa_useless_type_conversion_1):
+       Convert the MIN/MAX of the inner type to the outer
+       type before comparing them.
+
+2007-05-09  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+           Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * fold-const.c  (fold_to_nonsharp_ineq_using_bound): Don't
+       use a pointer type for MINUS_EXPR.
+       (fold_binary <case MINUS_EXPR>): Fold (PTR0 p+ A) - (PTR1 p+ B)
+       into (PTR0 - PTR1) + (A - B). Fold (PTR0 p+ A) - PTR1 into
+       (PTR0 - PTR1) + A iff (PTR0 - PTR1) simplifies.
+       * tree-chrec.c (chrec_fold_plus_poly_poly): For
+       POINTER_PLUS_EXPR, use a different right hand side type.
+       Handle POINTER_PLUS_EXPR like PLUS_EXPR.
+       (chrec_fold_plus_1): Likewise.
+       (convert_affine_scev): Likewise.
+       (chrec_convert_aggressive): Likewise.
+       (chrec_fold_plus): For pointer types, use POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       (reset_evolution_in_loop): For pointer types, the new_evol
+       should be sizetype.
+       (chrec_convert_rhs): New function.
+       * tree-chrec.h (chrec_convert_rhs): New prototype.
+       (build_polynomial_chrec): For pointer types, the right hand
+       side should be sizetype and not the same as the left hand side.
+       * tree-scalar-evolution.c (add_to_evolution_1): Convert the
+       increment using chrec_convert_rhs instead of chrec_convert.
+       (follow_ssa_edge_in_rhs): Handle POINTER_PLUS_EXPR like
+       PLUS_EXPR except for the right hand side's type will be
+       sizetype.
+       (interpret_rhs_modify_stmt): Handle POINTER_PLUS_EXPR.
+       (fold_used_pointer_cast): Kill.
+       (pointer_offset_p): Kill.
+       (fold_used_pointer): Kill.
+       (pointer_used_p): Kill.
+       (analyze_scalar_evolution_1 <case GIMPLE_MODIFY_STMT>): Don't
+       call fold_used_pointer.
+       (instantiate_parameters_1): Convert the increment
+       using chrec_convert_rhs instead of chrec_convert.
+       Handle POINTER_PLUS_EXPR as PLUS_EXPR.
+       * tree-ssa-loop-niter.c (split_to_var_and_offset): Handle
+       POINTER_PLUS_EXPR as PLUS_EXPR.
+       (assert_loop_rolls_lt): For pointer types, use sizetype when
+       creating MINUS_EXPR/PLUS_EXPRs.
+       (number_of_iterations_le): Likewise.
+       (expand_simple_operations): POINTER_PLUS_EXPR are simple also.
+       (derive_constant_upper_bound): Handle POINTER_PLUS_EXPR just
+       like PLUS_EXPR and MINUS_EXPR.
+       * tree-data-ref.c (analyze_offset_expr): Likewise.
+       (address_analysis): Handle POINTER_PLUS_EXPR as PLUS_EXPR.
+       (analyze_offset): Handle POINTER_PLUS_EXPR also.
+       (create_data_ref): Convert the increment
+       using chrec_convert_rhs instead of chrec_convert.
+       * tree-vect-transform.c (vect_update_ivs_after_vectorizer):
+       For pointer types, create POINTER_PLUS_EXPR instead of
+       PLUS_EXPR and also create MULT_EXPR in sizetype.
+
+2007-05-07  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * builtins.c (std_gimplify_va_arg_expr): Use fold_build2 for
+       the creating of POINTER_PLUS_EXPR.  For the BIT_AND_EXPR, cast
+       the operands to sizetype first and then cast the BIT_AND_EXPR
+       back to the pointer type.
+       * tree-ssa-address.c (create_mem_ref): Create A
+       POINTER_PLUS_EXPR for one case.
+       * tree.c (const_hash_1): Handle POINTER_PLUS_EXPR same as
+       PLUS_EXPR.
+       (compare_constant): Likewise.
+       (copy_constant): Likewise.
+       (compute_reloc_for_constant): Likewise.
+       (output_addressed_constants): Likewise.
+
+2007-05-07  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree.def (POINTER_PLUS_EXPR): The second operand
+       is of type sizetype and not ssizetype.
+       * doc/c-tree.texi (POINTER_PLUS_EXPR): Document.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-mudflap.c (mf_xform_derefs_1 <case BIT_FIELD_REF>):
+       Add a conversion of ofs to sizetype.
+       (mf_decl_eligible_p): Reformat for length issues.
+       (mf_xform_derefs_1): Likewise.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree.c (build2_stat): Check to make sure the
+       second operand is compatiable with sizetype.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-cfg.c (verify_expr): Change error
+       message about sizetype to be correct.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 124478.
+       * fold-const.c (fold_unary): Handle for (T1)(X op Y),
+       only p+ as that is the only as that can be handled for
+       binary operators now.  Add a TODO for non pointer type
+       op's.
+       * gimplifier.c (gimplify_expr): Don't special case
+       PLUS_EXPR.  Special case POINTER_PLUS_EXPR instead,
+       remove check for pointer type as it will always be
+       a pointer type now.
+
+2007-05-04  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-vrp.c (extract_range_from_binary_expr): Handle
+       POINTER_PLUS_EXPRs.  Assert POINTER_PLUS_EXPR is
+       the only expression for pointer types.
+       * tree-vect-transform.c (vect_gen_niters_for_prolog_loop):
+       Add a cast when creating byte_misalign.
+
+2007-05-04  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * fold-const.c (fold_binary <case POINTER_PLUS_EXPR>);
+       Add comment on why you get INT +p INT.
+       (fold_binary <case PLUS_EXPR>): Add folding of PTR+INT into
+       PTR p+ INT.
+       * dwarf2out.c (loc_descriptor_from_tree_1):
+       Handle POINT_PLUS_EXPR as a PLUS_EXPR.
+
+2007-05-04  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree-vrp.c  (compare_values_warnv): Convert val2 to
+       the type of val1.
+       * fold-const.c (extract_array_ref): Look for
+       POINTER_PLUS_EXPR instead of PLUS_EXPR's.
+       * tree-ssa-ccp.c (maybe_fold_stmt_indirect): Likewise.
+
+2007-05-02  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * c-format.c (check_format_arg): Handle POINTER_PLUS_EXPR
+       instead of PLUS_EXPR of pointer types.
+
+2007-05-02  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * fold-const.c (try_move_mult_to_index): Remove code argument
+       and replace all uses with PLUS_EXPR.
+       (fold_binary <case POINTER_PLUS_EXR>): Remove code argument.
+       (fold_binary <case PLUS_EXPR>): Don't call try_move_mult_to_index.
+       (fold_binary <case MINUS_EXPR>): Likewise.
+       * tree-ssa-ccp.c (maybe_fold_stmt_indirect): Remove subtraction
+       case as it is always addition now.
+       (fold_stmt_r): Don't handle PLUS_EXPR/MINUS_EXPR specially.
+       Handle POINTER_PLUS_EXPR like PLUS_EXPR was handled before.
+
+2007-05-01  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 124343.
+       * tree-vect-transform.c (bump_vector_ptr): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for the pointer increment statement.
+       * expr.c (expand_expr_real_1): Add FIXME/assert for the unhandle case
+       where the modes of the two operands are different.
+
+2007-02-25  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       Merge mainline, revision 122323.
+
+2006-12-14  Zdenek Dvorak <dvorakz@suse.cz>
+
+       Merge mainline, revision 119860.
+
+2006-11-23  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * tree.def (POINTER_PLUS_EXPR): New tree code.
+       * tree-pretty-print.c (dump_generic_node): Handle
+       POINTER_PLUS_EXPR.
+       (op_prio): Likewise.
+       (op_symbol_1): Likewise.
+       * optabs.c (optab_for_tree_code): Likewise.
+       * tree-ssa-loop-manip.c (create_iv): Handle pointer base
+       specially.
+       * tree-tailcall.c (process_assignment): Mention
+       POINTER_PLUS_EXPR in a TODO comment.
+       * tree.c (build2_stat): Assert when trying to use PLUS_EXPR or 
+       MINUS_EXPR with a pointer. Also assert for POINTER_PLUS_EXPR
+       not used with a pointer and an integer type.
+       *  tree-scalar-evolution.c (fold_used_pointer): Mention
+       POINTER_PLUS_EXPR is what this needs to handle.
+       * builtins.c (get_pointer_alignment): Handle POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       (expand_builtin_strcat): Create a POINTER_PLUS_EXPR instead of
+       PLUS_EXPR for pointers.
+       (std_gimplify_va_arg_expr): Likewise.
+       (fold_builtin_memory_op): Likewise.
+       (fold_builtin_strstr): Likewise.
+       (fold_builtin_strchr): Likewise.
+       (fold_builtin_strrchr): Likewise.
+       (fold_builtin_strpbrk): Likewise.
+       (expand_builtin_memory_chk): Likewise.
+       (fold_builtin_memory_chk): Likewise.
+       * fold-const.c (build_range_check): Handle pointer types
+       specially.
+       (fold_to_nonsharp_ineq_using_bound): Likewise.
+       (fold_binary): Handle simple POINTER_PLUS_EXPR cases.
+       (tree_expr_nonnegative_p): Handle POINTER_PLUS_EXPR.
+       (tree_expr_nonzero_p): Likewise.
+       (fold_indirect_ref_1): Look at POINTER_PLUS_EXPR instead
+       of PLUS_EXPR for the complex expression folding.
+       * tree-ssa-loop-ivopts.c (determine_base_object): Handle
+       POINTER_PLUS_EXPR.
+       (tree_to_aff_combination): Likewise.
+       (force_expr_to_var_cost): Likewise.
+       (force_expr_to_var_cost): Likewise. Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       * c-format.c (check_format_arg): Mention this should be handling
+       POINTER_PLUS_EXPR.
+       * tree-stdarg.c (va_list_counter_bump): Handle POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       (check_va_list_escapes): Likewise.
+       (check_all_va_list_escapes): Likewise.
+       * expr.c (expand_expr_real_1): Handle POINTER_PLUS_EXPR.
+       (string_constant): Likewise.
+       * tree-ssa-address.c (add_to_parts): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       (most_expensive_mult_to_index): Likewise.
+       (addr_to_parts): Use the correct type for the index.
+       * c-typeck.c (build_unary_op): For pointers create the increment
+       as a sizetype. Create a POINTER_PLUS_EXPR instead of PLUS_EXPR
+       for pointers.
+       * gimplify.c (gimplify_self_mod_expr): Create a
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
+       (gimplify_omp_atomic_fetch_op): Handle POINTER_PLUS_EXPR.
+       * tree-mudflap.c (mf_xform_derefs_1): Create a
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
+       * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Add a
+       note this should be handling POINTER_PLUS_EXPR.
+       * varasm.c (initializer_constant_valid_p): Handle
+       POINTER_PLUS_EXPR.
+       * tree-ssa-loop-prefetch.c (idx_analyze_ref):  Handle
+       POINTER_PLUS_EXPR instead of PLUS_EXPR.
+       (issue_prefetch_ref): Create a POINTER_PLUS_EXPR instead
+       of PLUS_EXPR for pointers.
+       * tree-vect-transform.c (vect_create_addr_base_for_vector_ref):
+       Likewise.
+       * tree-inline.c (estimate_num_insns_1): Handle
+       POINTER_PLUS_EXPR.
+       * tree-object-size.c (plus_expr_object_size): Handle
+       POINTER_PLUS_EXPR instead of PLUS_EXPR.  Removing all the extra
+       code which is trying to figure out which side is a pointer and 
+       is the index.
+       (check_for_plus_in_loops_1): Likewise.
+       (check_for_plus_in_loops): Likewise.
+       * c-common.c (pointer_int_sum): Create a
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointers.
+       * tree-ssa-structalias.c (handle_ptr_arith): Handle
+       only POINTER_PLUS_EXPR.  Removing all the extra
+       code which is trying to figure out which side is a pointer and 
+       is the index.
+       * tree-cfg.c (verify_expr): Add extra checking for pointers and
+       PLUS_EXPR and MINUS_EXPR.
+       Also add checking to make sure the operands of POINTER_PLUS_EXPR
+       are correct.
+
+
index d3c8a54000da9267f8e61dd2a3f7beed429195de..8d8c3b782ee4256bca1ec1f3e114cc8982910925 100644 (file)
@@ -1,3 +1,18 @@
+2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * trans.c (Attribute_to_gnu): When subtracting an
+       offset from a pointer, use POINTER_PLUS_EXPR with
+       NEGATE_EXPR instead of MINUS_EXPR.
+       (gnat_to_gnu): Likewise.
+       * utils.c (convert): When converting between
+       thin pointers, use POINTER_PLUS_EXPR and sizetype
+       for the offset.
+       * utils2.c (known_alignment): POINTER_PLUS_EXPR
+       have the same semantics as PLUS_EXPR for alignment.
+       (build_binary_op): Add support for the semantics of
+       POINTER_PLUS_EXPR's operands.
+       When adding an offset to a pointer, use POINTER_PLUS_EXPR.
+
 2007-06-11  Rafael Avila de Espindola  <espindola@google.com>
 
        * trans.c (Attribute_to_gnu): Use signed_or_unsigned_type_for instead
diff --git a/gcc/ada/ChangeLog.ptr b/gcc/ada/ChangeLog.ptr
new file mode 100644 (file)
index 0000000..26d8b6a
--- /dev/null
@@ -0,0 +1,21 @@
+2007-06-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * trans.c (Attribute_to_gnu): Use fold_build1 instead
+       of build1 for NEGATE_EXPR.
+       (gnat_to_gnu): Likewise.
+
+2007-05-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * trans.c (Attribute_to_gnu): When subtracting an
+       offset from a pointer, use POINTER_PLUS_EXPR with
+       NEGATE_EXPR instead of MINUS_EXPR.
+       (gnat_to_gnu): Likewise.
+       * utils.c (convert): When converting between
+       thin pointers, use POINTER_PLUS_EXPR and sizetype
+       for the offset.
+       * utils2.c (known_alignment): POINTER_PLUS_EXPR
+       have the same semantics as PLUS_EXPR for alignment.
+       (build_binary_op): Add support for the semantics of
+       POINTER_PLUS_EXPR's operands.
+       When adding an offset to a pointer, use POINTER_PLUS_EXPR.
+
index 082ecd12661bed61aa4352cebab8f99ad82ac034..052935cefee49231959b56c4f1a36b6f418a8185 100644 (file)
@@ -829,11 +829,12 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
            tree gnu_char_ptr_type = build_pointer_type (char_type_node);
            tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
            tree gnu_byte_offset
-             = convert (gnu_char_ptr_type,
+             = convert (sizetype,
                         size_diffop (size_zero_node, gnu_pos));
+           gnu_byte_offset = fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
 
            gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
-           gnu_ptr = build_binary_op (MINUS_EXPR, gnu_char_ptr_type,
+           gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
                                       gnu_ptr, gnu_byte_offset);
          }
 
@@ -4571,11 +4572,12 @@ gnat_to_gnu (Node_Id gnat_node)
              tree gnu_char_ptr_type = build_pointer_type (char_type_node);
              tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
              tree gnu_byte_offset
-               = convert (gnu_char_ptr_type,
+               = convert (sizetype,
                           size_diffop (size_zero_node, gnu_pos));
+             gnu_byte_offset = fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
 
              gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
-             gnu_ptr = build_binary_op (MINUS_EXPR, gnu_char_ptr_type,
+             gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
                                         gnu_ptr, gnu_byte_offset);
            }
 
index a8a673c06dea37c40f93217123c518f4f79963a4..8a8ee7f96e047df7bb4c5d510242c734286f54bb 100644 (file)
@@ -3601,8 +3601,8 @@ convert (tree type, tree expr)
          if (integer_zerop (byte_diff))
            return expr;
 
-         return build_binary_op (PLUS_EXPR, type, expr,
-                                 fold (convert_to_pointer (type, byte_diff)));
+         return build_binary_op (POINTER_PLUS_EXPR, type, expr,
+                                 fold (convert (sizetype, byte_diff)));
        }
 
       /* If converting to a thin pointer, handle specially.  */
index e49ba30e273e87be15acaabf2e61cc97a48110f9..29d8f0fbab52c2a3d84fd9b8637048e7e2b414d3 100644 (file)
@@ -172,6 +172,7 @@ known_alignment (tree exp)
       break;
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
       /* If two address are added, the alignment of the result is the
         minimum of the two alignments.  */
@@ -961,6 +962,13 @@ build_binary_op (enum tree_code op_code, tree result_type,
       modulus = NULL_TREE;
       goto common;
 
+    case POINTER_PLUS_EXPR:
+      gcc_assert (operation_type == left_base_type
+                 && sizetype == right_base_type);
+      left_operand = convert (operation_type, left_operand);
+      right_operand = convert (sizetype, right_operand);
+      break;
+
     default:
     common:
       /* The result type should be the same as the base types of the
@@ -1116,8 +1124,7 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
                 type, if any.  */
              inner = build_unary_op (ADDR_EXPR, NULL_TREE, inner);
              inner = convert (ptr_void_type_node, inner);
-             offset = convert (ptr_void_type_node, offset);
-             result = build_binary_op (PLUS_EXPR, ptr_void_type_node,
+             result = build_binary_op (POINTER_PLUS_EXPR, ptr_void_type_node,
                                        inner, offset);
              result = convert (build_pointer_type (TREE_TYPE (operand)),
                                result);
index 133aa7c8d113ae815ffb829b6410396de077b9c9..6dff9b8f02f2b1337dcc2aaad6fcffda2e836528 100644 (file)
@@ -291,7 +291,7 @@ get_pointer_alignment (tree exp, unsigned int max_align)
          align = MIN (inner, max_align);
          break;
 
-       case PLUS_EXPR:
+       case POINTER_PLUS_EXPR:
          /* If sum of pointer + int, restrict our maximum alignment to that
             imposed by the integer.  If not, we can't do any better than
             ALIGN.  */
@@ -4433,10 +4433,9 @@ expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode
 
          /* Create strlen (dst).  */
          newdst = build_call_expr (strlen_fn, 1, dst);
-         /* Create (dst + (cast) strlen (dst)).  */
-         newdst = fold_convert (TREE_TYPE (dst), newdst);
-         newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
+         /* Create (dst p+ strlen (dst)).  */
 
+         newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
          newdst = builtin_save_expr (newdst);
 
          if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
@@ -4650,9 +4649,10 @@ void
 std_expand_builtin_va_start (tree valist, rtx nextarg)
 {
   tree t;
+  t = make_tree (sizetype, nextarg);
+  t = fold_convert (ptr_type_node, t);
 
-  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
-             make_tree (ptr_type_node, nextarg));
+  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
   TREE_SIDE_EFFECTS (t) = 1;
 
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -4719,14 +4719,16 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
   if (boundary > align
       && !integer_zerop (TYPE_SIZE (type)))
     {
-      t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
-                 build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
+                 fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist),
+                              valist_tmp, size_int (boundary - 1)));
       gimplify_and_add (t, pre_p);
 
-      t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
+      t = fold_convert (sizetype, valist_tmp);
       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
-                 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
+                 fold_convert (TREE_TYPE (valist),
+                               fold_build2 (BIT_AND_EXPR, sizetype, t,
+                                            size_int (-boundary))));
       gimplify_and_add (t, pre_p);
     }
   else
@@ -4757,13 +4759,11 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
       t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
                       size_binop (MINUS_EXPR, rounded_size, type_size));
-      t = fold_convert (TREE_TYPE (addr), t);
-      addr = fold_build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t);
+      addr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr), addr, t);
     }
 
   /* Compute new value for AP.  */
-  t = fold_convert (TREE_TYPE (valist), rounded_size);
-  t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
+  t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
   gimplify_and_add (t, pre_p);
 
@@ -8607,8 +8607,7 @@ fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, i
     len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
                       ssize_int (1));
 
-  len = fold_convert (TREE_TYPE (dest), len);
-  dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
+  dest = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
   dest = fold_convert (type, dest);
   if (expr)
     dest = omit_one_operand (type, dest, expr);
@@ -8731,8 +8730,8 @@ fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
          if (r == NULL)
            return build_int_cst (TREE_TYPE (arg1), 0);
 
-         tem = fold_build2 (PLUS_EXPR, TREE_TYPE (arg1), arg1,
-                            build_int_cst (TREE_TYPE (arg1), r - p1));
+         tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
+                            size_int (r - p1));
          return fold_convert (type, tem);
        }
       return NULL_TREE;
@@ -10609,8 +10608,8 @@ fold_builtin_strstr (tree s1, tree s2, tree type)
            return build_int_cst (TREE_TYPE (s1), 0);
 
          /* Return an offset into the constant string argument.  */
-         tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
-                            s1, build_int_cst (TREE_TYPE (s1), r - p1));
+         tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
+                            s1, size_int (r - p1));
          return fold_convert (type, tem);
        }
 
@@ -10679,8 +10678,8 @@ fold_builtin_strchr (tree s1, tree s2, tree type)
            return build_int_cst (TREE_TYPE (s1), 0);
 
          /* Return an offset into the constant string argument.  */
-         tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
-                            s1, build_int_cst (TREE_TYPE (s1), r - p1));
+         tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
+                            s1, size_int (r - p1));
          return fold_convert (type, tem);
        }
       return NULL_TREE;
@@ -10735,8 +10734,8 @@ fold_builtin_strrchr (tree s1, tree s2, tree type)
            return build_int_cst (TREE_TYPE (s1), 0);
 
          /* Return an offset into the constant string argument.  */
-         tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
-                            s1, build_int_cst (TREE_TYPE (s1), r - p1));
+         tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
+                            s1, size_int (r - p1));
          return fold_convert (type, tem);
        }
 
@@ -10795,8 +10794,8 @@ fold_builtin_strpbrk (tree s1, tree s2, tree type)
            return build_int_cst (TREE_TYPE (s1), 0);
 
          /* Return an offset into the constant string argument.  */
-         tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
-                            s1, build_int_cst (TREE_TYPE (s1), r - p1));
+         tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
+                            s1, size_int (r - p1));
          return fold_convert (type, tem);
        }
 
@@ -11382,8 +11381,7 @@ expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
              return expand_expr (dest, target, mode, EXPAND_NORMAL);
            }
 
-         len = fold_convert (TREE_TYPE (dest), len);
-         expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
+         expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
          return expand_expr (expr, target, mode, EXPAND_NORMAL);
        }
 
@@ -11630,8 +11628,7 @@ fold_builtin_memory_chk (tree fndecl,
        return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
       else
        {
-         tree temp = fold_convert (TREE_TYPE (dest), len);
-         temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
+         tree temp = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
          return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
        }
     }
index ccbc479fdee7413b48d4ba477766792d3f79b7c4..9bad32d637a98bcb88299010155ba2ab9021e1f4 100644 (file)
@@ -2700,12 +2700,16 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
      Do this multiplication as signed, then convert to the appropriate
      pointer type (actually unsigned integral).  */
 
-  intop = convert (result_type,
-                  build_binary_op (MULT_EXPR, intop,
-                                   convert (TREE_TYPE (intop), size_exp), 1));
+  intop = build_binary_op (MULT_EXPR, intop,
+                          convert (TREE_TYPE (intop), size_exp), 1);
+
+  if (resultcode == MINUS_EXPR)
+    intop = fold_build1 (NEGATE_EXPR, TREE_TYPE (intop), intop);
+
+  intop = convert (sizetype, intop);
 
   /* Create the sum or difference.  */
-  ret = fold_build2 (resultcode, result_type, ptrop, intop);
+  ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop);
 
   fold_undefer_and_ignore_overflow_warnings ();
 
index a64e30984eec631f73c703b4a68645deb50ea965..17f878c5ac950125fac41b63774010a5c01a7f15 100644 (file)
@@ -1313,7 +1313,7 @@ check_format_arg (void *ctx, tree format_tree,
     }
 
   offset = 0;
-  if (TREE_CODE (format_tree) == PLUS_EXPR)
+  if (TREE_CODE (format_tree) == POINTER_PLUS_EXPR)
     {
       tree arg0, arg1;
 
@@ -1323,11 +1323,6 @@ check_format_arg (void *ctx, tree format_tree,
       STRIP_NOPS (arg1);
       if (TREE_CODE (arg1) == INTEGER_CST)
        format_tree = arg0;
-      else if (TREE_CODE (arg0) == INTEGER_CST)
-       {
-         format_tree = arg1;
-         arg1 = arg0;
-       }
       else
        {
          res->number_non_literal++;
index aff4a63823450fa8006f6f37033fb7e64a815e90..9811d873d3810781ec576336c7f1146227fdf9d3 100644 (file)
@@ -2959,11 +2959,13 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
              }
 
            inc = c_size_in_bytes (TREE_TYPE (result_type));
+           inc = fold_convert (sizetype, inc);
          }
        else
-         inc = integer_one_node;
-
-       inc = convert (argtype, inc);
+         {
+           inc = integer_one_node;
+           inc = convert (argtype, inc);
+         }
 
        /* Complain about anything else that is not a true lvalue.  */
        if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
@@ -3051,10 +3053,10 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
       if (val && TREE_CODE (val) == INDIRECT_REF
           && TREE_CONSTANT (TREE_OPERAND (val, 0)))
        {
-         tree op0 = fold_convert (argtype, fold_offsetof (arg, val)), op1;
+         tree op0 = fold_convert (sizetype, fold_offsetof (arg, val)), op1;
 
          op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
-         return fold_build2 (PLUS_EXPR, argtype, op0, op1);
+         return fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
        }
 
       val = build1 (ADDR_EXPR, argtype, arg);
index 5c2489aa52008f508871d3cf9b43042b2314b535..4b3e53e990890fd2c9250c38b6e21365c4231824 100644 (file)
@@ -2205,7 +2205,8 @@ frv_expand_builtin_va_start (tree valist, rtx nextarg)
     }
 
   t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
-             make_tree (ptr_type_node, nextarg));
+             fold_convert (TREE_TYPE (valist),
+                           make_tree (sizetype, nextarg)));
   TREE_SIDE_EFFECTS (t) = 1;
 
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
index 83e1262260fddee19eabe7435a539950f0738b42..f9e67aa4af336f27343b1d092a3cc0bea82a83f9 100644 (file)
@@ -4830,8 +4830,8 @@ ix86_va_start (tree valist, rtx nextarg)
   type = TREE_TYPE (ovf);
   t = make_tree (type, virtual_incoming_args_rtx);
   if (words != 0)
-    t = build2 (PLUS_EXPR, type, t,
-               build_int_cst (type, words * UNITS_PER_WORD));
+    t = build2 (POINTER_PLUS_EXPR, type, t,
+               size_int (words * UNITS_PER_WORD));
   t = build2 (GIMPLE_MODIFY_STMT, type, ovf, t);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -4977,16 +4977,16 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
       if (needed_intregs)
        {
          /* int_addr = gpr + sav; */
-         t = fold_convert (ptr_type_node, fold_convert (size_type_node, gpr));
-         t = build2 (PLUS_EXPR, ptr_type_node, sav, t);
+         t = fold_convert (sizetype, gpr);
+         t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, t);
          t = build2 (GIMPLE_MODIFY_STMT, void_type_node, int_addr, t);
          gimplify_and_add (t, pre_p);
        }
       if (needed_sseregs)
        {
          /* sse_addr = fpr + sav; */
-         t = fold_convert (ptr_type_node, fold_convert (size_type_node, fpr));
-         t = build2 (PLUS_EXPR, ptr_type_node, sav, t);
+         t = fold_convert (sizetype, fpr);
+         t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, t);
          t = build2 (GIMPLE_MODIFY_STMT, void_type_node, sse_addr, t);
          gimplify_and_add (t, pre_p);
        }
@@ -5022,12 +5022,12 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
                  src_offset = REGNO (reg) * 8;
                }
              src_addr = fold_convert (addr_type, src_addr);
-             src_addr = fold_build2 (PLUS_EXPR, addr_type, src_addr,
+             src_addr = fold_build2 (POINTER_PLUS_EXPR, addr_type, src_addr,
                                      build_int_cst (addr_type, src_offset));
              src = build_va_arg_indirect_ref (src_addr);
 
              dest_addr = fold_convert (addr_type, addr);
-             dest_addr = fold_build2 (PLUS_EXPR, addr_type, dest_addr,
+             dest_addr = fold_build2 (POINTER_PLUS_EXPR, addr_type, dest_addr,
                                       build_int_cst (addr_type, INTVAL (XEXP (slot, 1))));
              dest = build_va_arg_indirect_ref (dest_addr);
 
@@ -5064,21 +5064,23 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64
       || integer_zerop (TYPE_SIZE (type)))
     t = ovf;
 else
+ else
     {
       HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8;
-      t = build2 (PLUS_EXPR, TREE_TYPE (ovf), ovf,
-                 build_int_cst (TREE_TYPE (ovf), align - 1));
+      t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), ovf,
+                 size_int (align - 1));
+      t = fold_convert (sizetype, t);
       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
-                 build_int_cst (TREE_TYPE (t), -align));
+                 size_int (-align));
+      t = fold_convert (TREE_TYPE (ovf), t);
     }
   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
 
   t2 = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
   gimplify_and_add (t2, pre_p);
 
-  t = build2 (PLUS_EXPR, TREE_TYPE (t), t,
-             build_int_cst (TREE_TYPE (t), rsize * UNITS_PER_WORD));
+  t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
+             size_int (rsize * UNITS_PER_WORD));
   t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
   gimplify_and_add (t, pre_p);
 
index 24af522fac3570e22c0e6c458f6bac2f8918b700..071baa29c843305061260670bc113d180727f290 100644 (file)
@@ -4326,10 +4326,12 @@ ia64_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   if ((TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == INTEGER_TYPE)
       ? int_size_in_bytes (type) > 8 : TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
     {
-      tree t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
-                      build_int_cst (NULL_TREE, 2 * UNITS_PER_WORD - 1));
+      tree t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist,
+                      size_int (2 * UNITS_PER_WORD - 1));
+      t = fold_convert (sizetype, t);
       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
-                 build_int_cst (NULL_TREE, -2 * UNITS_PER_WORD));
+                 size_int (-2 * UNITS_PER_WORD));
+      t = fold_convert (TREE_TYPE (valist), t);
       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist, t);
       gimplify_and_add (t, pre_p);
     }
index d84eb9b5595194e9373c89639382425a62033973..a132f0ff4c9e7cb974d6e22fd093cf99fb93b17c 100644 (file)
@@ -4366,9 +4366,8 @@ mips_va_start (tree valist, rtx nextarg)
         words used by named arguments.  */
       t = make_tree (TREE_TYPE (ovfl), virtual_incoming_args_rtx);
       if (cum->stack_words > 0)
-       t = build2 (PLUS_EXPR, TREE_TYPE (ovfl), t,
-                   build_int_cst (NULL_TREE,
-                                  cum->stack_words * UNITS_PER_WORD));
+       t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovfl), t,
+                   size_int (cum->stack_words * UNITS_PER_WORD));
       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovfl), ovfl, t);
       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
@@ -4384,8 +4383,8 @@ mips_va_start (tree valist, rtx nextarg)
       fpr_offset = gpr_save_area_size + UNITS_PER_FPVALUE - 1;
       fpr_offset &= ~(UNITS_PER_FPVALUE - 1);
       if (fpr_offset)
-       t = build2 (PLUS_EXPR, TREE_TYPE (ftop), t,
-                   build_int_cst (NULL_TREE, -fpr_offset));
+       t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ftop), t,
+                   size_int (-fpr_offset));
       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ftop), ftop, t);
       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
@@ -4535,28 +4534,27 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
       t = fold_convert (TREE_TYPE (off), build_int_cst (NULL_TREE, rsize));
       t = build2 (POSTDECREMENT_EXPR, TREE_TYPE (off), off, t);
       t = fold_convert (sizetype, t);
-      t = fold_convert (TREE_TYPE (top), t);
+      t = fold_build1 (NEGATE_EXPR, sizetype, t);
 
       /* [4] Emit code for: addr_rtx = top - off.  On big endian machines,
         the argument has RSIZE - SIZE bytes of leading padding.  */
-      t = build2 (MINUS_EXPR, TREE_TYPE (top), top, t);
+      t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (top), top, t);
       if (BYTES_BIG_ENDIAN && rsize > size)
        {
-         u = fold_convert (TREE_TYPE (t), build_int_cst (NULL_TREE,
-                                                         rsize - size));
-         t = build2 (PLUS_EXPR, TREE_TYPE (t), t, u);
+         u = size_int (rsize - size);
+         t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, u);
        }
       COND_EXPR_THEN (addr) = t;
 
       if (osize > UNITS_PER_WORD)
        {
          /* [9] Emit: ovfl += ((intptr_t) ovfl + osize - 1) & -osize.  */
-         u = fold_convert (TREE_TYPE (ovfl),
-                           build_int_cst (NULL_TREE, osize - 1));
-         t = build2 (PLUS_EXPR, TREE_TYPE (ovfl), ovfl, u);
-         u = fold_convert (TREE_TYPE (ovfl),
-                           build_int_cst (NULL_TREE, -osize));
-         t = build2 (BIT_AND_EXPR, TREE_TYPE (ovfl), t, u);
+         u = size_int (osize - 1);
+         t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovfl), ovfl, u);
+         t = fold_convert (sizetype, t);
+         u = size_int (-osize);
+         t = build2 (BIT_AND_EXPR, sizetype, t, u);
+         t = fold_convert (TREE_TYPE (ovfl), t);
          align = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovfl), ovfl, t);
        }
       else
@@ -4570,9 +4568,8 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
       t = build2 (POSTINCREMENT_EXPR, TREE_TYPE (ovfl), ovfl, u);
       if (BYTES_BIG_ENDIAN && osize > size)
        {
-         u = fold_convert (TREE_TYPE (t),
-                           build_int_cst (NULL_TREE, osize - size));
-         t = build2 (PLUS_EXPR, TREE_TYPE (t), t, u);
+         u = size_int (osize - size);
+         t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, u);
        }
 
       /* String [9] and [10,11] together.  */
index 01eb9c325ee9d71dc302a67c31abb605574f37e4..f22f26310b73995a049526a0792a4f006f6d62f7 100644 (file)
@@ -2046,6 +2046,7 @@ reloc_needed (tree exp)
     case ADDR_EXPR:
       return 1;
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
       reloc = reloc_needed (TREE_OPERAND (exp, 0));
@@ -5922,21 +5923,24 @@ hppa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
 
       /* Args grow down.  Not handled by generic routines.  */
 
-      u = fold_convert (valist_type, size_in_bytes (type));
-      t = build2 (MINUS_EXPR, valist_type, valist, u);
+      u = fold_convert (sizetype, size_in_bytes (type));
+      u = fold_build1 (NEGATE_EXPR, sizetype, u);
+      t = build2 (POINTER_PLUS_EXPR, valist_type, valist, u);
 
       /* Copied from va-pa.h, but we probably don't need to align to
         word size, since we generate and preserve that invariant.  */
-      u = build_int_cst (valist_type, (size > 4 ? -8 : -4));
-      t = build2 (BIT_AND_EXPR, valist_type, t, u);
+      u = size_int (size > 4 ? -8 : -4);
+      t = fold_convert (sizetype, t);
+      t = build2 (BIT_AND_EXPR, sizetype, t, u);
+      t = fold_convert (valist_type, t);
 
       t = build2 (MODIFY_EXPR, valist_type, valist, t);
 
       ofs = (8 - size) % 4;
       if (ofs != 0)
        {
-         u = fold_convert (valist_type, size_int (ofs));
-         t = build2 (PLUS_EXPR, valist_type, t, u);
+         u = size_int (ofs);
+         t = build2 (POINTER_PLUS_EXPR, valist_type, t, u);
        }
 
       t = fold_convert (ptr, t);
index 910dae7398f5752ce30c6c06b595cc505433f1c8..035d655e971601ab80a01a7b3607d5079712b3d4 100644 (file)
@@ -6210,8 +6210,8 @@ rs6000_va_start (tree valist, rtx nextarg)
   /* Find the overflow area.  */
   t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
   if (words != 0)
-    t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
-               build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
+    t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
+               size_int (words * UNITS_PER_WORD));
   t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -6227,8 +6227,8 @@ rs6000_va_start (tree valist, rtx nextarg)
   /* Find the register save area.  */
   t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
   if (cfun->machine->varargs_save_offset)
-    t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
-               build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
+    t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
+               size_int (cfun->machine->varargs_save_offset));
   t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -6367,12 +6367,12 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
 
       t = sav;
       if (sav_ofs)
-       t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
+       t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
 
       u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
-      u = build1 (CONVERT_EXPR, integer_type_node, u);
-      u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
-      t = build2 (PLUS_EXPR, ptr_type_node, t, u);
+      u = fold_convert (sizetype, u);
+      u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
+      t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
 
       t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
       gimplify_and_add (t, pre_p);
@@ -6398,16 +6398,18 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   t = ovf;
   if (align != 1)
     {
-      t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
+      t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
+      t = fold_convert (sizetype, t);
       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
-                 build_int_cst (NULL_TREE, -align));
+                 size_int (-align));
+      t = fold_convert (TREE_TYPE (ovf), t);
     }
   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
 
   u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
   gimplify_and_add (u, pre_p);
 
-  t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
+  t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
   t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
   gimplify_and_add (t, pre_p);
 
index a6524fc58b7efbe34ba87ddb5159be6f55d52424..b13415cb679e2c9e099b7fbc44ab483c5bcb1bff 100644 (file)
@@ -8002,7 +8002,7 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
        fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
                 (int)n_gpr, (int)n_fpr, off);
 
-      t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
+      t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t, size_int (off));
 
       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
       TREE_SIDE_EFFECTS (t) = 1;
@@ -8014,8 +8014,8 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
       || (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
     {
       t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
-      t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
-                 build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
+      t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
+                 size_int (-RETURN_REGNUM * UNITS_PER_WORD));
   
       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
       TREE_SIDE_EFFECTS (t) = 1;
@@ -8144,11 +8144,11 @@ s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
   t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
   gimplify_and_add (t, pre_p);
 
-  t = build2 (PLUS_EXPR, ptr_type_node, sav, 
-             fold_convert (ptr_type_node, size_int (sav_ofs)));
+  t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, 
+             size_int (sav_ofs));
   u = build2 (MULT_EXPR, TREE_TYPE (reg), reg, 
              fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
-  t = build2 (PLUS_EXPR, ptr_type_node, t, fold_convert (ptr_type_node, u));
+  t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, fold_convert (sizetype, u));
 
   t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
   gimplify_and_add (t, pre_p);
@@ -8164,16 +8164,16 @@ s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
 
   t = ovf;
   if (size < UNITS_PER_WORD)
-    t = build2 (PLUS_EXPR, ptr_type_node, t, 
-               fold_convert (ptr_type_node, size_int (UNITS_PER_WORD - size)));
+    t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, 
+               size_int (UNITS_PER_WORD - size));
 
   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
 
   u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
   gimplify_and_add (u, pre_p);
 
-  t = build2 (PLUS_EXPR, ptr_type_node, t, 
-             fold_convert (ptr_type_node, size_int (size)));
+  t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, 
+             size_int (size));
   t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, ovf, t);
   gimplify_and_add (t, pre_p);
 
index 4ca2d5c1a81f933a812ea622aeafe613ac4155e1..9d327847fe43f672dd61601cf9fa2848ff1e2c8f 100644 (file)
@@ -7049,7 +7049,8 @@ sh_va_start (tree valist, rtx nextarg)
                       valist, f_next_stack, NULL_TREE);
 
   /* Call __builtin_saveregs.  */
-  u = make_tree (ptr_type_node, expand_builtin_saveregs ());
+  u = make_tree (sizetype, expand_builtin_saveregs ());
+  u = fold_convert (ptr_type_node, u);
   t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_fp, u);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -7059,8 +7060,8 @@ sh_va_start (tree valist, rtx nextarg)
     nfp = 8 - nfp;
   else
     nfp = 0;
-  u = fold_build2 (PLUS_EXPR, ptr_type_node, u,
-                  build_int_cst (NULL_TREE, UNITS_PER_WORD * nfp));
+  u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u,
+                  size_int (UNITS_PER_WORD * nfp));
   t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_fp_limit, u);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -7074,8 +7075,8 @@ sh_va_start (tree valist, rtx nextarg)
     nint = 4 - nint;
   else
     nint = 0;
-  u = fold_build2 (PLUS_EXPR, ptr_type_node, u,
-                  build_int_cst (NULL_TREE, UNITS_PER_WORD * nint));
+  u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u,
+                  size_int (UNITS_PER_WORD * nint));
   t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_o_limit, u);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -7208,8 +7209,8 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
          gimplify_and_add (tmp, pre_p);
          tmp = next_fp_limit;
          if (size > 4 && !is_double)
-           tmp = build2 (PLUS_EXPR, TREE_TYPE (tmp), tmp,
-                         fold_convert (TREE_TYPE (tmp), size_int (4 - size)));
+           tmp = build2 (POINTER_PLUS_EXPR, TREE_TYPE (tmp), tmp,
+                         size_int (4 - size));
          tmp = build2 (GE_EXPR, boolean_type_node, next_fp_tmp, tmp);
          cmp = build3 (COND_EXPR, void_type_node, tmp,
                        build1 (GOTO_EXPR, void_type_node, lab_false),
@@ -7220,9 +7221,11 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
          if (TYPE_ALIGN (eff_type) > BITS_PER_WORD
              || (is_double || size == 16))
            {
-             tmp = fold_convert (ptr_type_node, size_int (UNITS_PER_WORD));
-             tmp = build2 (BIT_AND_EXPR, ptr_type_node, next_fp_tmp, tmp);
-             tmp = build2 (PLUS_EXPR, ptr_type_node, next_fp_tmp, tmp);
+             tmp = fold_convert (sizetype, next_fp_tmp);
+             tmp = build2 (BIT_AND_EXPR, sizetype, tmp,
+                           size_int (UNITS_PER_WORD));
+             tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node,
+                           next_fp_tmp, tmp);
              tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node,
                            next_fp_tmp, tmp);
              gimplify_and_add (tmp, pre_p);
@@ -7268,8 +7271,8 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
        }
       else
        {
-         tmp = fold_convert (ptr_type_node, size_int (rsize));
-         tmp = build2 (PLUS_EXPR, ptr_type_node, next_o, tmp);
+         tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, next_o,
+                       size_int (rsize));
          tmp = build2 (GT_EXPR, boolean_type_node, tmp, next_o_limit);
          tmp = build3 (COND_EXPR, void_type_node, tmp,
                        build1 (GOTO_EXPR, void_type_node, lab_false),
index 190c82ec0ce278d47161df1db2e29dd15bdabcd1..85b41cbbcf2e1c769c252091c27d566f394fbe7f 100644 (file)
@@ -5716,18 +5716,20 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   incr = valist;
   if (align)
     {
-      incr = fold_build2 (PLUS_EXPR, ptr_type_node, incr,
-                         ssize_int (align - 1));
-      incr = fold_build2 (BIT_AND_EXPR, ptr_type_node, incr,
-                         ssize_int (-align));
+      incr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, incr,
+                         size_int (align - 1));
+      incr = fold_convert (sizetype, incr);
+      incr = fold_build2 (BIT_AND_EXPR, sizetype, incr,
+                         size_int (-align));
+      incr = fold_convert (ptr_type_node, incr);
     }
 
   gimplify_expr (&incr, pre_p, post_p, is_gimple_val, fb_rvalue);
   addr = incr;
 
   if (BYTES_BIG_ENDIAN && size < rsize)
-    addr = fold_build2 (PLUS_EXPR, ptr_type_node, incr,
-                       ssize_int (rsize - size));
+    addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, incr,
+                       size_int (rsize - size));
 
   if (indirect)
     {
@@ -5755,7 +5757,7 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
   else
     addr = fold_convert (ptrtype, addr);
 
-  incr = fold_build2 (PLUS_EXPR, ptr_type_node, incr, ssize_int (rsize));
+  incr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, incr, size_int (rsize));
   incr = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, valist, incr);
   gimplify_and_add (incr, post_p);
 
index fed243f67df1ab37d795d162025cb3f2ecbb1733..9318e2442559a03e7df89f855a28f1f3f895cebc 100644 (file)
@@ -3115,18 +3115,17 @@ spu_va_start (tree valist, rtx nextarg)
   /* Find the __args area.  */
   t = make_tree (TREE_TYPE (args), nextarg);
   if (current_function_pretend_args_size > 0)
-    t = build2 (PLUS_EXPR, TREE_TYPE (args), t,
-               build_int_cst (integer_type_node, -STACK_POINTER_OFFSET));
+    t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (args), t,
+               size_int (-STACK_POINTER_OFFSET));
   t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (args), args, t);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
 
   /* Find the __skip area.  */
   t = make_tree (TREE_TYPE (skip), virtual_incoming_args_rtx);
-  t = build2 (PLUS_EXPR, TREE_TYPE (skip), t,
-             build_int_cst (integer_type_node,
-                            (current_function_pretend_args_size
-                             - STACK_POINTER_OFFSET)));
+  t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (skip), t,
+             size_int (current_function_pretend_args_size
+                        - STACK_POINTER_OFFSET));
   t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (skip), skip, t);
   TREE_SIDE_EFFECTS (t) = 1;
   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -3182,21 +3181,21 @@ spu_gimplify_va_arg_expr (tree valist, tree type, tree * pre_p,
 
   /* build conditional expression to calculate addr. The expression
      will be gimplified later. */
-  paddedsize = fold_convert (ptr_type_node, size_int (rsize));
-  tmp = build2 (PLUS_EXPR, ptr_type_node, args, paddedsize);
+  paddedsize = size_int (rsize);
+  tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, args, paddedsize);
   tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
                build2 (GT_EXPR, boolean_type_node, tmp, skip),
                build2 (LE_EXPR, boolean_type_node, args, skip));
 
   tmp = build3 (COND_EXPR, ptr_type_node, tmp,
-               build2 (PLUS_EXPR, ptr_type_node, skip,
-                       fold_convert (ptr_type_node, size_int (32))), args);
+               build2 (POINTER_PLUS_EXPR, ptr_type_node, skip,
+                       size_int (32)), args);
 
   tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, addr, tmp);
   gimplify_and_add (tmp, pre_p);
 
   /* update VALIST.__args */
-  tmp = build2 (PLUS_EXPR, ptr_type_node, addr, paddedsize);
+  tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, paddedsize);
   tmp = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (args), args, tmp);
   gimplify_and_add (tmp, pre_p);
 
index 2eeff3ce2728b4589d3f7930d97d98ee15579ff5..5360fce063f43bf399d63595d825968b5f1995f3 100644 (file)
@@ -1,3 +1,41 @@
+2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * typeck.c (build_binary_op): For templates build the
+       expression in pieces to avoid the assert in build2_stat.
+       (get_member_function_from_ptrfunc):
+       Change over to using POINTER_PLUS_EXPR and convert
+       the second operand to sizetype.
+       * typeck2.c (build_m_component_ref):  Likewise.
+       * init.c (expand_virtual_init): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       (build_new_1): Likewise.
+       (build_vec_delete_1): Likewise.
+       (build_vec_delete): Likewise.
+       * class.c (build_base_path): Likewise.
+       (build_base_path): Likewise.
+       (convert_to_base_statically): Likewise.
+       (fixed_type_or_null): Handle POINTER_PLUS_EXPR.
+       (get_vtbl_decl_for_binfo): Handle POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       (dfs_accumulate_vtbl_inits): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       * call.c (build_special_member_call): Likewise.
+       * rtti.c (build_headof): Likewise.
+       Use sizetype instead of ptrdiff_type_node.
+       (tinfo_base_init): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       * except.c (expand_start_catch_block):  Do a
+       NEGATIVE and then a POINTER_PLUS_EXPR instead
+       of a MINUS_EXPR.
+       * cp-gimplify.c (cxx_omp_clause_apply_fn): Convert
+       PLUS_EXPR on pointer types over to use
+       POINTER_PLUS_EXPR and remove the conversion
+       to the pointer types.
+       * method.c (thunk_adjust): Use POINTER_PLUS_EXPR for
+       adding to a pointer type. Use size_int instead of
+       ssize_int. Convert the index to sizetype before
+       adding it to the pointer.
+
 2007-06-15  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (DECL_VAR_MARKED_P): Remove.
        (copy_fn_p): Don't consider constructors taking rvalue references
        to be copy constructors.
        (move_fn_p): New.
-        * call.c (conversion): New "rvaluedness_matches_p" member.
+       * call.c (conversion): New "rvaluedness_matches_p" member.
        (convert_class_to_reference): Require reference type as first
        parameter instead of base type.
        (reference_binding): Add logic to handle rvalue references.
 
 2007-05-28  Andrew Pinski  <Andrew_pinski@playstation.sony.com>
 
-        PR c++/31339
+       PR c++/31339
        * typeck.c (build_unary_op <case PREINCREMENT_EXPR,
        case POSTINCREMENT_EXPR, case PREDECREMENT_EXPR,
        case POSTDECREMENT_EXPR>): Return the error_mark_node
        PR C++/30158
        * semantics.c (finish_stmt_expr_expr): Set TREE_TYPE of the 
        statement expression if we had an error mark node.
-               
+
 2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
            Brooks Moses  <brooks.moses@codesourcery.com>
            Lee Millward  <lee.millward@codesourcery.com>
diff --git a/gcc/cp/ChangeLog.ptr b/gcc/cp/ChangeLog.ptr
new file mode 100644 (file)
index 0000000..7df0cad
--- /dev/null
@@ -0,0 +1,68 @@
+2007-06-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * init.c (build_new_1): Use fold_build1 instead
+       of build1 for NEGATE_EXPR.
+       (build_vec_delete_1): Likewise.
+       * class.c (build_base_path): Likewise.
+       * except.c (expand_start_catch_block): Likewise.
+
+2007-05-28  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * typeck.c (build_binary_op): Add a comment on why creating
+       the tree in pieces while processing templates.
+
+2007-05-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * except.c (expand_start_catch_block):  Do a
+       NEGATIVE and then a POINTER_PLUS_EXPR instead
+       of a MINUS_EXPR.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * cp-gimplify.c (cxx_omp_clause_apply_fn): Convert
+       PLUS_EXPR on pointer types over to use
+       POINTER_PLUS_EXPR and remove the conversion
+       to the pointer types.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * typeck.c (build_unary_op): Remove code that used to
+       handle non lvalue increments/decrements as we now error
+       out all ways.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * typeck.c (get_member_function_from_ptrfunc):
+       Change over to using POINTER_PLUS_EXPR and convert
+       the second operand to sizetype.
+       * typeck2.c (build_m_component_ref): Likewise.
+       * rtti.c (build_headof): Use sizetype instead of
+       ptrdiff_type_node.
+
+2007-05-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * method.c (thunk_adjust): Use POINTER_PLUS_EXPR for
+       adding to a pointer type. Use size_int instead of
+       ssize_int. Convert the index to sizetype before
+       adding it to the pointer.
+
+2006-11-23  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * typeck.c (build_binary_op): For templates build the
+       expression in pieces to avoid the assert in build2_stat.
+       * init.c (expand_virtual_init): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       (build_new_1): Likewise.
+       (build_vec_delete_1): Likewise.
+       (build_vec_delete): Likewise.
+       * class.c (build_base_path): Likewise.
+       (build_base_path): Likewise.
+       (convert_to_base_statically): Likewise.
+       (fixed_type_or_null): Handle POINTER_PLUS_EXPR.
+       (get_vtbl_decl_for_binfo): Handle POINTER_PLUS_EXPR
+       instead of PLUS_EXPR.
+       (dfs_accumulate_vtbl_inits): Create a POINTER_PLUS_EXPR
+       instead of PLUS_EXPR for pointers.
+       * call.c (build_special_member_call): Likewise.
+       * rtti.c (build_headof): Likewise.
+       (tinfo_base_init): Likewise.
index 6e6be645d6e59a4089a969543bb2c0101b032b39..86d5fbccd10c124f7d30dc0207aed418b35d5d75 100644 (file)
@@ -5321,7 +5321,7 @@ build_special_member_call (tree instance, tree name, tree args,
                    current_vtt_parm,
                    vtt);
       gcc_assert (BINFO_SUBVTT_INDEX (binfo));
-      sub_vtt = build2 (PLUS_EXPR, TREE_TYPE (vtt), vtt,
+      sub_vtt = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtt), vtt,
                        BINFO_SUBVTT_INDEX (binfo));
 
       args = tree_cons (NULL_TREE, sub_vtt, args);
index 0314df3adc3af651b6d485be91077846ffb96647..67cf63db1bd025fa20c00e7824d882f6166afd23 100644 (file)
@@ -367,8 +367,8 @@ build_base_path (enum tree_code code,
        v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
                                     TREE_TYPE (TREE_TYPE (expr)));
 
-      v_offset = build2 (PLUS_EXPR, TREE_TYPE (v_offset),
-                        v_offset,  BINFO_VPTR_FIELD (v_binfo));
+      v_offset = build2 (POINTER_PLUS_EXPR, TREE_TYPE (v_offset),
+                        v_offset, fold_convert (sizetype, BINFO_VPTR_FIELD (v_binfo)));
       v_offset = build1 (NOP_EXPR,
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
@@ -406,7 +406,12 @@ build_base_path (enum tree_code code,
   expr = build1 (NOP_EXPR, ptr_target_type, expr);
 
   if (!integer_zerop (offset))
-    expr = build2 (code, ptr_target_type, expr, offset);
+    {
+      offset = fold_convert (sizetype, offset);
+      if (code == MINUS_EXPR)
+       offset = fold_build1 (NEGATE_EXPR, sizetype, offset);
+      expr = build2 (POINTER_PLUS_EXPR, ptr_target_type, expr, offset);
+    }
   else
     null_test = NULL;
 
@@ -539,8 +544,8 @@ convert_to_base_statically (tree expr, tree base)
       gcc_assert (!processing_template_decl);
       expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1);
       if (!integer_zerop (BINFO_OFFSET (base)))
-        expr = fold_build2 (PLUS_EXPR, pointer_type, expr,
-                           fold_convert (pointer_type, BINFO_OFFSET (base)));
+        expr = fold_build2 (POINTER_PLUS_EXPR, pointer_type, expr,
+                           fold_convert (sizetype, BINFO_OFFSET (base)));
       expr = fold_convert (build_pointer_type (BINFO_TYPE (base)), expr);
       expr = build_fold_indirect_ref (expr);
     }
@@ -5276,6 +5281,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
        }
       return RECUR (TREE_OPERAND (instance, 0));
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
       if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
@@ -6340,7 +6346,7 @@ get_vtbl_decl_for_binfo (tree binfo)
   tree decl;
 
   decl = BINFO_VTABLE (binfo);
-  if (decl && TREE_CODE (decl) == PLUS_EXPR)
+  if (decl && TREE_CODE (decl) == POINTER_PLUS_EXPR)
     {
       gcc_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR);
       decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
@@ -7126,7 +7132,7 @@ dfs_accumulate_vtbl_inits (tree binfo,
       index = size_binop (MULT_EXPR,
                          TYPE_SIZE_UNIT (vtable_entry_type),
                          index);
-      vtbl = build2 (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
+      vtbl = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
     }
 
   if (ctor_vtbl_p)
index bd67ad1b819e11d232c25a0ba164d045e4e0eb42..9d9cc4d388a0398c535ce588cc6fa5512ecac266 100644 (file)
@@ -802,8 +802,7 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
        start2 = build_fold_addr_expr (start2);
 
       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
-      end1 = fold_convert (TREE_TYPE (start1), end1);
-      end1 = build2 (PLUS_EXPR, TREE_TYPE (start1), start1, end1);
+      end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
 
       p1 = create_tmp_var (TREE_TYPE (start1), NULL);
       t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, start1);
@@ -830,15 +829,15 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
       t = build_call_a (fn, i, argarray);
       append_to_statement_list (t, &ret);
 
-      t = fold_convert (TREE_TYPE (p1), TYPE_SIZE_UNIT (inner_type));
-      t = build2 (PLUS_EXPR, TREE_TYPE (p1), p1, t);
+      t = TYPE_SIZE_UNIT (inner_type);
+      t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
       t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, t);
       append_to_statement_list (t, &ret);
 
       if (arg2)
        {
-         t = fold_convert (TREE_TYPE (p2), TYPE_SIZE_UNIT (inner_type));
-         t = build2 (PLUS_EXPR, TREE_TYPE (p2), p2, t);
+         t = TYPE_SIZE_UNIT (inner_type);
+         t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
          t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p2, t);
          append_to_statement_list (t, &ret);
        }
index 059754f36cdfff16bb4dcb67ae3ba0d8b8e6d569..887b0f17ef0c680c29d9da1c2739a93b23215fe7 100644 (file)
@@ -426,8 +426,9 @@ expand_start_catch_block (tree decl)
         generic exception header.  */
       exp = build_exc_ptr ();
       exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
-      exp = build2 (MINUS_EXPR, TREE_TYPE (exp), exp,
-                   TYPE_SIZE_UNIT (TREE_TYPE (exp)));
+      exp = build2 (POINTER_PLUS_EXPR, TREE_TYPE (exp), exp,
+                   fold_build1 (NEGATE_EXPR, sizetype,
+                                TYPE_SIZE_UNIT (TREE_TYPE (exp))));
       exp = build_indirect_ref (exp, NULL);
       initialize_handler_parm (decl, exp);
       return type;
index aecbed967954c91808fbda9785bbad9f43c4977f..6ca072ca5d467ae3e1e8fcce544522d6397fc656 100644 (file)
@@ -786,7 +786,7 @@ expand_virtual_init (tree binfo, tree decl)
 
       /* Compute the value to use, when there's a VTT.  */
       vtt_parm = current_vtt_parm;
-      vtbl2 = build2 (PLUS_EXPR,
+      vtbl2 = build2 (POINTER_PLUS_EXPR,
                      TREE_TYPE (vtt_parm),
                      vtt_parm,
                      vtt_index);
@@ -1919,14 +1919,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
       tree cookie_ptr;
 
       /* Adjust so we're pointing to the start of the object.  */
-      data_addr = get_target_expr (build2 (PLUS_EXPR, full_pointer_type,
+      data_addr = get_target_expr (build2 (POINTER_PLUS_EXPR, full_pointer_type,
                                           alloc_node, cookie_size));
 
       /* Store the number of bytes allocated so that we can know how
         many elements to destroy later.  We use the last sizeof
         (size_t) bytes to store the number of elements.  */
-      cookie_ptr = build2 (MINUS_EXPR, build_pointer_type (sizetype),
-                          data_addr, size_in_bytes (sizetype));
+      cookie_ptr = fold_build1 (NEGATE_EXPR, sizetype, size_in_bytes (sizetype));
+      cookie_ptr = build2 (POINTER_PLUS_EXPR, build_pointer_type (sizetype),
+                          data_addr, cookie_ptr);
       cookie = build_indirect_ref (cookie_ptr, NULL);
 
       cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
@@ -2301,6 +2302,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
      executing any other code in the loop.
      This is also the containing expression returned by this function.  */
   tree controller = NULL_TREE;
+  tree tmp;
 
   /* We should only have 1-D arrays here.  */
   gcc_assert (TREE_CODE (type) != ARRAY_TYPE);
@@ -2314,7 +2316,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
 
   tbase = create_temporary_var (ptype);
   tbase_init = build_modify_expr (tbase, NOP_EXPR,
-                                 fold_build2 (PLUS_EXPR, ptype,
+                                 fold_build2 (POINTER_PLUS_EXPR, ptype,
                                               base,
                                               virtual_size));
   DECL_REGISTER (tbase) = 1;
@@ -2325,9 +2327,10 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
   body = build1 (EXIT_EXPR, void_type_node,
                 build2 (EQ_EXPR, boolean_type_node, tbase,
                         fold_convert (ptype, base)));
+  tmp = fold_build1 (NEGATE_EXPR, sizetype, size_exp);
   body = build_compound_expr
     (body, build_modify_expr (tbase, NOP_EXPR,
-                             build2 (MINUS_EXPR, ptype, tbase, size_exp)));
+                             build2 (POINTER_PLUS_EXPR, ptype, tbase, tmp)));
   body = build_compound_expr
     (body, build_delete (ptype, tbase, sfk_complete_destructor,
                         LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1));
@@ -3048,10 +3051,11 @@ build_vec_delete (tree base, tree maxindex,
          base = TARGET_EXPR_SLOT (base_init);
        }
       type = strip_array_types (TREE_TYPE (type));
-      cookie_addr = build2 (MINUS_EXPR,
+      cookie_addr = fold_build1 (NEGATE_EXPR, sizetype, TYPE_SIZE_UNIT (sizetype));
+      cookie_addr = build2 (POINTER_PLUS_EXPR,
                            build_pointer_type (sizetype),
                            base,
-                           TYPE_SIZE_UNIT (sizetype));
+                           cookie_addr);
       maxindex = build_indirect_ref (cookie_addr, NULL);
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
index 03078a3f017dfd805d54ebfe4e52c20135ad6ed1..03f490884516958cb84b1b88c1ca44da7044bbfb 100644 (file)
@@ -220,8 +220,8 @@ thunk_adjust (tree ptr, bool this_adjusting,
 {
   if (this_adjusting)
     /* Adjust the pointer by the constant.  */
-    ptr = fold_build2 (PLUS_EXPR, TREE_TYPE (ptr), ptr,
-                      ssize_int (fixed_offset));
+    ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
+                      size_int (fixed_offset));
 
   /* If there's a virtual offset, look up that value in the vtable and
      adjust the pointer again.  */
@@ -238,17 +238,19 @@ thunk_adjust (tree ptr, bool this_adjusting,
       /* Form the vtable address.  */
       vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
       /* Find the entry with the vcall offset.  */
-      vtable = build2 (PLUS_EXPR, TREE_TYPE (vtable), vtable, virtual_offset);
+      vtable = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtable), vtable,
+                      fold_convert (sizetype, virtual_offset));
       /* Get the offset itself.  */
       vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
       /* Adjust the `this' pointer.  */
-      ptr = fold_build2 (PLUS_EXPR, TREE_TYPE (ptr), ptr, vtable);
+      ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
+                        fold_convert (sizetype, vtable));
     }
 
   if (!this_adjusting)
     /* Adjust the pointer by the constant.  */
-    ptr = fold_build2 (PLUS_EXPR, TREE_TYPE (ptr), ptr,
-                      ssize_int (fixed_offset));
+    ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
+                      size_int (fixed_offset));
 
   return ptr;
 }
index 1891f3b483322d087d7fe66ee79bd68933f599ab..2870b9ff41525e1411375c36d1c75dd09fd1aed6 100644 (file)
@@ -180,8 +180,8 @@ build_headof (tree exp)
 
   type = build_qualified_type (ptr_type_node,
                               cp_type_quals (TREE_TYPE (exp)));
-  return build2 (PLUS_EXPR, type, exp,
-                convert_to_integer (ptrdiff_type_node, offset));
+  return build2 (POINTER_PLUS_EXPR, type, exp,
+                convert_to_integer (sizetype, offset));
 }
 
 /* Get a bad_cast node for the program to throw...
@@ -856,7 +856,7 @@ tinfo_base_init (tinfo_s *ti, tree target)
 
       /* We need to point into the middle of the vtable.  */
       vtable_ptr = build2
-       (PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
+       (POINTER_PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
         size_binop (MULT_EXPR,
                     size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),
                     TYPE_SIZE_UNIT (vtable_entry_type)));
index f17aa807de4fc9e5fc6914c471242bf6552b2d05..7985d853ed19cf9a7192e51ef1ff56422308835d 100644 (file)
@@ -2627,8 +2627,8 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
            return error_mark_node;
        }
       /* ...and then the delta in the PMF.  */
-      instance_ptr = build2 (PLUS_EXPR, TREE_TYPE (instance_ptr),
-                            instance_ptr, delta);
+      instance_ptr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (instance_ptr),
+                            instance_ptr, fold_convert (sizetype, delta));
 
       /* Hand back the adjusted 'this' argument to our caller.  */
       *instance_ptrptr = instance_ptr;
@@ -2639,7 +2639,8 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
       vtbl = build_indirect_ref (vtbl, NULL);
 
       /* Finally, extract the function pointer from the vtable.  */
-      e2 = fold_build2 (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, idx);
+      e2 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
+                       fold_convert (sizetype, idx));
       e2 = build_indirect_ref (e2, NULL);
       TREE_CONSTANT (e2) = 1;
       TREE_INVARIANT (e2) = 1;
@@ -3578,9 +3579,17 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
   /* If we're in a template, the only thing we need to know is the
      RESULT_TYPE.  */
   if (processing_template_decl)
-    return build2 (resultcode,
-                  build_type ? build_type : result_type,
-                  op0, op1);
+    {
+      /* Since the middle-end checks the type when doing a build2, we
+        need to build the tree in pieces.  This built tree will never
+        get out of the front-end as we replace it when instantiating
+        the template.  */
+      tree tmp = build2 (resultcode,
+                        build_type ? build_type : result_type,
+                        NULL_TREE, op1);
+      TREE_OPERAND (tmp, 0) = op0;
+      return tmp;
+    }
 
   if (arithmetic_types_p)
     {
index 9ded7bbf8644406c379639245f97c9e14a14ba23..66c8b9c4febc42bb4ac7bd76720c22bef7e31507 100644 (file)
@@ -1277,8 +1277,8 @@ build_m_component_ref (tree datum, tree component)
 
       /* Build an expression for "object + offset" where offset is the
         value stored in the pointer-to-data-member.  */
-      datum = build2 (PLUS_EXPR, build_pointer_type (type),
-                     datum, build_nop (ptrdiff_type_node, component));
+      datum = build2 (POINTER_PLUS_EXPR, build_pointer_type (type),
+                     datum, build_nop (sizetype, component));
       return build_indirect_ref (datum, 0);
     }
   else
index c61b871a6792482185b8f032d00ee16aa2a6039b..4134007c24f9b1c063210b97a1b369c0b8024b24 100644 (file)
@@ -1918,6 +1918,7 @@ This macro returns the attributes on the type @var{type}.
 @tindex TRUTH_AND_EXPR
 @tindex TRUTH_OR_EXPR
 @tindex TRUTH_XOR_EXPR
+@tindex POINTER_PLUS_EXPR
 @tindex PLUS_EXPR
 @tindex MINUS_EXPR
 @tindex MULT_EXPR
@@ -2292,6 +2293,12 @@ generate these expressions anyhow, if it can tell that strictness does
 not matter.  The type of the operands and that of the result are
 always of @code{BOOLEAN_TYPE} or @code{INTEGER_TYPE}.
 
+@itemx POINTER_PLUS_EXPR
+This node represents pointer arithmetic.  The first operand is always
+a pointer/reference type.  The second operand is always an unsigned
+integer type compatible with sizetype.  This is the only binary
+arithmetic operand that can operate on pointer types.
+
 @itemx PLUS_EXPR
 @itemx MINUS_EXPR
 @itemx MULT_EXPR
index 22cac4f6d3bd37b1df2c5584300295f5908fcf6b..9bd7235356e87557b6243539dfdec59b29acb53a 100644 (file)
@@ -9442,6 +9442,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
       op = (TYPE_UNSIGNED (TREE_TYPE (loc)) ? DW_OP_shr : DW_OP_shra);
       goto do_binop;
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       if (TREE_CODE (TREE_OPERAND (loc, 1)) == INTEGER_CST
          && host_integerp (TREE_OPERAND (loc, 1), 0))
index 9c91c4e0f2466c3b30729fe8b91f25462ef10d09..3f0caf117d53261d237e358180e11b3662c85aad 100644 (file)
@@ -8036,7 +8036,12 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
 
       return op0;
 
+    case POINTER_PLUS_EXPR: 
+      /* Even though the sizetype mode and the pointer's mode can be different
+         expand is able to handle this correctly and get the correct result out 
+         of the PLUS_EXPR code.  */
     case PLUS_EXPR:
+
       /* Check if this is a case for multiplication and addition.  */
       if (TREE_CODE (type) == INTEGER_TYPE
          && TREE_CODE (TREE_OPERAND (exp, 0)) == MULT_EXPR)
@@ -9255,7 +9260,7 @@ string_constant (tree arg, tree *ptr_offset)
       else
        return 0;
     }
-  else if (TREE_CODE (arg) == PLUS_EXPR)
+  else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR)
     {
       tree arg0 = TREE_OPERAND (arg, 0);
       tree arg1 = TREE_OPERAND (arg, 1);
index 814d033ffc4ffa319d7493718b0d8f0e646758d1..9c6690ccfaaf2ee06a3279c542dde362344933a3 100644 (file)
@@ -4439,6 +4439,20 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
 
   value = const_binop (MINUS_EXPR, high, low, 0);
 
+
+  if (POINTER_TYPE_P (etype))
+    {
+      if (value != 0 && !TREE_OVERFLOW (value))
+       {
+         low = fold_convert (sizetype, low);
+         low = fold_build1 (NEGATE_EXPR, sizetype, low);
+          return build_range_check (type,
+                                   fold_build2 (POINTER_PLUS_EXPR, etype, exp, low),
+                                   1, build_int_cst (etype, 0), value);
+       }
+      return 0;
+    }
+
   if (value != 0 && !TREE_OVERFLOW (value))
     return build_range_check (type,
                              fold_build2 (MINUS_EXPR, etype, exp, low),
@@ -5992,7 +6006,7 @@ constant_boolean_node (int value, tree type)
    offset is set to NULL_TREE.  Base will be canonicalized to
    something you can get the element type from using
    TREE_TYPE (TREE_TYPE (base)).  Offset will be the offset
-   in bytes to the base.  */
+   in bytes to the base in sizetype.  */
 
 static bool
 extract_array_ref (tree expr, tree *base, tree *offset)
@@ -6000,21 +6014,20 @@ extract_array_ref (tree expr, tree *base, tree *offset)
   /* One canonical form is a PLUS_EXPR with the first
      argument being an ADDR_EXPR with a possible NOP_EXPR
      attached.  */
-  if (TREE_CODE (expr) == PLUS_EXPR)
+  if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
     {
       tree op0 = TREE_OPERAND (expr, 0);
       tree inner_base, dummy1;
       /* Strip NOP_EXPRs here because the C frontends and/or
-        folders present us (int *)&x.a + 4B possibly.  */
+        folders present us (int *)&x.a p+ 4 possibly.  */
       STRIP_NOPS (op0);
       if (extract_array_ref (op0, &inner_base, &dummy1))
        {
          *base = inner_base;
-         if (dummy1 == NULL_TREE)
-           *offset = TREE_OPERAND (expr, 1);
-         else
-           *offset = fold_build2 (PLUS_EXPR, TREE_TYPE (expr),
-                                  dummy1, TREE_OPERAND (expr, 1));
+         *offset = fold_convert (sizetype, TREE_OPERAND (expr, 1));
+         if (dummy1 != NULL_TREE)
+           *offset = fold_build2 (PLUS_EXPR, sizetype,
+                                  dummy1, *offset);
          return true;
        }
     }
@@ -6032,6 +6045,7 @@ extract_array_ref (tree expr, tree *base, tree *offset)
          *base = TREE_OPERAND (op0, 0);
          *offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
                                 array_ref_element_size (op0)); 
+         *offset = fold_convert (sizetype, *offset);
        }
       else
        {
@@ -6866,7 +6880,7 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
   return fold_build2 (code, type, arg0_inner, arg1);
 }
 
-/* Tries to replace &a[idx] CODE s * delta with &a[idx CODE delta], if s is
+/* Tries to replace &a[idx] p+ s * delta with &a[idx + delta], if s is
    step of the array.  Reconstructs s and delta in the case of s * delta
    being an integer constant (and thus already folded).
    ADDR is the address. MULT is the multiplicative expression.
@@ -6874,7 +6888,7 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
    NULL_TREE is returned.  */
 
 static tree
-try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
+try_move_mult_to_index (tree addr, tree op1)
 {
   tree s, delta, step;
   tree ref = TREE_OPERAND (addr, 0), pref;
@@ -6882,6 +6896,9 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
   tree itype;
   bool mdim = false;
 
+  /*  Strip the nops that might be added when converting op1 to sizetype. */
+  STRIP_NOPS (op1);
+
   /* Canonicalize op1 into a possibly non-constant delta
      and an INTEGER_CST s.  */
   if (TREE_CODE (op1) == MULT_EXPR)
@@ -6958,7 +6975,7 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
                  || TREE_CODE (TYPE_MAX_VALUE (itype)) != INTEGER_CST)
                continue;
 
-             tmp = fold_binary (code, itype,
+             tmp = fold_binary (PLUS_EXPR, itype,
                                 fold_convert (itype,
                                               TREE_OPERAND (ref, 1)),
                                 fold_convert (itype, delta));
@@ -6991,7 +7008,7 @@ try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
       pos = TREE_OPERAND (pos, 0);
     }
 
-  TREE_OPERAND (pos, 1) = fold_build2 (code, itype,
+  TREE_OPERAND (pos, 1) = fold_build2 (PLUS_EXPR, itype,
                                       fold_convert (itype,
                                                     TREE_OPERAND (pos, 1)),
                                       fold_convert (itype, delta));
@@ -7037,9 +7054,18 @@ fold_to_nonsharp_ineq_using_bound (tree ineq, tree bound)
   if (TREE_TYPE (a1) != typea)
     return NULL_TREE;
 
-  diff = fold_build2 (MINUS_EXPR, typea, a1, a);
-  if (!integer_onep (diff))
-    return NULL_TREE;
+  if (POINTER_TYPE_P (typea))
+    {
+      /* Convert the pointer types into integer before taking the difference.  */
+      tree ta = fold_convert (ssizetype, a);
+      tree ta1 = fold_convert (ssizetype, a1);
+      diff = fold_binary (MINUS_EXPR, ssizetype, ta1, ta);
+    }
+  else
+   diff = fold_binary (MINUS_EXPR, typea, a1, a);
+
+  if (!diff || !integer_onep (diff))
+   return NULL_TREE;
 
   return fold_build2 (GE_EXPR, type, a, y);
 }
@@ -7830,11 +7856,11 @@ fold_unary (enum tree_code code, tree type, tree op0)
            }
        }
 
-      /* Convert (T1)(X op Y) into ((T1)X op (T1)Y), for pointer type,
+      /* Convert (T1)(X p+ Y) into ((T1)X p+ Y), for pointer type,
          when one of the new casts will fold away. Conservatively we assume
-        that this happens when X or Y is NOP_EXPR or Y is INTEGER_CST.  */
-      if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (arg0))
-         && BINARY_CLASS_P (arg0)
+        that this happens when X or Y is NOP_EXPR or Y is INTEGER_CST. */
+      if (POINTER_TYPE_P (type)
+         && TREE_CODE (arg0) == POINTER_PLUS_EXPR
          && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
              || TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
              || TREE_CODE (TREE_OPERAND (arg0, 1)) == NOP_EXPR))
@@ -7843,7 +7869,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
          tree arg01 = TREE_OPERAND (arg0, 1);
 
          return fold_build2 (TREE_CODE (arg0), type, fold_convert (type, arg00),
-                             fold_convert (type, arg01));
+                             fold_convert (sizetype, arg01));
        }
 
       /* Convert (T1)(~(T2)X) into ~(T1)X if T1 and T2 are integral types
@@ -9066,7 +9092,68 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
 
   switch (code)
     {
+    case POINTER_PLUS_EXPR:
+      /* 0 +p index -> (type)index */
+      if (integer_zerop (arg0))
+       return non_lvalue (fold_convert (type, arg1));
+
+      /* PTR +p 0 -> PTR */
+      if (integer_zerop (arg1))
+       return non_lvalue (fold_convert (type, arg0));
+
+      /* INT +p INT -> (PTR)(INT + INT).  Stripping types allows for this. */
+      if (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+          && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+        return fold_convert (type, fold_build2 (PLUS_EXPR, sizetype,
+                                               fold_convert (sizetype, arg1),
+                                               fold_convert (sizetype, arg0)));
+
+      /* index +p PTR -> PTR +p index */
+      if (POINTER_TYPE_P (TREE_TYPE (arg1))
+         && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+        return fold_build2 (POINTER_PLUS_EXPR, type,
+                           fold_convert (type, arg1), fold_convert (sizetype, arg0));
+
+      /* (PTR +p B) +p A -> PTR +p (B + A) */
+      if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
+       {
+         tree inner;
+         tree arg01 = fold_convert (sizetype, TREE_OPERAND (arg0, 1));
+         tree arg00 = TREE_OPERAND (arg0, 0);
+         inner = fold_build2 (PLUS_EXPR, sizetype, arg01, fold_convert (sizetype, arg1));
+         return fold_build2 (POINTER_PLUS_EXPR, type, arg00, inner);
+       }
+
+      /* PTR_CST +p CST -> CST1 */
+      if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
+       return fold_build2 (PLUS_EXPR, type, arg0, fold_convert (type, arg1));
+
+     /* Try replacing &a[i1] +p c * i2 with &a[i1 + i2], if c is step
+       of the array.  Loop optimizer sometimes produce this type of
+       expressions.  */
+      if (TREE_CODE (arg0) == ADDR_EXPR)
+       {
+         tem = try_move_mult_to_index (arg0, fold_convert (sizetype, arg1));
+         if (tem)
+           return fold_convert (type, tem);
+       }
+
+      return NULL_TREE;
     case PLUS_EXPR:
+      /* PTR + INT -> (INT)(PTR p+ INT) */
+      if (POINTER_TYPE_P (TREE_TYPE (arg0))
+         && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
+       return fold_convert (type, fold_build2 (POINTER_PLUS_EXPR,
+                                               TREE_TYPE (arg0),
+                                               arg0,
+                                               fold_convert (sizetype, arg1)));
+      /* INT + PTR -> (INT)(PTR p+ INT) */
+      if (POINTER_TYPE_P (TREE_TYPE (arg1))
+         && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+       return fold_convert (type, fold_build2 (POINTER_PLUS_EXPR,
+                                               TREE_TYPE (arg1),
+                                               arg1,
+                                               fold_convert (sizetype, arg0)));
       /* A + (-B) -> A - B */
       if (TREE_CODE (arg1) == NEGATE_EXPR)
        return fold_build2 (MINUS_EXPR, type,
@@ -9173,22 +9260,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
                                                 fold_convert (type,
                                                               parg1)));
            }
-
-         /* Try replacing &a[i1] + c * i2 with &a[i1 + i2], if c is step
-            of the array.  Loop optimizer sometimes produce this type of
-            expressions.  */
-         if (TREE_CODE (arg0) == ADDR_EXPR)
-           {
-             tem = try_move_mult_to_index (PLUS_EXPR, arg0, arg1);
-             if (tem)
-               return fold_convert (type, tem);
-           }
-         else if (TREE_CODE (arg1) == ADDR_EXPR)
-           {
-             tem = try_move_mult_to_index (PLUS_EXPR, arg1, arg0);
-             if (tem)
-               return fold_convert (type, tem);
-           }
        }
       else
        {
@@ -9465,6 +9536,31 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
       return NULL_TREE;
 
     case MINUS_EXPR:
+      /* Pointer simplifications for subtraction, simple reassociations. */
+      if (POINTER_TYPE_P (TREE_TYPE (arg1)) && POINTER_TYPE_P (TREE_TYPE (arg0)))
+       {
+         /* (PTR0 p+ A) - (PTR1 p+ B) -> (PTR0 - PTR1) + (A - B) */
+         if (TREE_CODE (arg0) == POINTER_PLUS_EXPR
+             && TREE_CODE (arg1) == POINTER_PLUS_EXPR)
+           {
+             tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
+             tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
+             tree arg10 = fold_convert (type, TREE_OPERAND (arg1, 0));
+             tree arg11 = fold_convert (type, TREE_OPERAND (arg1, 1));
+             return fold_build2 (PLUS_EXPR, type,
+                                 fold_build2 (MINUS_EXPR, type, arg00, arg10),
+                                 fold_build2 (MINUS_EXPR, type, arg01, arg11));
+           }
+         /* (PTR0 p+ A) - PTR1 -> (PTR0 - PTR1) + A, assuming PTR0 - PTR1 simplifies. */
+         else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
+           {
+             tree arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
+             tree arg01 = fold_convert (type, TREE_OPERAND (arg0, 1));
+             tree tmp = fold_binary (MINUS_EXPR, type, arg00, fold_convert (type, arg1));
+             if (tmp)
+               return fold_build2 (PLUS_EXPR, type, tmp, arg01);
+           }
+       }
       /* A - (-B) -> A + B */
       if (TREE_CODE (arg1) == NEGATE_EXPR)
        return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0));
@@ -9634,16 +9730,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
            }
        }
 
-      /* Try replacing &a[i1] - c * i2 with &a[i1 - i2], if c is step
-        of the array.  Loop optimizer sometimes produce this type of
-        expressions.  */
-      if (TREE_CODE (arg0) == ADDR_EXPR)
-       {
-         tem = try_move_mult_to_index (MINUS_EXPR, arg0, arg1);
-         if (tem)
-           return fold_convert (type, tem);
-       }
-
       if (flag_unsafe_math_optimizations
          && (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
          && (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
@@ -13231,6 +13317,7 @@ tree_expr_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
     case REAL_CST:
       return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       if (FLOAT_TYPE_P (TREE_TYPE (t)))
        return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
@@ -13586,6 +13673,7 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
     case INTEGER_CST:
       return !integer_zerop (t);
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       if (TYPE_OVERFLOW_UNDEFINED (type))
        {
@@ -14178,7 +14266,7 @@ fold_indirect_ref_1 (tree type, tree op0)
     }
 
   /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
-  if (TREE_CODE (sub) == PLUS_EXPR
+  if (TREE_CODE (sub) == POINTER_PLUS_EXPR
       && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
     {
       tree op00 = TREE_OPERAND (sub, 0);
index c2c8dd4a919e7921b2506cc074df235d60dcc6f4..932e004029b2930f2483df670f4b5cac18bc8b37 100644 (file)
@@ -1,3 +1,11 @@
+2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * trans-intrinsic.c (gfc_conv_intrinsic_repeat): Use
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointer addition.
+       * trans-expr.c (gfc_trans_string_copy): Create
+       POINTER_PLUS_EXPR instead of a PLUS_EXPR
+       for pointer types.
+
 2007-06-14  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/32302
diff --git a/gcc/fortran/ChangeLog.ptr b/gcc/fortran/ChangeLog.ptr
new file mode 100644 (file)
index 0000000..56bca5b
--- /dev/null
@@ -0,0 +1,11 @@
+2007-05-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * trans-intrinsic.c (gfc_conv_intrinsic_repeat): Use
+       POINTER_PLUS_EXPR instead of PLUS_EXPR for pointer addition.
+
+2007-05-07  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * trans-expr.c (gfc_trans_string_copy): Create
+       POINTER_PLUS_EXPR instead of a PLUS_EXPR
+       for pointer types.
+
index 407098e8e4adbb0c98f2193542a0ea58616fcec6..a46693587b341ae48156550a12a931db03692f27 100644 (file)
@@ -2571,8 +2571,8 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
   tmp3 = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE],
                          3, dest, src, slen);
 
-  tmp4 = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
-                     fold_convert (pchar_type_node, slen));
+  tmp4 = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, dest,
+                     fold_convert (sizetype, slen));
   tmp4 = build_call_expr (built_in_decls[BUILT_IN_MEMSET], 3,
                          tmp4, 
                          build_int_cst (gfc_get_int_type (gfc_c_int_kind),
index 35a0b57f5cc9085341d4c45835e8599e6775320b..d1c371092fb33cf178e97c5099a5257799ac6169 100644 (file)
@@ -3530,8 +3530,8 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
   /* Call memmove (dest + (i*slen), src, slen).  */
   tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node, slen,
                     fold_convert (gfc_charlen_type_node, count));
-  tmp = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
-                    fold_convert (pchar_type_node, tmp));
+  tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, dest,
+                    fold_convert (sizetype, tmp));
   tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3,
                         tmp, src, slen);
   gfc_add_expr_to_block (&body, tmp);
index 268bef184cfe548406fdefc4a77ad7a9904b5528..774af9adbf81b8b6920d046212137d50b57f1824 100644 (file)
@@ -1960,6 +1960,15 @@ gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
        return ret;
     }
 
+  /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
+  if (POINTER_TYPE_P (TREE_TYPE (lhs)))
+    {
+      rhs = fold_convert (sizetype, rhs);
+      if (arith_code == MINUS_EXPR)
+       rhs = fold_build1 (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
+      arith_code = POINTER_PLUS_EXPR;
+    }
+
   t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
   t1 = build_gimple_modify_stmt (lvalue, t1);
 
@@ -5125,6 +5134,7 @@ gimplify_omp_atomic_fetch_op (tree *expr_p, tree addr, tree rhs, int index)
   /* Check for one of the supported fetch-op operations.  */
   switch (TREE_CODE (rhs))
     {
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       base = BUILT_IN_FETCH_AND_ADD_N;
       optab = sync_add_optab;
@@ -5875,12 +5885,11 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          ret = GS_ALL_DONE;
          break;
 
-       case PLUS_EXPR:
+       case POINTER_PLUS_EXPR:
           /* Convert ((type *)A)+offset into &A->field_of_type_and_offset.
             The second is gimple immediate saving a need for extra statement.
           */
-         if (POINTER_TYPE_P (TREE_TYPE (*expr_p))
-             && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
+         if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
              && (tmp = maybe_fold_offset_to_reference
                         (TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1),
                          TREE_TYPE (TREE_TYPE (*expr_p)))))
@@ -5890,8 +5899,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
               break;
             }
          /* Convert (void *)&a + 4 into (void *)&a[1].  */
-         if (POINTER_TYPE_P (TREE_TYPE (*expr_p))
-             && TREE_CODE (TREE_OPERAND (*expr_p, 0)) == NOP_EXPR
+         if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == NOP_EXPR
              && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
              && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p,
                                                                        0),0)))
index ec3807dd123c62f0c172608a4756fc6c876ba630..493fe1ed839e43182a0f48fa137af6c03a48ca4e 100644 (file)
@@ -1,3 +1,17 @@
+2007-06-15 Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * class.c (make_class_data): Build the index in sizetype.
+       Use POINTER_PLUS_EXPR instead of PLUS_EXPR when
+       adding to a pointer type.
+       (build_symbol_entry): Likewise.
+       * expr.c (build_java_arrayaccess): Likewise.
+       (build_field_ref): Likewise.
+       (build_known_method_ref): Likewise.
+       (build_invokevirtual): Likewise.
+       * except.c (build_exception_object_ref): Do a
+       NEGATIVE and then a POINTER_PLUS_EXPR instead
+       of a MINUS_EXPR.
+
 2007-06-11  Rafael Avila de Espindola  <espindola@google.com>
 
        * typeck.c (java_signed_type): Remove.
diff --git a/gcc/java/ChangeLog.ptr b/gcc/java/ChangeLog.ptr
new file mode 100644 (file)
index 0000000..eb2c9a9
--- /dev/null
@@ -0,0 +1,19 @@
+2007-06-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * except.c (build_exception_object_ref):
+       Use fold_build1 instead of build1 for NEGATE_EXPR.
+
+2007-05-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * class.c (make_class_data): Build the index in sizetype.
+       Use POINTER_PLUS_EXPR instead of PLUS_EXPR when
+       adding to a pointer type.
+       (build_symbol_entry): Likewise.
+       * expr.c (build_java_arrayaccess): Likewise.
+       (build_field_ref): Likewise.
+       (build_known_method_ref): Likewise.
+       (build_invokevirtual): Likewise.
+       * except.c (build_exception_object_ref): Do a
+       NEGATIVE and then a POINTER_PLUS_EXPR instead
+       of a MINUS_EXPR.
+
index d7074610c7de9fe77805bc1479556158cb28bd45..3d4372646ed3e4bf796da144b806cef9ea8f4f87 100644 (file)
@@ -1669,8 +1669,7 @@ make_class_data (tree type)
   tree id_class = get_identifier("java.lang.Class");
   /** Offset from start of virtual function table declaration
       to where objects actually point at, following new g++ ABI. */
-  tree dtable_start_offset = build_int_cst (NULL_TREE,
-                                           2 * POINTER_SIZE / BITS_PER_UNIT);
+  tree dtable_start_offset = size_int (2 * POINTER_SIZE / BITS_PER_UNIT);
   VEC(int, heap) *field_indexes;
   tree first_real_field;
 
@@ -1957,7 +1956,7 @@ make_class_data (tree type)
   PUSH_FIELD_VALUE (temp, "vtable",
                    (flag_indirect_classes 
                     ? null_pointer_node
-                    : build2 (PLUS_EXPR, dtable_ptr_type,
+                    : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
                               build1 (ADDR_EXPR, dtable_ptr_type,
                                       class_dtable_decl),
                               dtable_start_offset)));
@@ -2005,7 +2004,7 @@ make_class_data (tree type)
   else
     PUSH_FIELD_VALUE (cons, "vtable",
                      dtable_decl == NULL_TREE ? null_pointer_node
-                     : build2 (PLUS_EXPR, dtable_ptr_type,
+                     : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
                                build1 (ADDR_EXPR, dtable_ptr_type,
                                        dtable_decl),
                                dtable_start_offset));
@@ -2807,7 +2806,8 @@ build_symbol_entry (tree decl, tree special)
      system that this is a "special" symbol, i.e. one that should
      bypass access controls.  */
   if (special != NULL_TREE)
-    signature = build2 (PLUS_EXPR, TREE_TYPE (signature), signature, special);
+    signature = build2 (POINTER_PLUS_EXPR, TREE_TYPE (signature), signature,
+                       fold_convert (sizetype, special));
       
   START_RECORD_CONSTRUCTOR (sym, symbol_type);
   PUSH_FIELD_VALUE (sym, "clname", clname);
index 788c260ae2845c3c7f872e0ff9743676e0eab6da..01c8a58d384e758a63a566aa7427ab2ecda2cb34 100644 (file)
@@ -467,8 +467,9 @@ build_exception_object_ref (tree type)
   /* Java only passes object via pointer and doesn't require adjusting.
      The java object is immediately before the generic exception header.  */
   obj = build0 (EXC_PTR_EXPR, build_pointer_type (type));
-  obj = build2 (MINUS_EXPR, TREE_TYPE (obj), obj,
-               TYPE_SIZE_UNIT (TREE_TYPE (obj)));
+  obj = build2 (POINTER_PLUS_EXPR, TREE_TYPE (obj), obj,
+               fold_build1 (NEGATE_EXPR, sizetype,
+                            TYPE_SIZE_UNIT (TREE_TYPE (obj))));
   obj = build1 (INDIRECT_REF, type, obj);
 
   return obj;
index c915a91589f1cd77a5abb9719208b22fea326d36..d446e490abb8e07ad91364b47bdd23fa4cc349ea 100644 (file)
@@ -929,13 +929,12 @@ build_java_arrayaccess (tree array, tree type, tree index)
 
   /* Multiply the index by the size of an element to obtain a byte
      offset.  Convert the result to a pointer to the element type.  */
-  index = fold_convert (TREE_TYPE (node),
-                       build2 (MULT_EXPR, sizetype, 
-                               fold_convert (sizetype, index), 
-                               size_exp));
+  index = build2 (MULT_EXPR, sizetype, 
+                 fold_convert (sizetype, index), 
+                 size_exp);
 
   /* Sum the byte offset and the address of the data field.  */
-  node = fold_build2 (PLUS_EXPR, TREE_TYPE (node), node, index);
+  node = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (node), node, index);
 
   /* Finally, return
 
@@ -1744,7 +1743,7 @@ build_field_ref (tree self_value, tree self_class, tree name)
          field_offset = fold (convert (sizetype, field_offset));
          self_value = java_check_reference (self_value, check);
          address 
-           = fold_build2 (PLUS_EXPR, 
+           = fold_build2 (POINTER_PLUS_EXPR, 
                           build_pointer_type (TREE_TYPE (field_decl)),
                           self_value, field_offset);
          return fold_build1 (INDIRECT_REF, TREE_TYPE (field_decl), address);
@@ -2228,8 +2227,8 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
          method_index++;
        }
       method_index *= int_size_in_bytes (method_type_node);
-      ref = fold_build2 (PLUS_EXPR, method_ptr_type_node,
-                        ref, build_int_cst (NULL_TREE, method_index));
+      ref = fold_build2 (POINTER_PLUS_EXPR, method_ptr_type_node,
+                        ref, size_int (method_index));
       ref = build1 (INDIRECT_REF, method_type_node, ref);
       func = build3 (COMPONENT_REF, nativecode_ptr_type_node,
                     ref, lookup_field (&method_type_node, ncode_ident),
@@ -2333,8 +2332,8 @@ build_invokevirtual (tree dtable, tree method, tree special)
                                   size_int (TARGET_VTABLE_USES_DESCRIPTORS));
     }
 
-  func = fold_build2 (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
-                     convert (nativecode_ptr_ptr_type_node, method_index));
+  func = fold_build2 (POINTER_PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
+                     convert (sizetype, method_index));
 
   if (TARGET_VTABLE_USES_DESCRIPTORS)
     func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
index e5bd46134765e5b2ad53727df003dd61cf3b584f..189073498d826e835c8074528000c6ec9fcaf1cd 100644 (file)
@@ -224,10 +224,10 @@ collect_data_for_malloc_call (tree stmt, struct malloc_call_data *m_data)
    initial address and index of each dimension.  */
 struct access_site_info
 {
-  /* The statement (INDIRECT_REF or PLUS_EXPR).  */
+  /* The statement (INDIRECT_REF or POINTER_PLUS_EXPR).  */
   tree stmt;
 
-  /* In case of PLUS_EXPR, what is the offset.  */
+  /* In case of POINTER_PLUS_EXPR, what is the offset.  */
   tree offset;
 
   /* The index which created the offset.  */
@@ -609,7 +609,7 @@ mark_min_matrix_escape_level (struct matrix_info *mi, int l, tree s)
 /* Find if the SSA variable is accessed inside the
    tree and record the tree containing it.
    The only relevant uses are the case of SSA_NAME, or SSA inside
-   INDIRECT_REF, CALL_EXPR, PLUS_EXPR, MULT_EXPR.  */
+   INDIRECT_REF, CALL_EXPR, PLUS_EXPR, POINTER_PLUS_EXPR, MULT_EXPR.  */
 static void
 ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
 {
@@ -644,6 +644,7 @@ ssa_accessed_in_tree (tree t, struct ssa_acc_in_tree *a)
          }
       }
       break;
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MULT_EXPR:
       op1 = TREE_OPERAND (t, 0);
@@ -903,7 +904,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
   for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
        i++)
     {
-      if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 1)) == PLUS_EXPR
+      if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 1)) == POINTER_PLUS_EXPR
          && acc_info->level < min_escape_l)
        {
          loop = loop_containing_stmt (acc_info->stmt);
@@ -1197,7 +1198,7 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
          return current_indirect_level;
        }
       if (rhs_acc.t_code != INDIRECT_REF
-         && rhs_acc.t_code != PLUS_EXPR && rhs_acc.t_code != SSA_NAME)
+         && rhs_acc.t_code != POINTER_PLUS_EXPR && rhs_acc.t_code != SSA_NAME)
        {
          mark_min_matrix_escape_level (mi, current_indirect_level, use_stmt);
          return current_indirect_level;
@@ -1212,11 +1213,8 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
                                           current_indirect_level, true);
          current_indirect_level += 1;
        }
-      else if (rhs_acc.t_code == PLUS_EXPR)
+      else if (rhs_acc.t_code == POINTER_PLUS_EXPR)
        {
-         /* ??? maybe we should check
-            the type of the PLUS_EXP and make sure it's
-            integral type.  */
          gcc_assert (rhs_acc.second_op);
          if (last_op)
            /* Currently we support only one PLUS expression on the
@@ -1286,7 +1284,7 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
          /* We are placing it in an SSA, follow that SSA.  */
          analyze_matrix_accesses (mi, lhs,
                                   current_indirect_level,
-                                  rhs_acc.t_code == PLUS_EXPR,
+                                  rhs_acc.t_code == POINTER_PLUS_EXPR,
                                   visited, record_accesses);
        }
     }
@@ -1321,7 +1319,7 @@ analyze_matrix_accesses (struct matrix_info *mi, tree ssa_var,
 
 /* Now go over the uses of the SSA_NAME and check how it is used in
    each one of them.  We are mainly looking for the pattern INDIRECT_REF,
-   then a PLUS_EXPR, then INDIRECT_REF etc.  while in between there could
+   then a POINTER_PLUS_EXPR, then INDIRECT_REF etc.  while in between there could
    be any number of copies and casts.  */
   gcc_assert (TREE_CODE (ssa_var) == SSA_NAME);
 
@@ -1405,6 +1403,7 @@ can_calculate_expr_before_stmt (tree expr, sbitmap visited)
     case PARM_DECL:
     case INTEGER_CST:
       return expr;
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
@@ -1798,7 +1797,7 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
                    GIMPLE_STMT_OPERAND (orig, 0));
          GIMPLE_STMT_OPERAND (acc_info->stmt, 1) = orig;
        }
-      else if (TREE_CODE (orig) == PLUS_EXPR
+      else if (TREE_CODE (orig) == POINTER_PLUS_EXPR
               && acc_info->level < (min_escape_l))
        {
          imm_use_iterator imm_iter;
@@ -1822,11 +1821,8 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
                  tree new_offset;
                  tree d_type_size, d_type_size_k;
 
-                 d_type_size =
-                   build_int_cst (type,
-                                  mi->dimension_type_size[min_escape_l]);
-                 d_type_size_k =
-                   build_int_cst (type, mi->dimension_type_size[k + 1]);
+                 d_type_size = size_int (mi->dimension_type_size[min_escape_l]);
+                 d_type_size_k = size_int (mi->dimension_type_size[k + 1]);
 
                  new_offset =
                    compute_offset (mi->dimension_type_size[min_escape_l],
@@ -1857,7 +1853,8 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
            {
              d_size = mi->dimension_size[mi->dim_map[k] + 1];
              num_elements =
-               fold_build2 (MULT_EXPR, type, acc_info->index, d_size);
+               fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, acc_info->index),
+                           fold_convert (sizetype, d_size));
              tmp1 = force_gimple_operand (num_elements, &stmts, true, NULL);
              add_referenced_var (d_size);
              if (stmts)
@@ -1880,8 +1877,8 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
 
                  FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, offset)
                    FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
-                   if (use_stmt == acc_info->stmt)
-                   SET_USE (use_p, tmp1);
+                     if (use_stmt == acc_info->stmt)
+                       SET_USE (use_p, tmp1);
                }
              else
                {
index dc097870ff8aa8620b253c7a66188e1125df5cc0..dd146da8b6d3bfdde2483beee4155a60614d6535 100644 (file)
@@ -372,6 +372,7 @@ optab_for_tree_code (enum tree_code code, tree type)
   trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
   switch (code)
     {
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       return trapv ? addv_optab : add_optab;
 
index 7c6d20d380d84dda6682c68ce37afc17567090e5..ba4707a541b46d78edd82056a7f709b9175cbf1e 100644 (file)
@@ -1,3 +1,36 @@
+2007-06-15  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       PR tree-opt/32225
+       * gcc.c-torture/compile/20070605-1.c: New test.
+
+       * gcc.c-torture/compile/20070603-1.c: New testcase.
+       * gcc.c-torture/compile/20070603-2.c: New testcase.
+
+       * gcc.c-torture/compile/20070531-1.c: New test.
+
+       PR tree-opt/32167
+       * gcc.c-torture/compile/20070531-2.c: New test.
+
+       PR tree-opt/32144
+       * gcc.c-torture/compile/20070529-1.c: New test.
+
+       PR tree-opt/32145
+       * gcc.c-torture/compile/20070529-2.c: New test.
+
+       PR tree-opt/32015
+       * gcc.c-torture/compile/20070520-1.c: New test.
+
+       * g++.dg/ext/java-1.C: New test.
+
+       * gcc.dg/vect/vect-106.c: We are now able to vectorize two
+       loops instead of one. Remove the "can't determine dependence"
+       check.
+       * gcc.dg/tree-ssa/20030815-1.c: Remove testcase which is no longer
+       needed as the cast is gone in the first place.
+       * gcc.dg/max-1.c: Change local variable a to be a global one.
+       * gcc.dg/tree-ssa/ssa-pre-8.c: Update testcase since we don't
+       have a cast which is PREd.
+
 2007-06-15  Mark Mitchell  <mark@codesourcery.com>
 
        * g++.dg/lookup/anon6.C: New test.
diff --git a/gcc/testsuite/ChangeLog.ptr b/gcc/testsuite/ChangeLog.ptr
new file mode 100644 (file)
index 0000000..7bb7901
--- /dev/null
@@ -0,0 +1,58 @@
+2007-06-14  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * gcc.dg/max-1.c: Fix spelling/grammer mistakes.
+       * gcc.dg/vect/vect-106.c: Likewise.
+
+2007-06-06  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       PR tree-opt/32225
+       * gcc.c-torture/compile/20070605-1.c: New test.
+
+2007-06-03  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * gcc.c-torture/compile/20070603-1.c: New testcase.
+       * gcc.c-torture/compile/20070603-2.c: New testcase.
+
+2007-05-31  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * gcc.c-torture/compile/20070531-1.c: New test.
+
+       PR tree-opt/32167
+       * gcc.c-torture/compile/20070531-2.c: New test.
+
+2007-05-28  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       PR tree-opt/32144
+       * gcc.c-torture/compile/20070529-1.c: New test.
+
+       PR tree-opt/32145
+       * gcc.c-torture/compile/20070529-2.c: New test.
+
+2007-05-21  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       PR tree-opt/32015
+       * gcc.c-torture/compile/20070520-1.c: New test.
+
+2007-05-12  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+        * g++.dg/ext/java-1.C: New test.
+
+2007-05-09  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * gcc.dg/vect/vect-106.c: We are now able to vectorize two
+       loops instead of one. Remove the "can't determine dependence"
+       check.
+
+2007-05-04  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * gcc.dg/tree-ssa/20030815-1.c: Remove testcase which is no longer
+       needed as the cast is gone in the first place.
+
+2007-05-04  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * gcc.dg/max-1.c: Change local variable a to be a global one.
+
+2006-11-23  Andrew Pinski  <andrew_pinski@playstation.sony.com>
+
+       * gcc.dg/tree-ssa/ssa-pre-8.c: Update testcase since we don't
+       have a cast which is PREd.
diff --git a/gcc/testsuite/g++.dg/ext/java-1.C b/gcc/testsuite/g++.dg/ext/java-1.C
new file mode 100644 (file)
index 0000000..3c1e423
--- /dev/null
@@ -0,0 +1,26 @@
+// { dg-do compile }
+// { dg-options "" }
+// Test extern "java" and some throwing of the objects.
+
+extern "Java"
+  namespace java
+  {
+    namespace lang
+    {
+      class Throwable;
+      class Class;
+  }
+}
+typedef class java::lang::Throwable* jthrowable;
+typedef class java::lang::Class* jclass;
+class java::lang::Throwable {
+public:
+  static jclass class$;
+};
+int
+_Jv_FindClassFromSignature ( )
+  try 
+    {
+    }
+  catch (java::lang::Throwable *ncdfe) {} 
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070520-1.c b/gcc/testsuite/gcc.c-torture/compile/20070520-1.c
new file mode 100644 (file)
index 0000000..fe9db97
--- /dev/null
@@ -0,0 +1,35 @@
+typedef unsigned char uint8_t;
+extern uint8_t ff_cropTbl[256 + 2 * 1024];
+
+void ff_pred8x8_plane_c(uint8_t *src, int stride){
+  int j, k;
+  int a;
+  uint8_t *cm = ff_cropTbl + 1024;
+  const uint8_t * const src0 = src+3-stride;
+  const uint8_t *src1 = src+4*stride-1;
+  const uint8_t *src2 = src1-2*stride;
+  int H = src0[1] - src0[-1];
+  int V = src1[0] - src2[ 0];
+  for(k=2; k<=4; ++k) {
+    src1 += stride; src2 -= stride;
+    H += k*(src0[k] - src0[-k]);
+    V += k*(src1[0] - src2[ 0]);
+  }
+  H = ( 17*H+16 ) >> 5;
+  V = ( 17*V+16 ) >> 5;
+
+  a = 16*(src1[0] + src2[8]+1) - 3*(V+H);
+  for(j=8; j>0; --j) {
+    int b = a;
+    a += V;
+    src[0] = cm[ (b ) >> 5 ];
+    src[1] = cm[ (b+ H) >> 5 ];
+    src[2] = cm[ (b+2*H) >> 5 ];
+    src[3] = cm[ (b+3*H) >> 5 ];
+    src[4] = cm[ (b+4*H) >> 5 ];
+    src[5] = cm[ (b+5*H) >> 5 ];
+    src[6] = cm[ (b+6*H) >> 5 ];
+    src[7] = cm[ (b+7*H) >> 5 ];
+    src += stride;
+  }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070529-1.c b/gcc/testsuite/gcc.c-torture/compile/20070529-1.c
new file mode 100644 (file)
index 0000000..f34add2
--- /dev/null
@@ -0,0 +1,16 @@
+/* ICE in chrec_fold_plus_poly_poly. */
+
+typedef unsigned short __u16;
+typedef unsigned int u32;
+typedef __u16 __be16;
+struct hfs_extent {
+ __be16 count;
+};
+int hfs_free_fork( int type)
+{
+ u32 total_blocks, blocks, start;
+ struct hfs_extent *extent;
+ int res, i;
+ for (i = 0; i < 3; extent++, i++)
+  blocks += __fswab16((( __u16)(__be16)(extent[i].count)));
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070529-2.c b/gcc/testsuite/gcc.c-torture/compile/20070529-2.c
new file mode 100644 (file)
index 0000000..cb38d20
--- /dev/null
@@ -0,0 +1,11 @@
+void xfs_dir2_grow_inode(void)
+{
+ int map;
+ int *mapp;
+ int nmap;
+ mapp = &map;
+ if (nmap == 0 )
+  mapp = ((void *)0);
+ if (mapp != &map)
+  kmem_free(mapp);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070531-1.c b/gcc/testsuite/gcc.c-torture/compile/20070531-1.c
new file mode 100644 (file)
index 0000000..90ecbb8
--- /dev/null
@@ -0,0 +1,11 @@
+/* MIN_EXPR/MAX_EXPR caused an ICE in VRP. */
+int *f(int *a, int *b)
+{
+ *a = 1;
+ *b = 2;
+ int *c = a < b ? a : b;
+ if (c)
+   return c;
+ else
+   return a;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070531-2.c b/gcc/testsuite/gcc.c-torture/compile/20070531-2.c
new file mode 100644 (file)
index 0000000..967180e
--- /dev/null
@@ -0,0 +1,6 @@
+int f(void)
+{
+  int *a = 0;
+  for(a = 0; a < (int*)32767;a++)
+   ;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070603-1.c b/gcc/testsuite/gcc.c-torture/compile/20070603-1.c
new file mode 100644 (file)
index 0000000..94e2baf
--- /dev/null
@@ -0,0 +1,9 @@
+
+int f(_Complex double *a, unsigned int n)
+{
+  unsigned int i;
+  for(i = 0; i< n; i++)
+    {
+      a[i] = __real__ a[i+1] + __real__ a[i];
+    }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070603-2.c b/gcc/testsuite/gcc.c-torture/compile/20070603-2.c
new file mode 100644 (file)
index 0000000..7aaa8c2
--- /dev/null
@@ -0,0 +1,9 @@
+typedef _Complex double ar[];
+int f(ar *a, unsigned int n)
+{
+  unsigned int i;
+  for(i = 0; i< n; i++)
+    {
+      (*a)[i*4] = __real__ (*a)[(i+1)*4] + __real__ (*a)[i*4];
+    }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20070605-1.c b/gcc/testsuite/gcc.c-torture/compile/20070605-1.c
new file mode 100644 (file)
index 0000000..8bf5325
--- /dev/null
@@ -0,0 +1,10 @@
+quantize_fs_dither (unsigned width, short *errorptr, int dir)
+{
+  short bpreverr;
+  unsigned col;
+  for (col = width; col > 0; col--) 
+    errorptr += dir;
+  errorptr[0] = (short) bpreverr;
+}
+
+
index 3eb7800a7f4c300e9546f69ad5e86dcb5cf19f65..a5f16056c31edcfa737669efeaa508751178e635 100644 (file)
@@ -24,10 +24,13 @@ void f(long a, long b)
    fff[i] = a;
 }
 
+/* The variable a cannot be a local variable as we get better aliasing
+   now and decide that the store to a is dead.  The better aliasing comes
+   from better representation of pointer arithmetic. */
+long a = 10;
 int main(void)
 {
   int i;
-  long a = 10;
   f((long)(&a)-1,0);
   for(i = 0;i<10;i++)
    if (fff[i]!=10)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c
deleted file mode 100644 (file)
index 6e41807..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-dom3" } */
-
-extern void abort (void);
-typedef unsigned int size_t;
-struct rtx_def;
-typedef struct rtx_def *rtx;
-typedef union varray_data_tag
-{
-  struct reg_info_def *reg[1];
-} varray_data;
-struct varray_head_tag
-{
-  size_t num_elements;
-  varray_data data;
-};
-typedef struct varray_head_tag *varray_type;
-typedef struct reg_info_def
-{
-} reg_info;
-extern varray_type reg_n_info;
-static rtx *reg_base_value;
-static rtx *new_reg_base_value;
-
-rtx
-blah (unsigned int regno)
-{
-  if (new_reg_base_value[regno] && ((*(
-                                       {
-                                       if (regno >=
-                                           reg_n_info->
-                                           num_elements)
-                                       abort ();
-                                       &reg_n_info->data.reg[regno];}
-                                    ))))
-    return reg_base_value[regno];
-}
-
-/* If we have more than 1 cast to a struct rtx_def * *, then we failed to
-   eliminate some useless typecasting.  The first type cast is needed
-   to convert the unsigned int regno parameter into a struct rtx_def **.  */
-/* { dg-final { scan-tree-dump-times "\\(struct rtx_def \\* \\*\\)" 1 "dom3"} } */
-/* { dg-final { cleanup-tree-dump "dom3" } } */
index a6535fb4013e2cbebba9a5f13ac9702884fc1d90..ae933bbccec6d1957525cd31f729cd7531fa837c 100644 (file)
@@ -16,6 +16,8 @@ foo (__SIZE_TYPE__ i, struct s *array)
     }
   return 0;
 }
-/* We should eliminate two address calculations, one cast, and one load.  */
-/* { dg-final { scan-tree-dump-times "Eliminated: 4" 1 "fre"} } */
+/* We should eliminate two address calculations, and one load.  */
+/* We used to eliminate a cast but that was before POINTER_PLUS_EXPR
+   was added.  */
+/* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "fre"} } */
 /* { dg-final { cleanup-tree-dump "fre" } } */
index 04a9f6c1c6806094d070b5b8eab895c47655fd42..891cd3155acef4c17a5ded91877b2efdb855fe1a 100644 (file)
@@ -17,9 +17,9 @@ int main1 () {
 
   p1 = p; q1 = q;
 
-  /* Not vectorizable: because of the redundant cast (caused by ponter
-     arithmetics), alias analysis fails to distinguish between 
-     the pointers.  */
+  /* Vectorizable, before pointer plus we would get a redundant cast
+     (caused by pointer arithmetics), alias analysis fails to distinguish
+     between the pointers.  */
   for (i = 0; i < N; i++)
     {
       *(q + i) = a[i];
@@ -67,7 +67,6 @@ int main (void)
   return main1 ();
 }
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "can't determine dependence" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
 /* { dg-final { cleanup-tree-dump "vect" } } */
 
index a25d55111694d1222ff67bc65c1277f94698b366..de4cf4ad59f341d02c3c7ea1069bd39adc75a006 100644 (file)
@@ -268,6 +268,13 @@ tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
       aff_combination_const (comb, type, tree_to_double_int (expr));
       return;
 
+    case POINTER_PLUS_EXPR:
+      tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
+      tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
+      aff_combination_convert (&tmp, type);
+      aff_combination_add (comb, &tmp);
+      return;
+
     case PLUS_EXPR:
     case MINUS_EXPR:
       tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
index 6dc0d3e4203a4622163814f8f384d496a2876743..3fd57720150a5fc86e0ea5d78218043ec2431a18 100644 (file)
@@ -3265,7 +3265,36 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
        }
       *walk_subtrees = 0;
       break;
+    case PLUS_EXPR:
+    case MINUS_EXPR:
+      /* PLUS_EXPR and MINUS_EXPR don't work on pointers, they should be done using
+        POINTER_PLUS_EXPR. */
+      if (POINTER_TYPE_P (TREE_TYPE (t)))
+       {
+         error ("invalid operand to plus/minus, type is a pointer");
+         return t;
+       }
+      CHECK_OP (0, "invalid operand to binary operator");
+      CHECK_OP (1, "invalid operand to binary operator");
+      break;
 
+    case POINTER_PLUS_EXPR:
+      /* Check to make sure the first operand is a pointer or reference type. */
+      if (!POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
+       {
+         error ("invalid operand to pointer plus, first operand is not a pointer");
+         return t;
+       }
+      /* Check to make sure the second operand is an integer with type of
+        sizetype.  */
+      if (!tree_ssa_useless_type_conversion_1 (sizetype,
+                                              TREE_TYPE (TREE_OPERAND (t, 1))))
+       {
+         error ("invalid operand to pointer plus, second operand is not an "
+                "integer with type of sizetype.");
+         return t;
+       }
+      /* FALLTHROUGH */
     case LT_EXPR:
     case LE_EXPR:
     case GT_EXPR:
@@ -3280,8 +3309,6 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
     case UNGE_EXPR:
     case UNEQ_EXPR:
     case LTGT_EXPR:
-    case PLUS_EXPR:
-    case MINUS_EXPR:
     case MULT_EXPR:
     case TRUNC_DIV_EXPR:
     case CEIL_DIV_EXPR:
index f55d004c8e9c1437e4b5982b2853fb829554cd3d..303e9567bda43ab63de6aa5dfdfc65ba4d8d7f8a 100644 (file)
@@ -101,12 +101,16 @@ chrec_fold_plus_poly_poly (enum tree_code code,
   tree left, right;
   struct loop *loop0 = get_chrec_loop (poly0);
   struct loop *loop1 = get_chrec_loop (poly1);
+  tree rtype = code == POINTER_PLUS_EXPR ? sizetype : type;
 
   gcc_assert (poly0);
   gcc_assert (poly1);
   gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
   gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
-  gcc_assert (chrec_type (poly0) == chrec_type (poly1));
+  if (POINTER_TYPE_P (chrec_type (poly0)))
+    gcc_assert (chrec_type (poly1) == sizetype);
+  else
+    gcc_assert (chrec_type (poly0) == chrec_type (poly1));
   gcc_assert (type == chrec_type (poly0));
   
   /*
@@ -115,7 +119,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
     {a, +, b}_x + {c, +, d}_x  ->  {a+c, +, b+d}_x.  */
   if (flow_loop_nested_p (loop0, loop1))
     {
-      if (code == PLUS_EXPR)
+      if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
        return build_polynomial_chrec 
          (CHREC_VARIABLE (poly1), 
           chrec_fold_plus (type, poly0, CHREC_LEFT (poly1)),
@@ -132,7 +136,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
   
   if (flow_loop_nested_p (loop1, loop0))
     {
-      if (code == PLUS_EXPR)
+      if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
        return build_polynomial_chrec 
          (CHREC_VARIABLE (poly0), 
           chrec_fold_plus (type, CHREC_LEFT (poly0), poly1),
@@ -148,12 +152,12 @@ chrec_fold_plus_poly_poly (enum tree_code code,
      do not belong to the same loop nest.  */
   gcc_assert (loop0 == loop1);
 
-  if (code == PLUS_EXPR)
+  if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
     {
       left = chrec_fold_plus 
        (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
       right = chrec_fold_plus 
-       (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
+       (rtype, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
     }
   else
     {
@@ -264,6 +268,8 @@ static tree
 chrec_fold_plus_1 (enum tree_code code, tree type, 
                   tree op0, tree op1)
 {
+  tree op1_type = code == POINTER_PLUS_EXPR ? sizetype : type;
+
   if (automatically_generated_chrec_p (op0)
       || automatically_generated_chrec_p (op1))
     return chrec_fold_automatically_generated_operands (op0, op1);
@@ -277,7 +283,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
          return chrec_fold_plus_poly_poly (code, type, op0, op1);
 
        default:
-         if (code == PLUS_EXPR)
+         if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
            return build_polynomial_chrec 
              (CHREC_VARIABLE (op0), 
               chrec_fold_plus (type, CHREC_LEFT (op0), op1),
@@ -293,7 +299,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
       switch (TREE_CODE (op1))
        {
        case POLYNOMIAL_CHREC:
-         if (code == PLUS_EXPR)
+         if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
            return build_polynomial_chrec 
              (CHREC_VARIABLE (op1), 
               chrec_fold_plus (type, op0, CHREC_LEFT (op1)),
@@ -317,7 +323,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
            else if (size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
              return fold_build2 (code, type,
                                  fold_convert (type, op0),
-                                 fold_convert (type, op1));
+                                 fold_convert (op1_type, op1));
            else
              return chrec_dont_know;
          }
@@ -332,16 +338,22 @@ chrec_fold_plus (tree type,
                 tree op0,
                 tree op1)
 {
+  enum tree_code code;
   if (automatically_generated_chrec_p (op0)
       || automatically_generated_chrec_p (op1))
     return chrec_fold_automatically_generated_operands (op0, op1);
 
   if (integer_zerop (op0))
-    return op1;
+    return chrec_convert (type, op1, NULL_TREE);
   if (integer_zerop (op1))
-    return op0;
+    return chrec_convert (type, op0, NULL_TREE);
+
+  if (POINTER_TYPE_P (type))
+    code = POINTER_PLUS_EXPR;
+  else
+    code = PLUS_EXPR;
   
-  return chrec_fold_plus_1 (PLUS_EXPR, type, op0, op1);
+  return chrec_fold_plus_1 (code, type, op0, op1);
 }
 
 /* Fold the subtraction of two chrecs.  */
@@ -566,8 +578,8 @@ chrec_apply (unsigned var,
   if (evolution_function_is_affine_p (chrec))
     {
       /* "{a, +, b} (x)"  ->  "a + b*x".  */
-      x = chrec_convert (type, x, NULL_TREE);
-      res = chrec_fold_multiply (type, CHREC_RIGHT (chrec), x);
+      x = chrec_convert_rhs (type, x, NULL_TREE);
+      res = chrec_fold_multiply (TREE_TYPE (x), CHREC_RIGHT (chrec), x);
       if (!integer_zerop (CHREC_LEFT (chrec)))
        res = chrec_fold_plus (type, CHREC_LEFT (chrec), res);
     }
@@ -767,7 +779,10 @@ reset_evolution_in_loop (unsigned loop_num,
 {
   struct loop *loop = get_loop (loop_num);
 
-  gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
+  if (POINTER_TYPE_P (chrec_type (chrec)))
+    gcc_assert (sizetype == chrec_type (new_evol));
+  else
+    gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
 
   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
       && flow_loop_nested_p (loop, get_chrec_loop (chrec)))
@@ -1119,6 +1134,7 @@ convert_affine_scev (struct loop *loop, tree type,
   bool enforce_overflow_semantics;
   bool must_check_src_overflow, must_check_rslt_overflow;
   tree new_base, new_step;
+  tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
 
   /* If we cannot perform arithmetic in TYPE, avoid creating an scev.  */
   if (avoid_arithmetics_in_type_p (type))
@@ -1188,10 +1204,10 @@ convert_affine_scev (struct loop *loop, tree type,
      [100, +, 255] with values 100, 355, ...; the sign-extension is 
      performed by default when CT is signed.  */
   new_step = *step;
-  if (TYPE_PRECISION (type) > TYPE_PRECISION (ct) && TYPE_UNSIGNED (ct))
+  if (TYPE_PRECISION (step_type) > TYPE_PRECISION (ct) && TYPE_UNSIGNED (ct))
     new_step = chrec_convert_1 (signed_type_for (ct), new_step, at_stmt,
                                use_overflow_semantics);
-  new_step = chrec_convert_1 (type, new_step, at_stmt, use_overflow_semantics);
+  new_step = chrec_convert_1 (step_type, new_step, at_stmt, use_overflow_semantics);
 
   if (automatically_generated_chrec_p (new_base)
       || automatically_generated_chrec_p (new_step))
@@ -1209,6 +1225,16 @@ convert_affine_scev (struct loop *loop, tree type,
 }
 \f
 
+/* Convert CHREC for the right hand side of a CREC.
+   The increment for a pointer type is always sizetype.  */
+tree 
+chrec_convert_rhs (tree type, tree chrec, tree at_stmt)
+{
+  if (POINTER_TYPE_P (type))
+   type = sizetype;
+  return chrec_convert (type, chrec, at_stmt);
+}
+
 /* Convert CHREC to TYPE.  When the analyzer knows the context in
    which the CHREC is built, it sets AT_STMT to the statement that
    contains the definition of the analyzed variable, otherwise the
@@ -1306,7 +1332,7 @@ keep_cast:
 tree
 chrec_convert_aggressive (tree type, tree chrec)
 {
-  tree inner_type, left, right, lc, rc;
+  tree inner_type, left, right, lc, rc, rtype;
 
   if (automatically_generated_chrec_p (chrec)
       || TREE_CODE (chrec) != POLYNOMIAL_CHREC)
@@ -1320,14 +1346,16 @@ chrec_convert_aggressive (tree type, tree chrec)
   if (avoid_arithmetics_in_type_p (type))
     return NULL_TREE;
 
+  rtype = POINTER_TYPE_P (type) ? sizetype : type;
+
   left = CHREC_LEFT (chrec);
   right = CHREC_RIGHT (chrec);
   lc = chrec_convert_aggressive (type, left);
   if (!lc)
     lc = chrec_convert (type, left, NULL_TREE);
-  rc = chrec_convert_aggressive (type, right);
+  rc = chrec_convert_aggressive (rtype, right);
   if (!rc)
-    rc = chrec_convert (type, right, NULL_TREE);
+    rc = chrec_convert (rtype, right, NULL_TREE);
  
   return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc);
 }
index 75ef41b112ac9f9d5aa7a9e2fd7054e6a4eb695c..e6bea92eb3b59e5730a103628c8d18e5facbefc5 100644 (file)
@@ -59,6 +59,7 @@ extern tree chrec_fold_plus (tree, tree, tree);
 extern tree chrec_fold_minus (tree, tree, tree);
 extern tree chrec_fold_multiply (tree, tree, tree);
 extern tree chrec_convert (tree, tree, tree);
+extern tree chrec_convert_rhs (tree, tree, tree);
 extern tree chrec_convert_aggressive (tree, tree);
 
 /* Operations.  */
@@ -108,7 +109,10 @@ build_polynomial_chrec (unsigned loop_num,
       || right == chrec_dont_know)
     return chrec_dont_know;
 
-  gcc_assert (TREE_TYPE (left) == TREE_TYPE (right));
+  if (POINTER_TYPE_P (TREE_TYPE (left)))
+    gcc_assert (sizetype == TREE_TYPE (right));
+  else
+    gcc_assert (TREE_TYPE (left) == TREE_TYPE (right));
 
   if (chrec_zerop (right))
     return left;
index 53c9c0054fb8d493b442953ee314df6810ab07d9..6f3ba84938863e3ee1967e70a775f8989c112502 100644 (file)
@@ -495,25 +495,30 @@ split_constant_offset (tree exp, tree *var, tree *off)
   tree type = TREE_TYPE (exp), otype;
   tree var0, var1;
   tree off0, off1;
+  enum tree_code code;
 
   *var = exp;
   STRIP_NOPS (exp);
   otype = TREE_TYPE (exp);
+  code = TREE_CODE (exp);
 
-  switch (TREE_CODE (exp))
+  switch (code)
     {
     case INTEGER_CST:
       *var = build_int_cst (type, 0);
       *off = fold_convert (ssizetype, exp);
       return;
 
+    case POINTER_PLUS_EXPR:
+      code = PLUS_EXPR;
+      /* FALLTHROUGH */
     case PLUS_EXPR:
     case MINUS_EXPR:
       split_constant_offset (TREE_OPERAND (exp, 0), &var0, &off0);
       split_constant_offset (TREE_OPERAND (exp, 1), &var1, &off1);
       *var = fold_convert (type, fold_build2 (TREE_CODE (exp), otype, 
                                              var0, var1));
-      *off = size_binop (TREE_CODE (exp), off0, off1);
+      *off = size_binop (code, off0, off1);
       return;
 
     case MULT_EXPR:
index 11d400afe61c9470b12354a925c33537d5b63307..01816862ce04cb8cd39175fc0193f3670b5876c6 100644 (file)
@@ -2085,6 +2085,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
     case VEC_COND_EXPR:
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
 
index c3c8604b177c0456b8a95d2fcaa4b22d06c3ab8e..3ea0fb017cf4722f68f2f1fba0edcc34bb3c9634 100644 (file)
@@ -824,8 +824,8 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
              elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)),
                            elt);
             addr = fold_convert (ptr_type_node, elt ? elt : base);
-            addr = fold_build2 (PLUS_EXPR, ptr_type_node,
-                               addr, fold_convert (ptr_type_node,
+            addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+                               addr, fold_convert (sizetype,
                                                    byte_position (field)));
           }
         else
@@ -842,17 +842,19 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
     case INDIRECT_REF:
       addr = TREE_OPERAND (t, 0);
       base = addr;
-      limit = fold_build2 (MINUS_EXPR, ptr_type_node,
-                           fold_build2 (PLUS_EXPR, ptr_type_node, base, size),
-                           integer_one_node);
+      limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+                          fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
+                                       size),
+                          size_int (-1));
       break;
 
     case TARGET_MEM_REF:
       addr = tree_mem_ref_addr (ptr_type_node, t);
       base = addr;
-      limit = fold_build2 (MINUS_EXPR, ptr_type_node,
-                          fold_build2 (PLUS_EXPR, ptr_type_node, base, size),
-                          build_int_cst (ptr_type_node, 1));
+      limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+                          fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
+                                       size),
+                          size_int (-1));
       break;
 
     case ARRAY_RANGE_REF:
@@ -872,7 +874,7 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
         bpu = bitsize_int (BITS_PER_UNIT);
         ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
         rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu);
-        ofs = size_binop (TRUNC_DIV_EXPR, ofs, bpu);
+        ofs = fold_convert (sizetype, size_binop (TRUNC_DIV_EXPR, ofs, bpu));
 
         size = convert (bitsizetype, TREE_OPERAND (t, 1));
         size = size_binop (PLUS_EXPR, size, rem);
@@ -881,12 +883,13 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
 
         addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
         addr = convert (ptr_type_node, addr);
-        addr = fold_build2 (PLUS_EXPR, ptr_type_node, addr, ofs);
+        addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, ofs);
 
         base = addr;
-        limit = fold_build2 (MINUS_EXPR, ptr_type_node,
-                             fold_build2 (PLUS_EXPR, ptr_type_node, base, size),
-                             integer_one_node);
+        limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+                             fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+                                          base, size),
+                             size_int (-1));
       }
       break;
 
index fee75a8e72af38985dc8425d68dadfd3e8b1d30c..aff1875752dbbb1705ea2e78c318e2306afdd78d 100644 (file)
@@ -555,7 +555,7 @@ merge_object_sizes (struct object_size_info *osi, tree dest, tree orig,
 
 
 /* Compute object_sizes for PTR, defined to VALUE, which is
-   a PLUS_EXPR.  Return true if the object size might need reexamination
+   a POINTER_PLUS_EXPR.  Return true if the object size might need reexamination
    later.  */
 
 static bool
@@ -563,33 +563,17 @@ plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
 {
   tree op0 = TREE_OPERAND (value, 0);
   tree op1 = TREE_OPERAND (value, 1);
-  bool ptr1_p = POINTER_TYPE_P (TREE_TYPE (op0))
-               && TREE_CODE (op0) != INTEGER_CST;
-  bool ptr2_p = POINTER_TYPE_P (TREE_TYPE (op1))
-               && TREE_CODE (op1) != INTEGER_CST;
   int object_size_type = osi->object_size_type;
   unsigned int varno = SSA_NAME_VERSION (var);
   unsigned HOST_WIDE_INT bytes;
 
-  gcc_assert (TREE_CODE (value) == PLUS_EXPR);
+  gcc_assert (TREE_CODE (value) == POINTER_PLUS_EXPR);
 
   if (object_sizes[object_size_type][varno] == unknown[object_size_type])
     return false;
 
-  /* Swap operands if needed.  */
-  if (ptr2_p && !ptr1_p)
-    {
-      tree tem = op0;
-      op0 = op1;
-      op1 = tem;
-      ptr1_p = true;
-      ptr2_p = false;
-    }
-
   /* Handle PTR + OFFSET here.  */
-  if (ptr1_p
-      && !ptr2_p
-      && TREE_CODE (op1) == INTEGER_CST
+  if (TREE_CODE (op1) == INTEGER_CST
       && (TREE_CODE (op0) == SSA_NAME
          || TREE_CODE (op0) == ADDR_EXPR))
     {
@@ -669,7 +653,7 @@ cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
    OSI->object_size_type).
    For allocation CALL_EXPR like malloc or calloc object size is the size
    of the allocation.
-   For pointer PLUS_EXPR where second operand is a constant integer,
+   For POINTER_PLUS_EXPR where second operand is a constant integer,
    object size is object size of the first operand minus the constant.
    If the constant is bigger than the number of remaining bytes until the
    end of the object, object size is 0, but if it is instead a pointer
@@ -750,7 +734,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
            && POINTER_TYPE_P (TREE_TYPE (rhs)))
          reexamine = merge_object_sizes (osi, var, rhs, 0);
 
-       else if (TREE_CODE (rhs) == PLUS_EXPR)
+       else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
          reexamine = plus_expr_object_size (osi, var, rhs);
 
         else if (TREE_CODE (rhs) == COND_EXPR)
@@ -877,23 +861,14 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
 
        if (TREE_CODE (rhs) == SSA_NAME)
          check_for_plus_in_loops_1 (osi, rhs, depth);
-       else if (TREE_CODE (rhs) == PLUS_EXPR)
+       else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
          {
            tree op0 = TREE_OPERAND (rhs, 0);
            tree op1 = TREE_OPERAND (rhs, 1);
            tree cst, basevar;
 
-           if (TREE_CODE (op0) == SSA_NAME)
-             {
-               basevar = op0;
-               cst = op1;
-             }
-           else
-             {
-               basevar = op1;
-               cst = op0;
-               gcc_assert (TREE_CODE (basevar) == SSA_NAME);
-             }
+           basevar = op0;
+           cst = op1;
            gcc_assert (TREE_CODE (cst) == INTEGER_CST);
 
            check_for_plus_in_loops_1 (osi, basevar,
@@ -953,23 +928,14 @@ check_for_plus_in_loops (struct object_size_info *osi, tree var)
              rhs = arg;
          }
 
-       if (TREE_CODE (rhs) == PLUS_EXPR)
+       if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
          {
            tree op0 = TREE_OPERAND (rhs, 0);
            tree op1 = TREE_OPERAND (rhs, 1);
            tree cst, basevar;
 
-           if (TREE_CODE (op0) == SSA_NAME)
-             {
-               basevar = op0;
-               cst = op1;
-             }
-           else
-             {
-               basevar = op1;
-               cst = op0;
-               gcc_assert (TREE_CODE (basevar) == SSA_NAME);
-             }
+           basevar = op0;
+           cst = op1;
            gcc_assert (TREE_CODE (cst) == INTEGER_CST);
 
            if (integer_zerop (cst))
index 3c9164db2c7762c5fe9ea491b8461bae07781326..db9a8d509f09626cc29aab41926c3fbda85bfa91 100644 (file)
@@ -1350,9 +1350,18 @@ ref_at_iteration (struct loop *loop, tree ref, int iter)
   else
     {
       type = TREE_TYPE (iv.base);
-      val = fold_build2 (MULT_EXPR, type, iv.step,
-                        build_int_cst_type (type, iter));
-      val = fold_build2 (PLUS_EXPR, type, iv.base, val);
+      if (POINTER_TYPE_P (type))
+       {
+         val = fold_build2 (MULT_EXPR, sizetype, iv.step,
+                            size_int (iter));
+         val = fold_build2 (POINTER_PLUS_EXPR, type, iv.base, val);
+       }
+      else
+       {
+         val = fold_build2 (MULT_EXPR, type, iv.step,
+                            build_int_cst_type (type, iter));
+         val = fold_build2 (PLUS_EXPR, type, iv.base, val);
+       }
       *idx_p = unshare_expr (val);
     }
 
index 0c313f20e88bbf3a5dd073cd0d6e95f30c6dd303..3aac9c7d9a7706379c0a27ab9e89de02daab23b0 100644 (file)
@@ -1233,6 +1233,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case WIDEN_MULT_EXPR:
     case MULT_EXPR:
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
     case TRUNC_DIV_EXPR:
     case CEIL_DIV_EXPR:
@@ -2328,6 +2329,7 @@ op_prio (tree op)
 
     case WIDEN_SUM_EXPR:
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
       return 12;
 
@@ -2486,6 +2488,9 @@ op_symbol_code (enum tree_code code)
 
     case VEC_RSHIFT_EXPR:
       return "v>>";
+
+    case POINTER_PLUS_EXPR:
+      return "+";
  
     case PLUS_EXPR:
       return "+";
index a5444abb38427fcbb7ba6f059cf56ee5d402d6c6..6dc69f2d304f616e6f2a5737ec9a349793058cb4 100644 (file)
@@ -665,8 +665,8 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
            }
 
          to_add = chrec_convert (type, to_add, at_stmt);
-         right = chrec_convert (type, right, at_stmt);
-         right = chrec_fold_plus (type, right, to_add);
+         right = chrec_convert_rhs (type, right, at_stmt);
+         right = chrec_fold_plus (chrec_type (right), right, to_add);
          return build_polynomial_chrec (var, left, right);
        }
       else
@@ -677,7 +677,7 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
          left = add_to_evolution_1 (loop_nb, CHREC_LEFT (chrec_before),
                                     to_add, at_stmt);
          right = CHREC_RIGHT (chrec_before);
-         right = chrec_convert (chrec_type (left), right, at_stmt);
+         right = chrec_convert_rhs (chrec_type (left), right, at_stmt);
          return build_polynomial_chrec (CHREC_VARIABLE (chrec_before),
                                         left, right);
        }
@@ -688,7 +688,7 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
        return chrec_dont_know;
 
       left = chrec_before;
-      right = chrec_convert (chrec_type (left), to_add, at_stmt);
+      right = chrec_convert_rhs (chrec_type (left), to_add, at_stmt);
       return build_polynomial_chrec (loop_nb, left, right);
     }
 }
@@ -1014,15 +1014,18 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
   tree rhs0, rhs1;
   tree type_rhs = TREE_TYPE (rhs);
   tree evol;
+  enum tree_code code;
   
   /* The RHS is one of the following cases:
      - an SSA_NAME, 
      - an INTEGER_CST,
      - a PLUS_EXPR, 
+     - a POINTER_PLUS_EXPR, 
      - a MINUS_EXPR,
      - an ASSERT_EXPR,
      - other cases are not yet handled.  */
-  switch (TREE_CODE (rhs))
+  code = TREE_CODE (rhs);
+  switch (code)
     {
     case NOP_EXPR:
       /* This assignment is under the form "a_1 = (cast) rhs.  */
@@ -1043,6 +1046,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
        (loop, SSA_NAME_DEF_STMT (rhs), halting_phi, evolution_of_loop, limit);
       break;
       
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       /* This case is under the form "rhs0 + rhs1".  */
       rhs0 = TREE_OPERAND (rhs, 0);
@@ -1071,7 +1075,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
                *evolution_of_loop = add_to_evolution 
                  (loop->num, 
                   chrec_convert (type_rhs, evol, at_stmt), 
-                  PLUS_EXPR, rhs1, at_stmt);
+                  code, rhs1, at_stmt);
              
              else if (res == t_false)
                {
@@ -1083,7 +1087,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
                    *evolution_of_loop = add_to_evolution 
                      (loop->num, 
                       chrec_convert (type_rhs, *evolution_of_loop, at_stmt), 
-                      PLUS_EXPR, rhs0, at_stmt);
+                      code, rhs0, at_stmt);
 
                  else if (res == t_dont_know)
                    *evolution_of_loop = chrec_dont_know;
@@ -1104,7 +1108,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
                *evolution_of_loop = add_to_evolution 
                  (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
                                             at_stmt),
-                  PLUS_EXPR, rhs1, at_stmt);
+                  code, rhs1, at_stmt);
 
              else if (res == t_dont_know)
                *evolution_of_loop = chrec_dont_know;
@@ -1122,7 +1126,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
            *evolution_of_loop = add_to_evolution 
              (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
                                         at_stmt),
-              PLUS_EXPR, rhs0, at_stmt);
+              code, rhs0, at_stmt);
 
          else if (res == t_dont_know)
            *evolution_of_loop = chrec_dont_know;
@@ -1611,6 +1615,16 @@ interpret_rhs_modify_stmt (struct loop *loop, tree at_stmt,
 
   switch (TREE_CODE (opnd1))
     {
+    case POINTER_PLUS_EXPR:
+      opnd10 = TREE_OPERAND (opnd1, 0);
+      opnd11 = TREE_OPERAND (opnd1, 1);
+      chrec10 = analyze_scalar_evolution (loop, opnd10);
+      chrec11 = analyze_scalar_evolution (loop, opnd11);
+      chrec10 = chrec_convert (type, chrec10, at_stmt);
+      chrec11 = chrec_convert (sizetype, chrec11, at_stmt);
+      res = chrec_fold_plus (type, chrec10, chrec11);
+      break;
+
     case PLUS_EXPR:
       opnd10 = TREE_OPERAND (opnd1, 0);
       opnd11 = TREE_OPERAND (opnd1, 1);
@@ -1702,187 +1716,6 @@ compute_scalar_evolution_in_loop (struct loop *wrto_loop,
   return analyze_scalar_evolution_1 (wrto_loop, res, chrec_not_analyzed_yet);
 }
 
-/* Folds EXPR, if it is a cast to pointer, assuming that the created
-   polynomial_chrec does not wrap.  */
-
-static tree
-fold_used_pointer_cast (tree expr)
-{
-  tree op;
-  tree type, inner_type;
-
-  if (TREE_CODE (expr) != NOP_EXPR && TREE_CODE (expr) != CONVERT_EXPR)
-    return expr;
-
-  op = TREE_OPERAND (expr, 0);
-  if (TREE_CODE (op) != POLYNOMIAL_CHREC)
-    return expr;
-
-  type = TREE_TYPE (expr);
-  inner_type = TREE_TYPE (op);
-
-  if (!INTEGRAL_TYPE_P (inner_type)
-      || TYPE_PRECISION (inner_type) != TYPE_PRECISION (type))
-    return expr;
-
-  return build_polynomial_chrec (CHREC_VARIABLE (op),
-               chrec_convert (type, CHREC_LEFT (op), NULL_TREE),
-               chrec_convert (type, CHREC_RIGHT (op), NULL_TREE));
-}
-
-/* Returns true if EXPR is an expression corresponding to offset of pointer
-   in p + offset.  */
-
-static bool
-pointer_offset_p (tree expr)
-{
-  if (TREE_CODE (expr) == INTEGER_CST)
-    return true;
-
-  if ((TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
-      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
-    return true;
-
-  return false;
-}
-
-/* EXPR is a scalar evolution of a pointer that is dereferenced or used in
-   comparison.  This means that it must point to a part of some object in
-   memory, which enables us to argue about overflows and possibly simplify
-   the EXPR.  AT_STMT is the statement in which this conversion has to be
-   performed.  Returns the simplified value.
-
-   Currently, for
-
-   int i, n;
-   int *p;
-
-   for (i = -n; i < n; i++)
-     *(p + i) = ...;
-
-   We generate the following code (assuming that size of int and size_t is
-   4 bytes):
-
-   for (i = -n; i < n; i++)
-     {
-       size_t tmp1, tmp2;
-       int *tmp3, *tmp4;
-
-       tmp1 = (size_t) i;      (1)
-       tmp2 = 4 * tmp1;                (2)
-       tmp3 = (int *) tmp2;    (3)
-       tmp4 = p + tmp3;                (4)
-
-       *tmp4 = ...;
-     }
-
-   We in general assume that pointer arithmetics does not overflow (since its
-   behavior is undefined in that case).  One of the problems is that our
-   translation does not capture this property very well -- (int *) is
-   considered unsigned, hence the computation in (4) does overflow if i is
-   negative.
-
-   This impreciseness creates complications in scev analysis.  The scalar
-   evolution of i is [-n, +, 1].  Since int and size_t have the same precision
-   (in this example), and size_t is unsigned (so we do not care about
-   overflows), we succeed to derive that scev of tmp1 is [(size_t) -n, +, 1]
-   and scev of tmp2 is [4 * (size_t) -n, +, 4].  With tmp3, we run into
-   problem -- [(int *) (4 * (size_t) -n), +, 4] wraps, and since we on several
-   places assume that this is not the case for scevs with pointer type, we
-   cannot use this scev for tmp3; hence, its scev is
-   (int *) [(4 * (size_t) -n), +, 4], and scev of tmp4 is
-   p + (int *) [(4 * (size_t) -n), +, 4].  Most of the optimizers are unable to
-   work with scevs of this shape.
-
-   However, since tmp4 is dereferenced, all its values must belong to a single
-   object, and taking into account that the precision of int * and size_t is
-   the same, it is impossible for its scev to wrap.  Hence, we can derive that
-   its evolution is [p + (int *) (4 * (size_t) -n), +, 4], which the optimizers
-   can work with.
-
-   ??? Maybe we should use different representation for pointer arithmetics,
-   however that is a long-term project with a lot of potential for creating
-   bugs.  */
-
-static tree
-fold_used_pointer (tree expr, tree at_stmt)
-{
-  tree op0, op1, new0, new1;
-  enum tree_code code = TREE_CODE (expr);
-
-  if (code == PLUS_EXPR
-      || code == MINUS_EXPR)
-    {
-      op0 = TREE_OPERAND (expr, 0);
-      op1 = TREE_OPERAND (expr, 1);
-
-      if (pointer_offset_p (op1))
-       {
-         new0 = fold_used_pointer (op0, at_stmt);
-         new1 = fold_used_pointer_cast (op1);
-       }
-      else if (code == PLUS_EXPR && pointer_offset_p (op0))
-       {
-         new0 = fold_used_pointer_cast (op0);
-         new1 = fold_used_pointer (op1, at_stmt);
-       }
-      else
-       return expr;
-
-      if (new0 == op0 && new1 == op1)
-       return expr;
-
-      new0 = chrec_convert (TREE_TYPE (expr), new0, at_stmt);
-      new1 = chrec_convert (TREE_TYPE (expr), new1, at_stmt);
-
-      if (code == PLUS_EXPR)
-       expr = chrec_fold_plus (TREE_TYPE (expr), new0, new1);
-      else
-       expr = chrec_fold_minus (TREE_TYPE (expr), new0, new1);
-
-      return expr;
-    }
-  else
-    return fold_used_pointer_cast (expr);
-}
-
-/* Returns true if PTR is dereferenced, or used in comparison.  */
-
-static bool
-pointer_used_p (tree ptr)
-{
-  use_operand_p use_p;
-  imm_use_iterator imm_iter;
-  tree stmt, rhs;
-  struct ptr_info_def *pi = get_ptr_info (ptr);
-
-  /* Check whether the pointer has a memory tag; if it does, it is
-     (or at least used to be) dereferenced.  */
-  if ((pi != NULL && pi->name_mem_tag != NULL)
-      || symbol_mem_tag (SSA_NAME_VAR (ptr)))
-    return true;
-
-  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ptr)
-    {
-      stmt = USE_STMT (use_p);
-      if (TREE_CODE (stmt) == COND_EXPR)
-       return true;
-
-      if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
-       continue;
-
-      rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-      if (!COMPARISON_CLASS_P (rhs))
-       continue;
-
-      if (GIMPLE_STMT_OPERAND (stmt, 0) == ptr
-         || GIMPLE_STMT_OPERAND (stmt, 1) == ptr)
-       return true;
-    }
-
-  return false;
-}
-
 /* Helper recursive function.  */
 
 static tree
@@ -1932,11 +1765,6 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
     case GIMPLE_MODIFY_STMT:
       res = interpret_rhs_modify_stmt (loop, def,
                                       GIMPLE_STMT_OPERAND (def, 1), type);
-
-      if (POINTER_TYPE_P (type)
-         && !automatically_generated_chrec_p (res)
-         && pointer_used_p (var))
-       res = fold_used_pointer (res, def);
       break;
 
     case PHI_NODE:
@@ -2220,11 +2048,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, int flags, htab_t cache
       if (CHREC_LEFT (chrec) != op0
          || CHREC_RIGHT (chrec) != op1)
        {
-         op1 = chrec_convert (chrec_type (op0), op1, NULL_TREE);
+         op1 = chrec_convert_rhs (chrec_type (op0), op1, NULL_TREE);
          chrec = build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
        }
       return chrec;
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
                                      flags, cache, size_expr);
@@ -2240,7 +2069,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec, int flags, htab_t cache
          || TREE_OPERAND (chrec, 1) != op1)
        {
          op0 = chrec_convert (type, op0, NULL_TREE);
-         op1 = chrec_convert (type, op1, NULL_TREE);
+         op1 = chrec_convert_rhs (type, op1, NULL_TREE);
          chrec = chrec_fold_plus (type, op0, op1);
        }
       return chrec;
index 1279a056e5fc9a82487cac1ae388e2565de8033b..5606dca89ea278fc6bbc62720c14dd8b6b268160 100644 (file)
@@ -290,9 +290,10 @@ tree_mem_ref_addr (tree type, tree mem_ref)
 
   if (addr_off)
     {
-      addr = fold_convert (type, addr_off);
       if (addr_base)
-       addr = fold_build2 (PLUS_EXPR, type, addr_base, addr);
+       addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
+      else
+       addr = fold_convert (type, addr_off);
     }
   else if (addr_base)
     addr = addr_base;
@@ -410,7 +411,7 @@ add_to_parts (struct mem_address *parts, tree elt)
 
   if (!parts->index)
     {
-      parts->index = elt;
+      parts->index = fold_convert (sizetype, elt);
       return;
     }
 
@@ -482,7 +483,7 @@ most_expensive_mult_to_index (struct mem_address *parts, aff_tree *addr)
          j++;
          continue;
        }
-  
+
       elt = fold_convert (sizetype, addr->elts[i].val);
       if (mult_elt)
        mult_elt = fold_build2 (op_code, sizetype, mult_elt, elt);
@@ -658,9 +659,9 @@ create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr)
        {
          atype = TREE_TYPE (parts.base);
          parts.base = force_gimple_operand_bsi (bsi, 
-                       fold_build2 (PLUS_EXPR, atype,
+                       fold_build2 (POINTER_PLUS_EXPR, atype,
                                     parts.base,
-                                    fold_convert (atype, parts.offset)),
+                                    fold_convert (sizetype, parts.offset)),
                        true, NULL_TREE);
        }
       else
index 3b275babf66bc0b6249633e8f02fa993a0e0bb53..0ea8675ae6b7deccc7a9e7293cd793cf502e3cdc 100644 (file)
@@ -1853,8 +1853,8 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
   if (t)
     return t;
 
-  /* Add in any offset from a PLUS_EXPR.  */
-  if (TREE_CODE (base) == PLUS_EXPR)
+  /* Add in any offset from a POINTER_PLUS_EXPR.  */
+  if (TREE_CODE (base) == POINTER_PLUS_EXPR)
     {
       tree offset2;
 
@@ -1863,7 +1863,8 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
        return NULL_TREE;
       base = TREE_OPERAND (base, 0);
 
-      offset = int_const_binop (PLUS_EXPR, offset, offset2, 1);
+      offset = fold_convert (sizetype,
+                            int_const_binop (PLUS_EXPR, offset, offset2, 1));
     }
 
   if (TREE_CODE (base) == ADDR_EXPR)
@@ -1923,7 +1924,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
 }
 
 
-/* A subroutine of fold_stmt_r.  EXPR is a PLUS_EXPR.
+/* A subroutine of fold_stmt_r.  EXPR is a POINTER_PLUS_EXPR.
 
    A quaint feature extant in our address arithmetic is that there
    can be hidden type changes here.  The type of the result need
@@ -1932,7 +1933,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
    What we're after here is an expression of the form
        (T *)(&array + const)
    where the cast doesn't actually exist, but is implicit in the
-   type of the PLUS_EXPR.  We'd like to turn this into
+   type of the POINTER_PLUS_EXPR.  We'd like to turn this into
        &array[x]
    which may be able to propagate further.  */
 
@@ -1944,18 +1945,9 @@ maybe_fold_stmt_addition (tree expr)
   tree ptr_type = TREE_TYPE (expr);
   tree ptd_type;
   tree t;
-  bool subtract = (TREE_CODE (expr) == MINUS_EXPR);
 
-  /* We're only interested in pointer arithmetic.  */
-  if (!POINTER_TYPE_P (ptr_type))
-    return NULL_TREE;
-  /* Canonicalize the integral operand to op1.  */
-  if (INTEGRAL_TYPE_P (TREE_TYPE (op0)))
-    {
-      if (subtract)
-       return NULL_TREE;
-      t = op0, op0 = op1, op1 = t;
-    }
+  gcc_assert (TREE_CODE (expr) == POINTER_PLUS_EXPR);
+
   /* It had better be a constant.  */
   if (TREE_CODE (op1) != INTEGER_CST)
     return NULL_TREE;
@@ -2001,32 +1993,11 @@ maybe_fold_stmt_addition (tree expr)
       array_idx = int_const_binop (MULT_EXPR, array_idx, elt_size, 0);
 
       /* Update the operands for the next round, or for folding.  */
-      /* If we're manipulating unsigned types, then folding into negative
-        values can produce incorrect results.  Particularly if the type
-        is smaller than the width of the pointer.  */
-      if (subtract
-         && TYPE_UNSIGNED (TREE_TYPE (op1))
-         && tree_int_cst_lt (array_idx, op1))
-       return NULL;
-      op1 = int_const_binop (subtract ? MINUS_EXPR : PLUS_EXPR,
+      op1 = int_const_binop (PLUS_EXPR,
                             array_idx, op1, 0);
-      subtract = false;
       op0 = array_obj;
     }
 
-  /* If we weren't able to fold the subtraction into another array reference,
-     canonicalize the integer for passing to the array and component ref
-     simplification functions.  */
-  if (subtract)
-    {
-      if (TYPE_UNSIGNED (TREE_TYPE (op1)))
-       return NULL;
-      op1 = fold_unary (NEGATE_EXPR, TREE_TYPE (op1), op1);
-      /* ??? In theory fold should always produce another integer.  */
-      if (op1 == NULL || TREE_CODE (op1) != INTEGER_CST)
-       return NULL;
-    }
-
   ptd_type = TREE_TYPE (ptr_type);
 
   /* At which point we can try some of the same things as for indirects.  */
@@ -2116,8 +2087,7 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
         recompute_tree_invariant_for_addr_expr (expr);
       return NULL_TREE;
 
-    case PLUS_EXPR:
-    case MINUS_EXPR:
+    case POINTER_PLUS_EXPR:
       t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
       if (t)
        return t;
index 967a824e9c7787d46300741665e1b01d5e46a725..29ee8887230f1864fc4cec19215dd3052124a08a 100644 (file)
@@ -504,20 +504,6 @@ forward_propagate_addr_into_variable_array_index (tree offset,
 {
   tree index;
 
-  /* The offset must be defined by a simple GIMPLE_MODIFY_STMT statement.  */
-  if (TREE_CODE (offset) != GIMPLE_MODIFY_STMT)
-    return false;
-
-  /* The RHS of the statement which defines OFFSET must be a gimple
-     cast of another SSA_NAME.  */
-  offset = GIMPLE_STMT_OPERAND (offset, 1);
-  if (!is_gimple_cast (offset))
-    return false;
-
-  offset = TREE_OPERAND (offset, 0);
-  if (TREE_CODE (offset) != SSA_NAME)
-    return false;
-
   /* Try to find an expression for a proper index.  This is either
      a multiplication expression by the element size or just the
      ssa name we came along in case the element size is one.  */
@@ -525,14 +511,19 @@ forward_propagate_addr_into_variable_array_index (tree offset,
     index = offset;
   else
     {
+      /* Get the offset's defining statement.  */
       offset = SSA_NAME_DEF_STMT (offset);
 
-      /* The RHS of the statement which defines OFFSET must be a
-        multiplication of an object by the size of the array elements.  */
+      /* The statement which defines OFFSET before type conversion
+         must be a simple GIMPLE_MODIFY_STMT.  */
       if (TREE_CODE (offset) != GIMPLE_MODIFY_STMT)
        return false;
 
-      offset = GIMPLE_STMT_OPERAND (offset, 1);
+      /* The RHS of the statement which defines OFFSET must be a
+        multiplication of an object by the size of the array elements. 
+        This implicitly verifies that the size of the array elements
+        is constant.  */
+     offset = GIMPLE_STMT_OPERAND (offset, 1);
       if (TREE_CODE (offset) != MULT_EXPR
          || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
          || !simple_cst_equal (TREE_OPERAND (offset, 1),
@@ -642,12 +633,12 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
       || !integer_zerop (TREE_OPERAND (array_ref, 1)))
     return false;
 
-  /* If the use of the ADDR_EXPR must be a PLUS_EXPR, or else there
+  /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
      is nothing to do. */
-  if (TREE_CODE (rhs) != PLUS_EXPR)
+  if (TREE_CODE (rhs) != POINTER_PLUS_EXPR)
     return false;
 
-  /* Try to optimize &x[0] + C where C is a multiple of the size
+  /* Try to optimize &x[0] p+ C where C is a multiple of the size
      of the elements in X into &x[C/element size].  */
   if (TREE_OPERAND (rhs, 0) == name
       && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
@@ -671,7 +662,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
        }
     }
 
-  /* Try to optimize &x[0] + OFFSET where OFFSET is defined by
+  /* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by
      converting a multiplication of an index by the size of the
      array elements, then the result is converted into the proper
      type for the arithmetic.  */
@@ -682,24 +673,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
       && lang_hooks.types_compatible_p (TREE_TYPE (name), TREE_TYPE (rhs)))
     {
       bool res;
-      tree offset_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1));
       
-      res = forward_propagate_addr_into_variable_array_index (offset_stmt,
-                                                             def_rhs, use_stmt);
-      return res;
-    }
-             
-  /* Same as the previous case, except the operands of the PLUS_EXPR
-     were reversed.  */
-  if (TREE_OPERAND (rhs, 1) == name
-      && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
-      /* Avoid problems with IVopts creating PLUS_EXPRs with a
-        different type than their operands.  */
-      && lang_hooks.types_compatible_p (TREE_TYPE (name), TREE_TYPE (rhs)))
-    {
-      bool res;
-      tree offset_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
-      res = forward_propagate_addr_into_variable_array_index (offset_stmt,
+      res = forward_propagate_addr_into_variable_array_index (TREE_OPERAND (rhs, 1),
                                                              def_rhs, use_stmt);
       return res;
     }
index 326c4dbcf7926387387a68011ec87f657b413e6b..7337d0213f3d0b15a415438a495d1d28015794ae 100644 (file)
@@ -755,7 +755,7 @@ static tree
 determine_base_object (tree expr)
 {
   enum tree_code code = TREE_CODE (expr);
-  tree base, obj, op0, op1;
+  tree base, obj;
 
   /* If this is a pointer casted to any type, we need to determine
      the base object for the pointer; so handle conversions before
@@ -785,20 +785,13 @@ determine_base_object (tree expr)
       return fold_convert (ptr_type_node,
                           build_fold_addr_expr (base));
 
+    case POINTER_PLUS_EXPR:
+      return determine_base_object (TREE_OPERAND (expr, 0));
+
     case PLUS_EXPR:
     case MINUS_EXPR:
-      op0 = determine_base_object (TREE_OPERAND (expr, 0));
-      op1 = determine_base_object (TREE_OPERAND (expr, 1));
-      
-      if (!op1)
-       return op0;
-
-      if (!op0)
-       return (code == PLUS_EXPR
-               ? op1
-               : fold_build1 (NEGATE_EXPR, ptr_type_node, op1));
-
-      return fold_build2 (code, ptr_type_node, op0, op1);
+      /* Pointer addition is done solely using POINTER_PLUS_EXPR.  */
+      gcc_unreachable ();
 
     default:
       return fold_convert (ptr_type_node, expr);
@@ -3100,9 +3093,9 @@ force_expr_to_var_cost (tree expr)
       symbol_cost = computation_cost (addr) + 1;
 
       address_cost
-       = computation_cost (build2 (PLUS_EXPR, type,
+       = computation_cost (build2 (POINTER_PLUS_EXPR, type,
                                    addr,
-                                   build_int_cst (type, 2000))) + 1;
+                                   build_int_cst (sizetype, 2000))) + 1;
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "force_expr_to_var_cost:\n");
@@ -3141,6 +3134,7 @@ force_expr_to_var_cost (tree expr)
 
   switch (TREE_CODE (expr))
     {
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
@@ -3169,6 +3163,7 @@ force_expr_to_var_cost (tree expr)
   mode = TYPE_MODE (TREE_TYPE (expr));
   switch (TREE_CODE (expr))
     {
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
       cost = add_cost (mode);
index a1d06911d6b93ff164ae29717e78d4a271d3f3e3..3354fdea6df5e73044805fc1fcd254d242656124 100644 (file)
@@ -96,7 +96,13 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
            }
        }
     }
-
+  if (POINTER_TYPE_P (TREE_TYPE (base)))
+    {
+      step = fold_convert (sizetype, step);
+      if (incr_op == MINUS_EXPR)
+       step = fold_build1 (NEGATE_EXPR, sizetype, step);
+      incr_op = POINTER_PLUS_EXPR;
+    }
   /* Gimplify the step if necessary.  We put the computations in front of the
      loop (i.e. the step should be loop invariant).  */
   step = force_gimple_operand (step, &stmts, true, var);
index 11e90a791b1a0190c72718cd92c3fa79e8afe233..966e52b06b395282881e6a02e1dce12d51a9b9bb 100644 (file)
@@ -85,6 +85,7 @@ split_to_var_and_offset (tree expr, tree *var, mpz_t offset)
       /* Fallthru.  */
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
       op0 = TREE_OPERAND (expr, 0);
       op1 = TREE_OPERAND (expr, 1);
 
@@ -678,12 +679,15 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
   mpz_t mmod;
   tree assumption = boolean_true_node, bound, noloop;
   bool ret = false;
+  tree type1 = type;
+  if (POINTER_TYPE_P (type))
+    type1 = sizetype;
 
   if (TREE_CODE (mod) != INTEGER_CST)
     return false;
   if (integer_nonzerop (mod))
     mod = fold_build2 (MINUS_EXPR, niter_type, step, mod);
-  tmod = fold_convert (type, mod);
+  tmod = fold_convert (type1, mod);
 
   mpz_init (mmod);
   mpz_set_double_int (mmod, tree_to_double_int (mod), true);
@@ -697,7 +701,7 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
       if (!iv1->no_overflow && !integer_zerop (mod))
        {
          bound = fold_build2 (MINUS_EXPR, type,
-                              TYPE_MAX_VALUE (type), tmod);
+                              TYPE_MAX_VALUE (type1), tmod);
          assumption = fold_build2 (LE_EXPR, boolean_type_node,
                                    iv1->base, bound);
          if (integer_zerop (assumption))
@@ -708,7 +712,7 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
       else
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
                              iv0->base,
-                             fold_build2 (PLUS_EXPR, type,
+                             fold_build2 (PLUS_EXPR, type1,
                                           iv1->base, tmod));
     }
   else
@@ -718,8 +722,8 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
         iv0->base - MOD <= iv1->base. */
       if (!iv0->no_overflow && !integer_zerop (mod))
        {
-         bound = fold_build2 (PLUS_EXPR, type,
-                              TYPE_MIN_VALUE (type), tmod);
+         bound = fold_build2 (PLUS_EXPR, type1,
+                              TYPE_MIN_VALUE (type1), tmod);
          assumption = fold_build2 (GE_EXPR, boolean_type_node,
                                    iv0->base, bound);
          if (integer_zerop (assumption))
@@ -729,7 +733,7 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
        noloop = boolean_false_node;
       else
        noloop = fold_build2 (GT_EXPR, boolean_type_node,
-                             fold_build2 (MINUS_EXPR, type,
+                             fold_build2 (MINUS_EXPR, type1,
                                           iv0->base, tmod),
                              iv1->base);
     }
@@ -830,7 +834,7 @@ assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1,
                      struct tree_niter_desc *niter, bounds *bnds)
 {
   tree assumption = boolean_true_node, bound, diff;
-  tree mbz, mbzl, mbzr;
+  tree mbz, mbzl, mbzr, type1;
   bool rolls_p, no_overflow_p;
   double_int dstep;
   mpz_t mstep, max;
@@ -888,21 +892,25 @@ assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1,
 
   if (rolls_p && no_overflow_p)
     return;
+  
+  type1 = type;
+  if (POINTER_TYPE_P (type))
+    type1 = sizetype;
 
   /* Now the hard part; we must formulate the assumption(s) as expressions, and
      we must be careful not to introduce overflow.  */
 
   if (integer_nonzerop (iv0->step))
     {
-      diff = fold_build2 (MINUS_EXPR, type,
-                         iv0->step, build_int_cst (type, 1));
+      diff = fold_build2 (MINUS_EXPR, type1,
+                         iv0->step, build_int_cst (type1, 1));
 
       /* We need to know that iv0->base >= MIN + iv0->step - 1.  Since
         0 address never belongs to any object, we can assume this for
         pointers.  */
       if (!POINTER_TYPE_P (type))
        {
-         bound = fold_build2 (PLUS_EXPR, type,
+         bound = fold_build2 (PLUS_EXPR, type1,
                               TYPE_MIN_VALUE (type), diff);
          assumption = fold_build2 (GE_EXPR, boolean_type_node,
                                    iv0->base, bound);
@@ -910,24 +918,24 @@ assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1,
 
       /* And then we can compute iv0->base - diff, and compare it with
         iv1->base.  */      
-      mbzl = fold_build2 (MINUS_EXPR, type, iv0->base, diff);
+      mbzl = fold_build2 (MINUS_EXPR, type1, iv0->base, diff);
       mbzr = iv1->base;
     }
   else
     {
-      diff = fold_build2 (PLUS_EXPR, type,
-                         iv1->step, build_int_cst (type, 1));
+      diff = fold_build2 (PLUS_EXPR, type1,
+                         iv1->step, build_int_cst (type1, 1));
 
       if (!POINTER_TYPE_P (type))
        {
-         bound = fold_build2 (PLUS_EXPR, type,
+         bound = fold_build2 (PLUS_EXPR, type1,
                               TYPE_MAX_VALUE (type), diff);
          assumption = fold_build2 (LE_EXPR, boolean_type_node,
                                    iv1->base, bound);
        }
 
       mbzl = iv0->base;
-      mbzr = fold_build2 (MINUS_EXPR, type, iv1->base, diff);
+      mbzr = fold_build2 (MINUS_EXPR, type1, iv1->base, diff);
     }
 
   if (!integer_nonzerop (assumption))
@@ -1062,6 +1070,9 @@ number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
                         bounds *bnds)
 {
   tree assumption;
+  tree type1 = type;
+  if (POINTER_TYPE_P (type))
+    type1 = sizetype;
 
   /* Say that IV0 is the control variable.  Then IV0 <= IV1 iff
      IV0 < IV1 + 1, assuming that IV1 is not equal to the greatest
@@ -1072,10 +1083,10 @@ number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
     {
       if (integer_nonzerop (iv0->step))
        assumption = fold_build2 (NE_EXPR, boolean_type_node,
-                                 iv1->base, TYPE_MAX_VALUE (type));
+                                 iv1->base, TYPE_MAX_VALUE (type1));
       else
        assumption = fold_build2 (NE_EXPR, boolean_type_node,
-                                 iv0->base, TYPE_MIN_VALUE (type));
+                                 iv0->base, TYPE_MIN_VALUE (type1));
 
       if (integer_zerop (assumption))
        return false;
@@ -1085,13 +1096,13 @@ number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
     }
 
   if (integer_nonzerop (iv0->step))
-    iv1->base = fold_build2 (PLUS_EXPR, type,
-                            iv1->base, build_int_cst (type, 1));
+    iv1->base = fold_build2 (PLUS_EXPR, type1,
+                            iv1->base, build_int_cst (type1, 1));
   else
-    iv0->base = fold_build2 (MINUS_EXPR, type,
-                            iv0->base, build_int_cst (type, 1));
+    iv0->base = fold_build2 (MINUS_EXPR, type1,
+                            iv0->base, build_int_cst (type1, 1));
 
-  bounds_add (bnds, double_int_one, type);
+  bounds_add (bnds, double_int_one, type1);
 
   return number_of_iterations_lt (type, iv0, iv1, niter, never_infinite, bnds);
 }
@@ -1433,7 +1444,8 @@ expand_simple_operations (tree expr)
       && !is_gimple_min_invariant (e)
       /* And increments and decrements by a constant are simple.  */
       && !((TREE_CODE (e) == PLUS_EXPR
-           || TREE_CODE (e) == MINUS_EXPR)
+           || TREE_CODE (e) == MINUS_EXPR
+           || TREE_CODE (e) == POINTER_PLUS_EXPR)
           && is_gimple_min_invariant (TREE_OPERAND (e, 1))))
     return expr;
 
@@ -2205,6 +2217,7 @@ derive_constant_upper_bound (tree val)
       return bnd;
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
       op0 = TREE_OPERAND (val, 0);
       op1 = TREE_OPERAND (val, 1);
index a4c2d0897953059963f13d0acd7c874316be5c92..4c965d19eb5185fafa0643675a73b437e279173a 100644 (file)
@@ -375,7 +375,7 @@ idx_analyze_ref (tree base, tree *index, void *data)
     return false;
   istep = int_cst_value (step);
 
-  if (TREE_CODE (ibase) == PLUS_EXPR
+  if (TREE_CODE (ibase) == POINTER_PLUS_EXPR
       && cst_and_fits_in_hwi (TREE_OPERAND (ibase, 1)))
     {
       idelta = int_cst_value (TREE_OPERAND (ibase, 1));
@@ -891,8 +891,8 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
     {
       /* Determine the address to prefetch.  */
       delta = (ahead + ap * ref->prefetch_mod) * ref->group->step;
-      addr = fold_build2 (PLUS_EXPR, ptr_type_node,
-                         addr_base, build_int_cst (ptr_type_node, delta));
+      addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
+                         addr_base, size_int (delta));
       addr = force_gimple_operand_bsi (&bsi, unshare_expr (addr), true, NULL);
 
       /* Create the prefetch instruction.  */
index c5dbf5c5d7f4fd490dff754abda62a4c14bf9374..f1abf37308ae5fe7fae1aa9f12b5663585338949 100644 (file)
@@ -3293,23 +3293,17 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
   VEC (ce_s, heap) *temp = NULL;
   unsigned int rhsoffset = 0;
 
-  if (TREE_CODE (expr) != PLUS_EXPR
-      && TREE_CODE (expr) != MINUS_EXPR)
+  if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
     return false;
 
   op0 = TREE_OPERAND (expr, 0);
   op1 = TREE_OPERAND (expr, 1);
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (op0)));
 
   get_constraint_for (op0, &temp);
-  if (POINTER_TYPE_P (TREE_TYPE (op0))
-      && TREE_CODE (op1) == INTEGER_CST
-      && TREE_CODE (expr) == PLUS_EXPR)
-    {
-      rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
-    }
-  else
-    return false;
 
+  if (TREE_CODE (op1) == INTEGER_CST)
+    rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
 
   for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++)
     for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++)
index 821440dafde14bc6c2d276d98ce9b4a68b9749e4..9c9206deb5a84cf9c9bd545ff12f5e4b9e63ca18 100644 (file)
@@ -949,13 +949,15 @@ tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
   else if (INTEGRAL_TYPE_P (inner_type)
            && INTEGRAL_TYPE_P (outer_type)
           && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
-          && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)
-          && simple_cst_equal (TYPE_MAX_VALUE (inner_type), TYPE_MAX_VALUE (outer_type))
-          && simple_cst_equal (TYPE_MIN_VALUE (inner_type), TYPE_MIN_VALUE (outer_type)))
+          && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
     {
+      tree min_inner = fold_convert (outer_type, TYPE_MIN_VALUE (inner_type));
+      tree max_inner = fold_convert (outer_type, TYPE_MAX_VALUE (inner_type));
       bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
       bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
-      if (first_boolean == second_boolean)
+      if (simple_cst_equal (max_inner, TYPE_MAX_VALUE (outer_type))
+         && simple_cst_equal (min_inner, TYPE_MIN_VALUE (outer_type))
+         && first_boolean == second_boolean)
        return true;
     }
 
index 44227e8b0f9fb9ef8efbe533e01a0344d702bcbf..0c0d259705b46ef903a7bab9788232461e00240d 100644 (file)
@@ -171,7 +171,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
          continue;
        }
 
-      if (TREE_CODE (rhs) == PLUS_EXPR
+      if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
+          || TREE_CODE (rhs) == PLUS_EXPR)
          && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
          && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
          && host_integerp (TREE_OPERAND (rhs, 1), 1))
@@ -229,7 +230,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
          continue;
        }
 
-      if (TREE_CODE (rhs) == PLUS_EXPR
+      if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
+          || TREE_CODE (rhs) == PLUS_EXPR)
          && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
          && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
          && host_integerp (TREE_OPERAND (rhs, 1), 1))
@@ -447,10 +449,11 @@ check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs)
   if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
     return;
 
-  if ((TREE_CODE (rhs) == PLUS_EXPR
-       && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
-      || TREE_CODE (rhs) == NOP_EXPR
-      || TREE_CODE (rhs) == CONVERT_EXPR)
+ if (((TREE_CODE (rhs) == POINTER_PLUS_EXPR
+       || TREE_CODE (rhs) == PLUS_EXPR)
+      && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
+     || TREE_CODE (rhs) == NOP_EXPR
+     || TREE_CODE (rhs) == CONVERT_EXPR)
     rhs = TREE_OPERAND (rhs, 0);
 
   if (TREE_CODE (rhs) != SSA_NAME
@@ -555,7 +558,7 @@ check_all_va_list_escapes (struct stdarg_info *si)
                     other_ap_temp = (some_type *) ap_temp;
                     ap = ap_temp;
                     statements.  */
-                 if ((TREE_CODE (rhs) == PLUS_EXPR
+                 if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
                       && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
                      || TREE_CODE (rhs) == NOP_EXPR
                      || TREE_CODE (rhs) == CONVERT_EXPR)
index c2e7d332cee56f102ebcc7d73f2a5dbc0b6b4f75..bf13f537ede092c93d741611dae9bc4c9083a075 100644 (file)
@@ -347,7 +347,7 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
       *ass_var = dest;
       return true;
 
-      /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR).  */
+      /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR, POINTER_PLUS_EXPR).  */
 
     default:
       return false;
index 477fc883b7d0285fcbe5b3fe002ad40ba3ce30ec..d9152f95a6bfc5640e93f9ecd31a21118d1dbf27 100644 (file)
@@ -635,6 +635,7 @@ vect_create_addr_base_for_vector_ref (tree stmt,
 
   /* Create base_offset */
   base_offset = size_binop (PLUS_EXPR, base_offset, init);
+  base_offset = fold_convert (sizetype, base_offset);
   dest = create_tmp_var (TREE_TYPE (base_offset), "base_off");
   add_referenced_var (dest);
   base_offset = force_gimple_operand (base_offset, &new_stmt, false, dest);  
@@ -642,7 +643,7 @@ vect_create_addr_base_for_vector_ref (tree stmt,
 
   if (offset)
     {
-      tree tmp = create_tmp_var (TREE_TYPE (base_offset), "offset");
+      tree tmp = create_tmp_var (sizetype, "offset");
       tree step; 
 
       /* For interleaved access step we divide STEP by the size of the
@@ -663,7 +664,7 @@ vect_create_addr_base_for_vector_ref (tree stmt,
     }
   
   /* base + base_offset */
-  addr_base = fold_build2 (PLUS_EXPR, TREE_TYPE (data_ref_base), data_ref_base,
+  addr_base = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (data_ref_base), data_ref_base,
                           base_offset);
 
   vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info));
@@ -894,14 +895,14 @@ bump_vector_ptr (tree dataref_ptr, tree ptr_incr, block_stmt_iterator *bsi,
   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
   tree vptr_type = TREE_TYPE (dataref_ptr);
   tree ptr_var = SSA_NAME_VAR (dataref_ptr);
-  tree update = fold_convert (vptr_type, TYPE_SIZE_UNIT (vectype));
+  tree update = TYPE_SIZE_UNIT (vectype);
   tree incr_stmt;
   ssa_op_iter iter;
   use_operand_p use_p;
   tree new_dataref_ptr;
 
   incr_stmt = build_gimple_modify_stmt (ptr_var,
-                                       build2 (PLUS_EXPR, vptr_type,
+                                       build2 (POINTER_PLUS_EXPR, vptr_type,
                                                dataref_ptr, update));
   new_dataref_ptr = make_ssa_name (ptr_var, incr_stmt);
   GIMPLE_STMT_OPERAND (incr_stmt, 0) = new_dataref_ptr;
@@ -5270,12 +5271,21 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
       init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, 
                                                               loop->num));
 
-      ni = fold_build2 (PLUS_EXPR, TREE_TYPE (init_expr),
-                       fold_build2 (MULT_EXPR, TREE_TYPE (init_expr),
-                                    fold_convert (TREE_TYPE (init_expr), 
-                                                  niters), 
-                                    step_expr),
-                       init_expr);
+      if (POINTER_TYPE_P (TREE_TYPE (init_expr)))
+       ni = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (init_expr), 
+                         init_expr, 
+                         fold_convert (sizetype, 
+                                       fold_build2 (MULT_EXPR, TREE_TYPE (niters),
+                                                    niters, step_expr)));
+      else
+       ni = fold_build2 (PLUS_EXPR, TREE_TYPE (init_expr),
+                         fold_build2 (MULT_EXPR, TREE_TYPE (init_expr),
+                                      fold_convert (TREE_TYPE (init_expr),
+                                                    niters),
+                                      step_expr),
+                         init_expr);
+
+
 
       var = create_tmp_var (TREE_TYPE (init_expr), "tmp");
       add_referenced_var (var);
@@ -5473,7 +5483,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
   
       /* Create:  byte_misalign = addr & (vectype_size - 1)  */
       byte_misalign = 
-        fold_build2 (BIT_AND_EXPR, type, start_addr, vectype_size_minus_1);
+        fold_build2 (BIT_AND_EXPR, type, fold_convert (type, start_addr), vectype_size_minus_1);
   
       /* Create:  elem_misalign = byte_misalign / element_size  */
       elem_misalign =
index 2a51de7ba43bce43be90b1e67a4be1ef179e5d03..8fba946ff6adeabdf6b8a5c6344bfca637726772 100644 (file)
@@ -766,6 +766,10 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
      both integers.  */
   gcc_assert (POINTER_TYPE_P (TREE_TYPE (val1))
              == POINTER_TYPE_P (TREE_TYPE (val2)));
+  /* Convert the two values into the same type.  This is needed because
+     sizetype causes sign extension even for unsigned types.  */
+  val2 = fold_convert (TREE_TYPE (val1), val2);
+  STRIP_USELESS_TYPE_CONVERSION (val2);
 
   if ((TREE_CODE (val1) == SSA_NAME
        || TREE_CODE (val1) == PLUS_EXPR
@@ -1494,10 +1498,14 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
                    }
                  max = negative_overflow_infinity (TREE_TYPE (var_vr->min));
                }
-             else
+             else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
                max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
                                   anti_min,
                                   build_int_cst (TREE_TYPE (var_vr->min), 1));
+             else
+               max = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (var_vr->min),
+                                  anti_min,
+                                  size_int (-1));
              min = real_min;
              set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
            }
@@ -1693,6 +1701,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
      meaningful way.  Handle only arithmetic operations.  */
   if (code != PLUS_EXPR
       && code != MINUS_EXPR
+      && code != POINTER_PLUS_EXPR
       && code != MULT_EXPR
       && code != TRUNC_DIV_EXPR
       && code != FLOOR_DIV_EXPR
@@ -1763,26 +1772,30 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
       || POINTER_TYPE_P (TREE_TYPE (op0))
       || POINTER_TYPE_P (TREE_TYPE (op1)))
     {
-      /* For pointer types, we are really only interested in asserting
-        whether the expression evaluates to non-NULL.  FIXME, we used
-        to gcc_assert (code == PLUS_EXPR || code == MINUS_EXPR), but
-        ivopts is generating expressions with pointer multiplication
-        in them.  */
-      if (code == PLUS_EXPR)
+      if (code == MIN_EXPR || code == MAX_EXPR)
        {
-         if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
+         /* For MIN/MAX expressions with pointers, we only care about
+            nullness, if both are non null, then the result is nonnull.
+            If both are null, then the result is null. Otherwise they
+            are varying.  */
+         if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1))
            set_value_range_to_nonnull (vr, TREE_TYPE (expr));
          else if (range_is_null (&vr0) && range_is_null (&vr1))
            set_value_range_to_null (vr, TREE_TYPE (expr));
          else
            set_value_range_to_varying (vr);
+
+         return;
        }
+      gcc_assert (code == POINTER_PLUS_EXPR);
+      /* For pointer types, we are really only interested in asserting
+        whether the expression evaluates to non-NULL.  */
+      if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
+       set_value_range_to_nonnull (vr, TREE_TYPE (expr));
+      else if (range_is_null (&vr0) && range_is_null (&vr1))
+       set_value_range_to_null (vr, TREE_TYPE (expr));
       else
-       {
-         /* Subtracting from a pointer, may yield 0, so just drop the
-            resulting range to varying.  */
-         set_value_range_to_varying (vr);
-       }
+       set_value_range_to_varying (vr);
 
       return;
     }
index 2560c8f72a47001314648a5f1a68380ce9e071b3..45e53ccda4b4540fe43a40931aeb9a45dc21841a 100644 (file)
@@ -3069,6 +3069,16 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
   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);
+
+  if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
+    gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
+               && TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
+               && tree_ssa_useless_type_conversion_1 (sizetype,
+                                                      TREE_TYPE (arg1)));
+
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
 
index d4038322bcd812cee8856111e13da180630c769d..d46499ab1e64716da393050d5cea17c23cd07d53 100644 (file)
@@ -612,6 +612,10 @@ DEFTREECODE (PLUS_EXPR, "plus_expr", tcc_binary, 2)
 DEFTREECODE (MINUS_EXPR, "minus_expr", tcc_binary, 2)
 DEFTREECODE (MULT_EXPR, "mult_expr", tcc_binary, 2)
 
+/* Pointer addition.  The first operand is always a pointer and the
+   second operand is an integer of type sizetype.  */
+DEFTREECODE (POINTER_PLUS_EXPR, "pointer_plus_expr", tcc_binary, 2)
+
 /* Division for integer result that rounds the quotient toward zero.  */
 DEFTREECODE (TRUNC_DIV_EXPR, "trunc_div_expr", tcc_binary, 2)
 
index ec7fc00e8356a35e512e1ba2602d79d44515d9f3..511bf89e6ec080379566cb705581eff18daff76a 100644 (file)
@@ -2810,6 +2810,7 @@ const_hash_1 (const tree exp)
       return hi;
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
       return (const_hash_1 (TREE_OPERAND (exp, 0)) * 9
              + const_hash_1 (TREE_OPERAND (exp, 1)));
@@ -2956,6 +2957,7 @@ compare_constant (const tree t1, const tree t2)
       }
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
     case RANGE_EXPR:
       return (compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
@@ -3010,6 +3012,7 @@ copy_constant (tree exp)
                            copy_constant (TREE_IMAGPART (exp)));
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
       return build2 (TREE_CODE (exp), TREE_TYPE (exp),
                     copy_constant (TREE_OPERAND (exp, 0)),
@@ -3901,6 +3904,7 @@ compute_reloc_for_constant (tree exp)
       break;
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
       reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
       reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1));
       break;
@@ -3970,6 +3974,7 @@ output_addressed_constants (tree exp)
       break;
 
     case PLUS_EXPR:
+    case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
       output_addressed_constants (TREE_OPERAND (exp, 1));
       /* Fall through.  */
@@ -4147,6 +4152,7 @@ initializer_constant_valid_p (tree value, tree endtype)
       }
       break;
 
+    case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       if (! INTEGRAL_TYPE_P (endtype)
          || TYPE_PRECISION (endtype) >= POINTER_SIZE)