4.4.1-2.fc11

This commit is contained in:
Jakub Jelinek 2009-07-29 13:35:47 +00:00
parent ff4c956886
commit a4dde828cd
7 changed files with 1469 additions and 37 deletions

View File

@ -1,2 +1,2 @@
fastjar-0.97.tar.gz
gcc-4.4.0-20090514.tar.bz2
gcc-4.4.1-20090729.tar.bz2

View File

@ -1,9 +1,9 @@
%global DATE 20090514
%global SVNREV 147523
%global gcc_version 4.4.0
%global DATE 20090729
%global SVNREV 150210
%global gcc_version 4.4.1
# Note, gcc_release must be integer, if you want to add suffixes to
# %{release}, append them after %{gcc_release} on Release: line.
%global gcc_release 5
%global gcc_release 2
%global _unpackaged_files_terminate_build 0
%global multilib_64_archs sparc64 ppc64 s390x x86_64
%global include_gappletviewer 1
@ -40,14 +40,14 @@
Summary: Various compilers (C, C++, Objective-C, Java, ...)
Name: gcc
Version: %{gcc_version}
Release: %{gcc_release}
Release: %{gcc_release}%{?dist}
# libgcc, libgfortran, libmudflap, libgomp, libstdc++ and crtstuff have
# GCC Runtime Exception.
License: GPLv3+, GPLv3+ with exceptions and GPLv2+ with exceptions
Group: Development/Languages
# The source for this package was pulled from upstream's vcs. Use the
# following commands to generate the tarball:
# svn export svn://gcc.gnu.org/svn/gcc/branches/redhat/gcc-4_4-branch@%{SVNREV} gcc-%{version}-%{DATE}
# svn export svn://gcc.gnu.org/svn/gcc/branches/redhat/fc11-4_4-branch@%{SVNREV} gcc-%{version}-%{DATE}
# tar cf - gcc-%{version}-%{DATE} | bzip2 -9 > gcc-%{version}-%{DATE}.tar.bz2
Source0: gcc-%{version}-%{DATE}.tar.bz2
Source1: libgcc_post_upgrade.c
@ -152,14 +152,14 @@ Patch16: gcc44-libgomp-omp_h-multilib.patch
Patch20: gcc44-libtool-no-rpath.patch
Patch21: gcc44-cloog-dl.patch
Patch22: gcc44-raw-string.patch
Patch24: gcc44-atom.patch
Patch24: gcc44-unwind-debug-hook.patch
Patch25: gcc44-power7.patch
Patch26: gcc44-power7-2.patch
Patch27: gcc44-power7-3.patch
Patch28: gcc44-pr38757.patch
Patch29: gcc44-pr39856.patch
Patch30: gcc44-libstdc++-docs.patch
Patch31: gcc44-pr39942.patch
Patch29: gcc44-libstdc++-docs.patch
Patch30: gcc44-rh503816-1.patch
Patch31: gcc44-rh503816-2.patch
Patch1000: fastjar-0.97-segfault.patch
@ -459,16 +459,16 @@ which are required to compile with the GNAT.
%patch21 -p0 -b .cloog-dl~
%endif
%patch22 -p0 -b .raw-string~
%patch24 -p0 -b .atom~
%patch24 -p0 -b .unwind-debug-hook~
%patch25 -p0 -b .power7~
%patch26 -p0 -b .power7-2~
%patch27 -p0 -b .power7-3~
%patch28 -p0 -b .pr38757~
%patch29 -p0 -b .pr39856~
%if %{build_libstdcxx_docs}
%patch30 -p0 -b .libstdc++-docs~
%patch29 -p0 -b .libstdc++-docs~
%endif
%patch31 -p0 -b .pr39942~
%patch30 -p0 -b .rh503816-1~
%patch31 -p0 -b .rh503816-2~
# This testcase doesn't compile.
rm libjava/testsuite/libjava.lang/PR35020*
@ -481,7 +481,7 @@ tar xzf %{SOURCE4}
tar xjf %{SOURCE10}
%endif
sed -i -e 's/4\.4\.1/4.4.0/' gcc/BASE-VER
sed -i -e 's/4\.4\.2/4.4.1/' gcc/BASE-VER
echo 'Red Hat %{version}-%{gcc_release}' > gcc/DEV-PHASE
cp -a libstdc++-v3/config/cpu/i{4,3}86/atomicity.h
@ -1803,6 +1803,61 @@ fi
%doc rpm.doc/changelogs/libmudflap/ChangeLog*
%changelog
* Wed Jul 29 2009 Jakub Jelinek <jakub@redhat.com> 4.4.1-2.fc11
- update from gcc-4_4-branch
- GCC 4.4.1 release
- PRs fortran/40727, rtl-optimization/40710, target/40832,
tree-optimization/40321, libfortran/40714, target/39943, target/40809,
tree-optimization/40792, c++/40740, libstdc++/40691, middle-end/40747,
c++/36628, c++/37206, c++/40502, c++/40684, c++/40689, fortran/40440,
rtl-optimization/40667, target/40668, c++/35828, c++/37816, c++/37946,
c++/40557, c++/40633, c++/40639, debug/40666, target/38900, c++/40274,
c++/40342, c++/40566, c++/40595, c++/40619, c/39902, fortran/40443,
fortran/40551, fortran/40576, fortran/40594, fortran/40638,
libfortran/40576, libstdc++/40297, libstdc++/40600, middle-end/40585,
middle-end/40669, other/40024, target/40587, tree-optimization/40493,
tree-optimization/40542, tree-optimization/40550,
tree-optimization/40579, tree-optimization/40582,
tree-optimization/40640, fortran/39800, fortran/40402,
libstdc++/40497, middle-end/40389, middle-end/40404, middle-end/40446,
middle-end/40460, objc/28050, target/40470, tree-optimization/40492,
fortran/40168, c++/40381, libfortran/40330, ada/40166,
bootstrap/40027, c++/38064, c++/39754, c++/40007,
c++/40139, c/40172, c++/40306, c++/40307, c++/40308, c++/40311,
c++/40370, c++/40372, c++/40373, debug/40109, fortran/22423,
fortran/38654, fortran/39893, fortran/40019, fortran/40195,
libfortran/25561, libfortran/37754, libfortran/38668,
libfortran/39665, libfortran/39667, libfortran/39702,
libfortran/39709, libfortran/39782, libfortran/40334,
libgfortran/39664, libgomp/40174, libstdc++/36211, libstdc++/40192,
libstdc++/40296, libstdc++/40299, middle-end/32950, middle-end/40147,
middle-end/40204, middle-end/40233, middle-end/40252,
middle-end/40291, middle-end/40328, middle-end/40340,
rtl-optimization/40105, target/40017, target/40153, target/40266,
testsuite/39907, tree-optimization/39999, tree-optimization/40087,
tree-optimization/40238, tree-optimization/40254
- fix ICE in gsi_insert_seq_nodes_after (#505798,
PR tree-optimization/40813)
- fix ICE in gimplify_conversion (#511229, PR c++/40780)
- fix Fortran MINLOC/MAXLOC/MINVAL/MAXVAL handling of infinities and NaNs,
speed them up (PRs fortran/40643, fortran/31067)
- fix ICE with Fortran data xfer without io unit (PR fortran/40839)
- vectorize unsigned int -> {float,double} conversions on x86/x86_64
(PR target/40811)
- avoid overlapping entries in .debug_ranges section (PR debug/40713)
- speed up polyhedron NF (PR middle-end/34163)
- fix debug info for inlines (PR debug/40573)
- optimize assuming allocatable arrays in the innermost
dimension are always stride 1 (PR fortran/32131)
- decrease memory consumption and speed up var-tracking pass (#503816)
- add -mcrc32 support on ix86
- fix up ix86 padding for branch mispredicts
- improve .debug_loc generation
- support Atom for -march=native
- add -mmovbe support for Atom
- improve ix86 instruction length computation, remove some unneeded padding
- add unwind debug hook for gdb
* Thu May 14 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-5
- update from gcc-4_4-branch
- PRs c++/17395, c/39983, fortran/38863, fortran/38956, fortran/39879,

View File

@ -3434,7 +3434,7 @@
+ "du2_power7,VSU_power7")
--- gcc/config/rs6000/rs6000-c.c (.../trunk) (revision 145777)
+++ gcc/config/rs6000/rs6000-c.c (.../branches/ibm/power7-meissner) (revision 146027)
@@ -105,11 +105,14 @@ altivec_categorize_keyword (const cpp_to
@@ -106,14 +106,17 @@ altivec_categorize_keyword (const cpp_to
if (ident == C_CPP_HASHNODE (vector_keyword))
return C_CPP_HASHNODE (__vector_keyword);
@ -3449,11 +3449,16 @@
- return C_CPP_HASHNODE (__bool_keyword);
+ if (ident == C_CPP_HASHNODE (bool_keyword))
+ return C_CPP_HASHNODE (__bool_keyword);
- if (ident == C_CPP_HASHNODE (_Bool_keyword))
- return C_CPP_HASHNODE (__bool_keyword);
+ if (ident == C_CPP_HASHNODE (_Bool_keyword))
+ return C_CPP_HASHNODE (__bool_keyword);
+ }
return ident;
}
@@ -127,20 +130,23 @@ init_vector_keywords (void)
@@ -131,23 +134,26 @@ init_vector_keywords (void)
__vector_keyword = get_identifier ("__vector");
C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
@ -3475,19 +3480,24 @@
+
+ __bool_keyword = get_identifier ("__bool");
+ C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL;
+
+ pixel_keyword = get_identifier ("pixel");
+ C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL;
- bool_keyword = get_identifier ("bool");
- C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
+ pixel_keyword = get_identifier ("pixel");
+ C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL;
- _Bool_keyword = get_identifier ("_Bool");
- C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;
+ bool_keyword = get_identifier ("bool");
+ C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
+
+ _Bool_keyword = get_identifier ("_Bool");
+ C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;
+ }
}
/* Called to decide whether a conditional macro should be expanded.
@@ -207,7 +213,8 @@ rs6000_macro_to_expand (cpp_reader *pfil
@@ -214,7 +220,8 @@ rs6000_macro_to_expand (cpp_reader *pfil
if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
|| rid_code == RID_SHORT || rid_code == RID_SIGNED
|| rid_code == RID_INT || rid_code == RID_CHAR
@ -3497,7 +3507,7 @@
{
expand_this = C_CPP_HASHNODE (__vector_keyword);
/* If the next keyword is bool or pixel, it
@@ -277,13 +284,14 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
@@ -284,13 +291,14 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
builtin_define ("_ARCH_PWR6X");
if (! TARGET_POWER && ! TARGET_POWER2 && ! TARGET_POWERPC)
builtin_define ("_ARCH_COM");
@ -3513,13 +3523,16 @@
builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short");
builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned");
@@ -292,9 +300,18 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
@@ -298,11 +306,20 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
{
/* Define this when supporting context-sensitive keywords. */
builtin_define ("__APPLE_ALTIVEC__");
-
- builtin_define ("vector=vector");
+
builtin_define ("pixel=pixel");
builtin_define ("bool=bool");
builtin_define ("_Bool=_Bool");
+ }
+ }
+ if (TARGET_ALTIVEC || TARGET_VSX)
@ -3533,7 +3546,7 @@
init_vector_keywords ();
/* Enable context-sensitive macros. */
@@ -318,6 +335,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
@@ -326,6 +343,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
/* Used by libstdc++. */
if (TARGET_NO_LWSYNC)
builtin_define ("__NO_LWSYNC__");
@ -3542,7 +3555,7 @@
/* May be overridden by target configuration. */
RS6000_CPU_CPP_ENDIAN_BUILTINS();
@@ -496,6 +515,8 @@ const struct altivec_builtin_types altiv
@@ -504,6 +523,8 @@ const struct altivec_builtin_types altiv
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
@ -3551,7 +3564,7 @@
{ ALTIVEC_BUILTIN_VEC_VADDFP, ALTIVEC_BUILTIN_VADDFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM,
@@ -639,6 +660,12 @@ const struct altivec_builtin_types altiv
@@ -647,6 +668,12 @@ const struct altivec_builtin_types altiv
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
@ -3564,7 +3577,7 @@
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
@@ -687,6 +714,12 @@ const struct altivec_builtin_types altiv
@@ -695,6 +722,12 @@ const struct altivec_builtin_types altiv
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
@ -3577,7 +3590,7 @@
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
@@ -1190,6 +1223,8 @@ const struct altivec_builtin_types altiv
@@ -1198,6 +1231,8 @@ const struct altivec_builtin_types altiv
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
@ -3586,7 +3599,7 @@
{ ALTIVEC_BUILTIN_VEC_VMAXFP, ALTIVEC_BUILTIN_VMAXFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW,
@@ -1366,6 +1401,8 @@ const struct altivec_builtin_types altiv
@@ -1374,6 +1409,8 @@ const struct altivec_builtin_types altiv
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
@ -3595,7 +3608,7 @@
{ ALTIVEC_BUILTIN_VEC_VMINFP, ALTIVEC_BUILTIN_VMINFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW,
@@ -1451,6 +1488,8 @@ const struct altivec_builtin_types altiv
@@ -1459,6 +1496,8 @@ const struct altivec_builtin_types altiv
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
@ -3604,7 +3617,7 @@
RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
@@ -1475,6 +1514,12 @@ const struct altivec_builtin_types altiv
@@ -1483,6 +1522,12 @@ const struct altivec_builtin_types altiv
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
@ -3617,7 +3630,7 @@
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
@@ -1932,6 +1977,8 @@ const struct altivec_builtin_types altiv
@@ -1940,6 +1985,8 @@ const struct altivec_builtin_types altiv
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
@ -3626,7 +3639,7 @@
{ ALTIVEC_BUILTIN_VEC_VSUBFP, ALTIVEC_BUILTIN_VSUBFP,
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM,
@@ -2091,6 +2138,12 @@ const struct altivec_builtin_types altiv
@@ -2099,6 +2146,12 @@ const struct altivec_builtin_types altiv
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 },
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
@ -3639,7 +3652,7 @@
RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 },
{ ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 },
@@ -2981,8 +3034,10 @@ altivec_resolve_overloaded_builtin (tree
@@ -2989,8 +3042,10 @@ altivec_resolve_overloaded_builtin (tree
const struct altivec_builtin_types *desc;
int n;

827
gcc44-rh503816-1.patch Normal file
View File

@ -0,0 +1,827 @@
2009-06-21 Jakub Jelinek <jakub@redhat.com>
* var-tracking.c (struct shared_hash_def, shared_hash): New types.
(dataflow_set): Change vars type from htab_t to shared_hash.
(shared_hash_pool, empty_shared_hash): New variables.
(vars_clear): Removed.
(shared_hash_shared, shared_hash_htab, shared_hash_copy,
shared_hash_find_slot_unshare, shared_hash_find_slot,
shared_hash_find_slot_noinsert, shared_hash_find): New
static inlines.
(shared_hash_unshare, shared_hash_destroy): New functions.
(unshare_variable): Unshare set->vars if shared, use
shared_hash_htab.
(vars_copy): Use htab_traverse_noresize instead of htab_traverse.
(get_init_value, find_src_set_src, dump_dataflow_set,
clobber_variable_part, emit_notes_for_differences): Use
shared_hash_htab.
(dataflow_set_init): Remove second argument, set vars to
empty_shared_hash instead of creating a new htab.
(dataflow_set_clear): Call shared_hash_destroy and set vars
to empty_shared_hash instead of calling vars_clear.
(dataflow_set_copy): Don't call vars_copy, instead just share
the src htab with dst.
(variable_union): Use shared_hash_*, use initially NO_INSERT
lookup if set->vars is shared. Don't keep slot cleared before
calling unshare_variable. Unshare set->vars if needed.
Even ->refcount == 1 vars must be unshared if set->vars is shared
and var needs to be modified.
(variable_canonicalize): New function.
(dataflow_set_union): If dst->vars is empty, just share src->vars
with dst->vars and traverse with variable_canonicalize to canonicalize
and unshare what is needed.
(dataflow_set_different): If old_set and new_set use the same shared
htab, they aren't different. If number of htab elements is different,
htabs are different. Use shared_hash_*.
(dataflow_set_destroy): Call shared_hash_destroy instead of
htab_delete.
(compute_bb_dataflow, emit_notes_in_bb, vt_emit_notes): Don't pass
second argument to dataflow_set_init.
(vt_initialize): Likewise. Initialize shared_hash_pool and
empty_shared_hash, move bb in/out initialization afterwards.
Use variable_htab_free instead of NULL as changed_variables del hook.
(variable_was_changed): Change type of second argument to pointer to
dataflow_set. When inserting var into changed_variables, bump
refcount. Unshare set->vars if set is shared htab and slot needs to
be cleared.
(set_variable_part): Use shared_hash_*, use initially NO_INSERT
lookup if set->vars is shared. Unshare set->vars if needed.
Even ->refcount == 1 vars must be unshared if set->vars is shared
and var needs to be modified. Adjust variable_was_changed caller.
(delete_variable_part): Use shared_hash_*. Even ->refcount == 1
vars must be unshared if set->vars is shared and var needs to be
modified. Adjust variable_was_changed caller.
(emit_note_insn_var_location): Don't pool_free var.
(emit_notes_for_differences_1): Initialize empty_var->refcount to 0
instead of 1.
(vt_finalize): Call htab_delete on empty_shared_hash->htab and
free_alloc_pool on shared_hash_pool.
* hashtab.c (htab_traverse): Don't call htab_expand for
nearly empty hashtabs with sizes 7, 13 or 31.
--- gcc/var-tracking.c (revision 148758)
+++ gcc/var-tracking.c (revision 148760)
@@ -182,6 +182,17 @@ typedef struct attrs_def
HOST_WIDE_INT offset;
} *attrs;
+/* Structure holding a refcounted hash table. If refcount > 1,
+ it must be first unshared before modified. */
+typedef struct shared_hash_def
+{
+ /* Reference count. */
+ int refcount;
+
+ /* Actual hash table. */
+ htab_t htab;
+} *shared_hash;
+
/* Structure holding the IN or OUT set for a basic block. */
typedef struct dataflow_set_def
{
@@ -192,7 +203,7 @@ typedef struct dataflow_set_def
attrs regs[FIRST_PSEUDO_REGISTER];
/* Variable locations. */
- htab_t vars;
+ shared_hash vars;
} dataflow_set;
/* The structure (one for each basic block) containing the information
@@ -280,12 +291,18 @@ static alloc_pool var_pool;
/* Alloc pool for struct location_chain_def. */
static alloc_pool loc_chain_pool;
+/* Alloc pool for struct shared_hash_def. */
+static alloc_pool shared_hash_pool;
+
/* Changed variables, notes will be emitted for them. */
static htab_t changed_variables;
/* Shall notes be emitted? */
static bool emit_notes;
+/* Empty shared hashtable. */
+static shared_hash empty_shared_hash;
+
/* Local function prototypes. */
static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
HOST_WIDE_INT *);
@@ -305,7 +322,6 @@ static void attrs_list_insert (attrs *,
static void attrs_list_copy (attrs *, attrs);
static void attrs_list_union (attrs *, attrs);
-static void vars_clear (htab_t);
static variable unshare_variable (dataflow_set *set, variable var,
enum var_init_status);
static int vars_copy_1 (void **, void *);
@@ -321,11 +337,12 @@ static void var_mem_delete_and_set (data
enum var_init_status, rtx);
static void var_mem_delete (dataflow_set *, rtx, bool);
-static void dataflow_set_init (dataflow_set *, int);
+static void dataflow_set_init (dataflow_set *);
static void dataflow_set_clear (dataflow_set *);
static void dataflow_set_copy (dataflow_set *, dataflow_set *);
static int variable_union_info_cmp_pos (const void *, const void *);
static int variable_union (void **, void *);
+static int variable_canonicalize (void **, void *);
static void dataflow_set_union (dataflow_set *, dataflow_set *);
static bool variable_part_different_p (variable_part *, variable_part *);
static bool variable_different_p (variable, variable, bool);
@@ -352,7 +369,7 @@ static void dump_vars (htab_t);
static void dump_dataflow_set (dataflow_set *);
static void dump_dataflow_sets (void);
-static void variable_was_changed (variable, htab_t);
+static void variable_was_changed (variable, dataflow_set *);
static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT,
enum var_init_status, rtx);
static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT,
@@ -742,12 +759,107 @@ attrs_list_union (attrs *dstp, attrs src
}
}
-/* Delete all variables from hash table VARS. */
+/* Shared hashtable support. */
+
+/* Return true if VARS is shared. */
+
+static inline bool
+shared_hash_shared (shared_hash vars)
+{
+ return vars->refcount > 1;
+}
+
+/* Return the hash table for VARS. */
+
+static inline htab_t
+shared_hash_htab (shared_hash vars)
+{
+ return vars->htab;
+}
+
+/* Copy variables into a new hash table. */
+
+static shared_hash
+shared_hash_unshare (shared_hash vars)
+{
+ shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool);
+ gcc_assert (vars->refcount > 1);
+ new_vars->refcount = 1;
+ new_vars->htab
+ = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash,
+ variable_htab_eq, variable_htab_free);
+ vars_copy (new_vars->htab, vars->htab);
+ vars->refcount--;
+ return new_vars;
+}
+
+/* Increment reference counter on VARS and return it. */
+
+static inline shared_hash
+shared_hash_copy (shared_hash vars)
+{
+ vars->refcount++;
+ return vars;
+}
+
+/* Decrement reference counter and destroy hash table if not shared
+ anymore. */
static void
-vars_clear (htab_t vars)
+shared_hash_destroy (shared_hash vars)
{
- htab_empty (vars);
+ gcc_assert (vars->refcount > 0);
+ if (--vars->refcount == 0)
+ {
+ htab_delete (vars->htab);
+ pool_free (shared_hash_pool, vars);
+ }
+}
+
+/* Unshare *PVARS if shared and return slot for DECL. If INS is
+ INSERT, insert it if not already present. */
+
+static inline void **
+shared_hash_find_slot_unshare (shared_hash *pvars, tree decl,
+ enum insert_option ins)
+{
+ if (shared_hash_shared (*pvars))
+ *pvars = shared_hash_unshare (*pvars);
+ return htab_find_slot_with_hash (shared_hash_htab (*pvars), decl,
+ VARIABLE_HASH_VAL (decl), ins);
+}
+
+/* Return slot for DECL, if it is already present in the hash table.
+ If it is not present, insert it only VARS is not shared, otherwise
+ return NULL. */
+
+static inline void **
+shared_hash_find_slot (shared_hash vars, tree decl)
+{
+ return htab_find_slot_with_hash (shared_hash_htab (vars), decl,
+ VARIABLE_HASH_VAL (decl),
+ shared_hash_shared (vars)
+ ? NO_INSERT : INSERT);
+}
+
+/* Return slot for DECL only if it is already present in the hash table. */
+
+static inline void **
+shared_hash_find_slot_noinsert (shared_hash vars, tree decl)
+{
+ return htab_find_slot_with_hash (shared_hash_htab (vars), decl,
+ VARIABLE_HASH_VAL (decl), NO_INSERT);
+}
+
+/* Return variable for DECL or NULL if not already present in the hash
+ table. */
+
+static inline variable
+shared_hash_find (shared_hash vars, tree decl)
+{
+ return (variable)
+ htab_find_with_hash (shared_hash_htab (vars), decl,
+ VARIABLE_HASH_VAL (decl));
}
/* Return a copy of a variable VAR and insert it to dataflow set SET. */
@@ -801,9 +913,7 @@ unshare_variable (dataflow_set *set, var
new_var->var_part[i].cur_loc = NULL;
}
- slot = htab_find_slot_with_hash (set->vars, new_var->decl,
- VARIABLE_HASH_VAL (new_var->decl),
- INSERT);
+ slot = shared_hash_find_slot_unshare (&set->vars, new_var->decl, INSERT);
*slot = new_var;
return new_var;
}
@@ -834,8 +944,7 @@ vars_copy_1 (void **slot, void *data)
static void
vars_copy (htab_t dst, htab_t src)
{
- vars_clear (dst);
- htab_traverse (src, vars_copy_1, dst);
+ htab_traverse_noresize (src, vars_copy_1, dst);
}
/* Map a decl to its main debug decl. */
@@ -874,7 +983,6 @@ var_reg_set (dataflow_set *set, rtx loc,
static int
get_init_value (dataflow_set *set, rtx loc, tree decl)
{
- void **slot;
variable var;
int i;
int ret_val = VAR_INIT_STATUS_UNKNOWN;
@@ -882,11 +990,9 @@ get_init_value (dataflow_set *set, rtx l
if (! flag_var_tracking_uninit)
return VAR_INIT_STATUS_INITIALIZED;
- slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
- NO_INSERT);
- if (slot)
+ var = shared_hash_find (set->vars, decl);
+ if (var)
{
- var = * (variable *) slot;
for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
{
location_chain nextp;
@@ -1050,11 +1156,10 @@ var_mem_delete (dataflow_set *set, rtx l
VARS_SIZE is the initial size of hash table VARS. */
static void
-dataflow_set_init (dataflow_set *set, int vars_size)
+dataflow_set_init (dataflow_set *set)
{
init_attrs_list_set (set->regs);
- set->vars = htab_create (vars_size, variable_htab_hash, variable_htab_eq,
- variable_htab_free);
+ set->vars = shared_hash_copy (empty_shared_hash);
set->stack_adjust = 0;
}
@@ -1068,7 +1173,8 @@ dataflow_set_clear (dataflow_set *set)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
attrs_list_clear (&set->regs[i]);
- vars_clear (set->vars);
+ shared_hash_destroy (set->vars);
+ set->vars = shared_hash_copy (empty_shared_hash);
}
/* Copy the contents of dataflow set SRC to DST. */
@@ -1081,7 +1187,8 @@ dataflow_set_copy (dataflow_set *dst, da
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
attrs_list_copy (&dst->regs[i], src->regs[i]);
- vars_copy (dst->vars, src->vars);
+ shared_hash_destroy (dst->vars);
+ dst->vars = shared_hash_copy (src->vars);
dst->stack_adjust = src->stack_adjust;
}
@@ -1129,15 +1236,14 @@ variable_union_info_cmp_pos (const void
static int
variable_union (void **slot, void *data)
{
- variable src, dst, *dstp;
+ variable src, dst;
+ void **dstp;
dataflow_set *set = (dataflow_set *) data;
int i, j, k;
src = *(variable *) slot;
- dstp = (variable *) htab_find_slot_with_hash (set->vars, src->decl,
- VARIABLE_HASH_VAL (src->decl),
- INSERT);
- if (!*dstp)
+ dstp = shared_hash_find_slot (set->vars, src->decl);
+ if (!dstp || !*dstp)
{
src->refcount++;
@@ -1162,16 +1268,23 @@ variable_union (void **slot, void *data)
if (! flag_var_tracking_uninit)
status = VAR_INIT_STATUS_INITIALIZED;
+ if (dstp)
+ *dstp = (void *) src;
unshare_variable (set, src, status);
}
else
- *dstp = src;
+ {
+ if (!dstp)
+ dstp = shared_hash_find_slot_unshare (&set->vars, src->decl,
+ INSERT);
+ *dstp = (void *) src;
+ }
/* Continue traversing the hash table. */
return 1;
}
else
- dst = *dstp;
+ dst = (variable) *dstp;
gcc_assert (src->n_var_parts);
@@ -1196,7 +1309,8 @@ variable_union (void **slot, void *data)
thus there are at most MAX_VAR_PARTS different offsets. */
gcc_assert (k <= MAX_VAR_PARTS);
- if (dst->refcount > 1 && dst->n_var_parts != k)
+ if ((dst->refcount > 1 || shared_hash_shared (set->vars))
+ && dst->n_var_parts != k)
{
enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
@@ -1226,7 +1340,7 @@ variable_union (void **slot, void *data)
/* If DST is shared compare the location chains.
If they are different we will modify the chain in DST with
high probability so make a copy of DST. */
- if (dst->refcount > 1)
+ if (dst->refcount > 1 || shared_hash_shared (set->vars))
{
for (node = src->var_part[i].loc_chain,
node2 = dst->var_part[j].loc_chain; node && node2;
@@ -1379,6 +1493,46 @@ variable_union (void **slot, void *data)
return 1;
}
+/* Like variable_union, but only used when doing dataflow_set_union
+ into an empty hashtab. To allow sharing, dst is initially shared
+ with src (so all variables are "copied" from src to dst hashtab),
+ so only unshare_variable for variables that need canonicalization
+ are needed. */
+
+static int
+variable_canonicalize (void **slot, void *data)
+{
+ variable src;
+ dataflow_set *set = (dataflow_set *) data;
+ int k;
+
+ src = *(variable *) slot;
+
+ /* If CUR_LOC of some variable part is not the first element of
+ the location chain we are going to change it so we have to make
+ a copy of the variable. */
+ for (k = 0; k < src->n_var_parts; k++)
+ {
+ gcc_assert (!src->var_part[k].loc_chain == !src->var_part[k].cur_loc);
+ if (src->var_part[k].loc_chain)
+ {
+ gcc_assert (src->var_part[k].cur_loc);
+ if (src->var_part[k].cur_loc != src->var_part[k].loc_chain->loc)
+ break;
+ }
+ }
+ if (k < src->n_var_parts)
+ {
+ enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
+
+ if (! flag_var_tracking_uninit)
+ status = VAR_INIT_STATUS_INITIALIZED;
+
+ unshare_variable (set, src, status);
+ }
+ return 1;
+}
+
/* Compute union of dataflow sets SRC and DST and store it to DST. */
static void
@@ -1389,7 +1543,14 @@ dataflow_set_union (dataflow_set *dst, d
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
attrs_list_union (&dst->regs[i], src->regs[i]);
- htab_traverse (src->vars, variable_union, dst);
+ if (dst->vars == empty_shared_hash)
+ {
+ shared_hash_destroy (dst->vars);
+ dst->vars = shared_hash_copy (src->vars);
+ htab_traverse (shared_hash_htab (src->vars), variable_canonicalize, dst);
+ }
+ else
+ htab_traverse (shared_hash_htab (src->vars), variable_union, dst);
}
/* Flag whether two dataflow sets being compared contain different data. */
@@ -1522,15 +1683,24 @@ dataflow_set_different_2 (void **slot, v
static bool
dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
{
+ if (old_set->vars == new_set->vars)
+ return false;
+
+ if (htab_elements (shared_hash_htab (old_set->vars))
+ != htab_elements (shared_hash_htab (new_set->vars)))
+ return true;
+
dataflow_set_different_value = false;
- htab_traverse (old_set->vars, dataflow_set_different_1, new_set->vars);
+ htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
+ shared_hash_htab (new_set->vars));
if (!dataflow_set_different_value)
{
/* We have compared the variables which are in both hash tables
so now only check whether there are some variables in NEW_SET->VARS
which are not in OLD_SET->VARS. */
- htab_traverse (new_set->vars, dataflow_set_different_2, old_set->vars);
+ htab_traverse (shared_hash_htab (new_set->vars), dataflow_set_different_2,
+ shared_hash_htab (old_set->vars));
}
return dataflow_set_different_value;
}
@@ -1545,7 +1715,7 @@ dataflow_set_destroy (dataflow_set *set)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
attrs_list_clear (&set->regs[i]);
- htab_delete (set->vars);
+ shared_hash_destroy (set->vars);
set->vars = NULL;
}
@@ -1985,7 +2155,6 @@ find_src_set_src (dataflow_set *set, rtx
{
tree decl = NULL_TREE; /* The variable being copied around. */
rtx set_src = NULL_RTX; /* The value for "decl" stored in "src". */
- void **slot;
variable var;
location_chain nextp;
int i;
@@ -1998,12 +2167,9 @@ find_src_set_src (dataflow_set *set, rtx
if (src && decl)
{
- slot = htab_find_slot_with_hash (set->vars, decl,
- VARIABLE_HASH_VAL (decl), NO_INSERT);
-
- if (slot)
+ var = shared_hash_find (set->vars, decl);
+ if (var)
{
- var = *(variable *) slot;
found = false;
for (i = 0; i < var->n_var_parts && !found; i++)
for (nextp = var->var_part[i].loc_chain; nextp && !found;
@@ -2031,7 +2197,7 @@ compute_bb_dataflow (basic_block bb)
dataflow_set *in = &VTI (bb)->in;
dataflow_set *out = &VTI (bb)->out;
- dataflow_set_init (&old_out, htab_elements (VTI (bb)->out.vars) + 3);
+ dataflow_set_init (&old_out);
dataflow_set_copy (&old_out, out);
dataflow_set_copy (out, in);
@@ -2323,7 +2489,7 @@ dump_dataflow_set (dataflow_set *set)
dump_attrs_list (set->regs[i]);
}
}
- dump_vars (set->vars);
+ dump_vars (shared_hash_htab (set->vars));
fprintf (dump_file, "\n");
}
@@ -2345,10 +2511,10 @@ dump_dataflow_sets (void)
}
/* Add variable VAR to the hash table of changed variables and
- if it has no locations delete it from hash table HTAB. */
+ if it has no locations delete it from SET's hash table. */
static void
-variable_was_changed (variable var, htab_t htab)
+variable_was_changed (variable var, dataflow_set *set)
{
hashval_t hash = VARIABLE_HASH_VAL (var->decl);
@@ -2359,36 +2525,39 @@ variable_was_changed (variable var, htab
slot = (variable *) htab_find_slot_with_hash (changed_variables,
var->decl, hash, INSERT);
- if (htab && var->n_var_parts == 0)
+ if (set && var->n_var_parts == 0)
{
variable empty_var;
- void **old;
empty_var = (variable) pool_alloc (var_pool);
empty_var->decl = var->decl;
empty_var->refcount = 1;
empty_var->n_var_parts = 0;
*slot = empty_var;
-
- old = htab_find_slot_with_hash (htab, var->decl, hash,
- NO_INSERT);
- if (old)
- htab_clear_slot (htab, old);
+ goto drop_var;
}
else
{
+ var->refcount++;
*slot = var;
}
}
else
{
- gcc_assert (htab);
+ gcc_assert (set);
if (var->n_var_parts == 0)
{
- void **slot = htab_find_slot_with_hash (htab, var->decl, hash,
- NO_INSERT);
+ void **slot;
+
+ drop_var:
+ slot = shared_hash_find_slot_noinsert (set->vars, var->decl);
if (slot)
- htab_clear_slot (htab, slot);
+ {
+ if (shared_hash_shared (set->vars))
+ slot = shared_hash_find_slot_unshare (&set->vars, var->decl,
+ NO_INSERT);
+ htab_clear_slot (shared_hash_htab (set->vars), slot);
+ }
}
}
}
@@ -2438,12 +2607,12 @@ set_variable_part (dataflow_set *set, rt
location_chain node, next;
location_chain *nextp;
variable var;
- void **slot;
-
- slot = htab_find_slot_with_hash (set->vars, decl,
- VARIABLE_HASH_VAL (decl), INSERT);
- if (!*slot)
+ void **slot = shared_hash_find_slot (set->vars, decl);
+
+ if (!slot || !*slot)
{
+ if (!slot)
+ slot = shared_hash_find_slot_unshare (&set->vars, decl, INSERT);
/* Create new variable information. */
var = (variable) pool_alloc (var_pool);
var->decl = decl;
@@ -2479,13 +2648,12 @@ set_variable_part (dataflow_set *set, rt
if (set_src != NULL)
node->set_src = set_src;
- *slot = var;
return;
}
else
{
/* We have to make a copy of a shared variable. */
- if (var->refcount > 1)
+ if (var->refcount > 1 || shared_hash_shared (set->vars))
var = unshare_variable (set, var, initialized);
}
}
@@ -2494,7 +2662,7 @@ set_variable_part (dataflow_set *set, rt
/* We have not found the location part, new one will be created. */
/* We have to make a copy of the shared variable. */
- if (var->refcount > 1)
+ if (var->refcount > 1 || shared_hash_shared (set->vars))
var = unshare_variable (set, var, initialized);
/* We track only variables whose size is <= MAX_VAR_PARTS bytes
@@ -2548,7 +2716,7 @@ set_variable_part (dataflow_set *set, rt
if (var->var_part[pos].cur_loc == NULL)
{
var->var_part[pos].cur_loc = loc;
- variable_was_changed (var, set->vars);
+ variable_was_changed (var, set);
}
}
@@ -2561,16 +2729,14 @@ static void
clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
HOST_WIDE_INT offset, rtx set_src)
{
- void **slot;
+ variable var;
if (! decl || ! DECL_P (decl))
return;
- slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
- NO_INSERT);
- if (slot)
+ var = shared_hash_find (set->vars, decl);
+ if (var)
{
- variable var = (variable) *slot;
int pos = find_variable_location_part (var, offset, NULL);
if (pos >= 0)
@@ -2627,13 +2793,9 @@ static void
delete_variable_part (dataflow_set *set, rtx loc, tree decl,
HOST_WIDE_INT offset)
{
- void **slot;
-
- slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
- NO_INSERT);
- if (slot)
+ variable var = shared_hash_find (set->vars, decl);;
+ if (var)
{
- variable var = (variable) *slot;
int pos = find_variable_location_part (var, offset, NULL);
if (pos >= 0)
@@ -2642,7 +2804,7 @@ delete_variable_part (dataflow_set *set,
location_chain *nextp;
bool changed;
- if (var->refcount > 1)
+ if (var->refcount > 1 || shared_hash_shared (set->vars))
{
/* If the variable contains the location part we have to
make a copy of the variable. */
@@ -2705,7 +2867,7 @@ delete_variable_part (dataflow_set *set,
}
}
if (changed)
- variable_was_changed (var, set->vars);
+ variable_was_changed (var, set);
}
}
}
@@ -2864,14 +3026,6 @@ emit_note_insn_var_location (void **varp
htab_clear_slot (changed_variables, varp);
- /* When there are no location parts the variable has been already
- removed from hash table and a new empty variable was created.
- Free the empty variable. */
- if (var->n_var_parts == 0)
- {
- pool_free (var_pool, var);
- }
-
/* Continue traversing the hash table. */
return 1;
}
@@ -2910,7 +3064,7 @@ emit_notes_for_differences_1 (void **slo
empty_var = (variable) pool_alloc (var_pool);
empty_var->decl = old_var->decl;
- empty_var->refcount = 1;
+ empty_var->refcount = 0;
empty_var->n_var_parts = 0;
variable_was_changed (empty_var, NULL);
}
@@ -2952,8 +3106,12 @@ static void
emit_notes_for_differences (rtx insn, dataflow_set *old_set,
dataflow_set *new_set)
{
- htab_traverse (old_set->vars, emit_notes_for_differences_1, new_set->vars);
- htab_traverse (new_set->vars, emit_notes_for_differences_2, old_set->vars);
+ htab_traverse (shared_hash_htab (old_set->vars),
+ emit_notes_for_differences_1,
+ shared_hash_htab (new_set->vars));
+ htab_traverse (shared_hash_htab (new_set->vars),
+ emit_notes_for_differences_2,
+ shared_hash_htab (old_set->vars));
emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
}
@@ -2965,7 +3123,7 @@ emit_notes_in_bb (basic_block bb)
int i;
dataflow_set set;
- dataflow_set_init (&set, htab_elements (VTI (bb)->in.vars) + 3);
+ dataflow_set_init (&set);
dataflow_set_copy (&set, &VTI (bb)->in);
for (i = 0; i < VTI (bb)->n_mos; i++)
@@ -3098,7 +3256,7 @@ vt_emit_notes (void)
delete_variable_part). */
emit_notes = true;
- dataflow_set_init (&empty, 7);
+ dataflow_set_init (&empty);
last_out = &empty;
FOR_EACH_BB (bb)
@@ -3343,14 +3501,6 @@ vt_initialize (void)
}
}
- /* Init the IN and OUT sets. */
- FOR_ALL_BB (bb)
- {
- VTI (bb)->visited = false;
- dataflow_set_init (&VTI (bb)->in, 7);
- dataflow_set_init (&VTI (bb)->out, 7);
- }
-
attrs_pool = create_alloc_pool ("attrs_def pool",
sizeof (struct attrs_def), 1024);
var_pool = create_alloc_pool ("variable_def pool",
@@ -3358,8 +3508,24 @@ vt_initialize (void)
loc_chain_pool = create_alloc_pool ("location_chain_def pool",
sizeof (struct location_chain_def),
1024);
+ shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
+ sizeof (struct shared_hash_def), 256);
+ empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
+ empty_shared_hash->refcount = 1;
+ empty_shared_hash->htab
+ = htab_create (1, variable_htab_hash, variable_htab_eq,
+ variable_htab_free);
changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
- NULL);
+ variable_htab_free);
+
+ /* Init the IN and OUT sets. */
+ FOR_ALL_BB (bb)
+ {
+ VTI (bb)->visited = false;
+ dataflow_set_init (&VTI (bb)->in);
+ dataflow_set_init (&VTI (bb)->out);
+ }
+
vt_add_function_parameters ();
}
@@ -3381,10 +3547,12 @@ vt_finalize (void)
dataflow_set_destroy (&VTI (bb)->out);
}
free_aux_for_blocks ();
+ htab_delete (empty_shared_hash->htab);
+ htab_delete (changed_variables);
free_alloc_pool (attrs_pool);
free_alloc_pool (var_pool);
free_alloc_pool (loc_chain_pool);
- htab_delete (changed_variables);
+ free_alloc_pool (shared_hash_pool);
}
/* The entry point to variable tracking pass. */
--- libiberty/hashtab.c (revision 148758)
+++ libiberty/hashtab.c (revision 148760)
@@ -759,7 +759,8 @@ htab_traverse_noresize (htab_t htab, hta
void
htab_traverse (htab_t htab, htab_trav callback, PTR info)
{
- if (htab_elements (htab) * 8 < htab_size (htab))
+ size_t size = htab_size (htab);
+ if (htab_elements (htab) * 8 < size && size > 32)
htab_expand (htab);
htab_traverse_noresize (htab, callback, info);

491
gcc44-rh503816-2.patch Normal file
View File

@ -0,0 +1,491 @@
2009-06-23 Jakub Jelinek <jakub@redhat.com>
* var-tracking.c (unshare_variable): Force initialized to
be VAR_INIT_STATUS_INITIALIZED unless flag_var_tracking_uninit.
(set_variable_part): Likewise.
(struct variable_union_info): Remove pos_src field.
(vui_vec, vui_allocated): New variables.
(variable_union): Pass VAR_INIT_STATUS_UNKNOWN to unshare_variable
unconditionally. Avoid XCVECNEW/free for every sorting, for dst_l
== 1 use a simpler sorting algorithm. Compute pos field right
away, don't fill in pos_src. For dst_l == 2 avoid qsort.
Avoid quadratic comparison if !flag_var_tracking_uninit.
(variable_canonicalize): Pass VAR_INIT_STATUS_UNKNOWN to
unshare_variable unconditionally.
(dataflow_set_different_2): Removed.
(dataflow_set_different): Don't traverse second hash table.
(compute_bb_dataflow): Pass VAR_INIT_STATUS_UNINITIALIZED
unconditionally to var_reg_set or var_mem_set.
(emit_notes_in_bb): Likewise.
(delete_variable_part): Pass VAR_INIT_STATUS_UNKNOWN to
unshare_variable.
(emit_note_insn_var_location): Don't set initialized to
VAR_INIT_STATUS_INITIALIZED early.
(vt_finalize): Free vui_vec if needed, clear vui_vec and
vui_allocated.
--- gcc/var-tracking.c (revision 148851)
+++ gcc/var-tracking.c (revision 148852)
@@ -347,7 +347,6 @@ static void dataflow_set_union (dataflow
static bool variable_part_different_p (variable_part *, variable_part *);
static bool variable_different_p (variable, variable, bool);
static int dataflow_set_different_1 (void **, void *);
-static int dataflow_set_different_2 (void **, void *);
static bool dataflow_set_different (dataflow_set *, dataflow_set *);
static void dataflow_set_destroy (dataflow_set *);
@@ -878,6 +877,9 @@ unshare_variable (dataflow_set *set, var
var->refcount--;
new_var->n_var_parts = var->n_var_parts;
+ if (! flag_var_tracking_uninit)
+ initialized = VAR_INIT_STATUS_INITIALIZED;
+
for (i = 0; i < var->n_var_parts; i++)
{
location_chain node;
@@ -1202,11 +1204,14 @@ struct variable_union_info
/* The sum of positions in the input chains. */
int pos;
- /* The position in the chains of SRC and DST dataflow sets. */
- int pos_src;
+ /* The position in the chain of DST dataflow set. */
int pos_dst;
};
+/* Buffer for location list sorting and its allocated size. */
+static struct variable_union_info *vui_vec;
+static int vui_allocated;
+
/* Compare function for qsort, order the structures by POS element. */
static int
@@ -1263,14 +1268,9 @@ variable_union (void **slot, void *data)
}
if (k < src->n_var_parts)
{
- enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
-
- if (! flag_var_tracking_uninit)
- status = VAR_INIT_STATUS_INITIALIZED;
-
if (dstp)
*dstp = (void *) src;
- unshare_variable (set, src, status);
+ unshare_variable (set, src, VAR_INIT_STATUS_UNKNOWN);
}
else
{
@@ -1311,13 +1311,7 @@ variable_union (void **slot, void *data)
if ((dst->refcount > 1 || shared_hash_shared (set->vars))
&& dst->n_var_parts != k)
- {
- enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
-
- if (! flag_var_tracking_uninit)
- status = VAR_INIT_STATUS_INITIALIZED;
- dst = unshare_variable (set, dst, status);
- }
+ dst = unshare_variable (set, dst, VAR_INIT_STATUS_UNKNOWN);
i = src->n_var_parts - 1;
j = dst->n_var_parts - 1;
@@ -1366,70 +1360,152 @@ variable_union (void **slot, void *data)
dst_l = 0;
for (node = dst->var_part[j].loc_chain; node; node = node->next)
dst_l++;
- vui = XCNEWVEC (struct variable_union_info, src_l + dst_l);
- /* Fill in the locations from DST. */
- for (node = dst->var_part[j].loc_chain, jj = 0; node;
- node = node->next, jj++)
+ if (dst_l == 1)
{
- vui[jj].lc = node;
- vui[jj].pos_dst = jj;
+ /* The most common case, much simpler, no qsort is needed. */
+ location_chain dstnode = dst->var_part[j].loc_chain;
+ dst->var_part[k].loc_chain = dstnode;
+ dst->var_part[k].offset = dst->var_part[j].offset;
+ node2 = dstnode;
+ for (node = src->var_part[i].loc_chain; node; node = node->next)
+ if (!((REG_P (dstnode->loc)
+ && REG_P (node->loc)
+ && REGNO (dstnode->loc) == REGNO (node->loc))
+ || rtx_equal_p (dstnode->loc, node->loc)))
+ {
+ location_chain new_node;
- /* Value larger than a sum of 2 valid positions. */
- vui[jj].pos_src = src_l + dst_l;
+ /* Copy the location from SRC. */
+ new_node = (location_chain) pool_alloc (loc_chain_pool);
+ new_node->loc = node->loc;
+ new_node->init = node->init;
+ if (!node->set_src || MEM_P (node->set_src))
+ new_node->set_src = NULL;
+ else
+ new_node->set_src = node->set_src;
+ node2->next = new_node;
+ node2 = new_node;
+ }
+ node2->next = NULL;
}
-
- /* Fill in the locations from SRC. */
- n = dst_l;
- for (node = src->var_part[i].loc_chain, ii = 0; node;
- node = node->next, ii++)
+ else
{
- /* Find location from NODE. */
- for (jj = 0; jj < dst_l; jj++)
+ if (src_l + dst_l > vui_allocated)
{
- if ((REG_P (vui[jj].lc->loc)
- && REG_P (node->loc)
- && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
- || rtx_equal_p (vui[jj].lc->loc, node->loc))
- {
- vui[jj].pos_src = ii;
- break;
- }
+ vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
+ vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
+ vui_allocated);
}
- if (jj >= dst_l) /* The location has not been found. */
+ vui = vui_vec;
+
+ /* Fill in the locations from DST. */
+ for (node = dst->var_part[j].loc_chain, jj = 0; node;
+ node = node->next, jj++)
{
- location_chain new_node;
+ vui[jj].lc = node;
+ vui[jj].pos_dst = jj;
- /* Copy the location from SRC. */
- new_node = (location_chain) pool_alloc (loc_chain_pool);
- new_node->loc = node->loc;
- new_node->init = node->init;
- if (!node->set_src || MEM_P (node->set_src))
- new_node->set_src = NULL;
- else
- new_node->set_src = node->set_src;
- vui[n].lc = new_node;
- vui[n].pos_src = ii;
- vui[n].pos_dst = src_l + dst_l;
- n++;
+ /* Pos plus value larger than a sum of 2 valid positions. */
+ vui[jj].pos = jj + src_l + dst_l;
}
- }
- for (ii = 0; ii < src_l + dst_l; ii++)
- vui[ii].pos = vui[ii].pos_src + vui[ii].pos_dst;
+ /* Fill in the locations from SRC. */
+ n = dst_l;
+ for (node = src->var_part[i].loc_chain, ii = 0; node;
+ node = node->next, ii++)
+ {
+ /* Find location from NODE. */
+ for (jj = 0; jj < dst_l; jj++)
+ {
+ if ((REG_P (vui[jj].lc->loc)
+ && REG_P (node->loc)
+ && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
+ || rtx_equal_p (vui[jj].lc->loc, node->loc))
+ {
+ vui[jj].pos = jj + ii;
+ break;
+ }
+ }
+ if (jj >= dst_l) /* The location has not been found. */
+ {
+ location_chain new_node;
- qsort (vui, n, sizeof (struct variable_union_info),
- variable_union_info_cmp_pos);
+ /* Copy the location from SRC. */
+ new_node = (location_chain) pool_alloc (loc_chain_pool);
+ new_node->loc = node->loc;
+ new_node->init = node->init;
+ if (!node->set_src || MEM_P (node->set_src))
+ new_node->set_src = NULL;
+ else
+ new_node->set_src = node->set_src;
+ vui[n].lc = new_node;
+ vui[n].pos_dst = src_l + dst_l;
+ vui[n].pos = ii + src_l + dst_l;
+ n++;
+ }
+ }
- /* Reconnect the nodes in sorted order. */
- for (ii = 1; ii < n; ii++)
- vui[ii - 1].lc->next = vui[ii].lc;
- vui[n - 1].lc->next = NULL;
+ if (dst_l == 2)
+ {
+ /* Special case still very common case. For dst_l == 2
+ all entries dst_l ... n-1 are sorted, with for i >= dst_l
+ vui[i].pos == i + src_l + dst_l. */
+ if (vui[0].pos > vui[1].pos)
+ {
+ /* Order should be 1, 0, 2... */
+ dst->var_part[k].loc_chain = vui[1].lc;
+ vui[1].lc->next = vui[0].lc;
+ if (n >= 3)
+ {
+ vui[0].lc->next = vui[2].lc;
+ vui[n - 1].lc->next = NULL;
+ }
+ else
+ vui[0].lc->next = NULL;
+ ii = 3;
+ }
+ else
+ {
+ dst->var_part[k].loc_chain = vui[0].lc;
+ if (n >= 3 && vui[2].pos < vui[1].pos)
+ {
+ /* Order should be 0, 2, 1, 3... */
+ vui[0].lc->next = vui[2].lc;
+ vui[2].lc->next = vui[1].lc;
+ if (n >= 4)
+ {
+ vui[1].lc->next = vui[3].lc;
+ vui[n - 1].lc->next = NULL;
+ }
+ else
+ vui[1].lc->next = NULL;
+ ii = 4;
+ }
+ else
+ {
+ /* Order should be 0, 1, 2... */
+ ii = 1;
+ vui[n - 1].lc->next = NULL;
+ }
+ }
+ for (; ii < n; ii++)
+ vui[ii - 1].lc->next = vui[ii].lc;
+ }
+ else
+ {
+ qsort (vui, n, sizeof (struct variable_union_info),
+ variable_union_info_cmp_pos);
- dst->var_part[k].loc_chain = vui[0].lc;
- dst->var_part[k].offset = dst->var_part[j].offset;
+ /* Reconnect the nodes in sorted order. */
+ for (ii = 1; ii < n; ii++)
+ vui[ii - 1].lc->next = vui[ii].lc;
+ vui[n - 1].lc->next = NULL;
+ dst->var_part[k].loc_chain = vui[0].lc;
+ }
- free (vui);
+ dst->var_part[k].offset = dst->var_part[j].offset;
+ }
i--;
j--;
}
@@ -1477,17 +1553,18 @@ variable_union (void **slot, void *data)
dst->var_part[k].cur_loc = NULL;
}
- for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
- {
- location_chain node, node2;
- for (node = src->var_part[i].loc_chain; node; node = node->next)
- for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
- if (rtx_equal_p (node->loc, node2->loc))
- {
- if (node->init > node2->init)
- node2->init = node->init;
- }
- }
+ if (flag_var_tracking_uninit)
+ for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
+ {
+ location_chain node, node2;
+ for (node = src->var_part[i].loc_chain; node; node = node->next)
+ for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
+ if (rtx_equal_p (node->loc, node2->loc))
+ {
+ if (node->init > node2->init)
+ node2->init = node->init;
+ }
+ }
/* Continue traversing the hash table. */
return 1;
@@ -1522,14 +1599,7 @@ variable_canonicalize (void **slot, void
}
}
if (k < src->n_var_parts)
- {
- enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
-
- if (! flag_var_tracking_uninit)
- status = VAR_INIT_STATUS_INITIALIZED;
-
- unshare_variable (set, src, status);
- }
+ unshare_variable (set, src, VAR_INIT_STATUS_UNKNOWN);
return 1;
}
@@ -1650,34 +1720,6 @@ dataflow_set_different_1 (void **slot, v
return 1;
}
-/* Compare variable *SLOT with the same variable in hash table DATA
- and set DATAFLOW_SET_DIFFERENT_VALUE if they are different. */
-
-static int
-dataflow_set_different_2 (void **slot, void *data)
-{
- htab_t htab = (htab_t) data;
- variable var1, var2;
-
- var1 = *(variable *) slot;
- var2 = (variable) htab_find_with_hash (htab, var1->decl,
- VARIABLE_HASH_VAL (var1->decl));
- if (!var2)
- {
- dataflow_set_different_value = true;
-
- /* Stop traversing the hash table. */
- return 0;
- }
-
- /* If both variables are defined they have been already checked for
- equivalence. */
- gcc_assert (!variable_different_p (var1, var2, false));
-
- /* Continue traversing the hash table. */
- return 1;
-}
-
/* Return true if dataflow sets OLD_SET and NEW_SET differ. */
static bool
@@ -1694,14 +1736,9 @@ dataflow_set_different (dataflow_set *ol
htab_traverse (shared_hash_htab (old_set->vars), dataflow_set_different_1,
shared_hash_htab (new_set->vars));
- if (!dataflow_set_different_value)
- {
- /* We have compared the variables which are in both hash tables
- so now only check whether there are some variables in NEW_SET->VARS
- which are not in OLD_SET->VARS. */
- htab_traverse (shared_hash_htab (new_set->vars), dataflow_set_different_2,
- shared_hash_htab (old_set->vars));
- }
+ /* No need to traverse the second hashtab, if both have the same number
+ of elements and the second one had all entries found in the first one,
+ then it can't have any extra entries. */
return dataflow_set_different_value;
}
@@ -2215,15 +2252,11 @@ compute_bb_dataflow (basic_block bb)
case MO_USE:
{
rtx loc = VTI (bb)->mos[i].u.loc;
- enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
-
- if (! flag_var_tracking_uninit)
- status = VAR_INIT_STATUS_INITIALIZED;
if (GET_CODE (loc) == REG)
- var_reg_set (out, loc, status, NULL);
+ var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
else if (GET_CODE (loc) == MEM)
- var_mem_set (out, loc, status, NULL);
+ var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
}
break;
@@ -2262,10 +2295,12 @@ compute_bb_dataflow (basic_block bb)
if (! flag_var_tracking_uninit)
src_status = VAR_INIT_STATUS_INITIALIZED;
else
- src_status = find_src_status (in, set_src);
+ {
+ src_status = find_src_status (in, set_src);
- if (src_status == VAR_INIT_STATUS_UNKNOWN)
- src_status = find_src_status (out, set_src);
+ if (src_status == VAR_INIT_STATUS_UNKNOWN)
+ src_status = find_src_status (out, set_src);
+ }
set_src = find_src_set_src (in, set_src);
@@ -2609,6 +2644,9 @@ set_variable_part (dataflow_set *set, rt
variable var;
void **slot = shared_hash_find_slot (set->vars, decl);
+ if (! flag_var_tracking_uninit)
+ initialized = VAR_INIT_STATUS_INITIALIZED;
+
if (!slot || !*slot)
{
if (!slot)
@@ -2815,10 +2853,8 @@ delete_variable_part (dataflow_set *set,
&& REGNO (node->loc) == REGNO (loc))
|| rtx_equal_p (node->loc, loc))
{
- enum var_init_status status = VAR_INIT_STATUS_UNKNOWN;
- if (! flag_var_tracking_uninit)
- status = VAR_INIT_STATUS_INITIALIZED;
- var = unshare_variable (set, var, status);
+ var = unshare_variable (set, var,
+ VAR_INIT_STATUS_UNKNOWN);
break;
}
}
@@ -2893,9 +2929,6 @@ emit_note_insn_var_location (void **varp
gcc_assert (var->decl);
- if (! flag_var_tracking_uninit)
- initialized = VAR_INIT_STATUS_INITIALIZED;
-
complete = true;
last_limit = 0;
n_var_parts = 0;
@@ -3148,14 +3181,11 @@ emit_notes_in_bb (basic_block bb)
case MO_USE:
{
rtx loc = VTI (bb)->mos[i].u.loc;
-
- enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
- if (! flag_var_tracking_uninit)
- status = VAR_INIT_STATUS_INITIALIZED;
+
if (GET_CODE (loc) == REG)
- var_reg_set (&set, loc, status, NULL);
+ var_reg_set (&set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
else
- var_mem_set (&set, loc, status, NULL);
+ var_mem_set (&set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
}
@@ -3553,6 +3583,10 @@ vt_finalize (void)
free_alloc_pool (var_pool);
free_alloc_pool (loc_chain_pool);
free_alloc_pool (shared_hash_pool);
+ if (vui_vec)
+ free (vui_vec);
+ vui_vec = NULL;
+ vui_allocated = 0;
}
/* The entry point to variable tracking pass. */

View File

@ -0,0 +1,46 @@
2009-05-27 Tom Tromey <tromey@redhat.com>
* unwind-dw2.c (_Unwind_DebugHook): New function.
(uw_install_context): Call _Unwind_DebugHook.
--- gcc/unwind-dw2.c (revision 147933)
+++ gcc/unwind-dw2.c (revision 147934)
@@ -1473,18 +1473,31 @@ uw_init_context_1 (struct _Unwind_Contex
context->ra = __builtin_extract_return_addr (outer_ra);
}
+static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__));
+
+/* This function is called during unwinding. It is intended as a hook
+ for a debugger to intercept exceptions. CFA is the CFA of the
+ target frame. HANDLER is the PC to which control will be
+ transferred. */
+static void
+_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
+ void *handler __attribute__ ((__unused__)))
+{
+ asm ("");
+}
/* Install TARGET into CURRENT so that we can return to it. This is a
macro because __builtin_eh_return must be invoked in the context of
our caller. */
-#define uw_install_context(CURRENT, TARGET) \
- do \
- { \
- long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
- void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
- __builtin_eh_return (offset, handler); \
- } \
+#define uw_install_context(CURRENT, TARGET) \
+ do \
+ { \
+ long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
+ void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
+ _Unwind_DebugHook ((TARGET)->cfa, handler); \
+ __builtin_eh_return (offset, handler); \
+ } \
while (0)
static long

View File

@ -1,2 +1,2 @@
2659f09c2e43ef8b7d4406321753f1b2 fastjar-0.97.tar.gz
271340a1883a595c5c8b4fe1007389fa gcc-4.4.0-20090514.tar.bz2
697eccb5f5690c419cb576b31b95ba93 gcc-4.4.1-20090729.tar.bz2