From 89b0433e3a1f0a9ae590c1be5a6ba4b9aa690ae0 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 19 Aug 2004 10:36:07 +0000 Subject: [PATCH] tree.h (TYPE_CACHED_VALUES_P): New. * tree.h (TYPE_CACHED_VALUES_P): New. (TYPE_CACHED_VALUES): New. (TYPE_ORIG_SIZE_TYPE): Adjust. * tree.def (INTEGER_CST): Update documentation. * tree.c: Inlcude params.h. (build_int_cst): Cache small values. (build_type_copy): Do not copy the value cache. * c-common.c (c_common_nodes_and_builtins): Add comment, remove unneeded zeroing. * c-typeck.c (build_c_cast): Add comment about OVERFLOW setting. * expmed.c (const_mult_add_overflow_p): Clear type copy's value cache. * fold-const.c (force_fit_type): Copy value when setting overflows. (int_const_binop): Likewise. * stor-layout.c: Include params.h (set_sizetype): Create values cache. (fixup_unsigned_type): Set UNSIGNED_P before caching any values. * params.def (PARAM_INTEGER_SHARE_LIMIT): New. * params.h (INTEGER_SHARE_LIMIT): New. * Makefile.in (tree.o, stor-layout.o): Depend on PARAMS_H. * cp/decl.c (finish_enum): Do not copy value node early, copy later. * cp/lex.c (cxx_init): Force null_node to be unique. * java/parse.h (JAVA_RADIX10_FLAG): Rename to ... (JAVA_NOT_RADIX10_FLAG): ... here. Invert meaning. * java/lex.c (do_java_lex): Adjust. (error_if_numeric_overflow): Likewise. From-SVN: r86247 --- gcc/ChangeLog | 61 +++++++++++++++++++++++++---------- gcc/Makefile.in | 8 +++-- gcc/c-common.c | 3 +- gcc/c-typeck.c | 4 +++ gcc/cp/ChangeLog | 6 ++++ gcc/cp/decl.c | 14 +++----- gcc/cp/lex.c | 6 ++-- gcc/expmed.c | 11 ++++++- gcc/fold-const.c | 26 +++++++++------ gcc/java/ChangeLog | 11 +++++-- gcc/java/lex.c | 11 +++++-- gcc/java/parse.h | 4 +-- gcc/params.def | 8 +++++ gcc/params.h | 2 ++ gcc/stor-layout.c | 7 +++- gcc/tree.c | 80 +++++++++++++++++++++++++++++++++++++++++++++- gcc/tree.def | 11 ++++--- gcc/tree.h | 11 ++++++- 18 files changed, 226 insertions(+), 58 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index afb0665def5..537d2a1c754 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2004-08-19 Nathan Sidwell + + * tree.h (TYPE_CACHED_VALUES_P): New. + (TYPE_CACHED_VALUES): New. + (TYPE_ORIG_SIZE_TYPE): Adjust. + * tree.def (INTEGER_CST): Update documentation. + * tree.c: Inlcude params.h. + (build_int_cst): Cache small values. + (build_type_copy): Do not copy the value cache. + * c-common.c (c_common_nodes_and_builtins): Add comment, remove + unneeded zeroing. + * c-typeck.c (build_c_cast): Add comment about OVERFLOW setting. + * expmed.c (const_mult_add_overflow_p): Clear type copy's value + cache. + * fold-const.c (force_fit_type): Copy value when setting + overflows. + (int_const_binop): Likewise. + * stor-layout.c: Include params.h + (set_sizetype): Create values cache. + (fixup_unsigned_type): Set UNSIGNED_P before caching any values. + * params.def (PARAM_INTEGER_SHARE_LIMIT): New. + * params.h (INTEGER_SHARE_LIMIT): New. + * Makefile.in (tree.o, stor-layout.o): Depend on PARAMS_H. + 2004-08-19 Paolo Bonzini * gimplify.c (gimplify_minimax_expr): Remove. @@ -404,19 +428,20 @@ * reg-stack.c (emit_swap_insn): Add condition to step over NOTE_INSN_UNLIKELY_EXECUTED_CODE notes. * toplev.c (user_defined_section_attribute): New global variable. - * toplev.h (user_defined_section_attribute): Extern declaration for new - global variable. + * toplev.h (user_defined_section_attribute): Extern declaration + for new global variable. * varasm.c (unlikely_section_label): New global variable. (unlikely_text_section_name): New global variable. - (unlikely_text_section): Add code to initialize unlikely_text_section_name - if necessary; modify to use unlikely_text_section_name and - unlikely_section_label; also to use named_section properly. - (in_unlikely_text_section): Modify to work correctly with named_section - and to use unlikely_text_section_name. + (unlikely_text_section): Add code to initialize + unlikely_text_section_name if necessary; modify to use + unlikely_text_section_name and unlikely_section_label; also to use + named_section properly. + (in_unlikely_text_section): Modify to work correctly with + named_section and to use unlikely_text_section_name. (named_section): Add code to work properly with cold section. (function_section): Clean up if-statement. - * config/darwin.c (darwin_asm_named_section): Return to original code, - removing use of SECTION_FORMAT_STRING. + * config/darwin.c (darwin_asm_named_section): Return to original + code, removing use of SECTION_FORMAT_STRING. * config/arm/pe.h (switch_to_section): Add case for in_unlikely_executed_text to switch statement. * config/i386/cygming.h (switch_to_section): Likewise. @@ -677,12 +702,13 @@ 2004-08-17 Dorit Naishlos - * tree-vectorizer.c: New File: loop vectorization on SSAed GIMPLE trees. + * tree-vectorizer.c: New File: loop vectorization on SSAed GIMPLE + trees. * tree-vectorizer.h: New File: Same. * Makefile.in (tree-vectorizer.c, tree-vectorizer.h): Add new files. * common.opt (ftree-vectorize): New flag to enable vectorization. - * timevar.def (TV_TREE_VECTORIZATION): New dump file for vectorization - pass. + * timevar.def (TV_TREE_VECTORIZATION): New dump file for + vectorization pass. * tree-data-ref.h (init_data_ref): Additional argument. (array_base_name_differ_p): Moved to tree-data-ref.c. * tree-data-ref.c (array_base_name_differ_p): Revised. @@ -690,7 +716,8 @@ with an extra argument. (analyze_all_data_dependences): Same. (init_data_ref): Additional argument is_read to set DR_IS_READ. - * tree-ssa-phiopt.c (empty_block_p): Expose for usage out of this file. + * tree-ssa-phiopt.c (empty_block_p): Expose for usage out of this + file. * tree-flow.h (vectorize_loops, empty_block_p): Add declaration. * tree-optimize.c (pass_vectorize): Schedule the vectorization pass. * tree-pass.h (tree_opt_pass pass_vectorize): Declare the new @@ -698,9 +725,9 @@ * tree-ssa-loop.c (tree_ssa_loop_init): Call scev_initialize. (tree_ssa_loop_done): Call scev_finalize. (tree_vectorize): Define the new vectorization pass. - * defaults.h (UNITS_PER_SIMD_WORD): Allow targets to specify the size of - the vector they support (until support for multiple vector sizes is - added to the vectorizer). + * defaults.h (UNITS_PER_SIMD_WORD): Allow targets to specify the + size of the vector they support (until support for multiple vector + sizes is added to the vectorizer). * config/i386/i386.h (UNITS_PER_SIMD_WORD): Define. * config/rs6000/rs6000.h (UNITS_PER_SIMD_WORD): Define. * invoke.texi (fdump-tree-vect, ftree-vectorize): Add @@ -2543,7 +2570,7 @@ * config/i386/xmmintrin.h: Include . 2004-08-03 H.J. Lu - Tanguy Fautrà + Tanguy Fautrà * config/i386/pmm_malloc.h: New file. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index b7fd64ff2ed..a71558bf3e4 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1563,7 +1563,8 @@ convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(FLA langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) toplev.h \ tree-inline.h $(RTL_H) insn-config.h $(INTEGRATE_H) langhooks.h \ $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) diagnostic.h -tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(FLAGS_H) function.h \ +tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ + $(FLAGS_H) function.h $(PARAMS_H) \ toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \ real.h gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ @@ -1576,8 +1577,9 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_GIMPLE_H) print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(GGC_H) langhooks.h real.h -stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ - $(FLAGS_H) function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H) \ +stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ + $(TREE_H) $(PARAMS_H) $(FLAGS_H) function.h $(EXPR_H) $(RTL_H) toplev.h \ + $(GGC_H) $(TM_P_H) $(TARGET_H) \ langhooks.h $(REGS_H) tree-alias-type.o: tree-alias-type.c tree-alias-type.h $(SYSTEM_H) $(CONFIG_H) \ $(GGC_H) $(TM_H) coretypes.h $(VARRAY_H) diff --git a/gcc/c-common.c b/gcc/c-common.c index 6e07cfcbbdb..663e2c1f7f4 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3001,9 +3001,8 @@ c_common_nodes_and_builtins (void) record_builtin_type (RID_VOID, NULL, void_type_node); + /* This node must not be shared. */ void_zero_node = make_node (INTEGER_CST); - TREE_INT_CST_LOW (void_zero_node) = 0; - TREE_INT_CST_HIGH (void_zero_node) = 0; TREE_TYPE (void_zero_node) = void_type_node; void_list_node = build_void_list_node (); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 168883421f4..ad8acee710d 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -3109,11 +3109,15 @@ build_c_cast (tree type, tree expr) if (TREE_CODE (value) == INTEGER_CST) { if (EXPR_P (ovalue)) + /* If OVALUE had overflow set, then so will VALUE, so it + is safe to overwrite. */ TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); else TREE_OVERFLOW (value) = 0; if (TREE_CODE_CLASS (TREE_CODE (ovalue)) == 'c') + /* Similarly, constant_overflow cannot have become + cleared. */ TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue); } } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5ce9af30f2a..0cd1b21d32e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-08-19 Nathan Sidwell + + * decl.c (finish_enum): Do not copy value node early, copy + later. + * lex.c (cxx_init): Force null_node to be unique. + 2004-08-19 Joseph S. Myers PR c++/17041 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a4856a9cfaf..0c60f3c6d35 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9311,16 +9311,6 @@ finish_enum (tree enumtype) maxnode = value; else if (tree_int_cst_lt (value, minnode)) minnode = value; - - /* Set the TREE_TYPE for the values as well. That's so that when - we call decl_constant_value we get an entity of the right type - (but with the constant value). But first make a copy so we - don't clobber shared INTEGER_CSTs. */ - if (TREE_TYPE (value) != enumtype) - { - value = DECL_INITIAL (decl) = copy_node (value); - TREE_TYPE (value) = enumtype; - } } } else @@ -9405,6 +9395,10 @@ finish_enum (tree enumtype) decl = TREE_VALUE (values); value = perform_implicit_conversion (underlying_type, DECL_INITIAL (decl)); + + /* Do not clobber shared ints. */ + value = copy_node (value); + TREE_TYPE (value) = enumtype; DECL_INITIAL (decl) = value; TREE_VALUE (values) = value; diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index c44e7c0863b..fe220f2ae24 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -354,8 +354,10 @@ cxx_init (void) cxx_init_decl_processing (); - /* Create the built-in __null node. */ - null_node = build_int_cst (c_common_type_for_size (POINTER_SIZE, 0), 0, 0); + /* Create the built-in __null node. It is important that this is + not shared. */ + null_node = make_node (INTEGER_CST); + TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0); ridpointers[RID_NULL] = null_node; interface_unknown = 1; diff --git a/gcc/expmed.c b/gcc/expmed.c index b44ba65e28b..bb24504d27c 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -4550,7 +4550,8 @@ make_tree (tree type, rtx x) UNSIGNEDP is nonzero to do unsigned multiplication. */ bool -const_mult_add_overflow_p (rtx x, rtx mult, rtx add, enum machine_mode mode, int unsignedp) +const_mult_add_overflow_p (rtx x, rtx mult, rtx add, + enum machine_mode mode, int unsignedp) { tree type, mult_type, add_type, result; @@ -4561,7 +4562,15 @@ const_mult_add_overflow_p (rtx x, rtx mult, rtx add, enum machine_mode mode, int mult_type = type; if (unsignedp) { + /* FIXME:It would be nice if we could step directly from this + type to its sizetype equivalent. */ mult_type = copy_node (type); + if (TYPE_CACHED_VALUES_P (mult_type)) + { + /* Clear any set of cached values it has. */ + TYPE_CACHED_VALUES_P (mult_type) = 0; + TYPE_CACHED_VALUES (mult_type) = NULL_TREE; + } TYPE_IS_SIZETYPE (mult_type) = 1; } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 319e455f433..092712bad95 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -268,18 +268,21 @@ force_fit_type (tree t, int overflowable, if (overflowed || overflowed_const || low != TREE_INT_CST_LOW (t) || high != TREE_INT_CST_HIGH (t)) { + t = build_int_cst (TREE_TYPE (t), low, high); + if (overflowed || overflowable < 0 || (overflowable > 0 && sign_extended_type)) { + t = copy_node (t); TREE_OVERFLOW (t) = 1; TREE_CONSTANT_OVERFLOW (t) = 1; } else if (overflowed_const) - TREE_CONSTANT_OVERFLOW (t) = 1; - - TREE_INT_CST_LOW (t) = low; - TREE_INT_CST_HIGH (t) = high; + { + t = copy_node (t); + TREE_CONSTANT_OVERFLOW (t) = 1; + } } return t; @@ -1425,11 +1428,16 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) /* Propagate overflow flags ourselves. */ if (((!uns || is_sizetype) && overflow) | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)) - TREE_OVERFLOW (t) = 1; - - if (TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1) - | TREE_CONSTANT_OVERFLOW (arg2)) - TREE_CONSTANT_OVERFLOW (t) = 1; + { + t = copy_node (t); + TREE_OVERFLOW (t) = 1; + TREE_CONSTANT_OVERFLOW (t) = 1; + } + else if (TREE_CONSTANT_OVERFLOW (arg1) | TREE_CONSTANT_OVERFLOW (arg2)) + { + t = copy_node (t); + TREE_CONSTANT_OVERFLOW (t) = 1; + } } else t = force_fit_type (t, 1, diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 1c0f9d44926..4489f6a5630 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,7 +1,14 @@ +2004-08-19 Nathan Sidwell + + * parse.h (JAVA_RADIX10_FLAG): Rename to ... + (JAVA_NOT_RADIX10_FLAG): ... here. Invert meaning. + * lex.c (do_java_lex): Adjust. + (error_if_numeric_overflow): Likewise. + 2004-08-18 Andrew Pinski - * class.c (make_local_function_alias): Only make a new decl if we support - alias attribute on all decls. + * class.c (make_local_function_alias): Only make a new decl if we + support alias attribute on all decls. 2004-08-18 Bryce McKinlay diff --git a/gcc/java/lex.c b/gcc/java/lex.c index 5467d60b9d6..7c497bda9ed 100644 --- a/gcc/java/lex.c +++ b/gcc/java/lex.c @@ -1303,9 +1303,14 @@ do_java_lex (YYSTYPE *java_lval) value = build_int_cst (long_suffix ? long_type_node : int_type_node, low, high); value = force_fit_type (value, 0, false, false); - SET_LVAL_NODE (value); + + if (radix != 10) + { + value = copy_node (value); + JAVA_NOT_RADIX10_FLAG (value) = 1; + } - JAVA_RADIX10_FLAG (value) = radix == 10; + SET_LVAL_NODE (value); #endif return INT_LIT_TK; } @@ -1733,7 +1738,7 @@ static void error_if_numeric_overflow (tree value) { if (TREE_CODE (value) == INTEGER_CST - && JAVA_RADIX10_FLAG (value) + && !JAVA_NOT_RADIX10_FLAG (value) && tree_int_cst_sgn (value) < 0) { if (TREE_TYPE (value) == long_type_node) diff --git a/gcc/java/parse.h b/gcc/java/parse.h index c873b855f8e..9e4e0f8fca4 100644 --- a/gcc/java/parse.h +++ b/gcc/java/parse.h @@ -910,9 +910,9 @@ struct parser_ctxt GTY(()) { TREE_PURPOSE (CPC_INSTANCE_INITIALIZER_LIST (C)) = (S); /* This is used by the lexer to communicate with the parser. It is - set on an integer constant if the radix is 10, so that the parser + set on an integer constant if the radix is NOT 10, so that the parser can correctly diagnose a numeric overflow. */ -#define JAVA_RADIX10_FLAG(NODE) TREE_LANG_FLAG_0(NODE) +#define JAVA_NOT_RADIX10_FLAG(NODE) TREE_LANG_FLAG_0(NODE) #ifndef JC1_LITE void java_complete_class (void); diff --git a/gcc/params.def b/gcc/params.def index aed7655c9a4..331e0523d2d 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -379,6 +379,14 @@ DEFPARAM(PARAM_MAX_SCHED_REGION_INSNS, "The maximum number of insns in a region to be considered for interblock scheduling", 100) +/* INTEGER_CST nodes are shared for values [{-1,0} .. N) for + {signed,unsigned} integral types. This determines N. + Experimentation shows 256 to be a good value. */ +DEFPARAM (PARAM_INTEGER_SHARE_LIMIT, + "integer-share-limit", + "The upper bound for sharing integer constants", + 256) + /* Local variables: mode:c diff --git a/gcc/params.h b/gcc/params.h index 3611294185a..603f21b6f3f 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -122,4 +122,6 @@ typedef enum compiler_param PARAM_VALUE (PARAM_GLOBAL_VAR_THRESHOLD) #define MAX_ALIASED_VOPS \ PARAM_VALUE (PARAM_MAX_ALIASED_VOPS) +#define INTEGER_SHARE_LIMIT \ + PARAM_VALUE (PARAM_INTEGER_SHARE_LIMIT) #endif /* ! GCC_PARAMS_H */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index eca60877c8a..156702f652f 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -35,6 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "langhooks.h" #include "regs.h" +#include "params.h" /* Set to one when set_sizetype has been called. */ static int sizetype_set; @@ -1900,7 +1901,9 @@ set_sizetype (tree type) /* Make copies of nodes since we'll be setting TYPE_IS_SIZETYPE. */ sizetype = copy_node (type); - TYPE_ORIG_SIZE_TYPE (sizetype) = type; + TYPE_CACHED_VALUES (sizetype) = make_tree_vec (INTEGER_SHARE_LIMIT); + TYPE_CACHED_VALUES_P (sizetype) = 1; + TREE_TYPE (TYPE_CACHED_VALUES (sizetype)) = type; TYPE_IS_SIZETYPE (sizetype) = 1; bitsizetype = make_node (INTEGER_TYPE); TYPE_NAME (bitsizetype) = TYPE_NAME (type); @@ -2047,6 +2050,8 @@ fixup_unsigned_type (tree type) if (precision > HOST_BITS_PER_WIDE_INT * 2) precision = HOST_BITS_PER_WIDE_INT * 2; + TYPE_UNSIGNED (type) = 1; + set_min_and_max_values_for_integral_type (type, precision, /*is_unsigned=*/true); diff --git a/gcc/tree.c b/gcc/tree.c index 1582d7b595f..d0a182b2052 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -48,6 +48,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "tree-iterator.h" #include "basic-block.h" #include "tree-flow.h" +#include "params.h" /* obstack.[ch] explicitly declined to prototype this. */ extern int _obstack_allocated_p (struct obstack *h, void *obj); @@ -427,15 +428,84 @@ tree build_int_cst (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi) { tree t; + int ix = -1; + int limit = 0; if (!type) type = integer_type_node; - + + switch (TREE_CODE (type)) + { + case POINTER_TYPE: + case REFERENCE_TYPE: + /* Cache NULL pointer. */ + if (!hi && !low) + { + limit = 1; + ix = 0; + } + break; + + case BOOLEAN_TYPE: + /* Cache false or true. */ + limit = 2; + if (!hi && low < 2) + ix = low; + break; + + case INTEGER_TYPE: + case CHAR_TYPE: + case OFFSET_TYPE: + if (TYPE_UNSIGNED (type)) + { + /* Cache 0..N */ + limit = INTEGER_SHARE_LIMIT; + if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT) + ix = low; + } + else + { + /* Cache -1..N */ + limit = INTEGER_SHARE_LIMIT + 1; + if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT) + ix = low + 1; + else if (hi == -1 && low == -(unsigned HOST_WIDE_INT)1) + ix = 0; + } + break; + default: + break; + } + + if (ix >= 0) + { + if (!TYPE_CACHED_VALUES_P (type)) + { + TYPE_CACHED_VALUES_P (type) = 1; + TYPE_CACHED_VALUES (type) = make_tree_vec (limit); + } + + t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix); + if (t) + { + /* Make sure no one is clobbering the shared constant. */ + if (TREE_TYPE (t) != type) + abort (); + if (TREE_INT_CST_LOW (t) != low || TREE_INT_CST_HIGH (t) != hi) + abort (); + return t; + } + } + t = make_node (INTEGER_CST); TREE_INT_CST_LOW (t) = low; TREE_INT_CST_HIGH (t) = hi; TREE_TYPE (t) = type; + + if (ix >= 0) + TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t; + return t; } @@ -3097,6 +3167,14 @@ build_type_copy (tree type) tree t, m = TYPE_MAIN_VARIANT (type); t = copy_node (type); + if (TYPE_CACHED_VALUES_P(t)) + { + /* Do not copy the values cache. */ + if (TREE_CODE (t) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t)) + abort (); + TYPE_CACHED_VALUES_P (t) = 0; + TYPE_CACHED_VALUES (t) = NULL_TREE; + } TYPE_POINTER_TO (t) = 0; TYPE_REFERENCE_TO (t) = 0; diff --git a/gcc/tree.def b/gcc/tree.def index 552be88fc94..fc7ed81a54f 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -258,10 +258,13 @@ DEFTREECODE (LANG_TYPE, "lang_type", 't', 0) /* First, the constants. */ /* Contents are in TREE_INT_CST_LOW and TREE_INT_CST_HIGH fields, - 32 bits each, giving us a 64 bit constant capability. - Note: constants of type char in Pascal are INTEGER_CST, - and so are pointer constants such as nil in Pascal or NULL in C. - `(int *) 1' in C also results in an INTEGER_CST. */ + 32 bits each, giving us a 64 bit constant capability. INTEGER_CST + nodes can be shared, and therefore should be considered read only. + They should be copied, before setting a flag such as + TREE_OVERFLOW. If an INTEGER_CST has TREE_OVERFLOW or + TREE_CONSTANT_OVERFLOW already set, it is known to be unique. + INTEGER_CST nodes are created for the integral types, for pointer + types and for vector and float types in some circumstances. */ DEFTREECODE (INTEGER_CST, "integer_cst", 'c', 0) /* Contents are in TREE_REAL_CST field. */ diff --git a/gcc/tree.h b/gcc/tree.h index 6c1fa2a7810..f498db1aaf8 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -230,6 +230,8 @@ struct tree_common GTY(()) VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE ASM_VOLATILE_P in ASM_EXPR + TYPE_CACHED_VALUES_P in + ..._TYPE private_flag: @@ -782,6 +784,10 @@ extern void tree_operand_check_failed (int, enum tree_code, for this name in an inner scope. */ #define TREE_PUBLIC(NODE) ((NODE)->common.public_flag) +/* In a _TYPE, indicates whether TYPE_CACHED_VALUES contains a vector + of cached values, or is something else. */ +#define TYPE_CACHED_VALUES_P(NODE) (TYPE_CHECK(NODE)->common.public_flag) + /* In any expression, decl, or constant, nonzero means it has side effects or reevaluation of the whole expression could produce a different value. This is set if any subexpression is a function call, a side effect or a @@ -1377,10 +1383,13 @@ struct tree_block GTY(()) #define TYPE_SIZE(NODE) (TYPE_CHECK (NODE)->type.size) #define TYPE_SIZE_UNIT(NODE) (TYPE_CHECK (NODE)->type.size_unit) #define TYPE_MODE(NODE) (TYPE_CHECK (NODE)->type.mode) -#define TYPE_ORIG_SIZE_TYPE(NODE) (INTEGER_TYPE_CHECK (NODE)->type.values) #define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type.values) #define TYPE_DOMAIN(NODE) (SET_OR_ARRAY_CHECK (NODE)->type.values) #define TYPE_FIELDS(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.values) +#define TYPE_CACHED_VALUES(NODE) (TYPE_CHECK(NODE)->type.values) +#define TYPE_ORIG_SIZE_TYPE(NODE) \ + (INTEGER_TYPE_CHECK (NODE)->type.values \ + ? TREE_TYPE ((NODE)->type.values) : NULL_TREE) #define TYPE_METHODS(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.maxval) #define TYPE_VFIELD(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.minval) #define TYPE_ARG_TYPES(NODE) (FUNC_OR_METHOD_CHECK (NODE)->type.values) -- 2.30.2