diff options
author | Diego Novillo <dnovillo@gcc.gnu.org> | 2012-08-14 21:56:07 -0400 |
---|---|---|
committer | Diego Novillo <dnovillo@gcc.gnu.org> | 2012-08-14 21:56:07 -0400 |
commit | 0823efedd0fb8669b7e840954bc54c3b2cf08d67 (patch) | |
tree | e43578612b8b33743caa0788b5bb5bb5175b0ebe | |
parent | 4ce8f1176c0e4bc675a72860e5e837e8d21652d9 (diff) | |
download | gcc-0823efedd0fb8669b7e840954bc54c3b2cf08d67.zip gcc-0823efedd0fb8669b7e840954bc54c3b2cf08d67.tar.gz gcc-0823efedd0fb8669b7e840954bc54c3b2cf08d67.tar.bz2 |
backport: As described in http://gcc.gnu.org/ml/gcc/2012-08/msg00015.html...
Merge from cxx-conversion branch (http://gcc.gnu.org/wiki/cxx-conversion).
As described in http://gcc.gnu.org/ml/gcc/2012-08/msg00015.html, this patch
changes the default bootstrap process so that stage 1 always builds with a C++
compiler.
Other than the bootstrap change, the patch makes no functional changes to the
compiler. Everything should build as it does now in trunk. The main
changes in this patch are:
1- Configuration changes.
2- Re-write of VEC.
3- Re-write of gengtype to support C++ templates and
user-provided marking functions.
4- New hash table class.
5- Re-write double_int.
6- Implement tree macros as inline functions so they can be
called from gdb.
As discussed before, several of these changes do not fully change
the call sites to use the new APIs.
The bootstrap changes have already been tested on a wide range of
targets (http://gcc.gnu.org/wiki/CppBuildStatus). Additionally,
I have tested the merged trunk on: x86_64-unknown-linux-gnu,
mips64el-unknown-linux-gnu, powerpc64-unknown-linux-gnu,
i686-pc-linux-gnu, and ia64-unknown-linux-gnu.
ChangeLog
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch.
* Makefile.tpl (STAGE[+id+]_CXXFLAGS): Remove
POSTSTAGE1_CONFIGURE_FLAGS.
* Makefile.in: Regenerate.
* configure.ac (ENABLE_BUILD_WITH_CXX): Remove. Update all users.
Force C++ when bootstrapping.
* configure: Regenerate.
libcpp/ChangeLog
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch. Configury.
* Makefile.in: Remove all handlers of ENABLE_BUILD_WITH_CXX.
* configure.ac: Likewise.
* configure: Regenerate.
2012-08-14 Lawrence Crowl <crowl@google.com>
Merge from cxx-conversion branch. New C++ hash table.
* include/symtab.h (typedef struct ht hash_table): Change the typedef
name to cpp_hash_table. Update all users of the typedef.
gcc/ChangeLog
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch. Configury.
* configure.ac (CXX_FOR_BUILD): Define and substitute.
(BUILD_CXXFLAGS): Define.
Remove all handlers of ENABLE_BUILD_WITH_CXX.
Force all build to be with C++.
* Makefile.in (BUILD_CXXFLAGS): Use it.
Remove all handlers of ENABLE_BUILD_WITH_CXX.
* configure: Regenerate.
* config.in: Regenerate.
* doc/install.texi: Remove documentation for --enable-build-with-cxx
and --enable-build-poststage1-with-cxx.
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch. Re-implement VEC in C++.
* vec.c (vec_heap_free): Convert into a template function.
(vec_gc_o_reserve_1): Make extern.
(vec_gc_p_reserve): Remove.
(vec_gc_p_reserve_exact): Remove.
(vec_gc_o_reserve): Remove.
(vec_gc_o_reserve_exact): Remove.
(vec_heap_o_reserve_1): Make extern.
(vec_heap_p_reserve): Remove.
(vec_heap_p_reserve_exact): Remove.
(vec_heap_o_reserve): Remove.
(vec_heap_o_reserve_exact): Remove.
(vec_stack_p_reserve): Remove.
(vec_stack_p_reserve_exact): Remove.
* vec.h (VEC_CHECK_INFO, VEC_CHECK_DECL, VEC_CHECK_PASS,
VEC_ASSERT, VEC_ASSERT_FAIL, vec_assert_fail): Move earlier
in the file.
(VEC): Define to vec_t<T>.
(vec_allocation_t): Define.
(struct vec_prefix): Move earlier in the file.
(vec_t<T>): New template.
(DEF_VEC_I, DEF_VECL_ALLOC_I, DEF_VEC_P, DEF_VEC_ALLOC_P,
DEF_VEC_O, DEF_VEC_ALLOC_P, DEF_VEC_O, DEF_VEC_ALLOC_O,
DEF_VEC_ALLOC_P_STACK, DEF_VEC_ALLOC_O_STACK,
DEF_VEC_ALLOC_I_STACK): Expand to 'struct vec_swallow_trailing_semi'.
(DEF_VEC_A): Provide template instantiations for
GC/PCH markers that do not traverse the vector.
(vec_stack_p_reserve): Remove.
(vec_stack_p_reserve_exact): Remove.
(vec_stack_p_reserve_exact_1): Remove.
(vec_stack_o_reserve): Remove.
(vec_stack_o_reserve_exact): Remove.
(vec_stack_free): Re-write as a template function.
(vec_reserve): New template function.
(vec_reserve_exact): New template function.
(vec_heap_free): New template function if GATHER_STATISTICS is
defined. Otherwise, macro that expands to free().
(VEC_length_1): New template function.
(VEC_length): Call it.
(VEC_empty_1): New template function.
(VEC_empty): Call it.
(VEC_address_1): New template function.
(VEC_address): Call it.
(VEC_last_1): New template function.
(VEC_last): Call it. Change return type to T&.
Change all users that used VEC_Os.
(VEC_index_1): New template function.
(VEC_index): Call it. Return a T& instead of a T*.
Update all callers that were using VEC_O before.
(VEC_iterate_1): New template function.
(VEC_iterate): Call it.
(VEC_embedded_size_1): New template function.
(VEC_embedded_size): Call it.
(VEC_embedded_init_1): New template function.
(VEC_embedded_init): Call it.
(VEC_alloc_1): New template function.
(VEC_alloc): Call it. If A is 'stack', call XALLOCAVAR to
do the allocation.
(VEC_free_1): New template function.
(VEC_free): Call it.
(VEC_copy_1): New template function.
(VEC_copy): Call it.
(VEC_space_1): New template function
(VEC_space): Call it.
(VEC_reserve_1): New template function.
(VEC_reserve): Call it.
(VEC_reserve_exact_1): New template function.
(VEC_reserve_exact): Call it.
(VEC_splice_1): New template function.
(VEC_splice): Call it.
(VEC_safe_splice_1): New template function.
(VEC_safe_splice): Call it.
(VEC_quick_push_1): New template function. Create two overloads, one
accepting T, the other accepting T *. Update all callers
where T and T * are ambiguous.
(VEC_quick_push): Call it.
(VEC_safe_push_1): New template function. Create two overloads, one
accepting T, the other accepting T *. Update all callers
where T and T * are ambiguous.
(VEC_safe_push): Call it.
(VEC_pop_1): New template function.
(VEC_pop): Call it.
(VEC_truncate_1): New template function.
(VEC_truncate): Call it.
(VEC_safe_grow_1): New template function.
(VEC_safe_grow): Call it.
(VEC_safe_grow_cleared_1): New template function.
(VEC_safe_grow_cleared): Call it.
(VEC_replace_1): New template function.
(VEC_replace): Call it. Always accept T instead of T*.
Update all callers that used VEC_Os.
(VEC_quick_insert_1): New template function.
(VEC_quick_insert): Call it.
(VEC_safe_insert_1): New template function.
(VEC_safe_insert): Call it.
(VEC_ordered_remove_1): New template function.
(VEC_ordered_remove): Call it.
(VEC_unordered_remove_1): New template function.
(VEC_unordered_remove): Call it.
(VEC_block_remove_1): New template function.
(VEC_block_remove): Call it.
(VEC_lower_bound_1): New template function.
(VEC_lower_bound): Call it.
(VEC_OP): Remove.
(DEF_VEC_FUNC_P): Remove.
(DEF_VEC_ALLOC_FUNC_P): Remove.
(DEF_VEC_NONALLOC_FUNCS_P): Remove.
(DEF_VEC_FUNC_O): Remove.
(DEF_VEC_ALLOC_FUNC_O): Remove.
(DEF_VEC_NONALLOC_FUNCS_O): Remove.
(DEF_VEC_ALLOC_FUNC_I): Remove.
(DEF_VEC_NONALLOC_FUNCS_I): Remove.
(DEF_VEC_ALLOC_FUNC_P_STACK): Remove.
(DEF_VEC_ALLOC_FUNC_O_STACK): Remove.
(DEF_VEC_ALLOC_FUNC_I_STACK): Remove.
(vec_reserve_exact): New template function.
* gengtype-lex.l (DEF_VEC_ALLOC_[IOP]/{EOID}): Remove.
* gengtype-parse.c (token_names): Remove DEF_VEC_ALLOC_[IOP].
(typedef_name): Emit vec_t<C1> instead of VEC_C1_C2.
(def_vec_alloc): Remove. Update all callers.
* gengtype.c (filter_type_name): New.
(output_mangled_typename): Call it.
(write_func_for_structure): Likewise.
(write_types): Likewise.
(write_root): Likewise.
(write_typed_alloc_def): Likewise.
(note_def_vec): Emit vec_t<TYPE_NAME> instead of VEC_TYPE_NAME_base.
(note_def_vec_alloc): Remove.
* gengtype.h (note_def_vec_alloc): Remove.
(DEFVEC_ALLOC): Remove token code.
* df-scan.c (df_bb_verify): Remove call to df_free_collection_rec
inside the insn traversal loop.
* gimplify.c (gimplify_compound_lval): Rename STACK to EXPR_STACK.
* ipa-inline.c (inline_small_functions): Rename HEAP to EDGE_HEAP.
* reg-stack.c (stack): Rename to STACK_PTR. Update all users.
* tree-vrp.c (stack): Rename to EQUIV_STACK. Update all users.
* config/bfin/bfin.c (hwloop_optimize): Update some calls to
VEC_* for vectors of non-pointers.
* config/c6x/c6x.c (try_rename_operands): Likewise.
(reshuffle_units): Likewise.
* config/mips/mips.c (mips_multi_start): Likewise.
(mips_multi_add): Likewise.
(mips_multi_copy_insn): Likewise.
(mips_multi_set_operand): Likewise.
* hw-doloop.c (discover_loop): Likewise.
(discover_loops): Likewise.
(reorg_loops): Likewise.
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch. C++ support in gengtype.
* coretypes.h (gt_pointer_operator): Move from ...
* ggc.h: ... here.
* doc/gty.texi: Document support for C++ templates and
user-provided markers.
* gcc/gengtype-lex.l: Update copyright year.
Remove support for recognizing DEF_VEC_O, DEF_VEC_P and
DEFVEC_I.
* gengtype-parse.c: Update copyright year.
(token_names): Remove DEF_VEC_O, DEF_VEC_P and DEF_VEC_I.
(require_template_declaration): New.
(typedef_name): Call it.
(type): Replace IS_UNION with KIND. Replace all users.
(def_vec): Remove. Update all users.
* gengtype-state.c (type_lineloc): Handle TYPE_USER_STRUCT.
(write_state_user_struct_type): New.
(write_state_type): Call it.
(read_state_user_struct_type): New.
(read_state_type): Call it.
* gengtype.c: Update copyright year.
(dump_pair): Move declaration to the top.
(dump_type): Likewise.
(dump_type_list): Likewise.
(dbgprint_count_type_at): Handle TYPE_USER_STRUCT.
(create_user_defined_type): New.
(resolve_typedef): Call it.
(new_structure): Replace argument ISUNION with KIND.
Change users to refer to KIND directly.
Update all callers.
(find_structure): Likewise.
(set_gc_used_type): Handle TYPE_USER_STRUCT.
(create_file): Update HDR to include new copyright year.
(struct walk_type_data): Add field IN_PTR_FIELD.
(output_mangled_typename): Handle TYPE_USER_STRUCT.
(walk_type): Set D->IN_PTR_FIELD when walking a TYPE_POINTER.
Clear it afterwards.
Handle TYPE_USER_STRUCT.
(write_types_process_field): Handle TYPE_USER_STRUCT.
(get_type_specifier): Move earlier in the file.
(write_type_decl): New.
(write_marker_function_name): New.
(write_user_func_for_structure_ptr): New.
(write_user_func_for_structure_body): New.
(write_user_marking_functions): New.
(write_func_for_structure): Call write_marker_function_name
and write_type_decl.
Do not call walk_type for TYPE_USER_STRUCT. Emit a call to the user
function directly.
Call write_user_marking_functions on TYPE_USER_STRUCTs.
(write_types_local_user_process_field): New.
(write_pch_user_walking_for_structure_body): New.
(write_pch_user_walking_functions): New.
(write_types_local_process_field): Handle TYPE_USER_STRUCT.
(write_local_func_for_structure): Do not call walk_type for
TYPE_USER_STRUCT. Instead, emit the call to gt_pch_nx directly.
Call write_pch_user_walking_functions for TYPE_USER_STRUCTs.
(write_root): Handle TYPE_USER_STRUCT.
(vec_prefix_type): Remove. Update all users.
(note_def_vec): Remove. Update all users.
(dump_typekind): Handle TYPE_USER_STRUCT.
(dump_type): Initialize SEEN_TYPES, if needed.
Handle TYPE_USER_STRUCT.
(dump_everything): Do not initialize SEEN_TYPES.
* gengtype.h: Update copyright year.
(enum typekind): Add TYPE_USER_STRUCT.
(union_or_struct_p): Rename from UNION_OR_STRUCT_P.
Convert into function.
Add an overload taking const_type_p.
Update all callers.
(new_structure): Change second field to type enum typekind.
Update all users.
(find_structure): Likewise.
(note_def_vec): Remove.
(DEFVEC_OP): Remove.
(DEFVEC_I): Remove.
* ggc-page.c (gt_ggc_mx): Add entry points for marking
'const char *&', 'unsigned char *&' and 'unsigned char&'.
* ggc-zone.c (gt_ggc_mx): Add entry points for marking
'const char *&' and 'unsigned char *&'.
* stringpool.c (gt_pch_nx): Add entry points for marking
'const char *&', 'unsigned char *&' and 'unsigned char&'.
Add an entry point for the overload taking arguments 'unsigned char
*', 'gt_pointer_operator' and 'void *'.
* vec.h (struct vec_prefix): Remove GTY marker.
(struct vec_t): Remove GTY((length)) attribute from field 'vec'.
(gt_ggc_mx (vec_t<T> *)): New template function.
(gt_pch_nx (vec_t<T> *)): New template function.
(gt_pch_nx (vec_t<T *> *, gt_pointer_operator, void *)): New template
function.
(gt_pch_nx (vec_t<T> *, gt_pointer_operator, void *)): New template
function.
* basic-block.h (struct edge_def): Mark GTY((user)).
Remove all GTY markers from fields.
(gt_ggc_mx): Declare.
(gt_pch_nx): Declare.
* tree-cfg.c (gt_ggc_mx): New.
(gt_pch_nx): New.
* gengtype-lex.l (USER_GTY): Add pattern for "user".
* gengtype-parse.c (option): Handle USER_GTY.
(opts_have): New.
(type): Call it.
If the keyword 'user' is used, do not walk the fields
of the structure.
* gengtype.h (USER_GTY): Add.
* doc/gty.texi: Update.
2012-08-14 Lawrence Crowl <crowl@google.com>
Merge cxx-conversion branch. Implement C++ hash table.
* hash-table.h: New. Implementation borrowed from libiberty/hashtab.c.
* hash-table.c: Likewise.
* tree-ssa-tail-merge.c: Include hash-table.h instead of hashtab.h.
(static htab_t same_succ_htab): Change type to hash_table;
move specification of helper functions from create call to declaration.
Change users to invoke member functions.
(same_succ_print_traverse): Make extern ssa_.... Change callers.
Remove void* casting.
(same_succ_hash): Likewise.
(same_succ_equal): Likewise.
(same_succ_delete): Likewise.
* tree-ssa-threadupdate.c: Include hash-table.h.
(struct local_info): Rename to ssa_local_info_t to avoid overloading
the type name local_info with the variable name local_info.
(static htab_t redirection_data): Change type to hash_table.
Move specification of helper functions from create call to declaration.
Change users to invoke member functions.
(redirection_data_hash): Make extern ssa_.... Change callers.
Remove void* casting.
(redirection_data_eq): Likewise.
(fix_duplicate_block_edges): Likewise.
(create_duplicates): Likewise.
(fixup_template_block): Likewise.
(redirect_edges): Likewise.
(lookup_redirection_data): Change types associated with the hash table
from void* to their actual type. Remove unnecessary casts.
* tree-ssa-ccp.c: Include hash-table.h.
(typedef gimple_htab): New. Uses hash_table. Replace specific uses
of htab_t with gimple_htab. Change users to invoke member functions.
Move specification of helper functions from create call to declaration.
* tree-ssa-coalesce.c: Include hash-table.h instead of hashtab.h.
(hash_ssa_name_by_var): Make extern. Remove void* casting.
(eq_ssa_name_by_var): Likewise.
(coalesce_ssa_name): Change type of local static htab_t ssa_name_hash
to hash_table. Change users to invoke member functions.
Move specification of helper functions from create call to declaration.
* coverage.c: Include hash-table.h instead of hashtab.h.
(static htab_t counts_hash): Change type to hash_table;
move specification of helper functions from create call to declaration.
Change users to invoke member functions.
(htab_counts_entry_hash): Make extern. Rename with coverage_... instead
of htab_... Remove void* casting.
(htab_counts_entry_eq): Likewise.
(htab_counts_entry_del): Likewise.
* tree-ssa-pre.c: Include hash-table.h instead of hashtab.h.
(static htab_t expression_to_id): Change type to hash_table.
Move specification of helper functions from create call to declaration.
Change users to invoke member functions.
(static htab_t phi_translate_table): Likewise.
(pre_expr_eq): Make extern ssa_.... Change callers.
Remove void* casting.
(pre_expr_hash): Likewise.
(expr_pred_trans_hash): Likewise.
(expr_pred_trans_eq): Likewise.
(alloc_expression_id): Change types associated with the hash table
from void* to their actual type. Remove unnecessary casts.
(lookup_expression_id): Likewise.
(phi_trans_lookup): Likewise.
(phi_trans_add): Likewise.
* stringpool.c: Rename uses of libcpp typedef hash_table to
cpp_hash_table.
* Makefile.in: Add hash-table.o to OBJS-libcommon-target.
Add $(HASH_TABLE_H). Add new dependences on $(HASH_TABLE_H).
2012-08-14 Lawrence Crowl <crowl@google.com>
Merge from cxx-conversion branch. Re-write double_int in C++.
* hash-table.h
(typedef double_int): Change to struct (POD).
(double_int::make): New overloads for int to double-int conversion.
(double_int::mask): New.
(double_int::max_value): New.
(double_int::min_value): New.
(double_int::operator ++): New.
(double_int::operator --): New.
(double_int::operator *=): New.
(double_int::operator +=): New.
(double_int::operator -=): New.
(double_int::to_signed): New.
(double_int::to_unsigned): New.
(double_int::fits_unsigned): New.
(double_int::fits_signed): New.
(double_int::fits): New.
(double_int::trailing_zeros): New.
(double_int::popcount): New.
(double_int::multiple_of): New.
(double_int::set_bit): New.
(double_int::mul_with_sign): New.
(double_int::operator * (binary)): New.
(double_int::operator + (binary)): New.
(double_int::operator - (binary)): New.
(double_int::operator - (unary)): New.
(double_int::operator ~ (unary)): New.
(double_int::operator & (binary)): New.
(double_int::operator | (binary)): New.
(double_int::operator ^ (binary)): New.
(double_int::and_not): New.
(double_int::lshift): New.
(double_int::rshift): New.
(double_int::alshift): New.
(double_int::arshift): New.
(double_int::llshift): New.
(double_int::lrshift): New.
(double_int::lrotate): New.
(double_int::rrotate): New.
(double_int::div): New.
(double_int::sdiv): New.
(double_int::udiv): New.
(double_int::mod): New.
(double_int::smod): New.
(double_int::umod): New.
(double_int::divmod): New.
(double_int::sdivmod): New.
(double_int::udivmod): New.
(double_int::ext): New.
(double_int::zext): New.
(double_int::sext): New.
(double_int::is_zero): New.
(double_int::is_one): New.
(double_int::is_minus_one): New.
(double_int::is_negative): New.
(double_int::cmp): New.
(double_int::ucmp): New.
(double_int::scmp): New.
(double_int::ult): New.
(double_int::ugt): New.
(double_int::slt): New.
(double_int::sgt): New.
(double_int::max): New.
(double_int::smax): New.
(double_int::umax): New.
(double_int::min): New.
(double_int::smin): New.
(double_int::umin): New.
(double_int::operator ==): New.
(double_int::operator !=): New.
(shwi_to_double_int): Change implementation to use member function.
(double_int_minus_one): Likewise.
(double_int_zero): Likewise.
(double_int_one): Likewise.
(double_int_two): Likewise.
(double_int_ten): Likewise.
(uhwi_to_double_int): Likewise.
(double_int_to_shwi): Likewise.
(double_int_to_uhwi): Likewise.
(double_int_fits_in_uhwi_p): Likewise.
(double_int_fits_in_shwi_p): Likewise.
(double_int_fits_in_hwi_p): Likewise.
(double_int_mul): Likewise.
(double_int_mul_with_sign): Likewise.
(double_int_add): Likewise.
(double_int_sub): Likewise.
(double_int_neg): Likewise.
(double_int_div): Likewise.
(double_int_sdiv): Likewise.
(double_int_udiv): Likewise.
(double_int_mod): Likewise.
(double_int_smod): Likewise.
(double_int_umod): Likewise.
(double_int_divmod): Likewise.
(double_int_sdivmod): Likewise.
(double_int_udivmod): Likewise.
(double_int_multiple_of): Likewise.
(double_int_setbit): Likewise.
(double_int_ctz): Likewise.
(double_int_not): Likewise.
(double_int_ior): Likewise.
(double_int_and): Likewise.
(double_int_and_not): Likewise.
(double_int_xor): Likewise.
(double_int_lshift): Likewise.
(double_int_rshift): Likewise.
(double_int_lrotate): Likewise.
(double_int_rrotate): Likewise.
(double_int_cmp): Likewise.
(double_int_scmp): Likewise.
(double_int_ucmp): Likewise.
(double_int_max): Likewise.
(double_int_smax): Likewise.
(double_int_umax): Likewise.
(double_int_min): Likewise.
(double_int_smin): Likewise.
(double_int_umin): Likewise.
(double_int_ext): Likewise.
(double_int_sext): Likewise.
(double_int_zext): Likewise.
(double_int_mask): Likewise.
(double_int_max_value): Likewise.
(double_int_min_value): Likewise.
(double_int_zero_p): Likewise.
(double_int_one_p): Likewise.
(double_int_minus_one_p): Likewise.
(double_int_equal_p): Likewise.
(double_int_popcount): Likewise.
* hash-table.c
(double_int_mask): Reuse implementation for double_int::mask.
(double_int_max_value): Likewise.
(double_int_min_value): Likewise.
(double_int_ext): Likewise.
(double_int_zext): Likewise.
(double_int_sext): Likewise.
(double_int_mul_with_sign): Likewise.
(double_int_divmod): Likewise.
(double_int_sdivmod): Likewise.
(double_int_udivmod): Likewise.
(double_int_div): Likewise.
(double_int_sdiv): Likewise.
(double_int_udiv): Likewise.
(double_int_mod): Likewise.
(double_int_smod): Likewise.
(double_int_umod): Likewise.
(double_int_multiple_of): Likewise.
(double_int_lshift): Likewise.
(double_int_rshift): Likewise.
(double_int_lrotate): Likewise.
(double_int_rrotate): Likewise.
(double_int_cmp): Likewise.
(double_int_ucmp): Likewise.
(double_int_scmp): Likewise.
(double_int_max): Likewise.
(double_int_smax): Likewise.
(double_int_umax): Likewise.
(double_int_min): Likewise.
(double_int_smin): Likewise.
(double_int_umin): Likewise.
(double_int_min): Likewise.
(double_int_min): Likewise.
(double_int_min): Likewise.
(double_int_min): Likewise.
(double_int_min): Likewise.
(double_int_min): Likewise.
(double_int::alshift): New.
(double_int::arshift): New.
(double_int::llshift): New.
(double_int::lrshift): New.
(double_int::ult): New.
(double_int::ugt): New.
(double_int::slt): New.
(double_int::sgt): New.
(double_int_setbit): Reuse implementation for double_int::set_bit,
which avoids a name conflict with a macro.
(double_int_double_int_ctz): Reuse implementation for
double_int::trailing_zeros.
(double_int_fits_in_shwi_p): Reuse implementation for
double_int::fits_signed.
(double_int_fits_in_hwi_p): Reuse implementation for double_int::fits.
(double_int_mul): Reuse implementation for binary
double_int::operator *.
(double_int_add): Likewise.
(double_int_sub): Likewise.
(double_int_neg): Reuse implementation for unary
double_int::operator -.
(double_int_max_value): Likewise.
* fixed-value.c: Change to use member functions introduced above.
2012-08-14 Lawrence Crowl <crowl@google.com>
Merge cxx-conversion branch. Support tree macro calling
from gdb.
* tree.h (tree_check): New.
(TREE_CHECK): Use inline function above instead of __extension__.
(tree_not_check): New.
(TREE_NOT_CHECK): Use inline function above instead of __extension__.
(tree_check2): New.
(TREE_CHECK2): Use inline function above instead of __extension__.
(tree_not_check2): New.
(TREE_NOT_CHECK2): Use inline function above instead of __extension__.
(tree_check3): New.
(TREE_CHECK3): Use inline function above instead of __extension__.
(tree_not_check3): New.
(TREE_NOT_CHECK3): Use inline function above instead of __extension__.
(tree_check4): New.
(TREE_CHECK4): Use inline function above instead of __extension__.
(tree_not_check4): New.
(TREE_NOT_CHECK4): Use inline function above instead of __extension__.
(tree_check5): New.
(TREE_CHECK5): Use inline function above instead of __extension__.
(tree_not_check5): New.
(TREE_NOT_CHECK5): Use inline function above instead of __extension__.
(contains_struct_check): New.
(CONTAINS_STRUCT_CHECK): Use inline function above instead of
__extension__.
(tree_class_check): New.
(TREE_CLASS_CHECK): Use inline function above instead of __extension__.
(tree_range_check): New.
(TREE_RANGE_CHECK): Use inline function above instead of __extension__.
(omp_clause_subcode_check): New.
(OMP_CLAUSE_SUBCODE_CHECK): Use inline function above instead of
__extension__.
(omp_clause_range_check): New.
(OMP_CLAUSE_RANGE_CHECK): Use inline function above instead of
__extension__.
(expr_check): New.
(EXPR_CHECK): Use inline function above instead of __extension__.
(non_type_check): New.
(NON_TYPE_CHECK): Use inline function above instead of __extension__.
(tree_vec_elt_check): New.
(TREE_VEC_ELT_CHECK): Use inline function above instead of
__extension__.
(omp_clause_elt_check): New.
(OMP_CLAUSE_ELT_CHECK): Use inline function above instead of
__extension__.
(tree_operand_check): New.
(TREE_OPERAND_CHECK): Use inline function above instead of
__extension__.
(tree_operand_check_code): New.
(TREE_OPERAND_CHECK_CODE): Use inline function above instead of
__extension__.
(TREE_CHAIN): Simplify implementation.
(TREE_TYPE): Simplify implementation.
(tree_operand_length): Move for compilation dependences.
* gdbinit.in: (macro define __FILE__): New.
(macro define __LINE__): New.
(skip "tree.h"): New.
gcc/cp/ChangeLog
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch. Re-write VEC in C++.
* call.c (add_function_candidate): Remove const qualifier
from call to VEC_index.
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch. Configury.
* go-c.h: Remove all handlers of ENABLE_BUILD_WITH_CXX.
* go-gcc.cc: Likewise.
* go-system.h: Likewise.
From-SVN: r190402
126 files changed, 5518 insertions, 3431 deletions
@@ -1,3 +1,14 @@ +2012-08-14 Diego Novillo <dnovillo@google.com> + + Merge from cxx-conversion branch. + + * Makefile.tpl (STAGE[+id+]_CXXFLAGS): Remove + POSTSTAGE1_CONFIGURE_FLAGS. + * Makefile.in: Regenerate. + * configure.ac (ENABLE_BUILD_WITH_CXX): Remove. Update all users. + Force C++ when bootstrapping. + * configure: Regenerate. + 2012-07-24 Jan-Benedict Glaw <jbglaw@lug-owl.de> * MAINTAINERS (Write After Approval): Add myself. diff --git a/Makefile.in b/Makefile.in index 346c4bf..0d25666 100644 --- a/Makefile.in +++ b/Makefile.in @@ -420,7 +420,6 @@ TFLAGS = STAGE_CFLAGS = $(BOOT_CFLAGS) STAGE_TFLAGS = $(TFLAGS) STAGE_CONFIGURE_FLAGS=@stage2_werror_flag@ -POSTSTAGE1_CONFIGURE_FLAGS = @POSTSTAGE1_CONFIGURE_FLAGS@ # Defaults for stage 1; some are overridden below. @@ -431,10 +430,7 @@ STAGE1_CXXFLAGS = $(CXXFLAGS) STAGE1_CXXFLAGS = $(STAGE1_CFLAGS) @endif target-libstdc++-v3-bootstrap STAGE1_TFLAGS = $(STAGE_TFLAGS) -# STAGE1_CONFIGURE_FLAGS overridden below, so we can use -# POSTSTAGE1_CONFIGURE_FLAGS here. -STAGE1_CONFIGURE_FLAGS = \ - $(STAGE_CONFIGURE_FLAGS) $(POSTSTAGE1_CONFIGURE_FLAGS) +STAGE1_CONFIGURE_FLAGS = $(STAGE_CONFIGURE_FLAGS) # Defaults for stage 2; some are overridden below. STAGE2_CFLAGS = $(STAGE_CFLAGS) @@ -444,10 +440,7 @@ STAGE2_CXXFLAGS = $(CXXFLAGS) STAGE2_CXXFLAGS = $(STAGE2_CFLAGS) @endif target-libstdc++-v3-bootstrap STAGE2_TFLAGS = $(STAGE_TFLAGS) -# STAGE1_CONFIGURE_FLAGS overridden below, so we can use -# POSTSTAGE1_CONFIGURE_FLAGS here. -STAGE2_CONFIGURE_FLAGS = \ - $(STAGE_CONFIGURE_FLAGS) $(POSTSTAGE1_CONFIGURE_FLAGS) +STAGE2_CONFIGURE_FLAGS = $(STAGE_CONFIGURE_FLAGS) # Defaults for stage 3; some are overridden below. STAGE3_CFLAGS = $(STAGE_CFLAGS) @@ -457,10 +450,7 @@ STAGE3_CXXFLAGS = $(CXXFLAGS) STAGE3_CXXFLAGS = $(STAGE3_CFLAGS) @endif target-libstdc++-v3-bootstrap STAGE3_TFLAGS = $(STAGE_TFLAGS) -# STAGE1_CONFIGURE_FLAGS overridden below, so we can use -# POSTSTAGE1_CONFIGURE_FLAGS here. -STAGE3_CONFIGURE_FLAGS = \ - $(STAGE_CONFIGURE_FLAGS) $(POSTSTAGE1_CONFIGURE_FLAGS) +STAGE3_CONFIGURE_FLAGS = $(STAGE_CONFIGURE_FLAGS) # Defaults for stage 4; some are overridden below. STAGE4_CFLAGS = $(STAGE_CFLAGS) @@ -470,10 +460,7 @@ STAGE4_CXXFLAGS = $(CXXFLAGS) STAGE4_CXXFLAGS = $(STAGE4_CFLAGS) @endif target-libstdc++-v3-bootstrap STAGE4_TFLAGS = $(STAGE_TFLAGS) -# STAGE1_CONFIGURE_FLAGS overridden below, so we can use -# POSTSTAGE1_CONFIGURE_FLAGS here. -STAGE4_CONFIGURE_FLAGS = \ - $(STAGE_CONFIGURE_FLAGS) $(POSTSTAGE1_CONFIGURE_FLAGS) +STAGE4_CONFIGURE_FLAGS = $(STAGE_CONFIGURE_FLAGS) # Defaults for stage profile; some are overridden below. STAGEprofile_CFLAGS = $(STAGE_CFLAGS) @@ -483,10 +470,7 @@ STAGEprofile_CXXFLAGS = $(CXXFLAGS) STAGEprofile_CXXFLAGS = $(STAGEprofile_CFLAGS) @endif target-libstdc++-v3-bootstrap STAGEprofile_TFLAGS = $(STAGE_TFLAGS) -# STAGE1_CONFIGURE_FLAGS overridden below, so we can use -# POSTSTAGE1_CONFIGURE_FLAGS here. -STAGEprofile_CONFIGURE_FLAGS = \ - $(STAGE_CONFIGURE_FLAGS) $(POSTSTAGE1_CONFIGURE_FLAGS) +STAGEprofile_CONFIGURE_FLAGS = $(STAGE_CONFIGURE_FLAGS) # Defaults for stage feedback; some are overridden below. STAGEfeedback_CFLAGS = $(STAGE_CFLAGS) @@ -496,10 +480,7 @@ STAGEfeedback_CXXFLAGS = $(CXXFLAGS) STAGEfeedback_CXXFLAGS = $(STAGEfeedback_CFLAGS) @endif target-libstdc++-v3-bootstrap STAGEfeedback_TFLAGS = $(STAGE_TFLAGS) -# STAGE1_CONFIGURE_FLAGS overridden below, so we can use -# POSTSTAGE1_CONFIGURE_FLAGS here. -STAGEfeedback_CONFIGURE_FLAGS = \ - $(STAGE_CONFIGURE_FLAGS) $(POSTSTAGE1_CONFIGURE_FLAGS) +STAGEfeedback_CONFIGURE_FLAGS = $(STAGE_CONFIGURE_FLAGS) # Only build the C compiler for stage1, because that is the only one that @@ -517,9 +498,6 @@ STAGE1_LANGUAGES = @stage1_languages@ # the last argument when conflicting --enable arguments are passed. # * Likewise, we force-disable coverage flags, since the installed # compiler probably has never heard of them. -# * Don't remove this, because above we added -# POSTSTAGE1_CONFIGURE_FLAGS to STAGE_CONFIGURE_FLAGS, which -# we don't want for STAGE1_CONFIGURE_FLAGS. STAGE1_CONFIGURE_FLAGS = --disable-intermodule $(STAGE1_CHECKING) \ --disable-coverage --enable-languages="$(STAGE1_LANGUAGES)" diff --git a/Makefile.tpl b/Makefile.tpl index 2573eee..f2c3f48 100644 --- a/Makefile.tpl +++ b/Makefile.tpl @@ -423,7 +423,6 @@ TFLAGS = STAGE_CFLAGS = $(BOOT_CFLAGS) STAGE_TFLAGS = $(TFLAGS) STAGE_CONFIGURE_FLAGS=@stage2_werror_flag@ -POSTSTAGE1_CONFIGURE_FLAGS = @POSTSTAGE1_CONFIGURE_FLAGS@ [+ FOR bootstrap-stage +] # Defaults for stage [+id+]; some are overridden below. @@ -434,10 +433,7 @@ STAGE[+id+]_CXXFLAGS = $(CXXFLAGS) STAGE[+id+]_CXXFLAGS = $(STAGE[+id+]_CFLAGS) @endif target-libstdc++-v3-bootstrap STAGE[+id+]_TFLAGS = $(STAGE_TFLAGS) -# STAGE1_CONFIGURE_FLAGS overridden below, so we can use -# POSTSTAGE1_CONFIGURE_FLAGS here. -STAGE[+id+]_CONFIGURE_FLAGS = \ - $(STAGE_CONFIGURE_FLAGS) $(POSTSTAGE1_CONFIGURE_FLAGS) +STAGE[+id+]_CONFIGURE_FLAGS = $(STAGE_CONFIGURE_FLAGS) [+ ENDFOR bootstrap-stage +] # Only build the C compiler for stage1, because that is the only one that @@ -455,9 +451,6 @@ STAGE1_LANGUAGES = @stage1_languages@ # the last argument when conflicting --enable arguments are passed. # * Likewise, we force-disable coverage flags, since the installed # compiler probably has never heard of them. -# * Don't remove this, because above we added -# POSTSTAGE1_CONFIGURE_FLAGS to STAGE[+id+]_CONFIGURE_FLAGS, which -# we don't want for STAGE1_CONFIGURE_FLAGS. STAGE1_CONFIGURE_FLAGS = --disable-intermodule $(STAGE1_CHECKING) \ --disable-coverage --enable-languages="$(STAGE1_LANGUAGES)" @@ -556,7 +556,6 @@ enable_option_checking=no ac_subst_vars='LTLIBOBJS LIBOBJS compare_exclusions -POSTSTAGE1_CONFIGURE_FLAGS stage2_werror_flag stage1_checking stage1_cflags @@ -753,8 +752,6 @@ enable_libada enable_libssp enable_static_libjava enable_bootstrap -enable_build_with_cxx -enable_build_poststage1_with_cxx with_mpc with_mpc_include with_mpc_lib @@ -1471,9 +1468,6 @@ Optional Features: --enable-static-libjava[=ARG] build static libjava [default=no] --enable-bootstrap enable bootstrapping [yes if native build] - --enable-build-with-cxx build with C++ compiler instead of C compiler - --enable-build-poststage1-with-cxx - build stages 2 and 3 with C++, not C --disable-isl-version-check disable check for ISL version --disable-cloog-version-check @@ -5109,24 +5103,6 @@ $as_echo "$as_me: WARNING: trying to bootstrap a cross compiler" >&2;} ;; esac -# See if we are building gcc with C++. -# Check whether --enable-build-with-cxx was given. -if test "${enable_build_with_cxx+set}" = set; then : - enableval=$enable_build_with_cxx; ENABLE_BUILD_WITH_CXX=$enableval -else - ENABLE_BUILD_WITH_CXX=no -fi - - -# Build stage1 with C and build stages 2 and 3 with C++. -# Check whether --enable-build-poststage1-with-cxx was given. -if test "${enable_build_poststage1_with_cxx+set}" = set; then : - enableval=$enable_build_poststage1_with_cxx; ENABLE_BUILD_POSTSTAGE1_WITH_CXX=$enableval -else - ENABLE_BUILD_POSTSTAGE1_WITH_CXX=yes -fi - - # Used for setting $lt_cv_objdir { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } @@ -5980,7 +5956,7 @@ fi -# By default, C is the only stage 1 language. +# By default, C and C++ are the only stage 1 languages. stage1_languages=,c, # Target libraries that we bootstrap. @@ -6018,15 +5994,14 @@ if test -d ${srcdir}/gcc; then ;; esac - # If bootstrapping, then using --enable-build-with-cxx or - # --enable-build-poststage1-with-cxx requires enabling C++. - case ",$enable_languages,:,$ENABLE_BUILD_WITH_CXX,$ENABLE_BUILD_POSTSTAGE1_WITH_CXX,:$enable_bootstrap" in - *,c++,*:*:*) ;; - *:*,yes,*:yes) + # If bootstrapping, C++ must be enabled. + case ",$enable_languages,:$enable_bootstrap" in + *,c++,*:*) ;; + *:yes) if test -f ${srcdir}/gcc/cp/config-lang.in; then enable_languages="${enable_languages},c++" else - as_fn_error "bootstrapping with --enable-build-with-cxx or --enable-build-poststage1-with-cxx requires c++ sources" "$LINENO" 5 + as_fn_error "bootstrapping requires c++ sources" "$LINENO" 5 fi ;; esac @@ -6121,10 +6096,7 @@ if test -d ${srcdir}/gcc; then fi if test "$language" = "c++"; then - if test "$ENABLE_BUILD_WITH_CXX" = "yes" \ - || test "$ENABLE_BUILD_POSTSTAGE1_WITH_CXX" = "yes"; then - boot_language=yes - fi + boot_language=yes fi case ,${enable_languages}, in @@ -14215,43 +14187,6 @@ case $build in esac ;; esac -# This is aimed to mimic bootstrap with a non-GCC compiler to catch problems. -if test "$GCC" = yes -a "$ENABLE_BUILD_WITH_CXX" != yes; then - saved_CFLAGS="$CFLAGS" - - # Pass -fkeep-inline-functions for stage 1 if the GCC version supports it. - CFLAGS="$CFLAGS -fkeep-inline-functions" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fkeep-inline-functions is supported" >&5 -$as_echo_n "checking whether -fkeep-inline-functions is supported... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#if (__GNUC__ < 3) \ - || (__GNUC__ == 3 && (__GNUC_MINOR__ < 3 \ - || (__GNUC_MINOR__ == 3 && __GNUC_PATCHLEVEL__ < 1))) -#error http://gcc.gnu.org/PR29382 -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; }; stage1_cflags="$stage1_cflags -fkeep-inline-functions" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - CFLAGS="$saved_CFLAGS" -fi - # Enable --enable-checking in stage1 of the compiler. @@ -14286,15 +14221,6 @@ case ${enable_werror} in esac -# If using ENABLE_BUILD_POSTSTAGE1_WITH_CXX, pass -# --enable-build-with-cxx after stage1. -if test "$ENABLE_BUILD_POSTSTAGE1_WITH_CXX" = "yes"; then - POSTSTAGE1_CONFIGURE_FLAGS=--enable-build-with-cxx -else - POSTSTAGE1_CONFIGURE_FLAGS= -fi - - # Specify what files to not compare during bootstrap. compare_exclusions="gcc/cc*-checksum\$(objext) | gcc/ada/*tools/*" diff --git a/configure.ac b/configure.ac index b4e1266..27692b4 100644 --- a/configure.ac +++ b/configure.ac @@ -1204,20 +1204,6 @@ case "$have_compiler:$host:$target:$enable_bootstrap" in ;; esac -# See if we are building gcc with C++. -AC_ARG_ENABLE(build-with-cxx, -[AS_HELP_STRING([--enable-build-with-cxx], - [build with C++ compiler instead of C compiler])], -ENABLE_BUILD_WITH_CXX=$enableval, -ENABLE_BUILD_WITH_CXX=no) - -# Build stage1 with C and build stages 2 and 3 with C++. -AC_ARG_ENABLE(build-poststage1-with-cxx, -[AS_HELP_STRING([--enable-build-poststage1-with-cxx], - [build stages 2 and 3 with C++, not C])], -ENABLE_BUILD_POSTSTAGE1_WITH_CXX=$enableval, -ENABLE_BUILD_POSTSTAGE1_WITH_CXX=yes) - # Used for setting $lt_cv_objdir _LT_CHECK_OBJDIR @@ -1595,7 +1581,7 @@ ACX_ELF_TARGET_IFELSE([# ELF platforms build the lto-plugin always. ]) -# By default, C is the only stage 1 language. +# By default, C and C++ are the only stage 1 languages. stage1_languages=,c, # Target libraries that we bootstrap. @@ -1633,15 +1619,14 @@ if test -d ${srcdir}/gcc; then ;; esac - # If bootstrapping, then using --enable-build-with-cxx or - # --enable-build-poststage1-with-cxx requires enabling C++. - case ",$enable_languages,:,$ENABLE_BUILD_WITH_CXX,$ENABLE_BUILD_POSTSTAGE1_WITH_CXX,:$enable_bootstrap" in - *,c++,*:*:*) ;; - *:*,yes,*:yes) + # If bootstrapping, C++ must be enabled. + case ",$enable_languages,:$enable_bootstrap" in + *,c++,*:*) ;; + *:yes) if test -f ${srcdir}/gcc/cp/config-lang.in; then enable_languages="${enable_languages},c++" else - AC_MSG_ERROR([bootstrapping with --enable-build-with-cxx or --enable-build-poststage1-with-cxx requires c++ sources]) + AC_MSG_ERROR([bootstrapping requires c++ sources]) fi ;; esac @@ -1736,10 +1721,7 @@ if test -d ${srcdir}/gcc; then fi if test "$language" = "c++"; then - if test "$ENABLE_BUILD_WITH_CXX" = "yes" \ - || test "$ENABLE_BUILD_POSTSTAGE1_WITH_CXX" = "yes"; then - boot_language=yes - fi + boot_language=yes fi case ,${enable_languages}, in @@ -3129,26 +3111,6 @@ case $build in esac ;; esac -# This is aimed to mimic bootstrap with a non-GCC compiler to catch problems. -if test "$GCC" = yes -a "$ENABLE_BUILD_WITH_CXX" != yes; then - saved_CFLAGS="$CFLAGS" - - # Pass -fkeep-inline-functions for stage 1 if the GCC version supports it. - CFLAGS="$CFLAGS -fkeep-inline-functions" - AC_MSG_CHECKING([whether -fkeep-inline-functions is supported]) - AC_TRY_COMPILE([ -#if (__GNUC__ < 3) \ - || (__GNUC__ == 3 && (__GNUC_MINOR__ < 3 \ - || (__GNUC_MINOR__ == 3 && __GNUC_PATCHLEVEL__ < 1))) -#error http://gcc.gnu.org/PR29382 -#endif - ],, - [AC_MSG_RESULT([yes]); stage1_cflags="$stage1_cflags -fkeep-inline-functions"], - [AC_MSG_RESULT([no])]) - - CFLAGS="$saved_CFLAGS" -fi - AC_SUBST(stage1_cflags) # Enable --enable-checking in stage1 of the compiler. @@ -3178,15 +3140,6 @@ case ${enable_werror} in esac AC_SUBST(stage2_werror_flag) -# If using ENABLE_BUILD_POSTSTAGE1_WITH_CXX, pass -# --enable-build-with-cxx after stage1. -if test "$ENABLE_BUILD_POSTSTAGE1_WITH_CXX" = "yes"; then - POSTSTAGE1_CONFIGURE_FLAGS=--enable-build-with-cxx -else - POSTSTAGE1_CONFIGURE_FLAGS= -fi -AC_SUBST(POSTSTAGE1_CONFIGURE_FLAGS) - # Specify what files to not compare during bootstrap. compare_exclusions="gcc/cc*-checksum\$(objext) | gcc/ada/*tools/*" diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b2c3d4..4229037 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,604 @@ +2012-08-14 Diego Novillo <dnovillo@google.com> + + Merge from cxx-conversion branch. Configury. + + * configure.ac (CXX_FOR_BUILD): Define and substitute. + (BUILD_CXXFLAGS): Define. + Remove all handlers of ENABLE_BUILD_WITH_CXX. + Force all build to be with C++. + * Makefile.in (BUILD_CXXFLAGS): Use it. + Remove all handlers of ENABLE_BUILD_WITH_CXX. + * configure: Regenerate. + * config.in: Regenerate. + * doc/install.texi: Remove documentation for --enable-build-with-cxx + and --enable-build-poststage1-with-cxx. + +2012-08-14 Diego Novillo <dnovillo@google.com> + + Merge from cxx-conversion branch. Re-implement VEC in C++. + + * vec.c (vec_heap_free): Convert into a template function. + (vec_gc_o_reserve_1): Make extern. + (vec_gc_p_reserve): Remove. + (vec_gc_p_reserve_exact): Remove. + (vec_gc_o_reserve): Remove. + (vec_gc_o_reserve_exact): Remove. + (vec_heap_o_reserve_1): Make extern. + (vec_heap_p_reserve): Remove. + (vec_heap_p_reserve_exact): Remove. + (vec_heap_o_reserve): Remove. + (vec_heap_o_reserve_exact): Remove. + (vec_stack_p_reserve): Remove. + (vec_stack_p_reserve_exact): Remove. + * vec.h (VEC_CHECK_INFO, VEC_CHECK_DECL, VEC_CHECK_PASS, + VEC_ASSERT, VEC_ASSERT_FAIL, vec_assert_fail): Move earlier + in the file. + (VEC): Define to vec_t<T>. + (vec_allocation_t): Define. + (struct vec_prefix): Move earlier in the file. + (vec_t<T>): New template. + (DEF_VEC_I, DEF_VECL_ALLOC_I, DEF_VEC_P, DEF_VEC_ALLOC_P, + DEF_VEC_O, DEF_VEC_ALLOC_P, DEF_VEC_O, DEF_VEC_ALLOC_O, + DEF_VEC_ALLOC_P_STACK, DEF_VEC_ALLOC_O_STACK, + DEF_VEC_ALLOC_I_STACK): Expand to 'struct vec_swallow_trailing_semi'. + (DEF_VEC_A): Provide template instantiations for + GC/PCH markers that do not traverse the vector. + (vec_stack_p_reserve): Remove. + (vec_stack_p_reserve_exact): Remove. + (vec_stack_p_reserve_exact_1): Remove. + (vec_stack_o_reserve): Remove. + (vec_stack_o_reserve_exact): Remove. + (vec_stack_free): Re-write as a template function. + (vec_reserve): New template function. + (vec_reserve_exact): New template function. + (vec_heap_free): New template function if GATHER_STATISTICS is + defined. Otherwise, macro that expands to free(). + (VEC_length_1): New template function. + (VEC_length): Call it. + (VEC_empty_1): New template function. + (VEC_empty): Call it. + (VEC_address_1): New template function. + (VEC_address): Call it. + (VEC_last_1): New template function. + (VEC_last): Call it. Change return type to T&. + Change all users that used VEC_Os. + (VEC_index_1): New template function. + (VEC_index): Call it. Return a T& instead of a T*. + Update all callers that were using VEC_O before. + (VEC_iterate_1): New template function. + (VEC_iterate): Call it. + (VEC_embedded_size_1): New template function. + (VEC_embedded_size): Call it. + (VEC_embedded_init_1): New template function. + (VEC_embedded_init): Call it. + (VEC_alloc_1): New template function. + (VEC_alloc): Call it. If A is 'stack', call XALLOCAVAR to + do the allocation. + (VEC_free_1): New template function. + (VEC_free): Call it. + (VEC_copy_1): New template function. + (VEC_copy): Call it. + (VEC_space_1): New template function + (VEC_space): Call it. + (VEC_reserve_1): New template function. + (VEC_reserve): Call it. + (VEC_reserve_exact_1): New template function. + (VEC_reserve_exact): Call it. + (VEC_splice_1): New template function. + (VEC_splice): Call it. + (VEC_safe_splice_1): New template function. + (VEC_safe_splice): Call it. + (VEC_quick_push_1): New template function. Create two overloads, one + accepting T, the other accepting T *. Update all callers + where T and T * are ambiguous. + (VEC_quick_push): Call it. + (VEC_safe_push_1): New template function. Create two overloads, one + accepting T, the other accepting T *. Update all callers + where T and T * are ambiguous. + (VEC_safe_push): Call it. + (VEC_pop_1): New template function. + (VEC_pop): Call it. + (VEC_truncate_1): New template function. + (VEC_truncate): Call it. + (VEC_safe_grow_1): New template function. + (VEC_safe_grow): Call it. + (VEC_safe_grow_cleared_1): New template function. + (VEC_safe_grow_cleared): Call it. + (VEC_replace_1): New template function. + (VEC_replace): Call it. Always accept T instead of T*. + Update all callers that used VEC_Os. + (VEC_quick_insert_1): New template function. + (VEC_quick_insert): Call it. + (VEC_safe_insert_1): New template function. + (VEC_safe_insert): Call it. + (VEC_ordered_remove_1): New template function. + (VEC_ordered_remove): Call it. + (VEC_unordered_remove_1): New template function. + (VEC_unordered_remove): Call it. + (VEC_block_remove_1): New template function. + (VEC_block_remove): Call it. + (VEC_lower_bound_1): New template function. + (VEC_lower_bound): Call it. + (VEC_OP): Remove. + (DEF_VEC_FUNC_P): Remove. + (DEF_VEC_ALLOC_FUNC_P): Remove. + (DEF_VEC_NONALLOC_FUNCS_P): Remove. + (DEF_VEC_FUNC_O): Remove. + (DEF_VEC_ALLOC_FUNC_O): Remove. + (DEF_VEC_NONALLOC_FUNCS_O): Remove. + (DEF_VEC_ALLOC_FUNC_I): Remove. + (DEF_VEC_NONALLOC_FUNCS_I): Remove. + (DEF_VEC_ALLOC_FUNC_P_STACK): Remove. + (DEF_VEC_ALLOC_FUNC_O_STACK): Remove. + (DEF_VEC_ALLOC_FUNC_I_STACK): Remove. + (vec_reserve_exact): New template function. + + * gengtype-lex.l (DEF_VEC_ALLOC_[IOP]/{EOID}): Remove. + * gengtype-parse.c (token_names): Remove DEF_VEC_ALLOC_[IOP]. + (typedef_name): Emit vec_t<C1> instead of VEC_C1_C2. + (def_vec_alloc): Remove. Update all callers. + * gengtype.c (filter_type_name): New. + (output_mangled_typename): Call it. + (write_func_for_structure): Likewise. + (write_types): Likewise. + (write_root): Likewise. + (write_typed_alloc_def): Likewise. + (note_def_vec): Emit vec_t<TYPE_NAME> instead of VEC_TYPE_NAME_base. + (note_def_vec_alloc): Remove. + * gengtype.h (note_def_vec_alloc): Remove. + (DEFVEC_ALLOC): Remove token code. + + * df-scan.c (df_bb_verify): Remove call to df_free_collection_rec + inside the insn traversal loop. + * gimplify.c (gimplify_compound_lval): Rename STACK to EXPR_STACK. + * ipa-inline.c (inline_small_functions): Rename HEAP to EDGE_HEAP. + * reg-stack.c (stack): Rename to STACK_PTR. Update all users. + * tree-vrp.c (stack): Rename to EQUIV_STACK. Update all users. + + * config/bfin/bfin.c (hwloop_optimize): Update some calls to + VEC_* for vectors of non-pointers. + * config/c6x/c6x.c (try_rename_operands): Likewise. + (reshuffle_units): Likewise. + * config/mips/mips.c (mips_multi_start): Likewise. + (mips_multi_add): Likewise. + (mips_multi_copy_insn): Likewise. + (mips_multi_set_operand): Likewise. + * hw-doloop.c (discover_loop): Likewise. + (discover_loops): Likewise. + (reorg_loops): Likewise. + +2012-08-14 Diego Novillo <dnovillo@google.com> + + Merge from cxx-conversion branch. C++ support in gengtype. + + * coretypes.h (gt_pointer_operator): Move from ... + * ggc.h: ... here. + * doc/gty.texi: Document support for C++ templates and + user-provided markers. + * gcc/gengtype-lex.l: Update copyright year. + Remove support for recognizing DEF_VEC_O, DEF_VEC_P and + DEFVEC_I. + * gengtype-parse.c: Update copyright year. + (token_names): Remove DEF_VEC_O, DEF_VEC_P and DEF_VEC_I. + (require_template_declaration): New. + (typedef_name): Call it. + (type): Replace IS_UNION with KIND. Replace all users. + (def_vec): Remove. Update all users. + * gengtype-state.c (type_lineloc): Handle TYPE_USER_STRUCT. + (write_state_user_struct_type): New. + (write_state_type): Call it. + (read_state_user_struct_type): New. + (read_state_type): Call it. + * gengtype.c: Update copyright year. + (dump_pair): Move declaration to the top. + (dump_type): Likewise. + (dump_type_list): Likewise. + (dbgprint_count_type_at): Handle TYPE_USER_STRUCT. + (create_user_defined_type): New. + (resolve_typedef): Call it. + (new_structure): Replace argument ISUNION with KIND. + Change users to refer to KIND directly. + Update all callers. + (find_structure): Likewise. + (set_gc_used_type): Handle TYPE_USER_STRUCT. + (create_file): Update HDR to include new copyright year. + (struct walk_type_data): Add field IN_PTR_FIELD. + (output_mangled_typename): Handle TYPE_USER_STRUCT. + (walk_type): Set D->IN_PTR_FIELD when walking a TYPE_POINTER. + Clear it afterwards. + Handle TYPE_USER_STRUCT. + (write_types_process_field): Handle TYPE_USER_STRUCT. + (get_type_specifier): Move earlier in the file. + (write_type_decl): New. + (write_marker_function_name): New. + (write_user_func_for_structure_ptr): New. + (write_user_func_for_structure_body): New. + (write_user_marking_functions): New. + (write_func_for_structure): Call write_marker_function_name + and write_type_decl. + Do not call walk_type for TYPE_USER_STRUCT. Emit a call to the user + function directly. + Call write_user_marking_functions on TYPE_USER_STRUCTs. + (write_types_local_user_process_field): New. + (write_pch_user_walking_for_structure_body): New. + (write_pch_user_walking_functions): New. + (write_types_local_process_field): Handle TYPE_USER_STRUCT. + (write_local_func_for_structure): Do not call walk_type for + TYPE_USER_STRUCT. Instead, emit the call to gt_pch_nx directly. + Call write_pch_user_walking_functions for TYPE_USER_STRUCTs. + (write_root): Handle TYPE_USER_STRUCT. + (vec_prefix_type): Remove. Update all users. + (note_def_vec): Remove. Update all users. + (dump_typekind): Handle TYPE_USER_STRUCT. + (dump_type): Initialize SEEN_TYPES, if needed. + Handle TYPE_USER_STRUCT. + (dump_everything): Do not initialize SEEN_TYPES. + * gengtype.h: Update copyright year. + (enum typekind): Add TYPE_USER_STRUCT. + (union_or_struct_p): Rename from UNION_OR_STRUCT_P. + Convert into function. + Add an overload taking const_type_p. + Update all callers. + (new_structure): Change second field to type enum typekind. + Update all users. + (find_structure): Likewise. + (note_def_vec): Remove. + (DEFVEC_OP): Remove. + (DEFVEC_I): Remove. + * ggc-page.c (gt_ggc_mx): Add entry points for marking + 'const char *&', 'unsigned char *&' and 'unsigned char&'. + * ggc-zone.c (gt_ggc_mx): Add entry points for marking + 'const char *&' and 'unsigned char *&'. + * stringpool.c (gt_pch_nx): Add entry points for marking + 'const char *&', 'unsigned char *&' and 'unsigned char&'. + Add an entry point for the overload taking arguments 'unsigned char + *', 'gt_pointer_operator' and 'void *'. + * vec.h (struct vec_prefix): Remove GTY marker. + (struct vec_t): Remove GTY((length)) attribute from field 'vec'. + (gt_ggc_mx (vec_t<T> *)): New template function. + (gt_pch_nx (vec_t<T> *)): New template function. + (gt_pch_nx (vec_t<T *> *, gt_pointer_operator, void *)): New template + function. + (gt_pch_nx (vec_t<T> *, gt_pointer_operator, void *)): New template + function. + + * basic-block.h (struct edge_def): Mark GTY((user)). + Remove all GTY markers from fields. + (gt_ggc_mx): Declare. + (gt_pch_nx): Declare. + * tree-cfg.c (gt_ggc_mx): New. + (gt_pch_nx): New. + + * gengtype-lex.l (USER_GTY): Add pattern for "user". + * gengtype-parse.c (option): Handle USER_GTY. + (opts_have): New. + (type): Call it. + If the keyword 'user' is used, do not walk the fields + of the structure. + * gengtype.h (USER_GTY): Add. + * doc/gty.texi: Update. + +2012-08-14 Lawrence Crowl <crowl@google.com> + + Merge cxx-conversion branch. Implement C++ hash table. + + * hash-table.h: New. Implementation borrowed from libiberty/hashtab.c. + * hash-table.c: Likewise. + * tree-ssa-tail-merge.c: Include hash-table.h instead of hashtab.h. + (static htab_t same_succ_htab): Change type to hash_table; + move specification of helper functions from create call to declaration. + Change users to invoke member functions. + (same_succ_print_traverse): Make extern ssa_.... Change callers. + Remove void* casting. + (same_succ_hash): Likewise. + (same_succ_equal): Likewise. + (same_succ_delete): Likewise. + * tree-ssa-threadupdate.c: Include hash-table.h. + (struct local_info): Rename to ssa_local_info_t to avoid overloading + the type name local_info with the variable name local_info. + (static htab_t redirection_data): Change type to hash_table. + Move specification of helper functions from create call to declaration. + Change users to invoke member functions. + (redirection_data_hash): Make extern ssa_.... Change callers. + Remove void* casting. + (redirection_data_eq): Likewise. + (fix_duplicate_block_edges): Likewise. + (create_duplicates): Likewise. + (fixup_template_block): Likewise. + (redirect_edges): Likewise. + (lookup_redirection_data): Change types associated with the hash table + from void* to their actual type. Remove unnecessary casts. + * tree-ssa-ccp.c: Include hash-table.h. + (typedef gimple_htab): New. Uses hash_table. Replace specific uses + of htab_t with gimple_htab. Change users to invoke member functions. + Move specification of helper functions from create call to declaration. + * tree-ssa-coalesce.c: Include hash-table.h instead of hashtab.h. + (hash_ssa_name_by_var): Make extern. Remove void* casting. + (eq_ssa_name_by_var): Likewise. + (coalesce_ssa_name): Change type of local static htab_t ssa_name_hash + to hash_table. Change users to invoke member functions. + Move specification of helper functions from create call to declaration. + * coverage.c: Include hash-table.h instead of hashtab.h. + (static htab_t counts_hash): Change type to hash_table; + move specification of helper functions from create call to declaration. + Change users to invoke member functions. + (htab_counts_entry_hash): Make extern. Rename with coverage_... instead + of htab_... Remove void* casting. + (htab_counts_entry_eq): Likewise. + (htab_counts_entry_del): Likewise. + * tree-ssa-pre.c: Include hash-table.h instead of hashtab.h. + (static htab_t expression_to_id): Change type to hash_table. + Move specification of helper functions from create call to declaration. + Change users to invoke member functions. + (static htab_t phi_translate_table): Likewise. + (pre_expr_eq): Make extern ssa_.... Change callers. + Remove void* casting. + (pre_expr_hash): Likewise. + (expr_pred_trans_hash): Likewise. + (expr_pred_trans_eq): Likewise. + (alloc_expression_id): Change types associated with the hash table + from void* to their actual type. Remove unnecessary casts. + (lookup_expression_id): Likewise. + (phi_trans_lookup): Likewise. + (phi_trans_add): Likewise. + * stringpool.c: Rename uses of libcpp typedef hash_table to + cpp_hash_table. + * Makefile.in: Add hash-table.o to OBJS-libcommon-target. + Add $(HASH_TABLE_H). Add new dependences on $(HASH_TABLE_H). + +2012-08-14 Lawrence Crowl <crowl@google.com> + + Merge from cxx-conversion branch. Re-write double_int in C++. + + * hash-table.h + (typedef double_int): Change to struct (POD). + (double_int::make): New overloads for int to double-int conversion. + (double_int::mask): New. + (double_int::max_value): New. + (double_int::min_value): New. + (double_int::operator ++): New. + (double_int::operator --): New. + (double_int::operator *=): New. + (double_int::operator +=): New. + (double_int::operator -=): New. + (double_int::to_signed): New. + (double_int::to_unsigned): New. + (double_int::fits_unsigned): New. + (double_int::fits_signed): New. + (double_int::fits): New. + (double_int::trailing_zeros): New. + (double_int::popcount): New. + (double_int::multiple_of): New. + (double_int::set_bit): New. + (double_int::mul_with_sign): New. + (double_int::operator * (binary)): New. + (double_int::operator + (binary)): New. + (double_int::operator - (binary)): New. + (double_int::operator - (unary)): New. + (double_int::operator ~ (unary)): New. + (double_int::operator & (binary)): New. + (double_int::operator | (binary)): New. + (double_int::operator ^ (binary)): New. + (double_int::and_not): New. + (double_int::lshift): New. + (double_int::rshift): New. + (double_int::alshift): New. + (double_int::arshift): New. + (double_int::llshift): New. + (double_int::lrshift): New. + (double_int::lrotate): New. + (double_int::rrotate): New. + (double_int::div): New. + (double_int::sdiv): New. + (double_int::udiv): New. + (double_int::mod): New. + (double_int::smod): New. + (double_int::umod): New. + (double_int::divmod): New. + (double_int::sdivmod): New. + (double_int::udivmod): New. + (double_int::ext): New. + (double_int::zext): New. + (double_int::sext): New. + (double_int::is_zero): New. + (double_int::is_one): New. + (double_int::is_minus_one): New. + (double_int::is_negative): New. + (double_int::cmp): New. + (double_int::ucmp): New. + (double_int::scmp): New. + (double_int::ult): New. + (double_int::ugt): New. + (double_int::slt): New. + (double_int::sgt): New. + (double_int::max): New. + (double_int::smax): New. + (double_int::umax): New. + (double_int::min): New. + (double_int::smin): New. + (double_int::umin): New. + (double_int::operator ==): New. + (double_int::operator !=): New. + (shwi_to_double_int): Change implementation to use member function. + (double_int_minus_one): Likewise. + (double_int_zero): Likewise. + (double_int_one): Likewise. + (double_int_two): Likewise. + (double_int_ten): Likewise. + (uhwi_to_double_int): Likewise. + (double_int_to_shwi): Likewise. + (double_int_to_uhwi): Likewise. + (double_int_fits_in_uhwi_p): Likewise. + (double_int_fits_in_shwi_p): Likewise. + (double_int_fits_in_hwi_p): Likewise. + (double_int_mul): Likewise. + (double_int_mul_with_sign): Likewise. + (double_int_add): Likewise. + (double_int_sub): Likewise. + (double_int_neg): Likewise. + (double_int_div): Likewise. + (double_int_sdiv): Likewise. + (double_int_udiv): Likewise. + (double_int_mod): Likewise. + (double_int_smod): Likewise. + (double_int_umod): Likewise. + (double_int_divmod): Likewise. + (double_int_sdivmod): Likewise. + (double_int_udivmod): Likewise. + (double_int_multiple_of): Likewise. + (double_int_setbit): Likewise. + (double_int_ctz): Likewise. + (double_int_not): Likewise. + (double_int_ior): Likewise. + (double_int_and): Likewise. + (double_int_and_not): Likewise. + (double_int_xor): Likewise. + (double_int_lshift): Likewise. + (double_int_rshift): Likewise. + (double_int_lrotate): Likewise. + (double_int_rrotate): Likewise. + (double_int_cmp): Likewise. + (double_int_scmp): Likewise. + (double_int_ucmp): Likewise. + (double_int_max): Likewise. + (double_int_smax): Likewise. + (double_int_umax): Likewise. + (double_int_min): Likewise. + (double_int_smin): Likewise. + (double_int_umin): Likewise. + (double_int_ext): Likewise. + (double_int_sext): Likewise. + (double_int_zext): Likewise. + (double_int_mask): Likewise. + (double_int_max_value): Likewise. + (double_int_min_value): Likewise. + (double_int_zero_p): Likewise. + (double_int_one_p): Likewise. + (double_int_minus_one_p): Likewise. + (double_int_equal_p): Likewise. + (double_int_popcount): Likewise. + * hash-table.c + (double_int_mask): Reuse implementation for double_int::mask. + (double_int_max_value): Likewise. + (double_int_min_value): Likewise. + (double_int_ext): Likewise. + (double_int_zext): Likewise. + (double_int_sext): Likewise. + (double_int_mul_with_sign): Likewise. + (double_int_divmod): Likewise. + (double_int_sdivmod): Likewise. + (double_int_udivmod): Likewise. + (double_int_div): Likewise. + (double_int_sdiv): Likewise. + (double_int_udiv): Likewise. + (double_int_mod): Likewise. + (double_int_smod): Likewise. + (double_int_umod): Likewise. + (double_int_multiple_of): Likewise. + (double_int_lshift): Likewise. + (double_int_rshift): Likewise. + (double_int_lrotate): Likewise. + (double_int_rrotate): Likewise. + (double_int_cmp): Likewise. + (double_int_ucmp): Likewise. + (double_int_scmp): Likewise. + (double_int_max): Likewise. + (double_int_smax): Likewise. + (double_int_umax): Likewise. + (double_int_min): Likewise. + (double_int_smin): Likewise. + (double_int_umin): Likewise. + (double_int_min): Likewise. + (double_int_min): Likewise. + (double_int_min): Likewise. + (double_int_min): Likewise. + (double_int_min): Likewise. + (double_int_min): Likewise. + (double_int::alshift): New. + (double_int::arshift): New. + (double_int::llshift): New. + (double_int::lrshift): New. + (double_int::ult): New. + (double_int::ugt): New. + (double_int::slt): New. + (double_int::sgt): New. + (double_int_setbit): Reuse implementation for double_int::set_bit, + which avoids a name conflict with a macro. + (double_int_double_int_ctz): Reuse implementation for + double_int::trailing_zeros. + (double_int_fits_in_shwi_p): Reuse implementation for + double_int::fits_signed. + (double_int_fits_in_hwi_p): Reuse implementation for double_int::fits. + (double_int_mul): Reuse implementation for binary + double_int::operator *. + (double_int_add): Likewise. + (double_int_sub): Likewise. + (double_int_neg): Reuse implementation for unary + double_int::operator -. + (double_int_max_value): Likewise. + * fixed-value.c: Change to use member functions introduced above. + +2012-08-14 Lawrence Crowl <crowl@google.com> + + Merge cxx-conversion branch. Support tree macro calling + from gdb. + + * tree.h (tree_check): New. + (TREE_CHECK): Use inline function above instead of __extension__. + (tree_not_check): New. + (TREE_NOT_CHECK): Use inline function above instead of __extension__. + (tree_check2): New. + (TREE_CHECK2): Use inline function above instead of __extension__. + (tree_not_check2): New. + (TREE_NOT_CHECK2): Use inline function above instead of __extension__. + (tree_check3): New. + (TREE_CHECK3): Use inline function above instead of __extension__. + (tree_not_check3): New. + (TREE_NOT_CHECK3): Use inline function above instead of __extension__. + (tree_check4): New. + (TREE_CHECK4): Use inline function above instead of __extension__. + (tree_not_check4): New. + (TREE_NOT_CHECK4): Use inline function above instead of __extension__. + (tree_check5): New. + (TREE_CHECK5): Use inline function above instead of __extension__. + (tree_not_check5): New. + (TREE_NOT_CHECK5): Use inline function above instead of __extension__. + (contains_struct_check): New. + (CONTAINS_STRUCT_CHECK): Use inline function above instead of + __extension__. + (tree_class_check): New. + (TREE_CLASS_CHECK): Use inline function above instead of __extension__. + (tree_range_check): New. + (TREE_RANGE_CHECK): Use inline function above instead of __extension__. + (omp_clause_subcode_check): New. + (OMP_CLAUSE_SUBCODE_CHECK): Use inline function above instead of + __extension__. + (omp_clause_range_check): New. + (OMP_CLAUSE_RANGE_CHECK): Use inline function above instead of + __extension__. + (expr_check): New. + (EXPR_CHECK): Use inline function above instead of __extension__. + (non_type_check): New. + (NON_TYPE_CHECK): Use inline function above instead of __extension__. + (tree_vec_elt_check): New. + (TREE_VEC_ELT_CHECK): Use inline function above instead of + __extension__. + (omp_clause_elt_check): New. + (OMP_CLAUSE_ELT_CHECK): Use inline function above instead of + __extension__. + (tree_operand_check): New. + (TREE_OPERAND_CHECK): Use inline function above instead of + __extension__. + (tree_operand_check_code): New. + (TREE_OPERAND_CHECK_CODE): Use inline function above instead of + __extension__. + (TREE_CHAIN): Simplify implementation. + (TREE_TYPE): Simplify implementation. + (tree_operand_length): Move for compilation dependences. + * gdbinit.in: (macro define __FILE__): New. + (macro define __LINE__): New. + (skip "tree.h"): New. + 2012-08-14 Uros Bizjak <ubizjak@gmail.com> * config/i386/i386.md (enabled): Add comment with explanation diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 65a49d7..54d4e56 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -223,13 +223,6 @@ RANLIB_FLAGS = @ranlib_flags@ HOST_LIBS = @HOST_LIBS@ # The name of the compiler to use. -ENABLE_BUILD_WITH_CXX = @ENABLE_BUILD_WITH_CXX@ -ifneq ($(ENABLE_BUILD_WITH_CXX),yes) -COMPILER = $(CC) -COMPILER_FLAGS = $(CFLAGS) -LINKER = $(CC) -LINKER_FLAGS = $(CFLAGS) -else COMPILER = $(CXX) COMPILER_FLAGS = $(CXXFLAGS) # If HOST_LIBS is set, then the user is controlling the libraries to @@ -243,7 +236,6 @@ else LINKER = $(CC) LINKER_FLAGS = $(CFLAGS) endif -endif # ------------------------------------------- # Programs which operate on the build machine @@ -336,13 +328,8 @@ CLOOGINC = @CLOOGINC@ enable_lto = @enable_lto@ # Compiler and flags needed for plugin support -ifneq ($(ENABLE_BUILD_WITH_CXX),yes) -PLUGINCC = @CC@ -PLUGINCFLAGS = @CFLAGS@ -else PLUGINCC = @CXX@ PLUGINCFLAGS = @CXXFLAGS@ -endif # Libs and linker options needed for plugin support PLUGINLIBS = @pluginlibs@ @@ -732,22 +719,12 @@ BUILD_CFLAGS= @BUILD_CFLAGS@ -DGENERATOR_FILE BUILD_CXXFLAGS = @BUILD_CXXFLAGS@ -DGENERATOR_FILE # Native compiler that we use. This may be C++ some day. -ifneq ($(ENABLE_BUILD_WITH_CXX),yes) -COMPILER_FOR_BUILD = $(CC_FOR_BUILD) -BUILD_COMPILERFLAGS = $(BUILD_CFLAGS) -else COMPILER_FOR_BUILD = $(CXX_FOR_BUILD) BUILD_COMPILERFLAGS = $(BUILD_CXXFLAGS) -endif # Native linker that we use. -ifneq ($(ENABLE_BUILD_WITH_CXX),yes) -LINKER_FOR_BUILD = $(CC_FOR_BUILD) -BUILD_LINKERFLAGS = $(BUILD_CFLAGS) -else LINKER_FOR_BUILD = $(CXX_FOR_BUILD) BUILD_LINKERFLAGS = $(BUILD_CXXFLAGS) -endif # Native linker and preprocessor flags. For x-fragment overrides. BUILD_LDFLAGS=@BUILD_LDFLAGS@ @@ -839,6 +816,7 @@ endif # Shorthand variables for dependency lists. VEC_H = vec.h statistics.h +HASH_TABLE_H = $(HASHTAB_H) hash-table.h EXCEPT_H = except.h $(HASHTAB_H) vecprim.h vecir.h TARGET_DEF = target.def target-hooks-macros.h C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h @@ -998,18 +976,10 @@ ALL_CXXFLAGS = $(T_CFLAGS) $(CFLAGS-$@) $(CXXFLAGS) $(INTERNAL_CFLAGS) \ ALL_CPPFLAGS = $(INCLUDES) $(CPPFLAGS) # This is the variable to use when using $(COMPILER). -ifneq ($(ENABLE_BUILD_WITH_CXX),yes) -ALL_COMPILERFLAGS = $(ALL_CFLAGS) -else ALL_COMPILERFLAGS = $(ALL_CXXFLAGS) -endif # This is the variable to use when using $(LINKER). -ifneq ($(ENABLE_BUILD_WITH_CXX),yes) -ALL_LINKERFLAGS = $(ALL_CFLAGS) -else ALL_LINKERFLAGS = $(ALL_CXXFLAGS) -endif # Build and host support libraries. LIBIBERTY = ../libiberty/libiberty.a @@ -1466,7 +1436,8 @@ OBJS-libcommon = diagnostic.o pretty-print.o intl.o input.o version.o # Objects in libcommon-target.a, used by drivers and by the core # compiler and containing target-dependent code. OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \ - opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o + opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \ + hash-table.o # This lists all host objects for the front ends. ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS)) @@ -2224,7 +2195,7 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \ $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \ $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \ - $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) \ + $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) $(TREE_DUMP_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(FUNCTION_H) tree-ssa-sccvn.h \ $(CGRAPH_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) tree-ssa-structalias.o: tree-ssa-structalias.c \ @@ -2260,7 +2231,7 @@ tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(GIMPLE_PRETTY_PRINT_H) tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h dumpfile.h \ - $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) $(HASHTAB_H) \ + $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) $(HASH_TABLE_H) \ $(TREE_PRETTY_PRINT_H) tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h dumpfile.h \ @@ -2321,7 +2292,7 @@ tree-ssa-threadedge.o : tree-ssa-threadedge.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-ssa-propagate.h langhooks.h \ $(PARAMS_H) tree-ssa-threadupdate.o : tree-ssa-threadupdate.c $(TREE_FLOW_H) $(CONFIG_H) \ - $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ + $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(HASH_TABLE_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h dumpfile.h \ $(BASIC_BLOCK_H) $(FLAGS_H) $(CFGLOOP_H) tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ @@ -2343,7 +2314,7 @@ tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \ $(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ - $(CFGLOOP_H) alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) \ + $(CFGLOOP_H) alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASH_TABLE_H) \ $(GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \ $(DBGCNT_H) tree-scalar-evolution.h $(GIMPLE_PRETTY_PRINT_H) tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ @@ -2927,8 +2898,8 @@ ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \ coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \ $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \ $(FUNCTION_H) $(BASIC_BLOCK_H) toplev.h $(DIAGNOSTIC_CORE_H) $(GGC_H) langhooks.h $(COVERAGE_H) \ - $(HASHTAB_H) tree-iterator.h $(CGRAPH_H) gcov-io.c $(TM_P_H) \ - $(DIAGNOSTIC_CORE_H) intl.h gt-coverage.h $(TARGET_H) + tree-iterator.h $(CGRAPH_H) gcov-io.c $(TM_P_H) \ + $(DIAGNOSTIC_CORE_H) intl.h gt-coverage.h $(TARGET_H) $(HASH_TABLE_H) cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) $(RTL_H) \ $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) \ $(EMIT_RTL_H) $(DIAGNOSTIC_CORE_H) $(FUNCTION_H) \ @@ -2999,7 +2970,8 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(TM_P_H) \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h $(PARAMS_H) \ - tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(DIAGNOSTIC_CORE_H) \ + tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) \ + $(DIAGNOSTIC_CORE_H) $(HASH_TABLE_H) \ $(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h tree-ssa-strlen.o : tree-ssa-strlen.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_FLOW_H) $(TREE_PASS_H) domwalk.h alloc-pool.h tree-ssa-propagate.h \ @@ -3153,6 +3125,8 @@ bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASHTAB_H) vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H) $(GGC_H) \ $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) +hash-table.o : hash-table.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(HASHTAB_H) reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \ $(FLAGS_H) $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) \ hard-reg-set.h insn-config.h $(REGS_H) $(FUNCTION_H) real.h \ diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 1b1bca8..cd35cd1 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -2921,7 +2921,7 @@ finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data) = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (TREE_OPERAND (TREE_OPERAND (ret_val, 0), 1)), - 1)->value; + 1).value; else ret_val = TREE_OPERAND (TREE_OPERAND (ret_val, 0), 1); } @@ -2980,7 +2980,7 @@ finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data) TREE_OPERAND (alloc, 0), VEC_index (constructor_elt, CONSTRUCTOR_ELTS (TREE_OPERAND (alloc, 1)), - 0)->value); + 0).value); /* Build a modified CONSTRUCTOR that references NEW_VAR. */ p_array = TYPE_FIELDS (TREE_TYPE (alloc)); @@ -2990,7 +2990,7 @@ finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data) VEC_index (constructor_elt, CONSTRUCTOR_ELTS (TREE_OPERAND (alloc, 1)), - 1)->value); + 1).value); new_ret = build_constructor (TREE_TYPE (alloc), v); } else diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index cd91873..c9b29ad 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -4491,10 +4491,10 @@ convert (tree type, tree expr) inner expression. */ if (TREE_CODE (expr) == CONSTRUCTOR && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (expr)) - && VEC_index (constructor_elt, CONSTRUCTOR_ELTS (expr), 0)->index + && VEC_index (constructor_elt, CONSTRUCTOR_ELTS (expr), 0).index == TYPE_FIELDS (etype)) unpadded - = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (expr), 0)->value; + = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (expr), 0).value; /* Otherwise, build an explicit component reference. */ else @@ -5047,7 +5047,7 @@ remove_conversions (tree exp, bool true_address) && TYPE_JUSTIFIED_MODULAR_P (TREE_TYPE (exp))) return remove_conversions (VEC_index (constructor_elt, - CONSTRUCTOR_ELTS (exp), 0)->value, + CONSTRUCTOR_ELTS (exp), 0).value, true); break; diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index a8a21a6..4578114 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -441,7 +441,7 @@ compare_fat_pointers (location_t loc, tree result_type, tree p1, tree p2) /* The constant folder doesn't fold fat pointer types so we do it here. */ if (TREE_CODE (p1) == CONSTRUCTOR) - p1_array = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p1), 0)->value; + p1_array = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p1), 0).value; else p1_array = build_component_ref (p1, NULL_TREE, TYPE_FIELDS (TREE_TYPE (p1)), true); @@ -452,7 +452,7 @@ compare_fat_pointers (location_t loc, tree result_type, tree p1, tree p2) null_pointer_node)); if (TREE_CODE (p2) == CONSTRUCTOR) - p2_array = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p2), 0)->value; + p2_array = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p2), 0).value; else p2_array = build_component_ref (p2, NULL_TREE, TYPE_FIELDS (TREE_TYPE (p2)), true); @@ -473,14 +473,14 @@ compare_fat_pointers (location_t loc, tree result_type, tree p1, tree p2) = fold_build2_loc (loc, EQ_EXPR, result_type, p1_array, p2_array); if (TREE_CODE (p1) == CONSTRUCTOR) - p1_bounds = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p1), 1)->value; + p1_bounds = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p1), 1).value; else p1_bounds = build_component_ref (p1, NULL_TREE, DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (p1))), true); if (TREE_CODE (p2) == CONSTRUCTOR) - p2_bounds = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p2), 1)->value; + p2_bounds = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (p2), 1).value; else p2_bounds = build_component_ref (p2, NULL_TREE, @@ -1336,7 +1336,7 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand) { result = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (operand), - 0)->value; + 0).value; result = convert (build_pointer_type (TREE_TYPE (operand)), build_unary_op (ADDR_EXPR, NULL_TREE, result)); break; @@ -2676,9 +2676,9 @@ gnat_stabilize_reference (tree ref, bool force, bool *success) && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (ref)) == 1) { tree index - = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ref), 0)->index; + = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ref), 0).index; tree value - = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ref), 0)->value; + = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ref), 0).value; result = build_constructor_single (type, index, gnat_stabilize_reference_1 (value, diff --git a/gcc/alias.c b/gcc/alias.c index a105004..de7640f 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -852,8 +852,8 @@ new_alias_set (void) if (flag_strict_aliasing) { if (alias_sets == 0) - VEC_safe_push (alias_set_entry, gc, alias_sets, 0); - VEC_safe_push (alias_set_entry, gc, alias_sets, 0); + VEC_safe_push (alias_set_entry, gc, alias_sets, (alias_set_entry) 0); + VEC_safe_push (alias_set_entry, gc, alias_sets, (alias_set_entry) 0); return VEC_length (alias_set_entry, alias_sets) - 1; } else diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 8183ce2..6e1d091 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -33,19 +33,19 @@ along with GCC; see the file COPYING3. If not see typedef HOST_WIDEST_INT gcov_type; /* Control flow edge information. */ -struct GTY(()) edge_def { +struct GTY((user)) edge_def { /* The two blocks at the ends of the edge. */ basic_block src; basic_block dest; /* Instructions queued on the edge. */ union edge_def_insns { - gimple_seq GTY ((tag ("true"))) g; - rtx GTY ((tag ("false"))) r; - } GTY ((desc ("current_ir_type () == IR_GIMPLE"))) insns; + gimple_seq g; + rtx r; + } insns; /* Auxiliary info specific to a pass. */ - PTR GTY ((skip (""))) aux; + PTR aux; /* Location of any goto implicit in the edge and associated BLOCK. */ tree goto_block; @@ -65,6 +65,11 @@ DEF_VEC_P(edge); DEF_VEC_ALLOC_P(edge,gc); DEF_VEC_ALLOC_P(edge,heap); +/* Garbage collection and PCH support for edge_def. */ +extern void gt_ggc_mx (edge_def *e); +extern void gt_pch_nx (edge_def *e); +extern void gt_pch_nx (edge_def *e, gt_pointer_operator, void *); + /* Masks for edge.flags. */ #define DEF_EDGE_FLAG(NAME,IDX) EDGE_##NAME = 1 << IDX , enum cfg_edge_flags { diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index a002541..ab3eb0a 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -8392,7 +8392,7 @@ parse_optimize_options (tree args, bool attr_p) /* Build up argv vector. Just in case the string is stored away, use garbage collected strings. */ VEC_truncate (const_char_p, optimize_args, 0); - VEC_safe_push (const_char_p, gc, optimize_args, NULL); + VEC_safe_push (const_char_p, gc, optimize_args, (const_char_p)NULL); for (ap = args; ap != NULL_TREE; ap = TREE_CHAIN (ap)) { @@ -9390,10 +9390,10 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default) constructor_elt *ce; bool fold_p = false; - if (VEC_index (constructor_elt, v, 0)->index) + if (VEC_index (constructor_elt, v, 0).index) maxindex = fold_convert_loc (input_location, sizetype, VEC_index (constructor_elt, - v, 0)->index); + v, 0).index); curindex = maxindex; for (cnt = 1; diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index 830ca81..77ed0f0 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -1209,9 +1209,9 @@ c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) + VEC_length (pragma_ns_name, registered_pp_pragmas))) { *space = VEC_index (pragma_ns_name, registered_pp_pragmas, - id - PRAGMA_FIRST_EXTERNAL)->space; + id - PRAGMA_FIRST_EXTERNAL).space; *name = VEC_index (pragma_ns_name, registered_pp_pragmas, - id - PRAGMA_FIRST_EXTERNAL)->name; + id - PRAGMA_FIRST_EXTERNAL).name; return; } @@ -1334,7 +1334,7 @@ c_invoke_pragma_handler (unsigned int id) pragma_handler_2arg handler_2arg; id -= PRAGMA_FIRST_EXTERNAL; - ihandler = VEC_index (internal_pragma_handler, registered_pragmas, id); + ihandler = &VEC_index (internal_pragma_handler, registered_pragmas, id); if (ihandler->extra_data) { handler_2arg = ihandler->handler.handler_2arg; diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 09df65d..e5d17b7 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -3932,7 +3932,7 @@ add_flexible_array_elts_to_size (tree decl, tree init) if (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init))) return; - elt = VEC_last (constructor_elt, CONSTRUCTOR_ELTS (init))->value; + elt = VEC_last (constructor_elt, CONSTRUCTOR_ELTS (init)).value; type = TREE_TYPE (elt); if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == NULL_TREE diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 2237749..34d5a34 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -6529,9 +6529,9 @@ c_parser_postfix_expression (c_parser *parser) break; } - e1_p = VEC_index (c_expr_t, cexpr_list, 0); - e2_p = VEC_index (c_expr_t, cexpr_list, 1); - e3_p = VEC_index (c_expr_t, cexpr_list, 2); + e1_p = &VEC_index (c_expr_t, cexpr_list, 0); + e2_p = &VEC_index (c_expr_t, cexpr_list, 1); + e3_p = &VEC_index (c_expr_t, cexpr_list, 2); c = e1_p->value; mark_exp_read (e2_p->value); @@ -6611,8 +6611,8 @@ c_parser_postfix_expression (c_parser *parser) break; } - e1_p = VEC_index (c_expr_t, cexpr_list, 0); - e2_p = VEC_index (c_expr_t, cexpr_list, 1); + e1_p = &VEC_index (c_expr_t, cexpr_list, 0); + e2_p = &VEC_index (c_expr_t, cexpr_list, 1); mark_exp_read (e1_p->value); if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR) @@ -6671,15 +6671,15 @@ c_parser_postfix_expression (c_parser *parser) if (VEC_length (c_expr_t, cexpr_list) == 2) expr.value = c_build_vec_perm_expr - (loc, VEC_index (c_expr_t, cexpr_list, 0)->value, - NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value); + (loc, VEC_index (c_expr_t, cexpr_list, 0).value, + NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1).value); else if (VEC_length (c_expr_t, cexpr_list) == 3) expr.value = c_build_vec_perm_expr - (loc, VEC_index (c_expr_t, cexpr_list, 0)->value, - VEC_index (c_expr_t, cexpr_list, 1)->value, - VEC_index (c_expr_t, cexpr_list, 2)->value); + (loc, VEC_index (c_expr_t, cexpr_list, 0).value, + VEC_index (c_expr_t, cexpr_list, 1).value, + VEC_index (c_expr_t, cexpr_list, 2).value); else { error_at (loc, "wrong number of arguments to " diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index c2f713e..5b710c3 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -6950,7 +6950,7 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) bool constructor_zeroinit = (VEC_length (constructor_elt, constructor_elements) == 1 && integer_zerop - (VEC_index (constructor_elt, constructor_elements, 0)->value)); + (VEC_index (constructor_elt, constructor_elements, 0).value)); /* Do not warn for flexible array members or zero-length arrays. */ while (constructor_unfilled_fields @@ -6997,10 +6997,10 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) else if (VEC_length (constructor_elt,constructor_elements) != 1) { error_init ("extra elements in scalar initializer"); - ret.value = VEC_index (constructor_elt,constructor_elements,0)->value; + ret.value = VEC_index (constructor_elt,constructor_elements,0).value; } else - ret.value = VEC_index (constructor_elt,constructor_elements,0)->value; + ret.value = VEC_index (constructor_elt,constructor_elements,0).value; } else { @@ -7671,9 +7671,9 @@ find_init_member (tree field, struct obstack * braced_init_obstack) else if (TREE_CODE (constructor_type) == UNION_TYPE) { if (!VEC_empty (constructor_elt, constructor_elements) - && (VEC_last (constructor_elt, constructor_elements)->index + && (VEC_last (constructor_elt, constructor_elements).index == field)) - return VEC_last (constructor_elt, constructor_elements)->value; + return VEC_last (constructor_elt, constructor_elements).value; } return 0; } @@ -7856,7 +7856,7 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, if (!implicit) { if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt, - constructor_elements)->value)) + constructor_elements).value)) warning_init (0, "initialized field with side-effects overwritten"); else if (warn_override_init) diff --git a/gcc/combine.c b/gcc/combine.c index 2b91eb9..3c4dee8 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -1587,7 +1587,7 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data) (DF_LR_IN (ENTRY_BLOCK_PTR->next_bb), REGNO (x)) && HWI_COMPUTABLE_MODE_P (GET_MODE (x))) { - reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x)); + reg_stat_type *rsp = &VEC_index (reg_stat_type, reg_stat, REGNO (x)); if (set == 0 || GET_CODE (set) == CLOBBER) { @@ -3635,21 +3635,21 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, && ! (temp = SET_DEST (XVECEXP (newpat, 0, 1)), (REG_P (temp) && VEC_index (reg_stat_type, reg_stat, - REGNO (temp))->nonzero_bits != 0 + REGNO (temp)).nonzero_bits != 0 && GET_MODE_PRECISION (GET_MODE (temp)) < BITS_PER_WORD && GET_MODE_PRECISION (GET_MODE (temp)) < HOST_BITS_PER_INT && (VEC_index (reg_stat_type, reg_stat, - REGNO (temp))->nonzero_bits + REGNO (temp)).nonzero_bits != GET_MODE_MASK (word_mode)))) && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG && (temp = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))), (REG_P (temp) && VEC_index (reg_stat_type, reg_stat, - REGNO (temp))->nonzero_bits != 0 + REGNO (temp)).nonzero_bits != 0 && GET_MODE_PRECISION (GET_MODE (temp)) < BITS_PER_WORD && GET_MODE_PRECISION (GET_MODE (temp)) < HOST_BITS_PER_INT && (VEC_index (reg_stat_type, reg_stat, - REGNO (temp))->nonzero_bits + REGNO (temp)).nonzero_bits != GET_MODE_MASK (word_mode))))) && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)), SET_SRC (XVECEXP (newpat, 0, 1))) @@ -9425,7 +9425,7 @@ reg_nonzero_bits_for_combine (const_rtx x, enum machine_mode mode, value. Otherwise, use the previously-computed global nonzero bits for this register. */ - rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x)); + rsp = &VEC_index (reg_stat_type, reg_stat, REGNO (x)); if (rsp->last_set_value != 0 && (rsp->last_set_mode == mode || (GET_MODE_CLASS (rsp->last_set_mode) == MODE_INT @@ -9494,7 +9494,7 @@ reg_num_sign_bit_copies_for_combine (const_rtx x, enum machine_mode mode, rtx tem; reg_stat_type *rsp; - rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x)); + rsp = &VEC_index (reg_stat_type, reg_stat, REGNO (x)); if (rsp->last_set_value != 0 && rsp->last_set_mode == mode && ((rsp->last_set_label >= label_tick_ebb_start @@ -12033,7 +12033,7 @@ update_table_tick (rtx x) for (r = regno; r < endregno; r++) { - reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, r); + reg_stat_type *rsp = &VEC_index (reg_stat_type, reg_stat, r); rsp->last_set_table_tick = label_tick; } @@ -12135,7 +12135,7 @@ record_value_for_reg (rtx reg, rtx insn, rtx value) register. */ for (i = regno; i < endregno; i++) { - rsp = VEC_index (reg_stat_type, reg_stat, i); + rsp = &VEC_index (reg_stat_type, reg_stat, i); if (insn) rsp->last_set = insn; @@ -12161,7 +12161,7 @@ record_value_for_reg (rtx reg, rtx insn, rtx value) for (i = regno; i < endregno; i++) { - rsp = VEC_index (reg_stat_type, reg_stat, i); + rsp = &VEC_index (reg_stat_type, reg_stat, i); rsp->last_set_label = label_tick; if (!insn || (value && rsp->last_set_table_tick >= label_tick_ebb_start)) @@ -12173,7 +12173,7 @@ record_value_for_reg (rtx reg, rtx insn, rtx value) /* The value being assigned might refer to X (like in "x++;"). In that case, we must replace it with (clobber (const_int 0)) to prevent infinite loops. */ - rsp = VEC_index (reg_stat_type, reg_stat, regno); + rsp = &VEC_index (reg_stat_type, reg_stat, regno); if (value && !get_last_value_validate (&value, insn, label_tick, 0)) { value = copy_rtx (value); @@ -12271,7 +12271,7 @@ record_dead_and_set_regs (rtx insn) { reg_stat_type *rsp; - rsp = VEC_index (reg_stat_type, reg_stat, i); + rsp = &VEC_index (reg_stat_type, reg_stat, i); rsp->last_death = insn; } } @@ -12286,7 +12286,7 @@ record_dead_and_set_regs (rtx insn) { reg_stat_type *rsp; - rsp = VEC_index (reg_stat_type, reg_stat, i); + rsp = &VEC_index (reg_stat_type, reg_stat, i); rsp->last_set_invalid = 1; rsp->last_set = insn; rsp->last_set_value = 0; @@ -12344,7 +12344,7 @@ record_promoted_value (rtx insn, rtx subreg) continue; } - rsp = VEC_index (reg_stat_type, reg_stat, regno); + rsp = &VEC_index (reg_stat_type, reg_stat, regno); if (rsp->last_set == insn) { if (SUBREG_PROMOTED_UNSIGNED_P (subreg) > 0) @@ -12369,7 +12369,7 @@ record_promoted_value (rtx insn, rtx subreg) static bool reg_truncated_to_mode (enum machine_mode mode, const_rtx x) { - reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x)); + reg_stat_type *rsp = &VEC_index (reg_stat_type, reg_stat, REGNO (x)); enum machine_mode truncated = rsp->truncated_to_mode; if (truncated == 0 @@ -12414,7 +12414,7 @@ record_truncated_value (rtx *p, void *data ATTRIBUTE_UNUSED) else return 0; - rsp = VEC_index (reg_stat_type, reg_stat, REGNO (x)); + rsp = &VEC_index (reg_stat_type, reg_stat, REGNO (x)); if (rsp->truncated_to_mode == 0 || rsp->truncation_label < label_tick_ebb_start || (GET_MODE_SIZE (truncated_mode) @@ -12493,7 +12493,7 @@ get_last_value_validate (rtx *loc, rtx insn, int tick, int replace) for (j = regno; j < endregno; j++) { - reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, j); + reg_stat_type *rsp = &VEC_index (reg_stat_type, reg_stat, j); if (rsp->last_set_invalid /* If this is a pseudo-register that was only set once and not live at the beginning of the function, it is always valid. */ @@ -12597,7 +12597,7 @@ get_last_value (const_rtx x) return 0; regno = REGNO (x); - rsp = VEC_index (reg_stat_type, reg_stat, regno); + rsp = &VEC_index (reg_stat_type, reg_stat, regno); value = rsp->last_set_value; /* If we don't have a value, or if it isn't for this basic block and @@ -12661,7 +12661,7 @@ use_crosses_set_p (const_rtx x, int from_luid) #endif for (; regno < endreg; regno++) { - reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, regno); + reg_stat_type *rsp = &VEC_index (reg_stat_type, reg_stat, regno); if (rsp->last_set && rsp->last_set_label == label_tick && DF_INSN_LUID (rsp->last_set) > from_luid) @@ -12909,7 +12909,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx to_insn, if (code == REG) { unsigned int regno = REGNO (x); - rtx where_dead = VEC_index (reg_stat_type, reg_stat, regno)->last_death; + rtx where_dead = VEC_index (reg_stat_type, reg_stat, regno).last_death; /* Don't move the register if it gets killed in between from and to. */ if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn) @@ -13524,7 +13524,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, if (place && REG_NOTE_KIND (note) == REG_DEAD) { unsigned int regno = REGNO (XEXP (note, 0)); - reg_stat_type *rsp = VEC_index (reg_stat_type, reg_stat, regno); + reg_stat_type *rsp = &VEC_index (reg_stat_type, reg_stat, regno); if (dead_or_set_p (place, XEXP (note, 0)) || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place))) diff --git a/gcc/config.in b/gcc/config.in index 7b12b4b..6d986be 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -45,12 +45,6 @@ #endif -/* Define if building with C++. */ -#ifndef USED_FOR_TARGET -#undef ENABLE_BUILD_WITH_CXX -#endif - - /* Define if you want more run-time sanity checks. This one gets a grab bag of miscellaneous but relatively cheap checks. */ #ifndef USED_FOR_TARGET diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 3a4b8af..0a0d702 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -3478,7 +3478,7 @@ hwloop_optimize (hwloop_info loop) /* If we have to insert the LSETUP before a jump, count that jump in the length. */ if (VEC_length (edge, loop->incoming) > 1 - || !(VEC_last (edge, loop->incoming)->flags & EDGE_FALLTHRU)) + || !(VEC_last (edge, loop->incoming).flags & EDGE_FALLTHRU)) { gcc_assert (JUMP_P (insn)); insn = PREV_INSN (insn); @@ -3747,7 +3747,7 @@ hwloop_optimize (hwloop_info loop) { rtx prev = BB_END (loop->incoming_src); if (VEC_length (edge, loop->incoming) > 1 - || !(VEC_last (edge, loop->incoming)->flags & EDGE_FALLTHRU)) + || !(VEC_last (edge, loop->incoming).flags & EDGE_FALLTHRU)) { gcc_assert (JUMP_P (prev)); prev = PREV_INSN (prev); diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index a189a1d..1905504 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -126,7 +126,7 @@ DEF_VEC_ALLOC_O(c6x_sched_insn_info, heap); static VEC(c6x_sched_insn_info, heap) *insn_info; #define INSN_INFO_LENGTH (VEC_length (c6x_sched_insn_info, insn_info)) -#define INSN_INFO_ENTRY(N) (*VEC_index (c6x_sched_insn_info, insn_info, (N))) +#define INSN_INFO_ENTRY(N) (VEC_index (c6x_sched_insn_info, insn_info, (N))) static bool done_cfi_sections; @@ -3448,8 +3448,8 @@ try_rename_operands (rtx head, rtx tail, unit_req_table reqs, rtx insn, { unsigned int mask1, mask2, mask_changed; int count, side1, side2, req1, req2; - insn_rr_info *this_rr = VEC_index (insn_rr_info, insn_rr, - INSN_UID (chain->insn)); + insn_rr_info *this_rr = &VEC_index (insn_rr_info, insn_rr, + INSN_UID (chain->insn)); count = get_unit_reqs (chain->insn, &req1, &side1, &req2, &side2); @@ -3555,7 +3555,7 @@ reshuffle_units (basic_block loop) if (!get_unit_operand_masks (insn, &mask1, &mask2)) continue; - info = VEC_index (insn_rr_info, insn_rr, INSN_UID (insn)); + info = &VEC_index (insn_rr_info, insn_rr, INSN_UID (insn)); if (info->op_info == NULL) continue; diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f36f65b..3688136 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -3971,7 +3971,8 @@ mips_multi_start (void) static struct mips_multi_member * mips_multi_add (void) { - return VEC_safe_push (mips_multi_member, heap, mips_multi_members, 0); + return VEC_safe_push (mips_multi_member, heap, mips_multi_members, + (struct mips_multi_member *) 0); } /* Add a normal insn with the given asm format to the current multi-insn @@ -4026,7 +4027,7 @@ mips_multi_copy_insn (unsigned int i) struct mips_multi_member *member; member = mips_multi_add (); - memcpy (member, VEC_index (mips_multi_member, mips_multi_members, i), + memcpy (member, &VEC_index (mips_multi_member, mips_multi_members, i), sizeof (*member)); gcc_assert (!member->is_label_p); } @@ -4038,7 +4039,7 @@ mips_multi_copy_insn (unsigned int i) static void mips_multi_set_operand (unsigned int i, unsigned int op, rtx x) { - VEC_index (mips_multi_member, mips_multi_members, i)->operands[op] = x; + VEC_index (mips_multi_member, mips_multi_members, i).operands[op] = x; } /* Write out the asm code for the current multi-insn sequence. */ diff --git a/gcc/configure b/gcc/configure index a457d3e..1585bae 100755 --- a/gcc/configure +++ b/gcc/configure @@ -766,7 +766,6 @@ enable_shared enable_fixed_point enable_decimal_float enable_multilib -ENABLE_BUILD_WITH_CXX coverage_flags valgrind_command valgrind_path_defines @@ -873,7 +872,6 @@ enable_werror_always enable_checking enable_coverage enable_gather_detailed_mem_stats -enable_build_with_cxx with_stabs enable_multilib enable___cxa_atexit @@ -1575,7 +1573,6 @@ Optional Features: Values are opt, noopt, default is noopt --enable-gather-detailed-mem-stats enable detailed memory allocation stats gathering - --enable-build-with-cxx build with C++ compiler instead of C compiler --enable-multilib enable library support for multiple ABIs --enable-__cxa_atexit enable __cxa_atexit for C++ --enable-decimal-float={no,yes,bid,dpd} @@ -6997,21 +6994,6 @@ _ACEOF # Miscenalleous configure options # ------------------------------- -# See if we are building gcc with C++. -# Check whether --enable-build-with-cxx was given. -if test "${enable_build_with_cxx+set}" = set; then : - enableval=$enable_build_with_cxx; ENABLE_BUILD_WITH_CXX=$enableval -else - ENABLE_BUILD_WITH_CXX=no -fi - - -if test "$ENABLE_BUILD_WITH_CXX" = "yes"; then - -$as_echo "#define ENABLE_BUILD_WITH_CXX 1" >>confdefs.h - -fi - # With stabs # Check whether --with-stabs was given. @@ -9516,6 +9498,12 @@ fi # g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different # iconv() prototype. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" @@ -10057,13 +10045,6 @@ fi fi -if test "$ENABLE_BUILD_WITH_CXX" = "yes"; then : - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - @@ -10219,169 +10200,12 @@ _ACEOF fi - ac_ext=c +ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -else - - - - - - am_save_CPPFLAGS="$CPPFLAGS" - - for element in $INCICONV; do - haveit= - for x in $CPPFLAGS; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 -$as_echo_n "checking for iconv... " >&6; } -if test "${am_cv_func_iconv+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <iconv.h> -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <iconv.h> -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - am_cv_lib_iconv=yes - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$am_save_LIBS" - fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 -$as_echo "$am_cv_func_iconv" >&6; } - if test "$am_cv_func_iconv" = yes; then - -$as_echo "#define HAVE_ICONV 1" >>confdefs.h - - fi - if test "$am_cv_lib_iconv" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 -$as_echo_n "checking how to link with libiconv... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 -$as_echo "$LIBICONV" >&6; } - else - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - - - - if test "$am_cv_func_iconv" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 -$as_echo_n "checking for iconv declaration... " >&6; } - if test "${am_cv_proto_iconv+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include <stdlib.h> -#include <iconv.h> -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - am_cv_proto_iconv_arg1="" -else - am_cv_proto_iconv_arg1="const" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" -fi - - am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:- - }$am_cv_proto_iconv" >&5 -$as_echo "${ac_t:- - }$am_cv_proto_iconv" >&6; } - -cat >>confdefs.h <<_ACEOF -#define ICONV_CONST $am_cv_proto_iconv_arg1 -_ACEOF - - fi - -fi # Until we have in-tree GNU iconv: LIBICONV_DEP= @@ -10767,14 +10591,13 @@ done # g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which hides the madvise() # prototype. -if test "$ENABLE_BUILD_WITH_CXX" = "yes"; then : - ac_ext=cpp +ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - for ac_func in madvise +for ac_func in madvise do ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5 @@ -10787,8 +10610,8 @@ else #undef $ac_tr_decl #define $ac_tr_decl 1 - #include "ansidecl.h" - #include "system.h" + #include "ansidecl.h" + #include "system.h" int @@ -10825,66 +10648,12 @@ fi done - ac_ext=c +ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -else - for ac_func in madvise -do - ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is declared" >&5 -$as_echo_n "checking whether $ac_func is declared... " >&6; } -if { as_var=gcc_cv_have_decl_$ac_func; eval "test \"\${$as_var+set}\" = set"; }; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#undef $ac_tr_decl -#define $ac_tr_decl 1 - - #include "ansidecl.h" - #include "system.h" - - -int -main () -{ -#ifndef $ac_func -char *(*pfn) = (char *(*)) $ac_func ; -#endif - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "gcc_cv_have_decl_$ac_func=yes" -else - eval "gcc_cv_have_decl_$ac_func=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } ; cat >>confdefs.h <<_ACEOF -#define $ac_tr_decl 1 -_ACEOF - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } ; cat >>confdefs.h <<_ACEOF -#define $ac_tr_decl 0 -_ACEOF - -fi - -done - - -fi # More time-related stuff. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct tms" >&5 @@ -17973,7 +17742,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17975 "configure" +#line 17744 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -18079,7 +17848,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 18081 "configure" +#line 17850 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/gcc/configure.ac b/gcc/configure.ac index e4069e8..579d9a8 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -596,18 +596,6 @@ AC_DEFINE_UNQUOTED(GATHER_STATISTICS, $gather_stats, # Miscenalleous configure options # ------------------------------- -# See if we are building gcc with C++. -AC_ARG_ENABLE(build-with-cxx, -[AS_HELP_STRING([--enable-build-with-cxx], - [build with C++ compiler instead of C compiler])], -ENABLE_BUILD_WITH_CXX=$enableval, -ENABLE_BUILD_WITH_CXX=no) -AC_SUBST(ENABLE_BUILD_WITH_CXX) -if test "$ENABLE_BUILD_WITH_CXX" = "yes"; then - AC_DEFINE(ENABLE_BUILD_WITH_CXX, 1, - [Define if building with C++.]) -fi - # With stabs AC_ARG_WITH(stabs, [AS_HELP_STRING([--with-stabs], @@ -1067,11 +1055,9 @@ AC_FUNC_FORK # g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different # iconv() prototype. -AS_IF([test "$ENABLE_BUILD_WITH_CXX" = "yes"], - [AC_LANG_PUSH([C++]) - AM_ICONV - AC_LANG_POP([C++])], - [AM_ICONV]) +AC_LANG_PUSH([C++]) +AM_ICONV +AC_LANG_POP([C++]) # Until we have in-tree GNU iconv: LIBICONV_DEP= @@ -1140,18 +1126,12 @@ gcc_AC_CHECK_DECLS(sigaltstack, , ,[ # g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which hides the madvise() # prototype. -AS_IF([test "$ENABLE_BUILD_WITH_CXX" = "yes"], - [AC_LANG_PUSH([C++]) - gcc_AC_CHECK_DECLS(madvise, , ,[ - #include "ansidecl.h" - #include "system.h" - ]) - AC_LANG_POP([C++])], - [gcc_AC_CHECK_DECLS(madvise, , ,[ - #include "ansidecl.h" - #include "system.h" - ]) +AC_LANG_PUSH([C++]) +gcc_AC_CHECK_DECLS(madvise, , ,[ + #include "ansidecl.h" + #include "system.h" ]) +AC_LANG_POP([C++]) # More time-related stuff. AC_CACHE_CHECK(for struct tms, ac_cv_struct_tms, [ diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 02578f6..a2ca9c8 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -196,5 +196,9 @@ enum memmodel /* Suppose that higher bits are target dependant. */ #define MEMMODEL_MASK ((1<<16)-1) +/* Support for user-provided GGC and PCH markers. The first parameter + is a pointer to a pointer, the second a cookie. */ +typedef void (*gt_pointer_operator) (void *, void *); + #endif /* coretypes.h */ diff --git a/gcc/coverage.c b/gcc/coverage.c index af52289..3fea525 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "coverage.h" #include "langhooks.h" -#include "hashtab.h" +#include "hash-table.h" #include "tree-iterator.h" #include "cgraph.h" #include "dumpfile.h" @@ -109,17 +109,11 @@ static unsigned bbg_file_stamp; /* Name of the count data (gcda) file. */ static char *da_file_name; -/* Hash table of count data. */ -static htab_t counts_hash = NULL; - /* The names of merge functions for counters. */ static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS; static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES; /* Forward declarations. */ -static hashval_t htab_counts_entry_hash (const void *); -static int htab_counts_entry_eq (const void *, const void *); -static void htab_counts_entry_del (void *); static void read_counts_file (void); static tree build_var (tree, tree, int); static void build_fn_info_type (tree, unsigned, tree); @@ -149,32 +143,31 @@ get_gcov_unsigned_t (void) return lang_hooks.types.type_for_mode (mode, true); } -static hashval_t -htab_counts_entry_hash (const void *of) +inline hashval_t +coverage_counts_entry_hash (const counts_entry_t *entry) { - const counts_entry_t *const entry = (const counts_entry_t *) of; - return entry->ident * GCOV_COUNTERS + entry->ctr; } -static int -htab_counts_entry_eq (const void *of1, const void *of2) +inline int +coverage_counts_entry_eq (const counts_entry_t *entry1, + const counts_entry_t *entry2) { - const counts_entry_t *const entry1 = (const counts_entry_t *) of1; - const counts_entry_t *const entry2 = (const counts_entry_t *) of2; - return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr; } -static void -htab_counts_entry_del (void *of) +inline void +coverage_counts_entry_del (counts_entry_t *entry) { - counts_entry_t *const entry = (counts_entry_t *) of; - free (entry->counts); free (entry); } +/* Hash table of count data. */ +static hash_table <counts_entry_t, coverage_counts_entry_hash, + coverage_counts_entry_eq, coverage_counts_entry_del> + counts_hash; + /* Read in the counts file, if available. */ static void @@ -214,9 +207,7 @@ read_counts_file (void) tag = gcov_read_unsigned (); bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag); - counts_hash = htab_create (10, - htab_counts_entry_hash, htab_counts_entry_eq, - htab_counts_entry_del); + counts_hash.create (10); while ((tag = gcov_read_unsigned ())) { gcov_unsigned_t length; @@ -264,8 +255,7 @@ read_counts_file (void) elt.ident = fn_ident; elt.ctr = GCOV_COUNTER_FOR_TAG (tag); - slot = (counts_entry_t **) htab_find_slot - (counts_hash, &elt, INSERT); + slot = counts_hash.find_slot (&elt, INSERT); entry = *slot; if (!entry) { @@ -285,14 +275,14 @@ read_counts_file (void) error ("checksum is (%x,%x) instead of (%x,%x)", entry->lineno_checksum, entry->cfg_checksum, lineno_checksum, cfg_checksum); - htab_delete (counts_hash); + counts_hash.dispose (); break; } else if (entry->summary.num != n_counts) { error ("Profile data for function %u is corrupted", fn_ident); error ("number of counters is %d instead of %d", entry->summary.num, n_counts); - htab_delete (counts_hash); + counts_hash.dispose (); break; } else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE) @@ -318,7 +308,7 @@ read_counts_file (void) { error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted", da_file_name); - htab_delete (counts_hash); + counts_hash.dispose (); break; } } @@ -336,7 +326,7 @@ get_coverage_counts (unsigned counter, unsigned expected, counts_entry_t *entry, elt; /* No hash table, no counts. */ - if (!counts_hash) + if (!counts_hash.is_created ()) { static int warned = 0; @@ -350,7 +340,7 @@ get_coverage_counts (unsigned counter, unsigned expected, elt.ident = current_function_funcdef_no + 1; elt.ctr = counter; - entry = (counts_entry_t *) htab_find (counts_hash, &elt); + entry = counts_hash.find (&elt); if (!entry || !entry->summary.num) /* The function was not emitted, or is weak and not chosen in the final executable. Silently fail, because there's nothing we diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b967735..15bedb4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-08-14 Diego Novillo <dnovillo@google.com> + + Merge from cxx-conversion branch. Re-write VEC in C++. + + * call.c (add_function_candidate): Remove const qualifier + from call to VEC_index. + 2012-08-10 Richard Guenther <rguenther@suse.de> * error.c (dump_expr): Handle anonymous SSA names. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5345f2b..7a72666 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1924,7 +1924,8 @@ add_function_candidate (struct z_candidate **candidates, for (i = 0; i < len; ++i) { - tree arg, argtype, to_type; + tree argtype, to_type; + tree arg; conversion *t; int is_this; @@ -1934,8 +1935,9 @@ add_function_candidate (struct z_candidate **candidates, if (i == 0 && first_arg != NULL_TREE) arg = first_arg; else - arg = VEC_index (tree, args, - i + skip - (first_arg != NULL_TREE ? 1 : 0)); + arg = CONST_CAST_TREE ( + VEC_index (tree, args, + i + skip - (first_arg != NULL_TREE ? 1 : 0))); argtype = lvalue_type (arg); is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 2f377c8..dfa2b52 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -8403,12 +8403,12 @@ build_vtbl_initializer (tree binfo, int new_position = (TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix + (TARGET_VTABLE_DATA_ENTRY_DISTANCE - 1)); - VEC_replace (constructor_elt, vid.inits, new_position, e); + VEC_replace (constructor_elt, vid.inits, new_position, *e); for (j = 1; j < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++j) { - constructor_elt *f = VEC_index (constructor_elt, vid.inits, - new_position - j); + constructor_elt *f = &VEC_index (constructor_elt, vid.inits, + new_position - j); f->index = NULL_TREE; f->value = build1 (NOP_EXPR, vtable_entry_type, null_pointer_node); @@ -8429,7 +8429,7 @@ build_vtbl_initializer (tree binfo, for (ix = VEC_length (constructor_elt, vid.inits) - 1; VEC_iterate (constructor_elt, vid.inits, ix, e); ix--, jx++) - VEC_replace (constructor_elt, *inits, jx, e); + VEC_replace (constructor_elt, *inits, jx, *e); /* Go through all the ordinary virtual functions, building up initializers. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b637643..5908996 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5282,7 +5282,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (str_init)) == 1) { str_init = VEC_index (constructor_elt, - CONSTRUCTOR_ELTS (str_init), 0)->value; + CONSTRUCTOR_ELTS (str_init), 0).value; } /* If it's a string literal, then it's the initializer for the array @@ -5372,7 +5372,7 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) return init; /* Recurse on this CONSTRUCTOR. */ - d.cur = VEC_index (constructor_elt, v, 0); + d.cur = &VEC_index (constructor_elt, v, 0); d.end = d.cur + VEC_length (constructor_elt, v); new_init = reshape_init_r (type, &d, true, complain); @@ -5917,7 +5917,7 @@ type_dependent_init_p (tree init) nelts = VEC_length (constructor_elt, elts); for (i = 0; i < nelts; ++i) if (type_dependent_init_p (VEC_index (constructor_elt, - elts, i)->value)) + elts, i).value)) return true; } else @@ -5947,7 +5947,7 @@ value_dependent_init_p (tree init) nelts = VEC_length (constructor_elt, elts); for (i = 0; i < nelts; ++i) if (value_dependent_init_p (VEC_index (constructor_elt, - elts, i)->value)) + elts, i).value)) return true; } else @@ -6896,7 +6896,7 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (initial_value))) { VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (initial_value); - tree value = VEC_index (constructor_elt, v, 0)->value; + tree value = VEC_index (constructor_elt, v, 0).value; if (TREE_CODE (value) == STRING_CST && VEC_length (constructor_elt, v) == 1) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d8c3305..a7f12ba7 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -273,7 +273,7 @@ cp_lexer_dump_tokens (FILE *file, VEC(cp_token,gc) *buffer, if (start_token > VEC_address (cp_token, buffer)) { - cp_lexer_print_token (file, VEC_index (cp_token, buffer, 0)); + cp_lexer_print_token (file, &VEC_index (cp_token, buffer, 0)); fprintf (file, " ... "); } @@ -313,8 +313,7 @@ cp_lexer_dump_tokens (FILE *file, VEC(cp_token,gc) *buffer, if (i == num && i < VEC_length (cp_token, buffer)) { fprintf (file, " ... "); - cp_lexer_print_token (file, VEC_index (cp_token, buffer, - VEC_length (cp_token, buffer) - 1)); + cp_lexer_print_token (file, &VEC_last (cp_token, buffer)); } fprintf (file, "\n"); @@ -1723,11 +1722,11 @@ cp_parser_context_new (cp_parser_context* next) /* Managing the unparsed function queues. */ #define unparsed_funs_with_default_args \ - VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_default_args + VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues).funs_with_default_args #define unparsed_funs_with_definitions \ - VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->funs_with_definitions + VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues).funs_with_definitions #define unparsed_nsdmis \ - VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues)->nsdmis + VEC_last (cp_unparsed_functions_entry, parser->unparsed_queues).nsdmis static void push_unparsed_function_queues (cp_parser *parser) @@ -8048,7 +8047,7 @@ record_lambda_scope (tree lambda) static void finish_lambda_scope (void) { - tree_int *p = VEC_last (tree_int, lambda_scope_stack); + tree_int *p = &VEC_last (tree_int, lambda_scope_stack); if (lambda_scope != p->t) { lambda_scope = p->t; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index a19a893..51cb5ee 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -295,7 +295,7 @@ typeid_ok_p (void) } pseudo_type_info - = VEC_index (tinfo_s, tinfo_descs, TK_TYPE_INFO_TYPE)->type; + = VEC_index (tinfo_s, tinfo_descs, TK_TYPE_INFO_TYPE).type; type_info_type = TYPE_MAIN_VARIANT (const_type_info_type_node); /* Make sure abi::__type_info_pseudo has the same alias set @@ -422,7 +422,7 @@ get_tinfo_decl (tree type) if (!d) { int ix = get_pseudo_ti_index (type); - tinfo_s *ti = VEC_index (tinfo_s, tinfo_descs, ix); + tinfo_s *ti = &VEC_index (tinfo_s, tinfo_descs, ix); d = build_lang_decl (VAR_DECL, name, ti->type); SET_DECL_ASSEMBLER_NAME (d, name); @@ -1079,7 +1079,7 @@ typeinfo_in_lib_p (tree type) static tree get_pseudo_ti_init (tree type, unsigned tk_index) { - tinfo_s *ti = VEC_index (tinfo_s, tinfo_descs, tk_index); + tinfo_s *ti = &VEC_index (tinfo_s, tinfo_descs, tk_index); gcc_assert (at_eof); switch (tk_index) @@ -1105,7 +1105,7 @@ get_pseudo_ti_init (tree type, unsigned tk_index) tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo)); /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */ - ti = VEC_index (tinfo_s, tinfo_descs, tk_index); + ti = &VEC_index (tinfo_s, tinfo_descs, tk_index); return class_initializer (ti, type, 1, tinfo); } @@ -1160,14 +1160,14 @@ get_pseudo_ti_init (tree type, unsigned tk_index) CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, tinfo); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, offset); base_init = build_constructor (init_list_type_node, v); - e = VEC_index (constructor_elt, init_vec, ix); + e = &VEC_index (constructor_elt, init_vec, ix); e->index = NULL_TREE; e->value = base_init; } base_inits = build_constructor (init_list_type_node, init_vec); /* get_tinfo_ptr might have reallocated the tinfo_descs vector. */ - ti = VEC_index (tinfo_s, tinfo_descs, tk_index); + ti = &VEC_index (tinfo_s, tinfo_descs, tk_index); return class_initializer (ti, type, 3, build_int_cst (NULL_TREE, hint), build_int_cst (NULL_TREE, nbases), @@ -1214,7 +1214,7 @@ create_pseudo_type_info (int tk, const char *real_name, ...) fields = build_decl (input_location, FIELD_DECL, NULL_TREE, VEC_index (tinfo_s, tinfo_descs, - TK_TYPE_INFO_TYPE)->type); + TK_TYPE_INFO_TYPE).type); /* Now add the derived fields. */ while ((field_decl = va_arg (ap, tree))) @@ -1228,7 +1228,7 @@ create_pseudo_type_info (int tk, const char *real_name, ...) finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE); CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type; - ti = VEC_index (tinfo_s, tinfo_descs, tk); + ti = &VEC_index (tinfo_s, tinfo_descs, tk); ti->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST); ti->name = get_identifier (real_name); ti->vtable = NULL_TREE; @@ -1321,7 +1321,7 @@ get_pseudo_ti_index (tree type) while (VEC_iterate (tinfo_s, tinfo_descs, len++, ti)) ti->type = ti->vtable = ti->name = NULL_TREE; } - else if (VEC_index (tinfo_s, tinfo_descs, ix)->type) + else if (VEC_index (tinfo_s, tinfo_descs, ix).type) /* already created. */ break; @@ -1335,7 +1335,7 @@ get_pseudo_ti_index (tree type) array_domain = build_index_type (size_int (num_bases)); base_array = build_array_type (VEC_index (tinfo_s, tinfo_descs, - TK_BASE_TYPE)->type, + TK_BASE_TYPE).type, array_domain); push_abi_namespace (); @@ -1387,7 +1387,7 @@ create_tinfo_types (void) DECL_CHAIN (field) = fields; fields = field; - ti = VEC_index (tinfo_s, tinfo_descs, TK_TYPE_INFO_TYPE); + ti = &VEC_index (tinfo_s, tinfo_descs, TK_TYPE_INFO_TYPE); ti->type = make_class_type (RECORD_TYPE); ti->vtable = NULL_TREE; ti->name = NULL_TREE; @@ -1427,7 +1427,7 @@ create_tinfo_types (void) DECL_CHAIN (field) = fields; fields = field; - ti = VEC_index (tinfo_s, tinfo_descs, TK_BASE_TYPE); + ti = &VEC_index (tinfo_s, tinfo_descs, TK_BASE_TYPE); ti->type = make_class_type (RECORD_TYPE); ti->vtable = NULL_TREE; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 230e967..ebac960 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -161,7 +161,7 @@ resume_deferring_access_checks (void) { if (!deferred_access_no_check) VEC_last (deferred_access, deferred_access_stack) - ->deferring_access_checks_kind = dk_deferred; + .deferring_access_checks_kind = dk_deferred; } /* Stop deferring access checks. */ @@ -171,7 +171,7 @@ stop_deferring_access_checks (void) { if (!deferred_access_no_check) VEC_last (deferred_access, deferred_access_stack) - ->deferring_access_checks_kind = dk_no_deferred; + .deferring_access_checks_kind = dk_no_deferred; } /* Discard the current deferred access checks and restore the @@ -198,7 +198,7 @@ get_deferred_access_checks (void) return NULL; else return (VEC_last (deferred_access, deferred_access_stack) - ->deferred_access_checks); + .deferred_access_checks); } /* Take current deferred checks and combine with the @@ -216,10 +216,10 @@ pop_to_parent_deferring_access_checks (void) deferred_access *ptr; checks = (VEC_last (deferred_access, deferred_access_stack) - ->deferred_access_checks); + .deferred_access_checks); VEC_pop (deferred_access, deferred_access_stack); - ptr = VEC_last (deferred_access, deferred_access_stack); + ptr = &VEC_last (deferred_access, deferred_access_stack); if (ptr->deferring_access_checks_kind == dk_no_deferred) { /* Check access. */ @@ -321,7 +321,7 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl, gcc_assert (TREE_CODE (binfo) == TREE_BINFO); - ptr = VEC_last (deferred_access, deferred_access_stack); + ptr = &VEC_last (deferred_access, deferred_access_stack); /* If we are not supposed to defer access checks, just check now. */ if (ptr->deferring_access_checks_kind == dk_no_deferred) @@ -5948,7 +5948,7 @@ build_constexpr_constructor_member_initializers (tree type, tree body) if (VEC_length (constructor_elt, vec) > 0) { /* In a delegating constructor, return the target. */ - constructor_elt *ce = VEC_index (constructor_elt, vec, 0); + constructor_elt *ce = &VEC_index (constructor_elt, vec, 0); if (ce->index == current_class_ptr) { body = ce->value; @@ -6820,7 +6820,7 @@ cxx_eval_array_reference (const constexpr_call *call, tree t, } i = tree_low_cst (index, 0); if (TREE_CODE (ary) == CONSTRUCTOR) - return VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ary), i)->value; + return VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ary), i).value; else if (elem_nchars == 1) return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))), TREE_STRING_POINTER (ary)[i]); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index bfbde04..7cc2457 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1337,7 +1337,7 @@ strip_typedefs_expr (tree t) type = strip_typedefs (TREE_TYPE (t)); for (i = 0; i < n; ++i) { - constructor_elt *e = VEC_index (constructor_elt, vec, i); + constructor_elt *e = &VEC_index (constructor_elt, vec, i); tree op = strip_typedefs_expr (e->value); if (op != e->value) { diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 326f602..2180535 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1178,7 +1178,7 @@ process_init_constructor_record (tree type, tree init, if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init))) { - constructor_elt *ce = VEC_index (constructor_elt, + constructor_elt *ce = &VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), idx); if (ce->index) { @@ -1305,7 +1305,7 @@ process_init_constructor_union (tree type, tree init, VEC_block_remove (constructor_elt, CONSTRUCTOR_ELTS (init), 1, len-1); } - ce = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), 0); + ce = &VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), 0); /* If this element specifies a field, initialize via that field. */ if (ce->index) diff --git a/gcc/df-scan.c b/gcc/df-scan.c index df90365..55492fa 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -4448,7 +4448,6 @@ df_bb_verify (basic_block bb) if (!INSN_P (insn)) continue; df_insn_refs_verify (&collection_rec, bb, insn, true); - df_free_collection_rec (&collection_rec); } /* Do the artificial defs and uses. */ diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi index ad0423a..cc46a61 100644 --- a/gcc/doc/gty.texi +++ b/gcc/doc/gty.texi @@ -13,17 +13,17 @@ involve determining information about GCC's data structures from GCC's source code and using this information to perform garbage collection and implement precompiled headers. -A full C parser would be too complicated for this task, so a limited -subset of C is interpreted and special markers are used to determine -what parts of the source to look at. All @code{struct} and -@code{union} declarations that define data structures that are -allocated under control of the garbage collector must be marked. All -global variables that hold pointers to garbage-collected memory must -also be marked. Finally, all global variables that need to be saved -and restored by a precompiled header must be marked. (The precompiled -header mechanism can only save static variables if they're scalar. -Complex data structures must be allocated in garbage-collected memory -to be saved in a precompiled header.) +A full C++ parser would be too complicated for this task, so a limited +subset of C++ is interpreted and special markers are used to determine +what parts of the source to look at. All @code{struct}, @code{union} +and @code{template} structure declarations that define data structures +that are allocated under control of the garbage collector must be +marked. All global variables that hold pointers to garbage-collected +memory must also be marked. Finally, all global variables that need +to be saved and restored by a precompiled header must be marked. (The +precompiled header mechanism can only save static variables if they're +scalar. Complex data structures must be allocated in garbage-collected +memory to be saved in a precompiled header.) The full format of a marker is @smallexample @@ -68,6 +68,7 @@ These don't need to be marked. @menu * GTY Options:: What goes inside a @code{GTY(())}. * GGC Roots:: Making global variables GGC roots. +* User GC:: Adding user-provided GC marking routines. * Files:: How the generated files work. * Invoking the garbage collector:: How to invoke the garbage collector. * Troubleshooting:: When something does not work as expected. @@ -440,8 +441,128 @@ The @code{special} option is used to mark types that have to be dealt with by special case machinery. The parameter is the name of the special case. See @file{gengtype.c} for further details. Avoid adding new special cases unless there is no other alternative. + +@findex user +@item user + +The @code{user} option indicates that the code to mark structure +fields is completely handled by user-provided routines. See section +@ref{User GC} for details on what functions need to be provided. @end table +@node User GC +@section Support for user-provided GC marking routines +@cindex user gc +The garbage collector supports types for which no automatic marking +code is generated. For these types, the user is required to provide +three functions: one to act as a marker for garbage collection, and +two functions to act as marker and pointer walker for pre-compiled +headers. + +Given a structure @code{struct GTY((user)) my_struct}, the following functions +should be defined to mark @code{my_struct}: + +@smallexample +void gt_ggc_mx (my_struct *p) +@{ + /* This marks field 'fld'. */ + gt_ggc_mx (p->fld); +@} + +void gt_pch_nx (my_struct *p) +@{ + /* This marks field 'fld'. */ + gt_pch_nx (tp->fld); +@} + +void gt_pch_nx (my_struct *p, gt_pointer_operator op, void *cookie) +@{ + /* For every field 'fld', call the given pointer operator. */ + op (&(tp->fld), cookie); +@} +@end smallexample + +In general, each marker @code{M} should call @code{M} for every +pointer field in the structure. Fields that are not allocated in GC +or are not pointers must be ignored. + +For embedded lists (e.g., structures with a @code{next} or @code{prev} +pointer), the marker must follow the chain and mark every element in +it. + +Note that the rules for the pointer walker @code{gt_pch_nx (my_struct +*, gt_pointer_operator, void *)} are slightly different. In this +case, the operation @code{op} must be applied to the @emph{address} of +every pointer field. + +@section User-provided marking routines for template types +When a template type @code{TP} is marked with @code{GTY}, all +instances of that type are considered user-provided types. This means +that the individual instances of @code{TP} do not need to be marked +with @code{GTY}. The user needs to provide template functions to mark +all the fields of the type. + +The following code snippets represent all the functions that need to +be provided. Note that type @code{TP} may reference to more than one +type. In these snippets, there is only one type @code{T}, but there +could be more. + +@smallexample +template<typename T> +void gt_ggc_mx (TP<T> *tp) +@{ + extern void gt_ggc_mx (T&); + + /* This marks field 'fld' of type 'T'. */ + gt_ggc_mx (tp->fld); +@} + +template<typename T> +void gt_pch_nx (TP<T> *tp) +@{ + extern void gt_pch_nx (T&); + + /* This marks field 'fld' of type 'T'. */ + gt_pch_nx (tp->fld); +@} + +template<typename T> +void gt_pch_nx (TP<T *> *tp, gt_pointer_operator op, void *cookie) +@{ + /* For every field 'fld' of 'tp' with type 'T *', call the given + pointer operator. */ + op (&(tp->fld), cookie); +@} + +template<typename T> +void gt_pch_nx (TP<T> *tp, gt_pointer_operator, void *cookie) +@{ + extern void gt_pch_nx (T *, gt_pointer_operator, void *); + + /* For every field 'fld' of 'tp' with type 'T', call the pointer + walker for all the fields of T. */ + gt_pch_nx (&(tp->fld), op, cookie); +@} +@end smallexample + +Support for user-defined types is currently limited. The following +restrictions apply: + +@enumerate +@item Type @code{TP} and all the argument types @code{T} must be +marked with @code{GTY}. + +@item Type @code{TP} can only have type names in its argument list. + +@item The pointer walker functions are different for @code{TP<T>} and +@code{TP<T *>}. In the case of @code{TP<T>}, references to +@code{T} must be handled by calling @code{gt_pch_nx} (which +will, in turn, walk all the pointers inside fields of @code{T}). +In the case of @code{TP<T *>}, references to @code{T *} must be +handled by calling the @code{op} function on the address of the +pointer (see the code snippets above). +@end enumerate + @node GGC Roots @section Marking Roots for the Garbage Collector @cindex roots, marking diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 6d40348..dfdd624 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1288,16 +1288,6 @@ opposite effect. If neither option is specified, the configure script will try to guess whether the @code{.init_array} and @code{.fini_array} sections are supported and, if they are, use them. -@item --enable-build-with-cxx -Build GCC using a C++ compiler rather than a C compiler. This is an -experimental option which may become the default in a later release. - -@item --enable-build-poststage1-with-cxx -When bootstrapping, build stages 2 and 3 of GCC using a C++ compiler -rather than a C compiler. Stage 1 is still built with a C compiler. -This is enabled by default and may be disabled using -@option{--disable-build-poststage1-with-cxx}. - @item --enable-maintainer-mode The build rules that regenerate the Autoconf and Automake output files as well as the GCC master message catalog @file{gcc.pot} are normally diff --git a/gcc/double-int.c b/gcc/double-int.c index ea518e3..2f48f2b 100644 --- a/gcc/double-int.c +++ b/gcc/double-int.c @@ -610,7 +610,7 @@ div_and_round_double (unsigned code, int uns, /* Returns mask for PREC bits. */ double_int -double_int_mask (unsigned prec) +double_int::mask (unsigned prec) { unsigned HOST_WIDE_INT m; double_int mask; @@ -635,20 +635,20 @@ double_int_mask (unsigned prec) of precision PREC. */ double_int -double_int_max_value (unsigned int prec, bool uns) +double_int::max_value (unsigned int prec, bool uns) { - return double_int_mask (prec - (uns ? 0 : 1)); + return double_int::mask (prec - (uns ? 0 : 1)); } /* Returns a minimum value for signed or unsigned integer of precision PREC. */ double_int -double_int_min_value (unsigned int prec, bool uns) +double_int::min_value (unsigned int prec, bool uns) { if (uns) return double_int_zero; - return double_int_lshift (double_int_one, prec - 1, prec, false); + return double_int_one.lshift (prec - 1, prec, false); } /* Clears the bits of CST over the precision PREC. If UNS is false, the bits @@ -659,20 +659,21 @@ double_int_min_value (unsigned int prec, bool uns) of CST, with the given signedness. */ double_int -double_int_ext (double_int cst, unsigned prec, bool uns) +double_int::ext (unsigned prec, bool uns) const { if (uns) - return double_int_zext (cst, prec); + return this->zext (prec); else - return double_int_sext (cst, prec); + return this->sext (prec); } -/* The same as double_int_ext with UNS = true. */ +/* The same as double_int::ext with UNS = true. */ double_int -double_int_zext (double_int cst, unsigned prec) +double_int::zext (unsigned prec) const { - double_int mask = double_int_mask (prec); + const double_int &cst = *this; + double_int mask = double_int::mask (prec); double_int r; r.low = cst.low & mask.low; @@ -681,12 +682,13 @@ double_int_zext (double_int cst, unsigned prec) return r; } -/* The same as double_int_ext with UNS = false. */ +/* The same as double_int::ext with UNS = false. */ double_int -double_int_sext (double_int cst, unsigned prec) +double_int::sext (unsigned prec) const { - double_int mask = double_int_mask (prec); + const double_int &cst = *this; + double_int mask = double_int::mask (prec); double_int r; unsigned HOST_WIDE_INT snum; @@ -714,8 +716,9 @@ double_int_sext (double_int cst, unsigned prec) /* Returns true if CST fits in signed HOST_WIDE_INT. */ bool -double_int_fits_in_shwi_p (double_int cst) +double_int::fits_signed () const { + const double_int &cst = *this; if (cst.high == 0) return (HOST_WIDE_INT) cst.low >= 0; else if (cst.high == -1) @@ -728,19 +731,20 @@ double_int_fits_in_shwi_p (double_int cst) unsigned HOST_WIDE_INT if UNS is true. */ bool -double_int_fits_in_hwi_p (double_int cst, bool uns) +double_int::fits (bool uns) const { if (uns) - return double_int_fits_in_uhwi_p (cst); + return this->fits_unsigned (); else - return double_int_fits_in_shwi_p (cst); + return this->fits_signed (); } /* Returns A * B. */ double_int -double_int_mul (double_int a, double_int b) +double_int::operator * (double_int b) const { + const double_int &a = *this; double_int ret; mul_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high); return ret; @@ -750,9 +754,9 @@ double_int_mul (double_int a, double_int b) *OVERFLOW is set to nonzero. */ double_int -double_int_mul_with_sign (double_int a, double_int b, - bool unsigned_p, int *overflow) +double_int::mul_with_sign (double_int b, bool unsigned_p, int *overflow) const { + const double_int &a = *this; double_int ret; *overflow = mul_double_with_sign (a.low, a.high, b.low, b.high, &ret.low, &ret.high, unsigned_p); @@ -762,8 +766,9 @@ double_int_mul_with_sign (double_int a, double_int b, /* Returns A + B. */ double_int -double_int_add (double_int a, double_int b) +double_int::operator + (double_int b) const { + const double_int &a = *this; double_int ret; add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high); return ret; @@ -772,8 +777,9 @@ double_int_add (double_int a, double_int b) /* Returns A - B. */ double_int -double_int_sub (double_int a, double_int b) +double_int::operator - (double_int b) const { + const double_int &a = *this; double_int ret; neg_double (b.low, b.high, &b.low, &b.high); add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high); @@ -783,8 +789,9 @@ double_int_sub (double_int a, double_int b) /* Returns -A. */ double_int -double_int_neg (double_int a) +double_int::operator - () const { + const double_int &a = *this; double_int ret; neg_double (a.low, a.high, &ret.low, &ret.high); return ret; @@ -796,9 +803,10 @@ double_int_neg (double_int a) stored to MOD. */ double_int -double_int_divmod (double_int a, double_int b, bool uns, unsigned code, - double_int *mod) +double_int::divmod (double_int b, bool uns, unsigned code, + double_int *mod) const { + const double_int &a = *this; double_int ret; div_and_round_double (code, uns, a.low, a.high, @@ -807,20 +815,20 @@ double_int_divmod (double_int a, double_int b, bool uns, unsigned code, return ret; } -/* The same as double_int_divmod with UNS = false. */ +/* The same as double_int::divmod with UNS = false. */ double_int -double_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod) +double_int::sdivmod (double_int b, unsigned code, double_int *mod) const { - return double_int_divmod (a, b, false, code, mod); + return this->divmod (b, false, code, mod); } -/* The same as double_int_divmod with UNS = true. */ +/* The same as double_int::divmod with UNS = true. */ double_int -double_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod) +double_int::udivmod (double_int b, unsigned code, double_int *mod) const { - return double_int_divmod (a, b, true, code, mod); + return this->divmod (b, true, code, mod); } /* Returns A / B (computed as unsigned depending on UNS, and rounded as @@ -828,27 +836,27 @@ double_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod) must be included before tree.h. */ double_int -double_int_div (double_int a, double_int b, bool uns, unsigned code) +double_int::div (double_int b, bool uns, unsigned code) const { double_int mod; - return double_int_divmod (a, b, uns, code, &mod); + return this->divmod (b, uns, code, &mod); } -/* The same as double_int_div with UNS = false. */ +/* The same as double_int::div with UNS = false. */ double_int -double_int_sdiv (double_int a, double_int b, unsigned code) +double_int::sdiv (double_int b, unsigned code) const { - return double_int_div (a, b, false, code); + return this->div (b, false, code); } -/* The same as double_int_div with UNS = true. */ +/* The same as double_int::div with UNS = true. */ double_int -double_int_udiv (double_int a, double_int b, unsigned code) +double_int::udiv (double_int b, unsigned code) const { - return double_int_div (a, b, true, code); + return this->div (b, true, code); } /* Returns A % B (computed as unsigned depending on UNS, and rounded as @@ -856,28 +864,28 @@ double_int_udiv (double_int a, double_int b, unsigned code) must be included before tree.h. */ double_int -double_int_mod (double_int a, double_int b, bool uns, unsigned code) +double_int::mod (double_int b, bool uns, unsigned code) const { double_int mod; - double_int_divmod (a, b, uns, code, &mod); + this->divmod (b, uns, code, &mod); return mod; } -/* The same as double_int_mod with UNS = false. */ +/* The same as double_int::mod with UNS = false. */ double_int -double_int_smod (double_int a, double_int b, unsigned code) +double_int::smod (double_int b, unsigned code) const { - return double_int_mod (a, b, false, code); + return this->mod (b, false, code); } -/* The same as double_int_mod with UNS = true. */ +/* The same as double_int::mod with UNS = true. */ double_int -double_int_umod (double_int a, double_int b, unsigned code) +double_int::umod (double_int b, unsigned code) const { - return double_int_mod (a, b, true, code); + return this->mod (b, true, code); } /* Return TRUE iff PRODUCT is an integral multiple of FACTOR, and return @@ -885,13 +893,13 @@ double_int_umod (double_int a, double_int b, unsigned code) unchanged. */ bool -double_int_multiple_of (double_int product, double_int factor, - bool unsigned_p, double_int *multiple) +double_int::multiple_of (double_int factor, + bool unsigned_p, double_int *multiple) const { double_int remainder; - double_int quotient = double_int_divmod (product, factor, unsigned_p, + double_int quotient = this->divmod (factor, unsigned_p, TRUNC_DIV_EXPR, &remainder); - if (double_int_zero_p (remainder)) + if (remainder.is_zero ()) { *multiple = quotient; return true; @@ -902,8 +910,9 @@ double_int_multiple_of (double_int product, double_int factor, /* Set BITPOS bit in A. */ double_int -double_int_setbit (double_int a, unsigned bitpos) +double_int::set_bit (unsigned bitpos) const { + double_int a = *this; if (bitpos < HOST_BITS_PER_WIDE_INT) a.low |= (unsigned HOST_WIDE_INT) 1 << bitpos; else @@ -914,8 +923,9 @@ double_int_setbit (double_int a, unsigned bitpos) /* Count trailing zeros in A. */ int -double_int_ctz (double_int a) +double_int::trailing_zeros () const { + const double_int &a = *this; unsigned HOST_WIDE_INT w = a.low ? a.low : (unsigned HOST_WIDE_INT) a.high; unsigned bits = a.low ? 0 : HOST_BITS_PER_WIDE_INT; if (!w) @@ -929,30 +939,76 @@ double_int_ctz (double_int a) otherwise use logical shift. */ double_int -double_int_lshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith) +double_int::lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const { + const double_int &a = *this; double_int ret; lshift_double (a.low, a.high, count, prec, &ret.low, &ret.high, arith); return ret; } -/* Shift A rigth by COUNT places keeping only PREC bits of result. Shift +/* Shift A right by COUNT places keeping only PREC bits of result. Shift left if COUNT is negative. ARITH true specifies arithmetic shifting; otherwise use logical shift. */ double_int -double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith) +double_int::rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const { + const double_int &a = *this; double_int ret; lshift_double (a.low, a.high, -count, prec, &ret.low, &ret.high, arith); return ret; } +/* Arithmetic shift A left by COUNT places keeping only PREC bits of result. + Shift right if COUNT is negative. */ + +double_int +double_int::alshift (HOST_WIDE_INT count, unsigned int prec) const +{ + double_int r; + lshift_double (low, high, count, prec, &r.low, &r.high, true); + return r; +} + +/* Arithmetic shift A right by COUNT places keeping only PREC bits of result. + Shift left if COUNT is negative. */ + +double_int +double_int::arshift (HOST_WIDE_INT count, unsigned int prec) const +{ + double_int r; + lshift_double (low, high, -count, prec, &r.low, &r.high, true); + return r; +} + +/* Logical shift A left by COUNT places keeping only PREC bits of result. + Shift right if COUNT is negative. */ + +double_int +double_int::llshift (HOST_WIDE_INT count, unsigned int prec) const +{ + double_int r; + lshift_double (low, high, count, prec, &r.low, &r.high, false); + return r; +} + +/* Logical shift A right by COUNT places keeping only PREC bits of result. + Shift left if COUNT is negative. */ + +double_int +double_int::lrshift (HOST_WIDE_INT count, unsigned int prec) const +{ + double_int r; + lshift_double (low, high, -count, prec, &r.low, &r.high, false); + return r; +} + /* Rotate A left by COUNT places keeping only PREC bits of result. Rotate right if COUNT is negative. */ double_int -double_int_lrotate (double_int a, HOST_WIDE_INT count, unsigned int prec) +double_int::lrotate (HOST_WIDE_INT count, unsigned int prec) const { double_int t1, t2; @@ -960,17 +1016,17 @@ double_int_lrotate (double_int a, HOST_WIDE_INT count, unsigned int prec) if (count < 0) count += prec; - t1 = double_int_lshift (a, count, prec, false); - t2 = double_int_rshift (a, prec - count, prec, false); + t1 = this->lshift (count, prec, false); + t2 = this->rshift (prec - count, prec, false); - return double_int_ior (t1, t2); + return t1 | t2; } /* Rotate A rigth by COUNT places keeping only PREC bits of result. Rotate right if COUNT is negative. */ double_int -double_int_rrotate (double_int a, HOST_WIDE_INT count, unsigned int prec) +double_int::rrotate (HOST_WIDE_INT count, unsigned int prec) const { double_int t1, t2; @@ -978,30 +1034,31 @@ double_int_rrotate (double_int a, HOST_WIDE_INT count, unsigned int prec) if (count < 0) count += prec; - t1 = double_int_rshift (a, count, prec, false); - t2 = double_int_lshift (a, prec - count, prec, false); + t1 = this->rshift (count, prec, false); + t2 = this->lshift (prec - count, prec, false); - return double_int_ior (t1, t2); + return t1 | t2; } /* Returns -1 if A < B, 0 if A == B and 1 if A > B. Signedness of the comparison is given by UNS. */ int -double_int_cmp (double_int a, double_int b, bool uns) +double_int::cmp (double_int b, bool uns) const { if (uns) - return double_int_ucmp (a, b); + return this->ucmp (b); else - return double_int_scmp (a, b); + return this->scmp (b); } /* Compares two unsigned values A and B. Returns -1 if A < B, 0 if A == B, and 1 if A > B. */ int -double_int_ucmp (double_int a, double_int b) +double_int::ucmp (double_int b) const { + const double_int &a = *this; if ((unsigned HOST_WIDE_INT) a.high < (unsigned HOST_WIDE_INT) b.high) return -1; if ((unsigned HOST_WIDE_INT) a.high > (unsigned HOST_WIDE_INT) b.high) @@ -1018,8 +1075,9 @@ double_int_ucmp (double_int a, double_int b) and 1 if A > B. */ int -double_int_scmp (double_int a, double_int b) +double_int::scmp (double_int b) const { + const double_int &a = *this; if (a.high < b.high) return -1; if (a.high > b.high) @@ -1032,49 +1090,111 @@ double_int_scmp (double_int a, double_int b) return 0; } +/* Compares two unsigned values A and B for less-than. */ + +bool +double_int::ult (double_int b) const +{ + if ((unsigned HOST_WIDE_INT) high < (unsigned HOST_WIDE_INT) b.high) + return true; + if ((unsigned HOST_WIDE_INT) high > (unsigned HOST_WIDE_INT) b.high) + return false; + if (low < b.low) + return true; + return false; +} + +/* Compares two unsigned values A and B for greater-than. */ + +bool +double_int::ugt (double_int b) const +{ + if ((unsigned HOST_WIDE_INT) high > (unsigned HOST_WIDE_INT) b.high) + return true; + if ((unsigned HOST_WIDE_INT) high < (unsigned HOST_WIDE_INT) b.high) + return false; + if (low > b.low) + return true; + return false; +} + +/* Compares two signed values A and B for less-than. */ + +bool +double_int::slt (double_int b) const +{ + if (high < b.high) + return true; + if (high > b.high) + return false; + if (low < b.low) + return true; + return false; +} + +/* Compares two signed values A and B for greater-than. */ + +bool +double_int::sgt (double_int b) const +{ + if (high > b.high) + return true; + if (high < b.high) + return false; + if (low > b.low) + return true; + return false; +} + + /* Compares two values A and B. Returns max value. Signedness of the comparison is given by UNS. */ double_int -double_int_max (double_int a, double_int b, bool uns) +double_int::max (double_int b, bool uns) { - return (double_int_cmp (a, b, uns) == 1) ? a : b; + return (this->cmp (b, uns) == 1) ? *this : b; } /* Compares two signed values A and B. Returns max value. */ -double_int double_int_smax (double_int a, double_int b) +double_int +double_int::smax (double_int b) { - return (double_int_scmp (a, b) == 1) ? a : b; + return (this->scmp (b) == 1) ? *this : b; } /* Compares two unsigned values A and B. Returns max value. */ -double_int double_int_umax (double_int a, double_int b) +double_int +double_int::umax (double_int b) { - return (double_int_ucmp (a, b) == 1) ? a : b; + return (this->ucmp (b) == 1) ? *this : b; } /* Compares two values A and B. Returns mix value. Signedness of the comparison is given by UNS. */ -double_int double_int_min (double_int a, double_int b, bool uns) +double_int +double_int::min (double_int b, bool uns) { - return (double_int_cmp (a, b, uns) == -1) ? a : b; + return (this->cmp (b, uns) == -1) ? *this : b; } /* Compares two signed values A and B. Returns min value. */ -double_int double_int_smin (double_int a, double_int b) +double_int +double_int::smin (double_int b) { - return (double_int_scmp (a, b) == -1) ? a : b; + return (this->scmp (b) == -1) ? *this : b; } /* Compares two unsigned values A and B. Returns min value. */ -double_int double_int_umin (double_int a, double_int b) +double_int +double_int::umin (double_int b) { - return (double_int_ucmp (a, b) == -1) ? a : b; + return (this->ucmp (b) == -1) ? *this : b; } /* Splits last digit of *CST (taken as unsigned) in BASE and returns it. */ @@ -1102,19 +1222,19 @@ dump_double_int (FILE *file, double_int cst, bool uns) unsigned digits[100], n; int i; - if (double_int_zero_p (cst)) + if (cst.is_zero ()) { fprintf (file, "0"); return; } - if (!uns && double_int_negative_p (cst)) + if (!uns && cst.is_negative ()) { fprintf (file, "-"); - cst = double_int_neg (cst); + cst = -cst; } - for (n = 0; !double_int_zero_p (cst); n++) + for (n = 0; !cst.is_zero (); n++) digits[n] = double_int_split_digit (&cst, 10); for (i = n - 1; i >= 0; i--) fprintf (file, "%u", digits[i]); @@ -1130,10 +1250,10 @@ mpz_set_double_int (mpz_t result, double_int val, bool uns) bool negate = false; unsigned HOST_WIDE_INT vp[2]; - if (!uns && double_int_negative_p (val)) + if (!uns && val.is_negative ()) { negate = true; - val = double_int_neg (val); + val = -val; } vp[0] = val.low; @@ -1191,9 +1311,9 @@ mpz_get_double_int (const_tree type, mpz_t val, bool wrap) res.low = vp[0]; res.high = (HOST_WIDE_INT) vp[1]; - res = double_int_ext (res, TYPE_PRECISION (type), TYPE_UNSIGNED (type)); + res = res.ext (TYPE_PRECISION (type), TYPE_UNSIGNED (type)); if (mpz_sgn (val) < 0) - res = double_int_neg (res); + res = -res; return res; } diff --git a/gcc/double-int.h b/gcc/double-int.h index 4c4c1b3..9bbf644 100644 --- a/gcc/double-int.h +++ b/gcc/double-int.h @@ -50,10 +50,132 @@ along with GCC; see the file COPYING3. If not see numbers with precision higher than HOST_WIDE_INT). It might be less confusing to have them both signed or both unsigned. */ -typedef struct +typedef struct double_int { +public: + /* Normally, we would define constructors to create instances. + Two things prevent us from doing so. + First, defining a constructor makes the class non-POD in C++03, + and we certainly want double_int to be a POD. + Second, the GCC conding conventions prefer explicit conversion, + and explicit conversion operators are not available until C++11. */ + + static double_int from_unsigned (unsigned HOST_WIDE_INT cst); + static double_int from_signed (HOST_WIDE_INT cst); + + /* No copy assignment operator or destructor to keep the type a POD. */ + + /* There are some special value-creation static member functions. */ + + static double_int mask (unsigned prec); + static double_int max_value (unsigned int prec, bool uns); + static double_int min_value (unsigned int prec, bool uns); + + /* The following functions are mutating operations. */ + + double_int &operator ++ (); // prefix + double_int &operator -- (); // prefix + double_int &operator *= (double_int); + double_int &operator += (double_int); + double_int &operator -= (double_int); + + /* The following functions are non-mutating operations. */ + + /* Conversion functions. */ + + HOST_WIDE_INT to_signed () const; + unsigned HOST_WIDE_INT to_unsigned () const; + + /* Conversion query functions. */ + + bool fits_unsigned () const; + bool fits_signed () const; + bool fits (bool uns) const; + + /* Attribute query functions. */ + + int trailing_zeros () const; + int popcount () const; + + /* Arithmetic query operations. */ + + bool multiple_of (double_int, bool, double_int *) const; + + /* Arithmetic operation functions. */ + + double_int set_bit (unsigned) const; + double_int mul_with_sign (double_int, bool, int *) const; + + double_int operator * (double_int b) const; + double_int operator + (double_int b) const; + double_int operator - (double_int b) const; + double_int operator - () const; + double_int operator ~ () const; + double_int operator & (double_int b) const; + double_int operator | (double_int b) const; + double_int operator ^ (double_int b) const; + double_int and_not (double_int b) const; + + double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const; + double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const; + double_int alshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int arshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int llshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const; + double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const; + + /* You must ensure that double_int::ext is called on the operands + of the following operations, if the precision of the numbers + is less than HOST_BITS_PER_DOUBLE_INT bits. */ + double_int div (double_int, bool, unsigned) const; + double_int sdiv (double_int, unsigned) const; + double_int udiv (double_int, unsigned) const; + double_int mod (double_int, bool, unsigned) const; + double_int smod (double_int, unsigned) const; + double_int umod (double_int, unsigned) const; + double_int divmod (double_int, bool, unsigned, double_int *) const; + double_int sdivmod (double_int, unsigned, double_int *) const; + double_int udivmod (double_int, unsigned, double_int *) const; + + /* Precision control functions. */ + + double_int ext (unsigned prec, bool uns) const; + double_int zext (unsigned prec) const; + double_int sext (unsigned prec) const; + + /* Comparative functions. */ + + bool is_zero () const; + bool is_one () const; + bool is_minus_one () const; + bool is_negative () const; + + int cmp (double_int b, bool uns) const; + int ucmp (double_int b) const; + int scmp (double_int b) const; + + bool ult (double_int b) const; + bool ugt (double_int b) const; + bool slt (double_int b) const; + bool sgt (double_int b) const; + + double_int max (double_int b, bool uns); + double_int smax (double_int b); + double_int umax (double_int b); + + double_int min (double_int b, bool uns); + double_int smin (double_int b); + double_int umin (double_int b); + + bool operator == (double_int cst2) const; + bool operator != (double_int cst2) const; + + /* Please migrate away from using these member variables publically. */ + unsigned HOST_WIDE_INT low; HOST_WIDE_INT high; + } double_int; #define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT) @@ -63,66 +185,148 @@ typedef struct /* Constructs double_int from integer CST. The bits over the precision of HOST_WIDE_INT are filled with the sign bit. */ -static inline double_int -shwi_to_double_int (HOST_WIDE_INT cst) +inline +double_int double_int::from_signed (HOST_WIDE_INT cst) { double_int r; - r.low = (unsigned HOST_WIDE_INT) cst; r.high = cst < 0 ? -1 : 0; - return r; } +/* FIXME(crowl): Remove after converting callers. */ +static inline double_int +shwi_to_double_int (HOST_WIDE_INT cst) +{ + return double_int::from_signed (cst); +} + /* Some useful constants. */ +/* FIXME(crowl): Maybe remove after converting callers? + The problem is that a named constant would not be as optimizable, + while the functional syntax is more verbose. */ -#define double_int_minus_one (shwi_to_double_int (-1)) -#define double_int_zero (shwi_to_double_int (0)) -#define double_int_one (shwi_to_double_int (1)) -#define double_int_two (shwi_to_double_int (2)) -#define double_int_ten (shwi_to_double_int (10)) +#define double_int_minus_one (double_int::from_signed (-1)) +#define double_int_zero (double_int::from_signed (0)) +#define double_int_one (double_int::from_signed (1)) +#define double_int_two (double_int::from_signed (2)) +#define double_int_ten (double_int::from_signed (10)) /* Constructs double_int from unsigned integer CST. The bits over the precision of HOST_WIDE_INT are filled with zeros. */ -static inline double_int -uhwi_to_double_int (unsigned HOST_WIDE_INT cst) +inline +double_int double_int::from_unsigned (unsigned HOST_WIDE_INT cst) { double_int r; - r.low = cst; r.high = 0; - return r; } +/* FIXME(crowl): Remove after converting callers. */ +static inline double_int +uhwi_to_double_int (unsigned HOST_WIDE_INT cst) +{ + return double_int::from_unsigned (cst); +} + +inline double_int & +double_int::operator ++ () +{ + *this += double_int_one; + return *this; +} + +inline double_int & +double_int::operator -- () +{ + *this -= double_int_one; + return *this; +} + +inline double_int & +double_int::operator *= (double_int b) +{ + *this = *this * b; + return *this; +} + +inline double_int & +double_int::operator += (double_int b) +{ + *this = *this + b; + return *this; +} + +inline double_int & +double_int::operator -= (double_int b) +{ + *this = *this - b; + return *this; +} + /* Returns value of CST as a signed number. CST must satisfy - double_int_fits_in_shwi_p. */ + double_int::fits_signed. */ +inline HOST_WIDE_INT +double_int::to_signed () const +{ + return (HOST_WIDE_INT) low; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline HOST_WIDE_INT double_int_to_shwi (double_int cst) { - return (HOST_WIDE_INT) cst.low; + return cst.to_signed (); } /* Returns value of CST as an unsigned number. CST must satisfy - double_int_fits_in_uhwi_p. */ + double_int::fits_unsigned. */ + +inline unsigned HOST_WIDE_INT +double_int::to_unsigned () const +{ + return low; +} +/* FIXME(crowl): Remove after converting callers. */ static inline unsigned HOST_WIDE_INT double_int_to_uhwi (double_int cst) { - return cst.low; + return cst.to_unsigned (); } -bool double_int_fits_in_hwi_p (double_int, bool); -bool double_int_fits_in_shwi_p (double_int); - /* Returns true if CST fits in unsigned HOST_WIDE_INT. */ +inline bool +double_int::fits_unsigned () const +{ + return high == 0; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline bool double_int_fits_in_uhwi_p (double_int cst) { - return cst.high == 0; + return cst.fits_unsigned (); +} + +/* Returns true if CST fits in signed HOST_WIDE_INT. */ + +/* FIXME(crowl): Remove after converting callers. */ +inline bool +double_int_fits_in_shwi_p (double_int cst) +{ + return cst.fits_signed (); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline bool +double_int_fits_in_hwi_p (double_int cst, bool uns) +{ + return cst.fits (uns); } /* The following operations perform arithmetics modulo 2^precision, @@ -130,88 +334,258 @@ double_int_fits_in_uhwi_p (double_int cst) you are representing numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */ -double_int double_int_mul (double_int, double_int); -double_int double_int_mul_with_sign (double_int, double_int, bool, int *); -double_int double_int_add (double_int, double_int); -double_int double_int_sub (double_int, double_int); -double_int double_int_neg (double_int); +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_mul (double_int a, double_int b) +{ + return a * b; +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_mul_with_sign (double_int a, double_int b, + bool unsigned_p, int *overflow) +{ + return a.mul_with_sign (b, unsigned_p, overflow); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_add (double_int a, double_int b) +{ + return a + b; +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_sub (double_int a, double_int b) +{ + return a - b; +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_neg (double_int a) +{ + return -a; +} /* You must ensure that double_int_ext is called on the operands of the following operations, if the precision of the numbers is less than HOST_BITS_PER_DOUBLE_INT bits. */ -double_int double_int_div (double_int, double_int, bool, unsigned); -double_int double_int_sdiv (double_int, double_int, unsigned); -double_int double_int_udiv (double_int, double_int, unsigned); -double_int double_int_mod (double_int, double_int, bool, unsigned); -double_int double_int_smod (double_int, double_int, unsigned); -double_int double_int_umod (double_int, double_int, unsigned); -double_int double_int_divmod (double_int, double_int, bool, unsigned, double_int *); -double_int double_int_sdivmod (double_int, double_int, unsigned, double_int *); -double_int double_int_udivmod (double_int, double_int, unsigned, double_int *); -bool double_int_multiple_of (double_int, double_int, bool, double_int *); +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_div (double_int a, double_int b, bool uns, unsigned code) +{ + return a.div (b, uns, code); +} -double_int double_int_setbit (double_int, unsigned); -int double_int_ctz (double_int); +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_sdiv (double_int a, double_int b, unsigned code) +{ + return a.sdiv (b, code); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_udiv (double_int a, double_int b, unsigned code) +{ + return a.udiv (b, code); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_mod (double_int a, double_int b, bool uns, unsigned code) +{ + return a.mod (b, uns, code); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_smod (double_int a, double_int b, unsigned code) +{ + return a.smod (b, code); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_umod (double_int a, double_int b, unsigned code) +{ + return a.umod (b, code); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_divmod (double_int a, double_int b, bool uns, + unsigned code, double_int *mod) +{ + return a.divmod (b, uns, code, mod); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod) +{ + return a.sdivmod (b, code, mod); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod) +{ + return a.udivmod (b, code, mod); +} + +/***/ + +/* FIXME(crowl): Remove after converting callers. */ +inline bool +double_int_multiple_of (double_int product, double_int factor, + bool unsigned_p, double_int *multiple) +{ + return product.multiple_of (factor, unsigned_p, multiple); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_setbit (double_int a, unsigned bitpos) +{ + return a.set_bit (bitpos); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline int +double_int_ctz (double_int a) +{ + return a.trailing_zeros (); +} /* Logical operations. */ /* Returns ~A. */ +inline double_int +double_int::operator ~ () const +{ + double_int result; + result.low = ~low; + result.high = ~high; + return result; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline double_int double_int_not (double_int a) { - a.low = ~a.low; - a.high = ~a.high; - return a; + return ~a; } /* Returns A | B. */ +inline double_int +double_int::operator | (double_int b) const +{ + double_int result; + result.low = low | b.low; + result.high = high | b.high; + return result; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline double_int double_int_ior (double_int a, double_int b) { - a.low |= b.low; - a.high |= b.high; - return a; + return a | b; } /* Returns A & B. */ +inline double_int +double_int::operator & (double_int b) const +{ + double_int result; + result.low = low & b.low; + result.high = high & b.high; + return result; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline double_int double_int_and (double_int a, double_int b) { - a.low &= b.low; - a.high &= b.high; - return a; + return a & b; } /* Returns A & ~B. */ +inline double_int +double_int::and_not (double_int b) const +{ + double_int result; + result.low = low & ~b.low; + result.high = high & ~b.high; + return result; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline double_int double_int_and_not (double_int a, double_int b) { - a.low &= ~b.low; - a.high &= ~b.high; - return a; + return a.and_not (b); } /* Returns A ^ B. */ +inline double_int +double_int::operator ^ (double_int b) const +{ + double_int result; + result.low = low ^ b.low; + result.high = high ^ b.high; + return result; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline double_int double_int_xor (double_int a, double_int b) { - a.low ^= b.low; - a.high ^= b.high; - return a; + return a ^ b; } /* Shift operations. */ -double_int double_int_lshift (double_int, HOST_WIDE_INT, unsigned int, bool); -double_int double_int_rshift (double_int, HOST_WIDE_INT, unsigned int, bool); -double_int double_int_lrotate (double_int, HOST_WIDE_INT, unsigned int); -double_int double_int_rrotate (double_int, HOST_WIDE_INT, unsigned int); + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_lshift (double_int a, HOST_WIDE_INT count, unsigned int prec, + bool arith) +{ + return a.lshift (count, prec, arith); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec, + bool arith) +{ + return a.rshift (count, prec, arith); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_lrotate (double_int a, HOST_WIDE_INT count, unsigned int prec) +{ + return a.lrotate (count, prec); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_rrotate (double_int a, HOST_WIDE_INT count, unsigned int prec) +{ + return a.rrotate (count, prec); +} /* Returns true if CST is negative. Of course, CST is considered to be signed. */ @@ -222,29 +596,115 @@ double_int_negative_p (double_int cst) return cst.high < 0; } -int double_int_cmp (double_int, double_int, bool); -int double_int_scmp (double_int, double_int); -int double_int_ucmp (double_int, double_int); +/* FIXME(crowl): Remove after converting callers. */ +inline int +double_int_cmp (double_int a, double_int b, bool uns) +{ + return a.cmp (b, uns); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline int +double_int_scmp (double_int a, double_int b) +{ + return a.scmp (b); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline int +double_int_ucmp (double_int a, double_int b) +{ + return a.ucmp (b); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_max (double_int a, double_int b, bool uns) +{ + return a.max (b, uns); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_smax (double_int a, double_int b) +{ + return a.smax (b); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_umax (double_int a, double_int b) +{ + return a.umax (b); +} -double_int double_int_max (double_int, double_int, bool); -double_int double_int_smax (double_int, double_int); -double_int double_int_umax (double_int, double_int); -double_int double_int_min (double_int, double_int, bool); -double_int double_int_smin (double_int, double_int); -double_int double_int_umin (double_int, double_int); +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_min (double_int a, double_int b, bool uns) +{ + return a.min (b, uns); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_smin (double_int a, double_int b) +{ + return a.smin (b); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_umin (double_int a, double_int b) +{ + return a.umin (b); +} void dump_double_int (FILE *, double_int, bool); /* Zero and sign extension of numbers in smaller precisions. */ -double_int double_int_ext (double_int, unsigned, bool); -double_int double_int_sext (double_int, unsigned); -double_int double_int_zext (double_int, unsigned); -double_int double_int_mask (unsigned); +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_ext (double_int a, unsigned prec, bool uns) +{ + return a.ext (prec, uns); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_sext (double_int a, unsigned prec) +{ + return a.sext (prec); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_zext (double_int a, unsigned prec) +{ + return a.zext (prec); +} -double_int double_int_max_value (unsigned int, bool); -double_int double_int_min_value (unsigned int, bool); +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_mask (unsigned prec) +{ + return double_int::mask (prec); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_max_value (unsigned int prec, bool uns) +{ + return double_int::max_value (prec, uns); +} + +/* FIXME(crowl): Remove after converting callers. */ +inline double_int +double_int_min_value (unsigned int prec, bool uns) +{ + return double_int::min_value (prec, uns); +} #define ALL_ONES (~((unsigned HOST_WIDE_INT) 0)) @@ -254,69 +714,128 @@ double_int double_int_min_value (unsigned int, bool); /* Returns true if CST is zero. */ +inline bool +double_int::is_zero () const +{ + return low == 0 && high == 0; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline bool double_int_zero_p (double_int cst) { - return cst.low == 0 && cst.high == 0; + return cst.is_zero (); } /* Returns true if CST is one. */ +inline bool +double_int::is_one () const +{ + return low == 1 && high == 0; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline bool double_int_one_p (double_int cst) { - return cst.low == 1 && cst.high == 0; + return cst.is_one (); } /* Returns true if CST is minus one. */ +inline bool +double_int::is_minus_one () const +{ + return low == ALL_ONES && high == -1; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline bool double_int_minus_one_p (double_int cst) { - return (cst.low == ALL_ONES && cst.high == -1); + return cst.is_minus_one (); +} + +/* Returns true if CST is negative. */ + +inline bool +double_int::is_negative () const +{ + return high < 0; } /* Returns true if CST1 == CST2. */ +inline bool +double_int::operator == (double_int cst2) const +{ + return low == cst2.low && high == cst2.high; +} + +/* FIXME(crowl): Remove after converting callers. */ static inline bool double_int_equal_p (double_int cst1, double_int cst2) { - return cst1.low == cst2.low && cst1.high == cst2.high; + return cst1 == cst2; +} + +/* Returns true if CST1 != CST2. */ + +inline bool +double_int::operator != (double_int cst2) const +{ + return low != cst2.low || high != cst2.high; } /* Return number of set bits of CST. */ +inline int +double_int::popcount () const +{ + return popcount_hwi (high) + popcount_hwi (low); +} + +/* FIXME(crowl): Remove after converting callers. */ static inline int double_int_popcount (double_int cst) { - return popcount_hwi (cst.high) + popcount_hwi (cst.low); + return cst.popcount (); } /* Legacy interface with decomposed high/low parts. */ +/* FIXME(crowl): Remove after converting callers. */ extern int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool); +/* FIXME(crowl): Remove after converting callers. */ #define add_double(l1,h1,l2,h2,lv,hv) \ add_double_with_sign (l1, h1, l2, h2, lv, hv, false) +/* FIXME(crowl): Remove after converting callers. */ extern int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *); +/* FIXME(crowl): Remove after converting callers. */ extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool); +/* FIXME(crowl): Remove after converting callers. */ extern int mul_double_wide_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool); +/* FIXME(crowl): Remove after converting callers. */ #define mul_double(l1,h1,l2,h2,lv,hv) \ mul_double_with_sign (l1, h1, l2, h2, lv, hv, false) +/* FIXME(crowl): Remove after converting callers. */ extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, unsigned int, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool); +/* FIXME(crowl): Remove after converting callers. */ extern int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT, HOST_WIDE_INT, unsigned HOST_WIDE_INT *, diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 3edb6e1..1702785 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -2550,7 +2550,7 @@ create_cfi_notes (void) gcc_checking_assert (trace_work_list == NULL); /* Always begin at the entry trace. */ - ti = VEC_index (dw_trace_info, trace_info, 0); + ti = &VEC_index (dw_trace_info, trace_info, 0); scan_trace (ti); while (!VEC_empty (dw_trace_info_ref, trace_work_list)) @@ -2597,7 +2597,7 @@ connect_traces (void) /* Remove all unprocessed traces from the list. */ for (i = n - 1; i > 0; --i) { - ti = VEC_index (dw_trace_info, trace_info, i); + ti = &VEC_index (dw_trace_info, trace_info, i); if (ti->beg_row == NULL) { VEC_ordered_remove (dw_trace_info, trace_info, i); @@ -2609,13 +2609,13 @@ connect_traces (void) /* Work from the end back to the beginning. This lets us easily insert remember/restore_state notes in the correct order wrt other notes. */ - prev_ti = VEC_index (dw_trace_info, trace_info, n - 1); + prev_ti = &VEC_index (dw_trace_info, trace_info, n - 1); for (i = n - 1; i > 0; --i) { dw_cfi_row *old_row; ti = prev_ti; - prev_ti = VEC_index (dw_trace_info, trace_info, i - 1); + prev_ti = &VEC_index (dw_trace_info, trace_info, i - 1); add_cfi_insn = ti->head; @@ -2686,7 +2686,7 @@ connect_traces (void) for (i = 0; i < n; ++i) { - ti = VEC_index (dw_trace_info, trace_info, i); + ti = &VEC_index (dw_trace_info, trace_info, i); if (ti->switch_sections) prev_args_size = 0; @@ -2884,8 +2884,8 @@ create_cie_data (void) break; case 1: cie_return_save = ggc_alloc_reg_saved_in_data (); - *cie_return_save = *VEC_index (reg_saved_in_data, - cie_trace.regs_saved_in_regs, 0); + *cie_return_save = VEC_index (reg_saved_in_data, + cie_trace.regs_saved_in_regs, 0); VEC_free (reg_saved_in_data, heap, cie_trace.regs_saved_in_regs); break; default: diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 4b67d82..4bc4cc3 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -5821,7 +5821,7 @@ same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark) return 0; FOR_EACH_VEC_ELT (dw_attr_node, die1->die_attr, ix, a1) - if (!same_attr_p (a1, VEC_index (dw_attr_node, die2->die_attr, ix), mark)) + if (!same_attr_p (a1, &VEC_index (dw_attr_node, die2->die_attr, ix), mark)) return 0; c1 = die1->die_child; @@ -7072,7 +7072,7 @@ build_abbrev_table (dw_die_ref die, htab_t extern_map) FOR_EACH_VEC_ELT (dw_attr_node, die->die_attr, ix, die_a) { - abbrev_a = VEC_index (dw_attr_node, abbrev->die_attr, ix); + abbrev_a = &VEC_index (dw_attr_node, abbrev->die_attr, ix); if ((abbrev_a->dw_attr != die_a->dw_attr) || (value_format (abbrev_a) != value_format (die_a))) { @@ -20532,8 +20532,8 @@ optimize_macinfo_range (unsigned int idx, VEC (macinfo_entry, gc) *files, unsigned int i, count, encoded_filename_len, linebuf_len; void **slot; - first = VEC_index (macinfo_entry, macinfo_table, idx); - second = VEC_index (macinfo_entry, macinfo_table, idx + 1); + first = &VEC_index (macinfo_entry, macinfo_table, idx); + second = &VEC_index (macinfo_entry, macinfo_table, idx + 1); /* Optimize only if there are at least two consecutive define/undef ops, and either all of them are before first DW_MACINFO_start_file @@ -20573,7 +20573,7 @@ optimize_macinfo_range (unsigned int idx, VEC (macinfo_entry, gc) *files, if (VEC_empty (macinfo_entry, files)) base = ""; else - base = lbasename (VEC_last (macinfo_entry, files)->info); + base = lbasename (VEC_last (macinfo_entry, files).info); for (encoded_filename_len = 0, i = 0; base[i]; i++) if (ISIDNUM (base[i]) || base[i] == '.') encoded_filename_len++; @@ -20604,7 +20604,7 @@ optimize_macinfo_range (unsigned int idx, VEC (macinfo_entry, gc) *files, /* Construct a macinfo_entry for DW_MACRO_GNU_transparent_include in the empty vector entry before the first define/undef. */ - inc = VEC_index (macinfo_entry, macinfo_table, idx - 1); + inc = &VEC_index (macinfo_entry, macinfo_table, idx - 1); inc->code = DW_MACRO_GNU_transparent_include; inc->lineno = 0; inc->info = ggc_strdup (grp_name); @@ -20697,7 +20697,7 @@ output_macinfo (void) && VEC_length (macinfo_entry, files) != 1 && i > 0 && i + 1 < length - && VEC_index (macinfo_entry, macinfo_table, i - 1)->code == 0) + && VEC_index (macinfo_entry, macinfo_table, i - 1).code == 0) { unsigned count = optimize_macinfo_range (i, files, &macinfo_htab); if (count) @@ -21307,14 +21307,14 @@ static inline void move_linkage_attr (dw_die_ref die) { unsigned ix = VEC_length (dw_attr_node, die->die_attr); - dw_attr_node linkage = *VEC_index (dw_attr_node, die->die_attr, ix - 1); + dw_attr_node linkage = VEC_index (dw_attr_node, die->die_attr, ix - 1); gcc_assert (linkage.dw_attr == DW_AT_linkage_name || linkage.dw_attr == DW_AT_MIPS_linkage_name); while (--ix > 0) { - dw_attr_node *prev = VEC_index (dw_attr_node, die->die_attr, ix - 1); + dw_attr_node *prev = &VEC_index (dw_attr_node, die->die_attr, ix - 1); if (prev->dw_attr == DW_AT_decl_line || prev->dw_attr == DW_AT_name) break; @@ -22226,8 +22226,8 @@ dwarf2out_finish (const char *filename) for (i = 0; i < VEC_length (deferred_locations, deferred_locations_list); i++) { add_location_or_const_value_attribute ( - VEC_index (deferred_locations, deferred_locations_list, i)->die, - VEC_index (deferred_locations, deferred_locations_list, i)->variable, + VEC_index (deferred_locations, deferred_locations_list, i).die, + VEC_index (deferred_locations, deferred_locations_list, i).variable, false, DW_AT_location); } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index ebd49b3..210cc14 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -6091,7 +6091,7 @@ locator_location (int loc) break; } } - return *VEC_index (location_t, locations_locators_vals, min); + return VEC_index (location_t, locations_locators_vals, min); } /* Return source line of the statement that produced this insn. */ diff --git a/gcc/except.c b/gcc/except.c index 605d8d7..0174512 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -304,8 +304,8 @@ init_eh_for_function (void) cfun->eh = ggc_alloc_cleared_eh_status (); /* Make sure zero'th entries are used. */ - VEC_safe_push (eh_region, gc, cfun->eh->region_array, NULL); - VEC_safe_push (eh_landing_pad, gc, cfun->eh->lp_array, NULL); + VEC_safe_push (eh_region, gc, cfun->eh->region_array, (eh_region) NULL); + VEC_safe_push (eh_landing_pad, gc, cfun->eh->lp_array, (eh_landing_pad) NULL); } /* Routines to generate the exception tree somewhat directly. @@ -806,7 +806,7 @@ add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list) if (targetm.arm_eabi_unwinder) VEC_safe_push (tree, gc, cfun->eh->ehspec_data.arm_eabi, NULL_TREE); else - VEC_safe_push (uchar, gc, cfun->eh->ehspec_data.other, 0); + VEC_safe_push (uchar, gc, cfun->eh->ehspec_data.other, (uchar) 0); } return n->filter; @@ -2395,10 +2395,10 @@ add_call_site (rtx landing_pad, int action, int section) record->action = action; VEC_safe_push (call_site_record, gc, - crtl->eh.call_site_record[section], record); + crtl->eh.call_site_record_v[section], record); return call_site_base + VEC_length (call_site_record, - crtl->eh.call_site_record[section]) - 1; + crtl->eh.call_site_record_v[section]) - 1; } /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes. @@ -2546,10 +2546,10 @@ convert_to_eh_region_ranges (void) else if (last_action != -3) last_landing_pad = pc_rtx; call_site_base += VEC_length (call_site_record, - crtl->eh.call_site_record[cur_sec]); + crtl->eh.call_site_record_v[cur_sec]); cur_sec++; - gcc_assert (crtl->eh.call_site_record[cur_sec] == NULL); - crtl->eh.call_site_record[cur_sec] + gcc_assert (crtl->eh.call_site_record_v[cur_sec] == NULL); + crtl->eh.call_site_record_v[cur_sec] = VEC_alloc (call_site_record, gc, 10); } @@ -2633,14 +2633,14 @@ push_sleb128 (VEC (uchar, gc) **data_area, int value) static int dw2_size_of_call_site_table (int section) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record[section]); + int n = VEC_length (call_site_record, crtl->eh.call_site_record_v[section]); int size = n * (4 + 4 + 4); int i; for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record[section], i); + VEC_index (call_site_record, crtl->eh.call_site_record_v[section], i); size += size_of_uleb128 (cs->action); } @@ -2650,14 +2650,14 @@ dw2_size_of_call_site_table (int section) static int sjlj_size_of_call_site_table (void) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record[0]); + int n = VEC_length (call_site_record, crtl->eh.call_site_record_v[0]); int size = 0; int i; for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record[0], i); + VEC_index (call_site_record, crtl->eh.call_site_record_v[0], i); size += size_of_uleb128 (INTVAL (cs->landing_pad)); size += size_of_uleb128 (cs->action); } @@ -2669,7 +2669,7 @@ sjlj_size_of_call_site_table (void) static void dw2_output_call_site_table (int cs_format, int section) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record[section]); + int n = VEC_length (call_site_record, crtl->eh.call_site_record_v[section]); int i; const char *begin; @@ -2683,7 +2683,7 @@ dw2_output_call_site_table (int cs_format, int section) for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record[section], i); + VEC_index (call_site_record, crtl->eh.call_site_record_v[section], i); char reg_start_lab[32]; char reg_end_lab[32]; char landing_pad_lab[32]; @@ -2731,13 +2731,13 @@ dw2_output_call_site_table (int cs_format, int section) static void sjlj_output_call_site_table (void) { - int n = VEC_length (call_site_record, crtl->eh.call_site_record[0]); + int n = VEC_length (call_site_record, crtl->eh.call_site_record_v[0]); int i; for (i = 0; i < n; ++i) { struct call_site_record_d *cs = - VEC_index (call_site_record, crtl->eh.call_site_record[0], i); + VEC_index (call_site_record, crtl->eh.call_site_record_v[0], i); dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad), "region %d landing pad", i); @@ -3051,7 +3051,7 @@ output_function_exception_table (const char *fnname) targetm.asm_out.emit_except_table_label (asm_out_file); output_one_function_exception_table (0); - if (crtl->eh.call_site_record[1] != NULL) + if (crtl->eh.call_site_record_v[1] != NULL) output_one_function_exception_table (1); switch_to_section (current_function_section ()); diff --git a/gcc/fixed-value.c b/gcc/fixed-value.c index 97aa8b5..9a34bc5 100644 --- a/gcc/fixed-value.c +++ b/gcc/fixed-value.c @@ -111,13 +111,11 @@ fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, enum machine_mode mode) /* From the spec, we need to evaluate 1 to the maximal value. */ f->data.low = -1; f->data.high = -1; - f->data = double_int_ext (f->data, - GET_MODE_FBIT (f->mode) - + GET_MODE_IBIT (f->mode), 1); + f->data = f->data.zext (GET_MODE_FBIT (f->mode) + + GET_MODE_IBIT (f->mode)); } else - f->data = double_int_ext (f->data, - SIGNED_FIXED_POINT_MODE_P (f->mode) + f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode) + GET_MODE_FBIT (f->mode) + GET_MODE_IBIT (f->mode), UNSIGNED_FIXED_POINT_MODE_P (f->mode)); @@ -159,8 +157,8 @@ fixed_saturate1 (enum machine_mode mode, double_int a, double_int *f, double_int max; max.low = -1; max.high = -1; - max = double_int_ext (max, i_f_bits, 1); - if (double_int_cmp (a, max, 1) == 1) + max = max.zext (i_f_bits); + if (a.ugt (max)) { if (sat_p) *f = max; @@ -173,21 +171,19 @@ fixed_saturate1 (enum machine_mode mode, double_int a, double_int *f, double_int max, min; max.high = -1; max.low = -1; - max = double_int_ext (max, i_f_bits, 1); + max = max.zext (i_f_bits); min.high = 0; min.low = 1; - lshift_double (min.low, min.high, i_f_bits, - HOST_BITS_PER_DOUBLE_INT, - &min.low, &min.high, 1); - min = double_int_ext (min, 1 + i_f_bits, 0); - if (double_int_cmp (a, max, 0) == 1) + min = min.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); + min = min.sext (1 + i_f_bits); + if (a.sgt (max)) { if (sat_p) *f = max; else overflow_p = true; } - else if (double_int_cmp (a, min, 0) == -1) + else if (a.slt (min)) { if (sat_p) *f = min; @@ -221,10 +217,10 @@ fixed_saturate2 (enum machine_mode mode, double_int a_high, double_int a_low, max_r.low = 0; max_s.high = -1; max_s.low = -1; - max_s = double_int_ext (max_s, i_f_bits, 1); - if (double_int_cmp (a_high, max_r, 1) == 1 - || (double_int_equal_p (a_high, max_r) && - double_int_cmp (a_low, max_s, 1) == 1)) + max_s = max_s.zext (i_f_bits); + if (a_high.ugt (max_r) + || (a_high == max_r && + a_low.ugt (max_s))) { if (sat_p) *f = max_s; @@ -239,27 +235,25 @@ fixed_saturate2 (enum machine_mode mode, double_int a_high, double_int a_low, max_r.low = 0; max_s.high = -1; max_s.low = -1; - max_s = double_int_ext (max_s, i_f_bits, 1); + max_s = max_s.zext (i_f_bits); min_r.high = -1; min_r.low = -1; min_s.high = 0; min_s.low = 1; - lshift_double (min_s.low, min_s.high, i_f_bits, - HOST_BITS_PER_DOUBLE_INT, - &min_s.low, &min_s.high, 1); - min_s = double_int_ext (min_s, 1 + i_f_bits, 0); - if (double_int_cmp (a_high, max_r, 0) == 1 - || (double_int_equal_p (a_high, max_r) && - double_int_cmp (a_low, max_s, 1) == 1)) + min_s = min_s.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); + min_s = min_s.sext (1 + i_f_bits); + if (a_high.sgt (max_r) + || (a_high == max_r && + a_low.ugt (max_s))) { if (sat_p) *f = max_s; else overflow_p = true; } - else if (double_int_cmp (a_high, min_r, 0) == -1 - || (double_int_equal_p (a_high, min_r) && - double_int_cmp (a_low, min_s, 1) == -1)) + else if (a_high.slt (min_r) + || (a_high == min_r && + a_low.ult (min_s))) { if (sat_p) *f = min_s; @@ -297,19 +291,19 @@ do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, /* This was a conditional expression but it triggered a bug in Sun C 5.5. */ if (subtract_p) - temp = double_int_neg (b->data); + temp = -b->data; else temp = b->data; unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); f->mode = a->mode; - f->data = double_int_add (a->data, temp); + f->data = a->data + temp; if (unsigned_p) /* Unsigned type. */ { if (subtract_p) /* Unsigned subtraction. */ { - if (double_int_cmp (a->data, b->data, 1) == -1) + if (a->data.ult (b->data)) { if (sat_p) { @@ -322,9 +316,9 @@ do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, } else /* Unsigned addition. */ { - f->data = double_int_ext (f->data, i_f_bits, 1); - if (double_int_cmp (f->data, a->data, 1) == -1 - || double_int_cmp (f->data, b->data, 1) == -1) + f->data = f->data.zext (i_f_bits); + if (f->data.ult (a->data) + || f->data.ult (b->data)) { if (sat_p) { @@ -353,22 +347,17 @@ do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, { f->data.low = 1; f->data.high = 0; - lshift_double (f->data.low, f->data.high, i_f_bits, - HOST_BITS_PER_DOUBLE_INT, - &f->data.low, &f->data.high, 1); + f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); if (get_fixed_sign_bit (a->data, i_f_bits) == 0) { - double_int one; - one.low = 1; - one.high = 0; - f->data = double_int_sub (f->data, one); + --f->data; } } else overflow_p = true; } } - f->data = double_int_ext (f->data, (!unsigned_p) + i_f_bits, unsigned_p); + f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); return overflow_p; } @@ -386,11 +375,10 @@ do_fixed_multiply (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, f->mode = a->mode; if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT) { - f->data = double_int_mul (a->data, b->data); - lshift_double (f->data.low, f->data.high, - (-GET_MODE_FBIT (f->mode)), + f->data = a->data * b->data; + f->data = f->data.lshift ((-GET_MODE_FBIT (f->mode)), HOST_BITS_PER_DOUBLE_INT, - &f->data.low, &f->data.high, !unsigned_p); + !unsigned_p); overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p); } else @@ -412,43 +400,43 @@ do_fixed_multiply (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, b_low.high = 0; /* Perform four multiplications. */ - low_low = double_int_mul (a_low, b_low); - low_high = double_int_mul (a_low, b_high); - high_low = double_int_mul (a_high, b_low); - high_high = double_int_mul (a_high, b_high); + low_low = a_low * b_low; + low_high = a_low * b_high; + high_low = a_high * b_low; + high_high = a_high * b_high; /* Accumulate four results to {r, s}. */ temp1.high = high_low.low; temp1.low = 0; - s = double_int_add (low_low, temp1); - if (double_int_cmp (s, low_low, 1) == -1 - || double_int_cmp (s, temp1, 1) == -1) + s = low_low + temp1; + if (s.ult (low_low) + || s.ult (temp1)) carry ++; /* Carry */ temp1.high = s.high; temp1.low = s.low; temp2.high = low_high.low; temp2.low = 0; - s = double_int_add (temp1, temp2); - if (double_int_cmp (s, temp1, 1) == -1 - || double_int_cmp (s, temp2, 1) == -1) + s = temp1 + temp2; + if (s.ult (temp1) + || s.ult (temp2)) carry ++; /* Carry */ temp1.low = high_low.high; temp1.high = 0; - r = double_int_add (high_high, temp1); + r = high_high + temp1; temp1.low = low_high.high; temp1.high = 0; - r = double_int_add (r, temp1); + r += temp1; temp1.low = carry; temp1.high = 0; - r = double_int_add (r, temp1); + r += temp1; /* We need to subtract b from r, if a < 0. */ if (!unsigned_p && a->data.high < 0) - r = double_int_sub (r, b->data); + r -= b->data; /* We need to subtract a from r, if b < 0. */ if (!unsigned_p && b->data.high < 0) - r = double_int_sub (r, a->data); + r -= a->data; /* Shift right the result by FBIT. */ if (GET_MODE_FBIT (f->mode) == HOST_BITS_PER_DOUBLE_INT) @@ -470,29 +458,23 @@ do_fixed_multiply (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, } else { - lshift_double (s.low, s.high, - (-GET_MODE_FBIT (f->mode)), - HOST_BITS_PER_DOUBLE_INT, - &s.low, &s.high, 0); - lshift_double (r.low, r.high, - (HOST_BITS_PER_DOUBLE_INT + s = s.llshift ((-GET_MODE_FBIT (f->mode)), HOST_BITS_PER_DOUBLE_INT); + f->data = r.llshift ((HOST_BITS_PER_DOUBLE_INT - GET_MODE_FBIT (f->mode)), - HOST_BITS_PER_DOUBLE_INT, - &f->data.low, &f->data.high, 0); + HOST_BITS_PER_DOUBLE_INT); f->data.low = f->data.low | s.low; f->data.high = f->data.high | s.high; s.low = f->data.low; s.high = f->data.high; - lshift_double (r.low, r.high, - (-GET_MODE_FBIT (f->mode)), + r = r.lshift ((-GET_MODE_FBIT (f->mode)), HOST_BITS_PER_DOUBLE_INT, - &r.low, &r.high, !unsigned_p); + !unsigned_p); } overflow_p = fixed_saturate2 (f->mode, r, s, &f->data, sat_p); } - f->data = double_int_ext (f->data, (!unsigned_p) + i_f_bits, unsigned_p); + f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); return overflow_p; } @@ -510,11 +492,10 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, f->mode = a->mode; if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT) { - lshift_double (a->data.low, a->data.high, - GET_MODE_FBIT (f->mode), + f->data = a->data.lshift (GET_MODE_FBIT (f->mode), HOST_BITS_PER_DOUBLE_INT, - &f->data.low, &f->data.high, !unsigned_p); - f->data = double_int_div (f->data, b->data, unsigned_p, TRUNC_DIV_EXPR); + !unsigned_p); + f->data = f->data.div (b->data, unsigned_p, TRUNC_DIV_EXPR); overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p); } else @@ -527,7 +508,7 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, /* If a < 0, negate a. */ if (!unsigned_p && a->data.high < 0) { - pos_a = double_int_neg (a->data); + pos_a = -a->data; num_of_neg ++; } else @@ -536,7 +517,7 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, /* If b < 0, negate b. */ if (!unsigned_p && b->data.high < 0) { - pos_b = double_int_neg (b->data); + pos_b = -b->data; num_of_neg ++; } else @@ -551,24 +532,15 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, } else { - lshift_double (pos_a.low, pos_a.high, - GET_MODE_FBIT (f->mode), - HOST_BITS_PER_DOUBLE_INT, - &s.low, &s.high, 0); - lshift_double (pos_a.low, pos_a.high, - - (HOST_BITS_PER_DOUBLE_INT + s = pos_a.llshift (GET_MODE_FBIT (f->mode), HOST_BITS_PER_DOUBLE_INT); + r = pos_a.llshift (- (HOST_BITS_PER_DOUBLE_INT - GET_MODE_FBIT (f->mode)), - HOST_BITS_PER_DOUBLE_INT, - &r.low, &r.high, 0); + HOST_BITS_PER_DOUBLE_INT); } /* Divide r by pos_b to quo_r. The remainder is in mod. */ - div_and_round_double (TRUNC_DIV_EXPR, 1, r.low, r.high, pos_b.low, - pos_b.high, &quo_r.low, &quo_r.high, &mod.low, - &mod.high); - - quo_s.high = 0; - quo_s.low = 0; + quo_r = r.divmod (pos_b, 1, TRUNC_DIV_EXPR, &mod); + quo_s = double_int_zero; for (i = 0; i < HOST_BITS_PER_DOUBLE_INT; i++) { @@ -576,37 +548,34 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, int leftmost_mod = (mod.high < 0); /* Shift left mod by 1 bit. */ - lshift_double (mod.low, mod.high, 1, HOST_BITS_PER_DOUBLE_INT, - &mod.low, &mod.high, 0); + mod = mod.llshift (1, HOST_BITS_PER_DOUBLE_INT); /* Test the leftmost bit of s to add to mod. */ if (s.high < 0) mod.low += 1; /* Shift left quo_s by 1 bit. */ - lshift_double (quo_s.low, quo_s.high, 1, HOST_BITS_PER_DOUBLE_INT, - &quo_s.low, &quo_s.high, 0); + quo_s = quo_s.llshift (1, HOST_BITS_PER_DOUBLE_INT); /* Try to calculate (mod - pos_b). */ - temp = double_int_sub (mod, pos_b); + temp = mod - pos_b; - if (leftmost_mod == 1 || double_int_cmp (mod, pos_b, 1) != -1) + if (leftmost_mod == 1 || mod.ucmp (pos_b) != -1) { quo_s.low += 1; mod = temp; } /* Shift left s by 1 bit. */ - lshift_double (s.low, s.high, 1, HOST_BITS_PER_DOUBLE_INT, - &s.low, &s.high, 0); + s = s.llshift (1, HOST_BITS_PER_DOUBLE_INT); } if (num_of_neg == 1) { - quo_s = double_int_neg (quo_s); + quo_s = -quo_s; if (quo_s.high == 0 && quo_s.low == 0) - quo_r = double_int_neg (quo_r); + quo_r = -quo_r; else { quo_r.low = ~quo_r.low; @@ -618,7 +587,7 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, overflow_p = fixed_saturate2 (f->mode, quo_r, quo_s, &f->data, sat_p); } - f->data = double_int_ext (f->data, (!unsigned_p) + i_f_bits, unsigned_p); + f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); return overflow_p; } @@ -643,10 +612,9 @@ do_fixed_shift (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT || (!left_p)) { - lshift_double (a->data.low, a->data.high, - left_p ? b->data.low : (-b->data.low), + f->data = a->data.lshift (left_p ? b->data.low : (-b->data.low), HOST_BITS_PER_DOUBLE_INT, - &f->data.low, &f->data.high, !unsigned_p); + !unsigned_p); if (left_p) /* Only left shift saturates. */ overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p); } @@ -661,23 +629,20 @@ do_fixed_shift (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, } else { - lshift_double (a->data.low, a->data.high, - b->data.low, + temp_low = a->data.lshift (b->data.low, HOST_BITS_PER_DOUBLE_INT, - &temp_low.low, &temp_low.high, !unsigned_p); + !unsigned_p); /* Logical shift right to temp_high. */ - lshift_double (a->data.low, a->data.high, - b->data.low - HOST_BITS_PER_DOUBLE_INT, - HOST_BITS_PER_DOUBLE_INT, - &temp_high.low, &temp_high.high, 0); + temp_high = a->data.llshift (b->data.low - HOST_BITS_PER_DOUBLE_INT, + HOST_BITS_PER_DOUBLE_INT); } if (!unsigned_p && a->data.high < 0) /* Signed-extend temp_high. */ - temp_high = double_int_ext (temp_high, b->data.low, unsigned_p); + temp_high = temp_high.ext (b->data.low, unsigned_p); f->data = temp_low; overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data, sat_p); } - f->data = double_int_ext (f->data, (!unsigned_p) + i_f_bits, unsigned_p); + f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); return overflow_p; } @@ -692,8 +657,8 @@ do_fixed_neg (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, bool sat_p) bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); f->mode = a->mode; - f->data = double_int_neg (a->data); - f->data = double_int_ext (f->data, (!unsigned_p) + i_f_bits, unsigned_p); + f->data = -a->data; + f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); if (unsigned_p) /* Unsigned type. */ { @@ -718,7 +683,7 @@ do_fixed_neg (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, bool sat_p) /* Saturate to the maximum by subtracting f->data by one. */ f->data.low = -1; f->data.high = -1; - f->data = double_int_ext (f->data, i_f_bits, 1); + f->data = f->data.zext (i_f_bits); } else overflow_p = true; @@ -789,25 +754,25 @@ fixed_compare (int icode, const FIXED_VALUE_TYPE *op0, switch (code) { case NE_EXPR: - return !double_int_equal_p (op0->data, op1->data); + return op0->data != op1->data; case EQ_EXPR: - return double_int_equal_p (op0->data, op1->data); + return op0->data == op1->data; case LT_EXPR: - return double_int_cmp (op0->data, op1->data, + return op0->data.cmp (op1->data, UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == -1; case LE_EXPR: - return double_int_cmp (op0->data, op1->data, + return op0->data.cmp (op1->data, UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != 1; case GT_EXPR: - return double_int_cmp (op0->data, op1->data, + return op0->data.cmp (op1->data, UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == 1; case GE_EXPR: - return double_int_cmp (op0->data, op1->data, + return op0->data.cmp (op1->data, UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != -1; default: @@ -835,19 +800,15 @@ fixed_convert (FIXED_VALUE_TYPE *f, enum machine_mode mode, /* Left shift a to temp_high, temp_low based on a->mode. */ double_int temp_high, temp_low; int amount = GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode); - lshift_double (a->data.low, a->data.high, - amount, + temp_low = a->data.lshift (amount, HOST_BITS_PER_DOUBLE_INT, - &temp_low.low, &temp_low.high, SIGNED_FIXED_POINT_MODE_P (a->mode)); /* Logical shift right to temp_high. */ - lshift_double (a->data.low, a->data.high, - amount - HOST_BITS_PER_DOUBLE_INT, - HOST_BITS_PER_DOUBLE_INT, - &temp_high.low, &temp_high.high, 0); + temp_high = a->data.llshift (amount - HOST_BITS_PER_DOUBLE_INT, + HOST_BITS_PER_DOUBLE_INT); if (SIGNED_FIXED_POINT_MODE_P (a->mode) && a->data.high < 0) /* Signed-extend temp_high. */ - temp_high = double_int_ext (temp_high, amount, 0); + temp_high = temp_high.sext (amount); f->mode = mode; f->data = temp_low; if (SIGNED_FIXED_POINT_MODE_P (a->mode) == @@ -885,10 +846,9 @@ fixed_convert (FIXED_VALUE_TYPE *f, enum machine_mode mode, /* Set to maximum. */ f->data.low = -1; /* Set to all ones. */ f->data.high = -1; /* Set to all ones. */ - f->data = double_int_ext (f->data, - GET_MODE_FBIT (f->mode) - + GET_MODE_IBIT (f->mode), - 1); /* Clear the sign. */ + f->data = f->data.zext (GET_MODE_FBIT (f->mode) + + GET_MODE_IBIT (f->mode)); + /* Clear the sign. */ } else overflow_p = true; @@ -903,10 +863,8 @@ fixed_convert (FIXED_VALUE_TYPE *f, enum machine_mode mode, { /* Right shift a to temp based on a->mode. */ double_int temp; - lshift_double (a->data.low, a->data.high, - GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode), + temp = a->data.lshift (GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode), HOST_BITS_PER_DOUBLE_INT, - &temp.low, &temp.high, SIGNED_FIXED_POINT_MODE_P (a->mode)); f->mode = mode; f->data = temp; @@ -944,10 +902,9 @@ fixed_convert (FIXED_VALUE_TYPE *f, enum machine_mode mode, /* Set to maximum. */ f->data.low = -1; /* Set to all ones. */ f->data.high = -1; /* Set to all ones. */ - f->data = double_int_ext (f->data, - GET_MODE_FBIT (f->mode) - + GET_MODE_IBIT (f->mode), - 1); /* Clear the sign. */ + f->data = f->data.zext (GET_MODE_FBIT (f->mode) + + GET_MODE_IBIT (f->mode)); + /* Clear the sign. */ } else overflow_p = true; @@ -959,8 +916,7 @@ fixed_convert (FIXED_VALUE_TYPE *f, enum machine_mode mode, } } - f->data = double_int_ext (f->data, - SIGNED_FIXED_POINT_MODE_P (f->mode) + f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode) + GET_MODE_FBIT (f->mode) + GET_MODE_IBIT (f->mode), UNSIGNED_FIXED_POINT_MODE_P (f->mode)); @@ -988,19 +944,14 @@ fixed_convert_from_int (FIXED_VALUE_TYPE *f, enum machine_mode mode, } else { - lshift_double (a.low, a.high, - amount, - HOST_BITS_PER_DOUBLE_INT, - &temp_low.low, &temp_low.high, 0); + temp_low = a.llshift (amount, HOST_BITS_PER_DOUBLE_INT); /* Logical shift right to temp_high. */ - lshift_double (a.low, a.high, - amount - HOST_BITS_PER_DOUBLE_INT, - HOST_BITS_PER_DOUBLE_INT, - &temp_high.low, &temp_high.high, 0); + temp_high = a.llshift (amount - HOST_BITS_PER_DOUBLE_INT, + HOST_BITS_PER_DOUBLE_INT); } if (!unsigned_p && a.high < 0) /* Signed-extend temp_high. */ - temp_high = double_int_ext (temp_high, amount, 0); + temp_high = temp_high.sext (amount); f->mode = mode; f->data = temp_low; @@ -1038,10 +989,9 @@ fixed_convert_from_int (FIXED_VALUE_TYPE *f, enum machine_mode mode, /* Set to maximum. */ f->data.low = -1; /* Set to all ones. */ f->data.high = -1; /* Set to all ones. */ - f->data = double_int_ext (f->data, - GET_MODE_FBIT (f->mode) - + GET_MODE_IBIT (f->mode), - 1); /* Clear the sign. */ + f->data = f->data.zext (GET_MODE_FBIT (f->mode) + + GET_MODE_IBIT (f->mode)); + /* Clear the sign. */ } else overflow_p = true; @@ -1051,8 +1001,7 @@ fixed_convert_from_int (FIXED_VALUE_TYPE *f, enum machine_mode mode, &f->data, sat_p); } } - f->data = double_int_ext (f->data, - SIGNED_FIXED_POINT_MODE_P (f->mode) + f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode) + GET_MODE_FBIT (f->mode) + GET_MODE_IBIT (f->mode), UNSIGNED_FIXED_POINT_MODE_P (f->mode)); @@ -1093,10 +1042,8 @@ fixed_convert_from_real (FIXED_VALUE_TYPE *f, enum machine_mode mode, { f->data.low = 1; f->data.high = 0; - lshift_double (f->data.low, f->data.high, i_f_bits, - HOST_BITS_PER_DOUBLE_INT, - &f->data.low, &f->data.high, 1); - f->data = double_int_ext (f->data, 1 + i_f_bits, 0); + f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); + f->data = f->data.sext (1 + i_f_bits); } } else @@ -1108,12 +1055,12 @@ fixed_convert_from_real (FIXED_VALUE_TYPE *f, enum machine_mode mode, { f->data.low = -1; f->data.high = -1; - f->data = double_int_ext (f->data, i_f_bits, 1); + f->data = f->data.zext (i_f_bits); } else overflow_p = true; } - f->data = double_int_ext (f->data, (!unsigned_p) + i_f_bits, unsigned_p); + f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); return overflow_p; } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5e14125..3bfd203 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14285,7 +14285,7 @@ fold (tree expr) while (begin != end) { unsigned HOST_WIDE_INT middle = (begin + end) / 2; - tree index = VEC_index (constructor_elt, elts, middle)->index; + tree index = VEC_index (constructor_elt, elts, middle).index; if (TREE_CODE (index) == INTEGER_CST && tree_int_cst_lt (index, op1)) @@ -14300,7 +14300,7 @@ fold (tree expr) && tree_int_cst_lt (op1, TREE_OPERAND (index, 0))) end = middle; else - return VEC_index (constructor_elt, elts, middle)->value; + return VEC_index (constructor_elt, elts, middle).value; } } diff --git a/gcc/function.h b/gcc/function.h index 3d3313f..684bbce 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -157,7 +157,7 @@ struct GTY(()) rtl_eh { VEC(uchar,gc) *action_record_data; - VEC(call_site_record,gc) *call_site_record[2]; + VEC(call_site_record,gc) *call_site_record_v[2]; }; #define pending_stack_adjust (crtl->expr.x_pending_stack_adjust) diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 65087ad..d1cba88 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -223,7 +223,7 @@ single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, bitmap_copy (local_lr, &lr_bb_info->in); /* Push a marker for the leave_block callback. */ - VEC_safe_push (df_ref, heap, reg_defs_stack, NULL); + VEC_safe_push (df_ref, heap, reg_defs_stack, (df_ref) NULL); process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP); process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP); @@ -2520,7 +2520,7 @@ execute (void) and record info about each one. Also search for the programs that are to be run. */ - VEC_safe_push (const_char_p, heap, argbuf, 0); + VEC_safe_push (const_char_p, heap, argbuf, (const_char_p)0); commands[0].prog = VEC_index (const_char_p, argbuf, 0); /* first command. */ commands[0].argv = VEC_address (const_char_p, argbuf); diff --git a/gcc/gdbinit.in b/gcc/gdbinit.in index d1ae46d..6432113 100644 --- a/gcc/gdbinit.in +++ b/gcc/gdbinit.in @@ -182,6 +182,13 @@ document pbm Dump the bitmap that is in $ as a comma-separated list of numbers. end +# Define some macros helpful to gdb when it is expanding macros. +macro define __FILE__ "gdb" +macro define __LINE__ 1 + +# Gracefully handle aborts in functions used from gdb. +set unwindonsignal on + # Put breakpoints at exit and fancy_abort in case abort is mapped # to either fprintf/exit or fancy_abort. b fancy_abort @@ -196,3 +203,9 @@ set complaints 0 # USE_SYSTEM_ABORT is defined, so gdb may complain and bail out. b exit b abort + +# Skip all inline functions in tree.h. +# These are used in accessor macros. +# Note that this is added at the end because older gdb versions +# do not understand the 'skip' command. +skip "tree.h" diff --git a/gcc/genautomata.c b/gcc/genautomata.c index 9f9e066b..122a4a4 100644 --- a/gcc/genautomata.c +++ b/gcc/genautomata.c @@ -5076,7 +5076,8 @@ store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle, length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num; while (VEC_length (unit_usage_t, cycle_alt_unit_usages) < length) - VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, 0); + VEC_safe_push (unit_usage_t, heap, cycle_alt_unit_usages, + (unit_usage_t) NULL); index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num; prev = NULL; @@ -7673,7 +7674,8 @@ output_min_issue_delay_table (automaton_t automaton) if (VEC_index (vect_el_t, min_issue_delay_vect, asn)) { - VEC_replace (vect_el_t, min_issue_delay_vect, asn, 0); + VEC_replace (vect_el_t, min_issue_delay_vect, asn, + (vect_el_t) 0); changed = 1; } @@ -7723,7 +7725,8 @@ output_min_issue_delay_table (automaton_t automaton) if (automaton->max_min_delay < x) automaton->max_min_delay = x; if (x == -1) - VEC_replace (vect_el_t, min_issue_delay_vect, np, 0); + VEC_replace (vect_el_t, min_issue_delay_vect, np, + (vect_el_t) 0); } } @@ -7749,7 +7752,8 @@ output_min_issue_delay_table (automaton_t automaton) = VEC_alloc (vect_el_t, heap, compressed_min_issue_delay_len); for (i = 0; i < compressed_min_issue_delay_len; i++) - VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, 0); + VEC_quick_push (vect_el_t, compressed_min_issue_delay_vect, + (vect_el_t) 0); for (i = 0; i < min_issue_delay_len; i++) { @@ -7798,7 +7802,8 @@ output_dead_lock_vect (automaton_t automaton) automaton->locked_states++; } else - VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, 0); + VEC_replace (vect_el_t, dead_lock_vect, s->order_state_num, + (vect_el_t) 0); } if (automaton->locked_states == 0) return; @@ -7840,7 +7845,7 @@ output_reserved_units_table (automaton_t automaton) reserved_units_table = VEC_alloc (vect_el_t, heap, reserved_units_size); for (i = 0; i < reserved_units_size; i++) - VEC_quick_push (vect_el_t, reserved_units_table, 0); + VEC_quick_push (vect_el_t, reserved_units_table, (vect_el_t) 0); for (n = 0; n < VEC_length (state_t, output_states_vect); n++) { state_t s = VEC_index (state_t, output_states_vect, n); diff --git a/gcc/genextract.c b/gcc/genextract.c index 09e7cde..175febe 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -201,7 +201,7 @@ VEC_safe_set_locstr (VEC(locstr,heap) **vp, unsigned int ix, char *str) else { while (ix > VEC_length (locstr, *vp)) - VEC_safe_push (locstr, heap, *vp, 0); + VEC_safe_push (locstr, heap, *vp, (locstr) NULL); VEC_safe_push (locstr, heap, *vp, str); } } diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l index a71cce0..5788a6a 100644 --- a/gcc/gengtype-lex.l +++ b/gcc/gengtype-lex.l @@ -1,6 +1,6 @@ /* -*- indented-text -*- */ /* Process source files and output type information. - Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -91,19 +91,6 @@ EOID [^[:alnum:]_] BEGIN(in_struct); return STATIC; } - -^{HWS}DEF_VEC_[OP]/{EOID} { - BEGIN(in_struct); - return DEFVEC_OP; -} -^{HWS}DEF_VEC_I/{EOID} { - BEGIN(in_struct); - return DEFVEC_I; -} -^{HWS}DEF_VEC_ALLOC_[IOP]/{EOID} { - BEGIN(in_struct); - return DEFVEC_ALLOC; -} } <in_struct>{ @@ -121,6 +108,7 @@ EOID [^[:alnum:]_] "enum"/{EOID} { return ENUM; } "ptr_alias"/{EOID} { return PTR_ALIAS; } "nested_ptr"/{EOID} { return NESTED_PTR; } +"user"/{EOID} { return USER_GTY; } [0-9]+ { return NUM; } "param"[0-9]*"_is"/{EOID} { *yylval = XDUPVAR (const char, yytext, yyleng, yyleng+1); diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c index c0ad403..03ee781 100644 --- a/gcc/gengtype-parse.c +++ b/gcc/gengtype-parse.c @@ -1,5 +1,5 @@ /* Process source files and output type information. - Copyright (C) 2006, 2007, 2010 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2010, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -77,9 +77,6 @@ static const char *const token_names[] = { "struct", "enum", "VEC", - "DEF_VEC_[OP]", - "DEF_VEC_I", - "DEF_VEC_ALLOC_[IOP]", "...", "ptr_alias", "nested_ptr", @@ -212,28 +209,70 @@ string_seq (void) return s1; } -/* typedef_name: either an ID, or VEC(x,y) which is translated to VEC_x_y. - Use only where VEC(x,y) is legitimate, i.e. in positions where a - typedef name may appear. */ + +/* The caller has detected a template declaration that starts + with TMPL_NAME. Parse up to the closing '>'. This recognizes + simple template declarations of the form ID<ID1,ID2,...,IDn>. + It does not try to parse anything more sophisticated than that. + + Returns the template declaration string "ID<ID1,ID2,...,IDn>". */ + +static const char * +require_template_declaration (const char *tmpl_name) +{ + char *str; + + /* Recognize the opening '<'. */ + require ('<'); + str = concat (tmpl_name, "<", (char *) 0); + + /* Read the comma-separated list of identifiers. */ + while (token () != '>') + { + const char *id = require2 (ID, ','); + if (id == NULL) + id = ","; + str = concat (str, id, (char *) 0); + } + + /* Recognize the closing '>'. */ + require ('>'); + str = concat (str, ">", (char *) 0); + + return str; +} + + +/* typedef_name: either an ID, or VEC(x,y), or a template type + specification of the form ID<t1,t2,...,tn>. + + FIXME cxx-conversion. VEC(x,y) is currently translated to the + template 'vec_t<x>'. This is to support the transition to C++ and + avoid re-writing all the 'VEC(x,y)' declarations in the code. This + needs to be fixed when the branch is merged into trunk. */ + static const char * typedef_name (void) { if (token () == VEC_TOKEN) { - const char *c1, *c2, *r; + const char *c1, *r; advance (); require ('('); c1 = require2 (ID, SCALAR); require (','); - c2 = require (ID); + require (ID); require (')'); - r = concat ("VEC_", c1, "_", c2, (char *) 0); + r = concat ("vec_t<", c1, ">", (char *) 0); free (CONST_CAST (char *, c1)); - free (CONST_CAST (char *, c2)); return r; } + + const char *id = require (ID); + if (token () == '<') + return require_template_declaration (id); else - return require (ID); + return id; } /* Absorb a sequence of tokens delimited by balanced ()[]{}. */ @@ -460,6 +499,10 @@ option (options_p prev) advance (); return nestedptr_optvalue (prev); + case USER_GTY: + advance (); + return create_string_option (prev, "user", ""); + default: parse_error ("expected an option keyword, have %s", print_cur_token ()); advance (); @@ -694,6 +737,18 @@ struct_field_seq (void) return nreverse_pairs (f); } +/* Return true if OPTS contain the option named STR. */ + +static bool +opts_have (options_p opts, const char *str) +{ + for (options_p opt = opts; opt; opt = opt->next) + if (strcmp (opt->name, str) == 0) + return true; + return false; +} + + /* This is called type(), but what it parses (sort of) is what C calls declaration-specifiers and specifier-qualifier-list: @@ -735,7 +790,7 @@ type (options_p *optsp, bool nested) GTY_BEFORE_ID, GTY_AFTER_ID } is_gty = NO_GTY; - bool is_union = (token () == UNION); + enum typekind kind = (token () == UNION) ? TYPE_UNION : TYPE_STRUCT; advance (); /* Top-level structures that are not explicitly tagged GTY(()) @@ -766,6 +821,7 @@ type (options_p *optsp, bool nested) if (is_gty) { + bool is_user_gty = opts_have (opts, "user"); if (token () == '{') { pair_p fields; @@ -773,17 +829,28 @@ type (options_p *optsp, bool nested) if (is_gty == GTY_AFTER_ID) parse_error ("GTY must be specified before identifier"); - advance (); - fields = struct_field_seq (); - require ('}'); - return new_structure (s, is_union, &lexer_line, fields, opts); + if (!is_user_gty) + { + advance (); + fields = struct_field_seq (); + require ('}'); + } + else + { + /* Do not look inside user defined structures. */ + fields = NULL; + kind = TYPE_USER_STRUCT; + consume_balanced ('{', '}'); + } + + return new_structure (s, kind, &lexer_line, fields, opts); } } else if (token () == '{') consume_balanced ('{', '}'); if (opts) *optsp = opts; - return find_structure (s, is_union); + return find_structure (s, kind); } case ENUM: @@ -891,55 +958,6 @@ extern_or_static (void) } } -/* Definition of a generic VEC structure: - - 'DEF_VEC_[IPO]' '(' id ')' ';' - - Scalar VECs require slightly different treatment than otherwise - - that's handled in note_def_vec, we just pass it along.*/ -static void -def_vec (void) -{ - bool is_scalar = (token () == DEFVEC_I); - const char *type; - - require2 (DEFVEC_OP, DEFVEC_I); - require ('('); - type = require2 (ID, SCALAR); - require (')'); - require (';'); - - if (!type) - return; - - note_def_vec (type, is_scalar, &lexer_line); - note_def_vec_alloc (type, "none", &lexer_line); -} - -/* Definition of an allocation strategy for a VEC structure: - - 'DEF_VEC_ALLOC_[IPO]' '(' id ',' id ')' ';' - - For purposes of gengtype, this just declares a wrapper structure. */ -static void -def_vec_alloc (void) -{ - const char *type, *astrat; - - require (DEFVEC_ALLOC); - require ('('); - type = require2 (ID, SCALAR); - require (','); - astrat = require (ID); - require (')'); - require (';'); - - if (!type || !astrat) - return; - - note_def_vec_alloc (type, astrat, &lexer_line); -} - /* Parse the file FNAME for GC-relevant declarations and definitions. This is the only entry point to this file. */ void @@ -964,15 +982,6 @@ parse_file (const char *fname) typedef_decl (); break; - case DEFVEC_OP: - case DEFVEC_I: - def_vec (); - break; - - case DEFVEC_ALLOC: - def_vec_alloc (); - break; - case EOF_TOKEN: goto eof; diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c index d7ea9b4..c94d50b 100644 --- a/gcc/gengtype-state.c +++ b/gcc/gengtype-state.c @@ -51,6 +51,7 @@ type_lineloc (const_type_p ty) case TYPE_STRUCT: case TYPE_UNION: case TYPE_LANG_STRUCT: + case TYPE_USER_STRUCT: return CONST_CAST (struct fileloc*, &ty->u.s.line); case TYPE_PARAM_STRUCT: return CONST_CAST (struct fileloc*, &ty->u.param_struct.line); @@ -798,6 +799,22 @@ write_state_struct_type (type_p current) write_state_type (current->u.s.lang_struct); } +/* Write a GTY user-defined struct type. */ +static void +write_state_user_struct_type (type_p current) +{ + DBGPRINTF ("user_struct type @ %p #%d '%s'", (void *) current, + current->state_number, current->u.s.tag); + fprintf (state_file, "user_struct "); + write_state_common_type_content (current); + if (current->u.s.tag != NULL) + write_state_a_string (current->u.s.tag); + else + fprintf (state_file, "nil"); + write_state_fileloc (type_lineloc (current)); + write_state_fields (current->u.s.fields); +} + /* write a GTY union type. */ static void write_state_union_type (type_p current) @@ -828,7 +845,7 @@ write_state_lang_struct_type (type_p current) DBGPRINTF ("homonymous #%d hty @ %p #%d '%s'", nbhomontype, (void *) hty, hty->state_number, hty->u.s.tag); /* Every member of the homonymous list should have the same tag. */ - gcc_assert (UNION_OR_STRUCT_P (hty)); + gcc_assert (union_or_struct_p (hty)); gcc_assert (hty->u.s.lang_struct == current); if (!homoname) homoname = hty->u.s.tag; @@ -947,6 +964,9 @@ write_state_type (type_p current) case TYPE_STRUCT: write_state_struct_type (current); break; + case TYPE_USER_STRUCT: + write_state_user_struct_type (current); + break; case TYPE_UNION: write_state_union_type (current); break; @@ -1365,6 +1385,42 @@ read_state_struct_type (type_p type) } +/* Read a GTY-ed user-provided struct TYPE. */ + +static void +read_state_user_struct_type (type_p type) +{ + struct state_token_st *t0; + + type->kind = TYPE_USER_STRUCT; + read_state_common_type_content (type); + t0 = peek_state_token (0); + if (state_token_kind (t0) == STOK_STRING) + { + if (state_token_is_name (t0, "nil")) + { + type->u.s.tag = NULL; + DBGPRINTF ("read anonymous struct type @%p #%d", + (void *) type, type->state_number); + } + else + { + type->u.s.tag = xstrdup (t0->stok_un.stok_string); + DBGPRINTF ("read struct type @%p #%d '%s'", + (void *) type, type->state_number, type->u.s.tag); + } + + next_state_tokens (1); + read_state_fileloc (&(type->u.s.line)); + read_state_fields (&(type->u.s.fields)); + } + else + { + fatal_reading_state (t0, "Bad tag in user-struct type"); + } +} + + /* Read a GTY-ed union type. */ static void read_state_union_type (type_p type) @@ -1655,6 +1711,12 @@ read_state_type (type_p *current) next_state_tokens (1); read_state_array_type (*current); } + else if (state_token_is_name (t0, "user_struct")) + { + *current = XCNEW (struct type); + next_state_tokens (1); + read_state_user_struct_type (*current); + } else fatal_reading_state (t0, "bad type in (!type"); } diff --git a/gcc/gengtype.c b/gcc/gengtype.c index a4aa725..2ae4372 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -1,5 +1,6 @@ /* Process source files and output type information. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, + 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -89,6 +90,10 @@ static const char *get_file_realbasename (const input_file *); static int get_prefix_langdir_index (const char *); static const char *get_file_langdir (const input_file *); + +static void dump_pair (int indent, pair_p p); +static void dump_type (int indent, type_p p); +static void dump_type_list (int indent, type_p p); /* Nonzero iff an error has occurred. */ @@ -166,6 +171,7 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t) int nb_types = 0, nb_scalar = 0, nb_string = 0; int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0; int nb_lang_struct = 0, nb_param_struct = 0; + int nb_user_struct = 0; type_p p = NULL; for (p = t; p; p = p->next) { @@ -181,6 +187,9 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t) case TYPE_STRUCT: nb_struct++; break; + case TYPE_USER_STRUCT: + nb_user_struct++; + break; case TYPE_UNION: nb_union++; break; @@ -211,6 +220,8 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t) if (nb_lang_struct > 0 || nb_param_struct > 0) fprintf (stderr, "@@%%@@ %d lang_structs, %d param_structs\n", nb_lang_struct, nb_param_struct); + if (nb_user_struct > 0) + fprintf (stderr, "@@%%@@ %d user_structs\n", nb_user_struct); fprintf (stderr, "\n"); } #endif /* ENABLE_CHECKING */ @@ -539,6 +550,51 @@ do_scalar_typedef (const char *s, struct fileloc *pos) do_typedef (s, &scalar_nonchar, pos); } + +/* Define TYPE_NAME to be a user defined type at location POS. */ + +static type_p +create_user_defined_type (const char *type_name, struct fileloc *pos) +{ + type_p ty = find_structure (type_name, TYPE_USER_STRUCT); + ty->u.s.line = *pos; + ty->u.s.bitmap = get_lang_bitmap (pos->file); + do_typedef (type_name, ty, pos); + + /* If TYPE_NAME specifies a template, create references to the types + in the template by pretending that each type is a field of TY. + This is needed to make sure that the types referenced by the + template are marked as used. */ + char *str = xstrdup (type_name); + char *open_bracket = strchr (str, '<'); + if (open_bracket) + { + /* We only accept simple template declarations (see + require_template_declaration), so we only need to parse a + comma-separated list of strings, implicitly assumed to + be type names. */ + char *arg = open_bracket + 1; + char *type_id = strtok (arg, ",>"); + pair_p fields = 0; + while (type_id) + { + /* Create a new field for every type found inside the template + parameter list. */ + const char *field_name = xstrdup (type_id); + type_p arg_type = resolve_typedef (field_name, pos); + fields = create_field_at (fields, arg_type, field_name, 0, pos); + type_id = strtok (0, ",>"); + } + + /* Associate the field list to TY. */ + ty->u.s.fields = fields; + } + free (str); + + return ty; +} + + /* Return the type previously defined for S. Use POS to report errors. */ type_p @@ -548,20 +604,27 @@ resolve_typedef (const char *s, struct fileloc *pos) for (p = typedefs; p != NULL; p = p->next) if (strcmp (p->name, s) == 0) return p->type; - error_at_line (pos, "unidentified type `%s'", s); - return &scalar_nonchar; /* treat as "int" */ + + /* If we did not find a typedef registered, assume this is a name + for a user-defined type which will need to provide its own + marking functions. */ + return create_user_defined_type (s, pos); } -/* Create and return a new structure with tag NAME (or a union iff - ISUNION is nonzero), at POS with fields FIELDS and options O. */ +/* Create and return a new structure with tag NAME at POS with fields + FIELDS and options O. The KIND of structure must be one of + TYPE_STRUCT, TYPE_UNION or TYPE_USER_STRUCT. */ type_p -new_structure (const char *name, int isunion, struct fileloc *pos, +new_structure (const char *name, enum typekind kind, struct fileloc *pos, pair_p fields, options_p o) { type_p si; type_p s = NULL; lang_bitmap bitmap = get_lang_bitmap (pos->file); + bool isunion = (kind == TYPE_UNION); + + gcc_assert (union_or_struct_p (kind)); for (si = structures; si != NULL; si = si->next) if (strcmp (name, si->u.s.tag) == 0 && UNION_P (si) == isunion) @@ -621,7 +684,7 @@ new_structure (const char *name, int isunion, struct fileloc *pos, error_at_line (&s->u.s.line, "previous definition here"); } - s->kind = isunion ? TYPE_UNION : TYPE_STRUCT; + s->kind = kind; s->u.s.tag = name; s->u.s.line = *pos; s->u.s.fields = fields; @@ -633,14 +696,18 @@ new_structure (const char *name, int isunion, struct fileloc *pos, return s; } -/* Return the previously-defined structure with tag NAME (or a union - iff ISUNION is nonzero), or a new empty structure or union if none - was defined previously. */ +/* Return the previously-defined structure or union with tag NAME, + or a new empty structure or union if none was defined previously. + The KIND of structure must be one of TYPE_STRUCT, TYPE_UNION or + TYPE_USER_STRUCT. */ type_p -find_structure (const char *name, int isunion) +find_structure (const char *name, enum typekind kind) { type_p s; + bool isunion = (kind == TYPE_UNION); + + gcc_assert (union_or_struct_p (kind)); for (s = structures; s != NULL; s = s->next) if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion) @@ -651,7 +718,7 @@ find_structure (const char *name, int isunion) s->next = structures; s->state_number = -type_count; structures = s; - s->kind = isunion ? TYPE_UNION : TYPE_STRUCT; + s->kind = kind; s->u.s.tag = name; structures = s; return s; @@ -851,7 +918,7 @@ create_optional_field_ (pair_p next, type_p type, const char *name, union_fields->opt = create_string_option (union_fields->opt, "tag", "1"); union_type = - new_structure (xasprintf ("%s_%d", "fake_union", id++), 1, + new_structure (xasprintf ("%s_%d", "fake_union", id++), TYPE_UNION, &lexer_line, union_fields, NULL); /* Create the field and give it the new fake union type. Add a "desc" @@ -993,16 +1060,16 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) nodot = create_string_option (NULL, "dot", ""); - rtx_tp = create_pointer (find_structure ("rtx_def", 0)); - rtvec_tp = create_pointer (find_structure ("rtvec_def", 0)); - tree_tp = create_pointer (find_structure ("tree_node", 1)); - mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0)); + rtx_tp = create_pointer (find_structure ("rtx_def", TYPE_STRUCT)); + rtvec_tp = create_pointer (find_structure ("rtvec_def", TYPE_STRUCT)); + tree_tp = create_pointer (find_structure ("tree_node", TYPE_UNION)); + mem_attrs_tp = create_pointer (find_structure ("mem_attrs", TYPE_STRUCT)); reg_attrs_tp = - create_pointer (find_structure ("reg_attrs", 0)); + create_pointer (find_structure ("reg_attrs", TYPE_STRUCT)); basic_block_tp = - create_pointer (find_structure ("basic_block_def", 0)); + create_pointer (find_structure ("basic_block_def", TYPE_STRUCT)); constant_tp = - create_pointer (find_structure ("constant_descriptor_rtx", 0)); + create_pointer (find_structure ("constant_descriptor_rtx", TYPE_STRUCT)); scalar_tp = &scalar_nonchar; /* rtunion int */ { @@ -1042,7 +1109,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) note_flds->opt = create_string_option (nodot, "tag", note_insn_name[c]); } - note_union_tp = new_structure ("rtx_def_note_subunion", 1, + note_union_tp = new_structure ("rtx_def_note_subunion", TYPE_UNION, &lexer_line, note_flds, NULL); } /* Create a type to represent the various forms of SYMBOL_REF_DATA. */ @@ -1052,7 +1119,7 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) sym_flds->opt = create_string_option (nodot, "default", ""); sym_flds = create_field (sym_flds, constant_tp, "rt_constant"); sym_flds->opt = create_string_option (nodot, "tag", "1"); - symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1, + symbol_union_tp = new_structure ("rtx_def_symbol_subunion", TYPE_UNION, &lexer_line, sym_flds, NULL); } for (i = 0; i < NUM_RTX_CODE; i++) @@ -1185,14 +1252,15 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) { /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P holds. */ - type_p field_tp = find_structure ("block_symbol", 0); + type_p field_tp = find_structure ("block_symbol", TYPE_STRUCT); subfields = create_optional_field (subfields, field_tp, "block_sym", "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)"); } sname = xasprintf ("rtx_def_%s", rtx_name[i]); - substruct = new_structure (sname, 0, &lexer_line, subfields, NULL); + substruct = new_structure (sname, TYPE_STRUCT, &lexer_line, subfields, + NULL); ftag = xstrdup (rtx_name[i]); for (nmindex = 0; nmindex < strlen (ftag); nmindex++) @@ -1200,7 +1268,8 @@ adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt)) flds = create_field (flds, substruct, ""); flds->opt = create_string_option (nodot, "tag", ftag); } - return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot); + return new_structure ("rtx_def_subunion", TYPE_UNION, &lexer_line, flds, + nodot); } /* Handle `special("tree_exp")'. This is a special case for @@ -1229,7 +1298,8 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED) "TREE_OPERAND_LENGTH ((tree) &%0)"); flds->opt = create_string_option (flds->opt, "default", ""); - return new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot); + return new_structure ("tree_exp_subunion", TYPE_UNION, &lexer_line, flds, + nodot); } /* Perform any special processing on a type T, about to become the type @@ -1275,8 +1345,8 @@ adjust_field_type (type_p t, options_p opt) { int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0; - if (!UNION_OR_STRUCT_P (t) - && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p))) + if (!union_or_struct_p (t) + && (t->kind != TYPE_POINTER || !union_or_struct_p (t->u.p))) { error_at_line (&lexer_line, "option `%s' may only be applied to structures or structure pointers", @@ -1369,6 +1439,7 @@ set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM]) { case TYPE_STRUCT: case TYPE_UNION: + case TYPE_USER_STRUCT: { pair_p f; int dummy; @@ -1468,7 +1539,7 @@ static outf_p create_file (const char *name, const char *oname) { static const char *const hdr[] = { - " Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n", + " Copyright (C) 2004, 2007, 2009, 2012 Free Software Foundation, Inc.\n", "\n", "This file is part of GCC.\n", "\n", @@ -2176,7 +2247,6 @@ close_output_files (void) for (of = output_files; of; of = of->next) { - if (!is_file_equal (of)) { FILE *newfile = NULL; @@ -2303,9 +2373,38 @@ struct walk_type_data bool fn_wants_lvalue; bool in_record_p; int loopcounter; + bool in_ptr_field; bool have_this_obj; }; + +/* Given a string TYPE_NAME, representing a C++ typename, return a valid + pre-processor identifier to use in a #define directive. This replaces + special characters used in C++ identifiers like '>', '<' and ':' with + '_'. + + If no C++ special characters are found in TYPE_NAME, return + TYPE_NAME. Otherwise, return a copy of TYPE_NAME with the special + characters replaced with '_'. In this case, the caller is + responsible for freeing the allocated string. */ + +static const char * +filter_type_name (const char *type_name) +{ + if (strchr (type_name, '<') || strchr (type_name, ':')) + { + size_t i; + char *s = xstrdup (type_name); + for (i = 0; i < strlen (s); i++) + if (s[i] == '<' || s[i] == '>' || s[i] == ':') + s[i] = '_'; + return s; + } + else + return type_name; +} + + /* Print a mangled name representing T to OF. */ static void @@ -2332,8 +2431,14 @@ output_mangled_typename (outf_p of, const_type_p t) case TYPE_STRUCT: case TYPE_UNION: case TYPE_LANG_STRUCT: - oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), - t->u.s.tag); + case TYPE_USER_STRUCT: + { + const char *id_for_tag = filter_type_name (t->u.s.tag); + oprintf (of, "%lu%s", (unsigned long) strlen (id_for_tag), + id_for_tag); + if (id_for_tag != t->u.s.tag) + free (CONST_CAST(char *, id_for_tag)); + } break; case TYPE_PARAM_STRUCT: { @@ -2390,6 +2495,7 @@ output_escaped_param (struct walk_type_data *d, const char *param, } } + /* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL, which is of type T. Write code to D->OF to constrain execution (at the point that D->PROCESS_FIELD is called) to the appropriate @@ -2470,7 +2576,7 @@ walk_type (type_p t, struct walk_type_data *d) if (pointer_p) t = t->u.p; - if (!UNION_OR_STRUCT_P (t)) + if (!union_or_struct_p (t)) error_at_line (d->line, "`use_params' option on unimplemented type"); else t = find_param_structure (t, d->param); @@ -2498,7 +2604,7 @@ walk_type (type_p t, struct walk_type_data *d) } if (maybe_undef_p - && (t->kind != TYPE_POINTER || !UNION_OR_STRUCT_P (t->u.p))) + && (t->kind != TYPE_POINTER || !union_or_struct_p (t->u.p))) { error_at_line (d->line, "field `%s' has invalid option `maybe_undef_p'\n", @@ -2521,6 +2627,7 @@ walk_type (type_p t, struct walk_type_data *d) case TYPE_POINTER: { + d->in_ptr_field = true; if (maybe_undef_p && t->u.p->u.s.line.file == NULL) { oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val); @@ -2548,7 +2655,7 @@ walk_type (type_p t, struct walk_type_data *d) if (!length) { - if (!UNION_OR_STRUCT_P (t->u.p) + if (!union_or_struct_p (t->u.p) && t->u.p->kind != TYPE_PARAM_STRUCT) { error_at_line (d->line, @@ -2561,7 +2668,7 @@ walk_type (type_p t, struct walk_type_data *d) { const char *oldprevval2 = d->prev_val[2]; - if (!UNION_OR_STRUCT_P (nested_ptr_d->type)) + if (!union_or_struct_p (nested_ptr_d->type)) { error_at_line (d->line, "field `%s' has invalid " @@ -2638,6 +2745,7 @@ walk_type (type_p t, struct walk_type_data *d) d->indent -= 2; oprintf (d->of, "%*s}\n", d->indent, ""); } + d->in_ptr_field = false; } break; @@ -2921,6 +3029,10 @@ walk_type (type_p t, struct walk_type_data *d) } break; + case TYPE_USER_STRUCT: + d->process_field (t, d); + break; + default: gcc_unreachable (); } @@ -2978,7 +3090,7 @@ write_types_process_field (type_p f, const struct walk_type_data *d) oprintf (d->of, ", gt_e_"); output_mangled_typename (d->of, f); } - else if (UNION_OR_STRUCT_P (f) && f->u.p->u.s.line.file != NULL) + else if (union_or_struct_p (f) && f->u.p->u.s.line.file != NULL) { oprintf (d->of, ", gt_ggc_e_"); output_mangled_typename (d->of, f); @@ -2998,13 +3110,27 @@ write_types_process_field (type_p f, const struct walk_type_data *d) case TYPE_UNION: case TYPE_LANG_STRUCT: case TYPE_PARAM_STRUCT: - oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix); - output_mangled_typename (d->of, f); - oprintf (d->of, " (%s%s);\n", cast, d->val); - if (d->reorder_fn && wtd->reorder_note_routine) - oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "", - wtd->reorder_note_routine, cast, d->val, cast, d->val, - d->reorder_fn); + case TYPE_USER_STRUCT: + if (f->kind == TYPE_USER_STRUCT && !d->in_ptr_field) + { + /* If F is a user-defined type and the field is not a + pointer to the type, then we should not generate the + standard pointer-marking code. All we need to do is call + the user-provided marking function to process the fields + of F. */ + oprintf (d->of, "%*sgt_%sx (&(%s));\n", d->indent, "", wtd->prefix, + d->val); + } + else + { + oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix); + output_mangled_typename (d->of, f); + oprintf (d->of, " (%s%s);\n", cast, d->val); + if (d->reorder_fn && wtd->reorder_note_routine) + oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "", + wtd->reorder_note_routine, cast, d->val, cast, d->val, + d->reorder_fn); + } break; case TYPE_SCALAR: @@ -3025,7 +3151,7 @@ output_type_enum (outf_p of, type_p s) oprintf (of, ", gt_e_"); output_mangled_typename (of, s); } - else if (UNION_OR_STRUCT_P (s) && s->u.s.line.file != NULL) + else if (union_or_struct_p (s) && s->u.s.line.file != NULL) { oprintf (of, ", gt_ggc_e_"); output_mangled_typename (of, s); @@ -3043,13 +3169,13 @@ get_output_file_for_structure (const_type_p s, type_p *param) const input_file *fn; int i; - gcc_assert (UNION_OR_STRUCT_P (s)); + gcc_assert (union_or_struct_p (s)); fn = s->u.s.line.file; /* This is a hack, and not the good kind either. */ for (i = NUM_PARAM - 1; i >= 0; i--) if (param && param[i] && param[i]->kind == TYPE_POINTER - && UNION_OR_STRUCT_P (param[i]->u.p)) + && union_or_struct_p (param[i]->u.p)) fn = param[i]->u.p->u.s.line.file; /* The call to get_output_file_with_visibility may update fn by @@ -3057,13 +3183,185 @@ get_output_file_for_structure (const_type_p s, type_p *param) return get_output_file_with_visibility (CONST_CAST (input_file*, fn)); } + +/* Returns the specifier keyword for a string or union type S, empty string + otherwise. */ + +static const char * +get_type_specifier (const type_p s) +{ + if (s->kind == TYPE_STRUCT) + return "struct "; + else if (s->kind == TYPE_LANG_STRUCT) + return get_type_specifier (s->u.s.lang_struct); + else if (s->kind == TYPE_UNION) + return "union "; + return ""; +} + + +/* Emits a declaration for type TY (assumed to be a union or a + structure) on stream OUT. */ + +static void +write_type_decl (outf_p out, type_p ty) +{ + if (union_or_struct_p (ty)) + oprintf (out, "%s%s", get_type_specifier (ty), ty->u.s.tag); + else if (ty->kind == TYPE_SCALAR) + { + if (ty->u.scalar_is_char) + oprintf (out, "const char"); + else + oprintf (out, "void"); + } + else if (ty->kind == TYPE_POINTER) + { + write_type_decl (out, ty->u.p); + oprintf (out, " *"); + } + else if (ty->kind == TYPE_ARRAY) + { + write_type_decl (out, ty->u.a.p); + oprintf (out, " *"); + } + else if (ty->kind == TYPE_STRING) + { + oprintf (out, "const char *"); + } + else + gcc_unreachable (); +} + + +/* Write on OF the name of the marker function for structure S. PREFIX + is the prefix to use (to distinguish ggc from pch markers). */ + +static void +write_marker_function_name (outf_p of, type_p s, const char *prefix) +{ + if (union_or_struct_p (s)) + { + const char *id_for_tag = filter_type_name (s->u.s.tag); + oprintf (of, "gt_%sx_%s", prefix, id_for_tag); + if (id_for_tag != s->u.s.tag) + free (CONST_CAST(char *, id_for_tag)); + } + else if (s->kind == TYPE_PARAM_STRUCT) + { + oprintf (of, "gt_%s_", prefix); + output_mangled_typename (of, s); + } + else + gcc_unreachable (); +} + + +/* Write on OF a user-callable routine to act as an entry point for + the marking routine for S, generated by write_func_for_structure. + PREFIX is the prefix to use to distinguish ggc and pch markers. */ + +static void +write_user_func_for_structure_ptr (outf_p of, type_p s, const char *prefix) +{ + /* Parameterized structures are not supported in user markers. There + is no way for the marker function to know which specific type + to use to generate the call to the void * entry point. For + instance, a marker for struct htab may need to call different + routines to mark the fields, depending on the paramN_is attributes. + + A user-defined marker that accepts 'struct htab' as its argument + would not know which variant to call. Generating several entry + points accepting 'struct htab' would cause multiply-defined + errors during compilation. */ + gcc_assert (union_or_struct_p (s)); + + type_p alias_of = NULL; + for (options_p opt = s->u.s.opt; opt; opt = opt->next) + if (strcmp (opt->name, "ptr_alias") == 0) + { + /* ALIAS_OF is set if ORIG_S is marked "ptr_alias". This means that + we do not generate marking code for ORIG_S here. Instead, a + forwarder #define in gtype-desc.h will cause every call to its + marker to call the target of this alias. + + However, we still want to create a user entry code for the + aliased type. So, if ALIAS_OF is set, we only generate the + user-callable marker function. */ + alias_of = opt->info.type; + break; + } + + oprintf (of, "\nvoid\n"); + oprintf (of, "gt_%sx (", prefix); + write_type_decl (of, s); + oprintf (of, " *& x)\n"); + oprintf (of, "{\n"); + oprintf (of, " if (x)\n "); + write_marker_function_name (of, alias_of ? alias_of : s, prefix); + oprintf (of, " ((void *) x);\n"); + oprintf (of, "}\n"); +} + + +/* Write a function to mark all the fields of type S on OF. PREFIX + and D are as in write_user_marking_functions. */ + +static void +write_user_func_for_structure_body (type_p s, const char *prefix, + struct walk_type_data *d) +{ + oprintf (d->of, "\nvoid\n"); + oprintf (d->of, "gt_%sx (", prefix); + write_type_decl (d->of, s); + oprintf (d->of, "& x_r ATTRIBUTE_UNUSED)\n"); + oprintf (d->of, "{\n"); + oprintf (d->of, " "); + write_type_decl (d->of, s); + oprintf (d->of, " * ATTRIBUTE_UNUSED x = &x_r;\n"); + d->val = "(*x)"; + d->indent = 2; + walk_type (s, d); + oprintf (d->of, "}\n"); +} + + +/* Emit the user-callable functions needed to mark all the types used + by the user structure S. PREFIX is the prefix to use to + distinguish ggc and pch markers. D contains data needed to pass to + walk_type when traversing the fields of a type. + + For every type T referenced by S, two routines are generated: one + that takes 'T *', marks the pointer and calls the second routine, + which just marks the fields of T. */ + +static void +write_user_marking_functions (type_p s, const char *prefix, + struct walk_type_data *d) +{ + gcc_assert (s->kind == TYPE_USER_STRUCT); + + for (pair_p fld = s->u.s.fields; fld; fld = fld->next) + { + type_p fld_type = fld->type; + if (fld_type->kind == TYPE_POINTER) + { + type_p pointed_to_type = fld_type->u.p; + if (union_or_struct_p (pointed_to_type)) + write_user_func_for_structure_ptr (d->of, pointed_to_type, prefix); + } + else if (union_or_struct_p (fld_type)) + write_user_func_for_structure_body (fld_type, prefix, d); + } +} + + /* For S, a structure that's part of ORIG_S, and using parameters PARAM, write out a routine that: - Takes a parameter, a void * but actually of type *S - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each field of S or its substructures and (in some cases) things - that are pointed to by S. -*/ + that are pointed to by S. */ static void write_func_for_structure (type_p orig_s, type_p s, type_p *param, @@ -3113,22 +3411,19 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param, oprintf (d.of, "\n"); oprintf (d.of, "void\n"); - if (param == NULL) - oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag); - else - { - oprintf (d.of, "gt_%s_", wtd->prefix); - output_mangled_typename (d.of, orig_s); - } + write_marker_function_name (d.of, orig_s, wtd->prefix); oprintf (d.of, " (void *x_p)\n"); - oprintf (d.of, "{\n"); - oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n", - s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, - chain_next == NULL ? "const " : "", - s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); + oprintf (d.of, "{\n "); + write_type_decl (d.of, s); + oprintf (d.of, " * %sx = (", chain_next == NULL ? "const " : ""); + write_type_decl (d.of, s); + oprintf (d.of, " *)x_p;\n"); if (chain_next != NULL) - oprintf (d.of, " %s %s * xlimit = x;\n", - s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); + { + oprintf (d.of, " "); + write_type_decl (d.of, s); + oprintf (d.of, " * xlimit = x;\n"); + } if (chain_next == NULL) { oprintf (d.of, " if (%s (x", wtd->marker_routine); @@ -3211,9 +3506,17 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param, { oprintf (d.of, " %s (x);\n", mark_hook_name); } + d.prev_val[2] = "*x"; d.indent = 6; - walk_type (s, &d); + if (orig_s->kind != TYPE_USER_STRUCT) + walk_type (s, &d); + else + { + /* User structures have no fields to walk. Simply generate a call + to the user-provided structure marker. */ + oprintf (d.of, "%*sgt_%sx (x);\n", d.indent, "", wtd->prefix); + } if (chain_next != NULL) { @@ -3226,8 +3529,12 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param, if (chain_circular != NULL) oprintf (d.of, " while (x != xlimit);\n"); oprintf (d.of, "}\n"); + + if (orig_s->kind == TYPE_USER_STRUCT) + write_user_marking_functions (orig_s, wtd->prefix, &d); } + /* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */ static void @@ -3238,9 +3545,10 @@ write_types (outf_p output_header, type_p structures, type_p param_structs, type_p s; oprintf (output_header, "\n/* %s*/\n", wtd->comment); + /* We first emit the macros and the declarations. Functions' code is emitted afterwards. This is needed in plugin mode. */ - oprintf (output_header, "/* macros and declarations */\n"); + oprintf (output_header, "/* Macros and declarations. */\n"); for (s = structures; s; s = s->next) if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO) { @@ -3249,12 +3557,14 @@ write_types (outf_p output_header, type_p structures, type_p param_structs, if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL) continue; + const char *s_id_for_tag = filter_type_name (s->u.s.tag); + oprintf (output_header, "#define gt_%s_", wtd->prefix); output_mangled_typename (output_header, s); oprintf (output_header, "(X) do { \\\n"); oprintf (output_header, " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix, - s->u.s.tag); + s_id_for_tag); oprintf (output_header, " } while (0)\n"); for (opt = s->u.s.opt; opt; opt = opt->next) @@ -3264,9 +3574,14 @@ write_types (outf_p output_header, type_p structures, type_p param_structs, const_type_p const t = (const_type_p) opt->info.type; if (t->kind == TYPE_STRUCT || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT) - oprintf (output_header, - "#define gt_%sx_%s gt_%sx_%s\n", - wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag); + { + const char *t_id_for_tag = filter_type_name (t->u.s.tag); + oprintf (output_header, + "#define gt_%sx_%s gt_%sx_%s\n", + wtd->prefix, s->u.s.tag, wtd->prefix, t_id_for_tag); + if (t_id_for_tag != t->u.s.tag) + free (CONST_CAST(char *, t_id_for_tag)); + } else error_at_line (&s->u.s.line, "structure alias is not a structure"); @@ -3278,7 +3593,10 @@ write_types (outf_p output_header, type_p structures, type_p param_structs, /* Declare the marker procedure only once. */ oprintf (output_header, "extern void gt_%sx_%s (void *);\n", - wtd->prefix, s->u.s.tag); + wtd->prefix, s_id_for_tag); + + if (s_id_for_tag != s->u.s.tag) + free (CONST_CAST(char *, s_id_for_tag)); if (s->u.s.line.file == NULL) { @@ -3400,6 +3718,90 @@ static const struct write_types_data pch_wtd = { /* Write out the local pointer-walking routines. */ +/* process_field routine for local pointer-walking for user-callable + routines. The difference between this and + write_types_local_process_field is that, in this case, we do not + need to check whether the given pointer matches the address of the + parent structure. This check was already generated by the call + to gt_pch_nx in the main gt_pch_p_*() function that is calling + this code. */ + +static void +write_types_local_user_process_field (type_p f, const struct walk_type_data *d) +{ + switch (f->kind) + { + case TYPE_POINTER: + case TYPE_STRUCT: + case TYPE_UNION: + case TYPE_LANG_STRUCT: + case TYPE_PARAM_STRUCT: + case TYPE_STRING: + oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); + break; + + case TYPE_USER_STRUCT: + if (d->in_ptr_field) + oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); + else + oprintf (d->of, "%*s gt_pch_nx (&(%s), op, cookie);\n", + d->indent, "", d->val); + break; + + case TYPE_SCALAR: + break; + + default: + gcc_unreachable (); + } +} + + +/* Write a function to PCH walk all the fields of type S on OF. + D contains data needed by walk_type to recurse into the fields of S. */ + +static void +write_pch_user_walking_for_structure_body (type_p s, struct walk_type_data *d) +{ + oprintf (d->of, "\nvoid\n"); + oprintf (d->of, "gt_pch_nx ("); + write_type_decl (d->of, s); + oprintf (d->of, "* x ATTRIBUTE_UNUSED,\n" + "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n" + "\tATTRIBUTE_UNUSED void *cookie)\n"); + oprintf (d->of, "{\n"); + d->val = "(*x)"; + d->indent = 2; + d->process_field = write_types_local_user_process_field; + walk_type (s, d); + oprintf (d->of, "}\n"); +} + + +/* Emit the user-callable functions needed to mark all the types used + by the user structure S. PREFIX is the prefix to use to + distinguish ggc and pch markers. CHAIN_NEXT is set if S has the + chain_next option defined. D contains data needed to pass to + walk_type when traversing the fields of a type. + + For every type T referenced by S, two routines are generated: one + that takes 'T *', marks the pointer and calls the second routine, + which just marks the fields of T. */ + +static void +write_pch_user_walking_functions (type_p s, struct walk_type_data *d) +{ + gcc_assert (s->kind == TYPE_USER_STRUCT); + + for (pair_p fld = s->u.s.fields; fld; fld = fld->next) + { + type_p fld_type = fld->type; + if (union_or_struct_p (fld_type)) + write_pch_user_walking_for_structure_body (fld_type, d); + } +} + + /* process_field routine for local pointer-walking. */ static void @@ -3419,6 +3821,16 @@ write_types_local_process_field (type_p f, const struct walk_type_data *d) oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); break; + case TYPE_USER_STRUCT: + oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "", + d->prev_val[3]); + if (d->in_ptr_field) + oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val); + else + oprintf (d->of, "%*s gt_pch_nx (&(%s), op, cookie);\n", + d->indent, "", d->val); + break; + case TYPE_SCALAR: break; @@ -3427,6 +3839,7 @@ write_types_local_process_field (type_p f, const struct walk_type_data *d) } } + /* For S, a structure that's part of ORIG_S, and using parameters PARAM, write out a routine that: - Is of type gt_note_pointers @@ -3460,13 +3873,29 @@ write_local_func_for_structure (const_type_p orig_s, type_p s, type_p *param) "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n" "\tATTRIBUTE_UNUSED void *cookie)\n"); oprintf (d.of, "{\n"); - oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n", + oprintf (d.of, " %s %s * x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n", s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); d.indent = 2; d.have_this_obj = true; - walk_type (s, &d); + + if (s->kind != TYPE_USER_STRUCT) + walk_type (s, &d); + else + { + /* User structures have no fields to walk. Simply generate a + call to the user-provided PCH walker. */ + oprintf (d.of, "%*sif ((void *)(%s) == this_obj)\n", d.indent, "", + d.prev_val[3]); + oprintf (d.of, "%*s gt_pch_nx (&(%s), op, cookie);\n", + d.indent, "", d.val); + } + oprintf (d.of, "}\n"); + + /* Write user-callable entry points for the PCH walking routines. */ + if (orig_s->kind == TYPE_USER_STRUCT) + write_pch_user_walking_functions (s, &d); } /* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */ @@ -3478,6 +3907,7 @@ write_local (outf_p output_header, type_p structures, type_p param_structs) if (!output_header) return; + oprintf (output_header, "\n/* Local pointer-walking routines. */\n"); for (s = structures; s; s = s->next) if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO) @@ -3557,15 +3987,15 @@ write_local (outf_p output_header, type_p structures, type_p param_structs) /* Nonzero if S is a type for which typed GC allocators should be output. */ #define USED_BY_TYPED_GC_P(s) \ - (((s->kind == TYPE_POINTER) \ - && ((s->u.p->gc_used == GC_POINTED_TO) \ - || (s->u.p->gc_used == GC_USED))) \ - || (UNION_OR_STRUCT_P (s) && \ - (((s)->gc_used == GC_POINTED_TO) \ - || ((s)->gc_used == GC_MAYBE_POINTED_TO \ - && s->u.s.line.file != NULL) \ - || ((s)->gc_used == GC_USED \ - && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous")))))) + ((s->kind == TYPE_POINTER \ + && (s->u.p->gc_used == GC_POINTED_TO \ + || s->u.p->gc_used == GC_USED)) \ + || (union_or_struct_p (s) \ + && ((s)->gc_used == GC_POINTED_TO \ + || ((s)->gc_used == GC_MAYBE_POINTED_TO \ + && s->u.s.line.file != NULL) \ + || ((s)->gc_used == GC_USED \ + && strncmp (s->u.s.tag, "anonymous", strlen ("anonymous")))))) /* Write out the 'enum' definition for gt_types_enum. */ @@ -3587,7 +4017,7 @@ write_enum_defn (type_p structures, type_p param_structs) nbstruct++; DBGPRINTF ("write_enum_defn s @ %p nbstruct %d", (void*) s, nbstruct); - if (UNION_OR_STRUCT_P (s)) + if (union_or_struct_p (s)) DBGPRINTF ("write_enum_defn s %p #%d is unionorstruct tagged %s", (void*) s, nbstruct, s->u.s.tag); oprintf (header_file, " gt_ggc_e_"); @@ -3873,6 +4303,11 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length, } break; + case TYPE_USER_STRUCT: + write_root (f, v, type->u.a.p, name, has_length, line, if_marked, + emit_pch); + break; + case TYPE_POINTER: { type_p tp; @@ -3882,13 +4317,16 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length, tp = type->u.p; - if (!has_length && UNION_OR_STRUCT_P (tp)) + if (!has_length && union_or_struct_p (tp)) { - oprintf (f, " >_ggc_mx_%s,\n", tp->u.s.tag); + const char *id_for_tag = filter_type_name (tp->u.s.tag); + oprintf (f, " >_ggc_mx_%s,\n", id_for_tag); if (emit_pch) - oprintf (f, " >_pch_nx_%s", tp->u.s.tag); + oprintf (f, " >_pch_nx_%s", id_for_tag); else oprintf (f, " NULL"); + if (id_for_tag != tp->u.s.tag) + free (CONST_CAST(char *, id_for_tag)); } else if (!has_length && tp->kind == TYPE_PARAM_STRUCT) { @@ -3903,7 +4341,7 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length, oprintf (f, ",\n NULL"); } else if (has_length - && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp))) + && (tp->kind == TYPE_POINTER || union_or_struct_p (tp))) { oprintf (f, " >_ggc_ma_%s,\n", name); if (emit_pch) @@ -4146,7 +4584,8 @@ write_roots (pair_p variables, bool emit_pch) continue; if (v->type->kind != TYPE_POINTER || v->type->u.p->kind != TYPE_PARAM_STRUCT - || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0)) + || v->type->u.p->u.param_struct.stru != find_structure ("htab", + TYPE_STRUCT)) { error_at_line (&v->line, "if_marked option used but not hash table"); @@ -4249,96 +4688,6 @@ write_roots (pair_p variables, bool emit_pch) finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab", "gt_pch_scalar_rtab"); } -/* Record the definition of the vec_prefix structure, as defined in vec.h: - - struct vec_prefix GTY(()) { - unsigned num; - unsigned alloc; - }; */ -static type_p -vec_prefix_type (void) -{ - static type_p prefix_type = NULL; - if (prefix_type == NULL) - { - pair_p fields; - static struct fileloc pos = { NULL, 0 }; - type_p len_ty = create_scalar_type ("unsigned"); - pos.file = input_file_by_name (__FILE__); pos.line = __LINE__; - fields = create_field_at (0, len_ty, "alloc", 0, &pos); - fields = create_field_at (fields, len_ty, "num", 0, &pos); - prefix_type = new_structure ("vec_prefix", 0, &pos, fields, 0); - prefix_type->u.s.bitmap = -1; - } - return prefix_type; -} - -/* Record the definition of a generic VEC structure, as if we had expanded - the macros in vec.h: - - typedef struct VEC_<type>_base GTY(()) { - struct vec_prefix prefix; - <type> GTY((length ("%h.prefix.num"))) vec[1]; - } VEC_<type>_base - - where the GTY(()) tags are only present if is_scalar is _false_. */ - -void -note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos) -{ - pair_p fields; - type_p t; - options_p o; - const char *name = concat ("VEC_", type_name, "_base", (char *) 0); - - if (is_scalar) - { - t = create_scalar_type (type_name); - o = 0; - } - else - { - t = resolve_typedef (type_name, pos); - o = create_string_option (0, "length", "%h.prefix.num"); - } - /* We assemble the field list in reverse order. */ - fields = create_field_at (0, create_array (t, "1"), "vec", o, pos); - fields = create_field_at (fields, vec_prefix_type (), "prefix", 0, pos); - - do_typedef (name, new_structure (name, 0, pos, fields, 0), pos); -} - -/* Record the definition of an allocation-specific VEC structure, as if - we had expanded the macros in vec.h: - - typedef struct VEC_<type>_<astrat> { - VEC_<type>_base base; - } VEC_<type>_<astrat>; -*/ -void -note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos) -{ - const char *astratname = concat ("VEC_", type, "_", astrat, (char *) 0); - const char *basename = concat ("VEC_", type, "_base", (char *) 0); - - pair_p field = create_field_at (0, resolve_typedef (basename, pos), - "base", 0, pos); - - do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos); -} - -/* Returns the specifier keyword for a string or union type S, empty string - otherwise. */ - -static const char * -get_type_specifier (const type_p s) -{ - if (s->kind == TYPE_STRUCT || s->kind == TYPE_LANG_STRUCT) - return "struct "; - if (s->kind == TYPE_UNION) - return "union "; - return ""; -} /* TRUE if type S has the GTY variable_size annotation. */ @@ -4375,7 +4724,8 @@ write_typed_alloc_def (outf_p f, bool third_arg = ((zone == specific_zone) && (variable_size || (quantity == vector))); gcc_assert (f != NULL); - oprintf (f, "#define ggc_alloc_%s%s", allocator_type, type_name); + const char *type_name_as_id = filter_type_name (type_name); + oprintf (f, "#define ggc_alloc_%s%s", allocator_type, type_name_as_id); oprintf (f, "(%s%s%s%s%s) ", (variable_size ? "SIZE" : ""), (two_args ? ", " : ""), @@ -4392,6 +4742,8 @@ write_typed_alloc_def (outf_p f, if (quantity == vector) oprintf (f, ", n"); oprintf (f, " MEM_STAT_INFO)))\n"); + if (type_name_as_id != type_name) + free (CONST_CAST(char *, type_name_as_id)); } /* Writes a typed allocator definition into output F for a struct or @@ -4403,7 +4755,7 @@ write_typed_struct_alloc_def (outf_p f, enum alloc_quantity quantity, enum alloc_zone zone) { - gcc_assert (UNION_OR_STRUCT_P (s)); + gcc_assert (union_or_struct_p (s)); write_typed_alloc_def (f, variable_size_p (s), get_type_specifier (s), s->u.s.tag, allocator_type, quantity, zone); } @@ -4438,7 +4790,7 @@ write_typed_alloc_defns (outf_p f, { if (!USED_BY_TYPED_GC_P (s)) continue; - gcc_assert (UNION_OR_STRUCT_P (s)); + gcc_assert (union_or_struct_p (s)); /* In plugin mode onput output ggc_alloc macro definitions relevant to plugin input files. */ if (nb_plugin_files > 0 @@ -4502,6 +4854,7 @@ output_typename (outf_p of, const_type_p t) output_typename (of, t->u.p); break; case TYPE_STRUCT: + case TYPE_USER_STRUCT: case TYPE_UNION: case TYPE_LANG_STRUCT: oprintf (of, "%s", t->u.s.tag); @@ -4560,10 +4913,6 @@ write_splay_tree_allocators (const_type_p param_structs) } } -static void dump_pair (int indent, pair_p p); -static void dump_type (int indent, type_p p); -static void dump_type_list (int indent, type_p p); - #define INDENT 2 /* Dumps the value of typekind KIND. */ @@ -4583,6 +4932,9 @@ dump_typekind (int indent, enum typekind kind) case TYPE_STRUCT: printf ("TYPE_STRUCT"); break; + case TYPE_USER_STRUCT: + printf ("TYPE_USER_STRUCT"); + break; case TYPE_UNION: printf ("TYPE_UNION"); break; @@ -4678,8 +5030,7 @@ dump_type_u_s (int indent, type_p t) { pair_p fields; - gcc_assert (t->kind == TYPE_STRUCT || t->kind == TYPE_UNION - || t->kind == TYPE_LANG_STRUCT); + gcc_assert (union_or_struct_p (t)); printf ("%*cu.s.tag = %s\n", indent, ' ', t->u.s.tag); dump_fileloc (indent, t->u.s.line); printf ("%*cu.s.fields =\n", indent, ' '); @@ -4750,6 +5101,9 @@ dump_type (int indent, type_p t) { PTR *slot; + if (seen_types == NULL) + seen_types = htab_create (100, htab_hash_pointer, htab_eq_pointer, NULL); + printf ("%*cType at %p: ", indent, ' ', (void *) t); slot = htab_find_slot (seen_types, t, INSERT); if (*slot != NULL) @@ -4775,6 +5129,7 @@ dump_type (int indent, type_p t) case TYPE_STRUCT: case TYPE_UNION: case TYPE_LANG_STRUCT: + case TYPE_USER_STRUCT: dump_type_u_s (indent + INDENT, t); break; case TYPE_POINTER: @@ -4834,11 +5189,12 @@ dump_structures (const char *name, type_p structures) static void dump_everything (void) { - seen_types = htab_create (100, htab_hash_pointer, htab_eq_pointer, NULL); dump_pair_list ("typedefs", typedefs); dump_structures ("structures", structures); dump_structures ("param_structs", param_structs); dump_pair_list ("variables", variables); + + /* Allocated with the first call to dump_type. */ htab_delete (seen_types); } diff --git a/gcc/gengtype.h b/gcc/gengtype.h index 560f7f3..4a178ec 100644 --- a/gcc/gengtype.h +++ b/gcc/gengtype.h @@ -1,5 +1,5 @@ /* Process source files and output type information. - Copyright (C) 2002, 2003, 2004, 2007, 2008, 2010, 2011 + Copyright (C) 2002, 2003, 2004, 2007, 2008, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -143,11 +143,14 @@ enum typekind { TYPE_LANG_STRUCT, /* GCC front-end language specific structs. Various languages may have homonymous but different structs. */ - TYPE_PARAM_STRUCT /* Type for parametrized structs, e.g. hash_t + TYPE_PARAM_STRUCT, /* Type for parametrized structs, e.g. hash_t hash-tables, ... See (param_is, use_param, param1_is, param2_is,... use_param1, use_param_2,... use_params) GTY options. */ + TYPE_USER_STRUCT /* User defined type. Walkers and markers for + this type are assumed to be provided by the + user. */ }; /* Discriminating kind for options. */ @@ -319,19 +322,27 @@ extern struct type scalar_char; /* Test if a type is a union, either a plain one or a language specific one. */ -#define UNION_P(x) \ - ((x)->kind == TYPE_UNION || \ - ((x)->kind == TYPE_LANG_STRUCT \ - && (x)->u.s.lang_struct->kind == TYPE_UNION)) +#define UNION_P(x) \ + ((x)->kind == TYPE_UNION \ + || ((x)->kind == TYPE_LANG_STRUCT \ + && (x)->u.s.lang_struct->kind == TYPE_UNION)) /* Test if a type is a union or a structure, perhaps a language specific one. */ -#define UNION_OR_STRUCT_P(x) \ - ((x)->kind == TYPE_UNION \ - || (x)->kind == TYPE_STRUCT \ - || (x)->kind == TYPE_LANG_STRUCT) - +static inline bool +union_or_struct_p (enum typekind kind) +{ + return (kind == TYPE_UNION + || kind == TYPE_STRUCT + || kind == TYPE_LANG_STRUCT + || kind == TYPE_USER_STRUCT); +} +static inline bool +union_or_struct_p (const_type_p x) +{ + return union_or_struct_p (x->kind); +} /* Give the file location of a type, if any. */ static inline struct fileloc* @@ -339,7 +350,7 @@ type_fileloc (type_p t) { if (!t) return NULL; - if (UNION_OR_STRUCT_P(t)) + if (union_or_struct_p (t)) return &t->u.s.line; if (t->kind == TYPE_PARAM_STRUCT) return &t->u.param_struct.line; @@ -410,10 +421,10 @@ extern char *xasprintf (const char *, ...) ATTRIBUTE_PRINTF_1; extern void do_typedef (const char *s, type_p t, struct fileloc *pos); extern void do_scalar_typedef (const char *s, struct fileloc *pos); extern type_p resolve_typedef (const char *s, struct fileloc *pos); -extern type_p new_structure (const char *name, int isunion, +extern type_p new_structure (const char *name, enum typekind kind, struct fileloc *pos, pair_p fields, options_p o); -extern type_p find_structure (const char *s, int isunion); +extern type_p find_structure (const char *s, enum typekind kind); extern type_p create_scalar_type (const char *name); extern type_p create_pointer (type_p t); extern type_p create_array (type_p t, const char *len); @@ -424,10 +435,6 @@ extern pair_p nreverse_pairs (pair_p list); extern type_p adjust_field_type (type_p, options_p); extern void note_variable (const char *s, type_p t, options_p o, struct fileloc *pos); -extern void note_def_vec (const char *type_name, bool is_scalar, - struct fileloc *pos); -extern void note_def_vec_alloc (const char *type, const char *astrat, - struct fileloc *pos); /* Lexer and parser routines. */ extern int yylex (const char **yylval); @@ -453,12 +460,10 @@ enum STRUCT, ENUM, VEC_TOKEN, - DEFVEC_OP, - DEFVEC_I, - DEFVEC_ALLOC, ELLIPSIS, PTR_ALIAS, NESTED_PTR, + USER_GTY, PARAM_IS, NUM, SCALAR, diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index d3d186d..ca3f632 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -1441,6 +1441,26 @@ gt_ggc_m_S (const void *p) return; } + +/* User-callable entry points for marking string X. */ + +void +gt_ggc_mx (const char *& x) +{ + gt_ggc_m_S (x); +} + +void +gt_ggc_mx (unsigned char *& x) +{ + gt_ggc_m_S (x); +} + +void +gt_ggc_mx (unsigned char& x ATTRIBUTE_UNUSED) +{ +} + /* If P is not marked, marks it and return false. Otherwise return true. P must have been allocated by the GC allocator; it mustn't point to static objects, stack variables, or memory allocated with malloc. */ diff --git a/gcc/ggc-zone.c b/gcc/ggc-zone.c index baf8076..2cf7167 100644 --- a/gcc/ggc-zone.c +++ b/gcc/ggc-zone.c @@ -1508,6 +1508,26 @@ gt_ggc_m_S (const void *p) ggc_set_mark (p); } + +/* User-callable entry points for marking string X. */ + +void +gt_ggc_mx (const char *& x) +{ + gt_ggc_m_S (x); +} + +void +gt_ggc_mx (unsigned char *& x) +{ + gt_ggc_m_S (x); +} + +void +gt_ggc_mx (unsigned char& x ATTRIBUTE_UNUSED) +{ +} + /* If P is not marked, mark it and return false. Otherwise return true. P must have been allocated by the GC allocator; it mustn't point to static objects, stack variables, or memory allocated with malloc. */ @@ -32,9 +32,6 @@ extern const char empty_string[]; /* empty string */ /* Internal functions and data structures used by the GTY machinery, including the generated gt*.[hc] files. */ -/* The first parameter is a pointer to a pointer, the second a cookie. */ -typedef void (*gt_pointer_operator) (void *, void *); - #include "gtype-desc.h" /* One of these applies its third parameter (with cookie in the fourth diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index f17d8e77..7a51e8c 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -121,7 +121,7 @@ lower_function_body (void) if (gimple_seq_may_fallthru (lowered_body) && (VEC_empty (return_statements_t, data.return_statements) || gimple_return_retval (VEC_last (return_statements_t, - data.return_statements)->stmt) != NULL)) + data.return_statements).stmt) != NULL)) { x = gimple_build_return (NULL); gimple_set_location (x, cfun->function_end_locus); @@ -137,7 +137,7 @@ lower_function_body (void) /* Unfortunately, we can't use VEC_pop because it returns void for objects. */ - t = *VEC_last (return_statements_t, data.return_statements); + t = VEC_last (return_statements_t, data.return_statements); VEC_truncate (return_statements_t, data.return_statements, VEC_length (return_statements_t, @@ -835,7 +835,7 @@ lower_gimple_return (gimple_stmt_iterator *gsi, struct lower_data *data) for (i = VEC_length (return_statements_t, data->return_statements) - 1; i >= 0; i--) { - tmp_rs = *VEC_index (return_statements_t, data->return_statements, i); + tmp_rs = VEC_index (return_statements_t, data->return_statements, i); if (gimple_return_retval (stmt) == gimple_return_retval (tmp_rs.stmt)) { diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 9b66a22..ed2474f 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2116,7 +2116,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, fallback_t fallback) { tree *p; - VEC(tree,heap) *stack; + VEC(tree,heap) *expr_stack; enum gimplify_status ret = GS_ALL_DONE, tret; int i; location_t loc = EXPR_LOCATION (*expr_p); @@ -2124,7 +2124,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* Create a stack of the subexpressions so later we can walk them in order from inner to outer. */ - stack = VEC_alloc (tree, heap, 10); + expr_stack = VEC_alloc (tree, heap, 10); /* We can handle anything that get_inner_reference can deal with. */ for (p = expr_p; ; p = &TREE_OPERAND (*p, 0)) @@ -2144,13 +2144,13 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, else break; - VEC_safe_push (tree, heap, stack, *p); + VEC_safe_push (tree, heap, expr_stack, *p); } - gcc_assert (VEC_length (tree, stack)); + gcc_assert (VEC_length (tree, expr_stack)); - /* Now STACK is a stack of pointers to all the refs we've walked through - and P points to the innermost expression. + /* Now EXPR_STACK is a stack of pointers to all the refs we've + walked through and P points to the innermost expression. Java requires that we elaborated nodes in source order. That means we must gimplify the inner expression followed by each of @@ -2161,9 +2161,9 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, So we do this in three steps. First we deal with the annotations for any variables in the components, then we gimplify the base, then we gimplify any indices, from left to right. */ - for (i = VEC_length (tree, stack) - 1; i >= 0; i--) + for (i = VEC_length (tree, expr_stack) - 1; i >= 0; i--) { - tree t = VEC_index (tree, stack, i); + tree t = VEC_index (tree, expr_stack, i); if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) { @@ -2256,9 +2256,9 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* And finally, the indices and operands of ARRAY_REF. During this loop we also remove any useless conversions. */ - for (; VEC_length (tree, stack) > 0; ) + for (; VEC_length (tree, expr_stack) > 0; ) { - tree t = VEC_pop (tree, stack); + tree t = VEC_pop (tree, expr_stack); if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) { @@ -2286,7 +2286,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, canonicalize_component_ref (expr_p); } - VEC_free (tree, heap, stack); + VEC_free (tree, heap, expr_stack); gcc_assert (*expr_p == expr || ret != GS_ALL_DONE); @@ -3845,7 +3845,7 @@ optimize_compound_literals_in_ctor (tree orig_ctor) for (idx = 0; idx < num; idx++) { - tree value = VEC_index (constructor_elt, elts, idx)->value; + tree value = VEC_index (constructor_elt, elts, idx).value; tree newval = value; if (TREE_CODE (value) == CONSTRUCTOR) newval = optimize_compound_literals_in_ctor (value); @@ -3869,7 +3869,7 @@ optimize_compound_literals_in_ctor (tree orig_ctor) CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts); elts = CONSTRUCTOR_ELTS (ctor); } - VEC_index (constructor_elt, elts, idx)->value = newval; + VEC_index (constructor_elt, elts, idx).value = newval; } return ctor; } @@ -4120,8 +4120,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* Extract the real and imaginary parts out of the ctor. */ gcc_assert (VEC_length (constructor_elt, elts) == 2); - r = VEC_index (constructor_elt, elts, 0)->value; - i = VEC_index (constructor_elt, elts, 1)->value; + r = VEC_index (constructor_elt, elts, 0).value; + i = VEC_index (constructor_elt, elts, 1).value; if (r == NULL || i == NULL) { tree zero = build_zero_cst (TREE_TYPE (type)); diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index f2c8a56..d3a6e29 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,11 @@ +2012-08-14 Diego Novillo <dnovillo@google.com> + + Merge from cxx-conversion branch. Configury. + + * go-c.h: Remove all handlers of ENABLE_BUILD_WITH_CXX. + * go-gcc.cc: Likewise. + * go-system.h: Likewise. + 2012-07-24 Uros Bizjak <ubizjak@gmail.com> * go-lang.c (lang_decl): Add variable_size GTY option. diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h index d46a087..a7f7b1f 100644 --- a/gcc/go/go-c.h +++ b/gcc/go/go-c.h @@ -20,16 +20,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GO_GO_C_H #define GO_GO_C_H -#ifdef ENABLE_BUILD_WITH_CXX #define GO_EXTERN_C -#else -#define GO_EXTERN_C extern "C" -#endif - -#if defined(__cplusplus) && !defined(ENABLE_BUILD_WITH_CXX) -extern "C" -{ -#endif #include "machmode.h" @@ -71,8 +62,4 @@ extern const char *go_read_export_data (int, off_t, char **, size_t *, int *); extern GTY(()) tree go_non_zero_struct; -#if defined(__cplusplus) && !defined(ENABLE_BUILD_WITH_CXX) -} /* End extern "C". */ -#endif - #endif /* !defined(GO_GO_C_H) */ diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 4729a3b..84bc972 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -24,20 +24,11 @@ // include it here before tree.h includes it later. #include <gmp.h> -#ifndef ENABLE_BUILD_WITH_CXX -extern "C" -{ -#endif - #include "tree.h" #include "tree-iterator.h" #include "gimple.h" #include "toplev.h" -#ifndef ENABLE_BUILD_WITH_CXX -} -#endif - #include "go-c.h" #include "gogo.h" diff --git a/gcc/go/go-system.h b/gcc/go/go-system.h index 08aac6a..2decc55 100644 --- a/gcc/go/go-system.h +++ b/gcc/go/go-system.h @@ -134,11 +134,6 @@ struct hash<T*> // later. #include <cstdio> -#ifndef ENABLE_BUILD_WITH_CXX -extern "C" -{ -#endif - #include "system.h" #include "ansidecl.h" #include "coretypes.h" @@ -147,10 +142,6 @@ extern "C" #include "input.h" /* For source_location. */ #include "intl.h" /* For _(). */ -#ifndef ENABLE_BUILD_WITH_CXX -} // End extern "C" -#endif - // When using gcc, go_assert is just gcc_assert. #define go_assert(EXPR) gcc_assert(EXPR) diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 67412a0..f53be25 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -1249,7 +1249,7 @@ build_sese_conditions_before (struct dom_walk_data *dw_data, if (e->flags & EDGE_TRUE_VALUE) VEC_safe_push (gimple, heap, *cases, stmt); else - VEC_safe_push (gimple, heap, *cases, NULL); + VEC_safe_push (gimple, heap, *cases, (gimple) NULL); } gbb = gbb_from_bb (bb); diff --git a/gcc/hash-table.c b/gcc/hash-table.c new file mode 100644 index 0000000..7909a98 --- /dev/null +++ b/gcc/hash-table.c @@ -0,0 +1,190 @@ +/* A type-safe hash table template. + Copyright (C) 2012 + Free Software Foundation, Inc. + Contributed by Lawrence Crowl <crowl@google.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + + +/* This file implements a typed hash table. + The implementation borrows from libiberty's hashtab. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "hash-table.h" + + +/* Table of primes and multiplicative inverses. + + Note that these are not minimally reduced inverses. Unlike when generating + code to divide by a constant, we want to be able to use the same algorithm + all the time. All of these inverses (are implied to) have bit 32 set. + + For the record, here's the function that computed the table; it's a + vastly simplified version of the function of the same name from gcc. */ + +#if 0 +unsigned int +ceil_log2 (unsigned int x) +{ + int i; + for (i = 31; i >= 0 ; --i) + if (x > (1u << i)) + return i+1; + abort (); +} + +unsigned int +choose_multiplier (unsigned int d, unsigned int *mlp, unsigned char *shiftp) +{ + unsigned long long mhigh; + double nx; + int lgup, post_shift; + int pow, pow2; + int n = 32, precision = 32; + + lgup = ceil_log2 (d); + pow = n + lgup; + pow2 = n + lgup - precision; + + nx = ldexp (1.0, pow) + ldexp (1.0, pow2); + mhigh = nx / d; + + *shiftp = lgup - 1; + *mlp = mhigh; + return mhigh >> 32; +} +#endif + +struct prime_ent const prime_tab[] = { + { 7, 0x24924925, 0x9999999b, 2 }, + { 13, 0x3b13b13c, 0x745d1747, 3 }, + { 31, 0x08421085, 0x1a7b9612, 4 }, + { 61, 0x0c9714fc, 0x15b1e5f8, 5 }, + { 127, 0x02040811, 0x0624dd30, 6 }, + { 251, 0x05197f7e, 0x073260a5, 7 }, + { 509, 0x01824366, 0x02864fc8, 8 }, + { 1021, 0x00c0906d, 0x014191f7, 9 }, + { 2039, 0x0121456f, 0x0161e69e, 10 }, + { 4093, 0x00300902, 0x00501908, 11 }, + { 8191, 0x00080041, 0x00180241, 12 }, + { 16381, 0x000c0091, 0x00140191, 13 }, + { 32749, 0x002605a5, 0x002a06e6, 14 }, + { 65521, 0x000f00e2, 0x00110122, 15 }, + { 131071, 0x00008001, 0x00018003, 16 }, + { 262139, 0x00014002, 0x0001c004, 17 }, + { 524287, 0x00002001, 0x00006001, 18 }, + { 1048573, 0x00003001, 0x00005001, 19 }, + { 2097143, 0x00004801, 0x00005801, 20 }, + { 4194301, 0x00000c01, 0x00001401, 21 }, + { 8388593, 0x00001e01, 0x00002201, 22 }, + { 16777213, 0x00000301, 0x00000501, 23 }, + { 33554393, 0x00001381, 0x00001481, 24 }, + { 67108859, 0x00000141, 0x000001c1, 25 }, + { 134217689, 0x000004e1, 0x00000521, 26 }, + { 268435399, 0x00000391, 0x000003b1, 27 }, + { 536870909, 0x00000019, 0x00000029, 28 }, + { 1073741789, 0x0000008d, 0x00000095, 29 }, + { 2147483647, 0x00000003, 0x00000007, 30 }, + /* Avoid "decimal constant so large it is unsigned" for 4294967291. */ + { 0xfffffffb, 0x00000006, 0x00000008, 31 } +}; + +/* The following function returns an index into the above table of the + nearest prime number which is greater than N, and near a power of two. */ + +unsigned int +hash_table_higher_prime_index (unsigned long n) +{ + unsigned int low = 0; + unsigned int high = sizeof(prime_tab) / sizeof(prime_tab[0]); + + while (low != high) + { + unsigned int mid = low + (high - low) / 2; + if (n > prime_tab[mid].prime) + low = mid + 1; + else + high = mid; + } + + /* If we've run out of primes, abort. */ + if (n > prime_tab[low].prime) + { + fprintf (stderr, "Cannot find prime bigger than %lu\n", n); + abort (); + } + + return low; +} + +/* Return X % Y using multiplicative inverse values INV and SHIFT. + + The multiplicative inverses computed above are for 32-bit types, + and requires that we be able to compute a highpart multiply. + + FIX: I am not at all convinced that + 3 loads, 2 multiplications, 3 shifts, and 3 additions + will be faster than + 1 load and 1 modulus + on modern systems running a compiler. */ + +#ifdef UNSIGNED_64BIT_TYPE +static inline hashval_t +mul_mod (hashval_t x, hashval_t y, hashval_t inv, int shift) +{ + __extension__ typedef UNSIGNED_64BIT_TYPE ull; + hashval_t t1, t2, t3, t4, q, r; + + t1 = ((ull)x * inv) >> 32; + t2 = x - t1; + t3 = t2 >> 1; + t4 = t1 + t3; + q = t4 >> shift; + r = x - (q * y); + + return r; +} +#endif + +/* Compute the primary table index for HASH given current prime index. */ + +hashval_t +hash_table_mod1 (hashval_t hash, unsigned int index) +{ + const struct prime_ent *p = &prime_tab[index]; +#ifdef UNSIGNED_64BIT_TYPE + if (sizeof (hashval_t) * CHAR_BIT <= 32) + return mul_mod (hash, p->prime, p->inv, p->shift); +#endif + return hash % p->prime; +} + + +/* Compute the secondary table index for HASH given current prime index. */ + +hashval_t +hash_table_mod2 (hashval_t hash, unsigned int index) +{ + const struct prime_ent *p = &prime_tab[index]; +#ifdef UNSIGNED_64BIT_TYPE + if (sizeof (hashval_t) * CHAR_BIT <= 32) + return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift); +#endif + return 1 + hash % (p->prime - 2); +} diff --git a/gcc/hash-table.h b/gcc/hash-table.h new file mode 100644 index 0000000..2c483e2 --- /dev/null +++ b/gcc/hash-table.h @@ -0,0 +1,783 @@ +/* A type-safe hash table template. + Copyright (C) 2012 + Free Software Foundation, Inc. + Contributed by Lawrence Crowl <crowl@google.com> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + + +/* This file implements a typed hash table. + The implementation borrows from libiberty's hashtab. */ + + +#ifndef TYPED_HASHTAB_H +#define TYPED_HASHTAB_H + +#include "hashtab.h" + + +/* The ordinary memory allocator. */ +/* FIXME (crowl): This allocator may be extracted for wider sharing later. */ + +template <typename Type> +struct xcallocator +{ + static Type *control_alloc (size_t count); + static Type *data_alloc (size_t count); + static void control_free (Type *memory); + static void data_free (Type *memory); +}; + + +/* Allocate memory for COUNT control blocks. */ + +template <typename Type> +inline Type * +xcallocator <Type>::control_alloc (size_t count) +{ + return static_cast <Type *> (xcalloc (count, sizeof (Type))); +} + + +/* Allocate memory for COUNT data blocks. */ + +template <typename Type> +inline Type * +xcallocator <Type>::data_alloc (size_t count) +{ + return static_cast <Type *> (xcalloc (count, sizeof (Type))); +} + + +/* Free memory for control blocks. */ + +template <typename Type> +inline void +xcallocator <Type>::control_free (Type *memory) +{ + return ::free (memory); +} + + +/* Free memory for data blocks. */ + +template <typename Type> +inline void +xcallocator <Type>::data_free (Type *memory) +{ + return ::free (memory); +} + + +/* A common function for hashing a CANDIDATE typed pointer. */ + +template <typename Element> +inline hashval_t +typed_pointer_hash (const Element *candidate) +{ + /* This is a really poor hash function, but it is what the current code uses, + so I am reusing it to avoid an additional axis in testing. */ + return (hashval_t) ((intptr_t)candidate >> 3); +} + + +/* A common function for comparing an EXISTING and CANDIDATE typed pointers + for equality. */ + +template <typename Element> +inline int +typed_pointer_equal (const Element *existing, const Element * candidate) +{ + return existing == candidate; +} + + +/* A common function for doing nothing on removing a RETIRED slot. */ + +template <typename Element> +inline void +typed_null_remove (Element *retired ATTRIBUTE_UNUSED) +{ +} + + +/* A common function for using free on removing a RETIRED slot. */ + +template <typename Element> +inline void +typed_free_remove (Element *retired) +{ + free (retired); +} + + +/* Table of primes and their inversion information. */ + +struct prime_ent +{ + hashval_t prime; + hashval_t inv; + hashval_t inv_m2; /* inverse of prime-2 */ + hashval_t shift; +}; + +extern struct prime_ent const prime_tab[]; + + +/* Functions for computing hash table indexes. */ + +extern unsigned int hash_table_higher_prime_index (unsigned long n); +extern hashval_t hash_table_mod1 (hashval_t hash, unsigned int index); +extern hashval_t hash_table_mod2 (hashval_t hash, unsigned int index); + + +/* Internal implementation type. */ + +template <typename Element> +struct hash_table_control +{ + /* Table itself. */ + Element **entries; + + /* Current size (in entries) of the hash table. */ + size_t size; + + /* Current number of elements including also deleted elements. */ + size_t n_elements; + + /* Current number of deleted elements in the table. */ + size_t n_deleted; + + /* The following member is used for debugging. Its value is number + of all calls of `htab_find_slot' for the hash table. */ + unsigned int searches; + + /* The following member is used for debugging. Its value is number + of collisions fixed for time of work with the hash table. */ + unsigned int collisions; + + /* Current size (in entries) of the hash table, as an index into the + table of primes. */ + unsigned int size_prime_index; +}; + + +/* User-facing hash table type. + + The table stores elements of type Element. + + It hashes elements with the Hash function. + The table currently works with relatively weak hash functions. + Use typed_pointer_hash <Element> when hashing pointers instead of objects. + + It compares elements with the Equal function. + Two elements with the same hash may not be equal. + Use typed_pointer_equal <Element> when hashing pointers instead of objects. + + It removes elements with the Remove function. + This feature is useful for freeing memory. + Use typed_null_remove <Element> when not freeing objects. + Use typed_free_remove <Element> when doing a simple object free. + + Use the Allocator template to allocate and free memory. + The default is xcallocator. + +*/ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator = xcallocator> +class hash_table +{ + +private: + + hash_table_control <Element> *htab; + + Element **find_empty_slot_for_expand (hashval_t hash); + void expand (); + +public: + + hash_table (); + void create (size_t initial_slots); + bool is_created (); + void dispose (); + Element *find (Element *comparable); + Element *find_with_hash (Element *comparable, hashval_t hash); + Element **find_slot (Element *comparable, enum insert_option insert); + Element **find_slot_with_hash (Element *comparable, hashval_t hash, + enum insert_option insert); + void empty (); + void clear_slot (Element **slot); + void remove_elt (Element *comparable); + void remove_elt_with_hash (Element *comparable, hashval_t hash); + size_t size(); + size_t elements(); + double collisions(); + + template <typename Argument, + int (*Callback) (Element **slot, Argument argument)> + void traverse_noresize (Argument argument); + + template <typename Argument, + int (*Callback) (Element **slot, Argument argument)> + void traverse (Argument argument); +}; + + +/* Construct the hash table. The only useful operation next is create. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline +hash_table <Element, Hash, Equal, Remove, Allocator>::hash_table () +: htab (NULL) +{ +} + + +/* See if the table has been created, as opposed to constructed. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline bool +hash_table <Element, Hash, Equal, Remove, Allocator>::is_created () +{ + return htab != NULL; +} + + +/* Like find_with_hash, but compute the hash value from the element. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline Element * +hash_table <Element, Hash, Equal, Remove, Allocator>::find (Element *comparable) +{ + return find_with_hash (comparable, Hash (comparable)); +} + + +/* Like find_slot_with_hash, but compute the hash value from the element. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline Element ** +hash_table <Element, Hash, Equal, Remove, Allocator> +::find_slot (Element *comparable, enum insert_option insert) +{ + return find_slot_with_hash (comparable, Hash (comparable), insert); +} + + +/* Like remove_elt_with_hash, but compute the hash value from the element. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline void +hash_table <Element, Hash, Equal, Remove, Allocator> +::remove_elt (Element *comparable) +{ + remove_elt_with_hash (comparable, Hash (comparable)); +} + + +/* Return the current size of this hash table. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline size_t +hash_table <Element, Hash, Equal, Remove, Allocator>::size() +{ + return htab->size; +} + + +/* Return the current number of elements in this hash table. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline size_t +hash_table <Element, Hash, Equal, Remove, Allocator>::elements() +{ + return htab->n_elements - htab->n_deleted; +} + + + /* Return the fraction of fixed collisions during all work with given + hash table. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +inline double +hash_table <Element, Hash, Equal, Remove, Allocator>::collisions() +{ + if (htab->searches == 0) + return 0.0; + + return static_cast <double> (htab->collisions) / htab->searches; +} + + +/* Create a hash table with at least the given number of INITIAL_SLOTS. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +void +hash_table <Element, Hash, Equal, Remove, Allocator>::create (size_t size) +{ + unsigned int size_prime_index; + + size_prime_index = hash_table_higher_prime_index (size); + size = prime_tab[size_prime_index].prime; + + htab = Allocator <hash_table_control <Element> > ::control_alloc (1); + gcc_assert (htab != NULL); + htab->entries = Allocator <Element*> ::data_alloc (size); + gcc_assert (htab->entries != NULL); + htab->size = size; + htab->size_prime_index = size_prime_index; +} + + +/* Dispose of a hash table. Free all memory and return this hash table to + the non-created state. Naturally the hash table must already exist. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +void +hash_table <Element, Hash, Equal, Remove, Allocator>::dispose () +{ + size_t size = htab->size; + Element **entries = htab->entries; + + for (int i = size - 1; i >= 0; i--) + if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY) + Remove (entries[i]); + + Allocator <Element *> ::data_free (entries); + Allocator <hash_table_control <Element> > ::control_free (htab); + htab = NULL; +} + + +/* Similar to find_slot, but without several unwanted side effects: + - Does not call Equal when it finds an existing entry. + - Does not change the count of elements/searches/collisions in the + hash table. + This function also assumes there are no deleted entries in the table. + HASH is the hash value for the element to be inserted. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +Element ** +hash_table <Element, Hash, Equal, Remove, Allocator> +::find_empty_slot_for_expand (hashval_t hash) +{ + hashval_t index = hash_table_mod1 (hash, htab->size_prime_index); + size_t size = htab->size; + Element **slot = htab->entries + index; + hashval_t hash2; + + if (*slot == HTAB_EMPTY_ENTRY) + return slot; + else if (*slot == HTAB_DELETED_ENTRY) + abort (); + + hash2 = hash_table_mod2 (hash, htab->size_prime_index); + for (;;) + { + index += hash2; + if (index >= size) + index -= size; + + slot = htab->entries + index; + if (*slot == HTAB_EMPTY_ENTRY) + return slot; + else if (*slot == HTAB_DELETED_ENTRY) + abort (); + } +} + + +/* The following function changes size of memory allocated for the + entries and repeatedly inserts the table elements. The occupancy + of the table after the call will be about 50%. Naturally the hash + table must already exist. Remember also that the place of the + table entries is changed. If memory allocation fails, this function + will abort. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +void +hash_table <Element, Hash, Equal, Remove, Allocator>::expand () +{ + Element **oentries; + Element **olimit; + Element **p; + Element **nentries; + size_t nsize, osize, elts; + unsigned int oindex, nindex; + + oentries = htab->entries; + oindex = htab->size_prime_index; + osize = htab->size; + olimit = oentries + osize; + elts = elements (); + + /* Resize only when table after removal of unused elements is either + too full or too empty. */ + if (elts * 2 > osize || (elts * 8 < osize && osize > 32)) + { + nindex = hash_table_higher_prime_index (elts * 2); + nsize = prime_tab[nindex].prime; + } + else + { + nindex = oindex; + nsize = osize; + } + + nentries = Allocator <Element *> ::data_alloc (nsize); + gcc_assert (nentries != NULL); + htab->entries = nentries; + htab->size = nsize; + htab->size_prime_index = nindex; + htab->n_elements -= htab->n_deleted; + htab->n_deleted = 0; + + p = oentries; + do + { + Element *x = *p; + + if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) + { + Element **q = find_empty_slot_for_expand (Hash (x)); + + *q = x; + } + + p++; + } + while (p < olimit); + + Allocator <Element *> ::data_free (oentries); +} + + +/* This function searches for a hash table entry equal to the given + COMPARABLE element starting with the given HASH value. It cannot + be used to insert or delete an element. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +Element * +hash_table <Element, Hash, Equal, Remove, Allocator> +::find_with_hash (Element *comparable, hashval_t hash) +{ + hashval_t index, hash2; + size_t size; + Element *entry; + + htab->searches++; + size = htab->size; + index = hash_table_mod1 (hash, htab->size_prime_index); + + entry = htab->entries[index]; + if (entry == HTAB_EMPTY_ENTRY + || (entry != HTAB_DELETED_ENTRY && Equal (entry, comparable))) + return entry; + + hash2 = hash_table_mod2 (hash, htab->size_prime_index); + for (;;) + { + htab->collisions++; + index += hash2; + if (index >= size) + index -= size; + + entry = htab->entries[index]; + if (entry == HTAB_EMPTY_ENTRY + || (entry != HTAB_DELETED_ENTRY && Equal (entry, comparable))) + return entry; + } +} + + +/* This function searches for a hash table slot containing an entry + equal to the given COMPARABLE element and starting with the given + HASH. To delete an entry, call this with insert=NO_INSERT, then + call clear_slot on the slot returned (possibly after doing some + checks). To insert an entry, call this with insert=INSERT, then + write the value you want into the returned slot. When inserting an + entry, NULL may be returned if memory allocation fails. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +Element ** +hash_table <Element, Hash, Equal, Remove, Allocator> +::find_slot_with_hash (Element *comparable, hashval_t hash, + enum insert_option insert) +{ + Element **first_deleted_slot; + hashval_t index, hash2; + size_t size; + Element *entry; + + size = htab->size; + if (insert == INSERT && size * 3 <= htab->n_elements * 4) + { + expand (); + size = htab->size; + } + + index = hash_table_mod1 (hash, htab->size_prime_index); + + htab->searches++; + first_deleted_slot = NULL; + + entry = htab->entries[index]; + if (entry == HTAB_EMPTY_ENTRY) + goto empty_entry; + else if (entry == HTAB_DELETED_ENTRY) + first_deleted_slot = &htab->entries[index]; + else if (Equal (entry, comparable)) + return &htab->entries[index]; + + hash2 = hash_table_mod2 (hash, htab->size_prime_index); + for (;;) + { + htab->collisions++; + index += hash2; + if (index >= size) + index -= size; + + entry = htab->entries[index]; + if (entry == HTAB_EMPTY_ENTRY) + goto empty_entry; + else if (entry == HTAB_DELETED_ENTRY) + { + if (!first_deleted_slot) + first_deleted_slot = &htab->entries[index]; + } + else if (Equal (entry, comparable)) + return &htab->entries[index]; + } + + empty_entry: + if (insert == NO_INSERT) + return NULL; + + if (first_deleted_slot) + { + htab->n_deleted--; + *first_deleted_slot = static_cast <Element *> (HTAB_EMPTY_ENTRY); + return first_deleted_slot; + } + + htab->n_elements++; + return &htab->entries[index]; +} + + +/* This function clears all entries in the given hash table. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +void +hash_table <Element, Hash, Equal, Remove, Allocator>::empty () +{ + size_t size = htab_size (htab); + Element **entries = htab->entries; + int i; + + for (i = size - 1; i >= 0; i--) + if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY) + Remove (entries[i]); + + /* Instead of clearing megabyte, downsize the table. */ + if (size > 1024*1024 / sizeof (PTR)) + { + int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR)); + int nsize = prime_tab[nindex].prime; + + Allocator <Element *> ::data_free (htab->entries); + htab->entries = Allocator <Element *> ::data_alloc (nsize); + htab->size = nsize; + htab->size_prime_index = nindex; + } + else + memset (entries, 0, size * sizeof (Element *)); + htab->n_deleted = 0; + htab->n_elements = 0; +} + + +/* This function clears a specified SLOT in a hash table. It is + useful when you've already done the lookup and don't want to do it + again. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +void +hash_table <Element, Hash, Equal, Remove, Allocator> +::clear_slot (Element **slot) +{ + if (slot < htab->entries || slot >= htab->entries + htab->size + || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY) + abort (); + + Remove (*slot); + + *slot = HTAB_DELETED_ENTRY; + htab->n_deleted++; +} + + +/* This function deletes an element with the given COMPARABLE value + from hash table starting with the given HASH. If there is no + matching element in the hash table, this function does nothing. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +void +hash_table <Element, Hash, Equal, Remove, Allocator> +::remove_elt_with_hash (Element *comparable, hashval_t hash) +{ + Element **slot; + + slot = find_slot_with_hash (comparable, hash, NO_INSERT); + if (*slot == HTAB_EMPTY_ENTRY) + return; + + Remove (*slot); + + *slot = static_cast <Element *> (HTAB_DELETED_ENTRY); + htab->n_deleted++; +} + + +/* This function scans over the entire hash table calling CALLBACK for + each live entry. If CALLBACK returns false, the iteration stops. + ARGUMENT is passed as CALLBACK's second argument. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +template <typename Argument, + int (*Callback) (Element **slot, Argument argument)> +void +hash_table <Element, Hash, Equal, Remove, Allocator> +::traverse_noresize (Argument argument) +{ + Element **slot; + Element **limit; + + slot = htab->entries; + limit = slot + htab->size; + + do + { + Element *x = *slot; + + if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) + if (! Callback (slot, argument)) + break; + } + while (++slot < limit); +} + + +/* Like traverse_noresize, but does resize the table when it is too empty + to improve effectivity of subsequent calls. */ + +template <typename Element, + hashval_t (*Hash) (const Element *candidate), + int (*Equal) (const Element *existing, const Element * candidate), + void (*Remove) (Element *retired), + template <typename Type> class Allocator> +template <typename Argument, + int (*Callback) (Element **slot, Argument argument)> +void +hash_table <Element, Hash, Equal, Remove, Allocator> +::traverse (Argument argument) +{ + size_t size = htab->size; + if (elements () * 8 < size && size > 32) + expand (); + + traverse_noresize <Argument, Callback> (argument); +} + +#endif /* TYPED_HASHTAB_H */ diff --git a/gcc/hw-doloop.c b/gcc/hw-doloop.c index 925039f..cd9b3f2 100644 --- a/gcc/hw-doloop.c +++ b/gcc/hw-doloop.c @@ -345,12 +345,12 @@ discover_loop (hwloop_info loop, basic_block tail_bb, rtx tail_insn, rtx reg) } /* Analyze the structure of the loops in the current function. Use - STACK for bitmap allocations. Returns all the valid candidates for + LOOP_STACK for bitmap allocations. Returns all the valid candidates for hardware loops found in this function. HOOKS is the argument passed to reorg_loops, used here to find the iteration registers from a loop_end pattern. */ static hwloop_info -discover_loops (bitmap_obstack *stack, struct hw_doloop_hooks *hooks) +discover_loops (bitmap_obstack *loop_stack, struct hw_doloop_hooks *hooks) { hwloop_info loops = NULL; hwloop_info loop; @@ -406,7 +406,7 @@ discover_loops (bitmap_obstack *stack, struct hw_doloop_hooks *hooks) loops = loop; loop->loop_no = nloops++; loop->blocks = VEC_alloc (basic_block, heap, 20); - loop->block_bitmap = BITMAP_ALLOC (stack); + loop->block_bitmap = BITMAP_ALLOC (loop_stack); if (dump_file) { @@ -626,18 +626,18 @@ reorg_loops (bool do_reorder, struct hw_doloop_hooks *hooks) { hwloop_info loops = NULL; hwloop_info loop; - bitmap_obstack stack; + bitmap_obstack loop_stack; df_live_add_problem (); df_live_set_all_dirty (); df_analyze (); - bitmap_obstack_initialize (&stack); + bitmap_obstack_initialize (&loop_stack); if (dump_file) fprintf (dump_file, ";; Find loops, first pass\n\n"); - loops = discover_loops (&stack, hooks); + loops = discover_loops (&loop_stack, hooks); if (do_reorder) { @@ -647,7 +647,7 @@ reorg_loops (bool do_reorder, struct hw_doloop_hooks *hooks) if (dump_file) fprintf (dump_file, ";; Find loops, second pass\n\n"); - loops = discover_loops (&stack, hooks); + loops = discover_loops (&loop_stack, hooks); } for (loop = loops; loop; loop = loop->next) diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index bf4d42a..453d685 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -331,9 +331,9 @@ add_clause (conditions conditions, struct predicate *p, clause_t clause) condition *cc1; if (!(clause & (1 << c1))) continue; - cc1 = VEC_index (condition, - conditions, - c1 - predicate_first_dynamic_condition); + cc1 = &VEC_index (condition, + conditions, + c1 - predicate_first_dynamic_condition); /* We have no way to represent !CHANGED and !IS_NOT_CONSTANT and thus there is no point for looking for them. */ if (cc1->code == CHANGED @@ -342,12 +342,12 @@ add_clause (conditions conditions, struct predicate *p, clause_t clause) for (c2 = c1 + 1; c2 <= NUM_CONDITIONS; c2++) if (clause & (1 << c2)) { - condition *cc1 = VEC_index (condition, - conditions, - c1 - predicate_first_dynamic_condition); - condition *cc2 = VEC_index (condition, - conditions, - c2 - predicate_first_dynamic_condition); + condition *cc1 = &VEC_index (condition, + conditions, + c1 - predicate_first_dynamic_condition); + condition *cc2 = &VEC_index (condition, + conditions, + c2 - predicate_first_dynamic_condition); if (cc1->operand_num == cc2->operand_num && cc1->val == cc2->val && cc2->code != IS_NOT_CONSTANT @@ -512,7 +512,7 @@ predicate_probability (conditions conds, { if (i2 >= predicate_first_dynamic_condition) { - condition *c = VEC_index + condition *c = &VEC_index (condition, conds, i2 - predicate_first_dynamic_condition); if (c->code == CHANGED @@ -522,7 +522,7 @@ predicate_probability (conditions conds, { int iprob = VEC_index (inline_param_summary_t, inline_param_summary, - c->operand_num)->change_prob; + c->operand_num).change_prob; this_prob = MAX (this_prob, iprob); } else @@ -552,8 +552,8 @@ dump_condition (FILE *f, conditions conditions, int cond) fprintf (f, "not inlined"); else { - c = VEC_index (condition, conditions, - cond - predicate_first_dynamic_condition); + c = &VEC_index (condition, conditions, + cond - predicate_first_dynamic_condition); fprintf (f, "op%i", c->operand_num); if (c->agg_contents) fprintf (f, "[%soffset: " HOST_WIDE_INT_PRINT_DEC "]", @@ -648,7 +648,7 @@ account_size_time (struct inline_summary *summary, int size, int time, { i = 0; found = true; - e = VEC_index (size_time_entry, summary->entry, 0); + e = &VEC_index (size_time_entry, summary->entry, 0); gcc_assert (!e->predicate.clause[0]); } if (dump_file && (dump_flags & TDF_DETAILS) && (time || size)) @@ -834,7 +834,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, else if (inline_p && !VEC_index (inline_param_summary_t, es->param, - i)->change_prob) + i).change_prob) VEC_replace (tree, known_vals, i, error_mark_node); /* TODO: When IPA-CP starts propagating and merging aggregate jump functions, use its knowledge of the caller too, just like the @@ -1218,7 +1218,7 @@ dump_inline_edge_summary (FILE * f, int indent, struct cgraph_node *node, i++) { int prob = VEC_index (inline_param_summary_t, - es->param, i)->change_prob; + es->param, i).change_prob; if (!prob) fprintf (f, "%*s op%i is compile time invariant\n", @@ -1822,8 +1822,8 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, return p; /* If we know when operand is constant, we still can say something useful. */ - if (!true_predicate_p (VEC_index (predicate_t, nonconstant_names, - SSA_NAME_VERSION (use)))) + if (!true_predicate_p (&VEC_index (predicate_t, nonconstant_names, + SSA_NAME_VERSION (use)))) continue; return p; } @@ -1846,14 +1846,14 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, continue; } else - p = *VEC_index (predicate_t, nonconstant_names, - SSA_NAME_VERSION (use)); + p = VEC_index (predicate_t, nonconstant_names, + SSA_NAME_VERSION (use)); op_non_const = or_predicates (summary->conds, &p, &op_non_const); } if (gimple_code (stmt) == GIMPLE_ASSIGN && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME) VEC_replace (predicate_t, nonconstant_names, - SSA_NAME_VERSION (gimple_assign_lhs (stmt)), &op_non_const); + SSA_NAME_VERSION (gimple_assign_lhs (stmt)), op_non_const); return op_non_const; } @@ -2068,7 +2068,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) struct predicate false_p = false_predicate (); VEC_replace (predicate_t, nonconstant_names, SSA_NAME_VERSION (gimple_call_lhs (stmt)), - &false_p); + false_p); } if (ipa_node_params_vector) { @@ -2083,7 +2083,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) int prob = param_change_prob (stmt, i); gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE); VEC_index (inline_param_summary_t, - es->param, i)->change_prob = prob; + es->param, i).change_prob = prob; } } @@ -2550,8 +2550,8 @@ remap_predicate (struct inline_summary *info, { struct condition *c; - c = VEC_index (condition, callee_info->conds, - cond - predicate_first_dynamic_condition); + c = &VEC_index (condition, callee_info->conds, + cond - predicate_first_dynamic_condition); /* See if we can remap condition operand to caller's operand. Otherwise give up. */ if (!operand_map @@ -2660,10 +2660,10 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge, { int jf_formal_id = ipa_get_jf_pass_through_formal_id (jfunc); int prob1 = VEC_index (inline_param_summary_t, - es->param, i)->change_prob; + es->param, i).change_prob; int prob2 = VEC_index (inline_param_summary_t, - inlined_es->param, jf_formal_id)->change_prob; + inlined_es->param, jf_formal_id).change_prob; int prob = ((prob1 * prob2 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE); @@ -2671,7 +2671,7 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge, prob = 1; VEC_index (inline_param_summary_t, - es->param, i)->change_prob = prob; + es->param, i).change_prob = prob; } } } @@ -2922,12 +2922,12 @@ do_estimate_edge_time (struct cgraph_edge *edge) <= edge->uid) VEC_safe_grow_cleared (edge_growth_cache_entry, heap, edge_growth_cache, cgraph_edge_max_uid); - VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid)->time + VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).time = ret + (ret >= 0); ret_size = size - es->call_stmt_size; gcc_checking_assert (es->call_stmt_size); - VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid)->size + VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size = ret_size + (ret_size >= 0); } return ret; @@ -2954,7 +2954,7 @@ do_estimate_edge_growth (struct cgraph_edge *edge) do_estimate_edge_time (edge); size = VEC_index (edge_growth_cache_entry, edge_growth_cache, - edge->uid)->size; + edge->uid).size; gcc_checking_assert (size); return size - (size > 0); } @@ -3191,7 +3191,7 @@ read_inline_edge_summary (struct lto_input_block *ib, struct cgraph_edge *e) { VEC_safe_grow_cleared (inline_param_summary_t, heap, es->param, length); for (i = 0; i < length; i++) - VEC_index (inline_param_summary_t, es->param, i)->change_prob + VEC_index (inline_param_summary_t, es->param, i).change_prob = streamer_read_uhwi (ib); } } @@ -3350,7 +3350,7 @@ write_inline_edge_summary (struct output_block *ob, struct cgraph_edge *e) streamer_write_uhwi (ob, VEC_length (inline_param_summary_t, es->param)); for (i = 0; i < (int)VEC_length (inline_param_summary_t, es->param); i++) streamer_write_uhwi (ob, VEC_index (inline_param_summary_t, - es->param, i)->change_prob); + es->param, i).change_prob); } diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index d8b66e6..c43ce25 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1287,7 +1287,7 @@ inline_small_functions (void) { struct cgraph_node *node; struct cgraph_edge *edge; - fibheap_t heap = fibheap_new (); + fibheap_t edge_heap = fibheap_new (); bitmap updated_nodes = BITMAP_ALLOC (NULL); int min_size, max_size; VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL; @@ -1344,7 +1344,7 @@ inline_small_functions (void) && edge->inline_failed) { gcc_assert (!edge->aux); - update_edge_key (heap, edge); + update_edge_key (edge_heap, edge); } } @@ -1352,16 +1352,16 @@ inline_small_functions (void) || !max_count || (profile_info && flag_branch_probabilities)); - while (!fibheap_empty (heap)) + while (!fibheap_empty (edge_heap)) { int old_size = overall_size; struct cgraph_node *where, *callee; - int badness = fibheap_min_key (heap); + int badness = fibheap_min_key (edge_heap); int current_badness; int cached_badness; int growth; - edge = (struct cgraph_edge *) fibheap_extract_min (heap); + edge = (struct cgraph_edge *) fibheap_extract_min (edge_heap); gcc_assert (edge->aux); edge->aux = NULL; if (!edge->inline_failed) @@ -1382,7 +1382,7 @@ inline_small_functions (void) gcc_assert (current_badness >= badness); if (current_badness != badness) { - edge->aux = fibheap_insert (heap, current_badness, edge); + edge->aux = fibheap_insert (edge_heap, current_badness, edge); continue; } @@ -1447,8 +1447,8 @@ inline_small_functions (void) /* Recursive inliner inlines all recursive calls of the function at once. Consequently we need to update all callee keys. */ if (flag_indirect_inlining) - add_new_edges_to_heap (heap, new_indirect_edges); - update_callee_keys (heap, where, updated_nodes); + add_new_edges_to_heap (edge_heap, new_indirect_edges); + update_callee_keys (edge_heap, where, updated_nodes); } else { @@ -1482,12 +1482,12 @@ inline_small_functions (void) gcc_checking_assert (!callee->global.inlined_to); inline_call (edge, true, &new_indirect_edges, &overall_size, true); if (flag_indirect_inlining) - add_new_edges_to_heap (heap, new_indirect_edges); + add_new_edges_to_heap (edge_heap, new_indirect_edges); reset_edge_caches (edge->callee); reset_node_growth_cache (callee); - update_callee_keys (heap, edge->callee, updated_nodes); + update_callee_keys (edge_heap, edge->callee, updated_nodes); } where = edge->caller; if (where->global.inlined_to) @@ -1499,7 +1499,7 @@ inline_small_functions (void) inlined into (since it's body size changed) and for the functions called by function we inlined (since number of it inlinable callers might change). */ - update_caller_keys (heap, where, updated_nodes, NULL); + update_caller_keys (edge_heap, where, updated_nodes, NULL); bitmap_clear (updated_nodes); if (dump_file) @@ -1525,7 +1525,7 @@ inline_small_functions (void) free_growth_caches (); if (new_indirect_edges) VEC_free (cgraph_edge_p, heap, new_indirect_edges); - fibheap_delete (heap); + fibheap_delete (edge_heap); if (dump_file) fprintf (dump_file, "Unit growth for small function inlining: %i->%i (%i%%)\n", diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h index 6bcbb94..d6909af 100644 --- a/gcc/ipa-inline.h +++ b/gcc/ipa-inline.h @@ -200,13 +200,13 @@ extern int nfunctions_inlined; static inline struct inline_summary * inline_summary (struct cgraph_node *node) { - return VEC_index (inline_summary_t, inline_summary_vec, node->uid); + return &VEC_index (inline_summary_t, inline_summary_vec, node->uid); } static inline struct inline_edge_summary * inline_edge_summary (struct cgraph_edge *edge) { - return VEC_index (inline_edge_summary_t, + return &VEC_index (inline_edge_summary_t, inline_edge_summary_vec, edge->uid); } @@ -235,7 +235,7 @@ estimate_edge_growth (struct cgraph_edge *edge) if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid || !(ret = VEC_index (edge_growth_cache_entry, edge_growth_cache, - edge->uid)->size)) + edge->uid).size)) return do_estimate_edge_growth (edge); return ret - (ret > 0); } @@ -251,7 +251,7 @@ estimate_edge_time (struct cgraph_edge *edge) if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid || !(ret = VEC_index (edge_growth_cache_entry, edge_growth_cache, - edge->uid)->time)) + edge->uid).time)) return do_estimate_edge_time (edge); return ret - (ret > 0); } @@ -274,6 +274,6 @@ reset_edge_growth_cache (struct cgraph_edge *edge) if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) > edge->uid) { struct edge_growth_cache_entry zero = {0, 0}; - VEC_replace (edge_growth_cache_entry, edge_growth_cache, edge->uid, &zero); + VEC_replace (edge_growth_cache_entry, edge_growth_cache, edge->uid, zero); } } diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 21a7493..966dbfa 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -94,7 +94,7 @@ ipa_populate_param_decls (struct cgraph_node *node, for (parm = fnargs; parm; parm = DECL_CHAIN (parm)) { VEC_index (ipa_param_descriptor_t, - info->descriptors, param_num)->decl = parm; + info->descriptors, param_num).decl = parm; param_num++; } } @@ -2439,10 +2439,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, old_args->jump_functions); for (i = 0; i < VEC_length (ipa_jump_func_t, old_args->jump_functions); i++) - VEC_index (ipa_jump_func_t, new_args->jump_functions, i)->agg.items + VEC_index (ipa_jump_func_t, new_args->jump_functions, i).agg.items = VEC_copy (ipa_agg_jf_item_t, gc, VEC_index (ipa_jump_func_t, - old_args->jump_functions, i)->agg.items); + old_args->jump_functions, i).agg.items); } /* Hook that is called by cgraph.c when a node is duplicated. */ @@ -2672,7 +2672,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments, struct ipa_parm_adjustment *adj; gcc_assert (link); - adj = VEC_index (ipa_parm_adjustment_t, adjustments, i); + adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i); parm = VEC_index (tree, oparms, adj->base_index); adj->base = parm; @@ -2738,8 +2738,8 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments, When we are asked to remove it, we need to build new FUNCTION_TYPE instead. */ if (TREE_CODE (orig_type) != METHOD_TYPE - || (VEC_index (ipa_parm_adjustment_t, adjustments, 0)->copy_param - && VEC_index (ipa_parm_adjustment_t, adjustments, 0)->base_index == 0)) + || (VEC_index (ipa_parm_adjustment_t, adjustments, 0).copy_param + && VEC_index (ipa_parm_adjustment_t, adjustments, 0).base_index == 0)) { new_type = build_distinct_type_copy (orig_type); TYPE_ARG_TYPES (new_type) = new_reversed; @@ -2806,7 +2806,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, { struct ipa_parm_adjustment *adj; - adj = VEC_index (ipa_parm_adjustment_t, adjustments, i); + adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i); if (adj->copy_param) { @@ -2989,7 +2989,7 @@ index_in_adjustments_multiple_times_p (int base_index, for (i = 0; i < len; i++) { struct ipa_parm_adjustment *adj; - adj = VEC_index (ipa_parm_adjustment_t, adjustments, i); + adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i); if (adj->base_index == base_index) { @@ -3020,7 +3020,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner, for (i = 0; i < inlen; i++) { struct ipa_parm_adjustment *n; - n = VEC_index (ipa_parm_adjustment_t, inner, i); + n = &VEC_index (ipa_parm_adjustment_t, inner, i); if (n->remove_param) removals++; @@ -3032,10 +3032,10 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner, for (i = 0; i < outlen; i++) { struct ipa_parm_adjustment *r; - struct ipa_parm_adjustment *out = VEC_index (ipa_parm_adjustment_t, - outer, i); - struct ipa_parm_adjustment *in = VEC_index (ipa_parm_adjustment_t, tmp, - out->base_index); + struct ipa_parm_adjustment *out = &VEC_index (ipa_parm_adjustment_t, + outer, i); + struct ipa_parm_adjustment *in = &VEC_index (ipa_parm_adjustment_t, tmp, + out->base_index); gcc_assert (!in->remove_param); if (out->remove_param) @@ -3068,8 +3068,8 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner, for (i = 0; i < inlen; i++) { - struct ipa_parm_adjustment *n = VEC_index (ipa_parm_adjustment_t, - inner, i); + struct ipa_parm_adjustment *n = &VEC_index (ipa_parm_adjustment_t, + inner, i); if (n->remove_param) VEC_quick_push (ipa_parm_adjustment_t, adjustments, n); @@ -3094,7 +3094,7 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments, for (i = 0; i < len; i++) { struct ipa_parm_adjustment *adj; - adj = VEC_index (ipa_parm_adjustment_t, adjustments, i); + adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i); if (!first) fprintf (file, " "); diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 3ef0dc79..1fdd833 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -359,7 +359,7 @@ ipa_get_param_count (struct ipa_node_params *info) static inline tree ipa_get_param (struct ipa_node_params *info, int i) { - return VEC_index (ipa_param_descriptor_t, info->descriptors, i)->decl; + return VEC_index (ipa_param_descriptor_t, info->descriptors, i).decl; } /* Set the used flag corresponding to the Ith formal parameter of the function @@ -368,7 +368,7 @@ ipa_get_param (struct ipa_node_params *info, int i) static inline void ipa_set_param_used (struct ipa_node_params *info, int i, bool val) { - VEC_index (ipa_param_descriptor_t, info->descriptors, i)->used = val; + VEC_index (ipa_param_descriptor_t, info->descriptors, i).used = val; } /* Return the used flag corresponding to the Ith formal parameter of the @@ -377,7 +377,7 @@ ipa_set_param_used (struct ipa_node_params *info, int i, bool val) static inline bool ipa_is_param_used (struct ipa_node_params *info, int i) { - return VEC_index (ipa_param_descriptor_t, info->descriptors, i)->used; + return VEC_index (ipa_param_descriptor_t, info->descriptors, i).used; } /* ipa_edge_args stores information related to a callsite and particularly its @@ -406,7 +406,7 @@ ipa_get_cs_argument_count (struct ipa_edge_args *args) static inline struct ipa_jump_func * ipa_get_ith_jump_func (struct ipa_edge_args *args, int i) { - return VEC_index (ipa_jump_func_t, args->jump_functions, i); + return &VEC_index (ipa_jump_func_t, args->jump_functions, i); } /* Vectors need to have typedefs of structures. */ @@ -425,10 +425,10 @@ extern GTY(()) VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector; /* Return the associated parameter/argument info corresponding to the given node/edge. */ -#define IPA_NODE_REF(NODE) (VEC_index (ipa_node_params_t, \ - ipa_node_params_vector, (NODE)->uid)) -#define IPA_EDGE_REF(EDGE) (VEC_index (ipa_edge_args_t, \ - ipa_edge_args_vector, (EDGE)->uid)) +#define IPA_NODE_REF(NODE) (&VEC_index (ipa_node_params_t, \ + ipa_node_params_vector, (NODE)->uid)) +#define IPA_EDGE_REF(EDGE) (&VEC_index (ipa_edge_args_t, \ + ipa_edge_args_vector, (EDGE)->uid)) /* This macro checks validity of index returned by ipa_get_param_decl_index function. */ #define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1) diff --git a/gcc/ipa-ref-inline.h b/gcc/ipa-ref-inline.h index 636af14..575bba9 100644 --- a/gcc/ipa-ref-inline.h +++ b/gcc/ipa-ref-inline.h @@ -73,7 +73,7 @@ ipa_ref_list_first_reference (struct ipa_ref_list *list) { if (!VEC_length (ipa_ref_t, list->references)) return NULL; - return VEC_index (ipa_ref_t, list->references, 0); + return &VEC_index (ipa_ref_t, list->references, 0); } /* Return first referring ref in LIST or NULL if empty. */ diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c index 7926eb6a..21799ab 100644 --- a/gcc/ipa-ref.c +++ b/gcc/ipa-ref.c @@ -49,7 +49,7 @@ ipa_record_reference (symtab_node referring_node, old_references = list->references; VEC_safe_grow (ipa_ref_t, gc, list->references, VEC_length (ipa_ref_t, list->references) + 1); - ref = VEC_last (ipa_ref_t, list->references); + ref = &VEC_last (ipa_ref_t, list->references); list2 = &referred_node->symbol.ref_list; VEC_safe_push (ipa_ref_ptr, heap, list2->referring, ref); @@ -93,7 +93,7 @@ ipa_remove_reference (struct ipa_ref *ref) } VEC_pop (ipa_ref_ptr, list->referring); - last = VEC_last (ipa_ref_t, list2->references); + last = &VEC_last (ipa_ref_t, list2->references); if (ref != last) { *ref = *last; @@ -111,7 +111,7 @@ void ipa_remove_all_references (struct ipa_ref_list *list) { while (VEC_length (ipa_ref_t, list->references)) - ipa_remove_reference (VEC_last (ipa_ref_t, list->references)); + ipa_remove_reference (&VEC_last (ipa_ref_t, list->references)); VEC_free (ipa_ref_t, gc, list->references); list->references = NULL; } diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 4e5a179..3eec70c 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -917,7 +917,7 @@ find_split_points (int overall_time, int overall_size) while (!VEC_empty (stack_entry, stack)) { - stack_entry *entry = VEC_last (stack_entry, stack); + stack_entry *entry = &VEC_last (stack_entry, stack); /* We are walking an acyclic graph, so edge_num counts succ and pred edges together. However when considering @@ -984,9 +984,9 @@ find_split_points (int overall_time, int overall_size) new_entry.bb = dest; new_entry.edge_num = 0; new_entry.overall_time - = VEC_index (bb_info, bb_info_vec, dest->index)->time; + = VEC_index (bb_info, bb_info_vec, dest->index).time; new_entry.overall_size - = VEC_index (bb_info, bb_info_vec, dest->index)->size; + = VEC_index (bb_info, bb_info_vec, dest->index).size; new_entry.earliest = INT_MAX; new_entry.set_ssa_names = BITMAP_ALLOC (NULL); new_entry.used_ssa_names = BITMAP_ALLOC (NULL); @@ -1006,8 +1006,8 @@ find_split_points (int overall_time, int overall_size) and merge stuff we accumulate during the walk. */ else if (entry->bb != ENTRY_BLOCK_PTR) { - stack_entry *prev = VEC_index (stack_entry, stack, - VEC_length (stack_entry, stack) - 2); + stack_entry *prev = &VEC_index (stack_entry, stack, + VEC_length (stack_entry, stack) - 2); entry->bb->aux = (void *)(intptr_t)-1; prev->can_split &= entry->can_split; @@ -1489,8 +1489,8 @@ execute_split_functions (void) } overall_time += time; overall_size += size; - VEC_index (bb_info, bb_info_vec, bb->index)->time = time; - VEC_index (bb_info, bb_info_vec, bb->index)->size = size; + VEC_index (bb_info, bb_info_vec, bb->index).time = time; + VEC_index (bb_info, bb_info_vec, bb->index).size = size; } find_split_points (overall_time, overall_size); if (best_split_point.split_bbs) diff --git a/gcc/java/boehm.c b/gcc/java/boehm.c index f4a9af6..07dfb61 100644 --- a/gcc/java/boehm.c +++ b/gcc/java/boehm.c @@ -233,6 +233,6 @@ uses_jv_markobj_p (tree dtable) this function is only used with flag_reduced_reflection. No point in asserting unless we hit the bad case. */ gcc_assert (!flag_reduced_reflection || TARGET_VTABLE_USES_DESCRIPTORS == 0); - v = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (dtable), 3)->value; + v = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (dtable), 3).value; return (PROCEDURE_OBJECT_DESCRIPTOR == TREE_INT_CST_LOW (v)); } diff --git a/gcc/java/class.c b/gcc/java/class.c index 40ff26d..f806cea 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -1533,7 +1533,7 @@ make_method_value (tree mdecl) v = VEC_alloc (constructor_elt, gc, length); VEC_safe_grow_cleared (constructor_elt, gc, v, length); - e = VEC_index (constructor_elt, v, idx--); + e = &VEC_index (constructor_elt, v, idx--); e->value = null_pointer_node; FOR_EACH_VEC_ELT (tree, DECL_FUNCTION_THROWS (mdecl), ix, t) @@ -1542,7 +1542,7 @@ make_method_value (tree mdecl) tree utf8 = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig), IDENTIFIER_LENGTH (sig))); - e = VEC_index (constructor_elt, v, idx--); + e = &VEC_index (constructor_elt, v, idx--); e->value = utf8; } gcc_assert (idx == -1); @@ -1621,7 +1621,7 @@ get_dispatch_table (tree type, tree this_class_addr) arraysize += 2; VEC_safe_grow_cleared (constructor_elt, gc, v, arraysize); - e = VEC_index (constructor_elt, v, arraysize - 1); + e = &VEC_index (constructor_elt, v, arraysize - 1); #define CONSTRUCTOR_PREPEND_VALUE(E, V) E->value = V, E-- for (i = nvirtuals; --i >= 0; ) @@ -3007,7 +3007,7 @@ emit_catch_table (tree this_class) int n_catch_classes; constructor_elt *e; /* Fill in the dummy entry that make_class created. */ - e = VEC_index (constructor_elt, TYPE_CATCH_CLASSES (this_class), 0); + e = &VEC_index (constructor_elt, TYPE_CATCH_CLASSES (this_class), 0); e->value = make_catch_class_record (null_pointer_node, null_pointer_node); CONSTRUCTOR_APPEND_ELT (TYPE_CATCH_CLASSES (this_class), NULL_TREE, make_catch_class_record (null_pointer_node, diff --git a/gcc/java/constants.c b/gcc/java/constants.c index 2cc911f..c709fa4 100644 --- a/gcc/java/constants.c +++ b/gcc/java/constants.c @@ -514,8 +514,8 @@ build_constants_constructor (void) int c = outgoing_cpool->count; VEC_safe_grow_cleared (constructor_elt, gc, tags, c); VEC_safe_grow_cleared (constructor_elt, gc, data, c); - t = VEC_index (constructor_elt, tags, c-1); - d = VEC_index (constructor_elt, data, c-1); + t = &VEC_index (constructor_elt, tags, c-1); + d = &VEC_index (constructor_elt, data, c-1); } #define CONSTRUCTOR_PREPEND_VALUE(E, V) E->value = V, E-- diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 6169b6a..5167b9b 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -1430,7 +1430,7 @@ extern tree *type_map; #define PUSH_SUPER_VALUE(V, VALUE) \ do \ { \ - constructor_elt *_elt___ = VEC_last (constructor_elt, V); \ + constructor_elt *_elt___ = &VEC_last (constructor_elt, V); \ tree _next___ = DECL_CHAIN (_elt___->index); \ gcc_assert (!DECL_NAME (_elt___->index)); \ _elt___->value = VALUE; \ @@ -1444,7 +1444,7 @@ extern tree *type_map; #define PUSH_FIELD_VALUE(V, NAME, VALUE) \ do \ { \ - constructor_elt *_elt___ = VEC_last (constructor_elt, V); \ + constructor_elt *_elt___ = &VEC_last (constructor_elt, V); \ tree _next___ = DECL_CHAIN (_elt___->index); \ gcc_assert (strcmp (IDENTIFIER_POINTER (DECL_NAME (_elt___->index)), \ NAME) == 0); \ diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c index af79fb6..673055e 100644 --- a/gcc/modulo-sched.c +++ b/gcc/modulo-sched.c @@ -229,7 +229,7 @@ static void remove_node_from_ps (partial_schedule_ptr, ps_insn_ptr); #define NODE_ASAP(node) ((node)->aux.count) -#define SCHED_PARAMS(x) VEC_index (node_sched_params, node_sched_param_vec, x) +#define SCHED_PARAMS(x) (&VEC_index (node_sched_params, node_sched_param_vec, x)) #define SCHED_TIME(x) (SCHED_PARAMS (x)->time) #define SCHED_ROW(x) (SCHED_PARAMS (x)->row) #define SCHED_STAGE(x) (SCHED_PARAMS (x)->stage) @@ -305,7 +305,7 @@ static struct ps_reg_move_info * ps_reg_move (partial_schedule_ptr ps, int id) { gcc_checking_assert (id >= ps->g->num_nodes); - return VEC_index (ps_reg_move_info, ps->reg_moves, id - ps->g->num_nodes); + return &VEC_index (ps_reg_move_info, ps->reg_moves, id - ps->g->num_nodes); } /* Return the rtl instruction that is being scheduled by partial schedule diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 5c924bf..caa16c7 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -3209,7 +3209,7 @@ objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts) #ifdef OBJCPLUS /* Adjust for impedance mismatch. We should figure out how to build CONSTRUCTORs that consistently please both the C and C++ gods. */ - if (!VEC_index (constructor_elt, elts, 0)->index) + if (!VEC_index (constructor_elt, elts, 0).index) TREE_TYPE (constructor) = init_list_type_node; #endif @@ -802,7 +802,7 @@ add_removable_extension (const_rtx expr, rtx insn, different extension. FIXME: this obviously can be improved. */ for (def = defs; def; def = def->next) if ((idx = def_map[INSN_UID(DF_REF_INSN (def->ref))]) - && (cand = VEC_index (ext_cand, *insn_list, idx - 1)) + && (cand = &VEC_index (ext_cand, *insn_list, idx - 1)) && (cand->code != code || cand->mode != mode)) { if (dump_file) diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index d1e195d..dc7550a 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -201,7 +201,7 @@ typedef struct stack_def int top; /* index to top stack element */ HARD_REG_SET reg_set; /* set of live registers */ unsigned char reg[REG_STACK_SIZE];/* register - stack mapping */ -} *stack; +} *stack_ptr; /* This is used to carry information about basic blocks. It is attached to the AUX field of the standard CFG block. */ @@ -246,7 +246,7 @@ static rtx not_a_num; /* Forward declarations */ static int stack_regs_mentioned_p (const_rtx pat); -static void pop_stack (stack, int); +static void pop_stack (stack_ptr, int); static rtx *get_true_reg (rtx *); static int check_asm_stack_operands (rtx); @@ -254,19 +254,19 @@ static void get_asm_operands_in_out (rtx, int *, int *); static rtx stack_result (tree); static void replace_reg (rtx *, int); static void remove_regno_note (rtx, enum reg_note, unsigned int); -static int get_hard_regnum (stack, rtx); -static rtx emit_pop_insn (rtx, stack, rtx, enum emit_where); -static void swap_to_top(rtx, stack, rtx, rtx); -static bool move_for_stack_reg (rtx, stack, rtx); -static bool move_nan_for_stack_reg (rtx, stack, rtx); +static int get_hard_regnum (stack_ptr, rtx); +static rtx emit_pop_insn (rtx, stack_ptr, rtx, enum emit_where); +static void swap_to_top(rtx, stack_ptr, rtx, rtx); +static bool move_for_stack_reg (rtx, stack_ptr, rtx); +static bool move_nan_for_stack_reg (rtx, stack_ptr, rtx); static int swap_rtx_condition_1 (rtx); static int swap_rtx_condition (rtx); -static void compare_for_stack_reg (rtx, stack, rtx); -static bool subst_stack_regs_pat (rtx, stack, rtx); -static void subst_asm_stack_regs (rtx, stack); -static bool subst_stack_regs (rtx, stack); -static void change_stack (rtx, stack, stack, enum emit_where); -static void print_stack (FILE *, stack); +static void compare_for_stack_reg (rtx, stack_ptr, rtx); +static bool subst_stack_regs_pat (rtx, stack_ptr, rtx); +static void subst_asm_stack_regs (rtx, stack_ptr); +static bool subst_stack_regs (rtx, stack_ptr); +static void change_stack (rtx, stack_ptr, stack_ptr, enum emit_where); +static void print_stack (FILE *, stack_ptr); static rtx next_flags_user (rtx); /* Return nonzero if any stack register is mentioned somewhere within PAT. */ @@ -354,7 +354,7 @@ next_flags_user (rtx insn) /* Reorganize the stack into ascending numbers, before this insn. */ static void -straighten_stack (rtx insn, stack regstack) +straighten_stack (rtx insn, stack_ptr regstack) { struct stack_def temp_stack; int top; @@ -377,7 +377,7 @@ straighten_stack (rtx insn, stack regstack) /* Pop a register from the stack. */ static void -pop_stack (stack regstack, int regno) +pop_stack (stack_ptr regstack, int regno) { int top = regstack->top; @@ -721,7 +721,7 @@ remove_regno_note (rtx insn, enum reg_note note, unsigned int regno) returned if the register is not found. */ static int -get_hard_regnum (stack regstack, rtx reg) +get_hard_regnum (stack_ptr regstack, rtx reg) { int i; @@ -742,7 +742,7 @@ get_hard_regnum (stack regstack, rtx reg) cases the movdf pattern to pop. */ static rtx -emit_pop_insn (rtx insn, stack regstack, rtx reg, enum emit_where where) +emit_pop_insn (rtx insn, stack_ptr regstack, rtx reg, enum emit_where where) { rtx pop_insn, pop_rtx; int hard_regno; @@ -793,7 +793,7 @@ emit_pop_insn (rtx insn, stack regstack, rtx reg, enum emit_where where) If REG is already at the top of the stack, no insn is emitted. */ static void -emit_swap_insn (rtx insn, stack regstack, rtx reg) +emit_swap_insn (rtx insn, stack_ptr regstack, rtx reg) { int hard_regno; rtx swap_rtx; @@ -900,7 +900,7 @@ emit_swap_insn (rtx insn, stack regstack, rtx reg) is emitted. */ static void -swap_to_top (rtx insn, stack regstack, rtx src1, rtx src2) +swap_to_top (rtx insn, stack_ptr regstack, rtx src1, rtx src2) { struct stack_def temp_stack; int regno, j, k, temp; @@ -941,7 +941,7 @@ swap_to_top (rtx insn, stack regstack, rtx src1, rtx src2) was deleted in the process. */ static bool -move_for_stack_reg (rtx insn, stack regstack, rtx pat) +move_for_stack_reg (rtx insn, stack_ptr regstack, rtx pat) { rtx *psrc = get_true_reg (&SET_SRC (pat)); rtx *pdest = get_true_reg (&SET_DEST (pat)); @@ -1092,7 +1092,7 @@ move_for_stack_reg (rtx insn, stack regstack, rtx pat) a NaN into DEST, then invokes move_for_stack_reg. */ static bool -move_nan_for_stack_reg (rtx insn, stack regstack, rtx dest) +move_nan_for_stack_reg (rtx insn, stack_ptr regstack, rtx dest) { rtx pat; @@ -1231,7 +1231,7 @@ swap_rtx_condition (rtx insn) set up. */ static void -compare_for_stack_reg (rtx insn, stack regstack, rtx pat_src) +compare_for_stack_reg (rtx insn, stack_ptr regstack, rtx pat_src) { rtx *src1, *src2; rtx src1_note, src2_note; @@ -1320,7 +1320,7 @@ compare_for_stack_reg (rtx insn, stack regstack, rtx pat_src) static int subst_stack_regs_in_debug_insn (rtx *loc, void *data) { - stack regstack = (stack)data; + stack_ptr regstack = (stack_ptr)data; int hard_regno; if (!STACK_REG_P (*loc)) @@ -1361,7 +1361,7 @@ subst_all_stack_regs_in_debug_insn (rtx insn, struct stack_def *regstack) was deleted in the process. */ static bool -subst_stack_regs_pat (rtx insn, stack regstack, rtx pat) +subst_stack_regs_pat (rtx insn, stack_ptr regstack, rtx pat) { rtx *dest, *src; bool control_flow_insn_deleted = false; @@ -2009,7 +2009,7 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat) requirements, since record_asm_stack_regs removes any problem asm. */ static void -subst_asm_stack_regs (rtx insn, stack regstack) +subst_asm_stack_regs (rtx insn, stack_ptr regstack) { rtx body = PATTERN (insn); int alt; @@ -2292,7 +2292,7 @@ subst_asm_stack_regs (rtx insn, stack regstack) a control flow insn was deleted in the process. */ static bool -subst_stack_regs (rtx insn, stack regstack) +subst_stack_regs (rtx insn, stack_ptr regstack) { rtx *note_link, note; bool control_flow_insn_deleted = false; @@ -2404,7 +2404,7 @@ subst_stack_regs (rtx insn, stack regstack) is no longer needed once this has executed. */ static void -change_stack (rtx insn, stack old, stack new_stack, enum emit_where where) +change_stack (rtx insn, stack_ptr old, stack_ptr new_stack, enum emit_where where) { int reg; int update_end = 0; @@ -2610,7 +2610,7 @@ change_stack (rtx insn, stack old, stack new_stack, enum emit_where where) /* Print stack configuration. */ static void -print_stack (FILE *file, stack s) +print_stack (FILE *file, stack_ptr s) { if (! file) return; @@ -2686,7 +2686,7 @@ static void convert_regs_exit (void) { int value_reg_low, value_reg_high; - stack output_stack; + stack_ptr output_stack; rtx retvalue; retvalue = stack_result (current_function_decl); @@ -2719,8 +2719,8 @@ convert_regs_exit (void) static void propagate_stack (edge e) { - stack src_stack = &BLOCK_INFO (e->src)->stack_out; - stack dest_stack = &BLOCK_INFO (e->dest)->stack_in; + stack_ptr src_stack = &BLOCK_INFO (e->src)->stack_out; + stack_ptr dest_stack = &BLOCK_INFO (e->dest)->stack_in; int reg; /* Preserve the order of the original stack, but check whether @@ -2746,8 +2746,8 @@ static bool compensate_edge (edge e) { basic_block source = e->src, target = e->dest; - stack target_stack = &BLOCK_INFO (target)->stack_in; - stack source_stack = &BLOCK_INFO (source)->stack_out; + stack_ptr target_stack = &BLOCK_INFO (target)->stack_in; + stack_ptr source_stack = &BLOCK_INFO (source)->stack_out; struct stack_def regstack; int reg; diff --git a/gcc/regrename.c b/gcc/regrename.c index 2366fb5..d125242 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -728,8 +728,8 @@ regrename_analyze (bitmap bb_mask) rtx insn; FOR_BB_INSNS (bb1, insn) { - insn_rr_info *p = VEC_index (insn_rr_info, insn_rr, - INSN_UID (insn)); + insn_rr_info *p = &VEC_index (insn_rr_info, insn_rr, + INSN_UID (insn)); p->op_info = NULL; } } @@ -1583,7 +1583,7 @@ build_def_use (basic_block bb) if (insn_rr != NULL) { - insn_info = VEC_index (insn_rr_info, insn_rr, INSN_UID (insn)); + insn_info = &VEC_index (insn_rr_info, insn_rr, INSN_UID (insn)); insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info, recog_data.n_operands); memset (insn_info->op_info, 0, diff --git a/gcc/reload.h b/gcc/reload.h index 29d15ea..a672ddc 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -243,19 +243,19 @@ typedef struct reg_equivs } reg_equivs_t; #define reg_equiv_constant(ELT) \ - VEC_index (reg_equivs_t, reg_equivs, (ELT))->constant + VEC_index (reg_equivs_t, reg_equivs, (ELT)).constant #define reg_equiv_invariant(ELT) \ - VEC_index (reg_equivs_t, reg_equivs, (ELT))->invariant + VEC_index (reg_equivs_t, reg_equivs, (ELT)).invariant #define reg_equiv_memory_loc(ELT) \ - VEC_index (reg_equivs_t, reg_equivs, (ELT))->memory_loc + VEC_index (reg_equivs_t, reg_equivs, (ELT)).memory_loc #define reg_equiv_address(ELT) \ - VEC_index (reg_equivs_t, reg_equivs, (ELT))->address + VEC_index (reg_equivs_t, reg_equivs, (ELT)).address #define reg_equiv_mem(ELT) \ - VEC_index (reg_equivs_t, reg_equivs, (ELT))->mem + VEC_index (reg_equivs_t, reg_equivs, (ELT)).mem #define reg_equiv_alt_mem_list(ELT) \ - VEC_index (reg_equivs_t, reg_equivs, (ELT))->alt_mem_list + VEC_index (reg_equivs_t, reg_equivs, (ELT)).alt_mem_list #define reg_equiv_init(ELT) \ - VEC_index (reg_equivs_t, reg_equivs, (ELT))->init + VEC_index (reg_equivs_t, reg_equivs, (ELT)).init DEF_VEC_O(reg_equivs_t); DEF_VEC_ALLOC_O(reg_equivs_t, gc); diff --git a/gcc/reload1.c b/gcc/reload1.c index 4c1ecfc..1a3d279 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -664,7 +664,8 @@ grow_reg_equivs (void) for (i = old_size; i < max_regno; i++) { VEC_quick_insert (reg_equivs_t, reg_equivs, i, 0); - memset (VEC_index (reg_equivs_t, reg_equivs, i), 0, sizeof (reg_equivs_t)); + memset (&VEC_index (reg_equivs_t, reg_equivs, i), 0, + sizeof (reg_equivs_t)); } } diff --git a/gcc/sched-int.h b/gcc/sched-int.h index fa5fc66..2e46238 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -873,7 +873,7 @@ DEF_VEC_ALLOC_O (haifa_insn_data_def, heap); extern VEC(haifa_insn_data_def, heap) *h_i_d; -#define HID(INSN) (VEC_index (haifa_insn_data_def, h_i_d, INSN_UID (INSN))) +#define HID(INSN) (&VEC_index (haifa_insn_data_def, h_i_d, INSN_UID (INSN))) /* Accessor macros for h_i_d. There are more in haifa-sched.c and sched-rgn.c. */ @@ -895,7 +895,7 @@ DEF_VEC_ALLOC_O (haifa_deps_insn_data_def, heap); extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d; -#define HDID(INSN) (VEC_index (haifa_deps_insn_data_def, h_d_i_d, \ +#define HDID(INSN) (&VEC_index (haifa_deps_insn_data_def, h_d_i_d, \ INSN_LUID (INSN))) #define INSN_DEP_COUNT(INSN) (HDID (INSN)->dep_count) #define HAS_INTERNAL_DEP(INSN) (HDID (INSN)->has_internal_dep) @@ -909,7 +909,7 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d; #define INSN_COND_DEPS(INSN) (HDID (INSN)->cond_deps) #define CANT_MOVE(INSN) (HDID (INSN)->cant_move) #define CANT_MOVE_BY_LUID(LUID) (VEC_index (haifa_deps_insn_data_def, h_d_i_d, \ - LUID)->cant_move) + LUID).cant_move) #define INSN_PRIORITY(INSN) (HID (INSN)->priority) diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index e7ca3f1..449efc9 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -1524,7 +1524,7 @@ insert_in_history_vect (VEC (expr_history_def, heap) **pvect, if (res) { - expr_history_def *phist = VEC_index (expr_history_def, vect, ind); + expr_history_def *phist = &VEC_index (expr_history_def, vect, ind); /* It is possible that speculation types of expressions that were propagated through different paths will be different here. In this @@ -4159,7 +4159,7 @@ finish_insns (void) removed during the scheduling. */ for (i = 0; i < VEC_length (sel_insn_data_def, s_i_d); i++) { - sel_insn_data_def *sid_entry = VEC_index (sel_insn_data_def, s_i_d, i); + sel_insn_data_def *sid_entry = &VEC_index (sel_insn_data_def, s_i_d, i); if (sid_entry->live) return_regset_to_pool (sid_entry->live); diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h index 2003552..ef884a5 100644 --- a/gcc/sel-sched-ir.h +++ b/gcc/sel-sched-ir.h @@ -765,8 +765,8 @@ DEF_VEC_ALLOC_O (sel_insn_data_def, heap); extern VEC (sel_insn_data_def, heap) *s_i_d; /* Accessor macros for s_i_d. */ -#define SID(INSN) (VEC_index (sel_insn_data_def, s_i_d, INSN_LUID (INSN))) -#define SID_BY_UID(UID) (VEC_index (sel_insn_data_def, s_i_d, LUID_BY_UID (UID))) +#define SID(INSN) (&VEC_index (sel_insn_data_def, s_i_d, INSN_LUID (INSN))) +#define SID_BY_UID(UID) (&VEC_index (sel_insn_data_def, s_i_d, LUID_BY_UID (UID))) extern sel_insn_data_def insn_sid (insn_t); @@ -897,7 +897,7 @@ extern void sel_finish_global_bb_info (void); /* Get data for BB. */ #define SEL_GLOBAL_BB_INFO(BB) \ - (VEC_index (sel_global_bb_info_def, sel_global_bb_info, (BB)->index)) + (&VEC_index (sel_global_bb_info_def, sel_global_bb_info, (BB)->index)) /* Access macros. */ #define BB_LV_SET(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set) @@ -927,8 +927,8 @@ DEF_VEC_ALLOC_O (sel_region_bb_info_def, heap); extern VEC (sel_region_bb_info_def, heap) *sel_region_bb_info; /* Get data for BB. */ -#define SEL_REGION_BB_INFO(BB) (VEC_index (sel_region_bb_info_def, \ - sel_region_bb_info, (BB)->index)) +#define SEL_REGION_BB_INFO(BB) (&VEC_index (sel_region_bb_info_def, \ + sel_region_bb_info, (BB)->index)) /* Get BB's note_list. A note_list is a list of various notes that was scattered across BB diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index f0c6eaf..b5bffa1 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -1938,9 +1938,9 @@ undo_transformations (av_set_t *av_ptr, rtx insn) { expr_history_def *phist; - phist = VEC_index (expr_history_def, - EXPR_HISTORY_OF_CHANGES (expr), - index); + phist = &VEC_index (expr_history_def, + EXPR_HISTORY_OF_CHANGES (expr), + index); switch (phist->type) { @@ -3581,7 +3581,7 @@ vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr) EXPR_HISTORY_OF_CHANGES (expr)) ? VEC_index (expr_history_def, EXPR_HISTORY_OF_CHANGES (expr), - i++)->old_expr_vinsn + i++).old_expr_vinsn : NULL)) FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) if (VINSN_SEPARABLE_P (vinsn)) diff --git a/gcc/stringpool.c b/gcc/stringpool.c index 747db17..281e550 100644 --- a/gcc/stringpool.c +++ b/gcc/stringpool.c @@ -49,7 +49,7 @@ static const char digit_vector[] = { struct ht *ident_hash; -static hashnode alloc_node (hash_table *); +static hashnode alloc_node (cpp_hash_table *); static int mark_ident (struct cpp_reader *, hashnode, const void *); static void * @@ -70,7 +70,7 @@ init_stringpool (void) /* Allocate a hash node. */ static hashnode -alloc_node (hash_table *table ATTRIBUTE_UNUSED) +alloc_node (cpp_hash_table *table ATTRIBUTE_UNUSED) { return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE)); } @@ -210,6 +210,32 @@ gt_pch_n_S (const void *x) gt_pch_note_object (CONST_CAST (void *, x), CONST_CAST (void *, x), >_pch_p_S, gt_types_enum_last); } + + +/* User-callable entry point for marking string X. */ + +void +gt_pch_nx (const char *& x) +{ + gt_pch_n_S (x); +} + +void +gt_pch_nx (unsigned char *& x) +{ + gt_pch_n_S (x); +} + +void +gt_pch_nx (unsigned char& x ATTRIBUTE_UNUSED) +{ +} + +void +gt_pch_nx (unsigned char *x, gt_pointer_operator op, void *cookie) +{ + op (x, cookie); +} /* Handle saving and restoring the string pool for PCH. */ diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c index c879548..be020da 100644 --- a/gcc/tree-call-cdce.c +++ b/gcc/tree-call-cdce.c @@ -374,7 +374,7 @@ gen_conditions_for_domain (tree arg, inp_domain domain, { /* Now push a separator. */ if (domain.has_lb) - VEC_quick_push (gimple, conds, NULL); + VEC_quick_push (gimple, conds, (gimple)NULL); gen_one_condition (arg, domain.ub, (domain.is_ub_inclusive @@ -496,7 +496,7 @@ gen_conditions_for_pow_int_base (tree base, tree expn, type is integer. */ /* Push a separator. */ - VEC_quick_push (gimple, conds, NULL); + VEC_quick_push (gimple, conds, (gimple)NULL); temp = create_tmp_var (int_type, "DCE_COND1"); cst0 = build_int_cst (int_type, 0); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 6ee01a3..c718cc0 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -7872,3 +7872,54 @@ struct gimple_opt_pass pass_warn_unused_result = 0, /* todo_flags_finish */ } }; + + +/* Garbage collection support for edge_def. */ + +extern void gt_ggc_mx (tree&); +extern void gt_ggc_mx (gimple&); +extern void gt_ggc_mx (rtx&); +extern void gt_ggc_mx (basic_block&); + +void +gt_ggc_mx (edge_def *e) +{ + gt_ggc_mx (e->src); + gt_ggc_mx (e->dest); + if (current_ir_type () == IR_GIMPLE) + gt_ggc_mx (e->insns.g); + else + gt_ggc_mx (e->insns.r); + gt_ggc_mx (e->goto_block); +} + +/* PCH support for edge_def. */ + +extern void gt_pch_nx (tree&); +extern void gt_pch_nx (gimple&); +extern void gt_pch_nx (rtx&); +extern void gt_pch_nx (basic_block&); + +void +gt_pch_nx (edge_def *e) +{ + gt_pch_nx (e->src); + gt_pch_nx (e->dest); + if (current_ir_type () == IR_GIMPLE) + gt_pch_nx (e->insns.g); + else + gt_pch_nx (e->insns.r); + gt_pch_nx (e->goto_block); +} + +void +gt_pch_nx (edge_def *e, gt_pointer_operator op, void *cookie) +{ + op (&(e->src), cookie); + op (&(e->dest), cookie); + if (current_ir_type () == IR_GIMPLE) + op (&(e->insns.g), cookie); + else + op (&(e->insns.r), cookie); + op (&(e->goto_block), cookie); +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 3c94b79..504f9a8 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3999,7 +3999,7 @@ splice_all_param_accesses (VEC (access_p, heap) **representatives) result = UNUSED_PARAMS; } else - VEC_quick_push (access_p, *representatives, NULL); + VEC_quick_push (access_p, *representatives, (access_p) NULL); } if (result == NO_GOOD_ACCESS) @@ -4208,7 +4208,7 @@ get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base) { struct ipa_parm_adjustment *adj; - adj = VEC_index (ipa_parm_adjustment_t, adjustments, i); + adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i); if (!adj->copy_param && adj->base == base) return adj; } @@ -4315,7 +4315,7 @@ sra_ipa_modify_expr (tree *expr, bool convert, for (i = 0; i < len; i++) { - adj = VEC_index (ipa_parm_adjustment_t, adjustments, i); + adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i); if (adj->base == base && (adj->offset == offset || adj->remove_param)) @@ -4522,7 +4522,7 @@ sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments) tree name, vexpr, copy = NULL_TREE; use_operand_p use_p; - adj = VEC_index (ipa_parm_adjustment_t, adjustments, i); + adj = &VEC_index (ipa_parm_adjustment_t, adjustments, i); if (adj->copy_param || !is_gimple_reg (adj->base)) continue; name = ssa_default_def (cfun, adj->base); diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index ddab7d8..57a590d 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -215,7 +215,8 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as, templ_index + 1); /* Reuse the templates for addresses, so that we do not waste memory. */ - templ = VEC_index (mem_addr_template, mem_addr_template_list, templ_index); + templ = &VEC_index (mem_addr_template, mem_addr_template_list, + templ_index); if (!templ->ref) { sym = (addr->symbol ? diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 8e42a51..4b798b70 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -130,6 +130,7 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "gimple-fold.h" #include "params.h" +#include "hash-table.h" /* Possible lattice values. */ @@ -1687,11 +1688,17 @@ evaluate_stmt (gimple stmt) return val; } +typedef hash_table <gimple_statement_d, typed_pointer_hash<gimple_statement_d>, + typed_pointer_equal<gimple_statement_d>, + typed_null_remove<gimple_statement_d> > + gimple_htab; + /* Given a BUILT_IN_STACK_SAVE value SAVED_VAL, insert a clobber of VAR before each matching BUILT_IN_STACK_RESTORE. Mark visited phis in VISITED. */ static void -insert_clobber_before_stack_restore (tree saved_val, tree var, htab_t *visited) +insert_clobber_before_stack_restore (tree saved_val, tree var, + gimple_htab *visited) { gimple stmt, clobber_stmt; tree clobber; @@ -1711,10 +1718,10 @@ insert_clobber_before_stack_restore (tree saved_val, tree var, htab_t *visited) } else if (gimple_code (stmt) == GIMPLE_PHI) { - if (*visited == NULL) - *visited = htab_create (10, htab_hash_pointer, htab_eq_pointer, NULL); + if (!visited->is_created ()) + visited->create (10); - slot = (gimple *)htab_find_slot (*visited, stmt, INSERT); + slot = visited->find_slot (stmt, INSERT); if (*slot != NULL) continue; @@ -1757,7 +1764,7 @@ insert_clobbers_for_var (gimple_stmt_iterator i, tree var) { gimple stmt; tree saved_val; - htab_t visited = NULL; + gimple_htab visited; for (; !gsi_end_p (i); gsi_prev_dom_bb_nondebug (&i)) { @@ -1774,8 +1781,8 @@ insert_clobbers_for_var (gimple_stmt_iterator i, tree var) break; } - if (visited != NULL) - htab_delete (visited); + if (visited.is_created ()) + visited.dispose (); } /* Detects a __builtin_alloca_with_align with constant size argument. Declares diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c index f4f5eb3..c8557ac 100644 --- a/gcc/tree-ssa-coalesce.c +++ b/gcc/tree-ssa-coalesce.c @@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "bitmap.h" #include "dumpfile.h" #include "tree-flow.h" -#include "hashtab.h" +#include "hash-table.h" #include "tree-ssa-live.h" #include "diagnostic-core.h" @@ -1258,22 +1258,19 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl, } } -/* Returns a hash code for P. */ +/* Returns a hash code for N. */ -static hashval_t -hash_ssa_name_by_var (const void *p) +inline hashval_t +hash_ssa_name_by_var (const_tree n) { - const_tree n = (const_tree) p; return (hashval_t) htab_hash_pointer (SSA_NAME_VAR (n)); } -/* Returns nonzero if P1 and P2 are equal. */ +/* Returns nonzero if N1 and N2 are equal. */ -static int -eq_ssa_name_by_var (const void *p1, const void *p2) +inline int +eq_ssa_name_by_var (const_tree n1, const_tree n2) { - const_tree n1 = (const_tree) p1; - const_tree n2 = (const_tree) p2; return SSA_NAME_VAR (n1) == SSA_NAME_VAR (n2); } @@ -1289,7 +1286,9 @@ coalesce_ssa_name (void) bitmap used_in_copies = BITMAP_ALLOC (NULL); var_map map; unsigned int i; - static htab_t ssa_name_hash; + static hash_table <tree_node, hash_ssa_name_by_var, eq_ssa_name_by_var, + typed_null_remove<tree_node> > + ssa_name_hash; cl = create_coalesce_list (); map = create_outofssa_var_map (cl, used_in_copies); @@ -1298,8 +1297,7 @@ coalesce_ssa_name (void) so debug info remains undisturbed. */ if (!optimize) { - ssa_name_hash = htab_create (10, hash_ssa_name_by_var, - eq_ssa_name_by_var, NULL); + ssa_name_hash.create (10); for (i = 1; i < num_ssa_names; i++) { tree a = ssa_name (i); @@ -1309,7 +1307,7 @@ coalesce_ssa_name (void) && !DECL_IGNORED_P (SSA_NAME_VAR (a)) && (!has_zero_uses (a) || !SSA_NAME_IS_DEFAULT_DEF (a))) { - tree *slot = (tree *) htab_find_slot (ssa_name_hash, a, INSERT); + tree *slot = ssa_name_hash.find_slot (a, INSERT); if (!*slot) *slot = a; @@ -1322,7 +1320,7 @@ coalesce_ssa_name (void) } } } - htab_delete (ssa_name_hash); + ssa_name_hash.dispose (); } if (dump_file && (dump_flags & TDF_DETAILS)) dump_var_map (dump_file, map); diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index f70dcc8..d3795be 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1734,7 +1734,8 @@ dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, /* Push a marker on the stacks of local information so that we know how far to unwind when we finalize this block. */ - VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL); + VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, + (expr_hash_elt_t)NULL); VEC_safe_push (tree, heap, const_and_copies_stack, NULL_TREE); record_equivalences_from_incoming_edge (bb); @@ -1745,7 +1746,8 @@ dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, /* Create equivalences from redundant PHIs. PHIs are only truly redundant when they exist in the same block, so push another marker and unwind right afterwards. */ - VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL); + VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, + (expr_hash_elt_t)NULL); for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) eliminate_redundant_computations (&gsi); remove_local_expressions_from_table (); @@ -1800,7 +1802,8 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb) /* Push a marker onto the available expression stack so that we unwind any expressions related to the TRUE arm before processing the false arm below. */ - VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL); + VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, + (expr_hash_elt_t)NULL); VEC_safe_push (tree, heap, const_and_copies_stack, NULL_TREE); edge_info = (struct edge_info *) true_edge->aux; diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 9e0c40a..c0a8252 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -3120,7 +3120,7 @@ multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, enum machine_mode mode, TODO -- there must be some better way. This all is quite crude. */ -typedef struct +typedef struct address_cost_data_s { HOST_WIDE_INT min_offset, max_offset; unsigned costs[2][2][2][2]; diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 3571479..51d9e02 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "tree-flow.h" #include "gimple.h" -#include "hashtab.h" +#include "hash-table.h" #include "tree-iterator.h" #include "alloc-pool.h" #include "obstack.h" @@ -177,12 +177,11 @@ typedef struct pre_expr_d #define PRE_EXPR_REFERENCE(e) (e)->u.reference #define PRE_EXPR_CONSTANT(e) (e)->u.constant -static int -pre_expr_eq (const void *p1, const void *p2) -{ - const struct pre_expr_d *e1 = (const struct pre_expr_d *) p1; - const struct pre_expr_d *e2 = (const struct pre_expr_d *) p2; +/* Compare E1 and E1 for equality. */ +inline int +ssa_pre_expr_eq (const struct pre_expr_d *e1, const struct pre_expr_d *e2) +{ if (e1->kind != e2->kind) return false; @@ -203,10 +202,11 @@ pre_expr_eq (const void *p1, const void *p2) } } -static hashval_t -pre_expr_hash (const void *p1) +/* Hash E. */ + +inline hashval_t +ssa_pre_expr_hash (const struct pre_expr_d *e) { - const struct pre_expr_d *e = (const struct pre_expr_d *) p1; switch (e->kind) { case CONSTANT: @@ -222,7 +222,6 @@ pre_expr_hash (const void *p1) } } - /* Next global expression id number. */ static unsigned int next_expression_id; @@ -230,7 +229,9 @@ static unsigned int next_expression_id; DEF_VEC_P (pre_expr); DEF_VEC_ALLOC_P (pre_expr, heap); static VEC(pre_expr, heap) *expressions; -static htab_t expression_to_id; +static hash_table <pre_expr_d, ssa_pre_expr_hash, ssa_pre_expr_eq, + typed_null_remove <pre_expr_d> > + expression_to_id; static VEC(unsigned, heap) *name_to_id; /* Allocate an expression id for EXPR. */ @@ -238,7 +239,7 @@ static VEC(unsigned, heap) *name_to_id; static inline unsigned int alloc_expression_id (pre_expr expr) { - void **slot; + struct pre_expr_d **slot; /* Make sure we won't overflow. */ gcc_assert (next_expression_id + 1 > next_expression_id); expr->id = next_expression_id++; @@ -257,7 +258,7 @@ alloc_expression_id (pre_expr expr) } else { - slot = htab_find_slot (expression_to_id, expr, INSERT); + slot = expression_to_id.find_slot (expr, INSERT); gcc_assert (!*slot); *slot = expr; } @@ -275,7 +276,7 @@ get_expression_id (const pre_expr expr) static inline unsigned int lookup_expression_id (const pre_expr expr) { - void **slot; + struct pre_expr_d **slot; if (expr->kind == NAME) { @@ -286,7 +287,7 @@ lookup_expression_id (const pre_expr expr) } else { - slot = htab_find_slot (expression_to_id, expr, NO_INSERT); + slot = expression_to_id.find_slot (expr, NO_INSERT); if (!slot) return 0; return ((pre_expr)*slot)->id; @@ -479,11 +480,6 @@ static bitmap need_eh_cleanup; /* Set of blocks with statements that have had their AB properties changed. */ static bitmap need_ab_cleanup; -/* The phi_translate_table caches phi translations for a given - expression and predecessor. */ - -static htab_t phi_translate_table; - /* A three tuple {e, pred, v} used to cache phi translations in the phi_translate_table. */ @@ -506,21 +502,19 @@ typedef const struct expr_pred_trans_d *const_expr_pred_trans_t; /* Return the hash value for a phi translation table entry. */ -static hashval_t -expr_pred_trans_hash (const void *p) +inline hashval_t +ssa_expr_pred_trans_hash (const expr_pred_trans_d *ve) { - const_expr_pred_trans_t const ve = (const_expr_pred_trans_t) p; return ve->hashcode; } /* Return true if two phi translation table entries are the same. P1 and P2 should point to the expr_pred_trans_t's to be compared.*/ -static int -expr_pred_trans_eq (const void *p1, const void *p2) +inline int +ssa_expr_pred_trans_eq (const expr_pred_trans_d *ve1, + const expr_pred_trans_d *ve2) { - const_expr_pred_trans_t const ve1 = (const_expr_pred_trans_t) p1; - const_expr_pred_trans_t const ve2 = (const_expr_pred_trans_t) p2; basic_block b1 = ve1->pred; basic_block b2 = ve2->pred; @@ -528,9 +522,17 @@ expr_pred_trans_eq (const void *p1, const void *p2) be equal. */ if (b1 != b2) return false; - return pre_expr_eq (ve1->e, ve2->e); + return ssa_pre_expr_eq (ve1->e, ve2->e); } +/* The phi_translate_table caches phi translations for a given + expression and predecessor. */ + +static hash_table <expr_pred_trans_d, ssa_expr_pred_trans_hash, + ssa_expr_pred_trans_eq, + typed_free_remove <expr_pred_trans_d> > + phi_translate_table; + /* Search in the phi translation table for the translation of expression E in basic block PRED. Return the translated value, if found, NULL otherwise. */ @@ -538,18 +540,18 @@ expr_pred_trans_eq (const void *p1, const void *p2) static inline pre_expr phi_trans_lookup (pre_expr e, basic_block pred) { - void **slot; + expr_pred_trans_t *slot; struct expr_pred_trans_d ept; ept.e = e; ept.pred = pred; - ept.hashcode = iterative_hash_hashval_t (pre_expr_hash (e), pred->index); - slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode, + ept.hashcode = iterative_hash_hashval_t (ssa_pre_expr_hash (e), pred->index); + slot = phi_translate_table.find_slot_with_hash (&ept, ept.hashcode, NO_INSERT); if (!slot) return NULL; else - return ((expr_pred_trans_t) *slot)->v; + return (*slot)->v; } @@ -559,18 +561,18 @@ phi_trans_lookup (pre_expr e, basic_block pred) static inline void phi_trans_add (pre_expr e, pre_expr v, basic_block pred) { - void **slot; + expr_pred_trans_t *slot; expr_pred_trans_t new_pair = XNEW (struct expr_pred_trans_d); new_pair->e = e; new_pair->pred = pred; new_pair->v = v; - new_pair->hashcode = iterative_hash_hashval_t (pre_expr_hash (e), + new_pair->hashcode = iterative_hash_hashval_t (ssa_pre_expr_hash (e), pred->index); - slot = htab_find_slot_with_hash (phi_translate_table, new_pair, + slot = phi_translate_table.find_slot_with_hash (new_pair, new_pair->hashcode, INSERT); free (*slot); - *slot = (void *) new_pair; + *slot = new_pair; } @@ -1607,12 +1609,12 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, if (double_int_fits_in_shwi_p (off)) newop.off = off.low; } - VEC_replace (vn_reference_op_s, newoperands, j, &newop); + VEC_replace (vn_reference_op_s, newoperands, j, newop); /* If it transforms from an SSA_NAME to an address, fold with a preceding indirect reference. */ if (j > 0 && op[0] && TREE_CODE (op[0]) == ADDR_EXPR && VEC_index (vn_reference_op_s, - newoperands, j - 1)->opcode == MEM_REF) + newoperands, j - 1).opcode == MEM_REF) vn_reference_fold_indirect (&newoperands, &j); } if (i != VEC_length (vn_reference_op_s, operands)) @@ -2596,8 +2598,8 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref, unsigned int *operand, gimple_seq *stmts, gimple domstmt) { - vn_reference_op_t currop = VEC_index (vn_reference_op_s, ref->operands, - *operand); + vn_reference_op_t currop = &VEC_index (vn_reference_op_s, ref->operands, + *operand); tree genop; ++*operand; switch (currop->opcode) @@ -2674,8 +2676,8 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref, { pre_expr op0expr, op1expr; tree genop0 = NULL_TREE, genop1 = NULL_TREE; - vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands, - ++*operand); + vn_reference_op_t nextop = &VEC_index (vn_reference_op_s, ref->operands, + ++*operand); tree baseop = create_component_ref_by_pieces_1 (block, ref, operand, stmts, domstmt); if (!baseop) @@ -3493,7 +3495,7 @@ do_regular_insertion (basic_block block, basic_block dom) do_insertion = true; if (first_s == NULL) first_s = edoubleprime; - else if (!pre_expr_eq (first_s, edoubleprime)) + else if (!ssa_pre_expr_eq (first_s, edoubleprime)) all_same = false; } } @@ -4774,7 +4776,7 @@ init_pre (bool do_fre) next_expression_id = 1; expressions = NULL; - VEC_safe_push (pre_expr, heap, expressions, NULL); + VEC_safe_push (pre_expr, heap, expressions, (pre_expr)NULL); value_expressions = VEC_alloc (bitmap_set_t, heap, get_max_value_id () + 1); VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions, get_max_value_id() + 1); @@ -4797,11 +4799,8 @@ init_pre (bool do_fre) calculate_dominance_info (CDI_DOMINATORS); bitmap_obstack_initialize (&grand_bitmap_obstack); - phi_translate_table = htab_create (5110, expr_pred_trans_hash, - expr_pred_trans_eq, free); - expression_to_id = htab_create (num_ssa_names * 3, - pre_expr_hash, - pre_expr_eq, NULL); + phi_translate_table.create (5110); + expression_to_id.create (num_ssa_names * 3); bitmap_set_pool = create_alloc_pool ("Bitmap sets", sizeof (struct bitmap_set), 30); pre_expr_pool = create_alloc_pool ("pre_expr nodes", @@ -4833,8 +4832,8 @@ fini_pre (bool do_fre) bitmap_obstack_release (&grand_bitmap_obstack); free_alloc_pool (bitmap_set_pool); free_alloc_pool (pre_expr_pool); - htab_delete (phi_translate_table); - htab_delete (expression_to_id); + phi_translate_table.dispose (); + expression_to_id.dispose (); VEC_free (unsigned, heap, name_to_id); free_aux_for_blocks (); diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 9c85391..2b1298d 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -962,7 +962,7 @@ static VEC (oecount, heap) *cvec; static hashval_t oecount_hash (const void *p) { - const oecount *c = VEC_index (oecount, cvec, (size_t)p - 42); + const oecount *c = &VEC_index (oecount, cvec, (size_t)p - 42); return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode; } @@ -971,8 +971,8 @@ oecount_hash (const void *p) static int oecount_eq (const void *p1, const void *p2) { - const oecount *c1 = VEC_index (oecount, cvec, (size_t)p1 - 42); - const oecount *c2 = VEC_index (oecount, cvec, (size_t)p2 - 42); + const oecount *c1 = &VEC_index (oecount, cvec, (size_t)p1 - 42); + const oecount *c2 = &VEC_index (oecount, cvec, (size_t)p2 - 42); return (c1->oecode == c2->oecode && c1->op == c2->op); } @@ -1354,7 +1354,7 @@ undistribute_ops_list (enum tree_code opcode, else { VEC_pop (oecount, cvec); - VEC_index (oecount, cvec, (size_t)*slot - 42)->cnt++; + VEC_index (oecount, cvec, (size_t)*slot - 42).cnt++; } } } @@ -1381,7 +1381,7 @@ undistribute_ops_list (enum tree_code opcode, candidates2 = sbitmap_alloc (length); while (!VEC_empty (oecount, cvec)) { - oecount *c = VEC_last (oecount, cvec); + oecount *c = &VEC_last (oecount, cvec); if (c->cnt < 2) break; @@ -3190,7 +3190,7 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops) fputs ("Multiplying by cached product ", dump_file); for (elt = j; elt < vec_len; elt++) { - rf = VEC_index (repeat_factor, repeat_factor_vec, elt); + rf = &VEC_index (repeat_factor, repeat_factor_vec, elt); print_generic_expr (dump_file, rf->factor, 0); if (elt < vec_len - 1) fputs (" * ", dump_file); @@ -3216,7 +3216,7 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops) dump_file); for (elt = j; elt < vec_len; elt++) { - rf = VEC_index (repeat_factor, repeat_factor_vec, elt); + rf = &VEC_index (repeat_factor, repeat_factor_vec, elt); print_generic_expr (dump_file, rf->factor, 0); if (elt < vec_len - 1) fputs (" * ", dump_file); @@ -3250,7 +3250,7 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops) fputs ("Building __builtin_pow call for (", dump_file); for (elt = j; elt < vec_len; elt++) { - rf = VEC_index (repeat_factor, repeat_factor_vec, elt); + rf = &VEC_index (repeat_factor, repeat_factor_vec, elt); print_generic_expr (dump_file, rf->factor, 0); if (elt < vec_len - 1) fputs (" * ", dump_file); @@ -3275,8 +3275,8 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops) { tree op1, op2; - rf1 = VEC_index (repeat_factor, repeat_factor_vec, ii); - rf2 = VEC_index (repeat_factor, repeat_factor_vec, ii + 1); + rf1 = &VEC_index (repeat_factor, repeat_factor_vec, ii); + rf2 = &VEC_index (repeat_factor, repeat_factor_vec, ii + 1); /* Init the last factor's representative to be itself. */ if (!rf2->repr) @@ -3300,7 +3300,7 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops) /* Form a call to __builtin_powi for the maximum product just formed, raised to the power obtained earlier. */ - rf1 = VEC_index (repeat_factor, repeat_factor_vec, j); + rf1 = &VEC_index (repeat_factor, repeat_factor_vec, j); iter_result = make_temp_ssa_name (type, NULL, "reassocpow"); pow_stmt = gimple_build_call (powi_fndecl, 2, rf1->repr, build_int_cst (integer_type_node, @@ -3333,7 +3333,7 @@ attempt_builtin_powi (gimple stmt, VEC(operand_entry_t, heap) **ops) unsigned k = power; unsigned n; - rf1 = VEC_index (repeat_factor, repeat_factor_vec, i); + rf1 = &VEC_index (repeat_factor, repeat_factor_vec, i); rf1->count -= power; FOR_EACH_VEC_ELT_REVERSE (operand_entry_t, *ops, n, oe) diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index b7e343b..5756df3 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -775,7 +775,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, alias_set_type base_alias_set = -1; /* First get the final access size from just the outermost expression. */ - op = VEC_index (vn_reference_op_s, ops, 0); + op = &VEC_index (vn_reference_op_s, ops, 0); if (op->opcode == COMPONENT_REF) size_tree = DECL_SIZE (op->op0); else if (op->opcode == BIT_FIELD_REF) @@ -815,7 +815,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, && op->op0 && DECL_P (TREE_OPERAND (op->op0, 0))) { - vn_reference_op_t pop = VEC_index (vn_reference_op_s, ops, i-1); + vn_reference_op_t pop = &VEC_index (vn_reference_op_s, ops, i-1); base = TREE_OPERAND (op->op0, 0); if (pop->off == -1) { @@ -1004,8 +1004,8 @@ vn_reference_fold_indirect (VEC (vn_reference_op_s, heap) **ops, unsigned int *i_p) { unsigned int i = *i_p; - vn_reference_op_t op = VEC_index (vn_reference_op_s, *ops, i); - vn_reference_op_t mem_op = VEC_index (vn_reference_op_s, *ops, i - 1); + vn_reference_op_t op = &VEC_index (vn_reference_op_s, *ops, i); + vn_reference_op_t mem_op = &VEC_index (vn_reference_op_s, *ops, i - 1); tree addr_base; HOST_WIDE_INT addr_offset; @@ -1036,8 +1036,8 @@ vn_reference_maybe_forwprop_address (VEC (vn_reference_op_s, heap) **ops, unsigned int *i_p) { unsigned int i = *i_p; - vn_reference_op_t op = VEC_index (vn_reference_op_s, *ops, i); - vn_reference_op_t mem_op = VEC_index (vn_reference_op_s, *ops, i - 1); + vn_reference_op_t op = &VEC_index (vn_reference_op_s, *ops, i); + vn_reference_op_t mem_op = &VEC_index (vn_reference_op_s, *ops, i - 1); gimple def_stmt; enum tree_code code; double_int off; @@ -1114,7 +1114,7 @@ fully_constant_vn_reference_p (vn_reference_t ref) /* Try to simplify the translated expression if it is a call to a builtin function with at most two arguments. */ - op = VEC_index (vn_reference_op_s, operands, 0); + op = &VEC_index (vn_reference_op_s, operands, 0); if (op->opcode == CALL_EXPR && TREE_CODE (op->op0) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (op->op0, 0)) == FUNCTION_DECL @@ -1124,9 +1124,9 @@ fully_constant_vn_reference_p (vn_reference_t ref) { vn_reference_op_t arg0, arg1 = NULL; bool anyconst = false; - arg0 = VEC_index (vn_reference_op_s, operands, 1); + arg0 = &VEC_index (vn_reference_op_s, operands, 1); if (VEC_length (vn_reference_op_s, operands) > 2) - arg1 = VEC_index (vn_reference_op_s, operands, 2); + arg1 = &VEC_index (vn_reference_op_s, operands, 2); if (TREE_CODE_CLASS (arg0->opcode) == tcc_constant || (arg0->opcode == ADDR_EXPR && is_gimple_min_invariant (arg0->op0))) @@ -1158,7 +1158,7 @@ fully_constant_vn_reference_p (vn_reference_t ref) && VEC_length (vn_reference_op_s, operands) == 2) { vn_reference_op_t arg0; - arg0 = VEC_index (vn_reference_op_s, operands, 1); + arg0 = &VEC_index (vn_reference_op_s, operands, 1); if (arg0->opcode == STRING_CST && (TYPE_MODE (op->type) == TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0->op0)))) @@ -1226,12 +1226,12 @@ valueize_refs_1 (VEC (vn_reference_op_s, heap) *orig, bool *valueized_anything) && vro->op0 && TREE_CODE (vro->op0) == ADDR_EXPR && VEC_index (vn_reference_op_s, - orig, i - 1)->opcode == MEM_REF) + orig, i - 1).opcode == MEM_REF) vn_reference_fold_indirect (&orig, &i); else if (i > 0 && vro->opcode == SSA_NAME && VEC_index (vn_reference_op_s, - orig, i - 1)->opcode == MEM_REF) + orig, i - 1).opcode == MEM_REF) vn_reference_maybe_forwprop_address (&orig, &i); /* If it transforms a non-constant ARRAY_REF into a constant one, adjust the constant offset. */ @@ -1624,9 +1624,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) i = VEC_length (vn_reference_op_s, vr->operands) - 1; j = VEC_length (vn_reference_op_s, lhs_ops) - 1; while (j >= 0 && i >= 0 - && vn_reference_op_eq (VEC_index (vn_reference_op_s, - vr->operands, i), - VEC_index (vn_reference_op_s, lhs_ops, j))) + && vn_reference_op_eq (&VEC_index (vn_reference_op_s, + vr->operands, i), + &VEC_index (vn_reference_op_s, lhs_ops, j))) { i--; j--; @@ -1639,10 +1639,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) don't care here - further lookups with the rewritten operands will simply fail if we messed up types too badly. */ if (j == 0 && i >= 0 - && VEC_index (vn_reference_op_s, lhs_ops, 0)->opcode == MEM_REF - && VEC_index (vn_reference_op_s, lhs_ops, 0)->off != -1 - && (VEC_index (vn_reference_op_s, lhs_ops, 0)->off - == VEC_index (vn_reference_op_s, vr->operands, i)->off)) + && VEC_index (vn_reference_op_s, lhs_ops, 0).opcode == MEM_REF + && VEC_index (vn_reference_op_s, lhs_ops, 0).off != -1 + && (VEC_index (vn_reference_op_s, lhs_ops, 0).off + == VEC_index (vn_reference_op_s, vr->operands, i).off)) i--, j--; /* i now points to the first additional op. @@ -1669,7 +1669,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) VEC_truncate (vn_reference_op_s, vr->operands, i + 1 + VEC_length (vn_reference_op_s, rhs)); FOR_EACH_VEC_ELT (vn_reference_op_s, rhs, j, vro) - VEC_replace (vn_reference_op_s, vr->operands, i + 1 + j, vro); + VEC_replace (vn_reference_op_s, vr->operands, i + 1 + j, *vro); VEC_free (vn_reference_op_s, heap, rhs); vr->operands = valueize_refs (vr->operands); vr->hashcode = vn_reference_compute_hash (vr); @@ -1807,12 +1807,12 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_) op.opcode = MEM_REF; op.op0 = build_int_cst (ptr_type_node, at - rhs_offset); op.off = at - lhs_offset + rhs_offset; - VEC_replace (vn_reference_op_s, vr->operands, 0, &op); + VEC_replace (vn_reference_op_s, vr->operands, 0, op); op.type = TREE_TYPE (rhs); op.opcode = TREE_CODE (rhs); op.op0 = rhs; op.off = -1; - VEC_replace (vn_reference_op_s, vr->operands, 1, &op); + VEC_replace (vn_reference_op_s, vr->operands, 1, op); vr->hashcode = vn_reference_compute_hash (vr); /* Adjust *ref from the new operands. */ @@ -3746,7 +3746,7 @@ start_over: /* Restore the last use walker and continue walking there. */ use = name; name = VEC_pop (tree, namevec); - memcpy (&iter, VEC_last (ssa_op_iter, itervec), + memcpy (&iter, &VEC_last (ssa_op_iter, itervec), sizeof (ssa_op_iter)); VEC_pop (ssa_op_iter, itervec); goto continue_walking; diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 6c60e002..162502e 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -2927,7 +2927,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, for (j = 0; j < n; j++) { varinfo_t curr; - c = *VEC_index (ce_s, *results, j); + c = VEC_index (ce_s, *results, j); curr = get_varinfo (c.var); if (c.type == ADDRESSOF @@ -2989,7 +2989,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, else c.offset = rhsoffset; - VEC_replace (ce_s, *results, j, &c); + VEC_replace (ce_s, *results, j, c); } } @@ -3058,7 +3058,7 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results, adding the required subset of sub-fields below. */ get_constraint_for_1 (t, results, true, lhs_p); gcc_assert (VEC_length (ce_s, *results) == 1); - result = VEC_last (ce_s, *results); + result = &VEC_last (ce_s, *results); if (result->type == SCALAR && get_varinfo (result->var)->is_full_var) @@ -3284,13 +3284,13 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p, if (address_p) return; - cs = *VEC_last (ce_s, *results); + cs = VEC_last (ce_s, *results); if (cs.type == DEREF && type_can_have_subvars (TREE_TYPE (t))) { /* For dereferences this means we have to defer it to solving time. */ - VEC_last (ce_s, *results)->offset = UNKNOWN_OFFSET; + VEC_last (ce_s, *results).offset = UNKNOWN_OFFSET; return; } if (cs.type != SCALAR) @@ -3451,8 +3451,8 @@ do_structure_copy (tree lhsop, tree rhsop) get_constraint_for (lhsop, &lhsc); get_constraint_for_rhs (rhsop, &rhsc); - lhsp = VEC_index (ce_s, lhsc, 0); - rhsp = VEC_index (ce_s, rhsc, 0); + lhsp = &VEC_index (ce_s, lhsc, 0); + rhsp = &VEC_index (ce_s, rhsc, 0); if (lhsp->type == DEREF || (lhsp->type == ADDRESSOF && lhsp->var == anything_id) || rhsp->type == DEREF) @@ -3481,7 +3481,7 @@ do_structure_copy (tree lhsop, tree rhsop) for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp);) { varinfo_t lhsv, rhsv; - rhsp = VEC_index (ce_s, rhsc, k); + rhsp = &VEC_index (ce_s, rhsc, k); lhsv = get_varinfo (lhsp->var); rhsv = get_varinfo (rhsp->var); if (lhsv->may_have_pointers @@ -4377,7 +4377,7 @@ find_func_aliases_for_call (gimple t) lhs = get_function_part_constraint (fi, fi_parm_base + j); while (VEC_length (ce_s, rhsc) != 0) { - rhsp = VEC_last (ce_s, rhsc); + rhsp = &VEC_last (ce_s, rhsc); process_constraint (new_constraint (lhs, *rhsp)); VEC_pop (ce_s, rhsc); } @@ -4399,7 +4399,7 @@ find_func_aliases_for_call (gimple t) VEC(ce_s, heap) *tem = NULL; VEC_safe_push (ce_s, heap, tem, &rhs); do_deref (&tem); - rhs = *VEC_index (ce_s, tem, 0); + rhs = VEC_index (ce_s, tem, 0); VEC_free(ce_s, heap, tem); } FOR_EACH_VEC_ELT (ce_s, lhsc, j, lhsp) @@ -4471,7 +4471,7 @@ find_func_aliases (gimple origt) struct constraint_expr *c2; while (VEC_length (ce_s, rhsc) > 0) { - c2 = VEC_last (ce_s, rhsc); + c2 = &VEC_last (ce_s, rhsc); process_constraint (new_constraint (*c, *c2)); VEC_pop (ce_s, rhsc); } @@ -5158,7 +5158,7 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, bool must_have_pointers_p; if (!VEC_empty (fieldoff_s, *fieldstack)) - pair = VEC_last (fieldoff_s, *fieldstack); + pair = &VEC_last (fieldoff_s, *fieldstack); /* If there isn't anything at offset zero, create sth. */ if (!pair diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c index 8d55030..ec644ee 100644 --- a/gcc/tree-ssa-tail-merge.c +++ b/gcc/tree-ssa-tail-merge.c @@ -193,7 +193,7 @@ along with GCC; see the file COPYING3. If not see #include "bitmap.h" #include "tree-ssa-alias.h" #include "params.h" -#include "hashtab.h" +#include "hash-table.h" #include "gimple-pretty-print.h" #include "tree-ssa-sccvn.h" #include "tree-dump.h" @@ -368,11 +368,10 @@ same_succ_print (FILE *file, const same_succ e) /* Prints same_succ VE to VFILE. */ -static int -same_succ_print_traverse (void **ve, void *vfile) +inline int +ssa_same_succ_print_traverse (same_succ *pe, FILE *file) { - const same_succ e = *((const same_succ *)ve); - FILE *file = ((FILE*)vfile); + const same_succ e = *pe; same_succ_print (file, e); return 1; } @@ -416,10 +415,9 @@ stmt_update_dep_bb (gimple stmt) /* Calculates hash value for same_succ VE. */ -static hashval_t -same_succ_hash (const void *ve) +hashval_t +ssa_same_succ_hash (const_same_succ e) { - const_same_succ e = (const_same_succ)ve; hashval_t hashval = bitmap_hash (e->succs); int flags; unsigned int i; @@ -515,11 +513,9 @@ inverse_flags (const_same_succ e1, const_same_succ e2) /* Compares SAME_SUCCs VE1 and VE2. */ -static int -same_succ_equal (const void *ve1, const void *ve2) +int +ssa_same_succ_equal (const_same_succ e1, const_same_succ e2) { - const_same_succ e1 = (const_same_succ)ve1; - const_same_succ e2 = (const_same_succ)ve2; unsigned int i, first1, first2; gimple_stmt_iterator gsi1, gsi2; gimple s1, s2; @@ -590,17 +586,15 @@ same_succ_alloc (void) /* Delete same_succ VE. */ -static void -same_succ_delete (void *ve) +inline void +ssa_same_succ_delete (same_succ e) { - same_succ e = (same_succ)ve; - BITMAP_FREE (e->bbs); BITMAP_FREE (e->succs); BITMAP_FREE (e->inverse); VEC_free (int, heap, e->succ_flags); - XDELETE (ve); + XDELETE (e); } /* Reset same_succ SAME. */ @@ -616,7 +610,9 @@ same_succ_reset (same_succ same) /* Hash table with all same_succ entries. */ -static htab_t same_succ_htab; +static hash_table <struct same_succ_def, ssa_same_succ_hash, + ssa_same_succ_equal, ssa_same_succ_delete> + same_succ_htab; /* Array that is used to store the edge flags for a successor. */ @@ -637,7 +633,7 @@ extern void debug_same_succ (void); DEBUG_FUNCTION void debug_same_succ ( void) { - htab_traverse (same_succ_htab, same_succ_print_traverse, stderr); + same_succ_htab.traverse <FILE *, ssa_same_succ_print_traverse> (stderr); } DEF_VEC_P (same_succ); @@ -696,10 +692,9 @@ find_same_succ_bb (basic_block bb, same_succ *same_p) EXECUTE_IF_SET_IN_BITMAP (same->succs, 0, j, bj) VEC_safe_push (int, heap, same->succ_flags, same_succ_edge_flags[j]); - same->hashval = same_succ_hash (same); + same->hashval = ssa_same_succ_hash (same); - slot = (same_succ *) htab_find_slot_with_hash (same_succ_htab, same, - same->hashval, INSERT); + slot = same_succ_htab.find_slot_with_hash (same, same->hashval, INSERT); if (*slot == NULL) { *slot = same; @@ -733,7 +728,7 @@ find_same_succ (void) same = same_succ_alloc (); } - same_succ_delete (same); + ssa_same_succ_delete (same); } /* Initializes worklist administration. */ @@ -742,9 +737,7 @@ static void init_worklist (void) { alloc_aux_for_blocks (sizeof (struct aux_bb_info)); - same_succ_htab - = htab_create (n_basic_blocks, same_succ_hash, same_succ_equal, - same_succ_delete); + same_succ_htab.create (n_basic_blocks); same_succ_edge_flags = XCNEWVEC (int, last_basic_block); deleted_bbs = BITMAP_ALLOC (NULL); deleted_bb_preds = BITMAP_ALLOC (NULL); @@ -764,8 +757,7 @@ static void delete_worklist (void) { free_aux_for_blocks (); - htab_delete (same_succ_htab); - same_succ_htab = NULL; + same_succ_htab.dispose (); XDELETEVEC (same_succ_edge_flags); same_succ_edge_flags = NULL; BITMAP_FREE (deleted_bbs); @@ -795,7 +787,7 @@ same_succ_flush_bb (basic_block bb) same_succ same = BB_SAME_SUCC (bb); BB_SAME_SUCC (bb) = NULL; if (bitmap_single_bit_set_p (same->bbs)) - htab_remove_elt_with_hash (same_succ_htab, same, same->hashval); + same_succ_htab.remove_elt_with_hash (same, same->hashval); else bitmap_clear_bit (same->bbs, bb->index); } @@ -868,7 +860,7 @@ update_worklist (void) if (same == NULL) same = same_succ_alloc (); } - same_succ_delete (same); + ssa_same_succ_delete (same); bitmap_clear (deleted_bb_preds); } @@ -1637,7 +1629,7 @@ tail_merge_optimize (unsigned int todo) if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "htab collision / search: %f\n", - htab_collisions (same_succ_htab)); + same_succ_htab.collisions ()); if (nr_bbs_removed_total > 0) { diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index a0536db..3ecb303 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-flow.h" #include "dumpfile.h" #include "cfgloop.h" +#include "hash-table.h" /* Given a block B, update the CFG and SSA graph to reflect redirecting one or more in-edges to B to instead reach the destination of an @@ -126,11 +127,8 @@ struct redirection_data struct el *incoming_edges; }; -/* Main data structure to hold information for duplicates of BB. */ -static htab_t redirection_data; - /* Data structure of information to pass to hash table traversal routines. */ -struct local_info +struct ssa_local_info_t { /* The current block we are working on. */ basic_block bb; @@ -220,24 +218,32 @@ create_block_for_threading (basic_block bb, struct redirection_data *rd) } /* Hashing and equality routines for our hash table. */ -static hashval_t -redirection_data_hash (const void *p) +inline hashval_t +ssa_redirection_data_hash (const struct redirection_data *p) { - edge e = ((const struct redirection_data *)p)->outgoing_edge; + edge e = p->outgoing_edge; return e->dest->index; } -static int -redirection_data_eq (const void *p1, const void *p2) +inline int +ssa_redirection_data_eq (const struct redirection_data *p1, + const struct redirection_data *p2) { - edge e1 = ((const struct redirection_data *)p1)->outgoing_edge; - edge e2 = ((const struct redirection_data *)p2)->outgoing_edge; - edge e3 = ((const struct redirection_data *)p1)->intermediate_edge; - edge e4 = ((const struct redirection_data *)p2)->intermediate_edge; + edge e1 = p1->outgoing_edge; + edge e2 = p2->outgoing_edge; + edge e3 = p1->intermediate_edge; + edge e4 = p2->intermediate_edge; return e1 == e2 && e3 == e4; } +/* Main data structure to hold information for duplicates of BB. */ + +static hash_table <struct redirection_data, ssa_redirection_data_hash, + ssa_redirection_data_eq, + typed_free_remove<struct redirection_data> > + redirection_data; + /* Given an outgoing edge E lookup and return its entry in our hash table. If INSERT is true, then we insert the entry into the hash table if @@ -247,7 +253,7 @@ redirection_data_eq (const void *p1, const void *p2) static struct redirection_data * lookup_redirection_data (edge e, enum insert_option insert) { - void **slot; + struct redirection_data **slot; struct redirection_data *elt; /* Build a hash table element so we can see if E is already @@ -259,7 +265,7 @@ lookup_redirection_data (edge e, enum insert_option insert) elt->dup_block = NULL; elt->incoming_edges = NULL; - slot = htab_find_slot (redirection_data, elt, insert); + slot = redirection_data.find_slot (elt, insert); /* This will only happen if INSERT is false and the entry is not in the hash table. */ @@ -273,7 +279,7 @@ lookup_redirection_data (edge e, enum insert_option insert) INSERT is true. */ if (*slot == NULL) { - *slot = (void *)elt; + *slot = elt; elt->incoming_edges = XNEW (struct el); elt->incoming_edges->e = e; elt->incoming_edges->next = NULL; @@ -287,7 +293,7 @@ lookup_redirection_data (edge e, enum insert_option insert) free (elt); /* Get the entry stored in the hash table. */ - elt = (struct redirection_data *) *slot; + elt = *slot; /* If insertion was requested, then we need to add INCOMING_EDGE to the list of incoming edges associated with E. */ @@ -375,9 +381,9 @@ create_edge_and_update_destination_phis (struct redirection_data *rd, /* Wire up the outgoing edges from the duplicate block and update any PHIs as needed. */ -static void -fix_duplicate_block_edges (struct redirection_data *rd, - struct local_info *local_info) +void +ssa_fix_duplicate_block_edges (struct redirection_data *rd, + ssa_local_info_t *local_info) { /* If we were threading through an joiner block, then we want to keep its control statement and redirect an outgoing edge. @@ -412,11 +418,11 @@ fix_duplicate_block_edges (struct redirection_data *rd, } /* Hash table traversal callback routine to create duplicate blocks. */ -static int -create_duplicates (void **slot, void *data) +int +ssa_create_duplicates (struct redirection_data **slot, + ssa_local_info_t *local_info) { - struct redirection_data *rd = (struct redirection_data *) *slot; - struct local_info *local_info = (struct local_info *)data; + struct redirection_data *rd = *slot; /* Create a template block if we have not done so already. Otherwise use the template to create a new block. */ @@ -435,7 +441,7 @@ create_duplicates (void **slot, void *data) /* Go ahead and wire up outgoing edges and update PHIs for the duplicate block. */ - fix_duplicate_block_edges (rd, local_info); + ssa_fix_duplicate_block_edges (rd, local_info); } /* Keep walking the hash table. */ @@ -446,11 +452,11 @@ create_duplicates (void **slot, void *data) block creation. This hash table traversal callback creates the outgoing edge for the template block. */ -static int -fixup_template_block (void **slot, void *data) +inline int +ssa_fixup_template_block (struct redirection_data **slot, + ssa_local_info_t *local_info) { - struct redirection_data *rd = (struct redirection_data *) *slot; - struct local_info *local_info = (struct local_info *)data; + struct redirection_data *rd = *slot; /* If this is the template block halt the traversal after updating it appropriately. @@ -461,7 +467,7 @@ fixup_template_block (void **slot, void *data) a new outgoing edge. In both cases we may need to update PHIs. */ if (rd->dup_block && rd->dup_block == local_info->template_block) { - fix_duplicate_block_edges (rd, local_info); + ssa_fix_duplicate_block_edges (rd, local_info); return 0; } @@ -471,11 +477,11 @@ fixup_template_block (void **slot, void *data) /* Hash table traversal callback to redirect each incoming edge associated with this hash table element to its new destination. */ -static int -redirect_edges (void **slot, void *data) +int +ssa_redirect_edges (struct redirection_data **slot, + ssa_local_info_t *local_info) { - struct redirection_data *rd = (struct redirection_data *) *slot; - struct local_info *local_info = (struct local_info *)data; + struct redirection_data *rd = *slot; struct el *next, *el; /* Walk over all the incoming edges associated associated with this @@ -594,17 +600,14 @@ thread_block (basic_block bb, bool noloop_only) redirect to a duplicate of BB. */ edge e, e2; edge_iterator ei; - struct local_info local_info; + ssa_local_info_t local_info; struct loop *loop = bb->loop_father; /* To avoid scanning a linear array for the element we need we instead use a hash table. For normal code there should be no noticeable difference. However, if we have a block with a large number of incoming and outgoing edges such linear searches can get expensive. */ - redirection_data = htab_create (EDGE_COUNT (bb->succs), - redirection_data_hash, - redirection_data_eq, - free); + redirection_data.create (EDGE_COUNT (bb->succs)); /* If we thread the latch of the loop to its exit, the loop ceases to exist. Make sure we do not restrict ourselves in order to preserve @@ -678,24 +681,26 @@ thread_block (basic_block bb, bool noloop_only) local_info.template_block = NULL; local_info.bb = bb; local_info.jumps_threaded = false; - htab_traverse (redirection_data, create_duplicates, &local_info); + redirection_data.traverse <ssa_local_info_t *, ssa_create_duplicates> + (&local_info); /* The template does not have an outgoing edge. Create that outgoing edge and update PHI nodes as the edge's target as necessary. We do this after creating all the duplicates to avoid creating unnecessary edges. */ - htab_traverse (redirection_data, fixup_template_block, &local_info); + redirection_data.traverse <ssa_local_info_t *, ssa_fixup_template_block> + (&local_info); /* The hash table traversals above created the duplicate blocks (and the statements within the duplicate blocks). This loop creates PHI nodes for the duplicated blocks and redirects the incoming edges into BB to reach the duplicates of BB. */ - htab_traverse (redirection_data, redirect_edges, &local_info); + redirection_data.traverse <ssa_local_info_t *, ssa_redirect_edges> + (&local_info); /* Done with this block. Clear REDIRECTION_DATA. */ - htab_delete (redirection_data); - redirection_data = NULL; + redirection_data.dispose (); if (noloop_only && bb == bb->loop_father->header) diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index 29ed23f..bdf3fd2 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -188,7 +188,7 @@ adjust_vec_debug_stmts (void) while (!VEC_empty (adjust_info, adjust_vec)) { - adjust_debug_stmts_now (VEC_last (adjust_info, adjust_vec)); + adjust_debug_stmts_now (&VEC_last (adjust_info, adjust_vec)); VEC_pop (adjust_info, adjust_vec); } @@ -2550,4 +2550,3 @@ vect_loop_versioning (loop_vec_info loop_vinfo, GSI_SAME_STMT); } } - diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 782172f..a4c7483 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1098,7 +1098,7 @@ vect_slp_rearrange_stmts (slp_tree node, unsigned int group_size, tmp_stmts = VEC_alloc (gimple, heap, group_size); for (i = 0; i < group_size; i++) - VEC_safe_push (gimple, heap, tmp_stmts, NULL); + VEC_safe_push (gimple, heap, tmp_stmts, (gimple)NULL); FOR_EACH_VEC_ELT (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt) { @@ -2653,7 +2653,7 @@ vect_create_mask_and_perm (gimple stmt, gimple next_scalar_stmt, stmts later. */ for (i = VEC_length (gimple, SLP_TREE_VEC_STMTS (node)); i < (int) SLP_TREE_NUMBER_OF_VEC_STMTS (node); i++) - VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (node), NULL); + VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (node), (gimple)NULL); perm_dest = vect_create_destination_var (gimple_assign_lhs (stmt), vectype); for (i = 0; i < ncopies; i++) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 156bdd4..0fd400d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -8864,7 +8864,7 @@ vrp_fold_stmt (gimple_stmt_iterator *si) A NULL entry is used to mark the end of pairs which need to be restored. */ -static VEC(tree,heap) *stack; +static VEC(tree,heap) *equiv_stack; /* A trivial wrapper so that we can present the generic jump threading code with a simple API for simplifying statements. STMT is the @@ -8932,7 +8932,7 @@ identify_jump_threads (void) /* Allocate our unwinder stack to unwind any temporary equivalences that might be recorded. */ - stack = VEC_alloc (tree, heap, 20); + equiv_stack = VEC_alloc (tree, heap, 20); /* To avoid lots of silly node creation, we create a single conditional and just modify it in-place when attempting to @@ -8986,7 +8986,7 @@ identify_jump_threads (void) if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) continue; - thread_across_edge (dummy, e, true, &stack, + thread_across_edge (dummy, e, true, &equiv_stack, simplify_stmt_for_jump_threading); } } @@ -9007,7 +9007,7 @@ static void finalize_jump_threads (void) { thread_through_all_blocks (false); - VEC_free (tree, heap, stack); + VEC_free (tree, heap, equiv_stack); } @@ -6704,8 +6704,8 @@ simple_cst_equal (const_tree t1, const_tree t2) for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx) /* ??? Should we handle also fields here? */ - if (!simple_cst_equal (VEC_index (constructor_elt, v1, idx)->value, - VEC_index (constructor_elt, v2, idx)->value)) + if (!simple_cst_equal (VEC_index (constructor_elt, v1, idx).value, + VEC_index (constructor_elt, v2, idx).value)) return false; return true; } @@ -719,195 +719,80 @@ enum tree_node_structure_enum { is accessed incorrectly. The macros die with a fatal error. */ #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) -#define TREE_CHECK(T, CODE) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE), 0); \ - __t; }) - -#define TREE_NOT_CHECK(T, CODE) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE), 0); \ - __t; }) - -#define TREE_CHECK2(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), 0); \ - __t; }) - -#define TREE_NOT_CHECK2(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), 0); \ - __t; }) - -#define TREE_CHECK3(T, CODE1, CODE2, CODE3) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2) \ - && TREE_CODE (__t) != (CODE3)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), 0); \ - __t; }) - -#define TREE_NOT_CHECK3(T, CODE1, CODE2, CODE3) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2) \ - || TREE_CODE (__t) == (CODE3)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), 0); \ - __t; }) - -#define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2) \ - && TREE_CODE (__t) != (CODE3) \ - && TREE_CODE (__t) != (CODE4)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), 0); \ - __t; }) - -#define TREE_NOT_CHECK4(T, CODE1, CODE2, CODE3, CODE4) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2) \ - || TREE_CODE (__t) == (CODE3) \ - || TREE_CODE (__t) == (CODE4)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), 0); \ - __t; }) - -#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2) \ - && TREE_CODE (__t) != (CODE3) \ - && TREE_CODE (__t) != (CODE4) \ - && TREE_CODE (__t) != (CODE5)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), (CODE5), 0);\ - __t; }) - -#define TREE_NOT_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2) \ - || TREE_CODE (__t) == (CODE3) \ - || TREE_CODE (__t) == (CODE4) \ - || TREE_CODE (__t) == (CODE5)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), (CODE5), 0);\ - __t; }) - -#define CONTAINS_STRUCT_CHECK(T, STRUCT) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (tree_contains_struct[TREE_CODE(__t)][(STRUCT)] != 1) \ - tree_contains_struct_check_failed (__t, (STRUCT), __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) - -#define TREE_CLASS_CHECK(T, CLASS) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE_CLASS (TREE_CODE(__t)) != (CLASS)) \ - tree_class_check_failed (__t, (CLASS), __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) - -#define TREE_RANGE_CHECK(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) < (CODE1) || TREE_CODE (__t) > (CODE2)) \ - tree_range_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2)); \ - __t; }) - -#define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != OMP_CLAUSE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - OMP_CLAUSE, 0); \ - if (__t->omp_clause.code != (CODE)) \ - omp_clause_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE)); \ - __t; }) - -#define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != OMP_CLAUSE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - OMP_CLAUSE, 0); \ - if ((int) __t->omp_clause.code < (int) (CODE1) \ - || (int) __t->omp_clause.code > (int) (CODE2)) \ - omp_clause_range_check_failed (__t, __FILE__, __LINE__, \ - __FUNCTION__, (CODE1), (CODE2)); \ - __t; }) +#define TREE_CHECK(T, CODE) \ +(tree_check ((T), __FILE__, __LINE__, __FUNCTION__, (CODE))) + +#define TREE_NOT_CHECK(T, CODE) \ +(tree_not_check ((T), __FILE__, __LINE__, __FUNCTION__, (CODE))) + +#define TREE_CHECK2(T, CODE1, CODE2) \ +(tree_check2 ((T), __FILE__, __LINE__, __FUNCTION__, (CODE1), (CODE2))) + +#define TREE_NOT_CHECK2(T, CODE1, CODE2) \ +(tree_not_check2 ((T), __FILE__, __LINE__, __FUNCTION__, (CODE1), (CODE2))) + +#define TREE_CHECK3(T, CODE1, CODE2, CODE3) \ +(tree_check3 ((T), __FILE__, __LINE__, __FUNCTION__, (CODE1), (CODE2), (CODE3))) + +#define TREE_NOT_CHECK3(T, CODE1, CODE2, CODE3) \ +(tree_not_check3 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3))) + +#define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) \ +(tree_check4 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4))) + +#define TREE_NOT_CHECK4(T, CODE1, CODE2, CODE3, CODE4) \ +(tree_not_check4 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4))) + +#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) \ +(tree_check5 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4), (CODE5))) + +#define TREE_NOT_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) \ +(tree_not_check5 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4), (CODE5))) + +#define CONTAINS_STRUCT_CHECK(T, STRUCT) \ +(contains_struct_check ((T), (STRUCT), __FILE__, __LINE__, __FUNCTION__)) + +#define TREE_CLASS_CHECK(T, CLASS) \ +(tree_class_check ((T), (CLASS), __FILE__, __LINE__, __FUNCTION__)) + +#define TREE_RANGE_CHECK(T, CODE1, CODE2) \ +(tree_range_check ((T), (CODE1), (CODE2), __FILE__, __LINE__, __FUNCTION__)) + +#define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) \ +(omp_clause_subcode_check ((T), (CODE), __FILE__, __LINE__, __FUNCTION__)) + +#define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) \ +(omp_clause_range_check ((T), (CODE1), (CODE2), \ + __FILE__, __LINE__, __FUNCTION__)) /* These checks have to be special cased. */ -#define EXPR_CHECK(T) __extension__ \ -({ __typeof (T) const __t = (T); \ - char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); \ - if (!IS_EXPR_CODE_CLASS (__c)) \ - tree_class_check_failed (__t, tcc_expression, __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) +#define EXPR_CHECK(T) \ +(expr_check ((T), __FILE__, __LINE__, __FUNCTION__)) /* These checks have to be special cased. */ -#define NON_TYPE_CHECK(T) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TYPE_P (__t)) \ - tree_not_class_check_failed (__t, tcc_type, __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) - -#define TREE_VEC_ELT_CHECK(T, I) __extension__ \ -(*({__typeof (T) const __t = (T); \ - const int __i = (I); \ - if (TREE_CODE (__t) != TREE_VEC) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - TREE_VEC, 0); \ - if (__i < 0 || __i >= __t->vec.length) \ - tree_vec_elt_check_failed (__i, __t->vec.length, \ - __FILE__, __LINE__, __FUNCTION__); \ - &__t->vec.a[__i]; })) - -#define OMP_CLAUSE_ELT_CHECK(T, I) __extension__ \ -(*({__typeof (T) const __t = (T); \ - const int __i = (I); \ - if (TREE_CODE (__t) != OMP_CLAUSE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - OMP_CLAUSE, 0); \ - if (__i < 0 || __i >= omp_clause_num_ops [__t->omp_clause.code]) \ - omp_clause_operand_check_failed (__i, __t, __FILE__, __LINE__, \ - __FUNCTION__); \ - &__t->omp_clause.ops[__i]; })) +#define NON_TYPE_CHECK(T) \ +(non_type_check ((T), __FILE__, __LINE__, __FUNCTION__)) + +#define TREE_VEC_ELT_CHECK(T, I) \ +(*(CONST_CAST2 (tree *, typeof (T)*, \ + tree_vec_elt_check ((T), (I), __FILE__, __LINE__, __FUNCTION__)))) + +#define OMP_CLAUSE_ELT_CHECK(T, I) \ +(*(omp_clause_elt_check ((T), (I), __FILE__, __LINE__, __FUNCTION__))) /* Special checks for TREE_OPERANDs. */ -#define TREE_OPERAND_CHECK(T, I) __extension__ \ -(*({__typeof (T) const __t = EXPR_CHECK (T); \ - const int __i = (I); \ - if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) \ - tree_operand_check_failed (__i, __t, \ - __FILE__, __LINE__, __FUNCTION__); \ - &__t->exp.operands[__i]; })) - -#define TREE_OPERAND_CHECK_CODE(T, CODE, I) __extension__ \ -(*({__typeof (T) const __t = (T); \ - const int __i = (I); \ - if (TREE_CODE (__t) != CODE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, (CODE), 0);\ - if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) \ - tree_operand_check_failed (__i, __t, \ - __FILE__, __LINE__, __FUNCTION__); \ - &__t->exp.operands[__i]; })) +#define TREE_OPERAND_CHECK(T, I) \ +(*(CONST_CAST2 (tree*, typeof (T)*, \ + tree_operand_check ((T), (I), __FILE__, __LINE__, __FUNCTION__)))) + +#define TREE_OPERAND_CHECK_CODE(T, CODE, I) \ +(*(tree_operand_check_code ((T), (CODE), (I), \ + __FILE__, __LINE__, __FUNCTION__))) /* Nodes are chained together for many purposes. Types are chained together to record them for being output to the debugger @@ -918,17 +803,15 @@ enum tree_node_structure_enum { Often lists of things are represented by TREE_LIST nodes that are chained together. */ -#define TREE_CHAIN(NODE) __extension__ \ -(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_COMMON);\ - &__t->common.chain; })) +#define TREE_CHAIN(NODE) \ +(CONTAINS_STRUCT_CHECK (NODE, TS_COMMON)->common.chain) /* In all nodes that are expressions, this is the data type of the expression. In POINTER_TYPE nodes, this is the type that the pointer points to. In ARRAY_TYPE nodes, this is the type of the elements. In VECTOR_TYPE nodes, this is the type of the elements. */ -#define TREE_TYPE(NODE) __extension__ \ -(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_TYPED); \ - &__t->typed.type; })) +#define TREE_TYPE(NODE) \ +(CONTAINS_STRUCT_CHECK (NODE, TS_TYPED)->typed.type) extern void tree_contains_struct_check_failed (const_tree, const enum tree_node_structure_enum, @@ -1608,7 +1491,7 @@ struct GTY(()) tree_vec { /* In a CONSTRUCTOR node. */ #define CONSTRUCTOR_ELTS(NODE) (CONSTRUCTOR_CHECK (NODE)->constructor.elts) #define CONSTRUCTOR_ELT(NODE,IDX) \ - (VEC_index (constructor_elt, CONSTRUCTOR_ELTS (NODE), IDX)) + (&VEC_index (constructor_elt, CONSTRUCTOR_ELTS (NODE), IDX)) #define CONSTRUCTOR_NELTS(NODE) \ (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (NODE))) @@ -1618,7 +1501,7 @@ struct GTY(()) tree_vec { #define FOR_EACH_CONSTRUCTOR_VALUE(V, IX, VAL) \ for (IX = 0; (IX >= VEC_length (constructor_elt, V)) \ ? false \ - : ((VAL = VEC_index (constructor_elt, V, IX)->value), \ + : ((VAL = VEC_index (constructor_elt, V, IX).value), \ true); \ (IX)++) @@ -1628,8 +1511,8 @@ struct GTY(()) tree_vec { #define FOR_EACH_CONSTRUCTOR_ELT(V, IX, INDEX, VAL) \ for (IX = 0; (IX >= VEC_length (constructor_elt, V)) \ ? false \ - : (((void) (VAL = VEC_index (constructor_elt, V, IX)->value)), \ - (INDEX = VEC_index (constructor_elt, V, IX)->index), \ + : (((void) (VAL = VEC_index (constructor_elt, V, IX).value)), \ + (INDEX = VEC_index (constructor_elt, V, IX).index), \ true); \ (IX)++) @@ -3743,6 +3626,486 @@ union GTY ((ptr_alias (union lang_tree_node), struct tree_optimization_option GTY ((tag ("TS_OPTIMIZATION"))) optimization; struct tree_target_option GTY ((tag ("TS_TARGET_OPTION"))) target_option; }; + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + +inline tree +tree_check (tree __t, const char *__f, int __l, const char *__g, tree_code __c) +{ + if (TREE_CODE (__t) != __c) + tree_check_failed (__t, __f, __l, __g, __c, 0); + return __t; +} + +inline tree +tree_not_check (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c) +{ + if (TREE_CODE (__t) == __c) + tree_not_check_failed (__t, __f, __l, __g, __c, 0); + return __t; +} + +inline tree +tree_check2 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return __t; +} + +inline tree +tree_not_check2 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return __t; +} + +inline tree +tree_check3 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return __t; +} + +inline tree +tree_not_check3 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return __t; +} + +inline tree +tree_check4 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return __t; +} + +inline tree +tree_not_check4 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return __t; +} + +inline tree +tree_check5 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4 + && TREE_CODE (__t) != __c5) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return __t; +} + +inline tree +tree_not_check5 (tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4 + || TREE_CODE (__t) == __c5) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return __t; +} + +inline tree +contains_struct_check (tree __t, const enum tree_node_structure_enum __s, + const char *__f, int __l, const char *__g) +{ + if (tree_contains_struct[TREE_CODE(__t)][__s] != 1) + tree_contains_struct_check_failed (__t, __s, __f, __l, __g); + return __t; +} + +inline tree +tree_class_check (tree __t, const enum tree_code_class __class, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE_CLASS (TREE_CODE(__t)) != __class) + tree_class_check_failed (__t, __class, __f, __l, __g); + return __t; +} + +inline tree +tree_range_check (tree __t, + enum tree_code __code1, enum tree_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) < __code1 || TREE_CODE (__t) > __code2) + tree_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return __t; +} + +inline tree +omp_clause_subcode_check (tree __t, enum omp_clause_code __code, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__t->omp_clause.code != __code) + omp_clause_check_failed (__t, __f, __l, __g, __code); + return __t; +} + +inline tree +omp_clause_range_check (tree __t, + enum omp_clause_code __code1, + enum omp_clause_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if ((int) __t->omp_clause.code < (int) __code1 + || (int) __t->omp_clause.code > (int) __code2) + omp_clause_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return __t; +} + +/* These checks have to be special cased. */ + +inline tree +expr_check (tree __t, const char *__f, int __l, const char *__g) +{ + char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); + if (!IS_EXPR_CODE_CLASS (__c)) + tree_class_check_failed (__t, tcc_expression, __f, __l, __g); + return __t; +} + +/* These checks have to be special cased. */ + +inline tree +non_type_check (tree __t, const char *__f, int __l, const char *__g) +{ + if (TYPE_P (__t)) + tree_not_class_check_failed (__t, tcc_type, __f, __l, __g); + return __t; +} + +inline tree * +tree_vec_elt_check (tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != TREE_VEC) + tree_check_failed (__t, __f, __l, __g, TREE_VEC, 0); + if (__i < 0 || __i >= __t->vec.length) + tree_vec_elt_check_failed (__i, __t->vec.length, __f, __l, __g); + return &CONST_CAST_TREE (__t)->vec.a[__i]; +} + +inline tree * +omp_clause_elt_check (tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__i < 0 || __i >= omp_clause_num_ops [__t->omp_clause.code]) + omp_clause_operand_check_failed (__i, __t, __f, __l, __g); + return &__t->omp_clause.ops[__i]; +} + +inline const_tree +tree_check (const_tree __t, const char *__f, int __l, const char *__g, + tree_code __c) +{ + if (TREE_CODE (__t) != __c) + tree_check_failed (__t, __f, __l, __g, __c, 0); + return __t; +} + +inline const_tree +tree_not_check (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c) +{ + if (TREE_CODE (__t) == __c) + tree_not_check_failed (__t, __f, __l, __g, __c, 0); + return __t; +} + +inline const_tree +tree_check2 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return __t; +} + +inline const_tree +tree_not_check2 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return __t; +} + +inline const_tree +tree_check3 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return __t; +} + +inline const_tree +tree_not_check3 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return __t; +} + +inline const_tree +tree_check4 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return __t; +} + +inline const_tree +tree_not_check4 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return __t; +} + +inline const_tree +tree_check5 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4 + && TREE_CODE (__t) != __c5) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return __t; +} + +inline const_tree +tree_not_check5 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4 + || TREE_CODE (__t) == __c5) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return __t; +} + +inline const_tree +contains_struct_check (const_tree __t, const enum tree_node_structure_enum __s, + const char *__f, int __l, const char *__g) +{ + if (tree_contains_struct[TREE_CODE(__t)][__s] != 1) + tree_contains_struct_check_failed (__t, __s, __f, __l, __g); + return __t; +} + +inline const_tree +tree_class_check (const_tree __t, const enum tree_code_class __class, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE_CLASS (TREE_CODE(__t)) != __class) + tree_class_check_failed (__t, __class, __f, __l, __g); + return __t; +} + +inline const_tree +tree_range_check (const_tree __t, + enum tree_code __code1, enum tree_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) < __code1 || TREE_CODE (__t) > __code2) + tree_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return __t; +} + +inline const_tree +omp_clause_subcode_check (const_tree __t, enum omp_clause_code __code, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__t->omp_clause.code != __code) + omp_clause_check_failed (__t, __f, __l, __g, __code); + return __t; +} + +inline const_tree +omp_clause_range_check (const_tree __t, + enum omp_clause_code __code1, + enum omp_clause_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if ((int) __t->omp_clause.code < (int) __code1 + || (int) __t->omp_clause.code > (int) __code2) + omp_clause_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return __t; +} + +inline const_tree +expr_check (const_tree __t, const char *__f, int __l, const char *__g) +{ + char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); + if (!IS_EXPR_CODE_CLASS (__c)) + tree_class_check_failed (__t, tcc_expression, __f, __l, __g); + return __t; +} + +inline const_tree +non_type_check (const_tree __t, const char *__f, int __l, const char *__g) +{ + if (TYPE_P (__t)) + tree_not_class_check_failed (__t, tcc_type, __f, __l, __g); + return __t; +} + +inline const_tree * +tree_vec_elt_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != TREE_VEC) + tree_check_failed (__t, __f, __l, __g, TREE_VEC, 0); + if (__i < 0 || __i >= __t->vec.length) + tree_vec_elt_check_failed (__i, __t->vec.length, __f, __l, __g); + return CONST_CAST (const_tree *, &__t->vec.a[__i]); + //return &__t->vec.a[__i]; +} + +inline const_tree * +omp_clause_elt_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__i < 0 || __i >= omp_clause_num_ops [__t->omp_clause.code]) + omp_clause_operand_check_failed (__i, __t, __f, __l, __g); + return CONST_CAST (const_tree *, &__t->omp_clause.ops[__i]); +} + +#endif + +/* Compute the number of operands in an expression node NODE. For + tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself, + otherwise it is looked up from the node's code. */ +static inline int +tree_operand_length (const_tree node) +{ + if (VL_EXP_CLASS_P (node)) + return VL_EXP_OPERAND_LENGTH (node); + else + return TREE_CODE_LENGTH (TREE_CODE (node)); +} + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + +/* Special checks for TREE_OPERANDs. */ +inline tree * +tree_operand_check (tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + const_tree __u = EXPR_CHECK (__t); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__u)) + tree_operand_check_failed (__i, __u, __f, __l, __g); + return &CONST_CAST_TREE (__u)->exp.operands[__i]; +} + +inline tree * +tree_operand_check_code (tree __t, enum tree_code __code, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != __code) + tree_check_failed (__t, __f, __l, __g, __code, 0); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) + tree_operand_check_failed (__i, __t, __f, __l, __g); + return &__t->exp.operands[__i]; +} + +inline const_tree * +tree_operand_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + const_tree __u = EXPR_CHECK (__t); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__u)) + tree_operand_check_failed (__i, __u, __f, __l, __g); + return CONST_CAST (const_tree *, &__u->exp.operands[__i]); +} + +inline const_tree * +tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != __code) + tree_check_failed (__t, __f, __l, __g, __code, 0); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) + tree_operand_check_failed (__i, __t, __f, __l, __g); + return CONST_CAST (const_tree *, &__t->exp.operands[__i]); +} + +#endif + /* Standard named or nameless data types of the C compiler. */ @@ -5917,18 +6280,6 @@ is_tm_safe_or_pure (const_tree x) void init_inline_once (void); -/* Compute the number of operands in an expression node NODE. For - tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself, - otherwise it is looked up from the node's code. */ -static inline int -tree_operand_length (const_tree node) -{ - if (VL_EXP_CLASS_P (node)) - return VL_EXP_OPERAND_LENGTH (node); - else - return TREE_CODE_LENGTH (TREE_CODE (node)); -} - /* Abstract iterators for CALL_EXPRs. These static inline definitions have to go towards the end of tree.h so that union tree_node is fully defined by this point. */ diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index a79872f..818fb24 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -7821,7 +7821,7 @@ loc_exp_dep_clear (variable var) { while (!VEC_empty (loc_exp_dep, VAR_LOC_DEP_VEC (var))) { - loc_exp_dep *led = VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var)); + loc_exp_dep *led = &VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var)); if (led->next) led->next->pprev = led->pprev; if (led->pprev) @@ -7865,7 +7865,7 @@ loc_exp_insert_dep (variable var, rtx x, htab_t vars) else { VEC_quick_push (loc_exp_dep, VAR_LOC_DEP_VEC (var), NULL); - led = VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var)); + led = &VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var)); } led->dv = var->dv; led->value = x; diff --git a/gcc/varasm.c b/gcc/varasm.c index a1f0a23..b380a47 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2871,8 +2871,8 @@ compare_constant (const tree t1, const tree t2) for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx) { - constructor_elt *c1 = VEC_index (constructor_elt, v1, idx); - constructor_elt *c2 = VEC_index (constructor_elt, v2, idx); + constructor_elt *c1 = &VEC_index (constructor_elt, v1, idx); + constructor_elt *c2 = &VEC_index (constructor_elt, v2, idx); /* Check that each value is the same... */ if (!compare_constant (c1->value, c2->value)) @@ -1,7 +1,8 @@ /* Vector API for GNU compiler. - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Nathan Sidwell <nathan@codesourcery.com> + Re-implemented in C++ by Diego Novillo <dnovillo@google.com> This file is part of GCC. @@ -213,7 +214,7 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve, bool exact) trailing array is at VEC_OFFSET offset and consists of ELT_SIZE sized elements. */ -static void * +void * vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size, bool exact MEM_STAT_DECL) { @@ -246,61 +247,10 @@ vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size, return vec; } -/* Ensure there are at least RESERVE free slots in VEC, growing - exponentially. If RESERVE < 0 grow exactly, else grow - exponentially. As a special case, if VEC is NULL, and RESERVE is - 0, no vector will be created. */ - -void * -vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL) -{ - return vec_gc_o_reserve_1 (vec, reserve, - sizeof (struct vec_prefix), - sizeof (void *), false - PASS_MEM_STAT); -} - -/* Ensure there are at least RESERVE free slots in VEC, growing - exactly. If RESERVE < 0 grow exactly, else grow exponentially. As - a special case, if VEC is NULL, and RESERVE is 0, no vector will be - created. */ - -void * -vec_gc_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL) -{ - return vec_gc_o_reserve_1 (vec, reserve, - sizeof (struct vec_prefix), - sizeof (void *), true - PASS_MEM_STAT); -} - -/* As for vec_gc_p_reserve, but for object vectors. The vector's - trailing array is at VEC_OFFSET offset and consists of ELT_SIZE - sized elements. */ - -void * -vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size - MEM_STAT_DECL) -{ - return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, false - PASS_MEM_STAT); -} - -/* As for vec_gc_p_reserve_exact, but for object vectors. The - vector's trailing array is at VEC_OFFSET offset and consists of - ELT_SIZE sized elements. */ - -void * -vec_gc_o_reserve_exact (void *vec, int reserve, size_t vec_offset, - size_t elt_size MEM_STAT_DECL) -{ - return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, true - PASS_MEM_STAT); -} /* As for vec_gc_o_reserve_1, but for heap allocated vectors. */ -static void * +void * vec_heap_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size, bool exact MEM_STAT_DECL) { @@ -328,47 +278,6 @@ vec_heap_o_reserve_1 (void *vec, int reserve, size_t vec_offset, return vec; } -/* As for vec_gc_p_reserve, but for heap allocated vectors. */ - -void * -vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL) -{ - return vec_heap_o_reserve_1 (vec, reserve, - sizeof (struct vec_prefix), - sizeof (void *), false - PASS_MEM_STAT); -} - -/* As for vec_gc_p_reserve_exact, but for heap allocated vectors. */ - -void * -vec_heap_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL) -{ - return vec_heap_o_reserve_1 (vec, reserve, - sizeof (struct vec_prefix), - sizeof (void *), true - PASS_MEM_STAT); -} - -/* As for vec_gc_o_reserve, but for heap allocated vectors. */ - -void * -vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size - MEM_STAT_DECL) -{ - return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, false - PASS_MEM_STAT); -} - -/* As for vec_gc_o_reserve_exact, but for heap allocated vectors. */ - -void * -vec_heap_o_reserve_exact (void *vec, int reserve, size_t vec_offset, - size_t elt_size MEM_STAT_DECL) -{ - return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, true - PASS_MEM_STAT); -} /* Stack vectors are a little different. VEC_alloc turns into a call to vec_stack_p_reserve_exact1 and passes in space allocated via a @@ -450,28 +359,6 @@ vec_stack_o_reserve_1 (void *vec, int reserve, size_t vec_offset, /* Grow a vector allocated on the stack. */ void * -vec_stack_p_reserve (void *vec, int reserve MEM_STAT_DECL) -{ - return vec_stack_o_reserve_1 (vec, reserve, - sizeof (struct vec_prefix), - sizeof (void *), false - PASS_MEM_STAT); -} - -/* Exact version of vec_stack_p_reserve. */ - -void * -vec_stack_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL) -{ - return vec_stack_o_reserve_1 (vec, reserve, - sizeof (struct vec_prefix), - sizeof (void *), true - PASS_MEM_STAT); -} - -/* Like vec_stack_p_reserve, but for objects. */ - -void * vec_stack_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size MEM_STAT_DECL) { @@ -479,7 +366,7 @@ vec_stack_o_reserve (void *vec, int reserve, size_t vec_offset, PASS_MEM_STAT); } -/* Like vec_stack_p_reserve_exact, but for objects. */ +/* Exact version of vec_stack_o_reserve. */ void * vec_stack_o_reserve_exact (void *vec, int reserve, size_t vec_offset, @@ -1,7 +1,8 @@ /* Vector API for GNU compiler. - Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010 + Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Nathan Sidwell <nathan@codesourcery.com> + Re-implemented in C++ by Diego Novillo <dnovillo@google.com> This file is part of GCC. @@ -134,6 +135,153 @@ along with GCC; see the file COPYING3. If not see */ +#if ENABLE_CHECKING +#define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__ +#define VEC_CHECK_DECL ,const char *file_,unsigned line_,const char *function_ +#define VEC_CHECK_PASS ,file_,line_,function_ + +#define VEC_ASSERT(EXPR,OP,T,A) \ + (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0)) + +extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL) + ATTRIBUTE_NORETURN; +#define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS) +#else +#define VEC_CHECK_INFO +#define VEC_CHECK_DECL +#define VEC_CHECK_PASS +#define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR) +#endif + +#define VEC(T,A) vec_t<T> + +enum vec_allocation_t { heap, gc, stack }; + +struct vec_prefix +{ + unsigned num; + unsigned alloc; +}; + +/* Vector type, user visible. */ +template<typename T> +struct GTY(()) vec_t +{ + vec_prefix prefix; + T vec[1]; +}; + +/* Garbage collection support for vec_t. */ + +template<typename T> +void +gt_ggc_mx (vec_t<T> *v) +{ + extern void gt_ggc_mx (T&); + for (unsigned i = 0; i < v->prefix.num; i++) + gt_ggc_mx (v->vec[i]); +} + + +/* PCH support for vec_t. */ + +template<typename T> +void +gt_pch_nx (vec_t<T> *v) +{ + extern void gt_pch_nx (T&); + for (unsigned i = 0; i < v->prefix.num; i++) + gt_pch_nx (v->vec[i]); +} + +template<typename T> +void +gt_pch_nx (vec_t<T *> *v, gt_pointer_operator op, void *cookie) +{ + for (unsigned i = 0; i < v->prefix.num; i++) + op (&(v->vec[i]), cookie); +} + +template<typename T> +void +gt_pch_nx (vec_t<T> *v, gt_pointer_operator op, void *cookie) +{ + extern void gt_pch_nx (T *, gt_pointer_operator, void *); + for (unsigned i = 0; i < v->prefix.num; i++) + gt_pch_nx (&(v->vec[i]), op, cookie); +} + + +/* FIXME cxx-conversion. Remove these definitions and update all + calling sites. */ +/* Vector of integer-like object. */ +#define DEF_VEC_I(T) struct vec_swallow_trailing_semi +#define DEF_VEC_ALLOC_I(T,A) struct vec_swallow_trailing_semi + +/* Vector of pointer to object. */ +#define DEF_VEC_P(T) struct vec_swallow_trailing_semi +#define DEF_VEC_ALLOC_P(T,A) struct vec_swallow_trailing_semi + +/* Vector of object. */ +#define DEF_VEC_O(T) struct vec_swallow_trailing_semi +#define DEF_VEC_ALLOC_O(T,A) struct vec_swallow_trailing_semi + +/* Vectors on the stack. */ +#define DEF_VEC_ALLOC_P_STACK(T) struct vec_swallow_trailing_semi +#define DEF_VEC_ALLOC_O_STACK(T) struct vec_swallow_trailing_semi +#define DEF_VEC_ALLOC_I_STACK(T) struct vec_swallow_trailing_semi + +/* Vectors of atomic types. Atomic types do not need to have its + elements marked for GC and PCH. To avoid unnecessary traversals, + we provide template instantiations for the GC/PCH functions that + do not traverse the vector. + + FIXME cxx-conversion - Once vec_t users are converted this can + be provided in some other way (e.g., adding an additional template + parameter to the vec_t class). */ +#define DEF_VEC_A(TYPE) \ +template<typename T> \ +void \ +gt_ggc_mx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \ +{ \ +} \ + \ +template<typename T> \ +void \ +gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED) \ +{ \ +} \ + \ +template<typename T> \ +void \ +gt_pch_nx (vec_t<TYPE> *v ATTRIBUTE_UNUSED, \ + gt_pointer_operator op ATTRIBUTE_UNUSED, \ + void *cookie ATTRIBUTE_UNUSED) \ +{ \ +} \ +struct vec_swallow_trailing_semi + +#define DEF_VEC_ALLOC_A(T,A) struct vec_swallow_trailing_semi + +/* Support functions for stack vectors. */ +extern void *vec_stack_p_reserve_exact_1 (int, void *); +extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL); +extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t + MEM_STAT_DECL); +extern void vec_stack_free (void *); + +/* Reallocate an array of elements with prefix. */ +template<typename T, enum vec_allocation_t A> +extern vec_t<T> *vec_reserve (vec_t<T> *, int MEM_STAT_DECL); + +template<typename T, enum vec_allocation_t A> +extern vec_t<T> *vec_reserve_exact (vec_t<T> *, int MEM_STAT_DECL); + +extern void dump_vec_loc_statistics (void); +extern void ggc_free (void *); +extern void vec_heap_free (void *); + + /* Macros to invoke API calls. A single macro works for both pointer and object vectors, but the argument and return types might well be different. In each macro, T is the typedef of the vector elements, @@ -148,7 +296,14 @@ along with GCC; see the file COPYING3. If not see Return the number of active elements in V. V can be NULL, in which case zero is returned. */ -#define VEC_length(T,V) (VEC_OP(T,base,length)(VEC_BASE(V))) +#define VEC_length(T,V) (VEC_length_1<T> (V)) + +template<typename T> +static inline unsigned +VEC_length_1 (const vec_t<T> *vec_) +{ + return vec_ ? vec_->prefix.num : 0; +} /* Check if vector is empty @@ -156,7 +311,30 @@ along with GCC; see the file COPYING3. If not see Return nonzero if V is an empty vector (or V is NULL), zero otherwise. */ -#define VEC_empty(T,V) (VEC_length (T,V) == 0) +#define VEC_empty(T,V) (VEC_empty_1<T> (V)) + +template<typename T> +static inline bool +VEC_empty_1 (const vec_t<T> *vec_) +{ + return VEC_length (T, vec_) == 0; +} + + +/* Get the address of the array of elements + T *VEC_T_address (VEC(T) v) + + If you need to directly manipulate the array (for instance, you + want to feed it to qsort), use this accessor. */ + +#define VEC_address(T,V) (VEC_address_1<T> (V)) + +template<typename T> +static inline T * +VEC_address_1 (vec_t<T> *vec_) +{ + return vec_ ? vec_->vec : 0; +} /* Get the final element of the vector. @@ -166,16 +344,42 @@ along with GCC; see the file COPYING3. If not see Return the final element. V must not be empty. */ -#define VEC_last(T,V) (VEC_OP(T,base,last)(VEC_BASE(V) VEC_CHECK_INFO)) +#define VEC_last(T,V) (VEC_last_1<T> (V VEC_CHECK_INFO)) + +template<typename T> +static inline T& +VEC_last_1 (vec_t<T> *vec_ VEC_CHECK_DECL) +{ + VEC_ASSERT (vec_ && vec_->prefix.num, "last", T, base); + return vec_->vec[vec_->prefix.num - 1]; +} + /* Index into vector T VEC_T_index(VEC(T) *v, unsigned ix); // Integer T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer T *VEC_T_index(VEC(T) *v, unsigned ix); // Object - Return the IX'th element. If IX must be in the domain of V. */ + Return the IX'th element. IX must be in the domain of V. */ + +#define VEC_index(T,V,I) (VEC_index_1<T> (V, I VEC_CHECK_INFO)) + +template<typename T> +static inline T& +VEC_index_1 (vec_t<T> *vec_, unsigned ix_ VEC_CHECK_DECL) +{ + VEC_ASSERT (vec_ && ix_ < vec_->prefix.num, "index", T, base); + return vec_->vec[ix_]; +} + +template<typename T> +static inline const T& +VEC_index_1 (const vec_t<T> *vec_, unsigned ix_ VEC_CHECK_DECL) +{ + VEC_ASSERT (vec_ && ix_ < vec_->prefix.num, "index", T, base); + return vec_->vec[ix_]; +} -#define VEC_index(T,V,I) (VEC_OP(T,base,index)(VEC_BASE(V),I VEC_CHECK_INFO)) /* Iterate over vector int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer @@ -189,7 +393,39 @@ along with GCC; see the file COPYING3. If not see for (ix = 0; VEC_iterate(T,v,ix,ptr); ix++) continue; */ -#define VEC_iterate(T,V,I,P) (VEC_OP(T,base,iterate)(VEC_BASE(V),I,&(P))) +#define VEC_iterate(T,V,I,P) (VEC_iterate_1<T> (V, I, &(P))) + +template<typename T> +static inline bool +VEC_iterate_1 (const vec_t<T> *vec_, unsigned ix_, T *ptr) +{ + if (vec_ && ix_ < vec_->prefix.num) + { + *ptr = vec_->vec[ix_]; + return true; + } + else + { + *ptr = 0; + return false; + } +} + +template<typename T> +static inline bool +VEC_iterate_1 (vec_t<T> *vec_, unsigned ix_, T **ptr) +{ + if (vec_ && ix_ < vec_->prefix.num) + { + *ptr = &vec_->vec[ix_]; + return true; + } + else + { + *ptr = 0; + return false; + } +} /* Convenience macro for forward iteration. */ @@ -208,31 +444,99 @@ along with GCC; see the file COPYING3. If not see VEC_iterate (T, (V), (I), (P)); \ (I)--) + +/* Use these to determine the required size and initialization of a + vector embedded within another structure (as the final member). + + size_t VEC_T_embedded_size(int reserve); + void VEC_T_embedded_init(VEC(T) *v, int reserve); + + These allow the caller to perform the memory allocation. */ + +#define VEC_embedded_size(T,N) (VEC_embedded_size_1<T> (N)) + +template<typename T> +static inline size_t +VEC_embedded_size_1 (int alloc_) +{ + return offsetof (vec_t<T>, vec) + alloc_ * sizeof (T); +} + +#define VEC_embedded_init(T,O,N) (VEC_embedded_init_1<T> (O, N)) + +template<typename T> +static inline void +VEC_embedded_init_1 (vec_t<T> *vec_, int alloc_) +{ + vec_->prefix.num = 0; + vec_->prefix.alloc = alloc_; +} + + /* Allocate new vector. VEC(T,A) *VEC_T_A_alloc(int reserve); Allocate a new vector with space for RESERVE objects. If RESERVE - is zero, NO vector is created. */ + is zero, NO vector is created. + + We support a vector which starts out with space on the stack and + switches to heap space when forced to reallocate. This works a + little differently. In the case of stack vectors, VEC_alloc will + expand to a call to VEC_alloc_1 that calls XALLOCAVAR to request the + initial allocation. This uses alloca to get the initial space. + Since alloca can not be usefully called in an inline function, + VEC_alloc must always be a macro. + + Only the initial allocation will be made using alloca, so pass a + reasonable estimate that doesn't use too much stack space; don't + pass zero. Don't return a VEC(TYPE,stack) vector from the function + which allocated it. */ + +#define VEC_alloc(T,A,N) \ + ((A == stack) \ + ? VEC_alloc_1 (N, \ + XALLOCAVAR (vec_t<T>, \ + VEC_embedded_size_1<T> (N))) \ + : VEC_alloc_1<T, A> (N MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline vec_t<T> * +VEC_alloc_1 (int alloc_ MEM_STAT_DECL) +{ + return vec_reserve_exact<T, A> (NULL, alloc_ PASS_MEM_STAT); +} + +template<typename T> +static inline vec_t<T> * +VEC_alloc_1 (int alloc_, vec_t<T> *space) +{ + return (vec_t<T> *) vec_stack_p_reserve_exact_1 (alloc_, space); +} -#define VEC_alloc(T,A,N) (VEC_OP(T,A,alloc)(N MEM_STAT_INFO)) /* Free a vector. void VEC_T_A_free(VEC(T,A) *&); Free a vector and set it to NULL. */ -#define VEC_free(T,A,V) (VEC_OP(T,A,free)(&V)) +#define VEC_free(T,A,V) (VEC_free_1<T, A> (&V)) -/* Use these to determine the required size and initialization of a - vector embedded within another structure (as the final member). - - size_t VEC_T_embedded_size(int reserve); - void VEC_T_embedded_init(VEC(T) *v, int reserve); - - These allow the caller to perform the memory allocation. */ +template<typename T, enum vec_allocation_t A> +static inline void +VEC_free_1 (vec_t<T> **vec_) +{ + if (*vec_) + { + if (A == heap) + vec_heap_free (*vec_); + else if (A == gc) + ggc_free (*vec_); + else if (A == stack) + vec_stack_free (*vec_); + } + *vec_ = NULL; +} -#define VEC_embedded_size(T,N) (VEC_OP(T,base,embedded_size)(N)) -#define VEC_embedded_init(T,O,N) (VEC_OP(T,base,embedded_init)(VEC_BASE(O),N)) /* Copy a vector. VEC(T,A) *VEC_T_A_copy(VEC(T) *); @@ -240,7 +544,24 @@ along with GCC; see the file COPYING3. If not see Copy the live elements of a vector into a new vector. The new and old vectors need not be allocated by the same mechanism. */ -#define VEC_copy(T,A,V) (VEC_OP(T,A,copy)(VEC_BASE(V) MEM_STAT_INFO)) +#define VEC_copy(T,A,V) (VEC_copy_1<T, A> (V MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline vec_t<T> * +VEC_copy_1 (vec_t<T> *vec_ MEM_STAT_DECL) +{ + size_t len_ = vec_ ? vec_->prefix.num : 0; + vec_t<T> *new_vec_ = NULL; + + if (len_) + { + new_vec_ = vec_reserve_exact<T, A> (NULL, len_ PASS_MEM_STAT); + new_vec_->prefix.num = len_; + memcpy (new_vec_->vec, vec_->vec, sizeof (T) * len_); + } + return new_vec_; +} + /* Determine if a vector has additional capacity. @@ -252,8 +573,18 @@ along with GCC; see the file COPYING3. If not see nonzero in exactly the same circumstances that VEC_T_reserve will. */ -#define VEC_space(T,V,R) \ - (VEC_OP(T,base,space)(VEC_BASE(V),R VEC_CHECK_INFO)) +#define VEC_space(T,V,R) (VEC_space_1<T> (V, R VEC_CHECK_INFO)) + +template<typename T> +static inline int +VEC_space_1 (vec_t<T> *vec_, int alloc_ VEC_CHECK_DECL) +{ + VEC_ASSERT (alloc_ >= 0, "space", T, base); + return vec_ + ? vec_->prefix.alloc - vec_->prefix.num >= (unsigned)alloc_ + : !alloc_; +} + /* Reserve space. int VEC_T_A_reserve(VEC(T,A) *&v, int reserve); @@ -264,7 +595,20 @@ along with GCC; see the file COPYING3. If not see occurred. */ #define VEC_reserve(T,A,V,R) \ - (VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO)) + (VEC_reserve_1<T, A> (&(V), (int)(R) VEC_CHECK_INFO MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline int +VEC_reserve_1 (vec_t<T> **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) +{ + int extend = !VEC_space_1 (*vec_, alloc_ VEC_CHECK_PASS); + + if (extend) + *vec_ = vec_reserve<T, A> (*vec_, alloc_ PASS_MEM_STAT); + + return extend; +} + /* Reserve space exactly. int VEC_T_A_reserve_exact(VEC(T,A) *&v, int reserve); @@ -275,7 +619,20 @@ along with GCC; see the file COPYING3. If not see occurred. */ #define VEC_reserve_exact(T,A,V,R) \ - (VEC_OP(T,A,reserve_exact)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO)) + (VEC_reserve_exact_1<T, A> (&(V), R VEC_CHECK_INFO MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline int +VEC_reserve_exact_1 (vec_t<T> **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) +{ + int extend = !VEC_space_1 (*vec_, alloc_ VEC_CHECK_PASS); + + if (extend) + *vec_ = vec_reserve_exact<T, A> (*vec_, alloc_ PASS_MEM_STAT); + + return extend; +} + /* Copy elements with no reallocation void VEC_T_splice (VEC(T) *dst, VEC(T) *src); // Integer @@ -287,8 +644,23 @@ along with GCC; see the file COPYING3. If not see often will be. DST is assumed to have sufficient headroom available. */ -#define VEC_splice(T,DST,SRC) \ - (VEC_OP(T,base,splice)(VEC_BASE(DST), VEC_BASE(SRC) VEC_CHECK_INFO)) +#define VEC_splice(T,DST,SRC) (VEC_splice_1<T> (DST, SRC VEC_CHECK_INFO)) + +template<typename T> +static inline void +VEC_splice_1 (vec_t<T> *dst_, vec_t<T> *src_ VEC_CHECK_DECL) +{ + if (src_) + { + unsigned len_ = src_->prefix.num; + VEC_ASSERT (dst_->prefix.num + len_ <= dst_->prefix.alloc, "splice", + T, base); + + memcpy (&dst_->vec[dst_->prefix.num], &src_->vec[0], len_ * sizeof (T)); + dst_->prefix.num += len_; + } +} + /* Copy elements with reallocation void VEC_T_safe_splice (VEC(T,A) *&dst, VEC(T) *src); // Integer @@ -301,7 +673,21 @@ along with GCC; see the file COPYING3. If not see reallocated if needed. */ #define VEC_safe_splice(T,A,DST,SRC) \ - (VEC_OP(T,A,safe_splice)(&(DST), VEC_BASE(SRC) VEC_CHECK_INFO MEM_STAT_INFO)) + (VEC_safe_splice_1<T, A> (&(DST), SRC VEC_CHECK_INFO MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline void +VEC_safe_splice_1 (vec_t<T> **dst_, vec_t<T> *src_ VEC_CHECK_DECL MEM_STAT_DECL) +{ + if (src_) + { + VEC_reserve_exact_1<T, A> (dst_, src_->prefix.num + VEC_CHECK_PASS MEM_STAT_INFO); + + VEC_splice_1 (*dst_, src_ VEC_CHECK_PASS); + } +} + /* Push object with no reallocation T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer @@ -313,8 +699,31 @@ along with GCC; see the file COPYING3. If not see case NO initialization is performed. There must be sufficient space in the vector. */ -#define VEC_quick_push(T,V,O) \ - (VEC_OP(T,base,quick_push)(VEC_BASE(V),O VEC_CHECK_INFO)) +#define VEC_quick_push(T,V,O) (VEC_quick_push_1<T> (V, O VEC_CHECK_INFO)) + +template<typename T> +static inline T & +VEC_quick_push_1 (vec_t<T> *vec_, T obj_ VEC_CHECK_DECL) +{ + VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "push", T, base); + vec_->vec[vec_->prefix.num] = obj_; + T &val_ = vec_->vec[vec_->prefix.num]; + vec_->prefix.num++; + return val_; +} + +template<typename T> +static inline T * +VEC_quick_push_1 (vec_t<T> *vec_, const T *ptr_ VEC_CHECK_DECL) +{ + T *slot_; + VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "push", T, base); + slot_ = &vec_->vec[vec_->prefix.num++]; + if (ptr_) + *slot_ = *ptr_; + return slot_; +} + /* Push object with reallocation T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer @@ -326,7 +735,24 @@ along with GCC; see the file COPYING3. If not see case NO initialization is performed. Reallocates V, if needed. */ #define VEC_safe_push(T,A,V,O) \ - (VEC_OP(T,A,safe_push)(&(V),O VEC_CHECK_INFO MEM_STAT_INFO)) + (VEC_safe_push_1<T, A> (&(V), O VEC_CHECK_INFO MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline T & +VEC_safe_push_1 (vec_t<T> **vec_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL) +{ + VEC_reserve_1<T, A> (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); + return VEC_quick_push_1 (*vec_, obj_ VEC_CHECK_PASS); +} + +template<typename T, enum vec_allocation_t A> +static inline T * +VEC_safe_push_1 (vec_t<T> **vec_, const T *ptr_ VEC_CHECK_DECL MEM_STAT_DECL) +{ + VEC_reserve_1<T, A> (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); + return VEC_quick_push_1 (*vec_, ptr_ VEC_CHECK_PASS); +} + /* Pop element off end T VEC_T_pop (VEC(T) *v); // Integer @@ -336,7 +762,16 @@ along with GCC; see the file COPYING3. If not see Pop the last element off the end. Returns the element popped, for pointer vectors. */ -#define VEC_pop(T,V) (VEC_OP(T,base,pop)(VEC_BASE(V) VEC_CHECK_INFO)) +#define VEC_pop(T,V) (VEC_pop_1<T> (V VEC_CHECK_INFO)) + +template<typename T> +static inline T& +VEC_pop_1 (vec_t<T> *vec_ VEC_CHECK_DECL) +{ + VEC_ASSERT (vec_->prefix.num, "pop", T, base); + return vec_->vec[--vec_->prefix.num]; +} + /* Truncate to specific length void VEC_T_truncate (VEC(T) *v, unsigned len); @@ -344,8 +779,18 @@ along with GCC; see the file COPYING3. If not see Set the length as specified. The new length must be less than or equal to the current length. This is an O(1) operation. */ -#define VEC_truncate(T,V,I) \ - (VEC_OP(T,base,truncate)(VEC_BASE(V),I VEC_CHECK_INFO)) +#define VEC_truncate(T,V,I) \ + (VEC_truncate_1<T> (V, (unsigned)(I) VEC_CHECK_INFO)) + +template<typename T> +static inline void +VEC_truncate_1 (vec_t<T> *vec_, unsigned size_ VEC_CHECK_DECL) +{ + VEC_ASSERT (vec_ ? vec_->prefix.num >= size_ : !size_, "truncate", T, base); + if (vec_) + vec_->prefix.num = size_; +} + /* Grow to a specific length. void VEC_T_A_safe_grow (VEC(T,A) *&v, int len); @@ -355,7 +800,20 @@ along with GCC; see the file COPYING3. If not see uninitialized. */ #define VEC_safe_grow(T,A,V,I) \ - (VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO)) + (VEC_safe_grow_1<T, A> (&(V), (int)(I) VEC_CHECK_INFO MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline void +VEC_safe_grow_1 (vec_t<T> **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) +{ + VEC_ASSERT (size_ >= 0 && VEC_length (T, *vec_) <= (unsigned)size_, + "grow", T, A); + VEC_reserve_exact_1<T, A> (vec_, + size_ - (int)(*vec_ ? (*vec_)->prefix.num : 0) + VEC_CHECK_PASS PASS_MEM_STAT); + (*vec_)->prefix.num = size_; +} + /* Grow to a specific length. void VEC_T_A_safe_grow_cleared (VEC(T,A) *&v, int len); @@ -364,8 +822,21 @@ along with GCC; see the file COPYING3. If not see long or longer than the current length. The new elements are initialized to zero. */ -#define VEC_safe_grow_cleared(T,A,V,I) \ - (VEC_OP(T,A,safe_grow_cleared)(&(V),I VEC_CHECK_INFO MEM_STAT_INFO)) +#define VEC_safe_grow_cleared(T,A,V,I) \ + (VEC_safe_grow_cleared_1<T,A> (&(V), (int)(I) \ + VEC_CHECK_INFO MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline void +VEC_safe_grow_cleared_1 (vec_t<T> **vec_, int size_ VEC_CHECK_DECL + MEM_STAT_DECL) +{ + int oldsize = VEC_length (T, *vec_); + VEC_safe_grow_1<T, A> (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT); + memset (&(VEC_address (T, *vec_)[oldsize]), 0, + sizeof (T) * (size_ - oldsize)); +} + /* Replace element T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer @@ -379,20 +850,57 @@ along with GCC; see the file COPYING3. If not see performed. */ #define VEC_replace(T,V,I,O) \ - (VEC_OP(T,base,replace)(VEC_BASE(V),I,O VEC_CHECK_INFO)) + (VEC_replace_1<T> (V, (unsigned)(I), O VEC_CHECK_INFO)) + +template<typename T> +static inline T& +VEC_replace_1 (vec_t<T> *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL) +{ + VEC_ASSERT (ix_ < vec_->prefix.num, "replace", T, base); + vec_->vec[ix_] = obj_; + return vec_->vec[ix_]; +} + /* Insert object with no reallocation - T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer - T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer - T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object + void VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer + void VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer + void VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object - Insert an element, VAL, at the IXth position of V. Return a pointer - to the slot created. For vectors of object, the new value can be - NULL, in which case no initialization of the inserted slot takes - place. There must be sufficient space. */ + Insert an element, VAL, at the IXth position of V. For vectors of + object, the new value can be NULL, in which case no initialization + of the inserted slot takes place. There must be sufficient space. */ #define VEC_quick_insert(T,V,I,O) \ - (VEC_OP(T,base,quick_insert)(VEC_BASE(V),I,O VEC_CHECK_INFO)) + (VEC_quick_insert_1<T> (V,I,O VEC_CHECK_INFO)) + +template<typename T> +static inline void +VEC_quick_insert_1 (vec_t<T> *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL) +{ + T *slot_; + + VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "insert", T, base); + VEC_ASSERT (ix_ <= vec_->prefix.num, "insert", T, base); + slot_ = &vec_->vec[ix_]; + memmove (slot_ + 1, slot_, (vec_->prefix.num++ - ix_) * sizeof (T)); + *slot_ = obj_; +} + +template<typename T> +static inline void +VEC_quick_insert_1 (vec_t<T> *vec_, unsigned ix_, const T *ptr_ VEC_CHECK_DECL) +{ + T *slot_; + + VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "insert", T, base); + VEC_ASSERT (ix_ <= vec_->prefix.num, "insert", T, base); + slot_ = &vec_->vec[ix_]; + memmove (slot_ + 1, slot_, (vec_->prefix.num++ - ix_) * sizeof (T)); + if (ptr_) + *slot_ = *ptr_; +} + /* Insert object with reallocation T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer @@ -405,31 +913,70 @@ along with GCC; see the file COPYING3. If not see place. Reallocate V, if necessary. */ #define VEC_safe_insert(T,A,V,I,O) \ - (VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO)) + (VEC_safe_insert_1<T, A> (&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO)) + +template<typename T, enum vec_allocation_t A> +static inline void +VEC_safe_insert_1 (vec_t<T> **vec_, unsigned ix_, T obj_ + VEC_CHECK_DECL MEM_STAT_DECL) +{ + VEC_reserve_1<T, A> (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); + VEC_quick_insert_1 (*vec_, ix_, obj_ VEC_CHECK_PASS); +} + +template<typename T, enum vec_allocation_t A> +static inline void +VEC_safe_insert_1 (vec_t<T> **vec_, unsigned ix_, T *ptr_ + VEC_CHECK_DECL MEM_STAT_DECL) +{ + VEC_reserve_1<T, A> (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); + VEC_quick_insert_1 (*vec_, ix_, ptr_ VEC_CHECK_PASS); +} + + /* Remove element retaining order - T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer - T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer + void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer + void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object Remove an element from the IXth position of V. Ordering of - remaining elements is preserved. For pointer vectors returns the - removed object. This is an O(N) operation due to a memmove. */ + remaining elements is preserved. This is an O(N) operation due to + a memmove. */ #define VEC_ordered_remove(T,V,I) \ - (VEC_OP(T,base,ordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO)) + (VEC_ordered_remove_1<T> (V,I VEC_CHECK_INFO)) + +template<typename T> +static inline void +VEC_ordered_remove_1 (vec_t<T> *vec_, unsigned ix_ VEC_CHECK_DECL) +{ + T *slot_; + VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base); + slot_ = &vec_->vec[ix_]; + memmove (slot_, slot_ + 1, (--vec_->prefix.num - ix_) * sizeof (T)); +} + /* Remove element destroying order - T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer - T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer + void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer + void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object - Remove an element from the IXth position of V. Ordering of - remaining elements is destroyed. For pointer vectors returns the - removed object. This is an O(1) operation. */ + Remove an element from the IXth position of V. Ordering of + remaining elements is destroyed. This is an O(1) operation. */ #define VEC_unordered_remove(T,V,I) \ - (VEC_OP(T,base,unordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO)) + (VEC_unordered_remove_1<T> (V,I VEC_CHECK_INFO)) + +template<typename T> +static inline void +VEC_unordered_remove_1 (vec_t<T> *vec_, unsigned ix_ VEC_CHECK_DECL) +{ + VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base); + vec_->vec[ix_] = vec_->vec[--vec_->prefix.num]; +} + /* Remove a block of elements void VEC_T_block_remove (VEC(T) *v, unsigned ix, unsigned len); @@ -438,22 +985,27 @@ along with GCC; see the file COPYING3. If not see This is an O(N) operation due to memmove. */ #define VEC_block_remove(T,V,I,L) \ - (VEC_OP(T,base,block_remove)(VEC_BASE(V),I,L VEC_CHECK_INFO)) + (VEC_block_remove_1<T> (V, I, L VEC_CHECK_INFO)) -/* Get the address of the array of elements - T *VEC_T_address (VEC(T) v) - - If you need to directly manipulate the array (for instance, you - want to feed it to qsort), use this accessor. */ +template<typename T> +static inline void +VEC_block_remove_1 (vec_t<T> *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL) +{ + T *slot_; + VEC_ASSERT (ix_ + len_ <= vec_->prefix.num, "block_remove", T, base); + slot_ = &vec_->vec[ix_]; + vec_->prefix.num -= len_; + memmove (slot_, slot_ + len_, (vec_->prefix.num - ix_) * sizeof (T)); +} -#define VEC_address(T,V) (VEC_OP(T,base,address)(VEC_BASE(V))) /* Conveniently sort the contents of the vector with qsort. void VEC_qsort (VEC(T) *v, int (*cmp_func)(const void *, const void *)) */ -#define VEC_qsort(T,V,CMP) qsort(VEC_address (T,V), VEC_length(T,V), \ +#define VEC_qsort(T,V,CMP) qsort(VEC_address (T, V), VEC_length (T, V), \ sizeof (T), CMP) + /* Find the first index in the vector not less than the object. unsigned VEC_T_lower_bound (VEC(T) *v, const T val, bool (*lessthan) (const T, const T)); // Integer @@ -466,955 +1018,140 @@ along with GCC; see the file COPYING3. If not see changing the ordering of V. LESSTHAN is a function that returns true if the first argument is strictly less than the second. */ -#define VEC_lower_bound(T,V,O,LT) \ - (VEC_OP(T,base,lower_bound)(VEC_BASE(V),O,LT VEC_CHECK_INFO)) +#define VEC_lower_bound(T,V,O,LT) \ + (VEC_lower_bound_1<T> (V, O, LT VEC_CHECK_INFO)) -/* Reallocate an array of elements with prefix. */ -extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL); -extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL); -extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL); -extern void *vec_gc_o_reserve_exact (void *, int, size_t, size_t - MEM_STAT_DECL); -extern void ggc_free (void *); -#define vec_gc_free(V) ggc_free (V) -extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL); -extern void *vec_heap_p_reserve_exact (void *, int MEM_STAT_DECL); -extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL); -extern void *vec_heap_o_reserve_exact (void *, int, size_t, size_t - MEM_STAT_DECL); -extern void dump_vec_loc_statistics (void); -extern void vec_heap_free (void *); - -#if ENABLE_CHECKING -#define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__ -#define VEC_CHECK_DECL ,const char *file_,unsigned line_,const char *function_ -#define VEC_CHECK_PASS ,file_,line_,function_ - -#define VEC_ASSERT(EXPR,OP,T,A) \ - (void)((EXPR) ? 0 : (VEC_ASSERT_FAIL(OP,VEC(T,A)), 0)) - -extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL) - ATTRIBUTE_NORETURN; -#define VEC_ASSERT_FAIL(OP,VEC) vec_assert_fail (OP,#VEC VEC_CHECK_PASS) -#else -#define VEC_CHECK_INFO -#define VEC_CHECK_DECL -#define VEC_CHECK_PASS -#define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR) -#endif - -/* Note: gengtype has hardwired knowledge of the expansions of the - VEC, DEF_VEC_*, and DEF_VEC_ALLOC_* macros. If you change the - expansions of these macros you may need to change gengtype too. */ - -typedef struct GTY(()) vec_prefix +template<typename T> +static inline unsigned +VEC_lower_bound_1 (vec_t<T> *vec_, T obj_, + bool (*lessthan_)(T, T) VEC_CHECK_DECL) { - unsigned num; - unsigned alloc; -} vec_prefix; - -#define VEC(T,A) VEC_##T##_##A -#define VEC_OP(T,A,OP) VEC_##T##_##A##_##OP - -/* Base of vector type, not user visible. */ -#define VEC_T(T,B) \ -typedef struct VEC(T,B) \ -{ \ - struct vec_prefix prefix; \ - T vec[1]; \ -} VEC(T,B) - -#define VEC_T_GTY(T,B) \ -typedef struct GTY(()) VEC(T,B) \ -{ \ - struct vec_prefix prefix; \ - T GTY ((length ("%h.prefix.num"))) vec[1]; \ -} VEC(T,B) - -#define VEC_T_GTY_ATOMIC(T,B) \ -typedef struct GTY(()) VEC(T,B) \ -{ \ - struct vec_prefix prefix; \ - T GTY ((atomic)) vec[1]; \ -} VEC(T,B) - -/* Derived vector type, user visible. */ -#define VEC_TA_GTY(T,B,A,GTY) \ -typedef struct GTY VEC(T,A) \ -{ \ - VEC(T,B) base; \ -} VEC(T,A) - -#define VEC_TA(T,B,A) \ -typedef struct VEC(T,A) \ -{ \ - VEC(T,B) base; \ -} VEC(T,A) - -/* Convert to base type. */ -#if GCC_VERSION >= 4000 -#define VEC_BASE(P) \ - ((offsetof (__typeof (*P), base) == 0 || (P)) ? &(P)->base : 0) -#else -#define VEC_BASE(P) ((P) ? &(P)->base : 0) -#endif - -/* Vector of integer-like object. */ -#define DEF_VEC_I(T) \ -static inline void VEC_OP (T,must_be,integral_type) (void) \ -{ \ - (void)~(T)0; \ -} \ - \ -VEC_T(T,base); \ -VEC_TA(T,base,none); \ -DEF_VEC_FUNC_P(T) \ -struct vec_swallow_trailing_semi -#define DEF_VEC_ALLOC_I(T,A) \ -VEC_TA(T,base,A); \ -DEF_VEC_ALLOC_FUNC_I(T,A) \ -DEF_VEC_NONALLOC_FUNCS_I(T,A) \ -struct vec_swallow_trailing_semi - -/* Vector of pointer to object. */ -#define DEF_VEC_P(T) \ -static inline void VEC_OP (T,must_be,pointer_type) (void) \ -{ \ - (void)((T)1 == (void *)1); \ -} \ - \ -VEC_T_GTY(T,base); \ -VEC_TA(T,base,none); \ -DEF_VEC_FUNC_P(T) \ -struct vec_swallow_trailing_semi -#define DEF_VEC_ALLOC_P(T,A) \ -VEC_TA(T,base,A); \ -DEF_VEC_ALLOC_FUNC_P(T,A) \ -DEF_VEC_NONALLOC_FUNCS_P(T,A) \ -struct vec_swallow_trailing_semi - -#define DEF_VEC_FUNC_P(T) \ -static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \ -{ \ - return vec_ ? vec_->prefix.num : 0; \ -} \ - \ -static inline T VEC_OP (T,base,last) \ - (const VEC(T,base) *vec_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (vec_ && vec_->prefix.num, "last", T, base); \ - \ - return vec_->vec[vec_->prefix.num - 1]; \ -} \ - \ -static inline T VEC_OP (T,base,index) \ - (const VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (vec_ && ix_ < vec_->prefix.num, "index", T, base); \ - \ - return vec_->vec[ix_]; \ -} \ - \ -static inline int VEC_OP (T,base,iterate) \ - (const VEC(T,base) *vec_, unsigned ix_, T *ptr) \ -{ \ - if (vec_ && ix_ < vec_->prefix.num) \ - { \ - *ptr = vec_->vec[ix_]; \ - return 1; \ - } \ - else \ - { \ - *ptr = (T) 0; \ - return 0; \ - } \ -} \ - \ -static inline size_t VEC_OP (T,base,embedded_size) \ - (int alloc_) \ -{ \ - return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T); \ -} \ - \ -static inline void VEC_OP (T,base,embedded_init) \ - (VEC(T,base) *vec_, int alloc_) \ -{ \ - vec_->prefix.num = 0; \ - vec_->prefix.alloc = alloc_; \ -} \ - \ -static inline int VEC_OP (T,base,space) \ - (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (alloc_ >= 0, "space", T, base); \ - return vec_ ? vec_->prefix.alloc - vec_->prefix.num >= (unsigned)alloc_ : !alloc_; \ -} \ - \ -static inline void VEC_OP(T,base,splice) \ - (VEC(T,base) *dst_, VEC(T,base) *src_ VEC_CHECK_DECL) \ -{ \ - if (src_) \ - { \ - unsigned len_ = src_->prefix.num; \ - VEC_ASSERT (dst_->prefix.num + len_ <= dst_->prefix.alloc, "splice", T, base); \ - \ - memcpy (&dst_->vec[dst_->prefix.num], &src_->vec[0], len_ * sizeof (T)); \ - dst_->prefix.num += len_; \ - } \ -} \ - \ -static inline T *VEC_OP (T,base,quick_push) \ - (VEC(T,base) *vec_, T obj_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "push", T, base); \ - slot_ = &vec_->vec[vec_->prefix.num++]; \ - *slot_ = obj_; \ - \ - return slot_; \ -} \ - \ -static inline T VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL) \ -{ \ - T obj_; \ - \ - VEC_ASSERT (vec_->prefix.num, "pop", T, base); \ - obj_ = vec_->vec[--vec_->prefix.num]; \ - \ - return obj_; \ -} \ - \ -static inline void VEC_OP (T,base,truncate) \ - (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (vec_ ? vec_->prefix.num >= size_ : !size_, "truncate", T, base); \ - if (vec_) \ - vec_->prefix.num = size_; \ -} \ - \ -static inline T VEC_OP (T,base,replace) \ - (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL) \ -{ \ - T old_obj_; \ - \ - VEC_ASSERT (ix_ < vec_->prefix.num, "replace", T, base); \ - old_obj_ = vec_->vec[ix_]; \ - vec_->vec[ix_] = obj_; \ - \ - return old_obj_; \ -} \ - \ -static inline T *VEC_OP (T,base,quick_insert) \ - (VEC(T,base) *vec_, unsigned ix_, T obj_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "insert", T, base); \ - VEC_ASSERT (ix_ <= vec_->prefix.num, "insert", T, base); \ - slot_ = &vec_->vec[ix_]; \ - memmove (slot_ + 1, slot_, (vec_->prefix.num++ - ix_) * sizeof (T)); \ - *slot_ = obj_; \ - \ - return slot_; \ -} \ - \ -static inline T VEC_OP (T,base,ordered_remove) \ - (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - T obj_; \ - \ - VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base); \ - slot_ = &vec_->vec[ix_]; \ - obj_ = *slot_; \ - memmove (slot_, slot_ + 1, (--vec_->prefix.num - ix_) * sizeof (T)); \ - \ - return obj_; \ -} \ - \ -static inline T VEC_OP (T,base,unordered_remove) \ - (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - T obj_; \ - \ - VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base); \ - slot_ = &vec_->vec[ix_]; \ - obj_ = *slot_; \ - *slot_ = vec_->vec[--vec_->prefix.num]; \ - \ - return obj_; \ -} \ - \ -static inline void VEC_OP (T,base,block_remove) \ - (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (ix_ + len_ <= vec_->prefix.num, "block_remove", T, base); \ - slot_ = &vec_->vec[ix_]; \ - vec_->prefix.num -= len_; \ - memmove (slot_, slot_ + len_, (vec_->prefix.num - ix_) * sizeof (T)); \ -} \ - \ -static inline T *VEC_OP (T,base,address) \ - (VEC(T,base) *vec_) \ -{ \ - return vec_ ? vec_->vec : 0; \ -} \ - \ -static inline unsigned VEC_OP (T,base,lower_bound) \ - (VEC(T,base) *vec_, const T obj_, \ - bool (*lessthan_)(const T, const T) VEC_CHECK_DECL) \ -{ \ - unsigned int len_ = VEC_OP (T,base, length) (vec_); \ - unsigned int half_, middle_; \ - unsigned int first_ = 0; \ - while (len_ > 0) \ - { \ - T middle_elem_; \ - half_ = len_ >> 1; \ - middle_ = first_; \ - middle_ += half_; \ - middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \ - if (lessthan_ (middle_elem_, obj_)) \ - { \ - first_ = middle_; \ - ++first_; \ - len_ = len_ - half_ - 1; \ - } \ - else \ - len_ = half_; \ - } \ - return first_; \ + unsigned int len_ = VEC_length (T, vec_); + unsigned int half_, middle_; + unsigned int first_ = 0; + while (len_ > 0) + { + T middle_elem_; + half_ = len_ >> 1; + middle_ = first_; + middle_ += half_; + middle_elem_ = VEC_index_1 (vec_, middle_ VEC_CHECK_PASS); + if (lessthan_ (middle_elem_, obj_)) + { + first_ = middle_; + ++first_; + len_ = len_ - half_ - 1; + } + else + len_ = half_; + } + return first_; } -#define DEF_VEC_ALLOC_FUNC_P(T,A) \ -static inline VEC(T,A) *VEC_OP (T,A,alloc) \ - (int alloc_ MEM_STAT_DECL) \ -{ \ - return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \ - PASS_MEM_STAT); \ -} - - -#define DEF_VEC_NONALLOC_FUNCS_P(T,A) \ -static inline void VEC_OP (T,A,free) \ - (VEC(T,A) **vec_) \ -{ \ - if (*vec_) \ - vec_##A##_free (*vec_); \ - *vec_ = NULL; \ -} \ - \ -static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ -{ \ - size_t len_ = vec_ ? vec_->prefix.num : 0; \ - VEC (T,A) *new_vec_ = NULL; \ - \ - if (len_) \ - { \ - new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact \ - (NULL, len_ PASS_MEM_STAT)); \ - \ - new_vec_->base.prefix.num = len_; \ - memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \ - } \ - return new_vec_; \ -} \ - \ -static inline int VEC_OP (T,A,reserve) \ - (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \ - VEC_CHECK_PASS); \ - \ - if (extend) \ - *vec_ = (VEC(T,A) *) vec_##A##_p_reserve (*vec_, alloc_ PASS_MEM_STAT); \ - \ - return extend; \ -} \ - \ -static inline int VEC_OP (T,A,reserve_exact) \ - (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \ - VEC_CHECK_PASS); \ - \ - if (extend) \ - *vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_ \ - PASS_MEM_STAT); \ - \ - return extend; \ -} \ - \ -static inline void VEC_OP (T,A,safe_grow) \ - (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_ASSERT (size_ >= 0 \ - && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \ - "grow", T, A); \ - VEC_OP (T,A,reserve_exact) (vec_, \ - size_ - (int)(*vec_ ? VEC_BASE(*vec_)->prefix.num : 0) \ - VEC_CHECK_PASS PASS_MEM_STAT); \ - VEC_BASE (*vec_)->prefix.num = size_; \ -} \ - \ -static inline void VEC_OP (T,A,safe_grow_cleared) \ - (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_); \ - VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT); \ - memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0, \ - sizeof (T) * (size_ - oldsize)); \ -} \ - \ -static inline void VEC_OP(T,A,safe_splice) \ - (VEC(T,A) **dst_, VEC(T,base) *src_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - if (src_) \ - { \ - VEC_OP (T,A,reserve_exact) (dst_, src_->prefix.num \ - VEC_CHECK_PASS MEM_STAT_INFO); \ - \ - VEC_OP (T,base,splice) (VEC_BASE (*dst_), src_ \ - VEC_CHECK_PASS); \ - } \ -} \ - \ -static inline T *VEC_OP (T,A,safe_push) \ - (VEC(T,A) **vec_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \ - \ - return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \ -} \ - \ -static inline T *VEC_OP (T,A,safe_insert) \ - (VEC(T,A) **vec_, unsigned ix_, T obj_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \ - \ - return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \ - VEC_CHECK_PASS); \ -} - -/* Vector of object. */ -#define DEF_VEC_O(T) \ -VEC_T_GTY(T,base); \ -VEC_TA(T,base,none); \ -DEF_VEC_FUNC_O(T) \ -struct vec_swallow_trailing_semi -#define DEF_VEC_ALLOC_O(T,A) \ -VEC_TA(T,base,A); \ -DEF_VEC_ALLOC_FUNC_O(T,A) \ -DEF_VEC_NONALLOC_FUNCS_O(T,A) \ -struct vec_swallow_trailing_semi - -/* Vector of atomic object. */ -#define DEF_VEC_A(T) \ -VEC_T_GTY_ATOMIC(T,base); \ -VEC_TA(T,base,none); \ -DEF_VEC_FUNC_O(T) \ -struct vec_swallow_trailing_semi -#define DEF_VEC_ALLOC_A(T,A) DEF_VEC_ALLOC_O(T,A) - -#define DEF_VEC_FUNC_O(T) \ -static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \ -{ \ - return vec_ ? vec_->prefix.num : 0; \ -} \ - \ -static inline T *VEC_OP (T,base,last) (VEC(T,base) *vec_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (vec_ && vec_->prefix.num, "last", T, base); \ - \ - return &vec_->vec[vec_->prefix.num - 1]; \ -} \ - \ -static inline T *VEC_OP (T,base,index) \ - (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (vec_ && ix_ < vec_->prefix.num, "index", T, base); \ - \ - return &vec_->vec[ix_]; \ -} \ - \ -static inline int VEC_OP (T,base,iterate) \ - (VEC(T,base) *vec_, unsigned ix_, T **ptr) \ -{ \ - if (vec_ && ix_ < vec_->prefix.num) \ - { \ - *ptr = &vec_->vec[ix_]; \ - return 1; \ - } \ - else \ - { \ - *ptr = 0; \ - return 0; \ - } \ -} \ - \ -static inline size_t VEC_OP (T,base,embedded_size) \ - (int alloc_) \ -{ \ - return offsetof (VEC(T,base),vec) + alloc_ * sizeof(T); \ -} \ - \ -static inline void VEC_OP (T,base,embedded_init) \ - (VEC(T,base) *vec_, int alloc_) \ -{ \ - vec_->prefix.num = 0; \ - vec_->prefix.alloc = alloc_; \ -} \ - \ -static inline int VEC_OP (T,base,space) \ - (VEC(T,base) *vec_, int alloc_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (alloc_ >= 0, "space", T, base); \ - return vec_ ? vec_->prefix.alloc - vec_->prefix.num >= (unsigned)alloc_ : !alloc_; \ -} \ - \ -static inline void VEC_OP(T,base,splice) \ - (VEC(T,base) *dst_, VEC(T,base) *src_ VEC_CHECK_DECL) \ -{ \ - if (src_) \ - { \ - unsigned len_ = src_->prefix.num; \ - VEC_ASSERT (dst_->prefix.num + len_ <= dst_->prefix.alloc, "splice", T, base); \ - \ - memcpy (&dst_->vec[dst_->prefix.num], &src_->vec[0], len_ * sizeof (T)); \ - dst_->prefix.num += len_; \ - } \ -} \ - \ -static inline T *VEC_OP (T,base,quick_push) \ - (VEC(T,base) *vec_, const T *obj_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "push", T, base); \ - slot_ = &vec_->vec[vec_->prefix.num++]; \ - if (obj_) \ - *slot_ = *obj_; \ - \ - return slot_; \ -} \ - \ -static inline void VEC_OP (T,base,pop) (VEC(T,base) *vec_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (vec_->prefix.num, "pop", T, base); \ - --vec_->prefix.num; \ -} \ - \ -static inline void VEC_OP (T,base,truncate) \ - (VEC(T,base) *vec_, unsigned size_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (vec_ ? vec_->prefix.num >= size_ : !size_, "truncate", T, base); \ - if (vec_) \ - vec_->prefix.num = size_; \ -} \ - \ -static inline T *VEC_OP (T,base,replace) \ - (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (ix_ < vec_->prefix.num, "replace", T, base); \ - slot_ = &vec_->vec[ix_]; \ - if (obj_) \ - *slot_ = *obj_; \ - \ - return slot_; \ -} \ - \ -static inline T *VEC_OP (T,base,quick_insert) \ - (VEC(T,base) *vec_, unsigned ix_, const T *obj_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (vec_->prefix.num < vec_->prefix.alloc, "insert", T, base); \ - VEC_ASSERT (ix_ <= vec_->prefix.num, "insert", T, base); \ - slot_ = &vec_->vec[ix_]; \ - memmove (slot_ + 1, slot_, (vec_->prefix.num++ - ix_) * sizeof (T)); \ - if (obj_) \ - *slot_ = *obj_; \ - \ - return slot_; \ -} \ - \ -static inline void VEC_OP (T,base,ordered_remove) \ - (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base); \ - slot_ = &vec_->vec[ix_]; \ - memmove (slot_, slot_ + 1, (--vec_->prefix.num - ix_) * sizeof (T)); \ -} \ - \ -static inline void VEC_OP (T,base,unordered_remove) \ - (VEC(T,base) *vec_, unsigned ix_ VEC_CHECK_DECL) \ -{ \ - VEC_ASSERT (ix_ < vec_->prefix.num, "remove", T, base); \ - vec_->vec[ix_] = vec_->vec[--vec_->prefix.num]; \ -} \ - \ -static inline void VEC_OP (T,base,block_remove) \ - (VEC(T,base) *vec_, unsigned ix_, unsigned len_ VEC_CHECK_DECL) \ -{ \ - T *slot_; \ - \ - VEC_ASSERT (ix_ + len_ <= vec_->prefix.num, "block_remove", T, base); \ - slot_ = &vec_->vec[ix_]; \ - vec_->prefix.num -= len_; \ - memmove (slot_, slot_ + len_, (vec_->prefix.num - ix_) * sizeof (T)); \ -} \ - \ -static inline T *VEC_OP (T,base,address) \ - (VEC(T,base) *vec_) \ -{ \ - return vec_ ? vec_->vec : 0; \ -} \ - \ -static inline unsigned VEC_OP (T,base,lower_bound) \ - (VEC(T,base) *vec_, const T *obj_, \ - bool (*lessthan_)(const T *, const T *) VEC_CHECK_DECL) \ -{ \ - unsigned int len_ = VEC_OP (T, base, length) (vec_); \ - unsigned int half_, middle_; \ - unsigned int first_ = 0; \ - while (len_ > 0) \ - { \ - T *middle_elem_; \ - half_ = len_ >> 1; \ - middle_ = first_; \ - middle_ += half_; \ - middle_elem_ = VEC_OP (T,base,index) (vec_, middle_ VEC_CHECK_PASS); \ - if (lessthan_ (middle_elem_, obj_)) \ - { \ - first_ = middle_; \ - ++first_; \ - len_ = len_ - half_ - 1; \ - } \ - else \ - len_ = half_; \ - } \ - return first_; \ -} - -#define DEF_VEC_ALLOC_FUNC_O(T,A) \ -static inline VEC(T,A) *VEC_OP (T,A,alloc) \ - (int alloc_ MEM_STAT_DECL) \ -{ \ - return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_, \ - offsetof (VEC(T,A),base.vec), \ - sizeof (T) \ - PASS_MEM_STAT); \ -} - -#define DEF_VEC_NONALLOC_FUNCS_O(T,A) \ -static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ -{ \ - size_t len_ = vec_ ? vec_->prefix.num : 0; \ - VEC (T,A) *new_vec_ = NULL; \ - \ - if (len_) \ - { \ - new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \ - (NULL, len_, \ - offsetof (VEC(T,A),base.vec), sizeof (T) \ - PASS_MEM_STAT)); \ - \ - new_vec_->base.prefix.num = len_; \ - memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \ - } \ - return new_vec_; \ -} \ - \ -static inline void VEC_OP (T,A,free) \ - (VEC(T,A) **vec_) \ -{ \ - if (*vec_) \ - vec_##A##_free (*vec_); \ - *vec_ = NULL; \ -} \ - \ -static inline int VEC_OP (T,A,reserve) \ - (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \ - VEC_CHECK_PASS); \ - \ - if (extend) \ - *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_, \ - offsetof (VEC(T,A),base.vec),\ - sizeof (T) \ - PASS_MEM_STAT); \ - \ - return extend; \ -} \ - \ -static inline int VEC_OP (T,A,reserve_exact) \ - (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \ - VEC_CHECK_PASS); \ - \ - if (extend) \ - *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \ - (*vec_, alloc_, \ - offsetof (VEC(T,A),base.vec), \ - sizeof (T) PASS_MEM_STAT); \ - \ - return extend; \ -} \ - \ -static inline void VEC_OP (T,A,safe_grow) \ - (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_ASSERT (size_ >= 0 \ - && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \ - "grow", T, A); \ - VEC_OP (T,A,reserve_exact) (vec_, \ - size_ - (int)(*vec_ ? VEC_BASE(*vec_)->prefix.num : 0) \ - VEC_CHECK_PASS PASS_MEM_STAT); \ - VEC_BASE (*vec_)->prefix.num = size_; \ -} \ - \ -static inline void VEC_OP (T,A,safe_grow_cleared) \ - (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_); \ - VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT); \ - memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0, \ - sizeof (T) * (size_ - oldsize)); \ -} \ - \ -static inline void VEC_OP(T,A,safe_splice) \ - (VEC(T,A) **dst_, VEC(T,base) *src_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - if (src_) \ - { \ - VEC_OP (T,A,reserve_exact) (dst_, src_->prefix.num \ - VEC_CHECK_PASS MEM_STAT_INFO); \ - \ - VEC_OP (T,base,splice) (VEC_BASE (*dst_), src_ \ - VEC_CHECK_PASS); \ - } \ -} \ - \ -static inline T *VEC_OP (T,A,safe_push) \ - (VEC(T,A) **vec_, const T *obj_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \ - \ - return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \ -} \ - \ -static inline T *VEC_OP (T,A,safe_insert) \ - (VEC(T,A) **vec_, unsigned ix_, const T *obj_ \ - VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \ - \ - return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \ - VEC_CHECK_PASS); \ -} - -#define DEF_VEC_ALLOC_FUNC_I(T,A) \ -static inline VEC(T,A) *VEC_OP (T,A,alloc) \ - (int alloc_ MEM_STAT_DECL) \ -{ \ - return (VEC(T,A) *) vec_##A##_o_reserve_exact \ - (NULL, alloc_, offsetof (VEC(T,A),base.vec), \ - sizeof (T) PASS_MEM_STAT); \ -} - -#define DEF_VEC_NONALLOC_FUNCS_I(T,A) \ -static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ -{ \ - size_t len_ = vec_ ? vec_->prefix.num : 0; \ - VEC (T,A) *new_vec_ = NULL; \ - \ - if (len_) \ - { \ - new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \ - (NULL, len_, \ - offsetof (VEC(T,A),base.vec), sizeof (T) \ - PASS_MEM_STAT)); \ - \ - new_vec_->base.prefix.num = len_; \ - memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \ - } \ - return new_vec_; \ -} \ - \ -static inline void VEC_OP (T,A,free) \ - (VEC(T,A) **vec_) \ -{ \ - if (*vec_) \ - vec_##A##_free (*vec_); \ - *vec_ = NULL; \ -} \ - \ -static inline int VEC_OP (T,A,reserve) \ - (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \ - VEC_CHECK_PASS); \ - \ - if (extend) \ - *vec_ = (VEC(T,A) *) vec_##A##_o_reserve (*vec_, alloc_, \ - offsetof (VEC(T,A),base.vec),\ - sizeof (T) \ - PASS_MEM_STAT); \ - \ - return extend; \ -} \ - \ -static inline int VEC_OP (T,A,reserve_exact) \ - (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \ - VEC_CHECK_PASS); \ - \ - if (extend) \ - *vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \ - (*vec_, alloc_, offsetof (VEC(T,A),base.vec), \ - sizeof (T) PASS_MEM_STAT); \ - \ - return extend; \ -} \ - \ -static inline void VEC_OP (T,A,safe_grow) \ - (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_ASSERT (size_ >= 0 \ - && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \ - "grow", T, A); \ - VEC_OP (T,A,reserve_exact) (vec_, \ - size_ - (int)(*vec_ ? VEC_BASE(*vec_)->prefix.num : 0) \ - VEC_CHECK_PASS PASS_MEM_STAT); \ - VEC_BASE (*vec_)->prefix.num = size_; \ -} \ - \ -static inline void VEC_OP (T,A,safe_grow_cleared) \ - (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - int oldsize = VEC_OP(T,base,length) VEC_BASE(*vec_); \ - VEC_OP (T,A,safe_grow) (vec_, size_ VEC_CHECK_PASS PASS_MEM_STAT); \ - memset (&(VEC_OP (T,base,address) VEC_BASE(*vec_))[oldsize], 0, \ - sizeof (T) * (size_ - oldsize)); \ -} \ - \ -static inline void VEC_OP(T,A,safe_splice) \ - (VEC(T,A) **dst_, VEC(T,base) *src_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - if (src_) \ - { \ - VEC_OP (T,A,reserve_exact) (dst_, src_->prefix.num \ - VEC_CHECK_PASS MEM_STAT_INFO); \ - \ - VEC_OP (T,base,splice) (VEC_BASE (*dst_), src_ \ - VEC_CHECK_PASS); \ - } \ -} \ - \ -static inline T *VEC_OP (T,A,safe_push) \ - (VEC(T,A) **vec_, const T obj_ VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \ - \ - return VEC_OP (T,base,quick_push) (VEC_BASE(*vec_), obj_ VEC_CHECK_PASS); \ -} \ - \ -static inline T *VEC_OP (T,A,safe_insert) \ - (VEC(T,A) **vec_, unsigned ix_, const T obj_ \ - VEC_CHECK_DECL MEM_STAT_DECL) \ -{ \ - VEC_OP (T,A,reserve) (vec_, 1 VEC_CHECK_PASS PASS_MEM_STAT); \ - \ - return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \ - VEC_CHECK_PASS); \ +template<typename T> +static inline unsigned +VEC_lower_bound_1 (vec_t<T> *vec_, const T *ptr_, + bool (*lessthan_)(const T*, const T*) VEC_CHECK_DECL) +{ + unsigned int len_ = VEC_length (T, vec_); + unsigned int half_, middle_; + unsigned int first_ = 0; + while (len_ > 0) + { + T *middle_elem_; + half_ = len_ >> 1; + middle_ = first_; + middle_ += half_; + middle_elem_ = &VEC_index_1 (vec_, middle_ VEC_CHECK_PASS); + if (lessthan_ (middle_elem_, ptr_)) + { + first_ = middle_; + ++first_; + len_ = len_ - half_ - 1; + } + else + len_ = half_; + } + return first_; } -/* We support a vector which starts out with space on the stack and - switches to heap space when forced to reallocate. This works a - little differently. Instead of DEF_VEC_ALLOC_P(TYPE, heap|gc), use - DEF_VEC_ALLOC_P_STACK(TYPE). This uses alloca to get the initial - space; because alloca can not be usefully called in an inline - function, and because a macro can not define a macro, you must then - write a #define for each type: - #define VEC_{TYPE}_stack_alloc(alloc) \ - VEC_stack_alloc({TYPE}, alloc) +void *vec_heap_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL); +void *vec_gc_o_reserve_1 (void *, int, size_t, size_t, bool MEM_STAT_DECL); - This is really a hack and perhaps can be made better. Note that - this macro will wind up evaluating the ALLOC parameter twice. +/* Ensure there are at least RESERVE free slots in VEC_, growing + exponentially. If RESERVE < 0 grow exactly, else grow + exponentially. As a special case, if VEC_ is NULL, and RESERVE is + 0, no vector will be created. */ - Only the initial allocation will be made using alloca, so pass a - reasonable estimate that doesn't use too much stack space; don't - pass zero. Don't return a VEC(TYPE,stack) vector from the function - which allocated it. */ - -extern void *vec_stack_p_reserve (void *, int MEM_STAT_DECL); -extern void *vec_stack_p_reserve_exact (void *, int MEM_STAT_DECL); -extern void *vec_stack_p_reserve_exact_1 (int, void *); -extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL); -extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t - MEM_STAT_DECL); -extern void vec_stack_free (void *); - -/* Unfortunately, we cannot use MEM_STAT_DECL here. */ -#if GATHER_STATISTICS -#define VEC_stack_alloc(T,alloc,name,line,function) \ - (VEC_OP (T,stack,alloc1) \ - (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc)))) -#else -#define VEC_stack_alloc(T,alloc) \ - (VEC_OP (T,stack,alloc1) \ - (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc)))) -#endif - -#define DEF_VEC_ALLOC_P_STACK(T) \ -VEC_TA(T,base,stack); \ -DEF_VEC_ALLOC_FUNC_P_STACK(T) \ -DEF_VEC_NONALLOC_FUNCS_P(T,stack) \ -struct vec_swallow_trailing_semi - -#define DEF_VEC_ALLOC_FUNC_P_STACK(T) \ -static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \ - (int alloc_, VEC(T,stack)* space) \ -{ \ - return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \ +template<typename T, enum vec_allocation_t A> +vec_t<T> * +vec_reserve (vec_t<T> *vec_, int reserve MEM_STAT_DECL) +{ + if (A == gc) + return (vec_t<T> *) vec_gc_o_reserve_1 (vec_, reserve, + offsetof (vec_t<T>, vec), + sizeof (T), false + PASS_MEM_STAT); + else if (A == heap) + return (vec_t<T> *) vec_heap_o_reserve_1 (vec_, reserve, + offsetof (vec_t<T>, vec), + sizeof (T), false + PASS_MEM_STAT); + else + { + /* Only allow stack vectors when re-growing them. The initial + allocation of stack vectors must be done with the + VEC_stack_alloc macro, because it uses alloca() for the + allocation. */ + if (vec_ == NULL) + { + fprintf (stderr, "Stack vectors must be initially allocated " + "with VEC_stack_alloc.\n"); + gcc_unreachable (); + } + return (vec_t<T> *) vec_stack_o_reserve (vec_, reserve, + offsetof (vec_t<T>, vec), + sizeof (T) PASS_MEM_STAT); + } } -#define DEF_VEC_ALLOC_O_STACK(T) \ -VEC_TA(T,base,stack); \ -DEF_VEC_ALLOC_FUNC_O_STACK(T) \ -DEF_VEC_NONALLOC_FUNCS_O(T,stack) \ -struct vec_swallow_trailing_semi -#define DEF_VEC_ALLOC_FUNC_O_STACK(T) \ -static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \ - (int alloc_, VEC(T,stack)* space) \ -{ \ - return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \ -} - -#define DEF_VEC_ALLOC_I_STACK(T) \ -VEC_TA(T,base,stack); \ -DEF_VEC_ALLOC_FUNC_I_STACK(T) \ -DEF_VEC_NONALLOC_FUNCS_I(T,stack) \ -struct vec_swallow_trailing_semi +/* Ensure there are at least RESERVE free slots in VEC_, growing + exactly. If RESERVE < 0 grow exactly, else grow exponentially. As + a special case, if VEC_ is NULL, and RESERVE is 0, no vector will be + created. */ -#define DEF_VEC_ALLOC_FUNC_I_STACK(T) \ -static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \ - (int alloc_, VEC(T,stack)* space) \ -{ \ - return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \ +template<typename T, enum vec_allocation_t A> +vec_t<T> * +vec_reserve_exact (vec_t<T> *vec_, int reserve MEM_STAT_DECL) +{ + if (A == gc) + return (vec_t<T> *) vec_gc_o_reserve_1 (vec_, reserve, + sizeof (struct vec_prefix), + sizeof (T), true + PASS_MEM_STAT); + else if (A == heap) + return (vec_t<T> *) vec_heap_o_reserve_1 (vec_, reserve, + sizeof (struct vec_prefix), + sizeof (T), true + PASS_MEM_STAT); + else if (A == stack) + { + /* Only allow stack vectors when re-growing them. The initial + allocation of stack vectors must be done with VEC_alloc, + because it uses alloca() for the allocation. */ + if (vec_ == NULL) + { + fprintf (stderr, "Stack vectors must be initially allocated " + "with VEC_stack_alloc.\n"); + gcc_unreachable (); + } + return (vec_t<T> *) vec_stack_o_reserve_exact (vec_, reserve, + sizeof (struct vec_prefix), + sizeof (T) + PASS_MEM_STAT); + } } #endif /* GCC_VEC_H */ diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 0ec3013..e4da6ef 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,18 @@ +2012-08-14 Diego Novillo <dnovillo@google.com> + + Merge from cxx-conversion branch. Configury. + + * Makefile.in: Remove all handlers of ENABLE_BUILD_WITH_CXX. + * configure.ac: Likewise. + * configure: Regenerate. + +2012-08-14 Lawrence Crowl <crowl@google.com> + + Merge from cxx-conversion branch. New C++ hash table. + + * include/symtab.h (typedef struct ht hash_table): Change the typedef + name to cpp_hash_table. Update all users of the typedef. + 2012-07-30 Laurynas Biveinis <laurynas.biveinis@gmail.com> * include/line-map.h (line_map_macro): Use the "atomic" GTY option diff --git a/libcpp/Makefile.in b/libcpp/Makefile.in index d6df46d..3ae3280 100644 --- a/libcpp/Makefile.in +++ b/libcpp/Makefile.in @@ -77,16 +77,9 @@ ALL_CXXFLAGS = $(CXXFLAGS) $(WARN_CXXFLAGS) $(NOEXCEPTION_FLAGS) $(INCLUDES) \ $(CPPFLAGS) # The name of the compiler to use. -ENABLE_BUILD_WITH_CXX = @ENABLE_BUILD_WITH_CXX@ -ifneq ($(ENABLE_BUILD_WITH_CXX),yes) -COMPILER = $(CC) -COMPILER_FLAGS = $(ALL_CFLAGS) -DEPMODE = $(CCDEPMODE) -else COMPILER = $(CXX) COMPILER_FLAGS = $(ALL_CXXFLAGS) DEPMODE = $(CXXDEPMODE) -endif libcpp_a_OBJS = charset.o directives.o directives-only.o errors.o \ diff --git a/libcpp/configure b/libcpp/configure index fb5654d..01e4462 100755 --- a/libcpp/configure +++ b/libcpp/configure @@ -612,7 +612,6 @@ USE_NLS ALLOCA LIBOBJS CXXDEPMODE -CCDEPMODE DEPDIR am__leading_dot WERROR @@ -623,7 +622,6 @@ warn AUTOHEADER AUTOCONF ACLOCAL -ENABLE_BUILD_WITH_CXX EGREP GREP CPP @@ -696,7 +694,6 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_largefile -enable_build_with_cxx enable_werror_always with_gnu_ld enable_rpath @@ -1332,7 +1329,6 @@ Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-largefile omit support for large files - --enable-build-with-cxx build with C++ compiler instead of C compiler --enable-werror-always enable -Werror despite compiler version --disable-rpath do not hardcode runtime library paths --enable-maintainer-mode enable rules only needed by maintainers @@ -4541,17 +4537,6 @@ rm -rf conftest* fi -# See if we are building gcc with C++. -# Do this early so setting lang to C++ affects following tests -# Check whether --enable-build-with-cxx was given. -if test "${enable_build_with_cxx+set}" = set; then : - enableval=$enable_build_with_cxx; ENABLE_BUILD_WITH_CXX=$enableval -else - ENABLE_BUILD_WITH_CXX=no -fi - - - MISSING=`cd $ac_aux_dir && ${PWDCMD-pwd}`/missing for ac_prog in aclocal do @@ -4895,104 +4880,6 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depdir" -if test "$ENABLE_BUILD_WITH_CXX" = "no"; then -depcc="$CC" am_compiler_list= - -am_depcomp=$ac_aux_dir/depcomp -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - if test $depmode = none; then break; fi - - $as_echo "$as_me:$LINENO: trying $depmode" >&5 - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "include sub/conftest.Po" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - depcmd="depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c" - echo "| $depcmd" | sed -e 's/ */ /g' >&5 - if env $depcmd > conftest.err 2>&1 && - grep sub/conftst6.h sub/conftest.Po >>conftest.err 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po >>conftest.err 2>&1 && - ${MAKE-make} -s -f confmf >>conftest.err 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - $as_echo "$as_me:$LINENO: success" >&5 - break - fi - fi - $as_echo "$as_me:$LINENO: failure, diagnostics are:" >&5 - sed -e 's/^/| /' < conftest.err >&5 - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -if test x${am_cv_CC_dependencies_compiler_type-none} = xnone -then as_fn_error "no usable dependency style found" "$LINENO" 5 -else CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - -fi - -else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -5112,7 +4999,6 @@ else CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type fi -fi # Checks for header files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 @@ -6454,6 +6340,12 @@ fi # g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different # iconv() prototype. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" @@ -6995,13 +6887,6 @@ fi fi -if test "$ENABLE_BUILD_WITH_CXX" = "yes"; then : - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - @@ -7157,169 +7042,12 @@ _ACEOF fi - ac_ext=c +ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -else - - - - - - am_save_CPPFLAGS="$CPPFLAGS" - - for element in $INCICONV; do - haveit= - for x in $CPPFLAGS; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 -$as_echo_n "checking for iconv... " >&6; } -if test "${am_cv_func_iconv+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <iconv.h> -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <iconv.h> -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - am_cv_lib_iconv=yes - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$am_save_LIBS" - fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 -$as_echo "$am_cv_func_iconv" >&6; } - if test "$am_cv_func_iconv" = yes; then - -$as_echo "#define HAVE_ICONV 1" >>confdefs.h - - fi - if test "$am_cv_lib_iconv" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 -$as_echo_n "checking how to link with libiconv... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 -$as_echo "$LIBICONV" >&6; } - else - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - - - - if test "$am_cv_func_iconv" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 -$as_echo_n "checking for iconv declaration... " >&6; } - if test "${am_cv_proto_iconv+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include <stdlib.h> -#include <iconv.h> -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - am_cv_proto_iconv_arg1="" -else - am_cv_proto_iconv_arg1="const" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" -fi - - am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:- - }$am_cv_proto_iconv" >&5 -$as_echo "${ac_t:- - }$am_cv_proto_iconv" >&6; } - -cat >>confdefs.h <<_ACEOF -#define ICONV_CONST $am_cv_proto_iconv_arg1 -_ACEOF - - fi - -fi # More defines and substitutions. PACKAGE="$PACKAGE_TARNAME" diff --git a/libcpp/configure.ac b/libcpp/configure.ac index 070ab63..29bd8c5 100644 --- a/libcpp/configure.ac +++ b/libcpp/configure.ac @@ -17,14 +17,6 @@ AC_PROG_RANLIB AC_USE_SYSTEM_EXTENSIONS AC_SYS_LARGEFILE -# See if we are building gcc with C++. -# Do this early so setting lang to C++ affects following tests -AC_ARG_ENABLE(build-with-cxx, -[ --enable-build-with-cxx build with C++ compiler instead of C compiler], -ENABLE_BUILD_WITH_CXX=$enableval, -ENABLE_BUILD_WITH_CXX=no) -AC_SUBST(ENABLE_BUILD_WITH_CXX) - MISSING=`cd $ac_aux_dir && ${PWDCMD-pwd}`/missing AC_CHECK_PROGS([ACLOCAL], [aclocal], [$MISSING aclocal]) AC_CHECK_PROGS([AUTOCONF], [autoconf], [$MISSING autoconf]) @@ -49,15 +41,11 @@ ACX_PROG_CC_WARNINGS_ARE_ERRORS([manual]) # Dependency checking. ZW_CREATE_DEPDIR -if test "$ENABLE_BUILD_WITH_CXX" = "no"; then -ZW_PROG_COMPILER_DEPENDENCIES([CC]) -else AC_LANG_PUSH([C++]) AC_COMPILE_IFELSE([[int i;]], [], [AC_MSG_ERROR([C++ compiler missing or inoperational])]) AC_LANG_POP([C++]) ZW_PROG_COMPILER_DEPENDENCIES([CXX]) -fi # Checks for header files. AC_HEADER_TIME @@ -108,11 +96,9 @@ fi # g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different # iconv() prototype. -AS_IF([test "$ENABLE_BUILD_WITH_CXX" = "yes"], - [AC_LANG_PUSH([C++]) - AM_ICONV - AC_LANG_POP([C++])], - [AM_ICONV]) +AC_LANG_PUSH([C++]) +AM_ICONV +AC_LANG_POP([C++]) # More defines and substitutions. PACKAGE="$PACKAGE_TARNAME" diff --git a/libcpp/identifiers.c b/libcpp/identifiers.c index 8244f0c..d0973f4 100644 --- a/libcpp/identifiers.c +++ b/libcpp/identifiers.c @@ -28,12 +28,12 @@ along with this program; see the file COPYING3. If not see #include "cpplib.h" #include "internal.h" -static hashnode alloc_node (hash_table *); +static hashnode alloc_node (cpp_hash_table *); /* Return an identifier node for hashtable.c. Used by cpplib except when integrated with the C front ends. */ static hashnode -alloc_node (hash_table *table) +alloc_node (cpp_hash_table *table) { cpp_hashnode *node; @@ -45,7 +45,7 @@ alloc_node (hash_table *table) /* Set up the identifier hash table. Use TABLE if non-null, otherwise create our own. */ void -_cpp_init_hashtable (cpp_reader *pfile, hash_table *table) +_cpp_init_hashtable (cpp_reader *pfile, cpp_hash_table *table) { struct spec_nodes *s; diff --git a/libcpp/include/symtab.h b/libcpp/include/symtab.h index 4107a6f..30d7645 100644 --- a/libcpp/include/symtab.h +++ b/libcpp/include/symtab.h @@ -38,7 +38,7 @@ struct GTY(()) ht_identifier { #define HT_LEN(NODE) ((NODE)->len) #define HT_STR(NODE) ((NODE)->str) -typedef struct ht hash_table; +typedef struct ht cpp_hash_table; typedef struct ht_identifier *hashnode; enum ht_lookup_option {HT_NO_INSERT = 0, HT_ALLOC}; @@ -51,7 +51,7 @@ struct ht hashnode *entries; /* Call back, allocate a node. */ - hashnode (*alloc_node) (hash_table *); + hashnode (*alloc_node) (cpp_hash_table *); /* Call back, allocate something that hangs off a node like a cpp_macro. NULL means use the usual allocator. */ void * (*alloc_subobject) (size_t); @@ -71,14 +71,14 @@ struct ht }; /* Initialize the hashtable with 2 ^ order entries. */ -extern hash_table *ht_create (unsigned int order); +extern cpp_hash_table *ht_create (unsigned int order); /* Frees all memory associated with a hash table. */ -extern void ht_destroy (hash_table *); +extern void ht_destroy (cpp_hash_table *); -extern hashnode ht_lookup (hash_table *, const unsigned char *, +extern hashnode ht_lookup (cpp_hash_table *, const unsigned char *, size_t, enum ht_lookup_option); -extern hashnode ht_lookup_with_hash (hash_table *, const unsigned char *, +extern hashnode ht_lookup_with_hash (cpp_hash_table *, const unsigned char *, size_t, unsigned int, enum ht_lookup_option); #define HT_HASHSTEP(r, c) ((r) * 67 + ((c) - 113)); @@ -88,17 +88,17 @@ extern hashnode ht_lookup_with_hash (hash_table *, const unsigned char *, TABLE->PFILE, the node, and a PTR, and the callback sequence stops if the callback returns zero. */ typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *); -extern void ht_forall (hash_table *, ht_cb, const void *); +extern void ht_forall (cpp_hash_table *, ht_cb, const void *); /* For all nodes in TABLE, call the callback. If the callback returns a nonzero value, the node is removed from the table. */ -extern void ht_purge (hash_table *, ht_cb, const void *); +extern void ht_purge (cpp_hash_table *, ht_cb, const void *); /* Restore the hash table. */ -extern void ht_load (hash_table *ht, hashnode *entries, +extern void ht_load (cpp_hash_table *ht, hashnode *entries, unsigned int nslots, unsigned int nelements, bool own); /* Dump allocation statistics to stderr. */ -extern void ht_dump_statistics (hash_table *); +extern void ht_dump_statistics (cpp_hash_table *); #endif /* LIBCPP_SYMTAB_H */ diff --git a/libcpp/init.c b/libcpp/init.c index 7752fea..040ab34 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -149,7 +149,7 @@ init_library (void) /* Initialize a cpp_reader structure. */ cpp_reader * -cpp_create_reader (enum c_lang lang, hash_table *table, +cpp_create_reader (enum c_lang lang, cpp_hash_table *table, struct line_maps *line_table) { cpp_reader *pfile; diff --git a/libcpp/internal.h b/libcpp/internal.h index 37aac82..79dd54f 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -619,7 +619,7 @@ extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *, extern void _cpp_backup_tokens_direct (cpp_reader *, unsigned int); /* In identifiers.c */ -extern void _cpp_init_hashtable (cpp_reader *, hash_table *); +extern void _cpp_init_hashtable (cpp_reader *, cpp_hash_table *); extern void _cpp_destroy_hashtable (cpp_reader *); /* In files.c */ diff --git a/libcpp/symtab.c b/libcpp/symtab.c index 48a5338..a3537a0 100644 --- a/libcpp/symtab.c +++ b/libcpp/symtab.c @@ -31,7 +31,7 @@ along with this program; see the file COPYING3. If not see existing entry with a potential new one. */ static unsigned int calc_hash (const unsigned char *, size_t); -static void ht_expand (hash_table *); +static void ht_expand (cpp_hash_table *); static double approx_sqrt (double); /* A deleted entry. */ @@ -53,13 +53,13 @@ calc_hash (const unsigned char *str, size_t len) /* Initialize an identifier hashtable. */ -hash_table * +cpp_hash_table * ht_create (unsigned int order) { unsigned int nslots = 1 << order; - hash_table *table; + cpp_hash_table *table; - table = XCNEW (hash_table); + table = XCNEW (cpp_hash_table); /* Strings need no alignment. */ _obstack_begin (&table->stack, 0, 0, @@ -77,7 +77,7 @@ ht_create (unsigned int order) /* Frees all memory associated with a hash table. */ void -ht_destroy (hash_table *table) +ht_destroy (cpp_hash_table *table) { obstack_free (&table->stack, NULL); if (table->entries_owned) @@ -91,7 +91,7 @@ ht_destroy (hash_table *table) returns NULL. Otherwise insert and returns a new entry. A new string is allocated. */ hashnode -ht_lookup (hash_table *table, const unsigned char *str, size_t len, +ht_lookup (cpp_hash_table *table, const unsigned char *str, size_t len, enum ht_lookup_option insert) { return ht_lookup_with_hash (table, str, len, calc_hash (str, len), @@ -99,7 +99,7 @@ ht_lookup (hash_table *table, const unsigned char *str, size_t len, } hashnode -ht_lookup_with_hash (hash_table *table, const unsigned char *str, +ht_lookup_with_hash (cpp_hash_table *table, const unsigned char *str, size_t len, unsigned int hash, enum ht_lookup_option insert) { @@ -182,7 +182,7 @@ ht_lookup_with_hash (hash_table *table, const unsigned char *str, /* Double the size of a hash table, re-hashing existing entries. */ static void -ht_expand (hash_table *table) +ht_expand (cpp_hash_table *table) { hashnode *nentries, *p, *limit; unsigned int size, sizemask; @@ -224,7 +224,7 @@ ht_expand (hash_table *table) /* For all nodes in TABLE, callback CB with parameters TABLE->PFILE, the node, and V. */ void -ht_forall (hash_table *table, ht_cb cb, const void *v) +ht_forall (cpp_hash_table *table, ht_cb cb, const void *v) { hashnode *p, *limit; @@ -242,7 +242,7 @@ ht_forall (hash_table *table, ht_cb cb, const void *v) /* Like ht_forall, but a nonzero return from the callback means that the entry should be removed from the table. */ void -ht_purge (hash_table *table, ht_cb cb, const void *v) +ht_purge (cpp_hash_table *table, ht_cb cb, const void *v) { hashnode *p, *limit; @@ -259,7 +259,7 @@ ht_purge (hash_table *table, ht_cb cb, const void *v) /* Restore the hash table. */ void -ht_load (hash_table *ht, hashnode *entries, +ht_load (cpp_hash_table *ht, hashnode *entries, unsigned int nslots, unsigned int nelements, bool own) { @@ -274,7 +274,7 @@ ht_load (hash_table *ht, hashnode *entries, /* Dump allocation statistics to stderr. */ void -ht_dump_statistics (hash_table *table) +ht_dump_statistics (cpp_hash_table *table) { size_t nelts, nids, overhead, headers; size_t total_bytes, longest, deleted = 0; |