summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail168
-rw-r--r--gcc/Makefile.in117
-rw-r--r--gcc/alloc-pool.c8
-rw-r--r--gcc/asan.c90
-rw-r--r--gcc/attribs.c83
-rw-r--r--gcc/bitmap.c64
-rw-r--r--gcc/config/arm/arm.c37
-rw-r--r--gcc/config/arm/t-arm4
-rw-r--r--gcc/config/i386/t-cygming2
-rw-r--r--gcc/config/i386/t-interix2
-rw-r--r--gcc/config/i386/winnt.c42
-rw-r--r--gcc/config/ia64/ia64.c71
-rw-r--r--gcc/config/ia64/t-ia643
-rw-r--r--gcc/config/mips/mips.c49
-rw-r--r--gcc/config/sol2.c53
-rw-r--r--gcc/config/t-sol22
-rw-r--r--gcc/config/vxworks.c37
-rw-r--r--gcc/coverage.c154
-rw-r--r--gcc/cselib.c178
-rw-r--r--gcc/data-streamer-out.c3
-rw-r--r--gcc/data-streamer.h38
-rw-r--r--gcc/doc/tm.texi10
-rw-r--r--gcc/doc/tm.texi.in10
-rw-r--r--gcc/dse.c192
-rw-r--r--gcc/dwarf2cfi.c57
-rw-r--r--gcc/dwarf2out.c448
-rw-r--r--gcc/except.c181
-rw-r--r--gcc/gcse.c74
-rw-r--r--gcc/ggc-common.c175
-rw-r--r--gcc/gimple-ssa-strength-reduction.c56
-rw-r--r--gcc/gimple.c111
-rw-r--r--gcc/gimple.h105
-rw-r--r--gcc/gimplify.c60
-rw-r--r--gcc/graphds.h1
-rw-r--r--gcc/graphite-clast-to-gimple.c186
-rw-r--r--gcc/graphite-clast-to-gimple.h19
-rw-r--r--gcc/graphite-dependences.c3
-rw-r--r--gcc/graphite-htab.h60
-rw-r--r--gcc/graphite-poly.h8
-rw-r--r--gcc/graphite.c7
-rw-r--r--gcc/haifa-sched.c162
-rw-r--r--gcc/hash-table.h207
-rw-r--r--gcc/ira-color.c35
-rw-r--r--gcc/ira-costs.c46
-rw-r--r--gcc/loop-invariant.c49
-rw-r--r--gcc/loop-iv.c57
-rw-r--r--gcc/loop-unroll.c145
-rw-r--r--gcc/lto-streamer-in.c22
-rw-r--r--gcc/lto-streamer-out.c5
-rw-r--r--gcc/lto-streamer.c36
-rw-r--r--gcc/lto-streamer.h47
-rw-r--r--gcc/passes.c41
-rw-r--r--gcc/plugin.c55
-rw-r--r--gcc/postreload-gcse.c142
-rw-r--r--gcc/sese.c105
-rw-r--r--gcc/sese.h21
-rw-r--r--gcc/statistics.c105
-rw-r--r--gcc/store-motion.c49
-rw-r--r--gcc/target.def8
-rw-r--r--gcc/targhooks.h2
-rw-r--r--gcc/trans-mem.c197
-rw-r--r--gcc/tree-browser.c70
-rw-r--r--gcc/tree-cfg.c63
-rw-r--r--gcc/tree-complex.c17
-rw-r--r--gcc/tree-eh.c35
-rw-r--r--gcc/tree-emutls.c62
-rw-r--r--gcc/tree-flow.h6
-rw-r--r--gcc/tree-hasher.h55
-rw-r--r--gcc/tree-into-ssa.c94
-rw-r--r--gcc/tree-mudflap.c23
-rw-r--r--gcc/tree-parloops.c264
-rw-r--r--gcc/tree-scalar-evolution.c96
-rw-r--r--gcc/tree-sra.c59
-rw-r--r--gcc/tree-ssa-coalesce.c130
-rw-r--r--gcc/tree-ssa-dom.c168
-rw-r--r--gcc/tree-ssa-live.c34
-rw-r--r--gcc/tree-ssa-loop-im.c62
-rw-r--r--gcc/tree-ssa-loop-ivopts.c65
-rw-r--r--gcc/tree-ssa-phiopt.c40
-rw-r--r--gcc/tree-ssa-reassoc.c30
-rw-r--r--gcc/tree-ssa-sccvn.c428
-rw-r--r--gcc/tree-ssa-sccvn.h5
-rw-r--r--gcc/tree-ssa-strlen.c60
-rw-r--r--gcc/tree-ssa-structalias.c95
-rw-r--r--gcc/tree-ssa-uncprop.c96
-rw-r--r--gcc/tree-ssa.c36
-rw-r--r--gcc/tree-vect-data-refs.c61
-rw-r--r--gcc/tree-vect-loop.c5
-rw-r--r--gcc/tree-vectorizer.h26
-rw-r--r--gcc/tree.c91
-rw-r--r--gcc/tree.h24
-rw-r--r--gcc/var-tracking.c844
92 files changed, 4131 insertions, 3517 deletions
diff --git a/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
index 44460616914..2671071127e 100644
--- a/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
+++ b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
@@ -1,135 +1,123 @@
-FAIL: g++.dg/other/anon5.C -std=gnu++98 (test for excess errors)
-FAIL: g++.dg/other/anon5.C -std=gnu++11 (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -Os (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-loops (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto -flto-partition=none (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto -flto-partition=none (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -g (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O1 (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -g (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -Os (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O1 (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-loops (internal compiler error)
-UNRESOLVED: gcc.dg/attr-weakref-1.c compilation failed to produce executable
-FAIL: gcc.dg/attr-weakref-1.c (test for excess errors)
-FAIL: gcc.dg/autopar/pr49960.c scan-tree-dump-times optimized "loopfn" 0
-FAIL: gcc.dg/autopar/pr49960.c scan-tree-dump-times parloops "SUCCESS: may be parallelized" 0
-FAIL: gcc.dg/builtin-object-size-8.c execution test
-FAIL: gcc.dg/cproj-fails-with-broken-glibc.c execution test
+FAIL: gfortran.dg/class_optional_2.f90 -Os execution test
+XPASS: gcc.dg/guality/example.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/example.c -O2 execution test
-XPASS: gcc.dg/guality/example.c -O2 -flto execution test
XPASS: gcc.dg/guality/example.c -O0 execution test
-XPASS: gcc.dg/guality/example.c -O2 -flto -flto-partition=none execution test
-XPASS: gcc.dg/guality/guality.c -O2 -flto -flto-partition=none execution test
XPASS: gcc.dg/guality/guality.c -O3 -fomit-frame-pointer execution test
+XPASS: gcc.dg/guality/guality.c -O1 execution test
XPASS: gcc.dg/guality/guality.c -O0 execution test
+XPASS: gcc.dg/guality/guality.c -O2 execution test
XPASS: gcc.dg/guality/guality.c -O3 -g execution test
XPASS: gcc.dg/guality/guality.c -Os execution test
-XPASS: gcc.dg/guality/guality.c -O2 -flto execution test
-XPASS: gcc.dg/guality/guality.c -O2 execution test
-XPASS: gcc.dg/guality/guality.c -O1 execution test
+XPASS: gcc.dg/guality/guality.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/guality.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
XPASS: gcc.dg/guality/inline-params.c -O2 execution test
+XPASS: gcc.dg/guality/inline-params.c -O3 -g execution test
+XPASS: gcc.dg/guality/inline-params.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/inline-params.c -O3 -fomit-frame-pointer execution test
-XPASS: gcc.dg/guality/inline-params.c -O2 -flto execution test
XPASS: gcc.dg/guality/inline-params.c -Os execution test
-XPASS: gcc.dg/guality/inline-params.c -O3 -g execution test
-XPASS: gcc.dg/guality/inline-params.c -O2 -flto -flto-partition=none execution test
+XPASS: gcc.dg/guality/pr41353-1.c -O3 -fomit-frame-pointer line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -Os line 28 j == 28 + 37
XPASS: gcc.dg/guality/pr41353-1.c -O3 -g line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 28 j == 28 + 37
XPASS: gcc.dg/guality/pr41353-1.c -O1 line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto -flto-partition=none line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -O2 line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -Os line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -O3 -fomit-frame-pointer line 28 j == 28 + 37
XPASS: gcc.dg/guality/pr41353-1.c -O0 line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -O2 line 28 j == 28 + 37
XPASS: gcc.dg/guality/pr41447-1.c -O1 execution test
-XPASS: gcc.dg/guality/pr41447-1.c -Os execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O2 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O3 -fomit-frame-pointer execution test
XPASS: gcc.dg/guality/pr41447-1.c -O0 execution test
+XPASS: gcc.dg/guality/pr41447-1.c -Os execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O2 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O3 -g execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -flto-partition=none execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O0 execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O3 -fomit-frame-pointer execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O3 -g execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
XPASS: gcc.dg/guality/pr41616-1.c -O1 execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O3 -fomit-frame-pointer execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41616-1.c -Os execution test
XPASS: gcc.dg/guality/pr41616-1.c -O2 execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O3 -g execution test
+FAIL: gcc.dg/guality/pr43051-1.c -O3 -fomit-frame-pointer -funroll-loops line 39 c == &a[0]
+FAIL: gcc.dg/guality/pr43051-1.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions line 39 c == &a[0]
FAIL: gcc.dg/guality/pr54200.c -Os line 20 z == 3
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 23 y == 117
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 20 y == 25
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 23 z == 8
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 20 z == 6
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 23 z == 8
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 23 y == 117
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 20 z == 6
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 20 y == 25
-FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto -flto-partition=none line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto -flto-partition=none line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 23 y == 117
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 23 z == 8
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 20 z == 6
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 20 z == 6
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 20 y == 25
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 20 y == 25
+FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 20 z == 6
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 23 z == 8
+FAIL: gcc.dg/guality/pr54519-4.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 y == 25
FAIL: gcc.dg/guality/pr54519-5.c -Os line 17 y == 25
FAIL: gcc.dg/guality/pr54519-5.c -O3 -fomit-frame-pointer line 17 y == 25
FAIL: gcc.dg/guality/pr54519-5.c -O2 line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 17 y == 25
FAIL: gcc.dg/guality/pr54519-5.c -O3 -g line 17 y == 25
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O3 -g line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 y == 25
+FAIL: gcc.dg/guality/pr54693-2.c -Os line 21 y == 20 - 2 * i
+FAIL: gcc.dg/guality/pr54693-2.c -Os line 21 x == 10 - i
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 17 sizeof (a) == 6
FAIL: gcc.dg/guality/vla-1.c -O3 -fomit-frame-pointer line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -O1 line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -Os line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto -flto-partition=none line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O2 line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O3 -fomit-frame-pointer line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O0 line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto -flto-partition=none line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/vla-1.c -O3 -g line 24 sizeof (a) == 17 * sizeof (short)
FAIL: gcc.dg/guality/vla-1.c -O2 line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/vla-1.c -O0 line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/vla-1.c -O3 -fomit-frame-pointer line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O1 line 24 sizeof (a) == 17 * sizeof (short)
FAIL: gcc.dg/guality/vla-1.c -O1 line 17 sizeof (a) == 6
FAIL: gcc.dg/guality/vla-1.c -O3 -g line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -Os line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 24 sizeof (a) == 17 * sizeof (short)
FAIL: gcc.dg/guality/vla-1.c -O0 line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O2 line 17 sizeof (a) == 6
FAIL: gcc.dg/guality/vla-1.c -Os line 24 sizeof (a) == 17 * sizeof (short)
FAIL: gcc.dg/guality/vla-2.c -O3 -g line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O0 line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O0 line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O3 -fomit-frame-pointer line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -Os line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O1 line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto line 16 sizeof (a) == 5 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -O3 -g line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O0 line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 25 sizeof (a) == 6 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -O1 line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O1 line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O0 line 16 sizeof (a) == 5 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -O2 line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto -flto-partition=none line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto -flto-partition=none line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O3 -fomit-frame-pointer line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 25 sizeof (a) == 6 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -Os line 16 sizeof (a) == 5 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -O3 -fomit-frame-pointer line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -Os line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 16 sizeof (a) == 5 * sizeof (int)
XPASS: gcc.dg/inline_3.c (test for excess errors)
XPASS: gcc.dg/inline_4.c (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O1 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -g (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -Os (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O0 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -fomit-frame-pointer (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto -flto-partition=none (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 (test for excess errors)
XPASS: gcc.dg/unroll_2.c (test for excess errors)
XPASS: gcc.dg/unroll_3.c (test for excess errors)
XPASS: gcc.dg/unroll_4.c (test for excess errors)
-FAIL: libmudflap.c++/pass55-frag.cxx (-O2) execution test
-FAIL: libmudflap.c++/pass55-frag.cxx ( -O) execution test
-FAIL: libmudflap.c++/pass55-frag.cxx (-O3) execution test
+XPASS: gfortran.dg/do_1.f90 -O0 execution test
+XPASS: gfortran.dg/do_1.f90 -O1 execution test
+UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
+FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error)
+FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin (internal compiler error)
+FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin (internal compiler error)
+UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
+UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -flto-partition=none -fuse-linker-plugin
+FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin (internal compiler error)
+UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -flto-partition=none -fuse-linker-plugin
+FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error)
+FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin (internal compiler error)
+UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
+UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
+FAIL: libmudflap.c++/pass41-frag.cxx (-O3) execution test
+FAIL: libmudflap.c++/pass41-frag.cxx (-O2) execution test
+FAIL: libmudflap.c++/pass41-frag.cxx ( -O) execution test
FAIL: libmudflap.c/fail37-frag.c (-O3) output pattern test
FAIL: libmudflap.c/fail37-frag.c (-O2) output pattern test
FAIL: libmudflap.c/fail37-frag.c (-O3) crash test
FAIL: libmudflap.c/fail37-frag.c (-O2) crash test
+FAIL: sourcelocation -findirect-dispatch output - source compiled test
+FAIL: sourcelocation -O3 output - source compiled test
+FAIL: sourcelocation output - source compiled test
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 54ea04f644a..83f9a63ffe2 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -874,7 +874,7 @@ BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \
cfg-flags.def cfghooks.h
GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \
$(GGC_H) $(BASIC_BLOCK_H) $(TREE_H) tree-ssa-operands.h \
- tree-ssa-alias.h $(INTERNAL_FN_H)
+ tree-ssa-alias.h $(INTERNAL_FN_H) $(HASH_TABLE_H)
TRANS_MEM_H = trans-mem.h
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
COVERAGE_H = coverage.h $(GCOV_IO_H)
@@ -937,6 +937,7 @@ TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
$(BITMAP_H) sbitmap.h $(BASIC_BLOCK_H) $(GIMPLE_H) \
$(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) \
tree-ssa-alias.h
+TREE_HASHER_H = tree-hasher.h $(HASH_TABLE_H) $(TREE_FLOW_H)
TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H)
SSAEXPAND_H = ssaexpand.h $(TREE_SSA_LIVE_H)
PRETTY_PRINT_H = pretty-print.h $(INPUT_H) $(OBSTACK_H)
@@ -956,7 +957,7 @@ IRA_INT_H = ira.h ira-int.h $(CFGLOOP_H) alloc-pool.h
LRA_INT_H = lra.h $(BITMAP_H) $(RECOG_H) $(INSN_ATTR_H) insn-codes.h lra-int.h
DBGCNT_H = dbgcnt.h dbgcnt.def
LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \
- $(CGRAPH_H) $(VEC_H) $(TREE_H) $(GIMPLE_H) \
+ $(CGRAPH_H) $(VEC_H) $(HASH_TABLE_H) $(TREE_H) $(GIMPLE_H) \
$(GCOV_IO_H) $(DIAGNOSTIC_H) alloc-pool.h
DATA_STREAMER_H = data-streamer.h $(VEC_H) $(LTO_STREAMER_H)
GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \
@@ -964,7 +965,8 @@ GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \
TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) \
$(STREAMER_HOOKS_H)
STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H)
-TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_H)
+TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_H) \
+ $(HASH_TABLE_H)
IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H) alloc-pool.h
IPA_INLINE_H = ipa-inline.h $(IPA_PROP_H)
GSTAB_H = gstab.h stab.def
@@ -974,6 +976,7 @@ GCC_PLUGIN_H = gcc-plugin.h highlev-plugin-common.h plugin.def \
PLUGIN_H = plugin.h $(GCC_PLUGIN_H)
PLUGIN_VERSION_H = plugin-version.h configargs.h
LIBFUNCS_H = libfuncs.h $(HASHTAB_H)
+GRAPHITE_HTAB_H = graphite-htab.h graphite-clast-to-gimple.h $(HASH_TABLE_H)
#
# Now figure out from those variables how to compile and link.
@@ -2013,7 +2016,7 @@ default-c.o: config/default-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
# Files used by all variants of C and some other languages.
attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \
+ $(HASH_TABLE_H) $(FLAGS_H) $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \
$(TARGET_H) langhooks.h $(CPPLIB_H) $(PLUGIN_H)
incpath.o: incpath.c incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
@@ -2105,7 +2108,7 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(CFGLOOP_H) $(TARGET_H) $(IPA_PROP_H) $(LTO_STREAMER_H) \
target-globals.h
-trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \
$(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_INLINE_H) \
$(DIAGNOSTIC_CORE_H) $(DEMANGLE_H) output.h $(TRANS_MEM_H) \
$(PARAMS_H) $(TARGET_H) langhooks.h \
@@ -2113,7 +2116,7 @@ trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
gt-trans-mem.h
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(GGC_H) $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \
+ $(GGC_H) $(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \
$(HOSTHOOKS_DEF_H) $(VEC_H) $(PLUGIN_H) $(GGC_INTERNAL_H) $(TIMEVAR_H)
ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
@@ -2244,8 +2247,8 @@ tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
$(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 \
- $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
+tree-ssa-structalias.o: tree-ssa-structalias.c $(SYSTEM_H) $(CONFIG_H) \
+ coretypes.h $(HASH_TABLE_H) $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
$(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \
$(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
@@ -2258,7 +2261,7 @@ tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(FLAGS_H) $(HASHTAB_H) pointer-set.h \
$(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \
+ $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \
toplev.h $(FUNCTION_H) $(TM_H) coretypes.h \
langhooks.h $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
$(FLAGS_H) $(GGC_H) $(HASHTAB_H) pointer-set.h \
@@ -2268,7 +2271,7 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(DIAGNOSTIC_CORE_H) \
$(FUNCTION_H) $(TM_H) coretypes.h \
langhooks.h domwalk.h $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) \
- $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASHTAB_H) \
+ $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASH_TABLE_H) \
$(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h dumpfile.h \
@@ -2300,7 +2303,7 @@ tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \
$(TREE_PRETTY_PRINT_H)
tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+ $(HASH_TABLE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) langhooks.h $(FLAGS_H) \
$(DIAGNOSTIC_H) pointer-set.h domwalk.h $(CFGLOOP_H) \
$(TREE_DATA_REF_H) $(TREE_PRETTY_PRINT_H) $(GIMPLE_PRETTY_PRINT_H) \
@@ -2321,13 +2324,13 @@ tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-ssa-propagate.h $(VEC_H) value-prof.h gt-tree-ssa-propagate.h $(FLAGS_H) \
$(GIMPLE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \
+ $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_H) \
$(FUNCTION_H) $(TM_H) coretypes.h \
$(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) langhooks.h \
tree-ssa-propagate.h $(CFGLOOP_H) $(PARAMS_H) \
$(GIMPLE_PRETTY_PRINT_H)
tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(TM_P_H) \
+ $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h \
$(BASIC_BLOCK_H) domwalk.h $(TREE_PASS_H) $(FLAGS_H) \
tree-ssa-propagate.h
@@ -2350,7 +2353,7 @@ domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(BASIC_BLOCK_H) domwalk.h sbitmap.h
tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h dumpfile.h $(TIMEVAR_H) \
- $(TREE_SSA_LIVE_H) $(BITMAP_H) debug.h $(FLAGS_H) \
+ $(TREE_SSA_LIVE_H) $(BITMAP_H) debug.h $(FLAGS_H) $(HASH_TABLE_H) \
$(GIMPLE_PRETTY_PRINT_H) $(GIMPLE_H)
tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) \
@@ -2366,12 +2369,12 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \
$(TM_H) coretypes.h dumpfile.h $(FLAGS_H) $(CFGLOOP_H) \
- alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) $(GIMPLE_H) \
+ alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASH_TABLE_H) $(GIMPLE_H) \
$(TREE_INLINE_H) tree-ssa-propagate.h tree-ssa-sccvn.h \
$(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h
gimple-ssa-strength-reduction.o : gimple-ssa-strength-reduction.c $(CONFIG_H) \
$(SYSTEM_H) coretypes.h $(TREE_H) $(GIMPLE_H) $(BASIC_BLOCK_H) \
- $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_PRETTY_PRINT_H) \
+ $(HASH_TABLE_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_PRETTY_PRINT_H) \
$(GIMPLE_PRETTY_PRINT_H) alloc-pool.h $(TREE_FLOW_H) domwalk.h \
pointer-set.h expmed.h
tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
@@ -2379,7 +2382,7 @@ tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \
$(CFGLOOP_H) $(SCEV_H) intl.h \
$(GIMPLE_PRETTY_PRINT_H) gimple-fold.h $(OPTABS_H) $(EXPR_H)
-tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) $(HASH_TABLE_H) \
$(TREE_H) $(TM_P_H) $(GGC_H) $(FLAGS_H) $(TARGET_H) \
$(DIAGNOSTIC_CORE_H) $(FUNCTION_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(EXCEPT_H) $(CFGLOOP_H) $(TREE_PASS_H) \
@@ -2424,7 +2427,7 @@ tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
coretypes.h dumpfile.h langhooks.h $(IPA_REFERENCE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) langhooks.h \
- $(GGC_H) $(TREE_PASS_H) coretypes.h pointer-set.h \
+ $(HASH_TABLE_H) $(GGC_H) $(TREE_PASS_H) coretypes.h pointer-set.h \
$(TREE_INLINE_H) tree-iterator.h toplev.h \
$(DIAGNOSTIC_CORE_H) $(TARGET_H) $(CFGLOOP_H)
tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -2470,7 +2473,7 @@ tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \
tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \
$(DIAGNOSTIC_H) $(TM_H) coretypes.h \
- $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
+ $(TREE_PASS_H) $(GGC_H) $(RECOG_H) insn-config.h $(HASH_TABLE_H) $(SCEV_H) \
$(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) \
tree-affine.h pointer-set.h $(TARGET_H) \
$(GIMPLE_PRETTY_PRINT_H) tree-ssa-propagate.h
@@ -2484,7 +2487,7 @@ tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \
$(CFGLOOP_H) $(TREE_PASS_H) \
$(SCEV_H) $(PARAMS_H) $(TREE_INLINE_H) langhooks.h
tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \
+ $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \
$(PARAMS_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h \
$(TREE_PASS_H) $(FLAGS_H) $(BASIC_BLOCK_H) \
pointer-set.h tree-affine.h tree-ssa-propagate.h $(GIMPLE_PRETTY_PRINT_H)
@@ -2501,7 +2504,7 @@ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
pointer-set.h alloc-pool.h \
$(TREE_PRETTY_PRINT_H)
tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \
+ $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(DIAGNOSTIC_H) \
$(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) \
tree-iterator.h $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_INLINE_H) \
$(VEC_H) langhooks.h alloc-pool.h pointer-set.h $(CFGLOOP_H) \
@@ -2537,14 +2540,15 @@ omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \
$(CFGLOOP_H) tree-iterator.h gt-omp-low.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TREE_H) $(TREE_PRETTY_PRINT_H)
+ coretypes.h $(HASH_TABLE_H) $(TREE_H) $(TREE_PRETTY_PRINT_H)
omega.o : omega.c $(OMEGA_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(TREE_H) $(DIAGNOSTIC_CORE_H)
tree-chrec.o : tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(TREE_PRETTY_PRINT_H) $(CFGLOOP_H) $(TREE_FLOW_H) $(SCEV_H) \
$(PARAMS_H)
tree-scalar-evolution.o : tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h dumpfile.h $(GIMPLE_PRETTY_PRINT_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(SCEV_H) \
+ coretypes.h dumpfile.h $(HASH_TABLE_H) $(GIMPLE_PRETTY_PRINT_H) \
+ $(TREE_FLOW_H) $(CFGLOOP_H) $(SCEV_H) \
$(PARAMS_H) gt-tree-scalar-evolution.h
tree-data-ref.o : tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(GIMPLE_PRETTY_PRINT_H) $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
@@ -2553,18 +2557,18 @@ sese.o : sese.c sese.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_PRETTY_PRINT_H
$(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) value-prof.h
graphite.o : graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) \
$(TREE_FLOW_H) $(TREE_DUMP_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \
- $(DBGCNT_H) graphite-poly.h graphite-scop-detection.h \
+ $(DBGCNT_H) $(GRAPHITE_HTAB_H) graphite-poly.h graphite-scop-detection.h \
graphite-clast-to-gimple.h graphite-sese-to-poly.h
graphite-blocking.o : graphite-blocking.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h dumpfile.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
sese.h graphite-poly.h
graphite-clast-to-gimple.o : graphite-clast-to-gimple.c $(CONFIG_H) \
$(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
- $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h \
+ $(CFGLOOP_H) $(TREE_DATA_REF_H) sese.h $(GRAPHITE_HTAB_H) \
graphite-poly.h graphite-clast-to-gimple.h
graphite-dependences.o : graphite-dependences.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_FLOW_H) $(TREE_PASS_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
- sese.h graphite-poly.h
+ sese.h $(GRAPHITE_HTAB_H) graphite-poly.h
graphite-interchange.o : graphite-interchange.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h dumpfile.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
sese.h graphite-poly.h
@@ -2618,7 +2622,8 @@ tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H)
tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(GIMPLE_PRETTY_PRINT_H) \
+ $(TREE_FLOW_H) $(TREE_HASHER_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \
+ $(GIMPLE_PRETTY_PRINT_H) $(HASH_TABLE_H) \
$(TREE_PASS_H) langhooks.h gt-tree-parloops.h $(TREE_VECTORIZER_H)
tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FUNCTION_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
@@ -2637,8 +2642,9 @@ gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) $(TREE_FLOW_H) \
$(TM_H) $(GIMPLE_H) value-prof.h \
$(TRANS_MEM_H) $(GIMPLE_PRETTY_PRINT_H)
-tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
- $(GIMPLE_H) $(DIAGNOSTIC_H) $(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
+tree-mudflap.o : tree-mudflap.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
+ $(TREE_INLINE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) \
+ $(DEMANGLE_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
$(TM_H) coretypes.h $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \
gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \
$(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h
@@ -2717,7 +2723,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(PLUGIN_H) $(IPA_UTILS_H)
plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
+ $(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) \
+ intl.h $(PLUGIN_VERSION_H) $(GGC_H)
main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H)
@@ -2754,7 +2761,7 @@ function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_
$(TREE_PASS_H) $(DF_H) $(PARAMS_H) bb-reorder.h \
$(COMMON_TARGET_H)
statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TREE_PASS_H) $(TREE_DUMP_H) $(HASHTAB_H) statistics.h $(FUNCTION_H)
+ $(TREE_PASS_H) $(TREE_DUMP_H) $(HASH_TABLE_H) statistics.h $(FUNCTION_H)
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \
$(LIBFUNCS_H) $(EXCEPT_H) $(RECOG_H) $(DIAGNOSTIC_CORE_H) \
@@ -2764,7 +2771,8 @@ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) $(RTL_H)
except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) $(LIBFUNCS_H) \
langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
- dwarf2asm.h $(DWARF2OUT_H) toplev.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) intl.h $(GGC_H) \
+ dwarf2asm.h $(DWARF2OUT_H) toplev.h $(DIAGNOSTIC_CORE_H) $(HASH_TABLE_H) \
+ intl.h $(GGC_H) \
gt-except.h $(CGRAPH_H) $(DIAGNOSTIC_H) $(DWARF2_H) \
$(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
$(TREE_PRETTY_PRINT_H) sbitmap.h $(COMMON_TARGET_H) $(CFGLOOP_H)
@@ -2818,12 +2826,12 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(TM_H) $(TREE_H) version.h $(RTL_H) $(DWARF2_H) debug.h $(FLAGS_H) \
insn-config.h output.h $(DIAGNOSTIC_H) hard-reg-set.h $(REGS_H) $(EXPR_H) \
toplev.h $(DIAGNOSTIC_CORE_H) $(DWARF2OUT_H) reload.h \
- $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \
+ $(GGC_H) $(EXCEPT_H) dwarf2asm.h $(TM_P_H) langhooks.h $(HASH_TABLE_H) \
gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) $(MD5_H) $(INPUT_H) $(FUNCTION_H) \
$(GIMPLE_H) ira.h lra.h $(TREE_FLOW_H) \
$(TREE_PRETTY_PRINT_H) $(COMMON_TARGET_H) $(OPTS_H)
-dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \
+dwarf2cfi.o : dwarf2cfi.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(HASH_TABLE_H) \
+ $(TM_H) version.h $(RTL_H) $(EXPR_H) $(REGS_H) $(FUNCTION_H) output.h \
gt-dwarf2cfi.h debug.h $(DWARF2_H) dwarf2asm.h $(DWARF2OUT_H) $(COMMON_TARGET_H) \
$(GGC_H) $(TM_P_H) $(TARGET_H) $(TREE_PASS_H) $(BASIC_BLOCK_H) $(EXCEPT_H)
dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -2949,7 +2957,8 @@ coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfil
$(FUNCTION_H) $(BASIC_BLOCK_H) toplev.h $(DIAGNOSTIC_CORE_H) $(GGC_H) langhooks.h $(COVERAGE_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) \
+cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
+ $(HASH_TABLE_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) \
cselib.h gt-cselib.h $(GGC_H) $(TM_P_H) $(PARAMS_H) alloc-pool.h \
@@ -2989,12 +2998,13 @@ cprop.o : cprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \
$(DF_H) $(CFGLOOP_H)
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
+ $(HASH_TABLE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) toplev.h $(DIAGNOSTIC_CORE_H) \
$(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) gt-gcse.h $(TREE_H) \
intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \
$(DF_H) gcse.h
-store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(HASH_TABLE_H) $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) toplev.h $(DIAGNOSTIC_CORE_H) \
$(TM_P_H) $(EXCEPT_H) $(TREE_H) \
@@ -3026,9 +3036,9 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_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 \
- $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) $(EXPR_H)
+ $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H) $(EXPR_H) $(HASH_TABLE_H)
tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
- $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \
+ $(HASH_TABLE_H) $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \
$(IPA_PROP_H) $(DIAGNOSTIC_H) statistics.h \
$(PARAMS_H) $(TARGET_H) $(FLAGS_H) \
$(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
@@ -3039,7 +3049,7 @@ tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H) \
$(GIMPLE_PRETTY_PRINT_H) langhooks.h
tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
- $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) \
+ $(TM_H) $(FLAGS_H) $(TREE_FLOW_H) $(TREE_HASHER_H) $(GIMPLE_H) \
tree-iterator.h $(TREE_PASS_H) tree-ssa-propagate.h
tree-emutls.o : tree-emutls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
$(GIMPLE_H) $(TREE_PASS_H) $(TREE_FLOW_H) $(CGRAPH_H) langhooks.h \
@@ -3069,7 +3079,7 @@ valtrack.o : valtrack.c $(VALTRACK_H) $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(FUNCTION_H) $(REGS_H) $(EMIT_RTL_H)
var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \
- $(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
+ $(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASH_TABLE_H) \
$(REGS_H) $(EXPR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) \
pointer-set.h $(RECOG_H) $(TM_P_H) $(TREE_PRETTY_PRINT_H) $(ALIAS_H)
@@ -3092,7 +3102,7 @@ value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_
loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) \
$(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
$(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) $(PARAMS_H) $(TARGET_H)
-alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
+alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASH_TABLE_H)
auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \
$(REGS_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) \
@@ -3137,11 +3147,11 @@ graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) $(BITMAP_H) $(OBSTACK_H)
loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(RTL_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(TM_H) $(OBSTACK_H) \
- intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASHTAB_H)
+ intl.h $(DIAGNOSTIC_CORE_H) $(DF_H) $(HASH_TABLE_H)
loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(RTL_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) \
$(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) $(TARGET_H) \
- $(OBSTACK_H) $(HASHTAB_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h
+ $(OBSTACK_H) $(HASH_TABLE_H) $(EXCEPT_H) $(PARAMS_H) $(REGS_H) ira.h
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) \
coretypes.h $(TM_H) $(OBSTACK_H) $(TREE_FLOW_H)
@@ -3154,8 +3164,7 @@ loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h
$(EXPR_H) $(TM_H) $(OBSTACK_H)
loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(RTL_H) $(TM_H) $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(PARAMS_H) \
- $(EXPR_H) $(TM_H) $(HASHTAB_H) $(RECOG_H) \
- $(OBSTACK_H)
+ $(EXPR_H) $(TM_H) $(HASH_TABLE_H) $(RECOG_H) $(OBSTACK_H)
dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) \
$(TIMEVAR_H) graphds.h pointer-set.h $(BITMAP_H)
@@ -3174,7 +3183,7 @@ reginfo.o : reginfo.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FUNCTION_H) output.h $(TM_P_H) $(EXPR_H) $(HASHTAB_H) \
$(TARGET_H) $(TREE_PASS_H) $(DF_H) ira.h
bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(VEC_H) \
- $(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASHTAB_H)
+ $(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASH_TABLE_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 \
@@ -3199,8 +3208,8 @@ postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) $(DIAGNOSTIC_CORE_H) \
- $(TM_P_H) $(EXCEPT_H) $(TREE_H) $(TARGET_H) $(HASHTAB_H) intl.h $(OBSTACK_H) \
- $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H)
+ $(TM_P_H) $(EXCEPT_H) $(TREE_H) $(TARGET_H) $(HASH_TABLE_H) intl.h \
+ $(OBSTACK_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H)
caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(TM_H) $(RTL_H) \
$(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
@@ -3233,14 +3242,14 @@ ira-build.o: ira-build.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(PARAMS_H) $(DF_H) sparseset.h $(IRA_INT_H) reload.h
ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
hard-reg-set.h $(RTL_H) $(EXPR_H) $(TM_P_H) $(FLAGS_H) $(BASIC_BLOCK_H) \
- $(REGS_H) addresses.h insn-config.h $(RECOG_H) $(DIAGNOSTIC_CORE_H) $(TARGET_H) \
- $(PARAMS_H) $(IRA_INT_H) reload.h
+ $(REGS_H) addresses.h insn-config.h $(RECOG_H) $(DIAGNOSTIC_CORE_H) \
+ $(HASH_TABLE_H) $(TARGET_H) $(PARAMS_H) $(IRA_INT_H) reload.h
ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(TREE_H) $(FLAGS_H) \
insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(PARAMS_H) \
$(DF_H) sparseset.h addresses.h $(IRA_INT_H)
ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
+ $(HASH_TABLE_H) $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
$(EXPR_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) reload.h $(PARAMS_H) \
$(DF_H) $(IRA_INT_H)
ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -3320,7 +3329,7 @@ haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h \
$(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
$(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) \
$(PARAMS_H) $(DBGCNT_H) $(CFGLOOP_H) ira.h $(EMIT_RTL_H) $(COMMON_TARGET_H) \
- $(HASHTAB_H)
+ $(HASH_TABLE_H)
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) cselib.h \
diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c
index 1989d86aadc..65907544565 100644
--- a/gcc/alloc-pool.c
+++ b/gcc/alloc-pool.c
@@ -82,6 +82,7 @@ struct alloc_pool_descriptor
int elt_size;
};
+/* Hashtable helpers. */
struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor>
{
typedef alloc_pool_descriptor value_type;
@@ -90,10 +91,6 @@ struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor>
static inline bool equal (const value_type *, const compare_type *);
};
-/* Hashtable mapping alloc_pool names to descriptors. */
-static hash_table <alloc_pool_hasher> alloc_pool_hash;
-
-/* Hashtable helpers. */
inline hashval_t
alloc_pool_hasher::hash (const value_type *d)
{
@@ -107,6 +104,9 @@ alloc_pool_hasher::equal (const value_type *d,
return d->name == p2;
}
+/* Hashtable mapping alloc_pool names to descriptors. */
+static hash_table <alloc_pool_hasher> alloc_pool_hash;
+
/* For given name, return descriptor, create new if needed. */
static struct alloc_pool_descriptor *
allocate_pool_descriptor (const char *name)
diff --git a/gcc/asan.c b/gcc/asan.c
index 52a2dbc5dfd..571882a6962 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1379,57 +1379,15 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
/* Slow path for 1, 2 and 4 byte accesses.
Test (shadow != 0)
& ((base_addr & 7) + (size_in_bytes - 1)) >= shadow). */
- g = gimple_build_assign_with_ops (NE_EXPR,
- make_ssa_name (boolean_type_node,
- NULL),
- shadow,
- build_int_cst (shadow_type, 0));
- gimple_set_location (g, location);
- gsi_insert_after (&gsi, g, GSI_NEW_STMT);
- t = gimple_assign_lhs (g);
-
- g = gimple_build_assign_with_ops (BIT_AND_EXPR,
- make_ssa_name (uintptr_type,
- NULL),
- base_addr,
- build_int_cst (uintptr_type, 7));
- gimple_set_location (g, location);
- gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
- g = gimple_build_assign_with_ops (NOP_EXPR,
- make_ssa_name (shadow_type,
- NULL),
- gimple_assign_lhs (g), NULL_TREE);
- gimple_set_location (g, location);
- gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
+ gimple_builder_ssa gb(location);
+ t = gb.add (NE_EXPR, shadow, 0);
+ tree t1 = gb.add (BIT_AND_EXPR, base_addr, 7);
+ t1 = gb.add_type_cast (shadow_type, t1);
if (size_in_bytes > 1)
- {
- g = gimple_build_assign_with_ops (PLUS_EXPR,
- make_ssa_name (shadow_type,
- NULL),
- gimple_assign_lhs (g),
- build_int_cst (shadow_type,
- size_in_bytes - 1));
- gimple_set_location (g, location);
- gsi_insert_after (&gsi, g, GSI_NEW_STMT);
- }
-
- g = gimple_build_assign_with_ops (GE_EXPR,
- make_ssa_name (boolean_type_node,
- NULL),
- gimple_assign_lhs (g),
- shadow);
- gimple_set_location (g, location);
- gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
- g = gimple_build_assign_with_ops (BIT_AND_EXPR,
- make_ssa_name (boolean_type_node,
- NULL),
- t, gimple_assign_lhs (g));
- gimple_set_location (g, location);
- gsi_insert_after (&gsi, g, GSI_NEW_STMT);
- t = gimple_assign_lhs (g);
+ t1 = gb.add (PLUS_EXPR, t1, size_in_bytes - 1);
+ t1 = gb.add (GE_EXPR, t1, shadow);
+ t = gb.add (BIT_AND_EXPR, t, t1);
+ gb.insert_after (&gsi, GSI_NEW_STMT);
}
else
t = shadow;
@@ -1968,28 +1926,16 @@ transform_statements (void)
static tree
asan_global_struct (void)
{
- static const char *field_names[5]
- = { "__beg", "__size", "__size_with_redzone",
- "__name", "__has_dynamic_init" };
- tree fields[5], ret;
- int i;
-
- ret = make_node (RECORD_TYPE);
- for (i = 0; i < 5; i++)
- {
- fields[i]
- = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
- get_identifier (field_names[i]),
- (i == 0 || i == 3) ? const_ptr_type_node
- : build_nonstandard_integer_type (POINTER_SIZE, 1));
- DECL_CONTEXT (fields[i]) = ret;
- if (i)
- DECL_CHAIN (fields[i - 1]) = fields[i];
- }
- TYPE_FIELDS (ret) = fields[0];
- TYPE_NAME (ret) = get_identifier ("__asan_global");
- layout_type (ret);
- return ret;
+ tree ptrint_type = build_nonstandard_integer_type (POINTER_SIZE, 1);
+ record_builder rec;
+ rec.add_field ("__beg", const_ptr_type_node);
+ rec.add_field ("__size", ptrint_type);
+ rec.add_field ("__size_with_redzone", ptrint_type);
+ rec.add_field ("__name", const_ptr_type_node);
+ rec.add_field ("__has_dynamic_init", ptrint_type);
+ rec.layout ();
+ rec.tag_name ("__asan_global");
+ return rec.as_tree ();
}
/* Append description of a single global DECL into vector V.
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 08ebfe10a8f..164385b2b3c 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "cpplib.h"
#include "target.h"
#include "langhooks.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "plugin.h"
/* Table of the tables of attributes (common, language, format, machine)
@@ -44,13 +44,45 @@ struct substring
int length;
};
+/* Simple hash function to avoid need to scan whole string. */
+
+static inline hashval_t
+substring_hash (const char *str, int l)
+{
+ return str[0] + str[l - 1] * 256 + l * 65536;
+}
+
+/* Used for attribute_hash. */
+
+struct attribute_hasher : typed_noop_remove <attribute_spec>
+{
+ typedef attribute_spec value_type;
+ typedef substring compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+attribute_hasher::hash (const value_type *spec)
+{
+ const int l = strlen (spec->name);
+ return substring_hash (spec->name, l);
+}
+
+inline bool
+attribute_hasher::equal (const value_type *spec, const compare_type *str)
+{
+ return (strncmp (spec->name, str->str, str->length) == 0
+ && !spec->name[str->length]);
+}
+
/* Scoped attribute name representation. */
struct scoped_attributes
{
const char *ns;
vec<attribute_spec> attributes;
- htab_t attribute_hash;
+ hash_table <attribute_hasher> attribute_hash;
};
/* The table of scope attributes. */
@@ -83,36 +115,6 @@ extract_attribute_substring (struct substring *str)
}
}
-/* Simple hash function to avoid need to scan whole string. */
-
-static inline hashval_t
-substring_hash (const char *str, int l)
-{
- return str[0] + str[l - 1] * 256 + l * 65536;
-}
-
-/* Used for attribute_hash. */
-
-static hashval_t
-hash_attr (const void *p)
-{
- const struct attribute_spec *const spec = (const struct attribute_spec *) p;
- const int l = strlen (spec->name);
-
- return substring_hash (spec->name, l);
-}
-
-/* Used for attribute_hash. */
-
-static int
-eq_attr (const void *p, const void *q)
-{
- const struct attribute_spec *const spec = (const struct attribute_spec *) p;
- const struct substring *const str = (const struct substring *) q;
-
- return (!strncmp (spec->name, str->str, str->length) && !spec->name[str->length]);
-}
-
/* Insert an array of attributes ATTRIBUTES into a namespace. This
array must be NULL terminated. NS is the name of attribute
namespace. The function returns the namespace into which the
@@ -139,7 +141,7 @@ register_scoped_attributes (const struct attribute_spec * attributes,
sa.ns = ns;
sa.attributes.create (64);
result = attributes_table.safe_push (sa);
- result->attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
+ result->attribute_hash.create (200);
}
/* Really add the attributes to their namespace now. */
@@ -272,11 +274,11 @@ register_scoped_attribute (const struct attribute_spec *attr,
scoped_attributes *name_space)
{
struct substring str;
- void **slot;
+ attribute_spec **slot;
gcc_assert (attr != NULL && name_space != NULL);
- gcc_assert (name_space->attribute_hash != NULL);
+ gcc_assert (name_space->attribute_hash.is_created ());
str.str = attr->name;
str.length = strlen (str.str);
@@ -285,11 +287,11 @@ register_scoped_attribute (const struct attribute_spec *attr,
in the form '__text__'. */
gcc_assert (str.length > 0 && str.str[0] != '_');
- slot = htab_find_slot_with_hash (name_space->attribute_hash, &str,
- substring_hash (str.str, str.length),
- INSERT);
+ slot = name_space->attribute_hash
+ .find_slot_with_hash (&str, substring_hash (str.str, str.length),
+ INSERT);
gcc_assert (!*slot || attr->name[0] == '*');
- *slot = (void *) CONST_CAST (struct attribute_spec *, attr);
+ *slot = CONST_CAST (struct attribute_spec *, attr);
}
/* Return the spec for the scoped attribute with namespace NS and
@@ -311,8 +313,7 @@ lookup_scoped_attribute_spec (const_tree ns, const_tree name)
attr.str = IDENTIFIER_POINTER (name);
attr.length = IDENTIFIER_LENGTH (name);
extract_attribute_substring (&attr);
- return (const struct attribute_spec *)
- htab_find_with_hash (attrs->attribute_hash, &attr,
+ return attrs->attribute_hash.find_with_hash (&attr,
substring_hash (attr.str, attr.length));
}
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index b60280a212f..f638db09429 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "obstack.h"
#include "ggc.h"
#include "bitmap.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "vec.h"
/* Store information about each particular bitmap, per allocation site. */
@@ -50,48 +50,55 @@ static int next_bitmap_desc_id = 0;
/* Vector mapping descriptor ids to descriptors. */
static vec<bitmap_descriptor> bitmap_descriptors;
-/* Hashtable mapping bitmap names to descriptors. */
-static htab_t bitmap_desc_hash;
-
/* Hashtable helpers. */
-static hashval_t
-hash_descriptor (const void *p)
-{
- const_bitmap_descriptor d = (const_bitmap_descriptor) p;
- return htab_hash_pointer (d->file) + d->line;
-}
+
struct loc
{
const char *file;
const char *function;
int line;
};
-static int
-eq_descriptor (const void *p1, const void *p2)
+
+struct bitmap_desc_hasher : typed_noop_remove <bitmap_descriptor_d>
+{
+ typedef bitmap_descriptor_d value_type;
+ typedef loc compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+bitmap_desc_hasher::hash (const value_type *d)
+{
+ return htab_hash_pointer (d->file) + d->line;
+}
+
+inline bool
+bitmap_desc_hasher::equal (const value_type *d, const compare_type *l)
{
- const_bitmap_descriptor d = (const_bitmap_descriptor) p1;
- const struct loc *const l = (const struct loc *) p2;
return d->file == l->file && d->function == l->function && d->line == l->line;
}
+/* Hashtable mapping bitmap names to descriptors. */
+static hash_table <bitmap_desc_hasher> bitmap_desc_hash;
+
/* For given file and line, return descriptor, create new if needed. */
static bitmap_descriptor
get_bitmap_descriptor (const char *file, int line, const char *function)
{
- bitmap_descriptor *slot;
+ bitmap_descriptor_d **slot;
struct loc loc;
loc.file = file;
loc.function = function;
loc.line = line;
- if (!bitmap_desc_hash)
- bitmap_desc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+ if (!bitmap_desc_hash.is_created ())
+ bitmap_desc_hash.create (10);
- slot = (bitmap_descriptor *)
- htab_find_slot_with_hash (bitmap_desc_hash, &loc,
- htab_hash_pointer (file) + line,
- INSERT);
+ slot = bitmap_desc_hash.find_slot_with_hash (&loc,
+ htab_hash_pointer (file) + line,
+ INSERT);
if (*slot)
return *slot;
@@ -2140,13 +2147,12 @@ struct output_info
unsigned HOST_WIDEST_INT count;
};
-/* Called via htab_traverse. Output bitmap descriptor pointed out by SLOT
- and update statistics. */
-static int
-print_statistics (void **slot, void *b)
+/* Called via hash_table::traverse. Output bitmap descriptor pointed out by
+ SLOT and update statistics. */
+int
+print_statistics (bitmap_descriptor_d **slot, output_info *i)
{
- bitmap_descriptor d = (bitmap_descriptor) *slot;
- struct output_info *i = (struct output_info *) b;
+ bitmap_descriptor d = *slot;
char s[4096];
if (d->allocated)
@@ -2180,7 +2186,7 @@ dump_bitmap_statistics (void)
if (! GATHER_STATISTICS)
return;
- if (!bitmap_desc_hash)
+ if (!bitmap_desc_hash.is_created ())
return;
fprintf (stderr,
@@ -2191,7 +2197,7 @@ dump_bitmap_statistics (void)
fprintf (stderr, "---------------------------------------------------------------------------------\n");
info.count = 0;
info.size = 0;
- htab_traverse (bitmap_desc_hash, print_statistics, &info);
+ bitmap_desc_hash.traverse <output_info *, print_statistics> (&info);
fprintf (stderr, "---------------------------------------------------------------------------------\n");
fprintf (stderr,
"%-41s %9"HOST_WIDEST_INT_PRINT"d %15"HOST_WIDEST_INT_PRINT"d\n",
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 0c48d6ee49c..567b75ece9c 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -23,6 +23,7 @@
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
@@ -3797,36 +3798,48 @@ arm_function_value(const_tree type, const_tree func,
return arm_libcall_value_1 (mode);
}
-static int
-libcall_eq (const void *p1, const void *p2)
+/* libcall hashtable helpers. */
+
+struct libcall_hasher : typed_noop_remove <rtx_def>
+{
+ typedef rtx_def value_type;
+ typedef rtx_def compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline bool
+libcall_hasher::equal (const value_type *p1, const compare_type *p2)
{
- return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
+ return rtx_equal_p (p1, p2);
}
-static hashval_t
-libcall_hash (const void *p1)
+inline hashval_t
+libcall_hasher::hash (const value_type *p1)
{
- return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
+ return hash_rtx (p1, VOIDmode, NULL, NULL, FALSE);
}
+typedef hash_table <libcall_hasher> libcall_table_type;
+
static void
-add_libcall (htab_t htab, rtx libcall)
+add_libcall (libcall_table_type htab, rtx libcall)
{
- *htab_find_slot (htab, libcall, INSERT) = libcall;
+ *htab.find_slot (libcall, INSERT) = libcall;
}
static bool
arm_libcall_uses_aapcs_base (const_rtx libcall)
{
static bool init_done = false;
- static htab_t libcall_htab;
+ static libcall_table_type libcall_htab;
if (!init_done)
{
init_done = true;
- libcall_htab = htab_create (31, libcall_hash, libcall_eq,
- NULL);
+ libcall_htab.create (31);
add_libcall (libcall_htab,
convert_optab_libfunc (sfloat_optab, SFmode, SImode));
add_libcall (libcall_htab,
@@ -3885,7 +3898,7 @@ arm_libcall_uses_aapcs_base (const_rtx libcall)
DFmode));
}
- return libcall && htab_find (libcall_htab, libcall) != NULL;
+ return libcall && libcall_htab.find (libcall) != NULL;
}
static rtx
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 96b88de0f7c..f3dca3a2516 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -76,8 +76,8 @@ $(srcdir)/config/arm/arm-tables.opt: $(srcdir)/config/arm/genopt.sh \
$(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
$(srcdir)/config/arm/arm-tables.opt
-arm.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(RTL_H) $(TREE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
+arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
insn-config.h conditions.h output.h dumpfile.h \
$(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \
$(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \
diff --git a/gcc/config/i386/t-cygming b/gcc/config/i386/t-cygming
index f615ad7a2af..ba076a7f49a 100644
--- a/gcc/config/i386/t-cygming
+++ b/gcc/config/i386/t-cygming
@@ -22,7 +22,7 @@ LIMITS_H_TEST = true
winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
- $(TM_P_H) $(HASHTAB_H) $(GGC_H) $(LTO_STREAMER_H)
+ $(TM_P_H) $(HASH_TABLE_H) $(GGC_H) $(LTO_STREAMER_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/winnt.c
diff --git a/gcc/config/i386/t-interix b/gcc/config/i386/t-interix
index 43443e72a45..4d7b5987037 100644
--- a/gcc/config/i386/t-interix
+++ b/gcc/config/i386/t-interix
@@ -18,7 +18,7 @@
winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
- $(TM_P_H) $(HASHTAB_H) $(GGC_H)
+ $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/winnt.c
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 118b1ecb007..2d53ccfd100 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "tm_p.h"
#include "diagnostic-core.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "langhooks.h"
#include "ggc.h"
#include "target.h"
@@ -449,7 +449,7 @@ i386_pe_reloc_rw_mask (void)
unsigned int
i386_pe_section_type_flags (tree decl, const char *name, int reloc)
{
- static htab_t htab;
+ static hash_table <pointer_hash <unsigned int> > htab;
unsigned int flags;
unsigned int **slot;
@@ -460,8 +460,8 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc)
/* The names we put in the hashtable will always be the unique
versions given to us by the stringtable, so we can just use
their addresses as the keys. */
- if (!htab)
- htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
+ if (!htab.is_created ())
+ htab.create (31);
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
flags = SECTION_CODE;
@@ -480,7 +480,7 @@ i386_pe_section_type_flags (tree decl, const char *name, int reloc)
flags |= SECTION_LINKONCE;
/* See if we already have an entry for this section. */
- slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
+ slot = htab.find_slot ((unsigned int *)name, INSERT);
if (!*slot)
{
*slot = (unsigned int *) xmalloc (sizeof (unsigned int));
@@ -680,12 +680,29 @@ i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
#ifdef CXX_WRAP_SPEC_LIST
+/* Hashtable helpers. */
+
+struct wrapped_symbol_hasher : typed_noop_remove <char>
+{
+ typedef char value_type;
+ typedef char compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline hashval_t
+wrapped_symbol_hasher::hash (const value_type *v)
+{
+ return htab_hash_string (v);
+}
+
/* Hash table equality helper function. */
-static int
-wrapper_strcmp (const void *x, const void *y)
+inline bool
+wrapped_symbol_hasher::equal (const value_type *x, const compare_type *y)
{
- return !strcmp ((const char *) x, (const char *) y);
+ return !strcmp (x, y);
}
/* Search for a function named TARGET in the list of library wrappers
@@ -699,7 +716,7 @@ static const char *
i386_find_on_wrapper_list (const char *target)
{
static char first_time = 1;
- static htab_t wrappers;
+ static hash_table <wrapped_symbol_hasher> wrappers;
if (first_time)
{
@@ -712,8 +729,7 @@ i386_find_on_wrapper_list (const char *target)
char *bufptr;
/* Breaks up the char array into separated strings
strings and enter them into the hash table. */
- wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
- 0, xcalloc, free);
+ wrappers.create (8);
for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
{
char *found = NULL;
@@ -726,12 +742,12 @@ i386_find_on_wrapper_list (const char *target)
if (*bufptr)
*bufptr = 0;
if (found)
- *htab_find_slot (wrappers, found, INSERT) = found;
+ *wrappers.find_slot (found, INSERT) = found;
}
first_time = 0;
}
- return (const char *) htab_find (wrappers, target);
+ return wrappers.find (target);
}
#endif /* CXX_WRAP_SPEC_LIST */
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 0e328ff827b..2f5220c91dc 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-def.h"
#include "common/common-target.h"
#include "tm_p.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "langhooks.h"
#include "gimple.h"
#include "intl.h"
@@ -257,8 +257,6 @@ static struct bundle_state *get_free_bundle_state (void);
static void free_bundle_state (struct bundle_state *);
static void initiate_bundle_states (void);
static void finish_bundle_states (void);
-static unsigned bundle_state_hash (const void *);
-static int bundle_state_eq_p (const void *, const void *);
static int insert_bundle_state (struct bundle_state *);
static void initiate_bundle_state_table (void);
static void finish_bundle_state_table (void);
@@ -8529,18 +8527,21 @@ finish_bundle_states (void)
}
}
-/* Hash table of the bundle states. The key is dfa_state and insn_num
- of the bundle states. */
+/* Hashtable helpers. */
-static htab_t bundle_state_table;
+struct bundle_state_hasher : typed_noop_remove <bundle_state>
+{
+ typedef bundle_state value_type;
+ typedef bundle_state compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
/* The function returns hash of BUNDLE_STATE. */
-static unsigned
-bundle_state_hash (const void *bundle_state)
+inline hashval_t
+bundle_state_hasher::hash (const value_type *state)
{
- const struct bundle_state *const state
- = (const struct bundle_state *) bundle_state;
unsigned result, i;
for (result = i = 0; i < dfa_state_size; i++)
@@ -8551,19 +8552,20 @@ bundle_state_hash (const void *bundle_state)
/* The function returns nonzero if the bundle state keys are equal. */
-static int
-bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
+inline bool
+bundle_state_hasher::equal (const value_type *state1,
+ const compare_type *state2)
{
- const struct bundle_state *const state1
- = (const struct bundle_state *) bundle_state_1;
- const struct bundle_state *const state2
- = (const struct bundle_state *) bundle_state_2;
-
return (state1->insn_num == state2->insn_num
&& memcmp (state1->dfa_state, state2->dfa_state,
dfa_state_size) == 0);
}
+/* Hash table of the bundle states. The key is dfa_state and insn_num
+ of the bundle states. */
+
+static hash_table <bundle_state_hasher> bundle_state_table;
+
/* The function inserts the BUNDLE_STATE into the hash table. The
function returns nonzero if the bundle has been inserted into the
table. The table contains the best bundle state with given key. */
@@ -8571,39 +8573,35 @@ bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
static int
insert_bundle_state (struct bundle_state *bundle_state)
{
- void **entry_ptr;
+ struct bundle_state **entry_ptr;
- entry_ptr = htab_find_slot (bundle_state_table, bundle_state, INSERT);
+ entry_ptr = bundle_state_table.find_slot (bundle_state, INSERT);
if (*entry_ptr == NULL)
{
bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
index_to_bundle_states [bundle_state->insn_num] = bundle_state;
- *entry_ptr = (void *) bundle_state;
+ *entry_ptr = bundle_state;
return TRUE;
}
- else if (bundle_state->cost < ((struct bundle_state *) *entry_ptr)->cost
- || (bundle_state->cost == ((struct bundle_state *) *entry_ptr)->cost
- && (((struct bundle_state *)*entry_ptr)->accumulated_insns_num
+ else if (bundle_state->cost < (*entry_ptr)->cost
+ || (bundle_state->cost == (*entry_ptr)->cost
+ && ((*entry_ptr)->accumulated_insns_num
> bundle_state->accumulated_insns_num
- || (((struct bundle_state *)
- *entry_ptr)->accumulated_insns_num
+ || ((*entry_ptr)->accumulated_insns_num
== bundle_state->accumulated_insns_num
- && (((struct bundle_state *)
- *entry_ptr)->branch_deviation
+ && ((*entry_ptr)->branch_deviation
> bundle_state->branch_deviation
- || (((struct bundle_state *)
- *entry_ptr)->branch_deviation
+ || ((*entry_ptr)->branch_deviation
== bundle_state->branch_deviation
- && ((struct bundle_state *)
- *entry_ptr)->middle_bundle_stops
+ && (*entry_ptr)->middle_bundle_stops
> bundle_state->middle_bundle_stops))))))
{
struct bundle_state temp;
- temp = *(struct bundle_state *) *entry_ptr;
- *(struct bundle_state *) *entry_ptr = *bundle_state;
- ((struct bundle_state *) *entry_ptr)->next = temp.next;
+ temp = **entry_ptr;
+ **entry_ptr = *bundle_state;
+ (*entry_ptr)->next = temp.next;
*bundle_state = temp;
}
return FALSE;
@@ -8614,8 +8612,7 @@ insert_bundle_state (struct bundle_state *bundle_state)
static void
initiate_bundle_state_table (void)
{
- bundle_state_table = htab_create (50, bundle_state_hash, bundle_state_eq_p,
- (htab_del) 0);
+ bundle_state_table.create (50);
}
/* Finish work with the hash table. */
@@ -8623,7 +8620,7 @@ initiate_bundle_state_table (void)
static void
finish_bundle_state_table (void)
{
- htab_delete (bundle_state_table);
+ bundle_state_table.dispose ();
}
diff --git a/gcc/config/ia64/t-ia64 b/gcc/config/ia64/t-ia64
index 5c3ac644be3..b009cdf2bc5 100644
--- a/gcc/config/ia64/t-ia64
+++ b/gcc/config/ia64/t-ia64
@@ -24,4 +24,5 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
# genattrtab generates very long string literals.
insn-attrtab.o-warn = -Wno-error
-ia64.o: debug.h $(PARAMS_H) sel-sched.h reload.h $(OPTS_H) dumpfile.h
+ia64.o: $(srcdir)/config/ia64/ia64.c debug.h $(PARAMS_H) sel-sched.h reload.h \
+ $(OPTS_H) dumpfile.h $(HASH_TABLE_H)
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 4957a150078..3d356b456ab 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "ggc.h"
#include "gstab.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "debug.h"
#include "target.h"
#include "target-def.h"
@@ -15881,30 +15881,43 @@ mips_hash_base (rtx base)
return hash_rtx (base, GET_MODE (base), &do_not_record_p, NULL, false);
}
+/* Hashtable helpers. */
+
+struct mips_lo_sum_offset_hasher : typed_free_remove <mips_lo_sum_offset>
+{
+ typedef mips_lo_sum_offset value_type;
+ typedef rtx_def compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
/* Hash-table callbacks for mips_lo_sum_offsets. */
-static hashval_t
-mips_lo_sum_offset_hash (const void *entry)
+inline hashval_t
+mips_lo_sum_offset_hasher::hash (const value_type *entry)
{
- return mips_hash_base (((const struct mips_lo_sum_offset *) entry)->base);
+ return mips_hash_base (entry->base);
}
-static int
-mips_lo_sum_offset_eq (const void *entry, const void *value)
+inline bool
+mips_lo_sum_offset_hasher::equal (const value_type *entry,
+ const compare_type *value)
{
- return rtx_equal_p (((const struct mips_lo_sum_offset *) entry)->base,
- (const_rtx) value);
+ return rtx_equal_p (entry->base, value);
}
+typedef hash_table <mips_lo_sum_offset_hasher> mips_offset_table;
+
/* Look up symbolic constant X in HTAB, which is a hash table of
mips_lo_sum_offsets. If OPTION is NO_INSERT, return true if X can be
paired with a recorded LO_SUM, otherwise record X in the table. */
static bool
-mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option option)
+mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
+ enum insert_option option)
{
rtx base, offset;
- void **slot;
+ mips_lo_sum_offset **slot;
struct mips_lo_sum_offset *entry;
/* Split X into a base and offset. */
@@ -15913,7 +15926,7 @@ mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option option)
base = UNSPEC_ADDRESS (base);
/* Look up the base in the hash table. */
- slot = htab_find_slot_with_hash (htab, base, mips_hash_base (base), option);
+ slot = htab.find_slot_with_hash (base, mips_hash_base (base), option);
if (slot == NULL)
return false;
@@ -15943,7 +15956,8 @@ static int
mips_record_lo_sum (rtx *loc, void *data)
{
if (GET_CODE (*loc) == LO_SUM)
- mips_lo_sum_offset_lookup ((htab_t) data, XEXP (*loc, 1), INSERT);
+ mips_lo_sum_offset_lookup (*(mips_offset_table*)data,
+ XEXP (*loc, 1), INSERT);
return 0;
}
@@ -15952,7 +15966,7 @@ mips_record_lo_sum (rtx *loc, void *data)
LO_SUMs in the current function. */
static bool
-mips_orphaned_high_part_p (htab_t htab, rtx insn)
+mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
{
enum mips_symbol_type type;
rtx x, set;
@@ -16060,7 +16074,7 @@ mips_reorg_process_insns (void)
{
rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg;
int hilo_delay;
- htab_t htab;
+ mips_offset_table htab;
/* Force all instructions to be split into their final form. */
split_all_insns_noflow ();
@@ -16097,14 +16111,13 @@ mips_reorg_process_insns (void)
if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
cfun->machine->all_noreorder_p = false;
- htab = htab_create (37, mips_lo_sum_offset_hash,
- mips_lo_sum_offset_eq, free);
+ htab.create (37);
/* Make a first pass over the instructions, recording all the LO_SUMs. */
for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
FOR_EACH_SUBINSN (subinsn, insn)
if (USEFUL_INSN_P (subinsn))
- for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, htab);
+ for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);
last_insn = 0;
hilo_delay = 2;
@@ -16161,7 +16174,7 @@ mips_reorg_process_insns (void)
}
}
- htab_delete (htab);
+ htab.dispose ();
}
/* Return true if the function has a long branch instruction. */
diff --git a/gcc/config/sol2.c b/gcc/config/sol2.c
index 718134e2b90..7c7c429db3d 100644
--- a/gcc/config/sol2.c
+++ b/gcc/config/sol2.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "diagnostic-core.h"
#include "ggc.h"
-#include "hashtab.h"
+#include "hash-table.h"
tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
@@ -157,10 +157,6 @@ solaris_assemble_visibility (tree decl, int vis ATTRIBUTE_UNUSED)
#endif
}
-/* Hash table of group signature symbols. */
-
-static htab_t solaris_comdat_htab;
-
/* Group section information entry stored in solaris_comdat_htab. */
typedef struct comdat_entry
@@ -171,25 +167,34 @@ typedef struct comdat_entry
const char *sig;
} comdat_entry;
-/* Helper routines for maintaining solaris_comdat_htab. */
+/* Helpers for maintaining solaris_comdat_htab. */
-static hashval_t
-comdat_hash (const void *p)
+struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
+{
+ typedef comdat_entry value_type;
+ typedef comdat_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline hashval_t
+comdat_entry_hasher::hash (const value_type *entry)
{
- const comdat_entry *entry = (const comdat_entry *) p;
-
return htab_hash_string (entry->sig);
}
-static int
-comdat_eq (const void *p1, const void *p2)
+inline bool
+comdat_entry_hasher::equal (const value_type *entry1,
+ const compare_type *entry2)
{
- const comdat_entry *entry1 = (const comdat_entry *) p1;
- const comdat_entry *entry2 = (const comdat_entry *) p2;
-
return strcmp (entry1->sig, entry2->sig) == 0;
}
+/* Hash table of group signature symbols. */
+
+static hash_table <comdat_entry_hasher> solaris_comdat_htab;
+
/* Output assembly to switch to COMDAT group section NAME with attributes
FLAGS and group signature symbol DECL, using Sun as syntax. */
@@ -229,12 +234,11 @@ solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
identify the missing ones without changing the affected frontents,
remember the signature symbols and emit those not marked
TREE_SYMBOL_REFERENCED in solaris_file_end. */
- if (solaris_comdat_htab == NULL)
- solaris_comdat_htab = htab_create_alloc (37, comdat_hash, comdat_eq, NULL,
- xcalloc, free);
+ if (!solaris_comdat_htab.is_created ())
+ solaris_comdat_htab.create (37);
entry.sig = signature;
- slot = (comdat_entry **) htab_find_slot (solaris_comdat_htab, &entry, INSERT);
+ slot = solaris_comdat_htab.find_slot (&entry, INSERT);
if (*slot == NULL)
{
@@ -250,10 +254,11 @@ solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
/* Define unreferenced COMDAT group signature symbol corresponding to SLOT. */
-static int
-solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
+int
+solaris_define_comdat_signature (comdat_entry **slot,
+ void *aux ATTRIBUTE_UNUSED)
{
- comdat_entry *entry = *(comdat_entry **) slot;
+ comdat_entry *entry = *slot;
tree decl = entry->decl;
if (TREE_CODE (decl) != IDENTIFIER_NODE)
@@ -277,10 +282,10 @@ solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
void
solaris_file_end (void)
{
- if (solaris_comdat_htab == NULL)
+ if (!solaris_comdat_htab.is_created ())
return;
- htab_traverse (solaris_comdat_htab, solaris_define_comdat_signature, NULL);
+ solaris_comdat_htab.traverse <void *, solaris_define_comdat_signature> (NULL);
}
void
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
index 25b825017f6..142de89de95 100644
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -34,5 +34,5 @@ sol2-stubs.o: $(srcdir)/config/sol2-stubs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h
# Solaris-specific attributes
sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
+ tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H) $(HASH_TABLE_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/vxworks.c b/gcc/config/vxworks.c
index 2900d9785ea..8ac2ede49a1 100644
--- a/gcc/config/vxworks.c
+++ b/gcc/config/vxworks.c
@@ -56,35 +56,18 @@ vxworks_asm_out_destructor (rtx symbol, int priority)
assemble_addr_to_section (symbol, sec);
}
-/* Return the list of FIELD_DECLs that make up an emulated TLS
- variable's control object. TYPE is the structure these are fields
- of and *NAME will be filled in with the structure tag that should
- be used. */
+/* Return the type of an emulated TLS variable's control object. */
static tree
-vxworks_emutls_var_fields (tree type, tree *name)
+vxworks_emutls_object_type ()
{
- tree field, next_field;
-
- *name = get_identifier ("__tls_var");
-
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- get_identifier ("size"), unsigned_type_node);
- DECL_CONTEXT (field) = type;
- next_field = field;
-
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- get_identifier ("module_id"), unsigned_type_node);
- DECL_CONTEXT (field) = type;
- DECL_CHAIN (field) = next_field;
- next_field = field;
-
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- get_identifier ("offset"), unsigned_type_node);
- DECL_CONTEXT (field) = type;
- DECL_CHAIN (field) = next_field;
-
- return field;
+ record_builder rec;
+ rec.add_field ("offset", unsigned_type_node);
+ rec.add_field ("module_id", unsigned_type_node);
+ rec.add_field ("size", unsigned_type_node);
+ rec.layout ();
+ rec.decl_name ("__tls_var");
+ return rec.as_tree ();
}
/* Return the CONSTRUCTOR to initialize an emulated TLS control
@@ -131,7 +114,7 @@ vxworks_override_options (void)
targetm.emutls.tmpl_section = ".tls_data";
targetm.emutls.var_prefix = "__tls__";
targetm.emutls.tmpl_prefix = "";
- targetm.emutls.var_fields = vxworks_emutls_var_fields;
+ targetm.emutls.object_type = vxworks_emutls_object_type;
targetm.emutls.var_init = vxworks_emutls_var_init;
targetm.emutls.var_align_fixed = true;
targetm.emutls.debug_form_tls_address = true;
diff --git a/gcc/coverage.c b/gcc/coverage.c
index bc6a46f5ff4..df22cdc0b4b 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -121,8 +121,8 @@ static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
/* Forward declarations. */
static void read_counts_file (void);
static tree build_var (tree, tree, int);
-static void build_fn_info_type (tree, unsigned, tree);
-static void build_info_type (tree, tree);
+static tree build_fn_info_type (unsigned, tree);
+static tree build_info_type (record_builder &, tree);
static tree build_fn_info (const struct coverage_data *, tree, tree);
static tree build_info (tree, tree);
static bool coverage_obj_init (void);
@@ -693,63 +693,47 @@ build_var (tree fn_decl, tree type, int counter)
return var;
}
-/* Creates the gcov_fn_info RECORD_TYPE. */
+/* Creates the gcov_fn_info RECORD_TYPE, given the number of COUNTERS and
+ using the GCOV_INFO_TYPE. */
-static void
-build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
+static tree
+build_fn_info_type (unsigned counters, tree gcov_info_type)
{
- tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
- tree field, fields;
- tree array_type;
-
gcc_assert (counters);
-
- /* ctr_info::num */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- get_gcov_unsigned_t ());
- fields = field;
-
- /* ctr_info::values */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- build_pointer_type (get_gcov_type ()));
- DECL_CHAIN (field) = fields;
- fields = field;
-
- finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
+ record_builder bld_ctr_info;
+ tree gcov_type = get_gcov_type ();
+ tree gcov_ptr_type = build_pointer_type (gcov_type);
+ bld_ctr_info.add_field (NULL_TREE, gcov_type, BUILTINS_LOCATION);
+ bld_ctr_info.add_field (NULL_TREE, gcov_ptr_type, BUILTINS_LOCATION);
+ bld_ctr_info.layout ();
+ bld_ctr_info.decl_name ("__gcov_ctr_info", BUILTINS_LOCATION);
+ tree ctr_info = bld_ctr_info.as_tree ();
+
+ record_builder bld_fn_info;
/* key */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- build_pointer_type (build_qualified_type
- (gcov_info_type, TYPE_QUAL_CONST)));
- fields = field;
-
+ tree pc_gcov_info
+ = build_pointer_type (build_qualified_type (gcov_info_type,
+ TYPE_QUAL_CONST));
+ bld_fn_info.add_field (NULL_TREE, pc_gcov_info, BUILTINS_LOCATION);
+
/* ident */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- get_gcov_unsigned_t ());
- DECL_CHAIN (field) = fields;
- fields = field;
-
+ bld_fn_info.add_field (NULL_TREE, get_gcov_unsigned_t ());
+
/* lineno_checksum */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- get_gcov_unsigned_t ());
- DECL_CHAIN (field) = fields;
- fields = field;
+ bld_fn_info.add_field (NULL_TREE, get_gcov_unsigned_t ());
/* cfg checksum */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- get_gcov_unsigned_t ());
- DECL_CHAIN (field) = fields;
- fields = field;
-
- array_type = build_index_type (size_int (counters - 1));
- array_type = build_array_type (ctr_info, array_type);
+ bld_fn_info.add_field (NULL_TREE, get_gcov_unsigned_t ());
/* counters */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
- DECL_CHAIN (field) = fields;
- fields = field;
+ tree index_type = build_index_type (size_int (counters - 1));
+ tree array_type = build_array_type (ctr_info, index_type);
- finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
+ bld_fn_info.add_field (NULL_TREE, array_type, BUILTINS_LOCATION);
+ bld_fn_info.layout ();
+ bld_fn_info.decl_name ("__gcov_fn_info", BUILTINS_LOCATION);
+ return bld_fn_info.as_tree ();
}
/* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
@@ -819,69 +803,52 @@ build_fn_info (const struct coverage_data *data, tree type, tree key)
return build_constructor (type, v1);
}
-/* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
+/* Return gcov_info struct. BLD_INFO_TYPE is the record_builder to be
completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
-static void
-build_info_type (tree type, tree fn_info_ptr_type)
+static tree
+build_info_type (record_builder &bld_info_type, tree fn_info_ptr_type)
{
- tree field, fields = NULL_TREE;
- tree merge_fn_type;
+ tree uns_type = get_gcov_unsigned_t ();
/* Version ident */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- get_gcov_unsigned_t ());
- DECL_CHAIN (field) = fields;
- fields = field;
+ bld_info_type.add_field (NULL_TREE, uns_type, BUILTINS_LOCATION);
/* next pointer */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- build_pointer_type (build_qualified_type
- (type, TYPE_QUAL_CONST)));
- DECL_CHAIN (field) = fields;
- fields = field;
+ tree self_type = bld_info_type.as_tree ();
+ tree qual_info = build_qualified_type (self_type, TYPE_QUAL_CONST);
+ tree ptr_info = build_pointer_type (qual_info);
+ bld_info_type.add_field (NULL_TREE, ptr_info, BUILTINS_LOCATION);
/* stamp */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- get_gcov_unsigned_t ());
- DECL_CHAIN (field) = fields;
- fields = field;
+ bld_info_type.add_field (NULL_TREE, uns_type, BUILTINS_LOCATION);
/* Filename */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- build_pointer_type (build_qualified_type
- (char_type_node, TYPE_QUAL_CONST)));
- DECL_CHAIN (field) = fields;
- fields = field;
+ tree qual_char = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
+ tree ptr_char = build_pointer_type (qual_char);
+ bld_info_type.add_field (NULL_TREE, ptr_char, BUILTINS_LOCATION);
/* merge fn array */
- merge_fn_type
+ tree merge_fn_type
= build_function_type_list (void_type_node,
build_pointer_type (get_gcov_type ()),
- get_gcov_unsigned_t (), NULL_TREE);
- merge_fn_type
+ uns_type, NULL_TREE);
+ tree array_fn_type
= build_array_type (build_pointer_type (merge_fn_type),
build_index_type (size_int (GCOV_COUNTERS - 1)));
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- merge_fn_type);
- DECL_CHAIN (field) = fields;
- fields = field;
-
+ bld_info_type.add_field (NULL_TREE, array_fn_type, BUILTINS_LOCATION);
+
/* n_functions */
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- get_gcov_unsigned_t ());
- DECL_CHAIN (field) = fields;
- fields = field;
-
+ bld_info_type.add_field (NULL_TREE, uns_type, BUILTINS_LOCATION);
+
/* function_info pointer pointer */
- fn_info_ptr_type = build_pointer_type
+ tree fn_info_ptr_ptr_type = build_pointer_type
(build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
- field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
- fn_info_ptr_type);
- DECL_CHAIN (field) = fields;
- fields = field;
+ bld_info_type.add_field (NULL_TREE, fn_info_ptr_ptr_type, BUILTINS_LOCATION);
- finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
+ bld_info_type.layout ();
+ bld_info_type.decl_name ("__gcov_info");
+ return bld_info_type.as_tree ();
}
/* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
@@ -974,7 +941,7 @@ build_info (tree info_type, tree fn_ary)
static bool
coverage_obj_init (void)
{
- tree gcov_info_type, ctor, stmt, init_fn;
+ tree ctor, stmt, init_fn;
unsigned n_counters = 0;
unsigned ix;
struct coverage_data *fn;
@@ -1005,12 +972,11 @@ coverage_obj_init (void)
n_counters++;
/* Build the info and fn_info types. These are mutually recursive. */
- gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
- gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
+ record_builder bld_info_type;
+ gcov_fn_info_type = build_fn_info_type (n_counters, bld_info_type.as_tree ());
gcov_fn_info_ptr_type = build_pointer_type
(build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
- build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
- build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
+ tree gcov_info_type = build_info_type (bld_info_type, gcov_fn_info_ptr_type);
/* Build the gcov info var, this is referred to in its own
initializer. */
diff --git a/gcc/cselib.c b/gcc/cselib.c
index f2021b985b0..7aef4a0d21b 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "emit-rtl.h"
#include "diagnostic-core.h"
#include "ggc.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "dumpfile.h"
#include "cselib.h"
#include "valtrack.h"
@@ -49,18 +49,18 @@ struct elt_list {
cselib_val *elt;
};
+/* See the documentation of cselib_find_slot below. */
+static enum machine_mode find_slot_memmode;
+
static bool cselib_record_memory;
static bool cselib_preserve_constants;
static bool cselib_any_perm_equivs;
-static int entry_and_rtx_equal_p (const void *, const void *);
-static hashval_t get_value_hash (const void *);
+static inline void promote_debug_loc (struct elt_loc_list *l);
static struct elt_list *new_elt_list (struct elt_list *, cselib_val *);
static void new_elt_loc_list (cselib_val *, rtx);
static void unchain_one_value (cselib_val *);
static void unchain_one_elt_list (struct elt_list **);
static void unchain_one_elt_loc_list (struct elt_loc_list **);
-static int discard_useless_locs (void **, void *);
-static int discard_useless_values (void **, void *);
static void remove_useless_values (void);
static int rtx_equal_for_cselib_1 (rtx, rtx, enum machine_mode);
static unsigned int cselib_hash_rtx (rtx, int, enum machine_mode);
@@ -91,8 +91,61 @@ static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int);
this involves walking the table entries for a given value and comparing
the locations of the entries with the rtx we are looking up. */
+struct cselib_hasher : typed_noop_remove <cselib_val>
+{
+ typedef cselib_val value_type;
+ typedef rtx_def compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* The hash function for our hash table. The value is always computed with
+ cselib_hash_rtx when adding an element; this function just extracts the
+ hash value from a cselib_val structure. */
+
+inline hashval_t
+cselib_hasher::hash (const value_type *v)
+{
+ return v->hash;
+}
+
+/* The equality test for our hash table. The first argument V is a table
+ element (i.e. a cselib_val), while the second arg X is an rtx. We know
+ that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a
+ CONST of an appropriate mode. */
+
+inline bool
+cselib_hasher::equal (const value_type *v, const compare_type *x_arg)
+{
+ struct elt_loc_list *l;
+ rtx x = CONST_CAST_RTX (x_arg);
+ enum machine_mode mode = GET_MODE (x);
+
+ gcc_assert (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED);
+
+ if (mode != GET_MODE (v->val_rtx))
+ return false;
+
+ /* Unwrap X if necessary. */
+ if (GET_CODE (x) == CONST
+ && (CONST_SCALAR_INT_P (XEXP (x, 0))
+ || GET_CODE (XEXP (x, 0)) == CONST_FIXED))
+ x = XEXP (x, 0);
+
+ /* We don't guarantee that distinct rtx's have different hash values,
+ so we need to do a comparison. */
+ for (l = v->locs; l; l = l->next)
+ if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode))
+ {
+ promote_debug_loc (l);
+ return true;
+ }
+
+ return false;
+}
+
/* A table that enables us to look up elts by their value. */
-static htab_t cselib_hash_table;
+static hash_table <cselib_hasher> cselib_hash_table;
/* This is a global so we don't have to pass this through every function.
It is used in new_elt_loc_list to set SETTING_INSN. */
@@ -432,13 +485,13 @@ invariant_or_equiv_p (cselib_val *v)
/* Remove from hash table all VALUEs except constants, function
invariants and VALUE equivalences. */
-static int
-preserve_constants_and_equivs (void **x, void *info ATTRIBUTE_UNUSED)
+int
+preserve_constants_and_equivs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
{
- cselib_val *v = (cselib_val *)*x;
+ cselib_val *v = *x;
if (!invariant_or_equiv_p (v))
- htab_clear_slot (cselib_hash_table, x);
+ cselib_hash_table.clear_slot (x);
return 1;
}
@@ -478,10 +531,10 @@ cselib_reset_table (unsigned int num)
}
if (cselib_preserve_constants)
- htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL);
+ cselib_hash_table.traverse <void *, preserve_constants_and_equivs> (NULL);
else
{
- htab_empty (cselib_hash_table);
+ cselib_hash_table.empty ();
gcc_checking_assert (!cselib_any_perm_equivs);
}
@@ -502,73 +555,23 @@ cselib_get_next_uid (void)
return next_uid;
}
-/* See the documentation of cselib_find_slot below. */
-static enum machine_mode find_slot_memmode;
-
/* Search for X, whose hashcode is HASH, in CSELIB_HASH_TABLE,
INSERTing if requested. When X is part of the address of a MEM,
MEMMODE should specify the mode of the MEM. While searching the
table, MEMMODE is held in FIND_SLOT_MEMMODE, so that autoinc RTXs
in X can be resolved. */
-static void **
+static cselib_val **
cselib_find_slot (rtx x, hashval_t hash, enum insert_option insert,
enum machine_mode memmode)
{
- void **slot;
+ cselib_val **slot;
find_slot_memmode = memmode;
- slot = htab_find_slot_with_hash (cselib_hash_table, x, hash, insert);
+ slot = cselib_hash_table.find_slot_with_hash (x, hash, insert);
find_slot_memmode = VOIDmode;
return slot;
}
-/* The equality test for our hash table. The first argument ENTRY is a table
- element (i.e. a cselib_val), while the second arg X is an rtx. We know
- that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a
- CONST of an appropriate mode. */
-
-static int
-entry_and_rtx_equal_p (const void *entry, const void *x_arg)
-{
- struct elt_loc_list *l;
- const cselib_val *const v = (const cselib_val *) entry;
- rtx x = CONST_CAST_RTX ((const_rtx)x_arg);
- enum machine_mode mode = GET_MODE (x);
-
- gcc_assert (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED);
-
- if (mode != GET_MODE (v->val_rtx))
- return 0;
-
- /* Unwrap X if necessary. */
- if (GET_CODE (x) == CONST
- && (CONST_SCALAR_INT_P (XEXP (x, 0))
- || GET_CODE (XEXP (x, 0)) == CONST_FIXED))
- x = XEXP (x, 0);
-
- /* We don't guarantee that distinct rtx's have different hash values,
- so we need to do a comparison. */
- for (l = v->locs; l; l = l->next)
- if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode))
- {
- promote_debug_loc (l);
- return 1;
- }
-
- return 0;
-}
-
-/* The hash function for our hash table. The value is always computed with
- cselib_hash_rtx when adding an element; this function just extracts the
- hash value from a cselib_val structure. */
-
-static hashval_t
-get_value_hash (const void *entry)
-{
- const cselib_val *const v = (const cselib_val *) entry;
- return v->hash;
-}
-
/* Return true if X contains a VALUE rtx. If ONLY_USELESS is set, we
only return true for values which point to a cselib_val whose value
element has been set to zero, which implies the cselib_val will be
@@ -603,10 +606,10 @@ references_value_p (const_rtx x, int only_useless)
values (i.e. values without any location). Called through
htab_traverse. */
-static int
-discard_useless_locs (void **x, void *info ATTRIBUTE_UNUSED)
+int
+discard_useless_locs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
{
- cselib_val *v = (cselib_val *)*x;
+ cselib_val *v = *x;
struct elt_loc_list **p = &v->locs;
bool had_locs = v->locs != NULL;
rtx setting_insn = v->locs ? v->locs->setting_insn : NULL;
@@ -632,10 +635,10 @@ discard_useless_locs (void **x, void *info ATTRIBUTE_UNUSED)
/* If X is a value with no locations, remove it from the hashtable. */
-static int
-discard_useless_values (void **x, void *info ATTRIBUTE_UNUSED)
+int
+discard_useless_values (cselib_val **x, void *info ATTRIBUTE_UNUSED)
{
- cselib_val *v = (cselib_val *)*x;
+ cselib_val *v = *x;
if (v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
{
@@ -643,7 +646,7 @@ discard_useless_values (void **x, void *info ATTRIBUTE_UNUSED)
cselib_discard_hook (v);
CSELIB_VAL_PTR (v->val_rtx) = NULL;
- htab_clear_slot (cselib_hash_table, x);
+ cselib_hash_table.clear_slot (x);
unchain_one_value (v);
n_useless_values--;
}
@@ -664,7 +667,7 @@ remove_useless_values (void)
do
{
values_became_useless = 0;
- htab_traverse (cselib_hash_table, discard_useless_locs, 0);
+ cselib_hash_table.traverse <void *, discard_useless_locs> (NULL);
}
while (values_became_useless);
@@ -683,7 +686,7 @@ remove_useless_values (void)
n_debug_values -= n_useless_debug_values;
n_useless_debug_values = 0;
- htab_traverse (cselib_hash_table, discard_useless_values, 0);
+ cselib_hash_table.traverse <void *, discard_useless_values> (NULL);
gcc_assert (!n_useless_values);
}
@@ -1352,7 +1355,7 @@ cselib_lookup_mem (rtx x, int create)
{
enum machine_mode mode = GET_MODE (x);
enum machine_mode addr_mode;
- void **slot;
+ cselib_val **slot;
cselib_val *addr;
cselib_val *mem_elt;
struct elt_list *l;
@@ -1958,7 +1961,7 @@ static cselib_val *
cselib_lookup_1 (rtx x, enum machine_mode mode,
int create, enum machine_mode memmode)
{
- void **slot;
+ cselib_val **slot;
cselib_val *e;
unsigned int hashval;
@@ -2069,7 +2072,7 @@ cselib_lookup_1 (rtx x, enum machine_mode mode,
/* We have to fill the slot before calling cselib_subst_to_values:
the hash table is inconsistent until we do so, and
cselib_subst_to_values will need to do lookups. */
- *slot = (void *) e;
+ *slot = e;
new_elt_loc_list (e, cselib_subst_to_values (x, memmode));
return e;
}
@@ -2695,9 +2698,7 @@ cselib_process_insn (rtx insn)
quadratic behavior for very large hashtables with very few
useless elements. */
&& ((unsigned int)n_useless_values
- > (cselib_hash_table->n_elements
- - cselib_hash_table->n_deleted
- - n_debug_values) / 4))
+ > (cselib_hash_table.elements () - n_debug_values) / 4))
remove_useless_values ();
}
@@ -2738,8 +2739,7 @@ cselib_init (int record_what)
}
used_regs = XNEWVEC (unsigned int, cselib_nregs);
n_used_regs = 0;
- cselib_hash_table = htab_create (31, get_value_hash,
- entry_and_rtx_equal_p, NULL);
+ cselib_hash_table.create (31);
next_uid = 1;
}
@@ -2758,23 +2758,21 @@ cselib_finish (void)
free_alloc_pool (cselib_val_pool);
free_alloc_pool (value_pool);
cselib_clear_table ();
- htab_delete (cselib_hash_table);
+ cselib_hash_table.dispose ();
free (used_regs);
used_regs = 0;
- cselib_hash_table = 0;
n_useless_values = 0;
n_useless_debug_values = 0;
n_debug_values = 0;
next_uid = 0;
}
-/* Dump the cselib_val *X to FILE *info. */
+/* Dump the cselib_val *X to FILE *OUT. */
-static int
-dump_cselib_val (void **x, void *info)
+int
+dump_cselib_val (cselib_val **x, FILE *out)
{
- cselib_val *v = (cselib_val *)*x;
- FILE *out = (FILE *)info;
+ cselib_val *v = *x;
bool need_lf = true;
print_inline_rtx (out, v->val_rtx, 0);
@@ -2849,7 +2847,7 @@ void
dump_cselib_table (FILE *out)
{
fprintf (out, "cselib hash table:\n");
- htab_traverse (cselib_hash_table, dump_cselib_val, out);
+ cselib_hash_table.traverse <FILE *, dump_cselib_val> (out);
if (first_containing_mem != &dummy_val)
{
fputs ("first mem ", out);
diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c
index ad50263fc96..8f032b49ac2 100644
--- a/gcc/data-streamer-out.c
+++ b/gcc/data-streamer-out.c
@@ -42,8 +42,7 @@ streamer_string_index (struct output_block *ob, const char *s, unsigned int len,
s_slot.len = len;
s_slot.slot_num = 0;
- slot = (struct string_slot **) htab_find_slot (ob->string_hash_table,
- &s_slot, INSERT);
+ slot = ob->string_hash_table.find_slot (&s_slot, INSERT);
if (*slot == NULL)
{
struct lto_output_stream *string_stream = ob->string_stream;
diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h
index 288da283d8f..126b6171d98 100644
--- a/gcc/data-streamer.h
+++ b/gcc/data-streamer.h
@@ -44,15 +44,6 @@ struct bitpack_d
void *stream;
};
-
-/* String hashing. */
-struct string_slot
-{
- const char *s;
- int len;
- unsigned int slot_num;
-};
-
/* In data-streamer.c */
void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT);
void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT);
@@ -90,35 +81,6 @@ const char *bp_unpack_string (struct data_in *, struct bitpack_d *);
unsigned HOST_WIDE_INT streamer_read_uhwi (struct lto_input_block *);
HOST_WIDE_INT streamer_read_hwi (struct lto_input_block *);
-/* Returns a hash code for P. Adapted from libiberty's htab_hash_string
- to support strings that may not end in '\0'. */
-
-static inline hashval_t
-hash_string_slot_node (const void *p)
-{
- const struct string_slot *ds = (const struct string_slot *) p;
- hashval_t r = ds->len;
- int i;
-
- for (i = 0; i < ds->len; i++)
- r = r * 67 + (unsigned)ds->s[i] - 113;
- return r;
-}
-
-/* Returns nonzero if P1 and P2 are equal. */
-
-static inline int
-eq_string_slot_node (const void *p1, const void *p2)
-{
- const struct string_slot *ds1 = (const struct string_slot *) p1;
- const struct string_slot *ds2 = (const struct string_slot *) p2;
-
- if (ds1->len == ds2->len)
- return memcmp (ds1->s, ds2->s, ds1->len) == 0;
-
- return 0;
-}
-
/* Returns a new bit-packing context for bit-packing into S. */
static inline struct bitpack_d
bitpack_create (struct lto_output_stream *s)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cbbc82dfe39..5830b2f213b 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -9966,12 +9966,10 @@ Contains the prefix to be prepended to TLS initializer objects. The
default of @code{NULL} uses a target-specific prefix.
@end deftypevr
-@deftypefn {Target Hook} tree TARGET_EMUTLS_VAR_FIELDS (tree @var{type}, tree *@var{name})
-Specifies a function that generates the FIELD_DECLs for a TLS control
-object type. @var{type} is the RECORD_TYPE the fields are for and
-@var{name} should be filled with the structure tag, if the default of
-@code{__emutls_object} is unsuitable. The default creates a type suitable
-for libgcc's emulated TLS function.
+@deftypefn {Target Hook} tree TARGET_EMUTLS_OBJECT_TYPE ()
+Specifies a function that generates the RECORD_TYPE for a TLS control
+object type. The default creates a type, with structure tag
+@code{__emutls_object}, suitable for libgcc's emulated TLS function.
@end deftypefn
@deftypefn {Target Hook} tree TARGET_EMUTLS_VAR_INIT (tree @var{var}, tree @var{decl}, tree @var{tmpl_addr})
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index dfba947f51b..fb2d6d61043 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -9827,12 +9827,10 @@ Contains the prefix to be prepended to TLS initializer objects. The
default of @code{NULL} uses a target-specific prefix.
@end deftypevr
-@hook TARGET_EMUTLS_VAR_FIELDS
-Specifies a function that generates the FIELD_DECLs for a TLS control
-object type. @var{type} is the RECORD_TYPE the fields are for and
-@var{name} should be filled with the structure tag, if the default of
-@code{__emutls_object} is unsuitable. The default creates a type suitable
-for libgcc's emulated TLS function.
+@hook TARGET_EMUTLS_OBJECT_TYPE
+Specifies a function that generates the RECORD_TYPE for a TLS control
+object type. The default creates a type, with structure tag
+@code{__emutls_object}, suitable for libgcc's emulated TLS function.
@end deftypefn
@hook TARGET_EMUTLS_VAR_INIT
diff --git a/gcc/dse.c b/gcc/dse.c
index 080822292e4..629d2387923 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -572,20 +572,6 @@ static alloc_pool deferred_change_pool;
static deferred_change_t deferred_change_list = NULL;
-/* This are used to hold the alias sets of spill variables. Since
- these are never aliased and there may be a lot of them, it makes
- sense to treat them specially. This bitvector is only allocated in
- calls from dse_record_singleton_alias_set which currently is only
- made during reload1. So when dse is called before reload this
- mechanism does nothing. */
-
-static bitmap clear_alias_sets = NULL;
-
-/* The set of clear_alias_sets that have been disqualified because
- there are loads or stores using a different mode than the alias set
- was registered with. */
-static bitmap disqualified_clear_alias_sets = NULL;
-
/* The group that holds all of the clear_alias_sets. */
static group_info_t clear_alias_group;
@@ -599,8 +585,6 @@ struct clear_alias_mode_holder
enum machine_mode mode;
};
-static alloc_pool clear_alias_mode_pool;
-
/* This is true except if cfun->stdarg -- i.e. we cannot do
this for vararg functions because they play games with the frame. */
static bool stores_off_frame_dead_at_return;
@@ -788,10 +772,7 @@ dse_step0 (void)
init_alias_analysis ();
- if (clear_alias_sets)
- clear_alias_group = get_group_info (NULL);
- else
- clear_alias_group = NULL;
+ clear_alias_group = NULL;
}
@@ -1189,39 +1170,6 @@ canon_address (rtx mem,
rtx expanded_address, address;
int expanded;
- /* Make sure that cselib is has initialized all of the operands of
- the address before asking it to do the subst. */
-
- if (clear_alias_sets)
- {
- /* If this is a spill, do not do any further processing. */
- alias_set_type alias_set = MEM_ALIAS_SET (mem);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "found alias set %d\n", (int) alias_set);
- if (bitmap_bit_p (clear_alias_sets, alias_set))
- {
- struct clear_alias_mode_holder *entry
- = clear_alias_set_lookup (alias_set);
-
- /* If the modes do not match, we cannot process this set. */
- if (entry->mode != GET_MODE (mem))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "disqualifying alias set %d, (%s) != (%s)\n",
- (int) alias_set, GET_MODE_NAME (entry->mode),
- GET_MODE_NAME (GET_MODE (mem)));
-
- bitmap_set_bit (disqualified_clear_alias_sets, alias_set);
- return false;
- }
-
- *alias_set_out = alias_set;
- *group_id = clear_alias_group->id;
- return true;
- }
- }
-
*alias_set_out = 0;
cselib_lookup (mem_address, address_mode, 1, GET_MODE (mem));
@@ -2993,47 +2941,6 @@ dse_step2_nospill (void)
}
-/* Init the offset tables for the spill case. */
-
-static bool
-dse_step2_spill (void)
-{
- unsigned int j;
- group_info_t group = clear_alias_group;
- bitmap_iterator bi;
-
- /* Position 0 is unused because 0 is used in the maps to mean
- unused. */
- current_position = 1;
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- bitmap_print (dump_file, clear_alias_sets,
- "clear alias sets ", "\n");
- bitmap_print (dump_file, disqualified_clear_alias_sets,
- "disqualified clear alias sets ", "\n");
- }
-
- memset (group->offset_map_n, 0, sizeof(int) * group->offset_map_size_n);
- memset (group->offset_map_p, 0, sizeof(int) * group->offset_map_size_p);
- bitmap_clear (group->group_kill);
-
- /* Remove the disqualified positions from the store2_p set. */
- bitmap_and_compl_into (group->store2_p, disqualified_clear_alias_sets);
-
- /* We do not need to process the store2_n set because
- alias_sets are always positive. */
- EXECUTE_IF_SET_IN_BITMAP (group->store2_p, 0, j, bi)
- {
- bitmap_set_bit (group->group_kill, current_position);
- group->offset_map_p[j] = current_position++;
- group->process_globally = true;
- }
-
- return current_position != 1;
-}
-
-
/*----------------------------------------------------------------------------
Third step.
@@ -3690,72 +3597,6 @@ dse_step5_nospill (void)
}
-static void
-dse_step5_spill (void)
-{
- basic_block bb;
- FOR_EACH_BB (bb)
- {
- bb_info_t bb_info = bb_table[bb->index];
- insn_info_t insn_info = bb_info->last_insn;
- bitmap v = bb_info->out;
-
- while (insn_info)
- {
- bool deleted = false;
- /* There may have been code deleted by the dce pass run before
- this phase. */
- if (insn_info->insn
- && INSN_P (insn_info->insn)
- && (!insn_info->cannot_delete)
- && (!bitmap_empty_p (v)))
- {
- /* Try to delete the current insn. */
- store_info_t store_info = insn_info->store_rec;
- deleted = true;
-
- while (store_info)
- {
- if (store_info->alias_set)
- {
- int index = get_bitmap_index (clear_alias_group,
- store_info->alias_set);
- if (index == 0 || !bitmap_bit_p (v, index))
- {
- deleted = false;
- break;
- }
- }
- else
- deleted = false;
- store_info = store_info->next;
- }
- if (deleted && dbg_cnt (dse)
- && check_for_inc_dec_1 (insn_info))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Spill deleting insn %d\n",
- INSN_UID (insn_info->insn));
- delete_insn (insn_info->insn);
- spill_deleted++;
- insn_info->insn = NULL;
- }
- }
-
- if (insn_info->insn
- && INSN_P (insn_info->insn)
- && (!deleted))
- {
- scan_stores_spill (insn_info->store_rec, v, NULL);
- scan_reads_spill (insn_info->read_rec, v, NULL);
- }
-
- insn_info = insn_info->prev_insn;
- }
- }
-}
-
-
/*----------------------------------------------------------------------------
Sixth step.
@@ -3819,14 +3660,6 @@ dse_step7 (void)
bitmap_obstack_release (&dse_bitmap_obstack);
obstack_free (&dse_obstack, NULL);
- if (clear_alias_sets)
- {
- BITMAP_FREE (clear_alias_sets);
- BITMAP_FREE (disqualified_clear_alias_sets);
- free_alloc_pool (clear_alias_mode_pool);
- htab_delete (clear_alias_mode_table);
- }
-
end_alias_analysis ();
free (bb_table);
rtx_group_table.dispose ();
@@ -3852,8 +3685,6 @@ dse_step7 (void)
static unsigned int
rest_of_handle_dse (void)
{
- bool did_global = false;
-
df_set_flags (DF_DEFER_INSN_RESCAN);
/* Need the notes since we must track live hardregs in the forwards
@@ -3868,7 +3699,6 @@ rest_of_handle_dse (void)
{
df_set_flags (DF_LR_RUN_DCE);
df_analyze ();
- did_global = true;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "doing global processing\n");
dse_step3 (false);
@@ -3876,26 +3706,6 @@ rest_of_handle_dse (void)
dse_step5_nospill ();
}
- /* For the instance of dse that runs after reload, we make a special
- pass to process the spills. These are special in that they are
- totally transparent, i.e, there is no aliasing issues that need
- to be considered. This means that the wild reads that kill
- everything else do not apply here. */
- if (clear_alias_sets && dse_step2_spill ())
- {
- if (!did_global)
- {
- df_set_flags (DF_LR_RUN_DCE);
- df_analyze ();
- }
- did_global = true;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "doing global spill processing\n");
- dse_step3 (true);
- dse_step4 ();
- dse_step5_spill ();
- }
-
dse_step6 ();
dse_step7 ();
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 9f0a594183a..29779d6ad6a 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "dwarf2out.h"
#include "dwarf2asm.h"
#include "ggc.h"
+#include "hash-table.h"
#include "tm_p.h"
#include "target.h"
#include "common/common-target.h"
@@ -153,10 +154,33 @@ typedef struct
typedef dw_trace_info *dw_trace_info_ref;
+/* Hashtable helpers. */
+
+struct trace_info_hasher : typed_noop_remove <dw_trace_info>
+{
+ typedef dw_trace_info value_type;
+ typedef dw_trace_info compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+trace_info_hasher::hash (const value_type *ti)
+{
+ return INSN_UID (ti->head);
+}
+
+inline bool
+trace_info_hasher::equal (const value_type *a, const compare_type *b)
+{
+ return a->head == b->head;
+}
+
+
/* The variables making up the pseudo-cfg, as described above. */
static vec<dw_trace_info> trace_info;
static vec<dw_trace_info_ref> trace_work_list;
-static htab_t trace_index;
+static hash_table <trace_info_hasher> trace_index;
/* A vector of call frame insns for the CIE. */
cfi_vec cie_cfi_vec;
@@ -275,28 +299,12 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
}
-static hashval_t
-dw_trace_info_hash (const void *ptr)
-{
- const dw_trace_info *ti = (const dw_trace_info *) ptr;
- return INSN_UID (ti->head);
-}
-
-static int
-dw_trace_info_eq (const void *ptr_a, const void *ptr_b)
-{
- const dw_trace_info *a = (const dw_trace_info *) ptr_a;
- const dw_trace_info *b = (const dw_trace_info *) ptr_b;
- return a->head == b->head;
-}
-
static dw_trace_info *
get_trace_info (rtx insn)
{
dw_trace_info dummy;
dummy.head = insn;
- return (dw_trace_info *)
- htab_find_with_hash (trace_index, &dummy, INSN_UID (insn));
+ return trace_index.find_with_hash (&dummy, INSN_UID (insn));
}
static bool
@@ -2744,22 +2752,20 @@ create_pseudo_cfg (void)
/* Create the trace index after we've finished building trace_info,
avoiding stale pointer problems due to reallocation. */
- trace_index = htab_create (trace_info.length (),
- dw_trace_info_hash, dw_trace_info_eq, NULL);
+ trace_index.create (trace_info.length ());
dw_trace_info *tp;
FOR_EACH_VEC_ELT (trace_info, i, tp)
{
- void **slot;
+ dw_trace_info **slot;
if (dump_file)
fprintf (dump_file, "Creating trace %u : start at %s %d%s\n", i,
rtx_name[(int) GET_CODE (tp->head)], INSN_UID (tp->head),
tp->switch_sections ? " (section switch)" : "");
- slot = htab_find_slot_with_hash (trace_index, tp,
- INSN_UID (tp->head), INSERT);
+ slot = trace_index.find_slot_with_hash (tp, INSN_UID (tp->head), INSERT);
gcc_assert (*slot == NULL);
- *slot = (void *) tp;
+ *slot = tp;
}
}
@@ -2908,8 +2914,7 @@ execute_dwarf2_frame (void)
}
trace_info.release ();
- htab_delete (trace_index);
- trace_index = NULL;
+ trace_index.dispose ();
return 0;
}
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 8cf3b767f9f..12d8578cb9e 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -84,7 +84,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "common/common-target.h"
#include "langhooks.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "cgraph.h"
#include "input.h"
#include "gimple.h"
@@ -3015,17 +3015,9 @@ static dw_die_ref remove_child_or_replace_with_skeleton (dw_die_ref,
dw_die_ref,
dw_die_ref);
static void break_out_comdat_types (dw_die_ref);
-static dw_die_ref copy_ancestor_tree (dw_die_ref, dw_die_ref, htab_t);
-static void copy_decls_walk (dw_die_ref, dw_die_ref, htab_t);
static void copy_decls_for_unworthy_types (dw_die_ref);
-static hashval_t htab_cu_hash (const void *);
-static int htab_cu_eq (const void *, const void *);
-static void htab_cu_del (void *);
-static int check_duplicate_cu (dw_die_ref, htab_t, unsigned *);
-static void record_comdat_symbol_number (dw_die_ref, htab_t, unsigned);
static void add_sibling_attributes (dw_die_ref);
-static void build_abbrev_table (dw_die_ref, htab_t);
static void output_location_lists (dw_die_ref);
static int constant_size (unsigned HOST_WIDE_INT);
static unsigned long size_of_die (dw_die_ref);
@@ -6489,31 +6481,34 @@ struct cu_hash_table_entry
struct cu_hash_table_entry *next;
};
-/* Routines to manipulate hash table of CUs. */
-static hashval_t
-htab_cu_hash (const void *of)
+/* Helpers to manipulate hash table of CUs. */
+
+struct cu_hash_table_entry_hasher
{
- const struct cu_hash_table_entry *const entry =
- (const struct cu_hash_table_entry *) of;
+ typedef cu_hash_table_entry value_type;
+ typedef die_struct compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+inline hashval_t
+cu_hash_table_entry_hasher::hash (const value_type *entry)
+{
return htab_hash_string (entry->cu->die_id.die_symbol);
}
-static int
-htab_cu_eq (const void *of1, const void *of2)
+inline bool
+cu_hash_table_entry_hasher::equal (const value_type *entry1,
+ const compare_type *entry2)
{
- const struct cu_hash_table_entry *const entry1 =
- (const struct cu_hash_table_entry *) of1;
- const struct die_struct *const entry2 = (const struct die_struct *) of2;
-
return !strcmp (entry1->cu->die_id.die_symbol, entry2->die_id.die_symbol);
}
-static void
-htab_cu_del (void *what)
+inline void
+cu_hash_table_entry_hasher::remove (value_type *entry)
{
- struct cu_hash_table_entry *next,
- *entry = (struct cu_hash_table_entry *) what;
+ struct cu_hash_table_entry *next;
while (entry)
{
@@ -6523,19 +6518,21 @@ htab_cu_del (void *what)
}
}
+typedef hash_table <cu_hash_table_entry_hasher> cu_hash_type;
+
/* Check whether we have already seen this CU and set up SYM_NUM
accordingly. */
static int
-check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num)
+check_duplicate_cu (dw_die_ref cu, cu_hash_type htable, unsigned int *sym_num)
{
struct cu_hash_table_entry dummy;
struct cu_hash_table_entry **slot, *entry, *last = &dummy;
dummy.max_comdat_num = 0;
- slot = (struct cu_hash_table_entry **)
- htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_id.die_symbol),
- INSERT);
+ slot = htable.find_slot_with_hash (cu,
+ htab_hash_string (cu->die_id.die_symbol),
+ INSERT);
entry = *slot;
for (; entry; last = entry, entry = entry->next)
@@ -6561,13 +6558,14 @@ check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num)
/* Record SYM_NUM to record of CU in HTABLE. */
static void
-record_comdat_symbol_number (dw_die_ref cu, htab_t htable, unsigned int sym_num)
+record_comdat_symbol_number (dw_die_ref cu, cu_hash_type htable,
+ unsigned int sym_num)
{
struct cu_hash_table_entry **slot, *entry;
- slot = (struct cu_hash_table_entry **)
- htab_find_slot_with_hash (htable, cu, htab_hash_string (cu->die_id.die_symbol),
- NO_INSERT);
+ slot = htable.find_slot_with_hash (cu,
+ htab_hash_string (cu->die_id.die_symbol),
+ NO_INSERT);
entry = *slot;
entry->max_comdat_num = sym_num;
@@ -6583,7 +6581,7 @@ break_out_includes (dw_die_ref die)
dw_die_ref c;
dw_die_ref unit = NULL;
limbo_die_node *node, **pnode;
- htab_t cu_hash_table;
+ cu_hash_type cu_hash_table;
c = die->die_child;
if (c) do {
@@ -6616,7 +6614,7 @@ break_out_includes (dw_die_ref die)
#endif
assign_symbol_names (die);
- cu_hash_table = htab_create (10, htab_cu_hash, htab_cu_eq, htab_cu_del);
+ cu_hash_table.create (10);
for (node = limbo_die_list, pnode = &limbo_die_list;
node;
node = node->next)
@@ -6636,7 +6634,7 @@ break_out_includes (dw_die_ref die)
comdat_symbol_number);
}
}
- htab_delete (cu_hash_table);
+ cu_hash_table.dispose ();
}
/* Return non-zero if this DIE is a declaration. */
@@ -6811,6 +6809,94 @@ clone_as_declaration (dw_die_ref die)
return clone;
}
+
+/* Structure to map a DIE in one CU to its copy in a comdat type unit. */
+
+struct decl_table_entry
+{
+ dw_die_ref orig;
+ dw_die_ref copy;
+};
+
+/* Helpers to manipulate hash table of copied declarations. */
+
+/* Hashtable helpers. */
+
+struct decl_table_entry_hasher : typed_free_remove <decl_table_entry>
+{
+ typedef decl_table_entry value_type;
+ typedef die_struct compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+decl_table_entry_hasher::hash (const value_type *entry)
+{
+ return htab_hash_pointer (entry->orig);
+}
+
+inline bool
+decl_table_entry_hasher::equal (const value_type *entry1,
+ const compare_type *entry2)
+{
+ return entry1->orig == entry2;
+}
+
+typedef hash_table <decl_table_entry_hasher> decl_hash_type;
+
+/* Copy DIE and its ancestors, up to, but not including, the compile unit
+ or type unit entry, to a new tree. Adds the new tree to UNIT and returns
+ a pointer to the copy of DIE. If DECL_TABLE is provided, it is used
+ to check if the ancestor has already been copied into UNIT. */
+
+static dw_die_ref
+copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table)
+{
+ dw_die_ref parent = die->die_parent;
+ dw_die_ref new_parent = unit;
+ dw_die_ref copy;
+ decl_table_entry **slot = NULL;
+ struct decl_table_entry *entry = NULL;
+
+ if (decl_table.is_created ())
+ {
+ /* Check if the entry has already been copied to UNIT. */
+ slot = decl_table.find_slot_with_hash (die, htab_hash_pointer (die),
+ INSERT);
+ if (*slot != HTAB_EMPTY_ENTRY)
+ {
+ entry = *slot;
+ return entry->copy;
+ }
+
+ /* Record in DECL_TABLE that DIE has been copied to UNIT. */
+ entry = XCNEW (struct decl_table_entry);
+ entry->orig = die;
+ entry->copy = NULL;
+ *slot = entry;
+ }
+
+ if (parent != NULL)
+ {
+ dw_die_ref spec = get_AT_ref (parent, DW_AT_specification);
+ if (spec != NULL)
+ parent = spec;
+ if (!is_unit_die (parent))
+ new_parent = copy_ancestor_tree (unit, parent, decl_table);
+ }
+
+ copy = clone_as_declaration (die);
+ add_child_die (new_parent, copy);
+
+ if (decl_table.is_created ())
+ {
+ /* Record the pointer to the copy. */
+ entry->copy = copy;
+ }
+
+ return copy;
+}
/* Copy the declaration context to the new type unit DIE. This includes
any surrounding namespace or type declarations. If the DIE has an
AT_specification attribute, it also includes attributes and children
@@ -6858,7 +6944,7 @@ copy_declaration_context (dw_die_ref unit, dw_die_ref die)
if (decl->die_parent != NULL
&& !is_unit_die (decl->die_parent))
{
- new_decl = copy_ancestor_tree (unit, decl, NULL);
+ new_decl = copy_ancestor_tree (unit, decl, decl_hash_type ());
if (new_decl != NULL)
{
remove_AT (new_decl, DW_AT_signature);
@@ -7057,106 +7143,16 @@ break_out_comdat_types (dw_die_ref die)
} while (next != NULL);
}
-/* Structure to map a DIE in one CU to its copy in a comdat type unit. */
-
-struct decl_table_entry
-{
- dw_die_ref orig;
- dw_die_ref copy;
-};
-
-/* Routines to manipulate hash table of copied declarations. */
-
-static hashval_t
-htab_decl_hash (const void *of)
-{
- const struct decl_table_entry *const entry =
- (const struct decl_table_entry *) of;
-
- return htab_hash_pointer (entry->orig);
-}
-
-static int
-htab_decl_eq (const void *of1, const void *of2)
-{
- const struct decl_table_entry *const entry1 =
- (const struct decl_table_entry *) of1;
- const struct die_struct *const entry2 = (const struct die_struct *) of2;
-
- return entry1->orig == entry2;
-}
-
-static void
-htab_decl_del (void *what)
-{
- struct decl_table_entry *entry = (struct decl_table_entry *) what;
-
- free (entry);
-}
-
-/* Copy DIE and its ancestors, up to, but not including, the compile unit
- or type unit entry, to a new tree. Adds the new tree to UNIT and returns
- a pointer to the copy of DIE. If DECL_TABLE is provided, it is used
- to check if the ancestor has already been copied into UNIT. */
-
-static dw_die_ref
-copy_ancestor_tree (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
-{
- dw_die_ref parent = die->die_parent;
- dw_die_ref new_parent = unit;
- dw_die_ref copy;
- void **slot = NULL;
- struct decl_table_entry *entry = NULL;
-
- if (decl_table)
- {
- /* Check if the entry has already been copied to UNIT. */
- slot = htab_find_slot_with_hash (decl_table, die,
- htab_hash_pointer (die), INSERT);
- if (*slot != HTAB_EMPTY_ENTRY)
- {
- entry = (struct decl_table_entry *) *slot;
- return entry->copy;
- }
-
- /* Record in DECL_TABLE that DIE has been copied to UNIT. */
- entry = XCNEW (struct decl_table_entry);
- entry->orig = die;
- entry->copy = NULL;
- *slot = entry;
- }
-
- if (parent != NULL)
- {
- dw_die_ref spec = get_AT_ref (parent, DW_AT_specification);
- if (spec != NULL)
- parent = spec;
- if (!is_unit_die (parent))
- new_parent = copy_ancestor_tree (unit, parent, decl_table);
- }
-
- copy = clone_as_declaration (die);
- add_child_die (new_parent, copy);
-
- if (decl_table != NULL)
- {
- /* Record the pointer to the copy. */
- entry->copy = copy;
- }
-
- return copy;
-}
-
/* Like clone_tree, but additionally enter all the children into
the hash table decl_table. */
static dw_die_ref
-clone_tree_hash (dw_die_ref die, htab_t decl_table)
+clone_tree_hash (dw_die_ref die, decl_hash_type decl_table)
{
dw_die_ref c;
dw_die_ref clone = clone_die (die);
struct decl_table_entry *entry;
- void **slot = htab_find_slot_with_hash (decl_table, die,
+ decl_table_entry **slot = decl_table.find_slot_with_hash (die,
htab_hash_pointer (die), INSERT);
/* Assert that DIE isn't in the hash table yet. If it would be there
before, the ancestors would be necessarily there as well, therefore
@@ -7178,7 +7174,7 @@ clone_tree_hash (dw_die_ref die, htab_t decl_table)
type_unit). */
static void
-copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
+copy_decls_walk (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table)
{
dw_die_ref c;
dw_attr_ref a;
@@ -7189,20 +7185,20 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
if (AT_class (a) == dw_val_class_die_ref)
{
dw_die_ref targ = AT_ref (a);
- void **slot;
+ decl_table_entry **slot;
struct decl_table_entry *entry;
if (targ->die_mark != 0 || targ->comdat_type_p)
continue;
- slot = htab_find_slot_with_hash (decl_table, targ,
- htab_hash_pointer (targ), INSERT);
+ slot = decl_table.find_slot_with_hash (targ, htab_hash_pointer (targ),
+ INSERT);
if (*slot != HTAB_EMPTY_ENTRY)
{
/* TARG has already been copied, so we just need to
modify the reference to point to the copy. */
- entry = (struct decl_table_entry *) *slot;
+ entry = *slot;
a->dw_attr_val.v.val_die_ref.die = entry->copy;
}
else
@@ -7269,12 +7265,12 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, htab_t decl_table)
static void
copy_decls_for_unworthy_types (dw_die_ref unit)
{
- htab_t decl_table;
+ decl_hash_type decl_table;
mark_dies (unit);
- decl_table = htab_create (10, htab_decl_hash, htab_decl_eq, htab_decl_del);
+ decl_table.create (10);
copy_decls_walk (unit, unit, decl_table);
- htab_delete (decl_table);
+ decl_table.dispose ();
unmark_dies (unit);
}
@@ -7329,37 +7325,42 @@ struct external_ref
unsigned n_refs;
};
-/* Hash an external_ref. */
+/* Hashtable helpers. */
-static hashval_t
-hash_external_ref (const void *p)
+struct external_ref_hasher : typed_free_remove <external_ref>
+{
+ typedef external_ref value_type;
+ typedef external_ref compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+external_ref_hasher::hash (const value_type *r)
{
- const struct external_ref *r = (const struct external_ref *)p;
return htab_hash_pointer (r->type);
}
-/* Compare external_refs. */
-
-static int
-external_ref_eq (const void *p1, const void *p2)
+inline bool
+external_ref_hasher::equal (const value_type *r1, const compare_type *r2)
{
- const struct external_ref *r1 = (const struct external_ref *)p1;
- const struct external_ref *r2 = (const struct external_ref *)p2;
return r1->type == r2->type;
}
+typedef hash_table <external_ref_hasher> external_ref_hash_type;
+
/* Return a pointer to the external_ref for references to DIE. */
static struct external_ref *
-lookup_external_ref (htab_t map, dw_die_ref die)
+lookup_external_ref (external_ref_hash_type map, dw_die_ref die)
{
struct external_ref ref, *ref_p;
- void ** slot;
+ external_ref **slot;
ref.type = die;
- slot = htab_find_slot (map, &ref, INSERT);
+ slot = map.find_slot (&ref, INSERT);
if (*slot != HTAB_EMPTY_ENTRY)
- return (struct external_ref *) *slot;
+ return *slot;
ref_p = XCNEW (struct external_ref);
ref_p->type = die;
@@ -7373,7 +7374,7 @@ lookup_external_ref (htab_t map, dw_die_ref die)
references, remember how many we've seen. */
static void
-optimize_external_refs_1 (dw_die_ref die, htab_t map)
+optimize_external_refs_1 (dw_die_ref die, external_ref_hash_type map)
{
dw_die_ref c;
dw_attr_ref a;
@@ -7406,17 +7407,17 @@ optimize_external_refs_1 (dw_die_ref die, htab_t map)
points to an external_ref, DATA is the CU we're processing. If we don't
already have a local stub, and we have multiple refs, build a stub. */
-static int
-build_local_stub (void **slot, void *data)
+int
+dwarf2_build_local_stub (external_ref **slot, dw_die_ref data)
{
- struct external_ref *ref_p = (struct external_ref *)*slot;
+ struct external_ref *ref_p = *slot;
if (ref_p->stub == NULL && ref_p->n_refs > 1 && !dwarf_strict)
{
/* We have multiple references to this type, so build a small stub.
Both of these forms are a bit dodgy from the perspective of the
DWARF standard, since technically they should have names. */
- dw_die_ref cu = (dw_die_ref) data;
+ dw_die_ref cu = data;
dw_die_ref type = ref_p->type;
dw_die_ref stub = NULL;
@@ -7444,12 +7445,13 @@ build_local_stub (void **slot, void *data)
them which will be applied in build_abbrev_table. This is useful because
references to local DIEs are smaller. */
-static htab_t
+static external_ref_hash_type
optimize_external_refs (dw_die_ref die)
{
- htab_t map = htab_create (10, hash_external_ref, external_ref_eq, free);
+ external_ref_hash_type map;
+ map.create (10);
optimize_external_refs_1 (die, map);
- htab_traverse (map, build_local_stub, die);
+ map.traverse <dw_die_ref, dwarf2_build_local_stub> (die);
return map;
}
@@ -7459,7 +7461,7 @@ optimize_external_refs (dw_die_ref die)
die are visited recursively. */
static void
-build_abbrev_table (dw_die_ref die, htab_t extern_map)
+build_abbrev_table (dw_die_ref die, external_ref_hash_type extern_map)
{
unsigned long abbrev_id;
unsigned int n_alloc;
@@ -8590,7 +8592,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty)
{
const char *secname, *oldsym;
char *tmp;
- htab_t extern_map;
+ external_ref_hash_type extern_map;
/* Unless we are outputting main CU, we may throw away empty ones. */
if (!output_if_empty && die->die_child == NULL)
@@ -8607,7 +8609,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty)
build_abbrev_table (die, extern_map);
- htab_delete (extern_map);
+ extern_map.dispose ();
/* Initialize the beginning DIE offset - and calculate sizes/offsets. */
next_die_offset = DWARF_COMPILE_UNIT_HEADER_SIZE;
@@ -8765,7 +8767,7 @@ output_comdat_type_unit (comdat_type_node *node)
#if defined (OBJECT_FORMAT_ELF)
tree comdat_key;
#endif
- htab_t extern_map;
+ external_ref_hash_type extern_map;
/* First mark all the DIEs in this CU so we know which get local refs. */
mark_dies (node->root_die);
@@ -8774,7 +8776,7 @@ output_comdat_type_unit (comdat_type_node *node)
build_abbrev_table (node->root_die, extern_map);
- htab_delete (extern_map);
+ extern_map.dispose ();
/* Initialize the beginning DIE offset - and calculate sizes/offsets. */
next_die_offset = DWARF_COMDAT_TYPE_UNIT_HEADER_SIZE;
@@ -21230,26 +21232,31 @@ dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
}
}
-/* Routines to manipulate hash table of CUs. */
+/* Helpers to manipulate hash table of CUs. */
-static hashval_t
-htab_macinfo_hash (const void *of)
+struct macinfo_entry_hasher : typed_noop_remove <macinfo_entry>
{
- const macinfo_entry *const entry =
- (const macinfo_entry *) of;
+ typedef macinfo_entry value_type;
+ typedef macinfo_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+inline hashval_t
+macinfo_entry_hasher::hash (const value_type *entry)
+{
return htab_hash_string (entry->info);
}
-static int
-htab_macinfo_eq (const void *of1, const void *of2)
+inline bool
+macinfo_entry_hasher::equal (const value_type *entry1,
+ const compare_type *entry2)
{
- const macinfo_entry *const entry1 = (const macinfo_entry *) of1;
- const macinfo_entry *const entry2 = (const macinfo_entry *) of2;
-
return !strcmp (entry1->info, entry2->info);
}
+typedef hash_table <macinfo_entry_hasher> macinfo_hash_type;
+
/* Output a single .debug_macinfo entry. */
static void
@@ -21338,7 +21345,7 @@ output_macinfo_op (macinfo_entry *ref)
static unsigned
optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
- htab_t *macinfo_htab)
+ macinfo_hash_type *macinfo_htab)
{
macinfo_entry *first, *second, *cur, *inc;
char linebuf[sizeof (HOST_WIDE_INT) * 3 + 1];
@@ -21347,7 +21354,7 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
char *grp_name, *tail;
const char *base;
unsigned int i, count, encoded_filename_len, linebuf_len;
- void **slot;
+ macinfo_entry **slot;
first = &(*macinfo_table)[idx];
second = &(*macinfo_table)[idx + 1];
@@ -21425,17 +21432,17 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
inc->code = DW_MACRO_GNU_transparent_include;
inc->lineno = 0;
inc->info = ggc_strdup (grp_name);
- if (*macinfo_htab == NULL)
- *macinfo_htab = htab_create (10, htab_macinfo_hash, htab_macinfo_eq, NULL);
+ if (!macinfo_htab->is_created ())
+ macinfo_htab->create (10);
/* Avoid emitting duplicates. */
- slot = htab_find_slot (*macinfo_htab, inc, INSERT);
+ slot = macinfo_htab->find_slot (inc, INSERT);
if (*slot != NULL)
{
inc->code = 0;
inc->info = NULL;
/* If such an entry has been used before, just emit
a DW_MACRO_GNU_transparent_include op. */
- inc = (macinfo_entry *) *slot;
+ inc = *slot;
output_macinfo_op (inc);
/* And clear all macinfo_entry in the range to avoid emitting them
in the second pass. */
@@ -21448,7 +21455,7 @@ optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
else
{
*slot = inc;
- inc->lineno = htab_elements (*macinfo_htab);
+ inc->lineno = macinfo_htab->elements ();
output_macinfo_op (inc);
}
return count;
@@ -21499,7 +21506,7 @@ output_macinfo (void)
unsigned long length = vec_safe_length (macinfo_table);
macinfo_entry *ref;
vec<macinfo_entry, va_gc> *files = NULL;
- htab_t macinfo_htab = NULL;
+ macinfo_hash_type macinfo_htab;
if (! length)
return;
@@ -21572,10 +21579,10 @@ output_macinfo (void)
ref->code = 0;
}
- if (macinfo_htab == NULL)
+ if (!macinfo_htab.is_created ())
return;
- htab_delete (macinfo_htab);
+ macinfo_htab.dispose ();
/* If any DW_MACRO_GNU_transparent_include were used, on those
DW_MACRO_GNU_transparent_include entries terminate the
@@ -22310,24 +22317,28 @@ file_table_relative_p (void ** slot, void *param)
return 1;
}
-/* Routines to manipulate hash table of comdat type units. */
+/* Helpers to manipulate hash table of comdat type units. */
-static hashval_t
-htab_ct_hash (const void *of)
+struct comdat_type_hasher : typed_noop_remove <comdat_type_node>
{
- hashval_t h;
- const comdat_type_node *const type_node = (const comdat_type_node *) of;
+ typedef comdat_type_node value_type;
+ typedef comdat_type_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+inline hashval_t
+comdat_type_hasher::hash (const value_type *type_node)
+{
+ hashval_t h;
memcpy (&h, type_node->signature, sizeof (h));
return h;
}
-static int
-htab_ct_eq (const void *of1, const void *of2)
+inline bool
+comdat_type_hasher::equal (const value_type *type_node_1,
+ const compare_type *type_node_2)
{
- const comdat_type_node *const type_node_1 = (const comdat_type_node *) of1;
- const comdat_type_node *const type_node_2 = (const comdat_type_node *) of2;
-
return (! memcmp (type_node_1->signature, type_node_2->signature,
DWARF_TYPE_SIGNATURE_SIZE));
}
@@ -23391,21 +23402,29 @@ compare_locs (dw_loc_descr_ref x, dw_loc_descr_ref y)
return x == NULL && y == NULL;
}
+/* Hashtable helpers. */
+
+struct loc_list_hasher : typed_noop_remove <dw_loc_list_struct>
+{
+ typedef dw_loc_list_struct value_type;
+ typedef dw_loc_list_struct compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
/* Return precomputed hash of location list X. */
-static hashval_t
-loc_list_hash (const void *x)
+inline hashval_t
+loc_list_hasher::hash (const value_type *x)
{
- return ((const struct dw_loc_list_struct *) x)->hash;
+ return x->hash;
}
-/* Return 1 if location lists X and Y are the same. */
+/* Return true if location lists A and B are the same. */
-static int
-loc_list_eq (const void *x, const void *y)
+inline bool
+loc_list_hasher::equal (const value_type *a, const compare_type *b)
{
- const struct dw_loc_list_struct *a = (const struct dw_loc_list_struct *) x;
- const struct dw_loc_list_struct *b = (const struct dw_loc_list_struct *) y;
if (a == b)
return 1;
if (a->hash != b->hash)
@@ -23420,16 +23439,19 @@ loc_list_eq (const void *x, const void *y)
return a == NULL && b == NULL;
}
+typedef hash_table <loc_list_hasher> loc_list_hash_type;
+
+
/* Recursively optimize location lists referenced from DIE
children and share them whenever possible. */
static void
-optimize_location_lists_1 (dw_die_ref die, htab_t htab)
+optimize_location_lists_1 (dw_die_ref die, loc_list_hash_type htab)
{
dw_die_ref c;
dw_attr_ref a;
unsigned ix;
- void **slot;
+ dw_loc_list_struct **slot;
FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
if (AT_class (a) == dw_val_class_loc_list)
@@ -23438,12 +23460,11 @@ optimize_location_lists_1 (dw_die_ref die, htab_t htab)
/* TODO: perform some optimizations here, before hashing
it and storing into the hash table. */
hash_loc_list (list);
- slot = htab_find_slot_with_hash (htab, list, list->hash,
- INSERT);
+ slot = htab.find_slot_with_hash (list, list->hash, INSERT);
if (*slot == NULL)
- *slot = (void *) list;
+ *slot = list;
else
- a->dw_attr_val.v.val_loc_list = (dw_loc_list_ref) *slot;
+ a->dw_attr_val.v.val_loc_list = *slot;
}
FOR_EACH_CHILD (die, c, optimize_location_lists_1 (c, htab));
@@ -23488,9 +23509,10 @@ index_location_lists (dw_die_ref die)
static void
optimize_location_lists (dw_die_ref die)
{
- htab_t htab = htab_create (500, loc_list_hash, loc_list_eq, NULL);
+ loc_list_hash_type htab;
+ htab.create (500);
optimize_location_lists_1 (die, htab);
- htab_delete (htab);
+ htab.dispose ();
}
/* Output stuff that dwarf requires at the end of every file,
@@ -23501,7 +23523,7 @@ dwarf2out_finish (const char *filename)
{
limbo_die_node *node, *next_node;
comdat_type_node *ctnode;
- htab_t comdat_type_table;
+ hash_table <comdat_type_hasher> comdat_type_table;
unsigned int i;
dw_die_ref main_comp_unit_die;
@@ -23761,10 +23783,10 @@ dwarf2out_finish (const char *filename)
for (node = limbo_die_list; node; node = node->next)
output_comp_unit (node->die, 0);
- comdat_type_table = htab_create (100, htab_ct_hash, htab_ct_eq, NULL);
+ comdat_type_table.create (100);
for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
{
- void **slot = htab_find_slot (comdat_type_table, ctnode, INSERT);
+ comdat_type_node **slot = comdat_type_table.find_slot (ctnode, INSERT);
/* Don't output duplicate types. */
if (*slot != HTAB_EMPTY_ENTRY)
@@ -23782,7 +23804,7 @@ dwarf2out_finish (const char *filename)
output_comdat_type_unit (ctnode);
*slot = ctnode;
}
- htab_delete (comdat_type_table);
+ comdat_type_table.dispose ();
/* The AT_pubnames attribute needs to go in all skeleton dies, including
both the main_cu and all skeleton TUs. Making this call unconditional
diff --git a/gcc/except.c b/gcc/except.c
index 4e85f731837..b25207b4c87 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -128,7 +128,7 @@ along with GCC; see the file COPYING3. If not see
#include "dwarf2out.h"
#include "dwarf2.h"
#include "toplev.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "intl.h"
#include "ggc.h"
#include "tm_p.h"
@@ -166,6 +166,49 @@ struct GTY(()) call_site_record_d
rtx landing_pad;
int action;
};
+
+/* In the following structure and associated functions,
+ we represent entries in the action table as 1-based indices.
+ Special cases are:
+
+ 0: null action record, non-null landing pad; implies cleanups
+ -1: null action record, null landing pad; implies no action
+ -2: no call-site entry; implies must_not_throw
+ -3: we have yet to process outer regions
+
+ Further, no special cases apply to the "next" field of the record.
+ For next, 0 means end of list. */
+
+struct action_record
+{
+ int offset;
+ int filter;
+ int next;
+};
+
+/* Hashtable helpers. */
+
+struct action_record_hasher : typed_free_remove <action_record>
+{
+ typedef action_record value_type;
+ typedef action_record compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+action_record_hasher::hash (const value_type *entry)
+{
+ return entry->next * 1009 + entry->filter;
+}
+
+inline bool
+action_record_hasher::equal (const value_type *entry, const compare_type *data)
+{
+ return entry->filter == data->filter && entry->next == data->next;
+}
+
+typedef hash_table <action_record_hasher> action_hash_type;
static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
eh_landing_pad *);
@@ -173,18 +216,9 @@ static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
static int t2r_eq (const void *, const void *);
static hashval_t t2r_hash (const void *);
-static int ttypes_filter_eq (const void *, const void *);
-static hashval_t ttypes_filter_hash (const void *);
-static int ehspec_filter_eq (const void *, const void *);
-static hashval_t ehspec_filter_hash (const void *);
-static int add_ttypes_entry (htab_t, tree);
-static int add_ehspec_entry (htab_t, htab_t, tree);
static void dw2_build_landing_pads (void);
-static int action_record_eq (const void *, const void *);
-static hashval_t action_record_hash (const void *);
-static int add_action_record (htab_t, int, int);
-static int collect_one_action_chain (htab_t, eh_region);
+static int collect_one_action_chain (action_hash_type, eh_region);
static int add_call_site (rtx, int, int);
static void push_uleb128 (vec<uchar, va_gc> **, unsigned int);
@@ -687,46 +721,60 @@ struct ttypes_filter {
int filter;
};
+/* Helper for ttypes_filter hashing. */
+
+struct ttypes_filter_hasher : typed_free_remove <ttypes_filter>
+{
+ typedef ttypes_filter value_type;
+ typedef tree_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
/* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
(a tree) for a @TTypes type node we are thinking about adding. */
-static int
-ttypes_filter_eq (const void *pentry, const void *pdata)
+inline bool
+ttypes_filter_hasher::equal (const value_type *entry, const compare_type *data)
{
- const struct ttypes_filter *const entry
- = (const struct ttypes_filter *) pentry;
- const_tree const data = (const_tree) pdata;
-
return entry->t == data;
}
-static hashval_t
-ttypes_filter_hash (const void *pentry)
+inline hashval_t
+ttypes_filter_hasher::hash (const value_type *entry)
{
- const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
return TREE_HASH (entry->t);
}
+typedef hash_table <ttypes_filter_hasher> ttypes_hash_type;
+
+
+/* Helper for ehspec hashing. */
+
+struct ehspec_hasher : typed_free_remove <ttypes_filter>
+{
+ typedef ttypes_filter value_type;
+ typedef ttypes_filter compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
/* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
exception specification list we are thinking about adding. */
/* ??? Currently we use the type lists in the order given. Someone
should put these in some canonical order. */
-static int
-ehspec_filter_eq (const void *pentry, const void *pdata)
+inline bool
+ehspec_hasher::equal (const value_type *entry, const compare_type *data)
{
- const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
- const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
-
return type_list_equal (entry->t, data->t);
}
/* Hash function for exception specification lists. */
-static hashval_t
-ehspec_filter_hash (const void *pentry)
+inline hashval_t
+ehspec_hasher::hash (const value_type *entry)
{
- const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
hashval_t h = 0;
tree list;
@@ -735,16 +783,19 @@ ehspec_filter_hash (const void *pentry)
return h;
}
+typedef hash_table <ehspec_hasher> ehspec_hash_type;
+
+
/* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
to speed up the search. Return the filter value to be used. */
static int
-add_ttypes_entry (htab_t ttypes_hash, tree type)
+add_ttypes_entry (ttypes_hash_type ttypes_hash, tree type)
{
struct ttypes_filter **slot, *n;
- slot = (struct ttypes_filter **)
- htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT);
+ slot = ttypes_hash.find_slot_with_hash (type, (hashval_t) TREE_HASH (type),
+ INSERT);
if ((n = *slot) == NULL)
{
@@ -765,14 +816,14 @@ add_ttypes_entry (htab_t ttypes_hash, tree type)
to speed up the search. Return the filter value to be used. */
static int
-add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
+add_ehspec_entry (ehspec_hash_type ehspec_hash, ttypes_hash_type ttypes_hash,
+ tree list)
{
struct ttypes_filter **slot, *n;
struct ttypes_filter dummy;
dummy.t = list;
- slot = (struct ttypes_filter **)
- htab_find_slot (ehspec_hash, &dummy, INSERT);
+ slot = ehspec_hash.find_slot (&dummy, INSERT);
if ((n = *slot) == NULL)
{
@@ -821,7 +872,8 @@ void
assign_filter_values (void)
{
int i;
- htab_t ttypes, ehspec;
+ ttypes_hash_type ttypes;
+ ehspec_hash_type ehspec;
eh_region r;
eh_catch c;
@@ -831,8 +883,8 @@ assign_filter_values (void)
else
vec_alloc (cfun->eh->ehspec_data.other, 64);
- ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
- ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
+ ttypes.create (31);
+ ehspec.create (31);
for (i = 1; vec_safe_iterate (cfun->eh->region_array, i, &r); ++i)
{
@@ -886,8 +938,8 @@ assign_filter_values (void)
}
}
- htab_delete (ttypes);
- htab_delete (ehspec);
+ ttypes.dispose ();
+ ehspec.dispose ();
}
/* Emit SEQ into basic block just before INSN (that is assumed to be
@@ -1009,12 +1061,12 @@ static vec<int> sjlj_lp_call_site_index;
static int
sjlj_assign_call_site_values (void)
{
- htab_t ar_hash;
+ action_hash_type ar_hash;
int i, disp_index;
eh_landing_pad lp;
vec_alloc (crtl->eh.action_record_data, 64);
- ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
+ ar_hash.create (31);
disp_index = 0;
call_site_base = 1;
@@ -1043,7 +1095,7 @@ sjlj_assign_call_site_values (void)
disp_index++;
}
- htab_delete (ar_hash);
+ ar_hash.dispose ();
return disp_index;
}
@@ -2236,47 +2288,14 @@ expand_builtin_extend_pointer (tree addr_tree)
return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
}
-/* In the following functions, we represent entries in the action table
- as 1-based indices. Special cases are:
-
- 0: null action record, non-null landing pad; implies cleanups
- -1: null action record, null landing pad; implies no action
- -2: no call-site entry; implies must_not_throw
- -3: we have yet to process outer regions
-
- Further, no special cases apply to the "next" field of the record.
- For next, 0 means end of list. */
-
-struct action_record
-{
- int offset;
- int filter;
- int next;
-};
-
-static int
-action_record_eq (const void *pentry, const void *pdata)
-{
- const struct action_record *entry = (const struct action_record *) pentry;
- const struct action_record *data = (const struct action_record *) pdata;
- return entry->filter == data->filter && entry->next == data->next;
-}
-
-static hashval_t
-action_record_hash (const void *pentry)
-{
- const struct action_record *entry = (const struct action_record *) pentry;
- return entry->next * 1009 + entry->filter;
-}
-
static int
-add_action_record (htab_t ar_hash, int filter, int next)
+add_action_record (action_hash_type ar_hash, int filter, int next)
{
struct action_record **slot, *new_ar, tmp;
tmp.filter = filter;
tmp.next = next;
- slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
+ slot = ar_hash.find_slot (&tmp, INSERT);
if ((new_ar = *slot) == NULL)
{
@@ -2301,7 +2320,7 @@ add_action_record (htab_t ar_hash, int filter, int next)
}
static int
-collect_one_action_chain (htab_t ar_hash, eh_region region)
+collect_one_action_chain (action_hash_type ar_hash, eh_region region)
{
int next;
@@ -2430,7 +2449,7 @@ static unsigned int
convert_to_eh_region_ranges (void)
{
rtx insn, iter, note;
- htab_t ar_hash;
+ action_hash_type ar_hash;
int last_action = -3;
rtx last_action_insn = NULL_RTX;
rtx last_landing_pad = NULL_RTX;
@@ -2444,7 +2463,7 @@ convert_to_eh_region_ranges (void)
vec_alloc (crtl->eh.action_record_data, 64);
- ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
+ ar_hash.create (31);
for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
if (INSN_P (iter))
@@ -2581,7 +2600,7 @@ convert_to_eh_region_ranges (void)
call_site_base = saved_call_site_base;
- htab_delete (ar_hash);
+ ar_hash.dispose ();
return 0;
}
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 0c176f69f48..3482f8faf62 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -158,7 +158,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "obstack.h"
#include "tree-pass.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "df.h"
#include "dbgcnt.h"
#include "target.h"
@@ -359,8 +359,34 @@ struct ls_expr
/* Head of the list of load/store memory refs. */
static struct ls_expr * pre_ldst_mems = NULL;
+struct pre_ldst_expr_hasher : typed_noop_remove <ls_expr>
+{
+ typedef ls_expr value_type;
+ typedef value_type compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hashtable helpers. */
+inline hashval_t
+pre_ldst_expr_hasher::hash (const value_type *x)
+{
+ int do_not_record_p = 0;
+ return
+ hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
+}
+
+static int expr_equiv_p (const_rtx, const_rtx);
+
+inline bool
+pre_ldst_expr_hasher::equal (const value_type *ptr1,
+ const compare_type *ptr2)
+{
+ return expr_equiv_p (ptr1->pattern, ptr2->pattern);
+}
+
/* Hashtable for the load/store memory refs. */
-static htab_t pre_ldst_table = NULL;
+static hash_table <pre_ldst_expr_hasher> pre_ldst_table;
/* Bitmap containing one bit for each register in the program.
Used when performing GCSE to track which registers have been set since
@@ -447,7 +473,6 @@ static int oprs_available_p (const_rtx, const_rtx);
static void insert_expr_in_table (rtx, enum machine_mode, rtx, int, int, int,
struct hash_table_d *);
static unsigned int hash_expr (const_rtx, enum machine_mode, int *, int);
-static int expr_equiv_p (const_rtx, const_rtx);
static void record_last_reg_set_info (rtx, int);
static void record_last_mem_set_info (rtx);
static void record_last_set_info (rtx, const_rtx, void *);
@@ -3663,23 +3688,6 @@ one_code_hoisting_pass (void)
load towards the exit, and we end up with no loads or stores of 'i'
in the loop. */
-static hashval_t
-pre_ldst_expr_hash (const void *p)
-{
- int do_not_record_p = 0;
- const struct ls_expr *const x = (const struct ls_expr *) p;
- return
- hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
-}
-
-static int
-pre_ldst_expr_eq (const void *p1, const void *p2)
-{
- const struct ls_expr *const ptr1 = (const struct ls_expr *) p1,
- *const ptr2 = (const struct ls_expr *) p2;
- return expr_equiv_p (ptr1->pattern, ptr2->pattern);
-}
-
/* This will search the ldst list for a matching expression. If it
doesn't find one, we create one and initialize it. */
@@ -3689,16 +3697,16 @@ ldst_entry (rtx x)
int do_not_record_p = 0;
struct ls_expr * ptr;
unsigned int hash;
- void **slot;
+ ls_expr **slot;
struct ls_expr e;
hash = hash_rtx (x, GET_MODE (x), &do_not_record_p,
NULL, /*have_reg_qty=*/false);
e.pattern = x;
- slot = htab_find_slot_with_hash (pre_ldst_table, &e, hash, INSERT);
+ slot = pre_ldst_table.find_slot_with_hash (&e, hash, INSERT);
if (*slot)
- return (struct ls_expr *)*slot;
+ return *slot;
ptr = XNEW (struct ls_expr);
@@ -3734,9 +3742,8 @@ free_ldst_entry (struct ls_expr * ptr)
static void
free_ld_motion_mems (void)
{
- if (pre_ldst_table)
- htab_delete (pre_ldst_table);
- pre_ldst_table = NULL;
+ if (pre_ldst_table.is_created ())
+ pre_ldst_table.dispose ();
while (pre_ldst_mems)
{
@@ -3791,14 +3798,14 @@ static struct ls_expr *
find_rtx_in_ldst (rtx x)
{
struct ls_expr e;
- void **slot;
- if (!pre_ldst_table)
+ ls_expr **slot;
+ if (!pre_ldst_table.is_created ())
return NULL;
e.pattern = x;
- slot = htab_find_slot (pre_ldst_table, &e, NO_INSERT);
- if (!slot || ((struct ls_expr *)*slot)->invalid)
+ slot = pre_ldst_table.find_slot (&e, NO_INSERT);
+ if (!slot || (*slot)->invalid)
return NULL;
- return (struct ls_expr *) *slot;
+ return *slot;
}
/* Load Motion for loads which only kill themselves. */
@@ -3886,8 +3893,7 @@ compute_ld_motion_mems (void)
rtx insn;
pre_ldst_mems = NULL;
- pre_ldst_table
- = htab_create (13, pre_ldst_expr_hash, pre_ldst_expr_eq, NULL);
+ pre_ldst_table.create (13);
FOR_EACH_BB (bb)
{
@@ -3978,7 +3984,7 @@ trim_ld_motion_mems (void)
else
{
*last = ptr->next;
- htab_remove_elt_with_hash (pre_ldst_table, ptr, ptr->hash_index);
+ pre_ldst_table.remove_elt_with_hash (ptr, ptr->hash_index);
free_ldst_entry (ptr);
ptr = * last;
}
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 91c8249f3ae..0bb2eb19f23 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "ggc.h"
#include "ggc-internal.h"
#include "diagnostic-core.h"
@@ -46,10 +46,6 @@ static ggc_statistics *ggc_stats;
struct traversal_state;
static int ggc_htab_delete (void **, void *);
-static hashval_t saving_htab_hash (const void *);
-static int saving_htab_eq (const void *, const void *);
-static int call_count (void **, void *);
-static int call_alloc (void **, void *);
static int compare_ptr_data (const void *, const void *);
static void relocate_ptrs (void *, void *);
static void write_pch_globals (const struct ggc_root_tab * const *tab,
@@ -289,8 +285,6 @@ ggc_print_common_statistics (FILE *stream ATTRIBUTE_UNUSED,
/* Functions for saving and restoring GCable memory to disk. */
-static htab_t saving_htab;
-
struct ptr_data
{
void *obj;
@@ -303,6 +297,30 @@ struct ptr_data
#define POINTER_HASH(x) (hashval_t)((intptr_t)x >> 3)
+/* Helper for hashing saving_htab. */
+
+struct saving_hasher : typed_free_remove <ptr_data>
+{
+ typedef ptr_data value_type;
+ typedef void compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+saving_hasher::hash (const value_type *p)
+{
+ return POINTER_HASH (p->obj);
+}
+
+inline bool
+saving_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ return p1->obj == p2;
+}
+
+static hash_table <saving_hasher> saving_htab;
+
/* Register an object in the hash table. */
int
@@ -315,8 +333,7 @@ gt_pch_note_object (void *obj, void *note_ptr_cookie,
return 0;
slot = (struct ptr_data **)
- htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj),
- INSERT);
+ saving_htab.find_slot_with_hash (obj, POINTER_HASH (obj), INSERT);
if (*slot != NULL)
{
gcc_assert ((*slot)->note_ptr_fn == note_ptr_fn
@@ -347,26 +364,12 @@ gt_pch_note_reorder (void *obj, void *note_ptr_cookie,
return;
data = (struct ptr_data *)
- htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
+ saving_htab.find_with_hash (obj, POINTER_HASH (obj));
gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie);
data->reorder_fn = reorder_fn;
}
-/* Hash and equality functions for saving_htab, callbacks for htab_create. */
-
-static hashval_t
-saving_htab_hash (const void *p)
-{
- return POINTER_HASH (((const struct ptr_data *)p)->obj);
-}
-
-static int
-saving_htab_eq (const void *p1, const void *p2)
-{
- return ((const struct ptr_data *)p1)->obj == p2;
-}
-
/* Handy state for the traversal functions. */
struct traversal_state
@@ -380,11 +383,10 @@ struct traversal_state
/* Callbacks for htab_traverse. */
-static int
-call_count (void **slot, void *state_p)
+int
+ggc_call_count (ptr_data **slot, traversal_state *state)
{
- struct ptr_data *d = (struct ptr_data *)*slot;
- struct traversal_state *state = (struct traversal_state *)state_p;
+ struct ptr_data *d = *slot;
ggc_pch_count_object (state->d, d->obj, d->size,
d->note_ptr_fn == gt_pch_p_S);
@@ -392,11 +394,10 @@ call_count (void **slot, void *state_p)
return 1;
}
-static int
-call_alloc (void **slot, void *state_p)
+int
+ggc_call_alloc (ptr_data **slot, traversal_state *state)
{
- struct ptr_data *d = (struct ptr_data *)*slot;
- struct traversal_state *state = (struct traversal_state *)state_p;
+ struct ptr_data *d = *slot;
d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size,
d->note_ptr_fn == gt_pch_p_S);
@@ -429,7 +430,7 @@ relocate_ptrs (void *ptr_p, void *state_p)
return;
result = (struct ptr_data *)
- htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
+ saving_htab.find_with_hash (*ptr, POINTER_HASH (*ptr));
gcc_assert (result);
*ptr = result->new_addr;
}
@@ -458,7 +459,7 @@ write_pch_globals (const struct ggc_root_tab * const *tab,
else
{
new_ptr = (struct ptr_data *)
- htab_find_with_hash (saving_htab, ptr, POINTER_HASH (ptr));
+ saving_htab.find_with_hash (ptr, POINTER_HASH (ptr));
if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
!= 1)
fatal_error ("can%'t write PCH file: %m");
@@ -492,7 +493,7 @@ gt_pch_save (FILE *f)
gt_pch_save_stringpool ();
timevar_push (TV_PCH_PTR_REALLOC);
- saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free);
+ saving_htab.create (50000);
for (rt = gt_ggc_rtab; *rt; rt++)
for (rti = *rt; rti->base != NULL; rti++)
@@ -508,7 +509,7 @@ gt_pch_save (FILE *f)
state.f = f;
state.d = init_ggc_pch ();
state.count = 0;
- htab_traverse (saving_htab, call_count, &state);
+ saving_htab.traverse <traversal_state *, ggc_call_count> (&state);
mmi.size = ggc_pch_total_size (state.d);
@@ -524,7 +525,7 @@ gt_pch_save (FILE *f)
state.ptrs = XNEWVEC (struct ptr_data *, state.count);
state.ptrs_i = 0;
- htab_traverse (saving_htab, call_alloc, &state);
+ saving_htab.traverse <traversal_state *, ggc_call_alloc> (&state);
timevar_pop (TV_PCH_PTR_REALLOC);
timevar_push (TV_PCH_PTR_SORT);
@@ -653,7 +654,7 @@ gt_pch_save (FILE *f)
XDELETE (state.ptrs);
XDELETE (this_object);
- htab_delete (saving_htab);
+ saving_htab.dispose ();
}
/* Read the state of the compiler back in from F. */
@@ -913,30 +914,32 @@ struct loc_descriptor
size_t collected;
};
-/* Hashtable used for statistics. */
-static htab_t loc_hash;
+/* Hash table helper. */
-/* Hash table helpers functions. */
-static hashval_t
-hash_descriptor (const void *p)
+struct loc_desc_hasher : typed_noop_remove <loc_descriptor>
{
- const struct loc_descriptor *const d = (const struct loc_descriptor *) p;
+ typedef loc_descriptor value_type;
+ typedef loc_descriptor compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+inline hashval_t
+loc_desc_hasher::hash (const value_type *d)
+{
return htab_hash_pointer (d->function) | d->line;
}
-static int
-eq_descriptor (const void *p1, const void *p2)
+inline bool
+loc_desc_hasher::equal (const value_type *d, const compare_type *d2)
{
- const struct loc_descriptor *const d = (const struct loc_descriptor *) p1;
- const struct loc_descriptor *const d2 = (const struct loc_descriptor *) p2;
-
return (d->file == d2->file && d->line == d2->line
&& d->function == d2->function);
}
-/* Hashtable converting address of allocated field to loc descriptor. */
-static htab_t ptr_hash;
+/* Hashtable used for statistics. */
+static hash_table <loc_desc_hasher> loc_hash;
+
struct ptr_hash_entry
{
void *ptr;
@@ -944,26 +947,34 @@ struct ptr_hash_entry
size_t size;
};
-/* Hash table helpers functions. */
-static hashval_t
-hash_ptr (const void *p)
+/* Helper for ptr_hash table. */
+
+struct ptr_hash_hasher : typed_noop_remove <ptr_hash_entry>
{
- const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p;
+ typedef ptr_hash_entry value_type;
+ typedef void compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+inline hashval_t
+ptr_hash_hasher::hash (const value_type *d)
+{
return htab_hash_pointer (d->ptr);
}
-static int
-eq_ptr (const void *p1, const void *p2)
+inline bool
+ptr_hash_hasher::equal (const value_type *p, const compare_type *p2)
{
- const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1;
-
return (p->ptr == p2);
}
+/* Hashtable converting address of allocated field to loc descriptor. */
+static hash_table <ptr_hash_hasher> ptr_hash;
+
/* Return descriptor for given call site, create new one if needed. */
static struct loc_descriptor *
-loc_descriptor (const char *name, int line, const char *function)
+make_loc_descriptor (const char *name, int line, const char *function)
{
struct loc_descriptor loc;
struct loc_descriptor **slot;
@@ -971,10 +982,10 @@ loc_descriptor (const char *name, int line, const char *function)
loc.file = name;
loc.line = line;
loc.function = function;
- if (!loc_hash)
- loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+ if (!loc_hash.is_created ())
+ loc_hash.create (10);
- slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, INSERT);
+ slot = loc_hash.find_slot (&loc, INSERT);
if (*slot)
return *slot;
*slot = XCNEW (struct loc_descriptor);
@@ -989,16 +1000,16 @@ void
ggc_record_overhead (size_t allocated, size_t overhead, void *ptr,
const char *name, int line, const char *function)
{
- struct loc_descriptor *loc = loc_descriptor (name, line, function);
+ struct loc_descriptor *loc = make_loc_descriptor (name, line, function);
struct ptr_hash_entry *p = XNEW (struct ptr_hash_entry);
- PTR *slot;
+ ptr_hash_entry **slot;
p->ptr = ptr;
p->loc = loc;
p->size = allocated + overhead;
- if (!ptr_hash)
- ptr_hash = htab_create (10, hash_ptr, eq_ptr, NULL);
- slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), INSERT);
+ if (!ptr_hash.is_created ())
+ ptr_hash.create (10);
+ slot = ptr_hash.find_slot_with_hash (ptr, htab_hash_pointer (ptr), INSERT);
gcc_assert (!*slot);
*slot = p;
@@ -1009,14 +1020,14 @@ ggc_record_overhead (size_t allocated, size_t overhead, void *ptr,
/* Helper function for prune_overhead_list. See if SLOT is still marked and
remove it from hashtable if it is not. */
-static int
-ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
+int
+ggc_prune_ptr (ptr_hash_entry **slot, void *b ATTRIBUTE_UNUSED)
{
- struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
+ struct ptr_hash_entry *p = *slot;
if (!ggc_marked_p (p->ptr))
{
p->loc->collected += p->size;
- htab_clear_slot (ptr_hash, slot);
+ ptr_hash.clear_slot (slot);
free (p);
}
return 1;
@@ -1027,15 +1038,15 @@ ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
void
ggc_prune_overhead_list (void)
{
- htab_traverse (ptr_hash, ggc_prune_ptr, NULL);
+ ptr_hash.traverse <void *, ggc_prune_ptr> (NULL);
}
/* Notice that the pointer has been freed. */
void
ggc_free_overhead (void *ptr)
{
- PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr),
- NO_INSERT);
+ ptr_hash_entry **slot;
+ slot = ptr_hash.find_slot_with_hash (ptr, htab_hash_pointer (ptr), NO_INSERT);
struct ptr_hash_entry *p;
/* The pointer might be not found if a PCH read happened between allocation
and ggc_free () call. FIXME: account memory properly in the presence of
@@ -1044,7 +1055,7 @@ ggc_free_overhead (void *ptr)
return;
p = (struct ptr_hash_entry *) *slot;
p->loc->freed += p->size;
- htab_clear_slot (ptr_hash, slot);
+ ptr_hash.clear_slot (slot);
free (p);
}
@@ -1083,11 +1094,10 @@ cmp_statistic (const void *loc1, const void *loc2)
/* Collect array of the descriptors from hashtable. */
static struct loc_descriptor **loc_array;
-static int
-add_statistics (void **slot, void *b)
+int
+ggc_add_statistics (loc_descriptor **slot, int *n)
{
- int *n = (int *)b;
- loc_array[*n] = (struct loc_descriptor *) *slot;
+ loc_array[*n] = *slot;
(*n)++;
return 1;
}
@@ -1108,12 +1118,13 @@ dump_ggc_loc_statistics (bool final)
ggc_force_collect = true;
ggc_collect ();
- loc_array = XCNEWVEC (struct loc_descriptor *, loc_hash->n_elements);
+ loc_array = XCNEWVEC (struct loc_descriptor *,
+ loc_hash.elements_with_deleted ());
fprintf (stderr, "-------------------------------------------------------\n");
fprintf (stderr, "\n%-48s %10s %10s %10s %10s %10s\n",
"source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
fprintf (stderr, "-------------------------------------------------------\n");
- htab_traverse (loc_hash, add_statistics, &nentries);
+ loc_hash.traverse <int *, ggc_add_statistics> (&nentries);
qsort (loc_array, nentries, sizeof (*loc_array),
final ? final_cmp_statistic : cmp_statistic);
for (i = 0; i < nentries; i++)
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index 873b8bcd7e9..d219af22764 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "expmed.h"
#include "params.h"
+#include "hash-table.h"
/* Information about a strength reduction candidate. Each statement
in the candidate table represents an expression of one of the
@@ -287,9 +288,6 @@ static struct pointer_map_t *stmt_cand_map;
/* Obstack for candidates. */
static struct obstack cand_obstack;
-/* Hash table embodying a mapping from base exprs to chains of candidates. */
-static htab_t base_cand_map;
-
/* Obstack for candidate chains. */
static struct obstack chain_obstack;
@@ -311,32 +309,31 @@ lookup_cand (cand_idx idx)
return cand_vec[idx - 1];
}
-/* Callback to produce a hash value for a candidate chain header. */
+/* Helper for hashing a candidate chain header. */
-static hashval_t
-base_cand_hash (const void *p)
+struct cand_chain_hasher : typed_noop_remove <cand_chain>
{
- tree base_expr = ((const_cand_chain_t) p)->base_expr;
- return iterative_hash_expr (base_expr, 0);
-}
-
-/* Callback when an element is removed from the hash table.
- We never remove entries until the entire table is released. */
+ typedef cand_chain value_type;
+ typedef cand_chain compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
-static void
-base_cand_free (void *p ATTRIBUTE_UNUSED)
+inline hashval_t
+cand_chain_hasher::hash (const value_type *p)
{
+ tree base_expr = p->base_expr;
+ return iterative_hash_expr (base_expr, 0);
}
-/* Callback to return true if two candidate chain headers are equal. */
-
-static int
-base_cand_eq (const void *p1, const void *p2)
+inline bool
+cand_chain_hasher::equal (const value_type *chain1, const compare_type *chain2)
{
- const_cand_chain_t const chain1 = (const_cand_chain_t) p1;
- const_cand_chain_t const chain2 = (const_cand_chain_t) p2;
return operand_equal_p (chain1->base_expr, chain2->base_expr, 0);
}
+
+/* Hash table embodying a mapping from base exprs to chains of candidates. */
+static hash_table <cand_chain_hasher> base_cand_map;
/* Use the base expr from candidate C to look for possible candidates
that can serve as a basis for C. Each potential basis must also
@@ -357,7 +354,7 @@ find_basis_for_candidate (slsr_cand_t c)
int max_iters = PARAM_VALUE (PARAM_MAX_SLSR_CANDIDATE_SCAN);
mapping_key.base_expr = c->base_expr;
- chain = (cand_chain_t) htab_find (base_cand_map, &mapping_key);
+ chain = base_cand_map.find (&mapping_key);
for (; chain && iters < max_iters; chain = chain->next, ++iters)
{
@@ -393,13 +390,13 @@ static void
record_potential_basis (slsr_cand_t c)
{
cand_chain_t node;
- void **slot;
+ cand_chain **slot;
node = (cand_chain_t) obstack_alloc (&chain_obstack, sizeof (cand_chain));
node->base_expr = c->base_expr;
node->cand = c;
node->next = NULL;
- slot = htab_find_slot (base_cand_map, node, INSERT);
+ slot = base_cand_map.find_slot (node, INSERT);
if (*slot)
{
@@ -1435,10 +1432,10 @@ dump_cand_vec (void)
/* Callback used to dump the candidate chains hash table. */
-static int
-base_cand_dump_callback (void **slot, void *ignored ATTRIBUTE_UNUSED)
+int
+ssa_base_cand_dump_callback (cand_chain **slot, void *ignored ATTRIBUTE_UNUSED)
{
- const_cand_chain_t chain = *((const_cand_chain_t *) slot);
+ const_cand_chain_t chain = *slot;
cand_chain_t p;
print_generic_expr (dump_file, chain->base_expr, 0);
@@ -1457,7 +1454,7 @@ static void
dump_cand_chains (void)
{
fprintf (dump_file, "\nStrength reduction candidate chains:\n\n");
- htab_traverse_noresize (base_cand_map, base_cand_dump_callback, NULL);
+ base_cand_map.traverse_noresize <void *, ssa_base_cand_dump_callback> (NULL);
fputs ("\n", dump_file);
}
@@ -2637,8 +2634,7 @@ execute_strength_reduction (void)
gcc_obstack_init (&chain_obstack);
/* Allocate the mapping from base expressions to candidate chains. */
- base_cand_map = htab_create (500, base_cand_hash,
- base_cand_eq, base_cand_free);
+ base_cand_map.create (500);
/* Initialize the loop optimizer. We need to detect flow across
back edges, and this gives us dominator information as well. */
@@ -2669,7 +2665,7 @@ execute_strength_reduction (void)
/* Free resources. */
fini_walk_dominator_tree (&walk_data);
loop_optimizer_finalize ();
- htab_delete (base_cand_map);
+ base_cand_map.dispose ();
obstack_free (&chain_obstack, NULL);
pointer_map_destroy (stmt_cand_map);
cand_vec.release ();
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 785c2f021a7..c4687df8605 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -4210,4 +4210,115 @@ gimple_asm_clobbers_memory_p (const_gimple stmt)
return false;
}
+
+
+/* Return the expression type to use based on the CODE and type of
+ the given operand OP. If the expression CODE is a comparison,
+ the returned type is boolean_type_node. Otherwise, it returns
+ the type of OP. */
+
+tree
+gimple_builder_base::get_expr_type (enum tree_code code, tree op)
+{
+ return (TREE_CODE_CLASS (code) == tcc_comparison)
+ ? boolean_type_node
+ : TREE_TYPE (op);
+}
+
+
+/* Add a new assignment to this GIMPLE sequence. The assignment has
+ the form: GIMPLE_ASSIGN <CODE, LHS, OP1, OP2>. Returns LHS. */
+
+tree
+gimple_builder_base::add (enum tree_code code, tree lhs, tree op1, tree op2)
+{
+ gimple s = gimple_build_assign_with_ops (code, lhs, op1, op2);
+ gimple_seq_add_stmt (&seq_, s);
+ return lhs;
+}
+
+
+/* Add a new assignment to this GIMPLE sequence. The new assignment will
+ have the opcode CODE and operands OP1 and OP2. The type of the
+ expression on the RHS is inferred to be the type of OP1.
+
+ The LHS of the statement will be an SSA name or a GIMPLE temporary
+ in normal form depending on the type of builder invoking this
+ function. */
+
+tree
+gimple_builder_base::add (enum tree_code code, tree op1, tree op2)
+{
+ tree lhs = create_lhs_for_assignment (get_expr_type (code, op1));
+ return add (code, lhs, op1, op2);
+}
+
+
+/* Add a new assignment to this GIMPLE sequence. The new
+ assignment will have the opcode CODE and operands OP1 and VAL.
+ VAL is converted into a an INTEGER_CST of the same type as OP1.
+
+ The LHS of the statement will be an SSA name or a GIMPLE temporary
+ in normal form depending on the type of builder invoking this
+ function. */
+
+tree
+gimple_builder_base::add (enum tree_code code, tree op1, int val)
+{
+ tree type = get_expr_type (code, op1);
+ tree op2 = build_int_cst (TREE_TYPE (op1), val);
+ tree lhs = create_lhs_for_assignment (type);
+ return add (code, lhs, op1, op2);
+}
+
+
+/* Add a type cast assignment to this GIMPLE sequence. This creates a NOP_EXPR
+ that converts OP to TO_TYPE. Return the LHS of the generated assignment. */
+
+tree
+gimple_builder_base::add_type_cast (tree to_type, tree op)
+{
+ tree lhs = create_lhs_for_assignment (to_type);
+ return add (NOP_EXPR, lhs, op, NULL_TREE);
+}
+
+
+/* Insert this sequence after the statement pointed-to by iterator I.
+ MODE is an is gs_insert_after. Scan the statements in SEQ for new
+ operands. */
+
+void
+gimple_builder_base::insert_after (gimple_stmt_iterator *i,
+ enum gsi_iterator_update mode)
+{
+ /* Since we are inserting a sequence, the semantics for GSI_NEW_STMT
+ are not quite what the caller is expecting. GSI_NEW_STMT will
+ leave the iterator pointing to the *first* statement of this
+ sequence. Rather, we want the iterator to point to the *last*
+ statement in the sequence. Therefore, we use
+ GSI_CONTINUE_LINKING when GSI_NEW_STMT is requested. */
+ if (mode == GSI_NEW_STMT)
+ mode = GSI_CONTINUE_LINKING;
+ gsi_insert_seq_after (i, seq_, mode);
+}
+
+
+/* Create a GIMPLE temporary type TYPE to be used as the LHS of an
+ assignment. */
+
+tree
+gimple_builder_normal::create_lhs_for_assignment (tree type)
+{
+ return create_tmp_var (type, NULL);
+}
+
+
+/* Create an SSA name of type TYPE to be used as the LHS of an assignment. */
+
+tree
+gimple_builder_ssa::create_lhs_for_assignment (tree type)
+{
+ return make_ssa_name (type, NULL);
+}
+
#include "gt-gimple.h"
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 475d2ea9ee7..9f72e6776cc 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_GIMPLE_H
#include "pointer-set.h"
+#include "hash-table.h"
#include "vec.h"
#include "ggc.h"
#include "basic-block.h"
@@ -940,6 +941,55 @@ enum gimplify_status {
GS_ALL_DONE = 1 /* The expression is fully gimplified. */
};
+/* Formal (expression) temporary table handling: multiple occurrences of
+ the same scalar expression are evaluated into the same temporary. */
+
+typedef struct gimple_temp_hash_elt
+{
+ tree val; /* Key */
+ tree temp; /* Value */
+} elt_t;
+
+/* Gimplify hashtable helper. */
+
+struct gimplify_hasher : typed_free_remove <elt_t>
+{
+ typedef elt_t value_type;
+ typedef elt_t compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+gimplify_hasher::hash (const value_type *p)
+{
+ tree t = p->val;
+ return iterative_hash_expr (t, 0);
+}
+
+inline bool
+gimplify_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ tree t1 = p1->val;
+ tree t2 = p2->val;
+ enum tree_code code = TREE_CODE (t1);
+
+ if (TREE_CODE (t2) != code
+ || TREE_TYPE (t1) != TREE_TYPE (t2))
+ return false;
+
+ if (!operand_equal_p (t1, t2, 0))
+ return false;
+
+#ifdef ENABLE_CHECKING
+ /* Only allow them to compare equal if they also hash equal; otherwise
+ results are nondeterminate, and we fail bootstrap comparison. */
+ gcc_assert (hash (p1) == hash (p2));
+#endif
+
+ return true;
+}
+
struct gimplify_ctx
{
struct gimplify_ctx *prev_context;
@@ -952,7 +1002,7 @@ struct gimplify_ctx
vec<tree> case_labels;
/* The formal temporary table. Should this be persistent? */
- htab_t temp_htab;
+ hash_table <gimplify_hasher> temp_htab;
int conditions;
bool save_stack;
@@ -5326,4 +5376,57 @@ extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree,
enum tree_code, tree, tree);
bool gimple_val_nonnegative_real_p (tree);
+
+
+/* GIMPLE builder class. This type provides a simplified interface
+ for generating new GIMPLE statements. */
+
+class gimple_builder_base
+{
+public:
+ tree add (enum tree_code, tree, tree);
+ tree add (enum tree_code, tree, int);
+ tree add (enum tree_code, tree, tree, tree);
+ tree add_type_cast (tree, tree);
+ void insert_after (gimple_stmt_iterator *, enum gsi_iterator_update);
+
+protected:
+ gimple_builder_base() : seq_(NULL), loc_(UNKNOWN_LOCATION) {}
+ gimple_builder_base(location_t l) : seq_(NULL), loc_(l) {}
+ tree get_expr_type (enum tree_code code, tree op);
+ virtual tree create_lhs_for_assignment (tree) = 0;
+
+private:
+ gimple_seq seq_;
+ location_t loc_;
+};
+
+
+/* GIMPLE builder class for statements in normal form. Statements generated
+ by instances of this class will produce non-SSA temporaries. */
+
+class gimple_builder_normal : public gimple_builder_base
+{
+public:
+ gimple_builder_normal() : gimple_builder_base() {}
+ gimple_builder_normal(location_t l) : gimple_builder_base(l) {}
+
+protected:
+ virtual tree create_lhs_for_assignment (tree);
+};
+
+
+/* GIMPLE builder class for statements in normal form. Statements generated
+ by instances of this class will produce SSA names. */
+
+class gimple_builder_ssa : public gimple_builder_base
+{
+public:
+ gimple_builder_ssa() : gimple_builder_base() {}
+ gimple_builder_ssa(location_t l) : gimple_builder_base(l) {}
+
+protected:
+ virtual tree create_lhs_for_assignment (tree);
+};
+
#endif /* GCC_GIMPLE_H */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a6a6565ce04..1f7b3da29fc 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -87,15 +87,6 @@ static struct gimplify_ctx *gimplify_ctxp;
static struct gimplify_omp_ctx *gimplify_omp_ctxp;
-/* Formal (expression) temporary table handling: multiple occurrences of
- the same scalar expression are evaluated into the same temporary. */
-
-typedef struct gimple_temp_hash_elt
-{
- tree val; /* Key */
- tree temp; /* Value */
-} elt_t;
-
/* Forward declaration. */
static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
@@ -130,40 +121,6 @@ mark_addressable (tree x)
}
}
-/* Return a hash value for a formal temporary table entry. */
-
-static hashval_t
-gimple_tree_hash (const void *p)
-{
- tree t = ((const elt_t *) p)->val;
- return iterative_hash_expr (t, 0);
-}
-
-/* Compare two formal temporary table entries. */
-
-static int
-gimple_tree_eq (const void *p1, const void *p2)
-{
- tree t1 = ((const elt_t *) p1)->val;
- tree t2 = ((const elt_t *) p2)->val;
- enum tree_code code = TREE_CODE (t1);
-
- if (TREE_CODE (t2) != code
- || TREE_TYPE (t1) != TREE_TYPE (t2))
- return 0;
-
- if (!operand_equal_p (t1, t2, 0))
- return 0;
-
-#ifdef ENABLE_CHECKING
- /* Only allow them to compare equal if they also hash equal; otherwise
- results are nondeterminate, and we fail bootstrap comparison. */
- gcc_assert (gimple_tree_hash (p1) == gimple_tree_hash (p2));
-#endif
-
- return 1;
-}
-
/* Link gimple statement GS to the end of the sequence *SEQ_P. If
*SEQ_P is NULL, a new sequence is allocated. This function is
similar to gimple_seq_add_stmt, but does not scan the operands.
@@ -241,8 +198,8 @@ pop_gimplify_context (gimple body)
else
record_vars (c->temps);
- if (c->temp_htab)
- htab_delete (c->temp_htab);
+ if (c->temp_htab.is_created ())
+ c->temp_htab.dispose ();
}
/* Push a GIMPLE_BIND tuple onto the stack of bindings. */
@@ -585,23 +542,22 @@ lookup_tmp_var (tree val, bool is_formal)
else
{
elt_t elt, *elt_p;
- void **slot;
+ elt_t **slot;
elt.val = val;
- if (gimplify_ctxp->temp_htab == NULL)
- gimplify_ctxp->temp_htab
- = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
- slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
+ if (!gimplify_ctxp->temp_htab.is_created ())
+ gimplify_ctxp->temp_htab.create (1000);
+ slot = gimplify_ctxp->temp_htab.find_slot (&elt, INSERT);
if (*slot == NULL)
{
elt_p = XNEW (elt_t);
elt_p->val = val;
elt_p->temp = ret = create_tmp_from_val (val, is_formal);
- *slot = (void *) elt_p;
+ *slot = elt_p;
}
else
{
- elt_p = (elt_t *) *slot;
+ elt_p = *slot;
ret = elt_p->temp;
}
}
diff --git a/gcc/graphds.h b/gcc/graphds.h
index 5e5ca7d841c..f6d9c36bfa6 100644
--- a/gcc/graphds.h
+++ b/gcc/graphds.h
@@ -46,7 +46,6 @@ struct graph
int n_vertices; /* Number of vertices. */
struct vertex *vertices;
/* The vertices. */
- htab_t indices; /* Fast lookup for indices. */
};
struct graph *new_graph (int);
diff --git a/gcc/graphite-clast-to-gimple.c b/gcc/graphite-clast-to-gimple.c
index 58a69ed0b4b..dcf8b94eaa1 100644
--- a/gcc/graphite-clast-to-gimple.c
+++ b/gcc/graphite-clast-to-gimple.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "cloog/cloog.h"
#include "graphite-poly.h"
#include "graphite-clast-to-gimple.h"
+#include "graphite-htab.h"
typedef const struct clast_expr *clast_name_p;
@@ -124,6 +125,55 @@ typedef struct clast_name_index {
char *free_name;
} *clast_name_index_p;
+/* Helper for hashing clast_name_index. */
+
+struct clast_index_hasher
+{
+ typedef clast_name_index value_type;
+ typedef clast_name_index compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+/* Computes a hash function for database element E. */
+
+inline hashval_t
+clast_index_hasher::hash (const value_type *e)
+{
+ hashval_t hash = 0;
+
+ int length = strlen (e->name);
+ int i;
+
+ for (i = 0; i < length; ++i)
+ hash = hash | (e->name[i] << (i % 4));
+
+ return hash;
+}
+
+/* Compares database elements ELT1 and ELT2. */
+
+inline bool
+clast_index_hasher::equal (const value_type *elt1, const compare_type *elt2)
+{
+ return strcmp (elt1->name, elt2->name) == 0;
+}
+
+/* Free the memory taken by a clast_name_index struct. */
+
+inline void
+clast_index_hasher::remove (value_type *c)
+{
+ if (c->free_name)
+ free (c->free_name);
+ mpz_clear (c->bound_one);
+ mpz_clear (c->bound_two);
+ free (c);
+}
+
+typedef hash_table <clast_index_hasher> clast_index_htab_type;
+
/* Returns a pointer to a new element of type clast_name_index_p built
from NAME, INDEX, LEVEL, BOUND_ONE, and BOUND_TWO. */
@@ -146,35 +196,22 @@ new_clast_name_index (const char *name, int index, int level,
return res;
}
-/* Free the memory taken by a clast_name_index struct. */
-
-static void
-free_clast_name_index (void *ptr)
-{
- struct clast_name_index *c = (struct clast_name_index *) ptr;
- if (c->free_name)
- free (c->free_name);
- mpz_clear (c->bound_one);
- mpz_clear (c->bound_two);
- free (ptr);
-}
-
/* For a given clast NAME, returns -1 if NAME is not in the
INDEX_TABLE, otherwise returns the loop level for the induction
variable NAME, or if it is a parameter, the parameter number in the
vector of parameters. */
static inline int
-clast_name_to_level (clast_name_p name, htab_t index_table)
+clast_name_to_level (clast_name_p name, clast_index_htab_type index_table)
{
struct clast_name_index tmp;
- PTR *slot;
+ clast_name_index **slot;
gcc_assert (name->type == clast_expr_name);
tmp.name = ((const struct clast_name *) name)->name;
tmp.free_name = NULL;
- slot = htab_find_slot (index_table, &tmp, NO_INSERT);
+ slot = index_table.find_slot (&tmp, NO_INSERT);
if (slot && *slot)
return ((struct clast_name_index *) *slot)->level;
@@ -187,18 +224,18 @@ clast_name_to_level (clast_name_p name, htab_t index_table)
SCATTERING_DIMENSIONS vector. */
static inline int
-clast_name_to_index (struct clast_name *name, htab_t index_table)
+clast_name_to_index (struct clast_name *name, clast_index_htab_type index_table)
{
struct clast_name_index tmp;
- PTR *slot;
+ clast_name_index **slot;
tmp.name = ((const struct clast_name *) name)->name;
tmp.free_name = NULL;
- slot = htab_find_slot (index_table, &tmp, NO_INSERT);
+ slot = index_table.find_slot (&tmp, NO_INSERT);
if (slot && *slot)
- return ((struct clast_name_index *) *slot)->index;
+ return (*slot)->index;
return -1;
}
@@ -208,16 +245,16 @@ clast_name_to_index (struct clast_name *name, htab_t index_table)
found in the INDEX_TABLE, false otherwise. */
static inline bool
-clast_name_to_lb_ub (struct clast_name *name, htab_t index_table,
+clast_name_to_lb_ub (struct clast_name *name, clast_index_htab_type index_table,
mpz_t bound_one, mpz_t bound_two)
{
struct clast_name_index tmp;
- PTR *slot;
+ clast_name_index **slot;
tmp.name = name->name;
tmp.free_name = NULL;
- slot = htab_find_slot (index_table, &tmp, NO_INSERT);
+ slot = index_table.find_slot (&tmp, NO_INSERT);
if (slot && *slot)
{
@@ -232,15 +269,15 @@ clast_name_to_lb_ub (struct clast_name *name, htab_t index_table,
/* Records in INDEX_TABLE the INDEX and LEVEL for NAME. */
static inline void
-save_clast_name_index (htab_t index_table, const char *name,
+save_clast_name_index (clast_index_htab_type index_table, const char *name,
int index, int level, mpz_t bound_one, mpz_t bound_two)
{
struct clast_name_index tmp;
- PTR *slot;
+ clast_name_index **slot;
tmp.name = name;
tmp.free_name = NULL;
- slot = htab_find_slot (index_table, &tmp, INSERT);
+ slot = index_table.find_slot (&tmp, INSERT);
if (slot)
{
@@ -249,35 +286,6 @@ save_clast_name_index (htab_t index_table, const char *name,
*slot = new_clast_name_index (name, index, level, bound_one, bound_two);
}
}
-
-/* Computes a hash function for database element ELT. */
-
-static inline hashval_t
-clast_name_index_elt_info (const void *elt)
-{
- const struct clast_name_index *e = ((const struct clast_name_index *) elt);
- hashval_t hash = 0;
-
- int length = strlen (e->name);
- int i;
-
- for (i = 0; i < length; ++i)
- hash = hash | (e->name[i] << (i % 4));
-
- return hash;
-}
-
-/* Compares database elements E1 and E2. */
-
-static inline int
-eq_clast_name_indexes (const void *e1, const void *e2)
-{
- const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
- const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
-
- return strcmp (elt1->name, elt2->name) == 0;
-}
-
/* NEWIVS_INDEX binds CLooG's scattering name to the index of the tree
@@ -288,7 +296,7 @@ eq_clast_name_indexes (const void *e1, const void *e2)
typedef struct ivs_params {
vec<tree> params, *newivs;
- htab_t newivs_index, params_index;
+ clast_index_htab_type newivs_index, params_index;
sese region;
} *ivs_params_p;
@@ -300,7 +308,7 @@ clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
{
int index;
- if (ip->params.exists () && ip->params_index)
+ if (ip->params.exists () && ip->params_index.is_created ())
{
index = clast_name_to_index (name, ip->params_index);
@@ -308,7 +316,7 @@ clast_name_to_gcc (struct clast_name *name, ivs_params_p ip)
return ip->params[index];
}
- gcc_assert (ip->newivs && ip->newivs_index);
+ gcc_assert (ip->newivs && ip->newivs_index.is_created ());
index = clast_name_to_index (name, ip->newivs_index);
gcc_assert (index >= 0);
@@ -699,12 +707,12 @@ type_for_clast_name (struct clast_name *name, ivs_params_p ip, mpz_t bound_one,
{
bool found = false;
- if (ip->params.exists () && ip->params_index)
+ if (ip->params.exists () && ip->params_index.is_created ())
found = clast_name_to_lb_ub (name, ip->params_index, bound_one, bound_two);
if (!found)
{
- gcc_assert (ip->newivs && ip->newivs_index);
+ gcc_assert (ip->newivs && ip->newivs_index.is_created ());
found = clast_name_to_lb_ub (name, ip->newivs_index, bound_one,
bound_two);
gcc_assert (found);
@@ -1009,13 +1017,14 @@ new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
/* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
static void
-mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
+mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
+ bb_pbb_htab_type bb_pbb_mapping)
{
bb_pbb_def tmp;
- PTR *x;
+ bb_pbb_def **x;
tmp.bb = bb;
- x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
+ x = bb_pbb_mapping.find_slot (&tmp, INSERT);
if (x && !*x)
*x = new_bb_pbb_def (bb, pbb);
@@ -1024,13 +1033,13 @@ mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
/* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING. */
poly_bb_p
-find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
+find_pbb_via_hash (bb_pbb_htab_type bb_pbb_mapping, basic_block bb)
{
bb_pbb_def tmp;
- PTR *slot;
+ bb_pbb_def **slot;
tmp.bb = bb;
- slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
+ slot = bb_pbb_mapping.find_slot (&tmp, NO_INSERT);
if (slot && *slot)
return ((bb_pbb_def *) *slot)->pbb;
@@ -1044,7 +1053,7 @@ find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
related poly_bb_p. */
scop_p
-get_loop_body_pbbs (loop_p loop, htab_t bb_pbb_mapping,
+get_loop_body_pbbs (loop_p loop, bb_pbb_htab_type bb_pbb_mapping,
vec<poly_bb_p> *pbbs)
{
unsigned i;
@@ -1074,7 +1083,7 @@ get_loop_body_pbbs (loop_p loop, htab_t bb_pbb_mapping,
static edge
translate_clast_user (struct clast_user_stmt *stmt, edge next_e,
- htab_t bb_pbb_mapping, ivs_params_p ip)
+ bb_pbb_htab_type bb_pbb_mapping, ivs_params_p ip)
{
int i, nb_loops;
basic_block new_bb;
@@ -1143,7 +1152,8 @@ graphite_create_new_loop_guard (edge entry_edge, struct clast_for *stmt,
}
static edge
-translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p);
+translate_clast (loop_p, struct clast_stmt *, edge, bb_pbb_htab_type,
+ int, ivs_params_p);
/* Create the loop for a clast for statement.
@@ -1152,8 +1162,9 @@ translate_clast (loop_p, struct clast_stmt *, edge, htab_t, int, ivs_params_p);
static edge
translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
- edge next_e, htab_t bb_pbb_mapping, int level,
- tree type, tree lb, tree ub, ivs_params_p ip)
+ edge next_e, bb_pbb_htab_type bb_pbb_mapping,
+ int level, tree type, tree lb, tree ub,
+ ivs_params_p ip)
{
struct loop *loop = graphite_create_new_loop (next_e, stmt, context_loop,
type, lb, ub, level, ip);
@@ -1186,7 +1197,8 @@ translate_clast_for_loop (loop_p context_loop, struct clast_for *stmt,
static edge
translate_clast_for (loop_p context_loop, struct clast_for *stmt, edge next_e,
- htab_t bb_pbb_mapping, int level, ivs_params_p ip)
+ bb_pbb_htab_type bb_pbb_mapping, int level,
+ ivs_params_p ip)
{
tree type, lb, ub;
edge last_e = graphite_create_new_loop_guard (next_e, stmt, &type,
@@ -1244,7 +1256,7 @@ translate_clast_assignment (struct clast_assignment *stmt, edge next_e,
static edge
translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
- edge next_e, htab_t bb_pbb_mapping, int level,
+ edge next_e, bb_pbb_htab_type bb_pbb_mapping, int level,
ivs_params_p ip)
{
edge last_e = graphite_create_new_guard (next_e, stmt, ip);
@@ -1263,7 +1275,7 @@ translate_clast_guard (loop_p context_loop, struct clast_guard *stmt,
static edge
translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
- htab_t bb_pbb_mapping, int level, ivs_params_p ip)
+ bb_pbb_htab_type bb_pbb_mapping, int level, ivs_params_p ip)
{
if (!stmt)
return next_e;
@@ -1304,7 +1316,8 @@ translate_clast (loop_p context_loop, struct clast_stmt *stmt, edge next_e,
static CloogUnionDomain *
add_names_to_union_domain (scop_p scop, CloogUnionDomain *union_domain,
- int nb_scattering_dims, htab_t params_index)
+ int nb_scattering_dims,
+ clast_index_htab_type params_index)
{
sese region = SCOP_REGION (scop);
int i;
@@ -1547,7 +1560,7 @@ int get_max_scattering_dimensions (scop_p scop)
}
static CloogInput *
-generate_cloog_input (scop_p scop, htab_t params_index)
+generate_cloog_input (scop_p scop, clast_index_htab_type params_index)
{
CloogUnionDomain *union_domain;
CloogInput *cloog_input;
@@ -1570,7 +1583,7 @@ generate_cloog_input (scop_p scop, htab_t params_index)
without a program. */
static struct clast_stmt *
-scop_to_clast (scop_p scop, htab_t params_index)
+scop_to_clast (scop_p scop, clast_index_htab_type params_index)
{
CloogInput *cloog_input;
struct clast_stmt *clast;
@@ -1599,11 +1612,10 @@ void
print_generated_program (FILE *file, scop_p scop)
{
CloogOptions *options = set_cloog_options ();
- htab_t params_index;
+ clast_index_htab_type params_index;
struct clast_stmt *clast;
- params_index = htab_create (10, clast_name_index_elt_info,
- eq_clast_name_indexes, free_clast_name_index);
+ params_index.create (10);
clast = scop_to_clast (scop, params_index);
@@ -1629,22 +1641,21 @@ debug_generated_program (scop_p scop)
*/
bool
-gloog (scop_p scop, htab_t bb_pbb_mapping)
+gloog (scop_p scop, bb_pbb_htab_type bb_pbb_mapping)
{
vec<tree> newivs;
newivs.create (10);
loop_p context_loop;
sese region = SCOP_REGION (scop);
ifsese if_region = NULL;
- htab_t newivs_index, params_index;
+ clast_index_htab_type newivs_index, params_index;
struct clast_stmt *clast;
struct ivs_params ip;
timevar_push (TV_GRAPHITE_CODE_GEN);
gloog_error = false;
- params_index = htab_create (10, clast_name_index_elt_info,
- eq_clast_name_indexes, free_clast_name_index);
+ params_index.create (10);
clast = scop_to_clast (scop, params_index);
@@ -1667,8 +1678,7 @@ gloog (scop_p scop, htab_t bb_pbb_mapping)
graphite_verify ();
context_loop = SESE_ENTRY (region)->src->loop_father;
- newivs_index = htab_create (10, clast_name_index_elt_info,
- eq_clast_name_indexes, free_clast_name_index);
+ newivs_index.create (10);
ip.newivs = &newivs;
ip.newivs_index = newivs_index;
@@ -1690,8 +1700,8 @@ gloog (scop_p scop, htab_t bb_pbb_mapping)
free (if_region->region);
free (if_region);
- htab_delete (newivs_index);
- htab_delete (params_index);
+ newivs_index.dispose ();
+ params_index.dispose ();
newivs.release ();
cloog_clast_free (clast);
timevar_pop (TV_GRAPHITE_CODE_GEN);
diff --git a/gcc/graphite-clast-to-gimple.h b/gcc/graphite-clast-to-gimple.h
index 737cbd0584c..78e60e2dafa 100644
--- a/gcc/graphite-clast-to-gimple.h
+++ b/gcc/graphite-clast-to-gimple.h
@@ -38,26 +38,7 @@ typedef struct bb_pbb_def
poly_bb_p pbb;
} bb_pbb_def;
-extern bool gloog (scop_p, htab_t);
extern void debug_clast_stmt (struct clast_stmt *);
extern void print_clast_stmt (FILE *, struct clast_stmt *);
-/* Hash function for data base element BB_PBB. */
-
-static inline hashval_t
-bb_pbb_map_hash (const void *bb_pbb)
-{
- return (hashval_t)(((const bb_pbb_def *)bb_pbb)->bb->index);
-}
-
-/* Compare data base element BB_PBB1 and BB_PBB2. */
-
-static inline int
-eq_bb_pbb_map (const void *bb_pbb1, const void *bb_pbb2)
-{
- const bb_pbb_def *bp1 = (const bb_pbb_def *) bb_pbb1;
- const bb_pbb_def *bp2 = (const bb_pbb_def *) bb_pbb2;
- return (bp1->bb->index == bp2->bb->index);
-}
-
#endif
diff --git a/gcc/graphite-dependences.c b/gcc/graphite-dependences.c
index 2f65c46d49f..366588b3595 100644
--- a/gcc/graphite-dependences.c
+++ b/gcc/graphite-dependences.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#ifdef HAVE_cloog
#include "graphite-poly.h"
+#include "graphite-htab.h"
/* Add the constraints from the set S to the domain of MAP. */
@@ -579,7 +580,7 @@ loop_level_carries_dependences (scop_p scop, vec<poly_bb_p> body,
poly_bb_p. */
bool
-loop_is_parallel_p (loop_p loop, htab_t bb_pbb_mapping, int depth)
+loop_is_parallel_p (loop_p loop, bb_pbb_htab_type bb_pbb_mapping, int depth)
{
bool dependences;
scop_p scop;
diff --git a/gcc/graphite-htab.h b/gcc/graphite-htab.h
new file mode 100644
index 00000000000..022b7698791
--- /dev/null
+++ b/gcc/graphite-htab.h
@@ -0,0 +1,60 @@
+/* Translation of CLAST (CLooG AST) to Gimple.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+ Contributed by Sebastian Pop <sebastian.pop@amd.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/>. */
+
+#ifndef GCC_GRAPHITE_HTAB_H
+#define GCC_GRAPHITE_HTAB_H
+
+#include "hash-table.h"
+#include "graphite-clast-to-gimple.h"
+
+/* Hashtable helpers. */
+
+struct bb_pbb_hasher : typed_free_remove <bb_pbb_def>
+{
+ typedef bb_pbb_def value_type;
+ typedef bb_pbb_def compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash function for data base element BB_PBB. */
+
+inline hashval_t
+bb_pbb_hasher::hash (const value_type *bb_pbb)
+{
+ return (hashval_t)(bb_pbb->bb->index);
+}
+
+/* Compare data base element PB1 and PB2. */
+
+inline bool
+bb_pbb_hasher::equal (const value_type *bp1, const compare_type *bp2)
+{
+ return (bp1->bb->index == bp2->bb->index);
+}
+
+typedef hash_table <bb_pbb_hasher> bb_pbb_htab_type;
+
+extern bool gloog (scop_p, bb_pbb_htab_type);
+poly_bb_p find_pbb_via_hash (bb_pbb_htab_type, basic_block);
+bool loop_is_parallel_p (loop_p, bb_pbb_htab_type, int);
+scop_p get_loop_body_pbbs (loop_p, bb_pbb_htab_type, vec<poly_bb_p> *);
+
+#endif
diff --git a/gcc/graphite-poly.h b/gcc/graphite-poly.h
index 6bf0b0e19de..52d6b1cdc53 100644
--- a/gcc/graphite-poly.h
+++ b/gcc/graphite-poly.h
@@ -1376,10 +1376,6 @@ struct scop
*must_war, *may_war, *must_war_no_source, *may_war_no_source,
*must_waw, *may_waw, *must_waw_no_source, *may_waw_no_source;
- /* A hashtable of the data dependence relations for the original
- scattering. */
- htab_t original_pddrs;
-
/* True when the scop has been converted to its polyhedral
representation. */
bool poly_scop_p;
@@ -1388,7 +1384,6 @@ struct scop
#define SCOP_BBS(S) (S->bbs)
#define SCOP_REGION(S) ((sese) S->region)
#define SCOP_CONTEXT(S) (NULL)
-#define SCOP_ORIGINAL_PDDRS(S) (S->original_pddrs)
#define SCOP_ORIGINAL_SCHEDULE(S) (S->original_schedule)
#define SCOP_TRANSFORMED_SCHEDULE(S) (S->transformed_schedule)
#define SCOP_SAVED_SCHEDULE(S) (S->saved_schedule)
@@ -1536,9 +1531,6 @@ restore_scattering (scop_p scop)
}
bool graphite_legal_transform (scop_p);
-poly_bb_p find_pbb_via_hash (htab_t, basic_block);
-bool loop_is_parallel_p (loop_p, htab_t, int);
-scop_p get_loop_body_pbbs (loop_p, htab_t, vec<poly_bb_p> *);
isl_map *reverse_loop_at_level (poly_bb_p, int);
isl_union_map *reverse_loop_for_pbbs (scop_p, vec<poly_bb_p> , int);
__isl_give isl_union_map *extend_schedule (__isl_take isl_union_map *);
diff --git a/gcc/graphite.c b/gcc/graphite.c
index 7511527de0b..10d1dd510c9 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
#include "graphite-scop-detection.h"
#include "graphite-clast-to-gimple.h"
#include "graphite-sese-to-poly.h"
+#include "graphite-htab.h"
CloogState *cloog_state;
@@ -255,7 +256,7 @@ graphite_transform_loops (void)
scop_p scop;
bool need_cfg_cleanup_p = false;
vec<scop_p> scops = vNULL;
- htab_t bb_pbb_mapping;
+ bb_pbb_htab_type bb_pbb_mapping;
isl_ctx *ctx;
/* If a function is parallel it was most probably already run through graphite
@@ -277,7 +278,7 @@ graphite_transform_loops (void)
print_global_statistics (dump_file);
}
- bb_pbb_mapping = htab_create (10, bb_pbb_map_hash, eq_bb_pbb_map, free);
+ bb_pbb_mapping.create (10);
FOR_EACH_VEC_ELT (scops, i, scop)
if (dbg_cnt (graphite_scop))
@@ -291,7 +292,7 @@ graphite_transform_loops (void)
need_cfg_cleanup_p = true;
}
- htab_delete (bb_pbb_mapping);
+ bb_pbb_mapping.dispose ();
free_scops (scops);
graphite_finalize (need_cfg_cleanup_p);
the_isl_ctx = NULL;
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index c4591bfe35b..34c0f2cbff1 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -145,7 +145,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "ira.h"
#include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
-#include "hashtab.h"
+#include "hash-table.h"
#include "dumpfile.h"
#ifdef INSN_SCHEDULING
@@ -581,22 +581,72 @@ struct delay_pair
int stages;
};
+/* Helpers for delay hashing. */
+
+struct delay_i1_hasher : typed_noop_remove <delay_pair>
+{
+ typedef delay_pair value_type;
+ typedef void compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Returns a hash value for X, based on hashing just I1. */
+
+inline hashval_t
+delay_i1_hasher::hash (const value_type *x)
+{
+ return htab_hash_pointer (x->i1);
+}
+
+/* Return true if I1 of pair X is the same as that of pair Y. */
+
+inline bool
+delay_i1_hasher::equal (const value_type *x, const compare_type *y)
+{
+ return x->i1 == y;
+}
+
+struct delay_i2_hasher : typed_free_remove <delay_pair>
+{
+ typedef delay_pair value_type;
+ typedef void compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Returns a hash value for X, based on hashing just I2. */
+
+inline hashval_t
+delay_i2_hasher::hash (const value_type *x)
+{
+ return htab_hash_pointer (x->i2);
+}
+
+/* Return true if I2 of pair X is the same as that of pair Y. */
+
+inline bool
+delay_i2_hasher::equal (const value_type *x, const compare_type *y)
+{
+ return x->i2 == y;
+}
+
/* Two hash tables to record delay_pairs, one indexed by I1 and the other
indexed by I2. */
-static htab_t delay_htab;
-static htab_t delay_htab_i2;
+static hash_table <delay_i1_hasher> delay_htab;
+static hash_table <delay_i2_hasher> delay_htab_i2;
/* Called through htab_traverse. Walk the hashtable using I2 as
index, and delete all elements involving an UID higher than
that pointed to by *DATA. */
-static int
-htab_i2_traverse (void **slot, void *data)
+int
+haifa_htab_i2_traverse (delay_pair **slot, int *data)
{
- int maxuid = *(int *)data;
- struct delay_pair *p = *(struct delay_pair **)slot;
+ int maxuid = *data;
+ struct delay_pair *p = *slot;
if (INSN_UID (p->i2) >= maxuid || INSN_UID (p->i1) >= maxuid)
{
- htab_clear_slot (delay_htab_i2, slot);
+ delay_htab_i2.clear_slot (slot);
}
return 1;
}
@@ -604,16 +654,15 @@ htab_i2_traverse (void **slot, void *data)
/* Called through htab_traverse. Walk the hashtable using I2 as
index, and delete all elements involving an UID higher than
that pointed to by *DATA. */
-static int
-htab_i1_traverse (void **slot, void *data)
+int
+haifa_htab_i1_traverse (delay_pair **pslot, int *data)
{
- int maxuid = *(int *)data;
- struct delay_pair **pslot = (struct delay_pair **)slot;
+ int maxuid = *data;
struct delay_pair *p, *first, **pprev;
if (INSN_UID ((*pslot)->i1) >= maxuid)
{
- htab_clear_slot (delay_htab, slot);
+ delay_htab.clear_slot (pslot);
return 1;
}
pprev = &first;
@@ -627,7 +676,7 @@ htab_i1_traverse (void **slot, void *data)
}
*pprev = NULL;
if (first == NULL)
- htab_clear_slot (delay_htab, slot);
+ delay_htab.clear_slot (pslot);
else
*pslot = first;
return 1;
@@ -638,38 +687,8 @@ htab_i1_traverse (void **slot, void *data)
void
discard_delay_pairs_above (int max_uid)
{
- htab_traverse (delay_htab, htab_i1_traverse, &max_uid);
- htab_traverse (delay_htab_i2, htab_i2_traverse, &max_uid);
-}
-
-/* Returns a hash value for X (which really is a delay_pair), based on
- hashing just I1. */
-static hashval_t
-delay_hash_i1 (const void *x)
-{
- return htab_hash_pointer (((const struct delay_pair *) x)->i1);
-}
-
-/* Returns a hash value for X (which really is a delay_pair), based on
- hashing just I2. */
-static hashval_t
-delay_hash_i2 (const void *x)
-{
- return htab_hash_pointer (((const struct delay_pair *) x)->i2);
-}
-
-/* Return nonzero if I1 of pair X is the same as that of pair Y. */
-static int
-delay_i1_eq (const void *x, const void *y)
-{
- return ((const struct delay_pair *) x)->i1 == y;
-}
-
-/* Return nonzero if I2 of pair X is the same as that of pair Y. */
-static int
-delay_i2_eq (const void *x, const void *y)
-{
- return ((const struct delay_pair *) x)->i2 == y;
+ delay_htab.traverse <int *, haifa_htab_i1_traverse> (&max_uid);
+ delay_htab_i2.traverse <int *, haifa_htab_i2_traverse> (&max_uid);
}
/* This function can be called by a port just before it starts the final
@@ -699,19 +718,15 @@ record_delay_slot_pair (rtx i1, rtx i2, int cycles, int stages)
p->cycles = cycles;
p->stages = stages;
- if (!delay_htab)
+ if (!delay_htab.is_created ())
{
- delay_htab = htab_create (10, delay_hash_i1, delay_i1_eq, NULL);
- delay_htab_i2 = htab_create (10, delay_hash_i2, delay_i2_eq, free);
+ delay_htab.create (10);
+ delay_htab_i2.create (10);
}
- slot = ((struct delay_pair **)
- htab_find_slot_with_hash (delay_htab, i1, htab_hash_pointer (i1),
- INSERT));
+ slot = delay_htab.find_slot_with_hash (i1, htab_hash_pointer (i1), INSERT);
p->next_same_i1 = *slot;
*slot = p;
- slot = ((struct delay_pair **)
- htab_find_slot_with_hash (delay_htab_i2, i2, htab_hash_pointer (i2),
- INSERT));
+ slot = delay_htab_i2.find_slot_with_hash (i2, htab_hash_pointer (i2), INSERT);
*slot = p;
}
@@ -722,12 +737,10 @@ real_insn_for_shadow (rtx insn)
{
struct delay_pair *pair;
- if (delay_htab == NULL)
+ if (!delay_htab.is_created ())
return NULL_RTX;
- pair
- = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, insn,
- htab_hash_pointer (insn));
+ pair = delay_htab_i2.find_with_hash (insn, htab_hash_pointer (insn));
if (!pair || pair->stages > 0)
return NULL_RTX;
return pair->i1;
@@ -755,12 +768,10 @@ add_delay_dependencies (rtx insn)
sd_iterator_def sd_it;
dep_t dep;
- if (!delay_htab)
+ if (!delay_htab.is_created ())
return;
- pair
- = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, insn,
- htab_hash_pointer (insn));
+ pair = delay_htab_i2.find_with_hash (insn, htab_hash_pointer (insn));
if (!pair)
return;
add_dependence (insn, pair->i1, REG_DEP_ANTI);
@@ -771,8 +782,7 @@ add_delay_dependencies (rtx insn)
{
rtx pro = DEP_PRO (dep);
struct delay_pair *other_pair
- = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, pro,
- htab_hash_pointer (pro));
+ = delay_htab_i2.find_with_hash (pro, htab_hash_pointer (pro));
if (!other_pair || other_pair->stages)
continue;
if (pair_delay (other_pair) >= pair_delay (pair))
@@ -1395,12 +1405,11 @@ dep_cost_1 (dep_t link, dw_t dw)
if (DEP_COST (link) != UNKNOWN_DEP_COST)
return DEP_COST (link);
- if (delay_htab)
+ if (delay_htab.is_created ())
{
struct delay_pair *delay_entry;
delay_entry
- = (struct delay_pair *)htab_find_with_hash (delay_htab_i2, used,
- htab_hash_pointer (used));
+ = delay_htab_i2.find_with_hash (used, htab_hash_pointer (used));
if (delay_entry)
{
if (delay_entry->i1 == insn)
@@ -5726,12 +5735,12 @@ prune_ready_list (state_t temp_state, bool first_cycle_insn_p,
{
int delay_cost = 0;
- if (delay_htab)
+ if (delay_htab.is_created ())
{
struct delay_pair *delay_entry;
delay_entry
- = (struct delay_pair *)htab_find_with_hash (delay_htab, insn,
- htab_hash_pointer (insn));
+ = delay_htab.find_with_hash (insn,
+ htab_hash_pointer (insn));
while (delay_entry && delay_cost == 0)
{
delay_cost = estimate_shadow_tick (delay_entry);
@@ -6189,14 +6198,13 @@ schedule_block (basic_block *target_bb, state_t init_state)
goto restart_choose_ready;
}
- if (delay_htab)
+ if (delay_htab.is_created ())
{
/* If this insn is the first part of a delay-slot pair, record a
backtrack point. */
struct delay_pair *delay_entry;
delay_entry
- = (struct delay_pair *)htab_find_with_hash (delay_htab, insn,
- htab_hash_pointer (insn));
+ = delay_htab.find_with_hash (insn, htab_hash_pointer (insn));
if (delay_entry)
{
save_backtrack_point (delay_entry, ls);
@@ -6761,10 +6769,10 @@ sched_finish (void)
void
free_delay_pairs (void)
{
- if (delay_htab)
+ if (delay_htab.is_created ())
{
- htab_empty (delay_htab);
- htab_empty (delay_htab_i2);
+ delay_htab.empty ();
+ delay_htab_i2.empty ();
}
}
diff --git a/gcc/hash-table.h b/gcc/hash-table.h
index 206423dc58b..00637789923 100644
--- a/gcc/hash-table.h
+++ b/gcc/hash-table.h
@@ -155,6 +155,47 @@ along with GCC; see the file COPYING3. If not see
hash_table <pointer_hash <whatever_type>> whatever_type_hash_table;
+
+ HASH TABLE ITERATORS
+
+ The hash table provides standard C++ iterators. For example, consider a
+ hash table of some_info. We wish to consume each element of the table:
+
+ extern void consume (some_info *);
+
+ We define a convenience typedef and the hash table:
+
+ typedef hash_table <some_info_hasher> info_table_type;
+ info_table_type info_table;
+
+ Then we write the loop in typical C++ style:
+
+ for (info_table_type::iterator iter = info_table.begin ();
+ iter != info_table.end ();
+ ++iter)
+ if ((*iter).status == INFO_READY)
+ consume (&*iter);
+
+ Or with common sub-expression elimination:
+
+ for (info_table_type::iterator iter = info_table.begin ();
+ iter != info_table.end ();
+ ++iter)
+ {
+ some_info &elem = *iter;
+ if (elem.status == INFO_READY)
+ consume (&elem);
+ }
+
+ One can also use a more typical GCC style:
+
+ typedef some_info *some_info_p;
+ some_info *elem_ptr;
+ info_table_type::iterator iter;
+ FOR_EACH_HASH_TABLE_ELEMENT (info_table, elem_ptr, some_info_p, iter)
+ if (elem_ptr->status == INFO_READY)
+ consume (elem_ptr);
+
*/
@@ -368,6 +409,20 @@ public:
typedef typename Descriptor::value_type value_type;
typedef typename Descriptor::compare_type compare_type;
+ class iterator
+ {
+ public:
+ inline iterator ();
+ inline iterator (value_type **, value_type **);
+ inline value_type &operator * ();
+ void slide ();
+ inline iterator &operator ++ ();
+ inline bool operator != (const iterator &) const;
+ private:
+ value_type **slot_;
+ value_type **limit_;
+ };
+
private:
hash_table_control <value_type> *htab;
@@ -379,19 +434,19 @@ public:
void create (size_t initial_slots);
bool is_created ();
void dispose ();
- value_type *find (const compare_type *comparable);
+ value_type *find (const value_type *value);
value_type *find_with_hash (const compare_type *comparable, hashval_t hash);
- value_type **find_slot (const compare_type *comparable,
- enum insert_option insert);
+ value_type **find_slot (const value_type *value, enum insert_option insert);
value_type **find_slot_with_hash (const compare_type *comparable,
hashval_t hash, enum insert_option insert);
void empty ();
void clear_slot (value_type **slot);
- void remove_elt (const compare_type *comparable);
+ void remove_elt (const value_type *value);
void remove_elt_with_hash (const compare_type *comparable, hashval_t hash);
- size_t size();
- size_t elements();
- double collisions();
+ size_t size ();
+ size_t elements ();
+ size_t elements_with_deleted ();
+ double collisions ();
template <typename Argument,
int (*Callback) (value_type **slot, Argument argument)>
@@ -400,6 +455,9 @@ public:
template <typename Argument,
int (*Callback) (value_type **slot, Argument argument)>
void traverse (Argument argument);
+
+ iterator begin();
+ iterator end();
};
@@ -430,9 +488,9 @@ hash_table <Descriptor, Allocator>::is_created ()
template <typename Descriptor,
template <typename Type> class Allocator>
inline typename Descriptor::value_type *
-hash_table <Descriptor, Allocator>::find (const compare_type *comparable)
+hash_table <Descriptor, Allocator>::find (const value_type *value)
{
- return find_with_hash (comparable, Descriptor::hash (comparable));
+ return find_with_hash (value, Descriptor::hash (value));
}
@@ -442,9 +500,9 @@ template <typename Descriptor,
template <typename Type> class Allocator>
inline typename Descriptor::value_type **
hash_table <Descriptor, Allocator>
-::find_slot (const compare_type *comparable, enum insert_option insert)
+::find_slot (const value_type *value, enum insert_option insert)
{
- return find_slot_with_hash (comparable, Descriptor::hash (comparable), insert);
+ return find_slot_with_hash (value, Descriptor::hash (value), insert);
}
@@ -453,9 +511,9 @@ hash_table <Descriptor, Allocator>
template <typename Descriptor,
template <typename Type> class Allocator>
inline void
-hash_table <Descriptor, Allocator>::remove_elt (const compare_type *comparable)
+hash_table <Descriptor, Allocator>::remove_elt (const value_type *value)
{
- remove_elt_with_hash (comparable, Descriptor::hash (comparable));
+ remove_elt_with_hash (value, Descriptor::hash (value));
}
@@ -475,12 +533,23 @@ hash_table <Descriptor, Allocator>::size()
template <typename Descriptor,
template <typename Type> class Allocator>
inline size_t
-hash_table <Descriptor, Allocator>::elements()
+hash_table <Descriptor, Allocator>::elements ()
{
return htab->n_elements - htab->n_deleted;
}
+/* Return the current number of elements in this hash table. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline size_t
+hash_table <Descriptor, Allocator>::elements_with_deleted ()
+{
+ return htab->n_elements;
+}
+
+
/* Return the fraction of fixed collisions during all work with given
hash table. */
@@ -881,4 +950,114 @@ hash_table <Descriptor, Allocator>::traverse (Argument argument)
traverse_noresize <Argument, Callback> (argument);
}
+
+/* Iterator definitions. */
+
+/* The default constructor produces the end value. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline
+hash_table <Descriptor, Allocator>::iterator::iterator ()
+: slot_ (NULL), limit_ (NULL)
+{
+}
+
+/* The parameterized constructor produces the begin value. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline
+hash_table <Descriptor, Allocator>::iterator::iterator
+ (value_type **slot, value_type **limit)
+: slot_ (slot), limit_ (limit)
+{
+}
+
+/* Obtain the element. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::value_type &
+hash_table <Descriptor, Allocator>::iterator::operator * ()
+{
+ return **slot_;
+}
+
+/* Slide down the iterator slots until an active entry is found. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+void
+hash_table <Descriptor, Allocator>::iterator::slide ()
+{
+ for ( ; slot_ < limit_; ++slot_ )
+ {
+ value_type *x = *slot_;
+ if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
+ return;
+ }
+ slot_ = NULL;
+ limit_ = NULL;
+}
+
+/* Bump the iterator. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::iterator &
+hash_table <Descriptor, Allocator>::iterator::operator ++ ()
+{
+ ++slot_;
+ slide ();
+ return *this;
+}
+
+/* Compare iterators. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline bool
+hash_table <Descriptor, Allocator>::iterator::
+ operator != (const iterator &other) const
+{
+ return slot_ != other.slot_ || limit_ != other.limit_;
+}
+
+/* Hash table iterator producers. */
+
+/* The beginning of a hash table iteration. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::iterator
+hash_table <Descriptor, Allocator>::begin ()
+{
+ iterator hti (htab->entries, htab->entries + htab->size);
+ hti.slide ();
+ return hti;
+}
+
+/* The end of a hash table iteration. */
+
+template <typename Descriptor,
+ template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::iterator
+hash_table <Descriptor, Allocator>::end ()
+{
+ return iterator ();
+}
+
+/* Iterate through the elements of hash_table HTAB,
+ using hash_table <....>::iterator ITER,
+ storing each element in RESULT, which is of type TYPE.
+
+ This macro has this form for compatibility with the
+ FOR_EACH_HTAB_ELEMENT currently defined in tree-flow.h. */
+
+#define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
+ for ((ITER) = (HTAB).begin (); \
+ (ITER) != (HTAB).end () ? (RESULT = &*(ITER) , true) : false; \
+ ++(ITER))
+
#endif /* TYPED_HASHTAB_H */
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index dea47fef2d7..0ee31573e2e 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "sbitmap.h"
#include "bitmap.h"
+#include "hash-table.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "expr.h"
@@ -173,33 +174,36 @@ static vec<ira_allocno_t> allocno_stack_vec;
/* Vector of unique allocno hard registers. */
static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
-/* Returns hash value for allocno hard registers V. */
-static hashval_t
-allocno_hard_regs_hash (const void *v)
+struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
{
- const struct allocno_hard_regs *hv = (const struct allocno_hard_regs *) v;
+ typedef allocno_hard_regs value_type;
+ typedef allocno_hard_regs compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+/* Returns hash value for allocno hard registers V. */
+inline hashval_t
+allocno_hard_regs_hasher::hash (const value_type *hv)
+{
return iterative_hash (&hv->set, sizeof (HARD_REG_SET), 0);
}
/* Compares allocno hard registers V1 and V2. */
-static int
-allocno_hard_regs_eq (const void *v1, const void *v2)
+inline bool
+allocno_hard_regs_hasher::equal (const value_type *hv1, const compare_type *hv2)
{
- const struct allocno_hard_regs *hv1 = (const struct allocno_hard_regs *) v1;
- const struct allocno_hard_regs *hv2 = (const struct allocno_hard_regs *) v2;
-
return hard_reg_set_equal_p (hv1->set, hv2->set);
}
/* Hash table of unique allocno hard registers. */
-static htab_t allocno_hard_regs_htab;
+static hash_table <allocno_hard_regs_hasher> allocno_hard_regs_htab;
/* Return allocno hard registers in the hash table equal to HV. */
static allocno_hard_regs_t
find_hard_regs (allocno_hard_regs_t hv)
{
- return (allocno_hard_regs_t) htab_find (allocno_hard_regs_htab, hv);
+ return allocno_hard_regs_htab.find (hv);
}
/* Insert allocno hard registers HV in the hash table (if it is not
@@ -207,11 +211,11 @@ find_hard_regs (allocno_hard_regs_t hv)
static allocno_hard_regs_t
insert_hard_regs (allocno_hard_regs_t hv)
{
- PTR *slot = htab_find_slot (allocno_hard_regs_htab, hv, INSERT);
+ allocno_hard_regs **slot = allocno_hard_regs_htab.find_slot (hv, INSERT);
if (*slot == NULL)
*slot = hv;
- return (allocno_hard_regs_t) *slot;
+ return *slot;
}
/* Initialize data concerning allocno hard registers. */
@@ -219,8 +223,7 @@ static void
init_allocno_hard_regs (void)
{
allocno_hard_regs_vec.create (200);
- allocno_hard_regs_htab
- = htab_create (200, allocno_hard_regs_hash, allocno_hard_regs_eq, NULL);
+ allocno_hard_regs_htab.create (200);
}
/* Add (or update info about) allocno hard registers with SET and
@@ -258,7 +261,7 @@ finish_allocno_hard_regs (void)
allocno_hard_regs_vec.iterate (i, &hv);
i++)
ira_free (hv);
- htab_delete (allocno_hard_regs_htab);
+ allocno_hard_regs_htab.dispose ();
allocno_hard_regs_vec.release ();
}
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 1de006129ed..03147625f55 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "hash-table.h"
#include "hard-reg-set.h"
#include "rtl.h"
#include "expr.h"
@@ -131,35 +132,41 @@ typedef const struct cost_classes *const_cost_classes_t;
/* Info about cost classes for each pseudo. */
static cost_classes_t *regno_cost_classes;
-/* Returns hash value for cost classes info V. */
-static hashval_t
-cost_classes_hash (const void *v)
+/* Helper for cost_classes hashing. */
+
+struct cost_classes_hasher
{
- const_cost_classes_t hv = (const_cost_classes_t) v;
+ typedef cost_classes value_type;
+ typedef cost_classes compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+/* Returns hash value for cost classes info HV. */
+inline hashval_t
+cost_classes_hasher::hash (const value_type *hv)
+{
return iterative_hash (&hv->classes, sizeof (enum reg_class) * hv->num, 0);
}
-/* Compares cost classes info V1 and V2. */
-static int
-cost_classes_eq (const void *v1, const void *v2)
+/* Compares cost classes info HV1 and HV2. */
+inline bool
+cost_classes_hasher::equal (const value_type *hv1, const compare_type *hv2)
{
- const_cost_classes_t hv1 = (const_cost_classes_t) v1;
- const_cost_classes_t hv2 = (const_cost_classes_t) v2;
-
return hv1->num == hv2->num && memcmp (hv1->classes, hv2->classes,
sizeof (enum reg_class) * hv1->num);
}
/* Delete cost classes info V from the hash table. */
-static void
-cost_classes_del (void *v)
+inline void
+cost_classes_hasher::remove (value_type *v)
{
ira_free (v);
}
/* Hash table of unique cost classes. */
-static htab_t cost_classes_htab;
+static hash_table <cost_classes_hasher> cost_classes_htab;
/* Map allocno class -> cost classes for pseudo of given allocno
class. */
@@ -180,8 +187,7 @@ initiate_regno_cost_classes (void)
sizeof (cost_classes_t) * N_REG_CLASSES);
memset (cost_classes_mode_cache, 0,
sizeof (cost_classes_t) * MAX_MACHINE_MODE);
- cost_classes_htab
- = htab_create (200, cost_classes_hash, cost_classes_eq, cost_classes_del);
+ cost_classes_htab.create (200);
}
/* Create new cost classes from cost classes FROM and set up members
@@ -229,7 +235,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
cost_classes_t classes_ptr;
enum reg_class cl;
int i;
- PTR *slot;
+ cost_classes **slot;
HARD_REG_SET temp, temp2;
bool exclude_p;
@@ -255,7 +261,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
}
classes.classes[classes.num++] = cl;
}
- slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
+ slot = cost_classes_htab.find_slot (&classes, INSERT);
if (*slot == NULL)
{
classes_ptr = setup_cost_classes (&classes);
@@ -279,7 +285,7 @@ setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
cost_classes_t classes_ptr;
enum reg_class cl;
int i;
- PTR *slot;
+ cost_classes **slot;
HARD_REG_SET temp;
if ((classes_ptr = cost_classes_mode_cache[mode]) == NULL)
@@ -294,7 +300,7 @@ setup_regno_cost_classes_by_mode (int regno, enum machine_mode mode)
continue;
classes.classes[classes.num++] = cl;
}
- slot = htab_find_slot (cost_classes_htab, &classes, INSERT);
+ slot = cost_classes_htab.find_slot (&classes, INSERT);
if (*slot == NULL)
{
classes_ptr = setup_cost_classes (&classes);
@@ -312,7 +318,7 @@ static void
finish_regno_cost_classes (void)
{
ira_free (regno_cost_classes);
- htab_delete (cost_classes_htab);
+ cost_classes_htab.dispose ();
}
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index f8a1b0ed846..73200e199b2 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -50,7 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "flags.h"
#include "df.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "except.h"
#include "params.h"
#include "regs.h"
@@ -424,27 +424,28 @@ invariant_expr_equal_p (rtx insn1, rtx e1, rtx insn2, rtx e2)
return true;
}
-/* Returns hash value for invariant expression entry E. */
-
-static hashval_t
-hash_invariant_expr (const void *e)
+struct invariant_expr_hasher : typed_free_remove <invariant_expr_entry>
{
- const struct invariant_expr_entry *const entry =
- (const struct invariant_expr_entry *) e;
+ typedef invariant_expr_entry value_type;
+ typedef invariant_expr_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Returns hash value for invariant expression entry ENTRY. */
+inline hashval_t
+invariant_expr_hasher::hash (const value_type *entry)
+{
return entry->hash;
}
-/* Compares invariant expression entries E1 and E2. */
+/* Compares invariant expression entries ENTRY1 and ENTRY2. */
-static int
-eq_invariant_expr (const void *e1, const void *e2)
+inline bool
+invariant_expr_hasher::equal (const value_type *entry1,
+ const compare_type *entry2)
{
- const struct invariant_expr_entry *const entry1 =
- (const struct invariant_expr_entry *) e1;
- const struct invariant_expr_entry *const entry2 =
- (const struct invariant_expr_entry *) e2;
-
if (entry1->mode != entry2->mode)
return 0;
@@ -452,24 +453,26 @@ eq_invariant_expr (const void *e1, const void *e2)
entry2->inv->insn, entry2->expr);
}
+typedef hash_table <invariant_expr_hasher> invariant_htab_type;
+
/* Checks whether invariant with value EXPR in machine mode MODE is
recorded in EQ. If this is the case, return the invariant. Otherwise
insert INV to the table for this expression and return INV. */
static struct invariant *
-find_or_insert_inv (htab_t eq, rtx expr, enum machine_mode mode,
+find_or_insert_inv (invariant_htab_type eq, rtx expr, enum machine_mode mode,
struct invariant *inv)
{
hashval_t hash = hash_invariant_expr_1 (inv->insn, expr);
struct invariant_expr_entry *entry;
struct invariant_expr_entry pentry;
- PTR *slot;
+ invariant_expr_entry **slot;
pentry.expr = expr;
pentry.inv = inv;
pentry.mode = mode;
- slot = htab_find_slot_with_hash (eq, &pentry, hash, INSERT);
- entry = (struct invariant_expr_entry *) *slot;
+ slot = eq.find_slot_with_hash (&pentry, hash, INSERT);
+ entry = *slot;
if (entry)
return entry->inv;
@@ -488,7 +491,7 @@ find_or_insert_inv (htab_t eq, rtx expr, enum machine_mode mode,
hash table of the invariants. */
static void
-find_identical_invariants (htab_t eq, struct invariant *inv)
+find_identical_invariants (invariant_htab_type eq, struct invariant *inv)
{
unsigned depno;
bitmap_iterator bi;
@@ -525,13 +528,13 @@ merge_identical_invariants (void)
{
unsigned i;
struct invariant *inv;
- htab_t eq = htab_create (invariants.length (),
- hash_invariant_expr, eq_invariant_expr, free);
+ invariant_htab_type eq;
+ eq.create (invariants.length ());
FOR_EACH_VEC_ELT (invariants, i, inv)
find_identical_invariants (eq, inv);
- htab_delete (eq);
+ eq.dispose ();
}
/* Determines the basic blocks inside LOOP that are always executed and
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 0847307e1a8..d4ecd0e014f 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -60,7 +60,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "diagnostic-core.h"
#include "df.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "dumpfile.h"
/* Possible return values of iv_get_reaching_def. */
@@ -106,9 +106,35 @@ static struct rtx_iv ** iv_ref_table;
static struct loop *current_loop;
+/* Hashtable helper. */
+
+struct biv_entry_hasher : typed_free_remove <biv_entry>
+{
+ typedef biv_entry value_type;
+ typedef rtx_def compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Returns hash value for biv B. */
+
+inline hashval_t
+biv_entry_hasher::hash (const value_type *b)
+{
+ return b->regno;
+}
+
+/* Compares biv B and register R. */
+
+inline bool
+biv_entry_hasher::equal (const value_type *b, const compare_type *r)
+{
+ return b->regno == REGNO (r);
+}
+
/* Bivs of the current loop. */
-static htab_t bivs;
+static hash_table <biv_entry_hasher> bivs;
static bool iv_analyze_op (rtx, rtx, struct rtx_iv *);
@@ -243,24 +269,9 @@ clear_iv_info (void)
}
}
- htab_empty (bivs);
-}
-
-/* Returns hash value for biv B. */
-
-static hashval_t
-biv_hash (const void *b)
-{
- return ((const struct biv_entry *) b)->regno;
+ bivs.empty ();
}
-/* Compares biv B and register R. */
-
-static int
-biv_eq (const void *b, const void *r)
-{
- return ((const struct biv_entry *) b)->regno == REGNO ((const_rtx) r);
-}
/* Prepare the data for an induction variable analysis of a LOOP. */
@@ -277,7 +288,7 @@ iv_analysis_loop_init (struct loop *loop)
if (clean_slate)
{
df_set_flags (DF_EQ_NOTES + DF_DEFER_INSN_RESCAN);
- bivs = htab_create (10, biv_hash, biv_eq, free);
+ bivs.create (10);
clean_slate = false;
}
else
@@ -837,8 +848,7 @@ record_iv (df_ref def, struct rtx_iv *iv)
static bool
analyzed_for_bivness_p (rtx def, struct rtx_iv *iv)
{
- struct biv_entry *biv =
- (struct biv_entry *) htab_find_with_hash (bivs, def, REGNO (def));
+ struct biv_entry *biv = bivs.find_with_hash (def, REGNO (def));
if (!biv)
return false;
@@ -851,7 +861,7 @@ static void
record_biv (rtx def, struct rtx_iv *iv)
{
struct biv_entry *biv = XNEW (struct biv_entry);
- void **slot = htab_find_slot_with_hash (bivs, def, REGNO (def), INSERT);
+ biv_entry **slot = bivs.find_slot_with_hash (def, REGNO (def), INSERT);
biv->regno = REGNO (def);
biv->iv = *iv;
@@ -1293,11 +1303,10 @@ iv_analysis_done (void)
clear_iv_info ();
clean_slate = true;
df_finish_pass (true);
- htab_delete (bivs);
+ bivs.dispose ();
free (iv_ref_table);
iv_ref_table = NULL;
iv_ref_table_size = 0;
- bivs = NULL;
}
}
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 1eb904b5061..41d9e5f0fad 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "params.h"
#include "expr.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "recog.h"
#include "target.h"
#include "dumpfile.h"
@@ -102,16 +102,70 @@ struct var_to_expand
var_expansions[REUSE_EXPANSION - 1]. */
};
+/* Hashtable helper for iv_to_split. */
+
+struct iv_split_hasher : typed_free_remove <iv_to_split>
+{
+ typedef iv_to_split value_type;
+ typedef iv_to_split compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+
+/* A hash function for information about insns to split. */
+
+inline hashval_t
+iv_split_hasher::hash (const value_type *ivts)
+{
+ return (hashval_t) INSN_UID (ivts->insn);
+}
+
+/* An equality functions for information about insns to split. */
+
+inline bool
+iv_split_hasher::equal (const value_type *i1, const compare_type *i2)
+{
+ return i1->insn == i2->insn;
+}
+
+/* Hashtable helper for iv_to_split. */
+
+struct var_expand_hasher : typed_free_remove <var_to_expand>
+{
+ typedef var_to_expand value_type;
+ typedef var_to_expand compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Return a hash for VES. */
+
+inline hashval_t
+var_expand_hasher::hash (const value_type *ves)
+{
+ return (hashval_t) INSN_UID (ves->insn);
+}
+
+/* Return true if I1 and I2 refer to the same instruction. */
+
+inline bool
+var_expand_hasher::equal (const value_type *i1, const compare_type *i2)
+{
+ return i1->insn == i2->insn;
+}
+
/* Information about optimization applied in
the unrolled loop. */
struct opt_info
{
- htab_t insns_to_split; /* A hashtable of insns to split. */
+ hash_table <iv_split_hasher> insns_to_split; /* A hashtable of insns to
+ split. */
struct iv_to_split *iv_to_split_head; /* The first iv to split. */
struct iv_to_split **iv_to_split_tail; /* Pointer to the tail of the list. */
- htab_t insns_with_var_to_expand; /* A hashtable of insns with accumulators
- to expand. */
+ hash_table <var_expand_hasher> insns_with_var_to_expand; /* A hashtable of
+ insns with accumulators to expand. */
struct var_to_expand *var_to_expand_head; /* The first var to expand. */
struct var_to_expand **var_to_expand_tail; /* Pointer to the tail of the list. */
unsigned first_new_block; /* The first basic block that was
@@ -1585,45 +1639,6 @@ unroll_loop_stupid (struct loop *loop)
nunroll, num_loop_insns (loop));
}
-/* A hash function for information about insns to split. */
-
-static hashval_t
-si_info_hash (const void *ivts)
-{
- return (hashval_t) INSN_UID (((const struct iv_to_split *) ivts)->insn);
-}
-
-/* An equality functions for information about insns to split. */
-
-static int
-si_info_eq (const void *ivts1, const void *ivts2)
-{
- const struct iv_to_split *const i1 = (const struct iv_to_split *) ivts1;
- const struct iv_to_split *const i2 = (const struct iv_to_split *) ivts2;
-
- return i1->insn == i2->insn;
-}
-
-/* Return a hash for VES, which is really a "var_to_expand *". */
-
-static hashval_t
-ve_info_hash (const void *ves)
-{
- return (hashval_t) INSN_UID (((const struct var_to_expand *) ves)->insn);
-}
-
-/* Return true if IVTS1 and IVTS2 (which are really both of type
- "var_to_expand *") refer to the same instruction. */
-
-static int
-ve_info_eq (const void *ivts1, const void *ivts2)
-{
- const struct var_to_expand *const i1 = (const struct var_to_expand *) ivts1;
- const struct var_to_expand *const i2 = (const struct var_to_expand *) ivts2;
-
- return i1->insn == i2->insn;
-}
-
/* Returns true if REG is referenced in one nondebug insn in LOOP.
Set *DEBUG_USES to the number of debug insns that reference the
variable. */
@@ -1908,8 +1923,8 @@ analyze_insns_in_loop (struct loop *loop)
rtx insn;
struct iv_to_split *ivts = NULL;
struct var_to_expand *ves = NULL;
- PTR *slot1;
- PTR *slot2;
+ iv_to_split **slot1;
+ var_to_expand **slot2;
vec<edge> edges = get_loop_exit_edges (loop);
edge exit;
bool can_apply = false;
@@ -1920,8 +1935,7 @@ analyze_insns_in_loop (struct loop *loop)
if (flag_split_ivs_in_unroller)
{
- opt_info->insns_to_split = htab_create (5 * loop->num_nodes,
- si_info_hash, si_info_eq, free);
+ opt_info->insns_to_split.create (5 * loop->num_nodes);
opt_info->iv_to_split_head = NULL;
opt_info->iv_to_split_tail = &opt_info->iv_to_split_head;
}
@@ -1942,9 +1956,7 @@ analyze_insns_in_loop (struct loop *loop)
if (flag_variable_expansion_in_unroller
&& can_apply)
{
- opt_info->insns_with_var_to_expand = htab_create (5 * loop->num_nodes,
- ve_info_hash,
- ve_info_eq, free);
+ opt_info->insns_with_var_to_expand.create (5 * loop->num_nodes);
opt_info->var_to_expand_head = NULL;
opt_info->var_to_expand_tail = &opt_info->var_to_expand_head;
}
@@ -1960,12 +1972,12 @@ analyze_insns_in_loop (struct loop *loop)
if (!INSN_P (insn))
continue;
- if (opt_info->insns_to_split)
+ if (opt_info->insns_to_split.is_created ())
ivts = analyze_iv_to_split_insn (insn);
if (ivts)
{
- slot1 = htab_find_slot (opt_info->insns_to_split, ivts, INSERT);
+ slot1 = opt_info->insns_to_split.find_slot (ivts, INSERT);
gcc_assert (*slot1 == NULL);
*slot1 = ivts;
*opt_info->iv_to_split_tail = ivts;
@@ -1973,12 +1985,12 @@ analyze_insns_in_loop (struct loop *loop)
continue;
}
- if (opt_info->insns_with_var_to_expand)
+ if (opt_info->insns_with_var_to_expand.is_created ())
ves = analyze_insn_to_expand_var (loop, insn);
if (ves)
{
- slot2 = htab_find_slot (opt_info->insns_with_var_to_expand, ves, INSERT);
+ slot2 = opt_info->insns_with_var_to_expand.find_slot (ves, INSERT);
gcc_assert (*slot2 == NULL);
*slot2 = ves;
*opt_info->var_to_expand_tail = ves;
@@ -2356,7 +2368,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
gcc_assert (!unrolling || rewrite_original_loop);
/* Allocate the basic variables (i0). */
- if (opt_info->insns_to_split)
+ if (opt_info->insns_to_split.is_created ())
for (ivts = opt_info->iv_to_split_head; ivts; ivts = ivts->next)
allocate_basic_variable (ivts);
@@ -2388,12 +2400,11 @@ apply_opt_in_copies (struct opt_info *opt_info,
ve_templ.insn = orig_insn;
/* Apply splitting iv optimization. */
- if (opt_info->insns_to_split)
+ if (opt_info->insns_to_split.is_created ())
{
maybe_strip_eq_note_for_split_iv (opt_info, insn);
- ivts = (struct iv_to_split *)
- htab_find (opt_info->insns_to_split, &ivts_templ);
+ ivts = opt_info->insns_to_split.find (&ivts_templ);
if (ivts)
{
@@ -2406,10 +2417,10 @@ apply_opt_in_copies (struct opt_info *opt_info,
}
}
/* Apply variable expansion optimization. */
- if (unrolling && opt_info->insns_with_var_to_expand)
+ if (unrolling && opt_info->insns_with_var_to_expand.is_created ())
{
ves = (struct var_to_expand *)
- htab_find (opt_info->insns_with_var_to_expand, &ve_templ);
+ opt_info->insns_with_var_to_expand.find (&ve_templ);
if (ves)
{
gcc_assert (GET_CODE (PATTERN (insn))
@@ -2426,7 +2437,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
/* Initialize the variable expansions in the loop preheader
and take care of combining them at the loop exit. */
- if (opt_info->insns_with_var_to_expand)
+ if (opt_info->insns_with_var_to_expand.is_created ())
{
for (ves = opt_info->var_to_expand_head; ves; ves = ves->next)
insert_var_expansion_initialization (ves, opt_info->loop_preheader);
@@ -2455,12 +2466,12 @@ apply_opt_in_copies (struct opt_info *opt_info,
continue;
ivts_templ.insn = orig_insn;
- if (opt_info->insns_to_split)
+ if (opt_info->insns_to_split.is_created ())
{
maybe_strip_eq_note_for_split_iv (opt_info, orig_insn);
ivts = (struct iv_to_split *)
- htab_find (opt_info->insns_to_split, &ivts_templ);
+ opt_info->insns_to_split.find (&ivts_templ);
if (ivts)
{
if (!delta)
@@ -2479,15 +2490,15 @@ apply_opt_in_copies (struct opt_info *opt_info,
static void
free_opt_info (struct opt_info *opt_info)
{
- if (opt_info->insns_to_split)
- htab_delete (opt_info->insns_to_split);
- if (opt_info->insns_with_var_to_expand)
+ if (opt_info->insns_to_split.is_created ())
+ opt_info->insns_to_split.dispose ();
+ if (opt_info->insns_with_var_to_expand.is_created ())
{
struct var_to_expand *ves;
for (ves = opt_info->var_to_expand_head; ves; ves = ves->next)
ves->var_expansions.release ();
- htab_delete (opt_info->insns_with_var_to_expand);
+ opt_info->insns_with_var_to_expand.dispose ();
}
free (opt_info);
}
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index f3a08884b53..1fa44e84989 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -49,8 +49,19 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "streamer-hooks.h"
+struct freeing_string_slot_hasher : string_slot_hasher
+{
+ static inline void remove (value_type *);
+};
+
+inline void
+freeing_string_slot_hasher::remove (value_type *v)
+{
+ free (v);
+}
+
/* The table to hold the file names. */
-static htab_t file_name_hash_table;
+static hash_table <freeing_string_slot_hasher> file_name_hash_table;
/* Check that tag ACTUAL has one of the given values. NUM_TAGS is the
@@ -94,14 +105,14 @@ lto_input_data_block (struct lto_input_block *ib, void *addr, size_t length)
static const char *
canon_file_name (const char *string)
{
- void **slot;
+ string_slot **slot;
struct string_slot s_slot;
size_t len = strlen (string);
s_slot.s = string;
s_slot.len = len;
- slot = htab_find_slot (file_name_hash_table, &s_slot, INSERT);
+ slot = file_name_hash_table.find_slot (&s_slot, INSERT);
if (*slot == NULL)
{
char *saved_string;
@@ -117,7 +128,7 @@ canon_file_name (const char *string)
}
else
{
- struct string_slot *old_slot = (struct string_slot *) *slot;
+ struct string_slot *old_slot = *slot;
return old_slot->s;
}
}
@@ -1137,8 +1148,7 @@ void
lto_reader_init (void)
{
lto_streamer_init ();
- file_name_hash_table = htab_create (37, hash_string_slot_node,
- eq_string_slot_node, free);
+ file_name_hash_table.create (37);
}
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index b205092f597..5bb734090a0 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -77,8 +77,7 @@ create_output_block (enum lto_section_type section_type)
clear_line_info (ob);
- ob->string_hash_table = htab_create (37, hash_string_slot_node,
- eq_string_slot_node, NULL);
+ ob->string_hash_table.create (37);
gcc_obstack_init (&ob->obstack);
return ob;
@@ -92,7 +91,7 @@ destroy_output_block (struct output_block *ob)
{
enum lto_section_type section_type = ob->section_type;
- htab_delete (ob->string_hash_table);
+ ob->string_hash_table.dispose ();
free (ob->main_stream);
free (ob->string_stream);
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index 5ff8a6dac16..89320381b6e 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -253,28 +253,33 @@ print_lto_report (const char *s)
#ifdef LTO_STREAMER_DEBUG
-static htab_t tree_htab;
-
struct tree_hash_entry
{
tree key;
intptr_t value;
};
-static hashval_t
-hash_tree (const void *p)
+struct tree_entry_hasher : typed_noop_remove <tree_hash_entry>
+{
+ typedef tree_hash_entry value_type;
+ typedef tree_hash_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+tree_entry_hasher::hash (const value_type *e)
{
- const struct tree_hash_entry *e = (const struct tree_hash_entry *) p;
return htab_hash_pointer (e->key);
}
-static int
-eq_tree (const void *p1, const void *p2)
+inline bool
+tree_entry_hasher::equal (const value_type *e1, const compare_type *e2)
{
- const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1;
- const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2;
return (e1->key == e2->key);
}
+
+static hash_table <tree_hash_entry> tree_htab;
#endif
/* Initialization common to the LTO reader and writer. */
@@ -289,7 +294,7 @@ lto_streamer_init (void)
streamer_check_handled_ts_structures ();
#ifdef LTO_STREAMER_DEBUG
- tree_htab = htab_create (31, hash_tree, eq_tree, NULL);
+ tree_htab.create (31);
#endif
}
@@ -324,8 +329,7 @@ lto_orig_address_map (tree t, intptr_t orig_t)
ent.key = t;
ent.value = orig_t;
- slot
- = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT);
+ slot = tree_htab.find_slot (&ent, INSERT);
gcc_assert (!*slot);
*slot = XNEW (struct tree_hash_entry);
**slot = ent;
@@ -342,8 +346,7 @@ lto_orig_address_get (tree t)
struct tree_hash_entry **slot;
ent.key = t;
- slot
- = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
+ slot = tree_htab.find_slot (&ent, NO_INSERT);
return (slot ? (*slot)->value : 0);
}
@@ -357,11 +360,10 @@ lto_orig_address_remove (tree t)
struct tree_hash_entry **slot;
ent.key = t;
- slot
- = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
+ slot = tree_htab.find_slot (&ent, NO_INSERT);
gcc_assert (slot);
free (*slot);
- htab_clear_slot (tree_htab, (PTR *)slot);
+ tree_htab.clear_slot (slot);
}
#endif
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 919e304e107..43a2a7d6ec9 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_LTO_STREAMER_H
#include "plugin-api.h"
+#include "hash-table.h"
#include "tree.h"
#include "gimple.h"
#include "target.h"
@@ -626,6 +627,50 @@ struct lto_simple_output_block
struct lto_output_stream *main_stream;
};
+/* String hashing. */
+
+struct string_slot
+{
+ const char *s;
+ int len;
+ unsigned int slot_num;
+};
+
+/* Hashtable helpers. */
+
+struct string_slot_hasher : typed_noop_remove <string_slot>
+{
+ typedef string_slot value_type;
+ typedef string_slot compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Returns a hash code for DS. Adapted from libiberty's htab_hash_string
+ to support strings that may not end in '\0'. */
+
+inline hashval_t
+string_slot_hasher::hash (const value_type *ds)
+{
+ hashval_t r = ds->len;
+ int i;
+
+ for (i = 0; i < ds->len; i++)
+ r = r * 67 + (unsigned)ds->s[i] - 113;
+ return r;
+}
+
+/* Returns nonzero if DS1 and DS2 are equal. */
+
+inline bool
+string_slot_hasher::equal (const value_type *ds1, const compare_type *ds2)
+{
+ if (ds1->len == ds2->len)
+ return memcmp (ds1->s, ds2->s, ds1->len) == 0;
+
+ return 0;
+}
+
/* Data structure holding all the data and descriptors used when writing
an LTO file. */
struct output_block
@@ -644,7 +689,7 @@ struct output_block
/* The hash table that contains the set of strings we have seen so
far and the indexes assigned to them. */
- htab_t string_hash_table;
+ hash_table <string_slot_hasher> string_hash_table;
/* The current cgraph_node that we are currently serializing. Null
if we are serializing something else. */
diff --git a/gcc/passes.c b/gcc/passes.c
index a47e092ea23..ede5013974a 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "line-map.h"
+#include "hash-table.h"
#include "input.h"
#include "tree.h"
#include "rtl.h"
@@ -579,27 +580,33 @@ struct pass_registry
struct opt_pass *pass;
};
+/* Helper for pass_registry hash table. */
+
+struct pass_registry_hasher : typed_noop_remove <pass_registry>
+{
+ typedef pass_registry value_type;
+ typedef pass_registry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
/* Pass registry hash function. */
-static hashval_t
-passr_hash (const void *p)
+inline hashval_t
+pass_registry_hasher::hash (const value_type *s)
{
- const struct pass_registry *const s = (const struct pass_registry *const) p;
return htab_hash_string (s->unique_name);
}
/* Hash equal function */
-static int
-passr_eq (const void *p1, const void *p2)
+inline bool
+pass_registry_hasher::equal (const value_type *s1, const compare_type *s2)
{
- const struct pass_registry *const s1 = (const struct pass_registry *const) p1;
- const struct pass_registry *const s2 = (const struct pass_registry *const) p2;
-
return !strcmp (s1->unique_name, s2->unique_name);
}
-static htab_t name_to_pass_map = NULL;
+static hash_table <pass_registry_hasher> name_to_pass_map;
/* Register PASS with NAME. */
@@ -609,11 +616,11 @@ register_pass_name (struct opt_pass *pass, const char *name)
struct pass_registry **slot;
struct pass_registry pr;
- if (!name_to_pass_map)
- name_to_pass_map = htab_create (256, passr_hash, passr_eq, NULL);
+ if (!name_to_pass_map.is_created ())
+ name_to_pass_map.create (256);
pr.unique_name = name;
- slot = (struct pass_registry **) htab_find_slot (name_to_pass_map, &pr, INSERT);
+ slot = name_to_pass_map.find_slot (&pr, INSERT);
if (!*slot)
{
struct pass_registry *new_pr;
@@ -634,10 +641,9 @@ static vec<char_ptr> pass_tab = vNULL;
/* Callback function for traversing NAME_TO_PASS_MAP. */
-static int
-pass_traverse (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+passes_pass_traverse (pass_registry **p, void *data ATTRIBUTE_UNUSED)
{
- struct pass_registry **p = (struct pass_registry **)slot;
struct opt_pass *pass = (*p)->pass;
gcc_assert (pass->static_pass_number > 0);
@@ -658,7 +664,7 @@ create_pass_tab (void)
return;
pass_tab.safe_grow_cleared (passes_by_id_size + 1);
- htab_traverse (name_to_pass_map, pass_traverse, NULL);
+ name_to_pass_map.traverse <void *, passes_pass_traverse> (NULL);
}
static bool override_gate_status (struct opt_pass *, tree, bool);
@@ -743,8 +749,7 @@ get_pass_by_name (const char *name)
struct pass_registry **slot, pr;
pr.unique_name = name;
- slot = (struct pass_registry **) htab_find_slot (name_to_pass_map,
- &pr, NO_INSERT);
+ slot = name_to_pass_map.find_slot (&pr, NO_INSERT);
if (!slot || !*slot)
return NULL;
diff --git a/gcc/plugin.c b/gcc/plugin.c
index 846055afe8b..b269dfa3971 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "diagnostic-core.h"
#include "tree.h"
#include "tree-pass.h"
@@ -50,9 +51,36 @@ static const char *plugin_event_name_init[] =
const char **plugin_event_name = plugin_event_name_init;
+/* Event hashtable helpers. */
+
+struct event_hasher : typed_noop_remove <const char *>
+{
+ typedef const char *value_type;
+ typedef const char *compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Helper function for the event hash table that hashes the entry V. */
+
+inline hashval_t
+event_hasher::hash (const value_type *v)
+{
+ return htab_hash_string (*v);
+}
+
+/* Helper function for the event hash table that compares the name of an
+ existing entry (S1) with the given string (S2). */
+
+inline bool
+event_hasher::equal (const value_type *s1, const compare_type *s2)
+{
+ return !strcmp (*s1, *s2);
+}
+
/* A hash table to map event names to the position of the names in the
plugin_event_name table. */
-static htab_t event_tab;
+static hash_table <event_hasher> event_tab;
/* Keep track of the limit of allocated events and space ready for
allocating events. */
@@ -312,41 +340,31 @@ register_plugin_info (const char* name, struct plugin_info *info)
plugin->help = info->help;
}
-/* Helper function for the event hash table that compares the name of an
- existing entry (E1) with the given string (S2). */
-
-static int
-htab_event_eq (const void *e1, const void *s2)
-{
- const char *s1= *(const char * const *) e1;
- return !strcmp (s1, (const char *) s2);
-}
-
/* Look up the event id for NAME. If the name is not found, return -1
if INSERT is NO_INSERT. */
int
get_named_event_id (const char *name, enum insert_option insert)
{
- void **slot;
+ const char ***slot;
- if (!event_tab)
+ if (!event_tab.is_created ())
{
int i;
- event_tab = htab_create (150, htab_hash_string, htab_event_eq, NULL);
+ event_tab.create (150);
for (i = 0; i < event_last; i++)
{
- slot = htab_find_slot (event_tab, plugin_event_name[i], INSERT);
+ slot = event_tab.find_slot (&plugin_event_name[i], INSERT);
gcc_assert (*slot == HTAB_EMPTY_ENTRY);
*slot = &plugin_event_name[i];
}
}
- slot = htab_find_slot (event_tab, name, insert);
+ slot = event_tab.find_slot (&name, insert);
if (slot == NULL)
return -1;
if (*slot != HTAB_EMPTY_ENTRY)
- return (const char **) *slot - &plugin_event_name[0];
+ return *slot - &plugin_event_name[0];
if (event_last >= event_horizon)
{
@@ -368,8 +386,7 @@ get_named_event_id (const char *name, enum insert_option insert)
plugin_callbacks, event_horizon);
}
/* All the pointers in the hash table will need to be updated. */
- htab_delete (event_tab);
- event_tab = NULL;
+ event_tab.dispose ();
}
else
*slot = &plugin_event_name[event_last];
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index eb6f0d85033..a375c991dc8 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "diagnostic-core.h"
+#include "hash-table.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
@@ -87,9 +88,6 @@ static struct
type 'struct expr', and for each expression there is a single linked
list of occurrences. */
-/* The table itself. */
-static htab_t expr_table;
-
/* Expression elements in the hash table. */
struct expr
{
@@ -103,6 +101,56 @@ struct expr
struct occr *avail_occr;
};
+/* Hashtable helpers. */
+
+struct expr_hasher : typed_noop_remove <expr>
+{
+ typedef expr value_type;
+ typedef expr compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+
+/* Hash expression X.
+ DO_NOT_RECORD_P is a boolean indicating if a volatile operand is found
+ or if the expression contains something we don't want to insert in the
+ table. */
+
+static hashval_t
+hash_expr (rtx x, int *do_not_record_p)
+{
+ *do_not_record_p = 0;
+ return hash_rtx (x, GET_MODE (x), do_not_record_p,
+ NULL, /*have_reg_qty=*/false);
+}
+
+/* Callback for hashtab.
+ Return the hash value for expression EXP. We don't actually hash
+ here, we just return the cached hash value. */
+
+inline hashval_t
+expr_hasher::hash (const value_type *exp)
+{
+ return exp->hash;
+}
+
+/* Callback for hashtab.
+ Return nonzero if exp1 is equivalent to exp2. */
+
+inline bool
+expr_hasher::equal (const value_type *exp1, const compare_type *exp2)
+{
+ int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);
+
+ gcc_assert (!equiv_p || exp1->hash == exp2->hash);
+ return equiv_p;
+}
+
+/* The table itself. */
+static hash_table <expr_hasher> expr_table;
+
+
static struct obstack expr_obstack;
/* Occurrence of an expression.
@@ -183,11 +231,8 @@ static void reset_opr_set_tables (void);
/* Hash table support. */
static hashval_t hash_expr (rtx, int *);
-static hashval_t hash_expr_for_htab (const void *);
-static int expr_equiv_p (const void *, const void *);
static void insert_expr_in_table (rtx, rtx);
static struct expr *lookup_expr_in_table (rtx);
-static int dump_hash_table_entry (void **, void *);
static void dump_hash_table (FILE *);
/* Helpers for eliminate_partially_redundant_load. */
@@ -234,8 +279,7 @@ alloc_mem (void)
make the hash table too small, but unnecessarily making it too large
also doesn't help. The i/4 is a gcse.c relic, and seems like a
reasonable choice. */
- expr_table = htab_create (MAX (i / 4, 13),
- hash_expr_for_htab, expr_equiv_p, NULL);
+ expr_table.create (MAX (i / 4, 13));
/* We allocate everything on obstacks because we often can roll back
the whole obstack to some point. Freeing obstacks is very fast. */
@@ -262,7 +306,7 @@ free_mem (void)
{
free (uid_cuid);
- htab_delete (expr_table);
+ expr_table.dispose ();
obstack_free (&expr_obstack, NULL);
obstack_free (&occr_obstack, NULL);
@@ -273,45 +317,6 @@ free_mem (void)
}
-/* Hash expression X.
- DO_NOT_RECORD_P is a boolean indicating if a volatile operand is found
- or if the expression contains something we don't want to insert in the
- table. */
-
-static hashval_t
-hash_expr (rtx x, int *do_not_record_p)
-{
- *do_not_record_p = 0;
- return hash_rtx (x, GET_MODE (x), do_not_record_p,
- NULL, /*have_reg_qty=*/false);
-}
-
-/* Callback for hashtab.
- Return the hash value for expression EXP. We don't actually hash
- here, we just return the cached hash value. */
-
-static hashval_t
-hash_expr_for_htab (const void *expp)
-{
- const struct expr *const exp = (const struct expr *) expp;
- return exp->hash;
-}
-
-/* Callback for hashtab.
- Return nonzero if exp1 is equivalent to exp2. */
-
-static int
-expr_equiv_p (const void *exp1p, const void *exp2p)
-{
- const struct expr *const exp1 = (const struct expr *) exp1p;
- const struct expr *const exp2 = (const struct expr *) exp2p;
- int equiv_p = exp_equiv_p (exp1->expr, exp2->expr, 0, true);
-
- gcc_assert (!equiv_p || exp1->hash == exp2->hash);
- return equiv_p;
-}
-
-
/* Insert expression X in INSN in the hash TABLE.
If it is already present, record it as the last occurrence in INSN's
basic block. */
@@ -343,8 +348,7 @@ insert_expr_in_table (rtx x, rtx insn)
cur_expr->hash = hash;
cur_expr->avail_occr = NULL;
- slot = (struct expr **) htab_find_slot_with_hash (expr_table, cur_expr,
- hash, INSERT);
+ slot = expr_table.find_slot_with_hash (cur_expr, hash, INSERT);
if (! (*slot))
/* The expression isn't found, so insert it. */
@@ -412,8 +416,7 @@ lookup_expr_in_table (rtx pat)
tmp_expr->hash = hash;
tmp_expr->avail_occr = NULL;
- slot = (struct expr **) htab_find_slot_with_hash (expr_table, tmp_expr,
- hash, INSERT);
+ slot = expr_table.find_slot_with_hash (tmp_expr, hash, INSERT);
obstack_free (&expr_obstack, tmp_expr);
if (!slot)
@@ -427,18 +430,17 @@ lookup_expr_in_table (rtx pat)
expression hash table to FILE. */
/* This helper is called via htab_traverse. */
-static int
-dump_hash_table_entry (void **slot, void *filep)
+int
+dump_expr_hash_table_entry (expr **slot, FILE *file)
{
- struct expr *expr = (struct expr *) *slot;
- FILE *file = (FILE *) filep;
+ struct expr *exprs = *slot;
struct occr *occr;
fprintf (file, "expr: ");
- print_rtl (file, expr->expr);
- fprintf (file,"\nhashcode: %u\n", expr->hash);
+ print_rtl (file, exprs->expr);
+ fprintf (file,"\nhashcode: %u\n", exprs->hash);
fprintf (file,"list of occurrences:\n");
- occr = expr->avail_occr;
+ occr = exprs->avail_occr;
while (occr)
{
rtx insn = occr->insn;
@@ -455,13 +457,13 @@ dump_hash_table (FILE *file)
{
fprintf (file, "\n\nexpression hash table\n");
fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
- (long) htab_size (expr_table),
- (long) htab_elements (expr_table),
- htab_collisions (expr_table));
- if (htab_elements (expr_table) > 0)
+ (long) expr_table.size (),
+ (long) expr_table.elements (),
+ expr_table.collisions ());
+ if (expr_table.elements () > 0)
{
fprintf (file, "\n\ntable entries:\n");
- htab_traverse (expr_table, dump_hash_table_entry, file);
+ expr_table.traverse <FILE *, dump_expr_hash_table_entry> (file);
}
fprintf (file, "\n");
}
@@ -1223,13 +1225,13 @@ eliminate_partially_redundant_loads (void)
marked for later deletion. */
/* This helper is called via htab_traverse. */
-static int
-delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+delete_redundant_insns_1 (expr **slot, void *data ATTRIBUTE_UNUSED)
{
- struct expr *expr = (struct expr *) *slot;
+ struct expr *exprs = *slot;
struct occr *occr;
- for (occr = expr->avail_occr; occr != NULL; occr = occr->next)
+ for (occr = exprs->avail_occr; occr != NULL; occr = occr->next)
{
if (occr->deleted_p && dbg_cnt (gcse2_delete))
{
@@ -1251,7 +1253,7 @@ delete_redundant_insns_1 (void **slot, void *data ATTRIBUTE_UNUSED)
static void
delete_redundant_insns (void)
{
- htab_traverse (expr_table, delete_redundant_insns_1, NULL);
+ expr_table.traverse <void *, delete_redundant_insns_1> (NULL);
if (dump_file)
fprintf (dump_file, "\n");
}
@@ -1277,7 +1279,7 @@ gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
if (dump_file)
dump_hash_table (dump_file);
- if (htab_elements (expr_table) > 0)
+ if (expr_table.elements () > 0)
{
eliminate_partially_redundant_loads ();
delete_redundant_insns ();
diff --git a/gcc/sese.c b/gcc/sese.c
index 98588f9c09a..5f9af622ef6 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tree-pretty-print.h"
#include "tree-flow.h"
#include "cfgloop.h"
@@ -46,90 +47,51 @@ debug_rename_elt (rename_map_elt elt)
/* Helper function for debug_rename_map. */
-static int
-debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
+int
+debug_rename_map_1 (rename_map_elt_s **slot, void *s ATTRIBUTE_UNUSED)
{
- struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot;
+ struct rename_map_elt_s *entry = *slot;
debug_rename_elt (entry);
return 1;
}
+
-/* Print to stderr all the elements of RENAME_MAP. */
+/* Hashtable helpers. */
-DEBUG_FUNCTION void
-debug_rename_map (htab_t rename_map)
+struct rename_map_hasher : typed_free_remove <rename_map_elt_s>
{
- htab_traverse (rename_map, debug_rename_map_1, NULL);
-}
+ typedef rename_map_elt_s value_type;
+ typedef rename_map_elt_s compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
/* Computes a hash function for database element ELT. */
-hashval_t
-rename_map_elt_info (const void *elt)
+inline hashval_t
+rename_map_hasher::hash (const value_type *elt)
{
- return SSA_NAME_VERSION (((const struct rename_map_elt_s *) elt)->old_name);
+ return SSA_NAME_VERSION (elt->old_name);
}
/* Compares database elements E1 and E2. */
-int
-eq_rename_map_elts (const void *e1, const void *e2)
+inline bool
+rename_map_hasher::equal (const value_type *elt1, const compare_type *elt2)
{
- const struct rename_map_elt_s *elt1 = (const struct rename_map_elt_s *) e1;
- const struct rename_map_elt_s *elt2 = (const struct rename_map_elt_s *) e2;
-
return (elt1->old_name == elt2->old_name);
}
+typedef hash_table <rename_map_hasher> rename_map_type;
-/* Print to stderr the element ELT. */
-
-static void
-debug_ivtype_elt (ivtype_map_elt elt)
-{
- fprintf (stderr, "(%s, ", elt->cloog_iv);
- print_generic_expr (stderr, elt->type, 0);
- fprintf (stderr, ")\n");
-}
-
-/* Helper function for debug_ivtype_map. */
-
-static int
-debug_ivtype_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
-{
- struct ivtype_map_elt_s *entry = (struct ivtype_map_elt_s *) *slot;
- debug_ivtype_elt (entry);
- return 1;
-}
-
-/* Print to stderr all the elements of MAP. */
+/* Print to stderr all the elements of RENAME_MAP. */
DEBUG_FUNCTION void
-debug_ivtype_map (htab_t map)
-{
- htab_traverse (map, debug_ivtype_map_1, NULL);
-}
-
-/* Computes a hash function for database element ELT. */
-
-hashval_t
-ivtype_map_elt_info (const void *elt)
+debug_rename_map (rename_map_type rename_map)
{
- return htab_hash_pointer (((const struct ivtype_map_elt_s *) elt)->cloog_iv);
+ rename_map.traverse <void *, debug_rename_map_1> (NULL);
}
-
-/* Compares database elements E1 and E2. */
-
-int
-eq_ivtype_map_elts (const void *e1, const void *e2)
-{
- const struct ivtype_map_elt_s *elt1 = (const struct ivtype_map_elt_s *) e1;
- const struct ivtype_map_elt_s *elt2 = (const struct ivtype_map_elt_s *) e2;
-
- return (elt1->cloog_iv == elt2->cloog_iv);
-}
-
/* Record LOOP as occurring in REGION. */
@@ -414,17 +376,17 @@ get_false_edge_from_guard_bb (basic_block bb)
/* Returns the expression associated to OLD_NAME in RENAME_MAP. */
static tree
-get_rename (htab_t rename_map, tree old_name)
+get_rename (rename_map_type rename_map, tree old_name)
{
struct rename_map_elt_s tmp;
- PTR *slot;
+ rename_map_elt_s **slot;
gcc_assert (TREE_CODE (old_name) == SSA_NAME);
tmp.old_name = old_name;
- slot = htab_find_slot (rename_map, &tmp, NO_INSERT);
+ slot = rename_map.find_slot (&tmp, NO_INSERT);
if (slot && *slot)
- return ((rename_map_elt) *slot)->expr;
+ return (*slot)->expr;
return NULL_TREE;
}
@@ -432,16 +394,16 @@ get_rename (htab_t rename_map, tree old_name)
/* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR). */
static void
-set_rename (htab_t rename_map, tree old_name, tree expr)
+set_rename (rename_map_type rename_map, tree old_name, tree expr)
{
struct rename_map_elt_s tmp;
- PTR *slot;
+ rename_map_elt_s **slot;
if (old_name == expr)
return;
tmp.old_name = old_name;
- slot = htab_find_slot (rename_map, &tmp, INSERT);
+ slot = rename_map.find_slot (&tmp, INSERT);
if (!slot)
return;
@@ -459,7 +421,8 @@ set_rename (htab_t rename_map, tree old_name, tree expr)
is set when the code generation cannot continue. */
static bool
-rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
+rename_uses (gimple copy, rename_map_type rename_map,
+ gimple_stmt_iterator *gsi_tgt,
sese region, loop_p loop, vec<tree> iv_map,
bool *gloog_error)
{
@@ -565,7 +528,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
static void
graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
- htab_t rename_map,
+ rename_map_type rename_map,
vec<tree> iv_map, sese region,
bool *gloog_error)
{
@@ -633,14 +596,14 @@ copy_bb_and_scalar_dependences (basic_block bb, sese region,
bool *gloog_error)
{
basic_block new_bb = split_edge (next_e);
- htab_t rename_map = htab_create (10, rename_map_elt_info,
- eq_rename_map_elts, free);
+ rename_map_type rename_map;
+ rename_map.create (10);
next_e = single_succ_edge (new_bb);
graphite_copy_stmts_from_block (bb, new_bb, rename_map, iv_map, region,
gloog_error);
remove_phi_nodes (new_bb);
- htab_delete (rename_map);
+ rename_map.dispose ();
return next_e;
}
diff --git a/gcc/sese.h b/gcc/sese.h
index 758783ee928..2e226c30b63 100644
--- a/gcc/sese.h
+++ b/gcc/sese.h
@@ -58,8 +58,6 @@ extern void build_sese_loop_nests (sese);
extern edge copy_bb_and_scalar_dependences (basic_block, sese, edge,
vec<tree> , bool *);
extern struct loop *outermost_loop_in_sese (sese, basic_block);
-extern void insert_loop_close_phis (htab_t, loop_p);
-extern void insert_guard_phis (basic_block, edge, edge, htab_t, htab_t);
extern tree scalar_evolution_in_region (sese, loop_p, tree);
/* Check that SESE contains LOOP. */
@@ -259,7 +257,6 @@ typedef struct rename_map_elt_s
} *rename_map_elt;
-extern void debug_rename_map (htab_t);
extern hashval_t rename_map_elt_info (const void *);
extern int eq_rename_map_elts (const void *, const void *);
@@ -285,24 +282,6 @@ typedef struct ivtype_map_elt_s
const char *cloog_iv;
} *ivtype_map_elt;
-extern void debug_ivtype_map (htab_t);
-extern hashval_t ivtype_map_elt_info (const void *);
-extern int eq_ivtype_map_elts (const void *, const void *);
-
-/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */
-
-static inline ivtype_map_elt
-new_ivtype_map_elt (const char *cloog_iv, tree type)
-{
- ivtype_map_elt res;
-
- res = XNEW (struct ivtype_map_elt_s);
- res->cloog_iv = cloog_iv;
- res->type = type;
-
- return res;
-}
-
/* Free and compute again all the dominators information. */
static inline void
diff --git a/gcc/statistics.c b/gcc/statistics.c
index 3b9685d01d0..3077cc0c36c 100644
--- a/gcc/statistics.c
+++ b/gcc/statistics.c
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "tree-dump.h"
#include "statistics.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "function.h"
static int statistics_dump_nr;
@@ -42,42 +42,52 @@ typedef struct statistics_counter_s {
unsigned HOST_WIDE_INT prev_dumped_count;
} statistics_counter_t;
-/* Array of statistic hashes, indexed by pass id. */
-static htab_t *statistics_hashes;
-static unsigned nr_statistics_hashes;
+/* Hashtable helpers. */
+
+struct stats_counter_hasher
+{
+ typedef statistics_counter_t value_type;
+ typedef statistics_counter_t compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
/* Hash a statistic counter by its string ID. */
-static hashval_t
-hash_statistics_hash (const void *p)
+inline hashval_t
+stats_counter_hasher::hash (const value_type *c)
{
- const statistics_counter_t *const c = (const statistics_counter_t *)p;
return htab_hash_string (c->id) + c->val;
}
/* Compare two statistic counters by their string IDs. */
-static int
-hash_statistics_eq (const void *p, const void *q)
+inline bool
+stats_counter_hasher::equal (const value_type *c1, const compare_type *c2)
{
- const statistics_counter_t *const c1 = (const statistics_counter_t *)p;
- const statistics_counter_t *const c2 = (const statistics_counter_t *)q;
return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
}
/* Free a statistics entry. */
-static void
-hash_statistics_free (void *p)
+inline void
+stats_counter_hasher::remove (value_type *v)
{
- free (CONST_CAST(char *, ((statistics_counter_t *)p)->id));
- free (p);
+ free (CONST_CAST(char *, v->id));
+ free (v);
}
+typedef hash_table <stats_counter_hasher> stats_counter_table_type;
+
+/* Array of statistic hashes, indexed by pass id. */
+static stats_counter_table_type *statistics_hashes;
+static unsigned nr_statistics_hashes;
+
/* Return the current hashtable to be used for recording or printing
statistics. */
-static htab_t
+static stats_counter_table_type
curr_statistics_hash (void)
{
unsigned idx;
@@ -86,20 +96,20 @@ curr_statistics_hash (void)
idx = current_pass->static_pass_number;
if (idx < nr_statistics_hashes
- && statistics_hashes[idx] != NULL)
+ && statistics_hashes[idx].is_created ())
return statistics_hashes[idx];
if (idx >= nr_statistics_hashes)
{
- statistics_hashes = XRESIZEVEC (struct htab *, statistics_hashes, idx+1);
+ statistics_hashes = XRESIZEVEC (stats_counter_table_type,
+ statistics_hashes, idx+1);
memset (statistics_hashes + nr_statistics_hashes, 0,
- (idx + 1 - nr_statistics_hashes) * sizeof (htab_t));
+ (idx + 1 - nr_statistics_hashes)
+ * sizeof (stats_counter_table_type));
nr_statistics_hashes = idx + 1;
}
- statistics_hashes[idx] = htab_create (15, hash_statistics_hash,
- hash_statistics_eq,
- hash_statistics_free);
+ statistics_hashes[idx].create (15);
return statistics_hashes[idx];
}
@@ -107,10 +117,11 @@ curr_statistics_hash (void)
/* Helper for statistics_fini_pass. Print the counter difference
since the last dump for the pass dump files. */
-static int
-statistics_fini_pass_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+statistics_fini_pass_1 (statistics_counter_t **slot,
+ void *data ATTRIBUTE_UNUSED)
{
- statistics_counter_t *counter = (statistics_counter_t *)*slot;
+ statistics_counter_t *counter = *slot;
unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
if (count == 0)
return 1;
@@ -127,10 +138,11 @@ statistics_fini_pass_1 (void **slot, void *data ATTRIBUTE_UNUSED)
/* Helper for statistics_fini_pass. Print the counter difference
since the last dump for the statistics dump. */
-static int
-statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+statistics_fini_pass_2 (statistics_counter_t **slot,
+ void *data ATTRIBUTE_UNUSED)
{
- statistics_counter_t *counter = (statistics_counter_t *)*slot;
+ statistics_counter_t *counter = *slot;
unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
if (count == 0)
return 1;
@@ -157,10 +169,11 @@ statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
/* Helper for statistics_fini_pass, reset the counters. */
-static int
-statistics_fini_pass_3 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+statistics_fini_pass_3 (statistics_counter_t **slot,
+ void *data ATTRIBUTE_UNUSED)
{
- statistics_counter_t *counter = (statistics_counter_t *)*slot;
+ statistics_counter_t *counter = *slot;
counter->prev_dumped_count = counter->count;
return 1;
}
@@ -179,26 +192,25 @@ statistics_fini_pass (void)
fprintf (dump_file, "\n");
fprintf (dump_file, "Pass statistics:\n");
fprintf (dump_file, "----------------\n");
- htab_traverse_noresize (curr_statistics_hash (),
- statistics_fini_pass_1, NULL);
+ curr_statistics_hash ()
+ .traverse_noresize <void *, statistics_fini_pass_1> (NULL);
fprintf (dump_file, "\n");
}
if (statistics_dump_file
&& !(statistics_dump_flags & TDF_STATS
|| statistics_dump_flags & TDF_DETAILS))
- htab_traverse_noresize (curr_statistics_hash (),
- statistics_fini_pass_2, NULL);
- htab_traverse_noresize (curr_statistics_hash (),
- statistics_fini_pass_3, NULL);
+ curr_statistics_hash ()
+ .traverse_noresize <void *, statistics_fini_pass_2> (NULL);
+ curr_statistics_hash ()
+ .traverse_noresize <void *, statistics_fini_pass_3> (NULL);
}
/* Helper for printing summary information. */
-static int
-statistics_fini_1 (void **slot, void *data)
+int
+statistics_fini_1 (statistics_counter_t **slot, opt_pass *pass)
{
- struct opt_pass *pass = (struct opt_pass *)data;
- statistics_counter_t *counter = (statistics_counter_t *)*slot;
+ statistics_counter_t *counter = *slot;
if (counter->count == 0)
return 1;
if (counter->histogram_p)
@@ -230,10 +242,11 @@ statistics_fini (void)
{
unsigned i;
for (i = 0; i < nr_statistics_hashes; ++i)
- if (statistics_hashes[i] != NULL
+ if (statistics_hashes[i].is_created ()
&& get_pass_for_id (i) != NULL)
- htab_traverse_noresize (statistics_hashes[i],
- statistics_fini_1, get_pass_for_id (i));
+ statistics_hashes[i]
+ .traverse_noresize <opt_pass *, statistics_fini_1>
+ (get_pass_for_id (i));
}
dump_end (statistics_dump_nr, statistics_dump_file);
@@ -261,14 +274,14 @@ statistics_init (void)
and HISTOGRAM_P. */
static statistics_counter_t *
-lookup_or_add_counter (htab_t hash, const char *id, int val,
+lookup_or_add_counter (stats_counter_table_type hash, const char *id, int val,
bool histogram_p)
{
statistics_counter_t **counter;
statistics_counter_t c;
c.id = id;
c.val = val;
- counter = (statistics_counter_t **) htab_find_slot (hash, &c, INSERT);
+ counter = hash.find_slot (&c, INSERT);
if (!*counter)
{
*counter = XNEW (struct statistics_counter_s);
diff --git a/gcc/store-motion.c b/gcc/store-motion.c
index 2e57d32422c..83fbf075544 100644
--- a/gcc/store-motion.c
+++ b/gcc/store-motion.c
@@ -39,7 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "intl.h"
#include "tree-pass.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "df.h"
#include "dbgcnt.h"
@@ -90,9 +90,6 @@ struct st_expr
/* Head of the list of load/store memory refs. */
static struct st_expr * store_motion_mems = NULL;
-/* Hashtable for the load/store memory refs. */
-static htab_t store_motion_mems_table = NULL;
-
/* These bitmaps will hold the local dataflow properties per basic block. */
static sbitmap *st_kill, *st_avloc, *st_antloc, *st_transp;
@@ -108,22 +105,32 @@ static int num_stores;
/* Contains the edge_list returned by pre_edge_lcm. */
static struct edge_list *edge_list;
-static hashval_t
-pre_st_expr_hash (const void *p)
+/* Hashtable helpers. */
+
+struct st_expr_hasher : typed_noop_remove <st_expr>
+{
+ typedef st_expr value_type;
+ typedef st_expr compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+st_expr_hasher::hash (const value_type *x)
{
int do_not_record_p = 0;
- const struct st_expr *const x = (const struct st_expr *) p;
return hash_rtx (x->pattern, GET_MODE (x->pattern), &do_not_record_p, NULL, false);
}
-static int
-pre_st_expr_eq (const void *p1, const void *p2)
+inline bool
+st_expr_hasher::equal (const value_type *ptr1, const compare_type *ptr2)
{
- const struct st_expr *const ptr1 = (const struct st_expr *) p1,
- *const ptr2 = (const struct st_expr *) p2;
return exp_equiv_p (ptr1->pattern, ptr2->pattern, 0, true);
}
+/* Hashtable for the load/store memory refs. */
+static hash_table <st_expr_hasher> store_motion_mems_table;
+
/* This will search the st_expr list for a matching expression. If it
doesn't find one, we create one and initialize it. */
@@ -133,16 +140,16 @@ st_expr_entry (rtx x)
int do_not_record_p = 0;
struct st_expr * ptr;
unsigned int hash;
- void **slot;
+ st_expr **slot;
struct st_expr e;
hash = hash_rtx (x, GET_MODE (x), &do_not_record_p,
NULL, /*have_reg_qty=*/false);
e.pattern = x;
- slot = htab_find_slot_with_hash (store_motion_mems_table, &e, hash, INSERT);
+ slot = store_motion_mems_table.find_slot_with_hash (&e, hash, INSERT);
if (*slot)
- return (struct st_expr *)*slot;
+ return *slot;
ptr = XNEW (struct st_expr);
@@ -176,9 +183,8 @@ free_st_expr_entry (struct st_expr * ptr)
static void
free_store_motion_mems (void)
{
- if (store_motion_mems_table)
- htab_delete (store_motion_mems_table);
- store_motion_mems_table = NULL;
+ if (store_motion_mems_table.is_created ())
+ store_motion_mems_table.dispose ();
while (store_motion_mems)
{
@@ -645,8 +651,7 @@ compute_store_table (void)
unsigned int max_gcse_regno = max_reg_num ();
store_motion_mems = NULL;
- store_motion_mems_table = htab_create (13, pre_st_expr_hash,
- pre_st_expr_eq, NULL);
+ store_motion_mems_table.create (13);
last_set_in = XCNEWVEC (int, max_gcse_regno);
already_set = XNEWVEC (int, max_gcse_regno);
@@ -708,8 +713,7 @@ compute_store_table (void)
if (! ptr->avail_stores)
{
*prev_next_ptr_ptr = ptr->next;
- htab_remove_elt_with_hash (store_motion_mems_table,
- ptr, ptr->hash_index);
+ store_motion_mems_table.remove_elt_with_hash (ptr, ptr->hash_index);
free_st_expr_entry (ptr);
}
else
@@ -1142,8 +1146,7 @@ one_store_motion_pass (void)
num_stores = compute_store_table ();
if (num_stores == 0)
{
- htab_delete (store_motion_mems_table);
- store_motion_mems_table = NULL;
+ store_motion_mems_table.dispose ();
end_alias_analysis ();
return 0;
}
diff --git a/gcc/target.def b/gcc/target.def
index 831cad8119b..f8b96d33c64 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2741,12 +2741,12 @@ DEFHOOKPOD
"",
const char *, NULL)
-/* Function to generate field definitions of the proxy variable. */
+/* Function to generate type of the proxy variable. */
DEFHOOK
-(var_fields,
+(object_type,
"",
- tree, (tree type, tree *name),
- default_emutls_var_fields)
+ tree, (),
+ default_emutls_object_type)
/* Function to initialize a proxy variable. */
DEFHOOK
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index d23b3529fe5..ba848610962 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -141,7 +141,7 @@ extern void default_target_option_override (void);
extern void hook_void_bitmap (bitmap);
extern int default_reloc_rw_mask (void);
extern tree default_mangle_decl_assembler_name (tree, tree);
-extern tree default_emutls_var_fields (tree, tree *);
+extern tree default_emutls_object_type ();
extern tree default_emutls_var_init (tree, tree, tree);
extern bool default_hard_regno_scratch_ok (unsigned int);
extern bool default_mode_dependent_address_p (const_rtx, addr_space_t);
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index b0f18b552bb..5cb82865910 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tree.h"
#include "gimple.h"
#include "tree-flow.h"
@@ -879,47 +880,29 @@ typedef struct tm_log_entry
tree save_var;
} *tm_log_entry_t;
-/* The actual log. */
-static htab_t tm_log;
-
-/* Addresses to log with a save/restore sequence. These should be in
- dominator order. */
-static vec<tree> tm_log_save_addresses;
-
-/* Map for an SSA_NAME originally pointing to a non aliased new piece
- of memory (malloc, alloc, etc). */
-static htab_t tm_new_mem_hash;
-enum thread_memory_type
- {
- mem_non_local = 0,
- mem_thread_local,
- mem_transaction_local,
- mem_max
- };
+/* Log entry hashtable helpers. */
-typedef struct tm_new_mem_map
+struct log_entry_hasher
{
- /* SSA_NAME being dereferenced. */
- tree val;
- enum thread_memory_type local_new_memory;
-} tm_new_mem_map_t;
+ typedef tm_log_entry value_type;
+ typedef tm_log_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
/* Htab support. Return hash value for a `tm_log_entry'. */
-static hashval_t
-tm_log_hash (const void *p)
+inline hashval_t
+log_entry_hasher::hash (const value_type *log)
{
- const struct tm_log_entry *log = (const struct tm_log_entry *) p;
return iterative_hash_expr (log->addr, 0);
}
/* Htab support. Return true if two log entries are the same. */
-static int
-tm_log_eq (const void *p1, const void *p2)
+inline bool
+log_entry_hasher::equal (const value_type *log1, const compare_type *log2)
{
- const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1;
- const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2;
-
/* FIXME:
rth: I suggest that we get rid of the component refs etc.
@@ -943,20 +926,68 @@ tm_log_eq (const void *p1, const void *p2)
}
/* Htab support. Free one tm_log_entry. */
-static void
-tm_log_free (void *p)
+inline void
+log_entry_hasher::remove (value_type *lp)
{
- struct tm_log_entry *lp = (struct tm_log_entry *) p;
lp->stmts.release ();
free (lp);
}
+
+/* The actual log. */
+static hash_table <log_entry_hasher> tm_log;
+
+/* Addresses to log with a save/restore sequence. These should be in
+ dominator order. */
+static vec<tree> tm_log_save_addresses;
+
+enum thread_memory_type
+ {
+ mem_non_local = 0,
+ mem_thread_local,
+ mem_transaction_local,
+ mem_max
+ };
+
+typedef struct tm_new_mem_map
+{
+ /* SSA_NAME being dereferenced. */
+ tree val;
+ enum thread_memory_type local_new_memory;
+} tm_new_mem_map_t;
+
+/* Hashtable helpers. */
+
+struct tm_mem_map_hasher : typed_free_remove <tm_new_mem_map_t>
+{
+ typedef tm_new_mem_map_t value_type;
+ typedef tm_new_mem_map_t compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+tm_mem_map_hasher::hash (const value_type *v)
+{
+ return (intptr_t)v->val >> 4;
+}
+
+inline bool
+tm_mem_map_hasher::equal (const value_type *v, const compare_type *c)
+{
+ return v->val == c->val;
+}
+
+/* Map for an SSA_NAME originally pointing to a non aliased new piece
+ of memory (malloc, alloc, etc). */
+static hash_table <tm_mem_map_hasher> tm_new_mem_hash;
+
/* Initialize logging data structures. */
static void
tm_log_init (void)
{
- tm_log = htab_create (10, tm_log_hash, tm_log_eq, tm_log_free);
- tm_new_mem_hash = htab_create (5, struct_ptr_hash, struct_ptr_eq, free);
+ tm_log.create (10);
+ tm_new_mem_hash.create (5);
tm_log_save_addresses.create (5);
}
@@ -964,8 +995,8 @@ tm_log_init (void)
static void
tm_log_delete (void)
{
- htab_delete (tm_log);
- htab_delete (tm_new_mem_hash);
+ tm_log.dispose ();
+ tm_new_mem_hash.dispose ();
tm_log_save_addresses.release ();
}
@@ -1006,11 +1037,11 @@ transaction_invariant_address_p (const_tree mem, basic_block region_entry_block)
static void
tm_log_add (basic_block entry_block, tree addr, gimple stmt)
{
- void **slot;
+ tm_log_entry **slot;
struct tm_log_entry l, *lp;
l.addr = addr;
- slot = htab_find_slot (tm_log, &l, INSERT);
+ slot = tm_log.find_slot (&l, INSERT);
if (!*slot)
{
tree type = TREE_TYPE (addr);
@@ -1051,7 +1082,7 @@ tm_log_add (basic_block entry_block, tree addr, gimple stmt)
size_t i;
gimple oldstmt;
- lp = (struct tm_log_entry *) *slot;
+ lp = *slot;
/* If we're generating a save/restore sequence, we don't care
about statements. */
@@ -1153,10 +1184,10 @@ tm_log_emit_stmt (tree addr, gimple stmt)
static void
tm_log_emit (void)
{
- htab_iterator hi;
+ hash_table <log_entry_hasher>::iterator hi;
struct tm_log_entry *lp;
- FOR_EACH_HTAB_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
{
size_t i;
gimple stmt;
@@ -1198,7 +1229,7 @@ tm_log_emit_saves (basic_block entry_block, basic_block bb)
for (i = 0; i < tm_log_save_addresses.length (); ++i)
{
l.addr = tm_log_save_addresses[i];
- lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
+ lp = *(tm_log.find_slot (&l, NO_INSERT));
gcc_assert (lp->save_var != NULL);
/* We only care about variables in the current transaction. */
@@ -1234,7 +1265,7 @@ tm_log_emit_restores (basic_block entry_block, basic_block bb)
for (i = tm_log_save_addresses.length () - 1; i >= 0; i--)
{
l.addr = tm_log_save_addresses[i];
- lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
+ lp = *(tm_log.find_slot (&l, NO_INSERT));
gcc_assert (lp->save_var != NULL);
/* We only care about variables in the current transaction. */
@@ -1271,7 +1302,7 @@ thread_private_new_memory (basic_block entry_block, tree x)
{
gimple stmt = NULL;
enum tree_code code;
- void **slot;
+ tm_new_mem_map_t **slot;
tm_new_mem_map_t elt, *elt_p;
tree val = x;
enum thread_memory_type retval = mem_transaction_local;
@@ -1285,8 +1316,8 @@ thread_private_new_memory (basic_block entry_block, tree x)
/* Look in cache first. */
elt.val = x;
- slot = htab_find_slot (tm_new_mem_hash, &elt, INSERT);
- elt_p = (tm_new_mem_map_t *) *slot;
+ slot = tm_new_mem_hash.find_slot (&elt, INSERT);
+ elt_p = *slot;
if (elt_p)
return elt_p->local_new_memory;
@@ -3146,6 +3177,35 @@ typedef struct tm_memop
tree addr;
} *tm_memop_t;
+/* TM memory operation hashtable helpers. */
+
+struct tm_memop_hasher : typed_free_remove <tm_memop>
+{
+ typedef tm_memop value_type;
+ typedef tm_memop compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Htab support. Return a hash value for a `tm_memop'. */
+inline hashval_t
+tm_memop_hasher::hash (const value_type *mem)
+{
+ tree addr = mem->addr;
+ /* We drill down to the SSA_NAME/DECL for the hash, but equality is
+ actually done with operand_equal_p (see tm_memop_eq). */
+ if (TREE_CODE (addr) == ADDR_EXPR)
+ addr = TREE_OPERAND (addr, 0);
+ return iterative_hash_expr (addr, 0);
+}
+
+/* Htab support. Return true if two tm_memop's are the same. */
+inline bool
+tm_memop_hasher::equal (const value_type *mem1, const compare_type *mem2)
+{
+ return operand_equal_p (mem1->addr, mem2->addr, 0);
+}
+
/* Sets for solving data flow equations in the memory optimization pass. */
struct tm_memopt_bitmaps
{
@@ -3178,7 +3238,7 @@ static bitmap_obstack tm_memopt_obstack;
/* Unique counter for TM loads and stores. Loads and stores of the
same address get the same ID. */
static unsigned int tm_memopt_value_id;
-static htab_t tm_memopt_value_numbers;
+static hash_table <tm_memop_hasher> tm_memopt_value_numbers;
#define STORE_AVAIL_IN(BB) \
((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in
@@ -3201,29 +3261,6 @@ static htab_t tm_memopt_value_numbers;
#define BB_VISITED_P(BB) \
((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p
-/* Htab support. Return a hash value for a `tm_memop'. */
-static hashval_t
-tm_memop_hash (const void *p)
-{
- const struct tm_memop *mem = (const struct tm_memop *) p;
- tree addr = mem->addr;
- /* We drill down to the SSA_NAME/DECL for the hash, but equality is
- actually done with operand_equal_p (see tm_memop_eq). */
- if (TREE_CODE (addr) == ADDR_EXPR)
- addr = TREE_OPERAND (addr, 0);
- return iterative_hash_expr (addr, 0);
-}
-
-/* Htab support. Return true if two tm_memop's are the same. */
-static int
-tm_memop_eq (const void *p1, const void *p2)
-{
- const struct tm_memop *mem1 = (const struct tm_memop *) p1;
- const struct tm_memop *mem2 = (const struct tm_memop *) p2;
-
- return operand_equal_p (mem1->addr, mem2->addr, 0);
-}
-
/* Given a TM load/store in STMT, return the value number for the address
it accesses. */
@@ -3231,13 +3268,13 @@ static unsigned int
tm_memopt_value_number (gimple stmt, enum insert_option op)
{
struct tm_memop tmpmem, *mem;
- void **slot;
+ tm_memop **slot;
gcc_assert (is_tm_load (stmt) || is_tm_store (stmt));
tmpmem.addr = gimple_call_arg (stmt, 0);
- slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op);
+ slot = tm_memopt_value_numbers.find_slot (&tmpmem, op);
if (*slot)
- mem = (struct tm_memop *) *slot;
+ mem = *slot;
else if (op == INSERT)
{
mem = XNEW (struct tm_memop);
@@ -3295,11 +3332,11 @@ dump_tm_memopt_set (const char *set_name, bitmap bits)
fprintf (dump_file, "TM memopt: %s: [", set_name);
EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
{
- htab_iterator hi;
- struct tm_memop *mem;
+ hash_table <tm_memop_hasher>::iterator hi;
+ struct tm_memop *mem = NULL;
/* Yeah, yeah, yeah. Whatever. This is just for debugging. */
- FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
if (mem->value_id == i)
break;
gcc_assert (mem->value_id == i);
@@ -3734,7 +3771,7 @@ execute_tm_memopt (void)
vec<basic_block> bbs;
tm_memopt_value_id = 0;
- tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free);
+ tm_memopt_value_numbers.create (10);
for (region = all_tm_regions; region; region = region->next)
{
@@ -3768,10 +3805,10 @@ execute_tm_memopt (void)
tm_memopt_free_sets (bbs);
bbs.release ();
bitmap_obstack_release (&tm_memopt_obstack);
- htab_empty (tm_memopt_value_numbers);
+ tm_memopt_value_numbers.empty ();
}
- htab_delete (tm_memopt_value_numbers);
+ tm_memopt_value_numbers.dispose ();
return 0;
}
diff --git a/gcc/tree-browser.c b/gcc/tree-browser.c
index ba2fe195781..b236cabd8df 100644
--- a/gcc/tree-browser.c
+++ b/gcc/tree-browser.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tree.h"
#include "tree-pretty-print.h"
@@ -94,14 +95,45 @@ static tree TB_next_expr (tree);
static tree TB_up_expr (tree);
static tree TB_first_in_bind (tree);
static tree TB_last_in_bind (tree);
-static int TB_parent_eq (const void *, const void *);
static tree TB_history_prev (void);
/* FIXME: To be declared in a .h file. */
void browse_tree (tree);
+/* Hashtable helpers. */
+struct tree_upper_hasher : typed_noop_remove <tree_node>
+{
+ typedef tree_node value_type;
+ typedef tree_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+tree_upper_hasher::hash (const value_type *v)
+{
+ return pointer_hash <value_type>::hash (v);
+}
+
+inline bool
+tree_upper_hasher::equal (const value_type *parent, const compare_type *node)
+{
+ if (parent == NULL || node == NULL)
+ return 0;
+
+ if (EXPR_P (parent))
+ {
+ int n = TREE_OPERAND_LENGTH (parent);
+ int i;
+ for (i = 0; i < n; i++)
+ if (node == TREE_OPERAND (parent, i))
+ return true;
+ }
+ return false;
+}
+
/* Static variables. */
-static htab_t TB_up_ht;
+static hash_table <tree_upper_hasher> TB_up_ht;
static vec<tree, va_gc> *TB_history_stack;
static int TB_verbose = 1;
@@ -134,7 +166,7 @@ browse_tree (tree begin)
/* Store in a hashtable information about previous and upper statements. */
{
- TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
+ TB_up_ht.create (1023);
TB_update_up (head);
}
@@ -612,7 +644,7 @@ browse_tree (tree begin)
}
ret:;
- htab_delete (TB_up_ht);
+ TB_up_ht.dispose ();
return;
}
@@ -658,7 +690,7 @@ TB_up_expr (tree node)
if (node == NULL_TREE)
return NULL_TREE;
- res = (tree) htab_find (TB_up_ht, node);
+ res = TB_up_ht.find (node);
return res;
}
@@ -724,7 +756,7 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED)
{
tree node;
- void **slot;
+ tree_node **slot;
node = *tp;
@@ -736,8 +768,8 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
for (i = 0; i < n; i++)
{
tree op = TREE_OPERAND (node, i);
- slot = htab_find_slot (TB_up_ht, op, INSERT);
- *slot = (void *) node;
+ slot = TB_up_ht.find_slot (op, INSERT);
+ *slot = node;
}
}
@@ -745,28 +777,6 @@ store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
return NULL_TREE;
}
-/* Function used in TB_up_ht. */
-
-static int
-TB_parent_eq (const void *p1, const void *p2)
-{
- const_tree const node = (const_tree)p2;
- const_tree const parent = (const_tree) p1;
-
- if (p1 == NULL || p2 == NULL)
- return 0;
-
- if (EXPR_P (parent))
- {
- int n = TREE_OPERAND_LENGTH (parent);
- int i;
- for (i = 0; i < n; i++)
- if (node == TREE_OPERAND (parent, i))
- return 1;
- }
- return 0;
-}
-
/* Update information about upper expressions in the hash table. */
static void
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index c3771e54fd0..dce08588798 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "tm_p.h"
@@ -87,7 +88,36 @@ struct locus_discrim_map
location_t locus;
int discriminator;
};
-static htab_t discriminator_per_locus;
+
+/* Hashtable helpers. */
+
+struct locus_descrim_hasher : typed_free_remove <locus_discrim_map>
+{
+ typedef locus_discrim_map value_type;
+ typedef locus_discrim_map compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Trivial hash function for a location_t. ITEM is a pointer to
+ a hash table entry that maps a location_t to a discriminator. */
+
+inline hashval_t
+locus_descrim_hasher::hash (const value_type *item)
+{
+ return item->locus;
+}
+
+/* Equality function for the locus-to-discriminator map. A and B
+ point to the two hash table entries to compare. */
+
+inline bool
+locus_descrim_hasher::equal (const value_type *a, const compare_type *b)
+{
+ return a->locus == b->locus;
+}
+
+static hash_table <locus_descrim_hasher> discriminator_per_locus;
/* Basic blocks and flowgraphs. */
static void make_blocks (gimple_seq);
@@ -99,8 +129,6 @@ static void make_cond_expr_edges (basic_block);
static void make_gimple_switch_edges (basic_block);
static void make_goto_expr_edges (basic_block);
static void make_gimple_asm_edges (basic_block);
-static unsigned int locus_map_hash (const void *);
-static int locus_map_eq (const void *, const void *);
static void assign_discriminator (location_t, basic_block);
static edge gimple_redirect_edge_and_branch (edge, basic_block);
static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);
@@ -201,11 +229,10 @@ build_gimple_cfg (gimple_seq seq)
group_case_labels ();
/* Create the edges of the flowgraph. */
- discriminator_per_locus = htab_create (13, locus_map_hash, locus_map_eq,
- free);
+ discriminator_per_locus.create (13);
make_edges ();
cleanup_dead_labels ();
- htab_delete (discriminator_per_locus);
+ discriminator_per_locus.dispose ();
}
static unsigned int
@@ -675,26 +702,6 @@ make_edges (void)
fold_cond_expr_cond ();
}
-/* Trivial hash function for a location_t. ITEM is a pointer to
- a hash table entry that maps a location_t to a discriminator. */
-
-static unsigned int
-locus_map_hash (const void *item)
-{
- return ((const struct locus_discrim_map *) item)->locus;
-}
-
-/* Equality function for the locus-to-discriminator map. VA and VB
- point to the two hash table entries to compare. */
-
-static int
-locus_map_eq (const void *va, const void *vb)
-{
- const struct locus_discrim_map *a = (const struct locus_discrim_map *) va;
- const struct locus_discrim_map *b = (const struct locus_discrim_map *) vb;
- return a->locus == b->locus;
-}
-
/* Find the next available discriminator value for LOCUS. The
discriminator distinguishes among several basic blocks that
share a common locus, allowing for more accurate sample-based
@@ -708,9 +715,7 @@ next_discriminator_for_locus (location_t locus)
item.locus = locus;
item.discriminator = 0;
- slot = (struct locus_discrim_map **)
- htab_find_slot_with_hash (discriminator_per_locus, (void *) &item,
- (hashval_t) locus, INSERT);
+ slot = discriminator_per_locus.find_slot_with_hash (&item, locus, INSERT);
gcc_assert (slot);
if (*slot == HTAB_EMPTY_ENTRY)
{
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index f8dbe0a8519..cd8f53b7b32 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
+#include "tree-hasher.h"
/* For each complex ssa name, a lattice value. We're interested in finding
@@ -53,7 +54,7 @@ static vec<complex_lattice_t> complex_lattice_values;
/* For each complex variable, a pair of variables for the components exists in
the hashtable. */
-static htab_t complex_variable_components;
+static int_tree_htab_type complex_variable_components;
/* For each complex SSA_NAME, a pair of ssa names for the components. */
static vec<tree> complex_ssa_name_components;
@@ -65,7 +66,7 @@ cvc_lookup (unsigned int uid)
{
struct int_tree_map *h, in;
in.uid = uid;
- h = (struct int_tree_map *) htab_find_with_hash (complex_variable_components, &in, uid);
+ h = complex_variable_components.find_with_hash (&in, uid);
return h ? h->to : NULL;
}
@@ -75,14 +76,13 @@ static void
cvc_insert (unsigned int uid, tree to)
{
struct int_tree_map *h;
- void **loc;
+ int_tree_map **loc;
h = XNEW (struct int_tree_map);
h->uid = uid;
h->to = to;
- loc = htab_find_slot_with_hash (complex_variable_components, h,
- uid, INSERT);
- *(struct int_tree_map **) loc = h;
+ loc = complex_variable_components.find_slot_with_hash (h, uid, INSERT);
+ *loc = h;
}
/* Return true if T is not a zero constant. In the case of real values,
@@ -1604,8 +1604,7 @@ tree_lower_complex (void)
init_parameter_lattice_values ();
ssa_propagate (complex_visit_stmt, complex_visit_phi);
- complex_variable_components = htab_create (10, int_tree_map_hash,
- int_tree_map_eq, free);
+ complex_variable_components.create (10);
complex_ssa_name_components.create (2 * num_ssa_names);
complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names);
@@ -1626,7 +1625,7 @@ tree_lower_complex (void)
gsi_commit_edge_inserts ();
- htab_delete (complex_variable_components);
+ complex_variable_components.dispose ();
complex_ssa_name_components.release ();
complex_lattice_values.release ();
return 0;
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 6b9dac9258e..88091051e2a 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
@@ -193,20 +194,42 @@ struct finally_tree_node
gimple parent;
};
+/* Hashtable helpers. */
+
+struct finally_tree_hasher : typed_free_remove <finally_tree_node>
+{
+ typedef finally_tree_node value_type;
+ typedef finally_tree_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+finally_tree_hasher::hash (const value_type *v)
+{
+ return (intptr_t)v->child.t >> 4;
+}
+
+inline bool
+finally_tree_hasher::equal (const value_type *v, const compare_type *c)
+{
+ return v->child.t == c->child.t;
+}
+
/* Note that this table is *not* marked GTY. It is short-lived. */
-static htab_t finally_tree;
+static hash_table <finally_tree_hasher> finally_tree;
static void
record_in_finally_tree (treemple child, gimple parent)
{
struct finally_tree_node *n;
- void **slot;
+ finally_tree_node **slot;
n = XNEW (struct finally_tree_node);
n->child = child;
n->parent = parent;
- slot = htab_find_slot (finally_tree, n, INSERT);
+ slot = finally_tree.find_slot (n, INSERT);
gcc_assert (!*slot);
*slot = n;
}
@@ -285,7 +308,7 @@ outside_finally_tree (treemple start, gimple target)
do
{
n.child = start;
- p = (struct finally_tree_node *) htab_find (finally_tree, &n);
+ p = finally_tree.find (&n);
if (!p)
return true;
start.g = p->parent;
@@ -2101,7 +2124,7 @@ lower_eh_constructs (void)
if (bodyp == NULL)
return 0;
- finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free);
+ finally_tree.create (31);
eh_region_may_contain_throw_map = BITMAP_ALLOC (NULL);
memset (&null_state, 0, sizeof (null_state));
@@ -2119,7 +2142,7 @@ lower_eh_constructs (void)
didn't change its value, and we don't have to re-set the function. */
gcc_assert (bodyp == gimple_body (current_function_decl));
- htab_delete (finally_tree);
+ finally_tree.dispose ();
BITMAP_FREE (eh_region_may_contain_throw_map);
eh_seq = NULL;
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index d7d7360a9f9..7537139f5da 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -103,41 +103,22 @@ get_emutls_object_name (tree name)
return prefix_name (prefix, name);
}
-/* Create the fields of the type for the control variables. Ordinarily
+/* Create the type for the control variables. Ordinarily
this must match struct __emutls_object defined in emutls.c. However
this is a target hook so that VxWorks can define its own layout. */
tree
-default_emutls_var_fields (tree type, tree *name ATTRIBUTE_UNUSED)
+default_emutls_object_type (void)
{
- tree word_type_node, field, next_field;
-
- field = build_decl (UNKNOWN_LOCATION,
- FIELD_DECL, get_identifier ("__templ"), ptr_type_node);
- DECL_CONTEXT (field) = type;
- next_field = field;
-
- field = build_decl (UNKNOWN_LOCATION,
- FIELD_DECL, get_identifier ("__offset"),
- ptr_type_node);
- DECL_CONTEXT (field) = type;
- DECL_CHAIN (field) = next_field;
- next_field = field;
-
- word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
- field = build_decl (UNKNOWN_LOCATION,
- FIELD_DECL, get_identifier ("__align"),
- word_type_node);
- DECL_CONTEXT (field) = type;
- DECL_CHAIN (field) = next_field;
- next_field = field;
-
- field = build_decl (UNKNOWN_LOCATION,
- FIELD_DECL, get_identifier ("__size"), word_type_node);
- DECL_CONTEXT (field) = type;
- DECL_CHAIN (field) = next_field;
-
- return field;
+ tree word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
+ record_builder rec;
+ rec.add_field ("__size", word_type_node);
+ rec.add_field ("__align", word_type_node);
+ rec.add_field ("__offset", ptr_type_node);
+ rec.add_field ("__templ", ptr_type_node);
+ rec.layout ();
+ rec.decl_name ("__emutls_object");
+ return rec.as_tree ();
}
/* Initialize emulated tls object TO, which refers to TLS variable DECL and
@@ -182,24 +163,9 @@ default_emutls_var_init (tree to, tree decl, tree proxy)
static tree
get_emutls_object_type (void)
{
- tree type, type_name, field;
-
- type = emutls_object_type;
- if (type)
- return type;
-
- emutls_object_type = type = lang_hooks.types.make_type (RECORD_TYPE);
- type_name = NULL;
- field = targetm.emutls.var_fields (type, &type_name);
- if (!type_name)
- type_name = get_identifier ("__emutls_object");
- type_name = build_decl (UNKNOWN_LOCATION,
- TYPE_DECL, type_name, type);
- TYPE_NAME (type) = type_name;
- TYPE_FIELDS (type) = field;
- layout_type (type);
-
- return type;
+ if (!emutls_object_type)
+ emutls_object_type = targetm.emutls.object_type ();
+ return emutls_object_type;
}
/* Create a read-only variable like DECL, with the same DECL_INITIAL.
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 20584b8c60f..37035382905 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -282,12 +282,6 @@ struct int_tree_map {
tree to;
};
-extern unsigned int int_tree_map_hash (const void *);
-extern int int_tree_map_eq (const void *, const void *);
-
-extern unsigned int uid_decl_map_hash (const void *);
-extern int uid_decl_map_eq (const void *, const void *);
-
#define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names))
#define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)])
diff --git a/gcc/tree-hasher.h b/gcc/tree-hasher.h
new file mode 100644
index 00000000000..e403c9fcbe4
--- /dev/null
+++ b/gcc/tree-hasher.h
@@ -0,0 +1,55 @@
+/* Hash Table Helper for Trees
+ 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/>. */
+
+#ifndef GCC_TREE_HASHER_H
+#define GCC_TREE_HASHER_H 1
+
+#include "hash-table.h"
+#include "tree-flow.h"
+
+/* Hashtable helpers. */
+
+struct int_tree_hasher : typed_free_remove <int_tree_map>
+{
+ typedef int_tree_map value_type;
+ typedef int_tree_map compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash a UID in a int_tree_map. */
+
+inline hashval_t
+int_tree_hasher::hash (const value_type *item)
+{
+ return item->uid;
+}
+
+/* Return true if the uid in both int tree maps are equal. */
+
+inline bool
+int_tree_hasher::equal (const value_type *a, const compare_type *b)
+{
+ return (a->uid == b->uid);
+}
+
+typedef hash_table <int_tree_hasher> int_tree_htab_type;
+
+#endif /* GCC_TREE_HASHER_H */
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 65c15daca4c..f028b25b19a 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "gimple.h"
#include "tree-inline.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "tree-pass.h"
#include "cfgloop.h"
#include "domwalk.h"
@@ -160,9 +160,32 @@ struct var_info_d
typedef struct var_info_d *var_info_p;
+/* VAR_INFOS hashtable helpers. */
+
+struct var_info_hasher : typed_free_remove <var_info_d>
+{
+ typedef var_info_d value_type;
+ typedef var_info_d compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+var_info_hasher::hash (const value_type *p)
+{
+ return DECL_UID (p->var);
+}
+
+inline bool
+var_info_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ return p1->var == p2->var;
+}
+
+
/* Each entry in VAR_INFOS contains an element of type STRUCT
VAR_INFO_D. */
-static htab_t var_infos;
+static hash_table <var_info_hasher> var_infos;
/* Information stored for SSA names. */
@@ -340,17 +363,17 @@ static inline var_info_p
get_var_info (tree decl)
{
struct var_info_d vi;
- void **slot;
+ var_info_d **slot;
vi.var = decl;
- slot = htab_find_slot_with_hash (var_infos, &vi, DECL_UID (decl), INSERT);
+ slot = var_infos.find_slot_with_hash (&vi, DECL_UID (decl), INSERT);
if (*slot == NULL)
{
var_info_p v = XCNEW (struct var_info_d);
v->var = decl;
- *slot = (void *)v;
+ *slot = v;
return v;
}
- return (var_info_p) *slot;
+ return *slot;
}
@@ -1044,15 +1067,15 @@ insert_phi_nodes_compare_var_infos (const void *a, const void *b)
static void
insert_phi_nodes (bitmap_head *dfs)
{
- htab_iterator hi;
+ hash_table <var_info_hasher>::iterator hi;
unsigned i;
var_info_p info;
vec<var_info_p> vars;
timevar_push (TV_TREE_INSERT_PHI_NODES);
- vars.create (htab_elements (var_infos));
- FOR_EACH_HTAB_ELEMENT (var_infos, info, var_info_p, hi)
+ vars.create (var_infos.elements ());
+ FOR_EACH_HASH_TABLE_ELEMENT (var_infos, info, var_info_p, hi)
if (info->info.need_phi_state != NEED_PHI_STATE_NO)
vars.quick_push (info);
@@ -1632,12 +1655,12 @@ debug_tree_ssa (void)
/* Dump statistics for the hash table HTAB. */
static void
-htab_statistics (FILE *file, htab_t htab)
+htab_statistics (FILE *file, hash_table <var_info_hasher> htab)
{
fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
- (long) htab_size (htab),
- (long) htab_elements (htab),
- htab_collisions (htab));
+ (long) htab.size (),
+ (long) htab.elements (),
+ htab.collisions ());
}
@@ -1646,7 +1669,7 @@ htab_statistics (FILE *file, htab_t htab)
void
dump_tree_ssa_stats (FILE *file)
{
- if (var_infos)
+ if (var_infos.is_created ())
{
fprintf (file, "\nHash table statistics:\n");
fprintf (file, " var_infos: ");
@@ -1665,29 +1688,12 @@ debug_tree_ssa_stats (void)
}
-/* Hashing and equality functions for VAR_INFOS. */
-
-static hashval_t
-var_info_hash (const void *p)
-{
- return DECL_UID (((const struct var_info_d *)p)->var);
-}
-
-static int
-var_info_eq (const void *p1, const void *p2)
-{
- return ((const struct var_info_d *)p1)->var
- == ((const struct var_info_d *)p2)->var;
-}
-
-
/* Callback for htab_traverse to dump the VAR_INFOS hash table. */
-static int
-debug_var_infos_r (void **slot, void *data)
+int
+debug_var_infos_r (var_info_d **slot, FILE *file)
{
- FILE *file = (FILE *) data;
- struct var_info_d *info = (struct var_info_d *) *slot;
+ struct var_info_d *info = *slot;
fprintf (file, "VAR: ");
print_generic_expr (file, info->var, dump_flags);
@@ -1708,8 +1714,8 @@ void
dump_var_infos (FILE *file)
{
fprintf (file, "\n\nDefinition and live-in blocks:\n\n");
- if (var_infos)
- htab_traverse (var_infos, debug_var_infos_r, file);
+ if (var_infos.is_created ())
+ var_infos.traverse <FILE *, debug_var_infos_r> (file);
}
@@ -2216,7 +2222,7 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what)
if (dump_file && (dump_flags & TDF_STATS))
{
dump_dfa_stats (dump_file);
- if (var_infos)
+ if (var_infos.is_created ())
dump_tree_ssa_stats (dump_file);
}
@@ -2296,9 +2302,8 @@ init_ssa_renamer (void)
cfun->gimple_df->in_ssa_p = false;
/* Allocate memory for the DEF_BLOCKS hash table. */
- gcc_assert (var_infos == NULL);
- var_infos = htab_create (vec_safe_length (cfun->local_decls),
- var_info_hash, var_info_eq, free);
+ gcc_assert (!var_infos.is_created ());
+ var_infos.create (vec_safe_length (cfun->local_decls));
bitmap_obstack_initialize (&update_ssa_obstack);
}
@@ -2309,11 +2314,8 @@ init_ssa_renamer (void)
static void
fini_ssa_renamer (void)
{
- if (var_infos)
- {
- htab_delete (var_infos);
- var_infos = NULL;
- }
+ if (var_infos.is_created ())
+ var_infos.dispose ();
bitmap_obstack_release (&update_ssa_obstack);
@@ -3189,7 +3191,7 @@ update_ssa (unsigned update_flags)
{
/* If we rename bare symbols initialize the mapping to
auxiliar info we need to keep track of. */
- var_infos = htab_create (47, var_info_hash, var_info_eq, free);
+ var_infos.create (47);
/* If we have to rename some symbols from scratch, we need to
start the process at the root of the CFG. FIXME, it should
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
index b250bfefadb..65943430322 100644
--- a/gcc/tree-mudflap.c
+++ b/gcc/tree-mudflap.c
@@ -317,23 +317,12 @@ mf_make_builtin (enum tree_code category, const char *name, tree type)
static inline tree
mf_make_mf_cache_struct_type (tree field_type)
{
- /* There is, abominably, no language-independent way to construct a
- RECORD_TYPE. So we have to call the basic type construction
- primitives by hand. */
- tree fieldlo = build_decl (UNKNOWN_LOCATION,
- FIELD_DECL, get_identifier ("low"), field_type);
- tree fieldhi = build_decl (UNKNOWN_LOCATION,
- FIELD_DECL, get_identifier ("high"), field_type);
-
- tree struct_type = make_node (RECORD_TYPE);
- DECL_CONTEXT (fieldlo) = struct_type;
- DECL_CONTEXT (fieldhi) = struct_type;
- DECL_CHAIN (fieldlo) = fieldhi;
- TYPE_FIELDS (struct_type) = fieldlo;
- TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
- layout_type (struct_type);
-
- return struct_type;
+ record_builder rec;
+ rec.add_field ("low", field_type);
+ rec.add_field ("high", field_type);
+ rec.layout ();
+ rec.tag_name ("__mf_cache");
+ return rec.as_tree ();
}
/* Initialize the global tree nodes that correspond to mf-runtime.h
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 1729f230115..088fc462970 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "langhooks.h"
#include "tree-vectorizer.h"
+#include "tree-hasher.h"
/* This pass tries to distribute iterations of loops into several threads.
The implementation is straightforward -- for each loop we test whether its
@@ -176,36 +177,44 @@ struct reduction_info
operation. */
};
-/* Equality and hash functions for hashtab code. */
+/* Reduction info hashtable helpers. */
-static int
-reduction_info_eq (const void *aa, const void *bb)
+struct reduction_hasher : typed_free_remove <reduction_info>
{
- const struct reduction_info *a = (const struct reduction_info *) aa;
- const struct reduction_info *b = (const struct reduction_info *) bb;
+ typedef reduction_info value_type;
+ typedef reduction_info compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Equality and hash functions for hashtab code. */
+inline bool
+reduction_hasher::equal (const value_type *a, const compare_type *b)
+{
return (a->reduc_phi == b->reduc_phi);
}
-static hashval_t
-reduction_info_hash (const void *aa)
+inline hashval_t
+reduction_hasher::hash (const value_type *a)
{
- const struct reduction_info *a = (const struct reduction_info *) aa;
-
return a->reduc_version;
}
+typedef hash_table <reduction_hasher> reduction_info_table_type;
+
+
static struct reduction_info *
-reduction_phi (htab_t reduction_list, gimple phi)
+reduction_phi (reduction_info_table_type reduction_list, gimple phi)
{
struct reduction_info tmpred, *red;
- if (htab_elements (reduction_list) == 0 || phi == NULL)
+ if (reduction_list.elements () == 0 || phi == NULL)
return NULL;
tmpred.reduc_phi = phi;
tmpred.reduc_version = gimple_uid (phi);
- red = (struct reduction_info *) htab_find (reduction_list, &tmpred);
+ red = reduction_list.find (&tmpred);
return red;
}
@@ -220,25 +229,32 @@ struct name_to_copy_elt
value. */
};
-/* Equality and hash functions for hashtab code. */
+/* Name copies hashtable helpers. */
-static int
-name_to_copy_elt_eq (const void *aa, const void *bb)
+struct name_to_copy_hasher : typed_free_remove <name_to_copy_elt>
{
- const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
- const struct name_to_copy_elt *b = (const struct name_to_copy_elt *) bb;
+ typedef name_to_copy_elt value_type;
+ typedef name_to_copy_elt compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Equality and hash functions for hashtab code. */
+inline bool
+name_to_copy_hasher::equal (const value_type *a, const compare_type *b)
+{
return a->version == b->version;
}
-static hashval_t
-name_to_copy_elt_hash (const void *aa)
+inline hashval_t
+name_to_copy_hasher::hash (const value_type *a)
{
- const struct name_to_copy_elt *a = (const struct name_to_copy_elt *) aa;
-
return (hashval_t) a->version;
}
+typedef hash_table <name_to_copy_hasher> name_to_copy_table_type;
+
/* A transformation matrix, which is a self-contained ROWSIZE x COLSIZE
matrix. Rather than use floats, we simply keep a single DENOMINATOR that
represents the denominator for every element in the matrix. */
@@ -445,11 +461,11 @@ loop_has_blocks_with_irreducible_flag (struct loop *loop)
right before GSI. */
static tree
-take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
- gimple_stmt_iterator *gsi)
+take_address_of (tree obj, tree type, edge entry,
+ int_tree_htab_type decl_address, gimple_stmt_iterator *gsi)
{
int uid;
- void **dslot;
+ int_tree_map **dslot;
struct int_tree_map ielt, *nielt;
tree *var_p, name, addr;
gimple stmt;
@@ -472,7 +488,7 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
on it. */
uid = DECL_UID (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0));
ielt.uid = uid;
- dslot = htab_find_slot_with_hash (decl_address, &ielt, uid, INSERT);
+ dslot = decl_address.find_slot_with_hash (&ielt, uid, INSERT);
if (!*dslot)
{
if (gsi == NULL)
@@ -490,7 +506,7 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
*dslot = nielt;
}
else
- name = ((struct int_tree_map *) *dslot)->to;
+ name = (*dslot)->to;
/* Express the address in terms of the canonical SSA name. */
TREE_OPERAND (*var_p, 0) = name;
@@ -517,15 +533,14 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address,
for reduction described in SLOT, and place it at the preheader of
the loop described in DATA. */
-static int
-initialize_reductions (void **slot, void *data)
+int
+initialize_reductions (reduction_info **slot, struct loop *loop)
{
tree init, c;
tree bvar, type, arg;
edge e;
- struct reduction_info *const reduc = (struct reduction_info *) *slot;
- struct loop *loop = (struct loop *) data;
+ struct reduction_info *const reduc = *slot;
/* Create initialization in preheader:
reduction_variable = initialization value of reduction. */
@@ -567,7 +582,7 @@ struct elv_data
{
struct walk_stmt_info info;
edge entry;
- htab_t decl_address;
+ int_tree_htab_type decl_address;
gimple_stmt_iterator *gsi;
bool changed;
bool reset;
@@ -657,7 +672,7 @@ eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data)
static void
eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi,
- htab_t decl_address)
+ int_tree_htab_type decl_address)
{
struct elv_data dta;
gimple stmt = gsi_stmt (*gsi);
@@ -709,8 +724,8 @@ eliminate_local_variables (edge entry, edge exit)
unsigned i;
gimple_stmt_iterator gsi;
bool has_debug_stmt = false;
- htab_t decl_address = htab_create (10, int_tree_map_hash, int_tree_map_eq,
- free);
+ int_tree_htab_type decl_address;
+ decl_address.create (10);
basic_block entry_bb = entry->src;
basic_block exit_bb = exit->dest;
@@ -734,7 +749,7 @@ eliminate_local_variables (edge entry, edge exit)
if (gimple_debug_bind_p (gsi_stmt (gsi)))
eliminate_local_variables_stmt (entry, &gsi, decl_address);
- htab_delete (decl_address);
+ decl_address.dispose ();
body.release ();
}
@@ -773,25 +788,25 @@ expr_invariant_in_region_p (edge entry, edge exit, tree expr)
duplicated, storing the copies in DECL_COPIES. */
static tree
-separate_decls_in_region_name (tree name,
- htab_t name_copies, htab_t decl_copies,
- bool copy_name_p)
+separate_decls_in_region_name (tree name, name_to_copy_table_type name_copies,
+ int_tree_htab_type decl_copies, bool copy_name_p)
{
tree copy, var, var_copy;
unsigned idx, uid, nuid;
struct int_tree_map ielt, *nielt;
struct name_to_copy_elt elt, *nelt;
- void **slot, **dslot;
+ name_to_copy_elt **slot;
+ int_tree_map **dslot;
if (TREE_CODE (name) != SSA_NAME)
return name;
idx = SSA_NAME_VERSION (name);
elt.version = idx;
- slot = htab_find_slot_with_hash (name_copies, &elt, idx,
- copy_name_p ? INSERT : NO_INSERT);
+ slot = name_copies.find_slot_with_hash (&elt, idx,
+ copy_name_p ? INSERT : NO_INSERT);
if (slot && *slot)
- return ((struct name_to_copy_elt *) *slot)->new_name;
+ return (*slot)->new_name;
if (copy_name_p)
{
@@ -814,7 +829,7 @@ separate_decls_in_region_name (tree name,
uid = DECL_UID (var);
ielt.uid = uid;
- dslot = htab_find_slot_with_hash (decl_copies, &ielt, uid, INSERT);
+ dslot = decl_copies.find_slot_with_hash (&ielt, uid, INSERT);
if (!*dslot)
{
var_copy = create_tmp_var (TREE_TYPE (var), get_name (var));
@@ -828,7 +843,7 @@ separate_decls_in_region_name (tree name,
it again. */
nuid = DECL_UID (var_copy);
ielt.uid = nuid;
- dslot = htab_find_slot_with_hash (decl_copies, &ielt, nuid, INSERT);
+ dslot = decl_copies.find_slot_with_hash (&ielt, nuid, INSERT);
gcc_assert (!*dslot);
nielt = XNEW (struct int_tree_map);
nielt->uid = nuid;
@@ -851,7 +866,8 @@ separate_decls_in_region_name (tree name,
static void
separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
- htab_t name_copies, htab_t decl_copies)
+ name_to_copy_table_type name_copies,
+ int_tree_htab_type decl_copies)
{
use_operand_p use;
def_operand_p def;
@@ -889,15 +905,17 @@ separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
replacement decls are stored in DECL_COPIES. */
static bool
-separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
- htab_t decl_copies)
+separate_decls_in_region_debug (gimple stmt,
+ name_to_copy_table_type name_copies,
+ int_tree_htab_type decl_copies)
{
use_operand_p use;
ssa_op_iter oi;
tree var, name;
struct int_tree_map ielt;
struct name_to_copy_elt elt;
- void **slot, **dslot;
+ name_to_copy_elt **slot;
+ int_tree_map **dslot;
if (gimple_debug_bind_p (stmt))
var = gimple_debug_bind_get_var (stmt);
@@ -909,7 +927,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
return true;
gcc_assert (DECL_P (var) && SSA_VAR_P (var));
ielt.uid = DECL_UID (var);
- dslot = htab_find_slot_with_hash (decl_copies, &ielt, ielt.uid, NO_INSERT);
+ dslot = decl_copies.find_slot_with_hash (&ielt, ielt.uid, NO_INSERT);
if (!dslot)
return true;
if (gimple_debug_bind_p (stmt))
@@ -924,7 +942,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
continue;
elt.version = SSA_NAME_VERSION (name);
- slot = htab_find_slot_with_hash (name_copies, &elt, elt.version, NO_INSERT);
+ slot = name_copies.find_slot_with_hash (&elt, elt.version, NO_INSERT);
if (!slot)
{
gimple_debug_bind_reset_value (stmt);
@@ -932,7 +950,7 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
break;
}
- SET_USE (use, ((struct name_to_copy_elt *) *slot)->new_name);
+ SET_USE (use, (*slot)->new_name);
}
return false;
@@ -941,12 +959,11 @@ separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
/* Callback for htab_traverse. Adds a field corresponding to the reduction
specified in SLOT. The type is passed in DATA. */
-static int
-add_field_for_reduction (void **slot, void *data)
+int
+add_field_for_reduction (reduction_info **slot, tree type)
{
- struct reduction_info *const red = (struct reduction_info *) *slot;
- tree const type = (tree) data;
+ struct reduction_info *const red = *slot;
tree var = SSA_NAME_VAR (gimple_assign_lhs (red->reduc_stmt));
tree field = build_decl (gimple_location (red->reduc_stmt),
FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
@@ -961,11 +978,10 @@ add_field_for_reduction (void **slot, void *data)
/* Callback for htab_traverse. Adds a field corresponding to a ssa name
described in SLOT. The type is passed in DATA. */
-static int
-add_field_for_name (void **slot, void *data)
+int
+add_field_for_name (name_to_copy_elt **slot, tree type)
{
- struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
- tree type = (tree) data;
+ struct name_to_copy_elt *const elt = *slot;
tree name = ssa_name (elt->version);
tree field = build_decl (UNKNOWN_LOCATION,
FIELD_DECL, SSA_NAME_IDENTIFIER (name),
@@ -984,11 +1000,10 @@ add_field_for_name (void **slot, void *data)
The phi's result will be stored in NEW_PHI field of the
reduction's data structure. */
-static int
-create_phi_for_local_result (void **slot, void *data)
+int
+create_phi_for_local_result (reduction_info **slot, struct loop *loop)
{
- struct reduction_info *const reduc = (struct reduction_info *) *slot;
- const struct loop *const loop = (const struct loop *) data;
+ struct reduction_info *const reduc = *slot;
edge e;
gimple new_phi;
basic_block store_bb;
@@ -1034,11 +1049,10 @@ struct clsn_data
DATA annotates the place in memory the atomic operation relates to,
and the basic block it needs to be generated in. */
-static int
-create_call_for_reduction_1 (void **slot, void *data)
+int
+create_call_for_reduction_1 (reduction_info **slot, struct clsn_data *clsn_data)
{
- struct reduction_info *const reduc = (struct reduction_info *) *slot;
- struct clsn_data *const clsn_data = (struct clsn_data *) data;
+ struct reduction_info *const reduc = *slot;
gimple_stmt_iterator gsi;
tree type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
tree load_struct;
@@ -1087,23 +1101,24 @@ create_call_for_reduction_1 (void **slot, void *data)
LD_ST_DATA describes the shared data structure where
shared data is stored in and loaded from. */
static void
-create_call_for_reduction (struct loop *loop, htab_t reduction_list,
+create_call_for_reduction (struct loop *loop,
+ reduction_info_table_type reduction_list,
struct clsn_data *ld_st_data)
{
- htab_traverse (reduction_list, create_phi_for_local_result, loop);
+ reduction_list.traverse <struct loop *, create_phi_for_local_result> (loop);
/* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
ld_st_data->load_bb = FALLTHRU_EDGE (loop->latch)->dest;
- htab_traverse (reduction_list, create_call_for_reduction_1, ld_st_data);
+ reduction_list
+ .traverse <struct clsn_data *, create_call_for_reduction_1> (ld_st_data);
}
/* Callback for htab_traverse. Loads the final reduction value at the
join point of all threads, and inserts it in the right place. */
-static int
-create_loads_for_reductions (void **slot, void *data)
+int
+create_loads_for_reductions (reduction_info **slot, struct clsn_data *clsn_data)
{
- struct reduction_info *const red = (struct reduction_info *) *slot;
- struct clsn_data *const clsn_data = (struct clsn_data *) data;
+ struct reduction_info *const red = *slot;
gimple stmt;
gimple_stmt_iterator gsi;
tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
@@ -1137,7 +1152,7 @@ create_loads_for_reductions (void **slot, void *data)
REDUCTION_LIST describes the list of reductions that the
loads should be generated for. */
static void
-create_final_loads_for_reduction (htab_t reduction_list,
+create_final_loads_for_reduction (reduction_info_table_type reduction_list,
struct clsn_data *ld_st_data)
{
gimple_stmt_iterator gsi;
@@ -1151,7 +1166,8 @@ create_final_loads_for_reduction (htab_t reduction_list,
gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
SSA_NAME_DEF_STMT (ld_st_data->load) = stmt;
- htab_traverse (reduction_list, create_loads_for_reductions, ld_st_data);
+ reduction_list
+ .traverse <struct clsn_data *, create_loads_for_reductions> (ld_st_data);
}
@@ -1161,11 +1177,10 @@ create_final_loads_for_reduction (htab_t reduction_list,
The reduction is specified in SLOT. The store information is
passed in DATA. */
-static int
-create_stores_for_reduction (void **slot, void *data)
+int
+create_stores_for_reduction (reduction_info **slot, struct clsn_data *clsn_data)
{
- struct reduction_info *const red = (struct reduction_info *) *slot;
- struct clsn_data *const clsn_data = (struct clsn_data *) data;
+ struct reduction_info *const red = *slot;
tree t;
gimple stmt;
gimple_stmt_iterator gsi;
@@ -1183,11 +1198,11 @@ create_stores_for_reduction (void **slot, void *data)
store to a field of STORE in STORE_BB for the ssa name and its duplicate
specified in SLOT. */
-static int
-create_loads_and_stores_for_name (void **slot, void *data)
+int
+create_loads_and_stores_for_name (name_to_copy_elt **slot,
+ struct clsn_data *clsn_data)
{
- struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
- struct clsn_data *const clsn_data = (struct clsn_data *) data;
+ struct name_to_copy_elt *const elt = *slot;
tree t;
gimple stmt;
gimple_stmt_iterator gsi;
@@ -1244,17 +1259,18 @@ create_loads_and_stores_for_name (void **slot, void *data)
in LOOP. */
static void
-separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
+separate_decls_in_region (edge entry, edge exit,
+ reduction_info_table_type reduction_list,
tree *arg_struct, tree *new_arg_struct,
struct clsn_data *ld_st_data)
{
basic_block bb1 = split_edge (entry);
basic_block bb0 = single_pred (bb1);
- htab_t name_copies = htab_create (10, name_to_copy_elt_hash,
- name_to_copy_elt_eq, free);
- htab_t decl_copies = htab_create (10, int_tree_map_hash, int_tree_map_eq,
- free);
+ name_to_copy_table_type name_copies;
+ name_copies.create (10);
+ int_tree_htab_type decl_copies;
+ decl_copies.create (10);
unsigned i;
tree type, type_name, nvar;
gimple_stmt_iterator gsi;
@@ -1320,7 +1336,7 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
body.release ();
- if (htab_elements (name_copies) == 0 && htab_elements (reduction_list) == 0)
+ if (name_copies.elements () == 0 && reduction_list.elements () == 0)
{
/* It may happen that there is nothing to copy (if there are only
loop carried and external variables in the loop). */
@@ -1336,12 +1352,11 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
type);
TYPE_NAME (type) = type_name;
- htab_traverse (name_copies, add_field_for_name, type);
- if (reduction_list && htab_elements (reduction_list) > 0)
+ name_copies.traverse <tree, add_field_for_name> (type);
+ if (reduction_list.is_created () && reduction_list.elements () > 0)
{
/* Create the fields for reductions. */
- htab_traverse (reduction_list, add_field_for_reduction,
- type);
+ reduction_list.traverse <tree, add_field_for_reduction> (type);
}
layout_type (type);
@@ -1355,15 +1370,17 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
ld_st_data->store_bb = bb0;
ld_st_data->load_bb = bb1;
- htab_traverse (name_copies, create_loads_and_stores_for_name,
- ld_st_data);
+ name_copies
+ .traverse <struct clsn_data *, create_loads_and_stores_for_name>
+ (ld_st_data);
/* Load the calculation from memory (after the join of the threads). */
- if (reduction_list && htab_elements (reduction_list) > 0)
+ if (reduction_list.is_created () && reduction_list.elements () > 0)
{
- htab_traverse (reduction_list, create_stores_for_reduction,
- ld_st_data);
+ reduction_list
+ .traverse <struct clsn_data *, create_stores_for_reduction>
+ (ld_st_data);
clsn_data.load = make_ssa_name (nvar, NULL);
clsn_data.load_bb = exit->dest;
clsn_data.store = ld_st_data->store;
@@ -1371,8 +1388,8 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
}
}
- htab_delete (decl_copies);
- htab_delete (name_copies);
+ decl_copies.dispose ();
+ name_copies.dispose ();
}
/* Bitmap containing uids of functions created by parallelization. We cannot
@@ -1461,7 +1478,9 @@ create_loop_fn (location_t loc)
REDUCTION_LIST describes the reductions in LOOP. */
static void
-transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit)
+transform_to_exit_first_loop (struct loop *loop,
+ reduction_info_table_type reduction_list,
+ tree nit)
{
basic_block *bbs, *nbbs, ex_bb, orig_header;
unsigned n;
@@ -1530,7 +1549,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
PHI_RESULT of this phi is the resulting value of the reduction
variable when exiting the loop. */
- if (htab_elements (reduction_list) > 0)
+ if (reduction_list.elements () > 0)
{
struct reduction_info *red;
@@ -1708,7 +1727,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
REDUCTION_LIST describes the reductions existent in the LOOP. */
static void
-gen_parallel_loop (struct loop *loop, htab_t reduction_list,
+gen_parallel_loop (struct loop *loop, reduction_info_table_type reduction_list,
unsigned n_threads, struct tree_niter_desc *niter)
{
loop_iterator li;
@@ -1834,8 +1853,8 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
transform_to_exit_first_loop (loop, reduction_list, nit);
/* Generate initializations for reductions. */
- if (htab_elements (reduction_list) > 0)
- htab_traverse (reduction_list, initialize_reductions, loop);
+ if (reduction_list.elements () > 0)
+ reduction_list.traverse <struct loop *, initialize_reductions> (loop);
/* Eliminate the references to local variables from the loop. */
gcc_assert (single_exit (loop));
@@ -1855,7 +1874,7 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
loc = gimple_location (cond_stmt);
parallel_head = create_parallel_loop (loop, create_loop_fn (loc), arg_struct,
new_arg_struct, n_threads, loc);
- if (htab_elements (reduction_list) > 0)
+ if (reduction_list.elements () > 0)
create_call_for_reduction (loop, reduction_list, &clsn_data);
scev_reset ();
@@ -1902,9 +1921,10 @@ loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED)
and PHI, insert it to the REDUCTION_LIST. */
static void
-build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi)
+build_new_reduction (reduction_info_table_type reduction_list,
+ gimple reduc_stmt, gimple phi)
{
- PTR *slot;
+ reduction_info **slot;
struct reduction_info *new_reduction;
gcc_assert (reduc_stmt);
@@ -1923,16 +1943,16 @@ build_new_reduction (htab_t reduction_list, gimple reduc_stmt, gimple phi)
new_reduction->reduc_phi = phi;
new_reduction->reduc_version = SSA_NAME_VERSION (gimple_phi_result (phi));
new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt);
- slot = htab_find_slot (reduction_list, new_reduction, INSERT);
+ slot = reduction_list.find_slot (new_reduction, INSERT);
*slot = new_reduction;
}
/* Callback for htab_traverse. Sets gimple_uid of reduc_phi stmts. */
-static int
-set_reduc_phi_uids (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+set_reduc_phi_uids (reduction_info **slot, void *data ATTRIBUTE_UNUSED)
{
- struct reduction_info *const red = (struct reduction_info *) *slot;
+ struct reduction_info *const red = *slot;
gimple_set_uid (red->reduc_phi, red->reduc_version);
return 1;
}
@@ -1940,7 +1960,7 @@ set_reduc_phi_uids (void **slot, void *data ATTRIBUTE_UNUSED)
/* Detect all reductions in the LOOP, insert them into REDUCTION_LIST. */
static void
-gather_scalar_reductions (loop_p loop, htab_t reduction_list)
+gather_scalar_reductions (loop_p loop, reduction_info_table_type reduction_list)
{
gimple_stmt_iterator gsi;
loop_vec_info simple_loop_info;
@@ -1972,7 +1992,7 @@ gather_scalar_reductions (loop_p loop, htab_t reduction_list)
/* As gimple_uid is used by the vectorizer in between vect_analyze_loop_form
and destroy_loop_vec_info, we can set gimple_uid of reduc_phi stmts
only now. */
- htab_traverse (reduction_list, set_reduc_phi_uids, NULL);
+ reduction_list.traverse <void *, set_reduc_phi_uids> (NULL);
}
/* Try to initialize NITER for code generation part. */
@@ -2001,7 +2021,8 @@ try_get_loop_niter (loop_p loop, struct tree_niter_desc *niter)
REDUCTION_LIST describes the reductions. */
static bool
-try_create_reduction_list (loop_p loop, htab_t reduction_list)
+try_create_reduction_list (loop_p loop,
+ reduction_info_table_type reduction_list)
{
edge exit = single_dom_exit (loop);
gimple_stmt_iterator gsi;
@@ -2032,7 +2053,7 @@ try_create_reduction_list (loop_p loop, htab_t reduction_list)
fprintf (dump_file,
" checking if it a part of reduction pattern: \n");
}
- if (htab_elements (reduction_list) == 0)
+ if (reduction_list.elements () == 0)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
@@ -2106,7 +2127,7 @@ parallelize_loops (void)
struct loop *loop;
struct tree_niter_desc niter_desc;
loop_iterator li;
- htab_t reduction_list;
+ reduction_info_table_type reduction_list;
struct obstack parloop_obstack;
HOST_WIDE_INT estimated;
LOC loop_loc;
@@ -2118,13 +2139,12 @@ parallelize_loops (void)
return false;
gcc_obstack_init (&parloop_obstack);
- reduction_list = htab_create (10, reduction_info_hash,
- reduction_info_eq, free);
+ reduction_list.create (10);
init_stmt_vec_info_vec ();
FOR_EACH_LOOP (li, loop, 0)
{
- htab_empty (reduction_list);
+ reduction_list.empty ();
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Trying loop %d as candidate\n",loop->num);
@@ -2204,7 +2224,7 @@ parallelize_loops (void)
}
free_stmt_vec_info_vec ();
- htab_delete (reduction_list);
+ reduction_list.dispose ();
obstack_free (&parloop_obstack, NULL);
/* Parallelization will cause new function calls to be inserted through
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 5c9ee519d73..0769f6d0b18 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -256,6 +256,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "gimple-pretty-print.h"
#include "tree-flow.h"
#include "cfgloop.h"
@@ -317,7 +318,7 @@ new_scev_info_str (basic_block instantiated_below, tree var)
/* Computes a hash function for database element ELT. */
-static hashval_t
+static inline hashval_t
hash_scev_info (const void *elt)
{
return SSA_NAME_VERSION (((const struct scev_info_str *) elt)->var);
@@ -325,7 +326,7 @@ hash_scev_info (const void *elt)
/* Compares database elements E1 and E2. */
-static int
+static inline int
eq_scev_info (const void *e1, const void *e2)
{
const struct scev_info_str *elt1 = (const struct scev_info_str *) e1;
@@ -343,6 +344,39 @@ del_scev_info (void *e)
ggc_free (e);
}
+/* Hashtable helpers. */
+
+struct scev_info_hasher
+{
+ typedef scev_info_str value_type;
+ typedef scev_info_str compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline hashval_t
+scev_info_hasher::hash (const value_type *elt)
+{
+ return hash_scev_info (elt);
+}
+
+inline bool
+scev_info_hasher::equal (const value_type *elt1, const compare_type *elt2)
+{
+ return eq_scev_info (elt1, elt2);
+}
+
+/* Deletes database element E. */
+
+inline void
+scev_info_hasher::remove (value_type *e)
+{
+ del_scev_info (e);
+}
+
+typedef hash_table <scev_info_hasher> scev_info_hash_table_type;
+
/* Get the scalar evolution of VAR for INSTANTIATED_BELOW basic block.
A first query on VAR returns chrec_not_analyzed_yet. */
@@ -2081,14 +2115,14 @@ analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop,
INSTANTIATED_BELOW block. */
static tree
-get_instantiated_value (htab_t cache, basic_block instantiated_below,
- tree version)
+get_instantiated_value (scev_info_hash_table_type cache,
+ basic_block instantiated_below, tree version)
{
struct scev_info_str *info, pattern;
pattern.var = version;
pattern.instantiated_below = instantiated_below;
- info = (struct scev_info_str *) htab_find (cache, &pattern);
+ info = cache.find (&pattern);
if (info)
return info->chrec;
@@ -2100,19 +2134,19 @@ get_instantiated_value (htab_t cache, basic_block instantiated_below,
INSTANTIATED_BELOW to VAL. */
static void
-set_instantiated_value (htab_t cache, basic_block instantiated_below,
- tree version, tree val)
+set_instantiated_value (scev_info_hash_table_type cache,
+ basic_block instantiated_below, tree version, tree val)
{
struct scev_info_str *info, pattern;
- PTR *slot;
+ scev_info_str **slot;
pattern.var = version;
pattern.instantiated_below = instantiated_below;
- slot = htab_find_slot (cache, &pattern, INSERT);
+ slot = cache.find_slot (&pattern, INSERT);
if (!*slot)
*slot = new_scev_info_str (instantiated_below, version);
- info = (struct scev_info_str *) *slot;
+ info = *slot;
info->chrec = val;
}
@@ -2147,7 +2181,7 @@ loop_closed_phi_def (tree var)
}
static tree instantiate_scev_r (basic_block, struct loop *, struct loop *,
- tree, bool, htab_t, int);
+ tree, bool, scev_info_hash_table_type, int);
/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
and EVOLUTION_LOOP, that were left under a symbolic form.
@@ -2167,7 +2201,8 @@ static tree
instantiate_scev_name (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree res;
struct loop *def_loop;
@@ -2269,7 +2304,8 @@ static tree
instantiate_scev_poly (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *,
tree chrec,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree op1;
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
@@ -2315,7 +2351,8 @@ instantiate_scev_binary (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec, enum tree_code code,
tree type, tree c0, tree c1,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree op1;
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop, inner_loop,
@@ -2374,7 +2411,8 @@ static tree
instantiate_array_ref (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree res;
tree index = TREE_OPERAND (chrec, 1);
@@ -2413,7 +2451,8 @@ instantiate_scev_convert (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
tree type, tree op,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions,
+ scev_info_hash_table_type cache, int size_expr)
{
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
inner_loop, op,
@@ -2462,7 +2501,8 @@ instantiate_scev_not (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
enum tree_code code, tree type, tree op,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
inner_loop, op,
@@ -2511,7 +2551,8 @@ static tree
instantiate_scev_3 (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree op1, op2;
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
@@ -2559,7 +2600,8 @@ static tree
instantiate_scev_2 (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree op1;
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
@@ -2599,7 +2641,8 @@ static tree
instantiate_scev_1 (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
tree op0 = instantiate_scev_r (instantiate_below, evolution_loop,
inner_loop, TREE_OPERAND (chrec, 0),
@@ -2632,7 +2675,8 @@ static tree
instantiate_scev_r (basic_block instantiate_below,
struct loop *evolution_loop, struct loop *inner_loop,
tree chrec,
- bool fold_conversions, htab_t cache, int size_expr)
+ bool fold_conversions, scev_info_hash_table_type cache,
+ int size_expr)
{
/* Give up if the expression is larger than the MAX that we allow. */
if (size_expr++ > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
@@ -2738,7 +2782,8 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
tree chrec)
{
tree res;
- htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
+ scev_info_hash_table_type cache;
+ cache.create (10);
if (dump_file && (dump_flags & TDF_SCEV))
{
@@ -2760,7 +2805,7 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
fprintf (dump_file, "))\n");
}
- htab_delete (cache);
+ cache.dispose ();
return res;
}
@@ -2773,10 +2818,11 @@ instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop,
tree
resolve_mixers (struct loop *loop, tree chrec)
{
- htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
+ scev_info_hash_table_type cache;
+ cache.create (10);
tree ret = instantiate_scev_r (block_before_loop (loop), loop, NULL,
chrec, true, cache, 0);
- htab_delete (cache);
+ cache.dispose ();
return ret;
}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 93446c2151a..20f725dba47 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "alloc-pool.h"
#include "tm.h"
#include "tree.h"
@@ -269,18 +270,44 @@ static alloc_pool link_pool;
/* Base (tree) -> Vector (vec<access_p> *) map. */
static struct pointer_map_t *base_access_vec;
+/* Candidate hash table helpers. */
+
+struct uid_decl_hasher : typed_noop_remove <tree_node>
+{
+ typedef tree_node value_type;
+ typedef tree_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash a tree in a uid_decl_map. */
+
+inline hashval_t
+uid_decl_hasher::hash (const value_type *item)
+{
+ return item->decl_minimal.uid;
+}
+
+/* Return true if the DECL_UID in both trees are equal. */
+
+inline bool
+uid_decl_hasher::equal (const value_type *a, const compare_type *b)
+{
+ return (a->decl_minimal.uid == b->decl_minimal.uid);
+}
+
/* Set of candidates. */
static bitmap candidate_bitmap;
-static htab_t candidates;
+static hash_table <uid_decl_hasher> candidates;
/* For a candidate UID return the candidates decl. */
static inline tree
candidate (unsigned uid)
{
- struct tree_decl_minimal t;
- t.uid = uid;
- return (tree) htab_find_with_hash (candidates, &t, uid);
+ tree_node t;
+ t.decl_minimal.uid = uid;
+ return candidates.find_with_hash (&t, static_cast <hashval_t> (uid));
}
/* Bitmap of candidates which we should try to entirely scalarize away and
@@ -611,8 +638,7 @@ static void
sra_initialize (void)
{
candidate_bitmap = BITMAP_ALLOC (NULL);
- candidates = htab_create (vec_safe_length (cfun->local_decls) / 2,
- uid_decl_map_hash, uid_decl_map_eq, NULL);
+ candidates.create (vec_safe_length (cfun->local_decls) / 2);
should_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
cannot_scalarize_away_bitmap = BITMAP_ALLOC (NULL);
gcc_obstack_init (&name_obstack);
@@ -642,7 +668,7 @@ static void
sra_deinitialize (void)
{
BITMAP_FREE (candidate_bitmap);
- htab_delete (candidates);
+ candidates.dispose ();
BITMAP_FREE (should_scalarize_away_bitmap);
BITMAP_FREE (cannot_scalarize_away_bitmap);
free_alloc_pool (access_pool);
@@ -659,9 +685,9 @@ static void
disqualify_candidate (tree decl, const char *reason)
{
if (bitmap_clear_bit (candidate_bitmap, DECL_UID (decl)))
- htab_clear_slot (candidates,
- htab_find_slot_with_hash (candidates, decl,
- DECL_UID (decl), NO_INSERT));
+ candidates.clear_slot (candidates.find_slot_with_hash (decl,
+ DECL_UID (decl),
+ NO_INSERT));
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -1680,7 +1706,7 @@ maybe_add_sra_candidate (tree var)
{
tree type = TREE_TYPE (var);
const char *msg;
- void **slot;
+ tree_node **slot;
if (!AGGREGATE_TYPE_P (type))
{
@@ -1728,8 +1754,8 @@ maybe_add_sra_candidate (tree var)
}
bitmap_set_bit (candidate_bitmap, DECL_UID (var));
- slot = htab_find_slot_with_hash (candidates, var, DECL_UID (var), INSERT);
- *slot = (void *) var;
+ slot = candidates.find_slot_with_hash (var, DECL_UID (var), INSERT);
+ *slot = var;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -3589,7 +3615,7 @@ find_param_candidates (void)
parm = DECL_CHAIN (parm))
{
tree type = TREE_TYPE (parm);
- void **slot;
+ tree_node **slot;
count++;
@@ -3628,9 +3654,8 @@ find_param_candidates (void)
continue;
bitmap_set_bit (candidate_bitmap, DECL_UID (parm));
- slot = htab_find_slot_with_hash (candidates, parm,
- DECL_UID (parm), INSERT);
- *slot = (void *) parm;
+ slot = candidates.find_slot_with_hash (parm, DECL_UID (parm), INSERT);
+ *slot = parm;
ret = true;
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index fd9c2cbdb33..354b5f182a8 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -49,6 +49,41 @@ typedef struct coalesce_pair
} * coalesce_pair_p;
typedef const struct coalesce_pair *const_coalesce_pair_p;
+/* Coalesce pair hashtable helpers. */
+
+struct coalesce_pair_hasher : typed_noop_remove <coalesce_pair>
+{
+ typedef coalesce_pair value_type;
+ typedef coalesce_pair compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash function for coalesce list. Calculate hash for PAIR. */
+
+inline hashval_t
+coalesce_pair_hasher::hash (const value_type *pair)
+{
+ hashval_t a = (hashval_t)(pair->first_element);
+ hashval_t b = (hashval_t)(pair->second_element);
+
+ return b * (b - 1) / 2 + a;
+}
+
+/* Equality function for coalesce list hash table. Compare PAIR1 and PAIR2,
+ returning TRUE if the two pairs are equivalent. */
+
+inline bool
+coalesce_pair_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ return (p1->first_element == p2->first_element
+ && p1->second_element == p2->second_element);
+}
+
+typedef hash_table <coalesce_pair_hasher> coalesce_table_type;
+typedef coalesce_table_type::iterator coalesce_iterator_type;
+
+
typedef struct cost_one_pair_d
{
int first_element;
@@ -60,7 +95,7 @@ typedef struct cost_one_pair_d
typedef struct coalesce_list_d
{
- htab_t list; /* Hash table. */
+ coalesce_table_type list; /* Hash table. */
coalesce_pair_p *sorted; /* List when sorted. */
int num_sorted; /* Number in the sorted list. */
cost_one_pair_p cost_one_list;/* Single use coalesces with cost 1. */
@@ -185,34 +220,6 @@ pop_best_coalesce (coalesce_list_p cl, int *p1, int *p2)
}
-#define COALESCE_HASH_FN(R1, R2) ((R2) * ((R2) - 1) / 2 + (R1))
-
-/* Hash function for coalesce list. Calculate hash for PAIR. */
-
-static unsigned int
-coalesce_pair_map_hash (const void *pair)
-{
- hashval_t a = (hashval_t)(((const_coalesce_pair_p)pair)->first_element);
- hashval_t b = (hashval_t)(((const_coalesce_pair_p)pair)->second_element);
-
- return COALESCE_HASH_FN (a,b);
-}
-
-
-/* Equality function for coalesce list hash table. Compare PAIR1 and PAIR2,
- returning TRUE if the two pairs are equivalent. */
-
-static int
-coalesce_pair_map_eq (const void *pair1, const void *pair2)
-{
- const_coalesce_pair_p const p1 = (const_coalesce_pair_p) pair1;
- const_coalesce_pair_p const p2 = (const_coalesce_pair_p) pair2;
-
- return (p1->first_element == p2->first_element
- && p1->second_element == p2->second_element);
-}
-
-
/* Create a new empty coalesce list object and return it. */
static inline coalesce_list_p
@@ -225,8 +232,7 @@ create_coalesce_list (void)
size = 40;
list = (coalesce_list_p) xmalloc (sizeof (struct coalesce_list_d));
- list->list = htab_create (size, coalesce_pair_map_hash,
- coalesce_pair_map_eq, NULL);
+ list->list.create (size);
list->sorted = NULL;
list->num_sorted = 0;
list->cost_one_list = NULL;
@@ -240,7 +246,7 @@ static inline void
delete_coalesce_list (coalesce_list_p cl)
{
gcc_assert (cl->cost_one_list == NULL);
- htab_delete (cl->list);
+ cl->list.dispose ();
free (cl->sorted);
gcc_assert (cl->num_sorted == 0);
free (cl);
@@ -255,7 +261,7 @@ static coalesce_pair_p
find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
{
struct coalesce_pair p;
- void **slot;
+ coalesce_pair **slot;
unsigned int hash;
/* Normalize so that p1 is the smaller value. */
@@ -270,9 +276,8 @@ find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
p.second_element = p2;
}
- hash = coalesce_pair_map_hash (&p);
- slot = htab_find_slot_with_hash (cl->list, &p, hash,
- create ? INSERT : NO_INSERT);
+ hash = coalesce_pair_hasher::hash (&p);
+ slot = cl->list.find_slot_with_hash (&p, hash, create ? INSERT : NO_INSERT);
if (!slot)
return NULL;
@@ -283,7 +288,7 @@ find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
pair->first_element = p.first_element;
pair->second_element = p.second_element;
pair->cost = 0;
- *slot = (void *)pair;
+ *slot = pair;
}
return (struct coalesce_pair *) *slot;
@@ -355,56 +360,14 @@ compare_pairs (const void *p1, const void *p2)
static inline int
num_coalesce_pairs (coalesce_list_p cl)
{
- return htab_elements (cl->list);
-}
-
-
-/* Iterator over hash table pairs. */
-typedef struct
-{
- htab_iterator hti;
-} coalesce_pair_iterator;
-
-
-/* Return first partition pair from list CL, initializing iterator ITER. */
-
-static inline coalesce_pair_p
-first_coalesce_pair (coalesce_list_p cl, coalesce_pair_iterator *iter)
-{
- coalesce_pair_p pair;
-
- pair = (coalesce_pair_p) first_htab_element (&(iter->hti), cl->list);
- return pair;
-}
-
-
-/* Return TRUE if there are no more partitions in for ITER to process. */
-
-static inline bool
-end_coalesce_pair_p (coalesce_pair_iterator *iter)
-{
- return end_htab_p (&(iter->hti));
-}
-
-
-/* Return the next partition pair to be visited by ITER. */
-
-static inline coalesce_pair_p
-next_coalesce_pair (coalesce_pair_iterator *iter)
-{
- coalesce_pair_p pair;
-
- pair = (coalesce_pair_p) next_htab_element (&(iter->hti));
- return pair;
+ return cl->list.elements ();
}
/* Iterate over CL using ITER, returning values in PAIR. */
#define FOR_EACH_PARTITION_PAIR(PAIR, ITER, CL) \
- for ((PAIR) = first_coalesce_pair ((CL), &(ITER)); \
- !end_coalesce_pair_p (&(ITER)); \
- (PAIR) = next_coalesce_pair (&(ITER)))
+ FOR_EACH_HASH_TABLE_ELEMENT ((CL)->list, (PAIR), coalesce_pair_p, (ITER))
/* Prepare CL for removal of preferred pairs. When finished they are sorted
@@ -415,7 +378,7 @@ sort_coalesce_list (coalesce_list_p cl)
{
unsigned x, num;
coalesce_pair_p p;
- coalesce_pair_iterator ppi;
+ coalesce_iterator_type ppi;
gcc_assert (cl->sorted == NULL);
@@ -461,7 +424,8 @@ static void
dump_coalesce_list (FILE *f, coalesce_list_p cl)
{
coalesce_pair_p node;
- coalesce_pair_iterator ppi;
+ coalesce_iterator_type ppi;
+
int x;
tree var;
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 57b814c49b3..dc4a19d6e48 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
@@ -101,15 +102,6 @@ struct edge_info
vec<cond_equivalence> cond_equivalences;
};
-/* Hash table with expressions made available during the renaming process.
- When an assignment of the form X_i = EXPR is found, the statement is
- stored in this table. If the same expression EXPR is later found on the
- RHS of another statement, it is replaced with X_i (thus performing
- global redundancy elimination). Similarly as we pass through conditionals
- we record the conditional itself as having either a true or false value
- in this table. */
-static htab_t avail_exprs;
-
/* Stack of available expressions in AVAIL_EXPRs. Each block pushes any
expressions it enters into the hash table along with a marker entry
(null). When we finish processing the block, we pop off entries and
@@ -140,6 +132,81 @@ struct expr_hash_elt
struct expr_hash_elt *stamp;
};
+/* Hashtable helpers. */
+
+static bool hashable_expr_equal_p (const struct hashable_expr *,
+ const struct hashable_expr *);
+static void free_expr_hash_elt (void *);
+
+struct expr_elt_hasher
+{
+ typedef expr_hash_elt value_type;
+ typedef expr_hash_elt compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+inline hashval_t
+expr_elt_hasher::hash (const value_type *p)
+{
+ return p->hash;
+}
+
+inline bool
+expr_elt_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ gimple stmt1 = p1->stmt;
+ const struct hashable_expr *expr1 = &p1->expr;
+ const struct expr_hash_elt *stamp1 = p1->stamp;
+ gimple stmt2 = p2->stmt;
+ const struct hashable_expr *expr2 = &p2->expr;
+ const struct expr_hash_elt *stamp2 = p2->stamp;
+
+ /* This case should apply only when removing entries from the table. */
+ if (stamp1 == stamp2)
+ return true;
+
+ /* FIXME tuples:
+ We add stmts to a hash table and them modify them. To detect the case
+ that we modify a stmt and then search for it, we assume that the hash
+ is always modified by that change.
+ We have to fully check why this doesn't happen on trunk or rewrite
+ this in a more reliable (and easier to understand) way. */
+ if (((const struct expr_hash_elt *)p1)->hash
+ != ((const struct expr_hash_elt *)p2)->hash)
+ return false;
+
+ /* In case of a collision, both RHS have to be identical and have the
+ same VUSE operands. */
+ if (hashable_expr_equal_p (expr1, expr2)
+ && types_compatible_p (expr1->type, expr2->type))
+ {
+ /* Note that STMT1 and/or STMT2 may be NULL. */
+ return ((stmt1 ? gimple_vuse (stmt1) : NULL_TREE)
+ == (stmt2 ? gimple_vuse (stmt2) : NULL_TREE));
+ }
+
+ return false;
+}
+
+/* Delete an expr_hash_elt and reclaim its storage. */
+
+inline void
+expr_elt_hasher::remove (value_type *element)
+{
+ free_expr_hash_elt (element);
+}
+
+/* Hash table with expressions made available during the renaming process.
+ When an assignment of the form X_i = EXPR is found, the statement is
+ stored in this table. If the same expression EXPR is later found on the
+ RHS of another statement, it is replaced with X_i (thus performing
+ global redundancy elimination). Similarly as we pass through conditionals
+ we record the conditional itself as having either a true or false value
+ in this table. */
+static hash_table <expr_elt_hasher> avail_exprs;
+
/* Stack of dest,src pairs that need to be restored during finalization.
A NULL entry is used to mark the end of pairs which need to be
@@ -169,9 +236,7 @@ static struct opt_stats_d opt_stats;
static void optimize_stmt (basic_block, gimple_stmt_iterator);
static tree lookup_avail_expr (gimple, bool);
static hashval_t avail_expr_hash (const void *);
-static hashval_t real_avail_expr_hash (const void *);
-static int avail_expr_eq (const void *, const void *);
-static void htab_statistics (FILE *, htab_t);
+static void htab_statistics (FILE *, hash_table <expr_elt_hasher>);
static void record_cond (cond_equivalence *);
static void record_const_or_copy (tree, tree);
static void record_equality (tree, tree);
@@ -722,7 +787,7 @@ tree_ssa_dominator_optimize (void)
memset (&opt_stats, 0, sizeof (opt_stats));
/* Create our hash tables. */
- avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free_expr_hash_elt);
+ avail_exprs.create (1024);
avail_exprs_stack.create (20);
const_and_copies_stack.create (20);
need_eh_cleanup = BITMAP_ALLOC (NULL);
@@ -830,7 +895,7 @@ tree_ssa_dominator_optimize (void)
loop_optimizer_finalize ();
/* Delete our main hashtable. */
- htab_delete (avail_exprs);
+ avail_exprs.dispose ();
/* And finalize the dominator walker. */
fini_walk_dominator_tree (&walk_data);
@@ -935,7 +1000,7 @@ remove_local_expressions_from_table (void)
while (avail_exprs_stack.length () > 0)
{
expr_hash_elt_t victim = avail_exprs_stack.pop ();
- void **slot;
+ expr_hash_elt **slot;
if (victim == NULL)
break;
@@ -949,10 +1014,9 @@ remove_local_expressions_from_table (void)
print_expr_hash_elt (dump_file, victim);
}
- slot = htab_find_slot_with_hash (avail_exprs,
- victim, victim->hash, NO_INSERT);
- gcc_assert (slot && *slot == (void *) victim);
- htab_clear_slot (avail_exprs, slot);
+ slot = avail_exprs.find_slot_with_hash (victim, victim->hash, NO_INSERT);
+ gcc_assert (slot && *slot == victim);
+ avail_exprs.clear_slot (slot);
}
}
@@ -1197,12 +1261,12 @@ debug_dominator_optimization_stats (void)
/* Dump statistics for the hash table HTAB. */
static void
-htab_statistics (FILE *file, htab_t htab)
+htab_statistics (FILE *file, hash_table <expr_elt_hasher> htab)
{
fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
- (long) htab_size (htab),
- (long) htab_elements (htab),
- htab_collisions (htab));
+ (long) htab.size (),
+ (long) htab.elements (),
+ htab.collisions ());
}
@@ -1214,15 +1278,14 @@ static void
record_cond (cond_equivalence *p)
{
struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
- void **slot;
+ expr_hash_elt **slot;
initialize_hash_element_from_expr (&p->cond, p->value, element);
- slot = htab_find_slot_with_hash (avail_exprs, (void *)element,
- element->hash, INSERT);
+ slot = avail_exprs.find_slot_with_hash (element, element->hash, INSERT);
if (*slot == NULL)
{
- *slot = (void *) element;
+ *slot = element;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -2398,7 +2461,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si)
static tree
lookup_avail_expr (gimple stmt, bool insert)
{
- void **slot;
+ expr_hash_elt **slot;
tree lhs;
tree temp;
struct expr_hash_elt element;
@@ -2426,8 +2489,8 @@ lookup_avail_expr (gimple stmt, bool insert)
return NULL_TREE;
/* Finally try to find the expression in the main expression hash table. */
- slot = htab_find_slot_with_hash (avail_exprs, &element, element.hash,
- (insert ? INSERT : NO_INSERT));
+ slot = avail_exprs.find_slot_with_hash (&element, element.hash,
+ (insert ? INSERT : NO_INSERT));
if (slot == NULL)
{
free_expr_hash_elt_contents (&element);
@@ -2438,7 +2501,7 @@ lookup_avail_expr (gimple stmt, bool insert)
struct expr_hash_elt *element2 = XNEW (struct expr_hash_elt);
*element2 = element;
element2->stamp = element2;
- *slot = (void *) element2;
+ *slot = element2;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -2505,49 +2568,6 @@ avail_expr_hash (const void *p)
return val;
}
-static hashval_t
-real_avail_expr_hash (const void *p)
-{
- return ((const struct expr_hash_elt *)p)->hash;
-}
-
-static int
-avail_expr_eq (const void *p1, const void *p2)
-{
- gimple stmt1 = ((const struct expr_hash_elt *)p1)->stmt;
- const struct hashable_expr *expr1 = &((const struct expr_hash_elt *)p1)->expr;
- const struct expr_hash_elt *stamp1 = ((const struct expr_hash_elt *)p1)->stamp;
- gimple stmt2 = ((const struct expr_hash_elt *)p2)->stmt;
- const struct hashable_expr *expr2 = &((const struct expr_hash_elt *)p2)->expr;
- const struct expr_hash_elt *stamp2 = ((const struct expr_hash_elt *)p2)->stamp;
-
- /* This case should apply only when removing entries from the table. */
- if (stamp1 == stamp2)
- return true;
-
- /* FIXME tuples:
- We add stmts to a hash table and them modify them. To detect the case
- that we modify a stmt and then search for it, we assume that the hash
- is always modified by that change.
- We have to fully check why this doesn't happen on trunk or rewrite
- this in a more reliable (and easier to understand) way. */
- if (((const struct expr_hash_elt *)p1)->hash
- != ((const struct expr_hash_elt *)p2)->hash)
- return false;
-
- /* In case of a collision, both RHS have to be identical and have the
- same VUSE operands. */
- if (hashable_expr_equal_p (expr1, expr2)
- && types_compatible_p (expr1->type, expr2->type))
- {
- /* Note that STMT1 and/or STMT2 may be NULL. */
- return ((stmt1 ? gimple_vuse (stmt1) : NULL_TREE)
- == (stmt2 ? gimple_vuse (stmt2) : NULL_TREE));
- }
-
- return false;
-}
-
/* PHI-ONLY copy and constant propagation. This pass is meant to clean
up degenerate PHIs created by or exposed by jump threading. */
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 7c763eacecb..3f4b41e2770 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "gimple-pretty-print.h"
@@ -53,6 +54,29 @@ static void verify_live_on_entry (tree_live_info_p);
ssa_name or variable, and vice versa. */
+/* Hashtable helpers. */
+
+struct tree_int_map_hasher : typed_noop_remove <tree_int_map>
+{
+ typedef tree_int_map value_type;
+ typedef tree_int_map compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+tree_int_map_hasher::hash (const value_type *v)
+{
+ return tree_map_base_hash (v);
+}
+
+inline bool
+tree_int_map_hasher::equal (const value_type *v, const compare_type *c)
+{
+ return tree_int_map_eq (v, c);
+}
+
+
/* This routine will initialize the basevar fields of MAP. */
static void
@@ -60,12 +84,11 @@ var_map_base_init (var_map map)
{
int x, num_part;
tree var;
- htab_t tree_to_index;
+ hash_table <tree_int_map_hasher> tree_to_index;
struct tree_int_map *m, *mapstorage;
num_part = num_var_partitions (map);
- tree_to_index = htab_create (num_part, tree_map_base_hash,
- tree_int_map_eq, NULL);
+ tree_to_index.create (num_part);
/* We can have at most num_part entries in the hash tables, so it's
enough to allocate so many map elements once, saving some malloc
calls. */
@@ -91,8 +114,7 @@ var_map_base_init (var_map map)
underlying decl. */
m->base.from = TREE_TYPE (var);
/* If base variable hasn't been seen, set it up. */
- slot = (struct tree_int_map **) htab_find_slot (tree_to_index,
- m, INSERT);
+ slot = tree_to_index.find_slot (m, INSERT);
if (!*slot)
{
baseindex = m - mapstorage;
@@ -108,7 +130,7 @@ var_map_base_init (var_map map)
map->num_basevars = m - mapstorage;
free (mapstorage);
- htab_delete (tree_to_index);
+ tree_to_index. dispose ();
}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 085789165a2..7ee00d6f585 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -31,7 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "tree-pass.h"
#include "flags.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "tree-affine.h"
#include "pointer-set.h"
#include "tree-ssa-propagate.h"
@@ -133,6 +133,32 @@ typedef struct mem_ref
and its subloops. */
#define LOOP_DEP_BIT(loopnum, storedp) (2 * (loopnum) + (storedp ? 1 : 0))
+/* Mem_ref hashtable helpers. */
+
+struct mem_ref_hasher : typed_noop_remove <mem_ref>
+{
+ typedef mem_ref value_type;
+ typedef tree_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* A hash function for struct mem_ref object OBJ. */
+
+inline hashval_t
+mem_ref_hasher::hash (const value_type *mem)
+{
+ return mem->hash;
+}
+
+/* An equality function for struct mem_ref object MEM1 with
+ memory reference OBJ2. */
+
+inline bool
+mem_ref_hasher::equal (const value_type *mem1, const compare_type *obj2)
+{
+ return operand_equal_p (mem1->mem.ref, (const_tree) obj2, 0);
+}
/* Description of memory accesses in loops. */
@@ -140,7 +166,7 @@ typedef struct mem_ref
static struct
{
/* The hash table of memory references accessed in loops. */
- htab_t refs;
+ hash_table <mem_ref_hasher> refs;
/* The list of memory references. */
vec<mem_ref_p> refs_list;
@@ -646,7 +672,7 @@ mem_ref_in_stmt (gimple stmt)
gcc_assert (!store);
hash = iterative_hash_expr (*mem, 0);
- ref = (mem_ref_p) htab_find_with_hash (memory_accesses.refs, *mem, hash);
+ ref = memory_accesses.refs.find_with_hash (*mem, hash);
gcc_assert (ref != NULL);
return ref;
@@ -1411,27 +1437,6 @@ force_move_till (tree ref, tree *index, void *data)
return true;
}
-/* A hash function for struct mem_ref object OBJ. */
-
-static hashval_t
-memref_hash (const void *obj)
-{
- const struct mem_ref *const mem = (const struct mem_ref *) obj;
-
- return mem->hash;
-}
-
-/* An equality function for struct mem_ref object OBJ1 with
- memory reference OBJ2. */
-
-static int
-memref_eq (const void *obj1, const void *obj2)
-{
- const struct mem_ref *const mem1 = (const struct mem_ref *) obj1;
-
- return operand_equal_p (mem1->mem.ref, (const_tree) obj2, 0);
-}
-
/* A function to free the mem_ref object OBJ. */
static void
@@ -1502,7 +1507,7 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt)
{
tree *mem = NULL;
hashval_t hash;
- PTR *slot;
+ mem_ref **slot;
mem_ref_p ref;
bool is_stored;
unsigned id;
@@ -1526,8 +1531,7 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt)
else
{
hash = iterative_hash_expr (*mem, 0);
- slot = htab_find_slot_with_hash (memory_accesses.refs,
- *mem, hash, INSERT);
+ slot = memory_accesses.refs.find_slot_with_hash (*mem, hash, INSERT);
if (*slot)
{
ref = (mem_ref_p) *slot;
@@ -2525,7 +2529,7 @@ tree_ssa_lim_initialize (void)
alloc_aux_for_edges (0);
- memory_accesses.refs = htab_create (100, memref_hash, memref_eq, NULL);
+ memory_accesses.refs.create (100);
memory_accesses.refs_list.create (100);
/* Allocate a special, unanalyzable mem-ref with ID zero. */
memory_accesses.refs_list.quick_push
@@ -2568,7 +2572,7 @@ tree_ssa_lim_finalize (void)
bitmap_obstack_release (&lim_bitmap_obstack);
pointer_map_destroy (lim_aux_data_map);
- htab_delete (memory_accesses.refs);
+ memory_accesses.refs.dispose ();
FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
memref_free (ref);
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 2940bf10044..cf196ea9d72 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -75,7 +75,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "insn-config.h"
#include "pointer-set.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "tree-chrec.h"
#include "tree-scalar-evolution.h"
#include "cfgloop.h"
@@ -236,6 +236,33 @@ typedef struct iv_use *iv_use_p;
typedef struct iv_cand *iv_cand_p;
+/* Hashtable helpers. */
+
+struct iv_inv_expr_hasher : typed_free_remove <iv_inv_expr_ent>
+{
+ typedef iv_inv_expr_ent value_type;
+ typedef iv_inv_expr_ent compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash function for loop invariant expressions. */
+
+inline hashval_t
+iv_inv_expr_hasher::hash (const value_type *expr)
+{
+ return expr->hash;
+}
+
+/* Hash table equality function for expressions. */
+
+inline bool
+iv_inv_expr_hasher::equal (const value_type *expr1, const compare_type *expr2)
+{
+ return expr1->hash == expr2->hash
+ && operand_equal_p (expr1->expr, expr2->expr, 0);
+}
+
struct ivopts_data
{
/* The currently optimized loop. */
@@ -255,7 +282,7 @@ struct ivopts_data
/* The hashtable of loop invariant expressions created
by ivopt. */
- htab_t inv_expr_tab;
+ hash_table <iv_inv_expr_hasher> inv_expr_tab;
/* Loop invariant expression id. */
int inv_expr_id;
@@ -814,30 +841,6 @@ niter_for_single_dom_exit (struct ivopts_data *data)
return niter_for_exit (data, exit);
}
-/* Hash table equality function for expressions. */
-
-static int
-htab_inv_expr_eq (const void *ent1, const void *ent2)
-{
- const struct iv_inv_expr_ent *expr1 =
- (const struct iv_inv_expr_ent *)ent1;
- const struct iv_inv_expr_ent *expr2 =
- (const struct iv_inv_expr_ent *)ent2;
-
- return expr1->hash == expr2->hash
- && operand_equal_p (expr1->expr, expr2->expr, 0);
-}
-
-/* Hash function for loop invariant expressions. */
-
-static hashval_t
-htab_inv_expr_hash (const void *ent)
-{
- const struct iv_inv_expr_ent *expr =
- (const struct iv_inv_expr_ent *)ent;
- return expr->hash;
-}
-
/* Initializes data structures used by the iv optimization pass, stored
in DATA. */
@@ -852,8 +855,7 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data)
data->niters = NULL;
data->iv_uses.create (20);
data->iv_candidates.create (20);
- data->inv_expr_tab = htab_create (10, htab_inv_expr_hash,
- htab_inv_expr_eq, free);
+ data->inv_expr_tab.create (10);
data->inv_expr_id = 0;
decl_rtl_to_reset.create (20);
}
@@ -3802,8 +3804,7 @@ get_expr_id (struct ivopts_data *data, tree expr)
ent.expr = expr;
ent.hash = iterative_hash_expr (expr, 0);
- slot = (struct iv_inv_expr_ent **) htab_find_slot (data->inv_expr_tab,
- &ent, INSERT);
+ slot = data->inv_expr_tab.find_slot (&ent, INSERT);
if (*slot)
return (*slot)->id;
@@ -6605,7 +6606,7 @@ free_loop_data (struct ivopts_data *data)
decl_rtl_to_reset.truncate (0);
- htab_empty (data->inv_expr_tab);
+ data->inv_expr_tab.empty ();
data->inv_expr_id = 0;
}
@@ -6623,7 +6624,7 @@ tree_ssa_iv_optimize_finalize (struct ivopts_data *data)
decl_rtl_to_reset.release ();
data->iv_uses.release ();
data->iv_candidates.release ();
- htab_delete (data->inv_expr_tab);
+ data->inv_expr_tab.dispose ();
}
/* Returns true if the loop body BODY includes any function calls. */
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 300016f7a0b..da90f45cea4 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
@@ -1239,8 +1240,15 @@ struct name_to_bb
basic_block bb;
};
-/* The hash table for remembering what we've seen. */
-static htab_t seen_ssa_names;
+/* Hashtable helpers. */
+
+struct ssa_names_hasher : typed_free_remove <name_to_bb>
+{
+ typedef name_to_bb value_type;
+ typedef name_to_bb compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
/* Used for quick clearing of the hash-table when we see calls.
Hash entries with phase < nt_call_phase are invalid. */
@@ -1250,27 +1258,28 @@ static unsigned int nt_call_phase;
static struct pointer_set_t *nontrap_set;
/* The hash function. */
-static hashval_t
-name_to_bb_hash (const void *p)
+
+inline hashval_t
+ssa_names_hasher::hash (const value_type *n)
{
- const struct name_to_bb *n = (const struct name_to_bb *) p;
return n->ssa_name_ver ^ (((hashval_t) n->store) << 31)
^ (n->offset << 6) ^ (n->size << 3);
}
/* The equality function of *P1 and *P2. */
-static int
-name_to_bb_eq (const void *p1, const void *p2)
-{
- const struct name_to_bb *n1 = (const struct name_to_bb *)p1;
- const struct name_to_bb *n2 = (const struct name_to_bb *)p2;
+inline bool
+ssa_names_hasher::equal (const value_type *n1, const compare_type *n2)
+{
return n1->ssa_name_ver == n2->ssa_name_ver
&& n1->store == n2->store
&& n1->offset == n2->offset
&& n1->size == n2->size;
}
+/* The hash table for remembering what we've seen. */
+static hash_table <ssa_names_hasher> seen_ssa_names;
+
/* We see the expression EXP in basic block BB. If it's an interesting
expression (an MEM_REF through an SSA_NAME) possibly insert the
expression into the set NONTRAP or the hash table of seen expressions.
@@ -1289,7 +1298,7 @@ add_or_mark_expr (basic_block bb, tree exp,
{
tree name = TREE_OPERAND (exp, 0);
struct name_to_bb map;
- void **slot;
+ name_to_bb **slot;
struct name_to_bb *n2bb;
basic_block found_bb = 0;
@@ -1302,8 +1311,8 @@ add_or_mark_expr (basic_block bb, tree exp,
map.offset = tree_low_cst (TREE_OPERAND (exp, 1), 0);
map.size = size;
- slot = htab_find_slot (seen_ssa_names, &map, INSERT);
- n2bb = (struct name_to_bb *) *slot;
+ slot = seen_ssa_names.find_slot (&map, INSERT);
+ n2bb = *slot;
if (n2bb && n2bb->phase >= nt_call_phase)
found_bb = n2bb->bb;
@@ -1413,8 +1422,7 @@ get_non_trapping (void)
nt_call_phase = 0;
nontrap = pointer_set_create ();
- seen_ssa_names = htab_create (128, name_to_bb_hash, name_to_bb_eq,
- free);
+ seen_ssa_names.create (128);
/* We're going to do a dominator walk, so ensure that we have
dominance information. */
calculate_dominance_info (CDI_DOMINATORS);
@@ -1431,7 +1439,7 @@ get_non_trapping (void)
init_walk_dominator_tree (&walk_data);
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
fini_walk_dominator_tree (&walk_data);
- htab_delete (seen_ssa_names);
+ seen_ssa_names.dispose ();
clear_aux_for_blocks ();
return nontrap;
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 27161cd1860..8ffb0947648 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "basic-block.h"
@@ -943,10 +944,23 @@ typedef struct oecount_s {
/* The heap for the oecount hashtable and the sorted list of operands. */
static vec<oecount> cvec;
+
+/* Oecount hashtable helpers. */
+
+struct oecount_hasher : typed_noop_remove <void>
+{
+ /* Note that this hash table stores integers, not pointers.
+ So, observe the casting in the member functions. */
+ typedef void value_type;
+ typedef void compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
/* Hash function for oecount. */
-static hashval_t
-oecount_hash (const void *p)
+inline hashval_t
+oecount_hasher::hash (const value_type *p)
{
const oecount *c = &cvec[(size_t)p - 42];
return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode;
@@ -954,8 +968,8 @@ oecount_hash (const void *p)
/* Comparison function for oecount. */
-static int
-oecount_eq (const void *p1, const void *p2)
+inline bool
+oecount_hasher::equal (const value_type *p1, const compare_type *p2)
{
const oecount *c1 = &cvec[(size_t)p1 - 42];
const oecount *c2 = &cvec[(size_t)p2 - 42];
@@ -1257,7 +1271,7 @@ undistribute_ops_list (enum tree_code opcode,
unsigned nr_candidates, nr_candidates2;
sbitmap_iterator sbi0;
vec<operand_entry_t> *subops;
- htab_t ctable;
+ hash_table <oecount_hasher> ctable;
bool changed = false;
int next_oecount_id = 0;
@@ -1305,7 +1319,7 @@ undistribute_ops_list (enum tree_code opcode,
/* Build linearized sub-operand lists and the counting table. */
cvec.create (0);
- ctable = htab_create (15, oecount_hash, oecount_eq, NULL);
+ ctable.create (15);
/* ??? Macro arguments cannot have multi-argument template types in
them. This typedef is needed to workaround that limitation. */
typedef vec<operand_entry_t> vec_operand_entry_t_heap;
@@ -1332,7 +1346,7 @@ undistribute_ops_list (enum tree_code opcode,
c.op = oe1->op;
cvec.safe_push (c);
idx = cvec.length () + 41;
- slot = htab_find_slot (ctable, (void *)idx, INSERT);
+ slot = ctable.find_slot ((void *)idx, INSERT);
if (!*slot)
{
*slot = (void *)idx;
@@ -1344,7 +1358,7 @@ undistribute_ops_list (enum tree_code opcode,
}
}
}
- htab_delete (ctable);
+ ctable.dispose ();
/* Sort the counting table. */
cvec.qsort (oecount_cmp);
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index e7aefbf0551..07bfdcccb81 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "gimple.h"
#include "dumpfile.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "alloc-pool.h"
#include "flags.h"
#include "bitmap.h"
@@ -96,19 +96,187 @@ along with GCC; see the file COPYING3. If not see
structure copies.
*/
+
+/* vn_nary_op hashtable helpers. */
+
+struct vn_nary_op_hasher : typed_noop_remove <vn_nary_op_s>
+{
+ typedef vn_nary_op_s value_type;
+ typedef vn_nary_op_s compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Return the computed hashcode for nary operation P1. */
+
+inline hashval_t
+vn_nary_op_hasher::hash (const value_type *vno1)
+{
+ return vno1->hashcode;
+}
+
+/* Compare nary operations P1 and P2 and return true if they are
+ equivalent. */
+
+inline bool
+vn_nary_op_hasher::equal (const value_type *vno1, const compare_type *vno2)
+{
+ return vn_nary_op_eq (vno1, vno2);
+}
+
+typedef hash_table <vn_nary_op_hasher> vn_nary_op_table_type;
+typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type;
+
+
+/* vn_phi hashtable helpers. */
+
+static int
+vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2);
+
+struct vn_phi_hasher
+{
+ typedef vn_phi_s value_type;
+ typedef vn_phi_s compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+/* Return the computed hashcode for phi operation P1. */
+
+inline hashval_t
+vn_phi_hasher::hash (const value_type *vp1)
+{
+ return vp1->hashcode;
+}
+
+/* Compare two phi entries for equality, ignoring VN_TOP arguments. */
+
+inline bool
+vn_phi_hasher::equal (const value_type *vp1, const compare_type *vp2)
+{
+ return vn_phi_eq (vp1, vp2);
+}
+
+/* Free a phi operation structure VP. */
+
+inline void
+vn_phi_hasher::remove (value_type *phi)
+{
+ phi->phiargs.release ();
+}
+
+typedef hash_table <vn_phi_hasher> vn_phi_table_type;
+typedef vn_phi_table_type::iterator vn_phi_iterator_type;
+
+
+/* Compare two reference operands P1 and P2 for equality. Return true if
+ they are equal, and false otherwise. */
+
+static int
+vn_reference_op_eq (const void *p1, const void *p2)
+{
+ const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
+ const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
+
+ return (vro1->opcode == vro2->opcode
+ /* We do not care for differences in type qualification. */
+ && (vro1->type == vro2->type
+ || (vro1->type && vro2->type
+ && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
+ TYPE_MAIN_VARIANT (vro2->type))))
+ && expressions_equal_p (vro1->op0, vro2->op0)
+ && expressions_equal_p (vro1->op1, vro2->op1)
+ && expressions_equal_p (vro1->op2, vro2->op2));
+}
+
+/* Free a reference operation structure VP. */
+
+static inline void
+free_reference (vn_reference_s *vr)
+{
+ vr->operands.release ();
+}
+
+
+/* vn_reference hashtable helpers. */
+
+struct vn_reference_hasher
+{
+ typedef vn_reference_s value_type;
+ typedef vn_reference_s compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+/* Return the hashcode for a given reference operation P1. */
+
+inline hashval_t
+vn_reference_hasher::hash (const value_type *vr1)
+{
+ return vr1->hashcode;
+}
+
+inline bool
+vn_reference_hasher::equal (const value_type *v, const compare_type *c)
+{
+ return vn_reference_eq (v, c);
+}
+
+inline void
+vn_reference_hasher::remove (value_type *v)
+{
+ free_reference (v);
+}
+
+typedef hash_table <vn_reference_hasher> vn_reference_table_type;
+typedef vn_reference_table_type::iterator vn_reference_iterator_type;
+
+
/* The set of hashtables and alloc_pool's for their items. */
typedef struct vn_tables_s
{
- htab_t nary;
- htab_t phis;
- htab_t references;
+ vn_nary_op_table_type nary;
+ vn_phi_table_type phis;
+ vn_reference_table_type references;
struct obstack nary_obstack;
alloc_pool phis_pool;
alloc_pool references_pool;
} *vn_tables_t;
-static htab_t constant_to_value_id;
+
+/* vn_constant hashtable helpers. */
+
+struct vn_constant_hasher : typed_free_remove <vn_constant_s>
+{
+ typedef vn_constant_s value_type;
+ typedef vn_constant_s compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash table hash function for vn_constant_t. */
+
+inline hashval_t
+vn_constant_hasher::hash (const value_type *vc1)
+{
+ return vc1->hashcode;
+}
+
+/* Hash table equality function for vn_constant_t. */
+
+inline bool
+vn_constant_hasher::equal (const value_type *vc1, const compare_type *vc2)
+{
+ if (vc1->hashcode != vc2->hashcode)
+ return false;
+
+ return vn_constant_eq_with_type (vc1->constant, vc2->constant);
+}
+
+static hash_table <vn_constant_hasher> constant_to_value_id;
static bitmap constant_value_ids;
@@ -338,62 +506,20 @@ vn_get_stmt_kind (gimple stmt)
}
}
-/* Free a phi operation structure VP. */
-
-static void
-free_phi (void *vp)
-{
- vn_phi_t phi = (vn_phi_t) vp;
- phi->phiargs.release ();
-}
-
-/* Free a reference operation structure VP. */
-
-static void
-free_reference (void *vp)
-{
- vn_reference_t vr = (vn_reference_t) vp;
- vr->operands.release ();
-}
-
-/* Hash table equality function for vn_constant_t. */
-
-static int
-vn_constant_eq (const void *p1, const void *p2)
-{
- const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
- const struct vn_constant_s *vc2 = (const struct vn_constant_s *) p2;
-
- if (vc1->hashcode != vc2->hashcode)
- return false;
-
- return vn_constant_eq_with_type (vc1->constant, vc2->constant);
-}
-
-/* Hash table hash function for vn_constant_t. */
-
-static hashval_t
-vn_constant_hash (const void *p1)
-{
- const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
- return vc1->hashcode;
-}
-
/* Lookup a value id for CONSTANT and return it. If it does not
exist returns 0. */
unsigned int
get_constant_value_id (tree constant)
{
- void **slot;
+ vn_constant_s **slot;
struct vn_constant_s vc;
vc.hashcode = vn_hash_constant_with_type (constant);
vc.constant = constant;
- slot = htab_find_slot_with_hash (constant_to_value_id, &vc,
- vc.hashcode, NO_INSERT);
+ slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, NO_INSERT);
if (slot)
- return ((vn_constant_t)*slot)->value_id;
+ return (*slot)->value_id;
return 0;
}
@@ -403,22 +529,21 @@ get_constant_value_id (tree constant)
unsigned int
get_or_alloc_constant_value_id (tree constant)
{
- void **slot;
+ vn_constant_s **slot;
struct vn_constant_s vc;
vn_constant_t vcp;
vc.hashcode = vn_hash_constant_with_type (constant);
vc.constant = constant;
- slot = htab_find_slot_with_hash (constant_to_value_id, &vc,
- vc.hashcode, INSERT);
+ slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, INSERT);
if (*slot)
- return ((vn_constant_t)*slot)->value_id;
+ return (*slot)->value_id;
vcp = XNEW (struct vn_constant_s);
vcp->hashcode = vc.hashcode;
vcp->constant = constant;
vcp->value_id = get_next_value_id ();
- *slot = (void *) vcp;
+ *slot = vcp;
bitmap_set_bit (constant_value_ids, vcp->value_id);
return vcp->value_id;
}
@@ -431,26 +556,6 @@ value_id_constant_p (unsigned int v)
return bitmap_bit_p (constant_value_ids, v);
}
-/* Compare two reference operands P1 and P2 for equality. Return true if
- they are equal, and false otherwise. */
-
-static int
-vn_reference_op_eq (const void *p1, const void *p2)
-{
- const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
- const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
-
- return (vro1->opcode == vro2->opcode
- /* We do not care for differences in type qualification. */
- && (vro1->type == vro2->type
- || (vro1->type && vro2->type
- && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
- TYPE_MAIN_VARIANT (vro2->type))))
- && expressions_equal_p (vro1->op0, vro2->op0)
- && expressions_equal_p (vro1->op1, vro2->op1)
- && expressions_equal_p (vro1->op2, vro2->op2));
-}
-
/* Compute the hash for a reference operand VRO1. */
static hashval_t
@@ -466,15 +571,6 @@ vn_reference_op_compute_hash (const vn_reference_op_t vro1, hashval_t result)
return result;
}
-/* Return the hashcode for a given reference operation P1. */
-
-static hashval_t
-vn_reference_hash (const void *p1)
-{
- const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
- return vr1->hashcode;
-}
-
/* Compute a hash for the reference operation VR1 and return it. */
hashval_t
@@ -524,16 +620,14 @@ vn_reference_compute_hash (const vn_reference_t vr1)
return result;
}
-/* Return true if reference operations P1 and P2 are equivalent. This
+/* Return true if reference operations VR1 and VR2 are equivalent. This
means they have the same set of operands and vuses. */
-int
-vn_reference_eq (const void *p1, const void *p2)
+bool
+vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2)
{
unsigned i, j;
- const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
- const_vn_reference_t const vr2 = (const_vn_reference_t) p2;
if (vr1->hashcode != vr2->hashcode)
return false;
@@ -1346,15 +1440,13 @@ valueize_shared_reference_ops_from_call (gimple call)
static tree
vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
{
- void **slot;
+ vn_reference_s **slot;
hashval_t hash;
hash = vr->hashcode;
- slot = htab_find_slot_with_hash (current_info->references, vr,
- hash, NO_INSERT);
+ slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (!slot && current_info == optimistic_info)
- slot = htab_find_slot_with_hash (valid_info->references, vr,
- hash, NO_INSERT);
+ slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (slot)
{
if (vnresult)
@@ -1377,7 +1469,7 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse,
unsigned int cnt, void *vr_)
{
vn_reference_t vr = (vn_reference_t)vr_;
- void **slot;
+ vn_reference_s **slot;
hashval_t hash;
/* This bounds the stmt walks we perform on reference lookups
@@ -1397,11 +1489,9 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse,
vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
hash = vr->hashcode;
- slot = htab_find_slot_with_hash (current_info->references, vr,
- hash, NO_INSERT);
+ slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (!slot && current_info == optimistic_info)
- slot = htab_find_slot_with_hash (valid_info->references, vr,
- hash, NO_INSERT);
+ slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (slot)
return *slot;
@@ -2004,7 +2094,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
vn_reference_t
vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
{
- void **slot;
+ vn_reference_s **slot;
vn_reference_t vr1;
vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
@@ -2020,8 +2110,8 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
vr1->result_vdef = vdef;
- slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
- INSERT);
+ slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode,
+ INSERT);
/* Because we lookup stores using vuses, and value number failures
using the vdefs (see visit_reference_op_store for how and why),
@@ -2049,7 +2139,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
tree result, unsigned int value_id)
{
- void **slot;
+ vn_reference_s **slot;
vn_reference_t vr1;
vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
@@ -2063,8 +2153,8 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
result = SSA_VAL (result);
vr1->result = result;
- slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
- INSERT);
+ slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode,
+ INSERT);
/* At this point we should have all the things inserted that we have
seen before, and we should never try inserting something that
@@ -2105,23 +2195,12 @@ vn_nary_op_compute_hash (const vn_nary_op_t vno1)
return hash;
}
-/* Return the computed hashcode for nary operation P1. */
-
-static hashval_t
-vn_nary_op_hash (const void *p1)
-{
- const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1;
- return vno1->hashcode;
-}
-
-/* Compare nary operations P1 and P2 and return true if they are
+/* Compare nary operations VNO1 and VNO2 and return true if they are
equivalent. */
-int
-vn_nary_op_eq (const void *p1, const void *p2)
+bool
+vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
{
- const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1;
- const_vn_nary_op_t const vno2 = (const_vn_nary_op_t) p2;
unsigned i;
if (vno1->hashcode != vno2->hashcode)
@@ -2238,22 +2317,20 @@ init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple stmt)
static tree
vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
{
- void **slot;
+ vn_nary_op_s **slot;
if (vnresult)
*vnresult = NULL;
vno->hashcode = vn_nary_op_compute_hash (vno);
- slot = htab_find_slot_with_hash (current_info->nary, vno, vno->hashcode,
- NO_INSERT);
+ slot = current_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
if (!slot && current_info == optimistic_info)
- slot = htab_find_slot_with_hash (valid_info->nary, vno, vno->hashcode,
- NO_INSERT);
+ slot = valid_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
if (!slot)
return NULL_TREE;
if (vnresult)
- *vnresult = (vn_nary_op_t)*slot;
- return ((vn_nary_op_t)*slot)->result;
+ *vnresult = *slot;
+ return (*slot)->result;
}
/* Lookup a n-ary operation by its pieces and return the resulting value
@@ -2331,14 +2408,15 @@ alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
VNO->HASHCODE first. */
static vn_nary_op_t
-vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash)
+vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type table,
+ bool compute_hash)
{
- void **slot;
+ vn_nary_op_s **slot;
if (compute_hash)
vno->hashcode = vn_nary_op_compute_hash (vno);
- slot = htab_find_slot_with_hash (table, vno, vno->hashcode, INSERT);
+ slot = table.find_slot_with_hash (vno, vno->hashcode, INSERT);
gcc_assert (!*slot);
*slot = vno;
@@ -2414,23 +2492,11 @@ vn_phi_compute_hash (vn_phi_t vp1)
return result;
}
-/* Return the computed hashcode for phi operation P1. */
-
-static hashval_t
-vn_phi_hash (const void *p1)
-{
- const_vn_phi_t const vp1 = (const_vn_phi_t) p1;
- return vp1->hashcode;
-}
-
/* Compare two phi entries for equality, ignoring VN_TOP arguments. */
static int
-vn_phi_eq (const void *p1, const void *p2)
+vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
{
- const_vn_phi_t const vp1 = (const_vn_phi_t) p1;
- const_vn_phi_t const vp2 = (const_vn_phi_t) p2;
-
if (vp1->hashcode != vp2->hashcode)
return false;
@@ -2468,7 +2534,7 @@ static vec<tree> shared_lookup_phiargs;
static tree
vn_phi_lookup (gimple phi)
{
- void **slot;
+ vn_phi_s **slot;
struct vn_phi_s vp1;
unsigned i;
@@ -2485,14 +2551,12 @@ vn_phi_lookup (gimple phi)
vp1.phiargs = shared_lookup_phiargs;
vp1.block = gimple_bb (phi);
vp1.hashcode = vn_phi_compute_hash (&vp1);
- slot = htab_find_slot_with_hash (current_info->phis, &vp1, vp1.hashcode,
- NO_INSERT);
+ slot = current_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT);
if (!slot && current_info == optimistic_info)
- slot = htab_find_slot_with_hash (valid_info->phis, &vp1, vp1.hashcode,
- NO_INSERT);
+ slot = valid_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT);
if (!slot)
return NULL_TREE;
- return ((vn_phi_t)*slot)->result;
+ return (*slot)->result;
}
/* Insert PHI into the current hash table with a value number of
@@ -2501,7 +2565,7 @@ vn_phi_lookup (gimple phi)
static vn_phi_t
vn_phi_insert (gimple phi, tree result)
{
- void **slot;
+ vn_phi_s **slot;
vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
unsigned i;
vec<tree> args = vNULL;
@@ -2520,8 +2584,7 @@ vn_phi_insert (gimple phi, tree result)
vp1->result = result;
vp1->hashcode = vn_phi_compute_hash (vp1);
- slot = htab_find_slot_with_hash (current_info->phis, vp1, vp1->hashcode,
- INSERT);
+ slot = current_info->phis.find_slot_with_hash (vp1, vp1->hashcode, INSERT);
/* Because we iterate over phi operations more than once, it's
possible the slot might already exist here, hence no assert.*/
@@ -2724,7 +2787,7 @@ visit_reference_op_call (tree lhs, gimple stmt)
}
else
{
- void **slot;
+ vn_reference_s **slot;
vn_reference_t vr2;
if (vdef)
changed |= set_ssa_val_to (vdef, vdef);
@@ -2738,8 +2801,8 @@ visit_reference_op_call (tree lhs, gimple stmt)
vr2->hashcode = vr1.hashcode;
vr2->result = lhs;
vr2->result_vdef = vdef;
- slot = htab_find_slot_with_hash (current_info->references,
- vr2, vr2->hashcode, INSERT);
+ slot = current_info->references.find_slot_with_hash (vr2, vr2->hashcode,
+ INSERT);
if (*slot)
free_reference (*slot);
*slot = vr2;
@@ -3599,10 +3662,10 @@ static void
copy_phi (vn_phi_t ophi, vn_tables_t info)
{
vn_phi_t phi = (vn_phi_t) pool_alloc (info->phis_pool);
- void **slot;
+ vn_phi_s **slot;
memcpy (phi, ophi, sizeof (*phi));
ophi->phiargs.create (0);
- slot = htab_find_slot_with_hash (info->phis, phi, phi->hashcode, INSERT);
+ slot = info->phis.find_slot_with_hash (phi, phi->hashcode, INSERT);
gcc_assert (!*slot);
*slot = phi;
}
@@ -3613,12 +3676,11 @@ static void
copy_reference (vn_reference_t oref, vn_tables_t info)
{
vn_reference_t ref;
- void **slot;
+ vn_reference_s **slot;
ref = (vn_reference_t) pool_alloc (info->references_pool);
memcpy (ref, oref, sizeof (*ref));
oref->operands.create (0);
- slot = htab_find_slot_with_hash (info->references, ref, ref->hashcode,
- INSERT);
+ slot = info->references.find_slot_with_hash (ref, ref->hashcode, INSERT);
if (*slot)
free_reference (*slot);
*slot = ref;
@@ -3633,7 +3695,9 @@ process_scc (vec<tree> scc)
unsigned int i;
unsigned int iterations = 0;
bool changed = true;
- htab_iterator hi;
+ vn_nary_op_iterator_type hin;
+ vn_phi_iterator_type hip;
+ vn_reference_iterator_type hir;
vn_nary_op_t nary;
vn_phi_t phi;
vn_reference_t ref;
@@ -3670,9 +3734,9 @@ process_scc (vec<tree> scc)
/* As we are value-numbering optimistically we have to
clear the expression tables and the simplified expressions
in each iteration until we converge. */
- htab_empty (optimistic_info->nary);
- htab_empty (optimistic_info->phis);
- htab_empty (optimistic_info->references);
+ optimistic_info->nary.empty ();
+ optimistic_info->phis.empty ();
+ optimistic_info->references.empty ();
obstack_free (&optimistic_info->nary_obstack, NULL);
gcc_obstack_init (&optimistic_info->nary_obstack);
empty_alloc_pool (optimistic_info->phis_pool);
@@ -3687,11 +3751,12 @@ process_scc (vec<tree> scc)
/* Finally, copy the contents of the no longer used optimistic
table to the valid table. */
- FOR_EACH_HTAB_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hin)
copy_nary (nary, valid_info);
- FOR_EACH_HTAB_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hip)
copy_phi (phi, valid_info);
- FOR_EACH_HTAB_ELEMENT (optimistic_info->references, ref, vn_reference_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->references,
+ ref, vn_reference_t, hir)
copy_reference (ref, valid_info);
current_info = valid_info;
@@ -3851,10 +3916,9 @@ continue_walking:
static void
allocate_vn_table (vn_tables_t table)
{
- table->phis = htab_create (23, vn_phi_hash, vn_phi_eq, free_phi);
- table->nary = htab_create (23, vn_nary_op_hash, vn_nary_op_eq, NULL);
- table->references = htab_create (23, vn_reference_hash, vn_reference_eq,
- free_reference);
+ table->phis.create (23);
+ table->nary.create (23);
+ table->references.create (23);
gcc_obstack_init (&table->nary_obstack);
table->phis_pool = create_alloc_pool ("VN phis",
@@ -3870,9 +3934,9 @@ allocate_vn_table (vn_tables_t table)
static void
free_vn_table (vn_tables_t table)
{
- htab_delete (table->phis);
- htab_delete (table->nary);
- htab_delete (table->references);
+ table->phis.dispose ();
+ table->nary.dispose ();
+ table->references.dispose ();
obstack_free (&table->nary_obstack, NULL);
free_alloc_pool (table->phis_pool);
free_alloc_pool (table->references_pool);
@@ -3887,8 +3951,7 @@ init_scc_vn (void)
calculate_dominance_info (CDI_DOMINATORS);
sccstack.create (0);
- constant_to_value_id = htab_create (23, vn_constant_hash, vn_constant_eq,
- free);
+ constant_to_value_id.create (23);
constant_value_ids = BITMAP_ALLOC (NULL);
@@ -3944,7 +4007,7 @@ free_scc_vn (void)
{
size_t i;
- htab_delete (constant_to_value_id);
+ constant_to_value_id.dispose ();
BITMAP_FREE (constant_value_ids);
shared_lookup_phiargs.release ();
shared_lookup_references.release ();
@@ -3985,7 +4048,9 @@ set_value_id_for_result (tree result, unsigned int *id)
static void
set_hashtable_value_ids (void)
{
- htab_iterator hi;
+ vn_nary_op_iterator_type hin;
+ vn_phi_iterator_type hip;
+ vn_reference_iterator_type hir;
vn_nary_op_t vno;
vn_reference_t vr;
vn_phi_t vp;
@@ -3993,16 +4058,13 @@ set_hashtable_value_ids (void)
/* Now set the value ids of the things we had put in the hash
table. */
- FOR_EACH_HTAB_ELEMENT (valid_info->nary,
- vno, vn_nary_op_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (valid_info->nary, vno, vn_nary_op_t, hin)
set_value_id_for_result (vno->result, &vno->value_id);
- FOR_EACH_HTAB_ELEMENT (valid_info->phis,
- vp, vn_phi_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (valid_info->phis, vp, vn_phi_t, hip)
set_value_id_for_result (vp->result, &vp->value_id);
- FOR_EACH_HTAB_ELEMENT (valid_info->references,
- vr, vn_reference_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (valid_info->references, vr, vn_reference_t, hir)
set_value_id_for_result (vr->result, &vr->value_id);
}
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index 072f7ddf65e..94e3603f740 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -216,10 +216,11 @@ vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
tree, unsigned int);
hashval_t vn_nary_op_compute_hash (const vn_nary_op_t);
-int vn_nary_op_eq (const void *, const void *);
+bool vn_nary_op_eq (const_vn_nary_op_t const vno1,
+ const_vn_nary_op_t const vno2);
bool vn_nary_may_trap (vn_nary_op_t);
hashval_t vn_reference_compute_hash (const vn_reference_t);
-int vn_reference_eq (const void *, const void *);
+bool vn_reference_eq (const_vn_reference_t const, const_vn_reference_t const);
unsigned int get_max_value_id (void);
unsigned int get_next_value_id (void);
unsigned int get_constant_value_id (tree);
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index c8324610914..ca2b2e931b0 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "hash-table.h"
#include "tree-flow.h"
#include "tree-pass.h"
#include "domwalk.h"
@@ -111,9 +112,33 @@ struct decl_stridxlist_map
struct stridxlist list;
};
+/* stridxlist hashtable helpers. */
+
+struct stridxlist_hasher : typed_noop_remove <decl_stridxlist_map>
+{
+ typedef decl_stridxlist_map value_type;
+ typedef decl_stridxlist_map compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash a from tree in a decl_stridxlist_map. */
+
+inline hashval_t
+stridxlist_hasher::hash (const value_type *item)
+{
+ return DECL_UID (item->base.from);
+}
+
+inline bool
+stridxlist_hasher::equal (const value_type *v, const compare_type *c)
+{
+ return tree_map_base_eq (&v->base, &c->base);
+}
+
/* Hash table for mapping decls to a chained list of offset -> idx
mappings. */
-static htab_t decl_to_stridxlist_htab;
+static hash_table <stridxlist_hasher> decl_to_stridxlist_htab;
/* Obstack for struct stridxlist and struct decl_stridxlist_map. */
static struct obstack stridx_obstack;
@@ -128,14 +153,6 @@ struct laststmt_struct
int stridx;
} laststmt;
-/* Hash a from tree in a decl_stridxlist_map. */
-
-static unsigned int
-decl_to_stridxlist_hash (const void *item)
-{
- return DECL_UID (((const struct decl_stridxlist_map *) item)->base.from);
-}
-
/* Helper function for get_stridx. */
static int
@@ -146,7 +163,7 @@ get_addr_stridx (tree exp)
struct stridxlist *list;
tree base;
- if (decl_to_stridxlist_htab == NULL)
+ if (!decl_to_stridxlist_htab.is_created ())
return 0;
base = get_addr_base_and_unit_offset (exp, &off);
@@ -154,8 +171,7 @@ get_addr_stridx (tree exp)
return 0;
ent.base.from = base;
- e = (struct decl_stridxlist_map *)
- htab_find_with_hash (decl_to_stridxlist_htab, &ent, DECL_UID (base));
+ e = decl_to_stridxlist_htab.find_with_hash (&ent, DECL_UID (base));
if (e == NULL)
return 0;
@@ -234,7 +250,7 @@ unshare_strinfo_vec (void)
static int *
addr_stridxptr (tree exp)
{
- void **slot;
+ decl_stridxlist_map **slot;
struct decl_stridxlist_map ent;
struct stridxlist *list;
HOST_WIDE_INT off;
@@ -243,19 +259,18 @@ addr_stridxptr (tree exp)
if (base == NULL_TREE || !DECL_P (base))
return NULL;
- if (decl_to_stridxlist_htab == NULL)
+ if (!decl_to_stridxlist_htab.is_created ())
{
- decl_to_stridxlist_htab
- = htab_create (64, decl_to_stridxlist_hash, tree_map_base_eq, NULL);
+ decl_to_stridxlist_htab.create (64);
gcc_obstack_init (&stridx_obstack);
}
ent.base.from = base;
- slot = htab_find_slot_with_hash (decl_to_stridxlist_htab, &ent,
- DECL_UID (base), INSERT);
+ slot = decl_to_stridxlist_htab.find_slot_with_hash (&ent, DECL_UID (base),
+ INSERT);
if (*slot)
{
int i;
- list = &((struct decl_stridxlist_map *)*slot)->list;
+ list = &(*slot)->list;
for (i = 0; i < 16; i++)
{
if (list->offset == off)
@@ -273,7 +288,7 @@ addr_stridxptr (tree exp)
struct decl_stridxlist_map *e
= XOBNEW (&stridx_obstack, struct decl_stridxlist_map);
e->base.from = base;
- *slot = (void *) e;
+ *slot = e;
list = &e->list;
}
list->next = NULL;
@@ -1985,11 +2000,10 @@ tree_ssa_strlen (void)
ssa_ver_to_stridx.release ();
free_alloc_pool (strinfo_pool);
- if (decl_to_stridxlist_htab)
+ if (decl_to_stridxlist_htab.is_created ())
{
obstack_free (&stridx_obstack, NULL);
- htab_delete (decl_to_stridxlist_htab);
- decl_to_stridxlist_htab = NULL;
+ decl_to_stridxlist_htab.dispose ();
}
laststmt.stmt = NULL;
laststmt.len = NULL_TREE;
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 236b86a9bdd..bbb84cfd925 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -32,7 +32,7 @@
#include "tree-inline.h"
#include "diagnostic-core.h"
#include "gimple.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "function.h"
#include "cgraph.h"
#include "tree-pass.h"
@@ -1862,48 +1862,54 @@ typedef struct equiv_class_label
} *equiv_class_label_t;
typedef const struct equiv_class_label *const_equiv_class_label_t;
-/* A hashtable for mapping a bitmap of labels->pointer equivalence
- classes. */
-static htab_t pointer_equiv_class_table;
+/* Equiv_class_label hashtable helpers. */
-/* A hashtable for mapping a bitmap of labels->location equivalence
- classes. */
-static htab_t location_equiv_class_table;
+struct equiv_class_hasher : typed_free_remove <equiv_class_label>
+{
+ typedef equiv_class_label value_type;
+ typedef equiv_class_label compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
/* Hash function for a equiv_class_label_t */
-static hashval_t
-equiv_class_label_hash (const void *p)
+inline hashval_t
+equiv_class_hasher::hash (const value_type *ecl)
{
- const_equiv_class_label_t const ecl = (const_equiv_class_label_t) p;
return ecl->hashcode;
}
/* Equality function for two equiv_class_label_t's. */
-static int
-equiv_class_label_eq (const void *p1, const void *p2)
+inline bool
+equiv_class_hasher::equal (const value_type *eql1, const compare_type *eql2)
{
- const_equiv_class_label_t const eql1 = (const_equiv_class_label_t) p1;
- const_equiv_class_label_t const eql2 = (const_equiv_class_label_t) p2;
return (eql1->hashcode == eql2->hashcode
&& bitmap_equal_p (eql1->labels, eql2->labels));
}
+/* A hashtable for mapping a bitmap of labels->pointer equivalence
+ classes. */
+static hash_table <equiv_class_hasher> pointer_equiv_class_table;
+
+/* A hashtable for mapping a bitmap of labels->location equivalence
+ classes. */
+static hash_table <equiv_class_hasher> location_equiv_class_table;
+
/* Lookup a equivalence class in TABLE by the bitmap of LABELS with
hash HAS it contains. Sets *REF_LABELS to the bitmap LABELS
is equivalent to. */
static equiv_class_label *
-equiv_class_lookup_or_add (htab_t table, bitmap labels)
+equiv_class_lookup_or_add (hash_table <equiv_class_hasher> table, bitmap labels)
{
equiv_class_label **slot;
equiv_class_label ecl;
ecl.labels = labels;
ecl.hashcode = bitmap_hash (labels);
- slot = (equiv_class_label **) htab_find_slot_with_hash (table, &ecl,
- ecl.hashcode, INSERT);
+ slot = table.find_slot_with_hash (&ecl, ecl.hashcode, INSERT);
if (!*slot)
{
*slot = XNEW (struct equiv_class_label);
@@ -2222,10 +2228,8 @@ perform_var_substitution (constraint_graph_t graph)
struct scc_info *si = init_scc_info (size);
bitmap_obstack_initialize (&iteration_obstack);
- pointer_equiv_class_table = htab_create (511, equiv_class_label_hash,
- equiv_class_label_eq, free);
- location_equiv_class_table = htab_create (511, equiv_class_label_hash,
- equiv_class_label_eq, free);
+ pointer_equiv_class_table.create (511);
+ location_equiv_class_table.create (511);
pointer_equiv_class = 1;
location_equiv_class = 1;
@@ -2339,8 +2343,8 @@ free_var_substitution_info (struct scc_info *si)
free (graph->points_to);
free (graph->eq_rep);
sbitmap_free (graph->direct_nodes);
- htab_delete (pointer_equiv_class_table);
- htab_delete (location_equiv_class_table);
+ pointer_equiv_class_table.dispose ();
+ location_equiv_class_table.dispose ();
bitmap_obstack_release (&iteration_obstack);
}
@@ -5877,45 +5881,54 @@ typedef struct shared_bitmap_info
} *shared_bitmap_info_t;
typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
-static htab_t shared_bitmap_table;
+/* Shared_bitmap hashtable helpers. */
+
+struct shared_bitmap_hasher : typed_free_remove <shared_bitmap_info>
+{
+ typedef shared_bitmap_info value_type;
+ typedef shared_bitmap_info compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
/* Hash function for a shared_bitmap_info_t */
-static hashval_t
-shared_bitmap_hash (const void *p)
+inline hashval_t
+shared_bitmap_hasher::hash (const value_type *bi)
{
- const_shared_bitmap_info_t const bi = (const_shared_bitmap_info_t) p;
return bi->hashcode;
}
/* Equality function for two shared_bitmap_info_t's. */
-static int
-shared_bitmap_eq (const void *p1, const void *p2)
+inline bool
+shared_bitmap_hasher::equal (const value_type *sbi1, const compare_type *sbi2)
{
- const_shared_bitmap_info_t const sbi1 = (const_shared_bitmap_info_t) p1;
- const_shared_bitmap_info_t const sbi2 = (const_shared_bitmap_info_t) p2;
return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
}
+/* Shared_bitmap hashtable. */
+
+static hash_table <shared_bitmap_hasher> shared_bitmap_table;
+
/* Lookup a bitmap in the shared bitmap hashtable, and return an already
existing instance if there is one, NULL otherwise. */
static bitmap
shared_bitmap_lookup (bitmap pt_vars)
{
- void **slot;
+ shared_bitmap_info **slot;
struct shared_bitmap_info sbi;
sbi.pt_vars = pt_vars;
sbi.hashcode = bitmap_hash (pt_vars);
- slot = htab_find_slot_with_hash (shared_bitmap_table, &sbi,
- sbi.hashcode, NO_INSERT);
+ slot = shared_bitmap_table.find_slot_with_hash (&sbi, sbi.hashcode,
+ NO_INSERT);
if (!slot)
return NULL;
else
- return ((shared_bitmap_info_t) *slot)->pt_vars;
+ return (*slot)->pt_vars;
}
@@ -5924,16 +5937,15 @@ shared_bitmap_lookup (bitmap pt_vars)
static void
shared_bitmap_add (bitmap pt_vars)
{
- void **slot;
+ shared_bitmap_info **slot;
shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
sbi->pt_vars = pt_vars;
sbi->hashcode = bitmap_hash (pt_vars);
- slot = htab_find_slot_with_hash (shared_bitmap_table, sbi,
- sbi->hashcode, INSERT);
+ slot = shared_bitmap_table.find_slot_with_hash (sbi, sbi->hashcode, INSERT);
gcc_assert (!*slot);
- *slot = (void *) sbi;
+ *slot = sbi;
}
@@ -6589,8 +6601,7 @@ init_alias_vars (void)
call_stmt_vars = pointer_map_create ();
memset (&stats, 0, sizeof (stats));
- shared_bitmap_table = htab_create (511, shared_bitmap_hash,
- shared_bitmap_eq, free);
+ shared_bitmap_table.create (511);
init_base_vars ();
gcc_obstack_init (&fake_var_decl_obstack);
@@ -6846,7 +6857,7 @@ delete_points_to_sets (void)
{
unsigned int i;
- htab_delete (shared_bitmap_table);
+ shared_bitmap_table.dispose ();
if (dump_file && (dump_flags & TDF_STATS))
fprintf (dump_file, "Points to sets created:%d\n",
stats.points_to_sets_created);
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index c7eed9e4e0f..1fbc524e57f 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -265,11 +265,6 @@ associate_equivalences_with_edges (void)
subtree rooted at the block where we record the equivalency. */
static vec<tree> equiv_stack;
-/* Global hash table implementing a mapping from invariant values
- to a list of SSA_NAMEs which have the same value. We might be
- able to reuse tree-vn for this code. */
-static htab_t equiv;
-
/* Main structure for recording equivalences into our hash table. */
struct equiv_hash_elt
{
@@ -280,53 +275,66 @@ struct equiv_hash_elt
vec<tree> equivalences;
};
-static void uncprop_enter_block (struct dom_walk_data *, basic_block);
-static void uncprop_leave_block (struct dom_walk_data *, basic_block);
-static void uncprop_into_successor_phis (basic_block);
+/* Value to ssa name equivalence hashtable helpers. */
-/* Hashing and equality routines for the hash table. */
+struct val_ssa_equiv_hasher
+{
+ typedef equiv_hash_elt value_type;
+ typedef equiv_hash_elt compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
-static hashval_t
-equiv_hash (const void *p)
+inline hashval_t
+val_ssa_equiv_hasher::hash (const value_type *p)
{
- tree const value = ((const struct equiv_hash_elt *)p)->value;
+ tree const value = p->value;
return iterative_hash_expr (value, 0);
}
-static int
-equiv_eq (const void *p1, const void *p2)
+inline bool
+val_ssa_equiv_hasher::equal (const value_type *p1, const compare_type *p2)
{
- tree value1 = ((const struct equiv_hash_elt *)p1)->value;
- tree value2 = ((const struct equiv_hash_elt *)p2)->value;
+ tree value1 = p1->value;
+ tree value2 = p2->value;
return operand_equal_p (value1, value2, 0);
}
/* Free an instance of equiv_hash_elt. */
-static void
-equiv_free (void *p)
+inline void
+val_ssa_equiv_hasher::remove (value_type *elt)
{
- struct equiv_hash_elt *elt = (struct equiv_hash_elt *) p;
elt->equivalences.release ();
free (elt);
}
+/* Global hash table implementing a mapping from invariant values
+ to a list of SSA_NAMEs which have the same value. We might be
+ able to reuse tree-vn for this code. */
+static hash_table <val_ssa_equiv_hasher> val_ssa_equiv;
+
+static void uncprop_enter_block (struct dom_walk_data *, basic_block);
+static void uncprop_leave_block (struct dom_walk_data *, basic_block);
+static void uncprop_into_successor_phis (basic_block);
+
/* Remove the most recently recorded equivalency for VALUE. */
static void
remove_equivalence (tree value)
{
- struct equiv_hash_elt equiv_hash_elt, *equiv_hash_elt_p;
- void **slot;
+ struct equiv_hash_elt an_equiv_elt, *an_equiv_elt_p;
+ equiv_hash_elt **slot;
- equiv_hash_elt.value = value;
- equiv_hash_elt.equivalences.create (0);
+ an_equiv_elt.value = value;
+ an_equiv_elt.equivalences.create (0);
- slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT);
+ slot = val_ssa_equiv.find_slot (&an_equiv_elt, NO_INSERT);
- equiv_hash_elt_p = (struct equiv_hash_elt *) *slot;
- equiv_hash_elt_p->equivalences.pop ();
+ an_equiv_elt_p = *slot;
+ an_equiv_elt_p->equivalences.pop ();
}
/* Record EQUIVALENCE = VALUE into our hash table. */
@@ -334,23 +342,23 @@ remove_equivalence (tree value)
static void
record_equiv (tree value, tree equivalence)
{
- struct equiv_hash_elt *equiv_hash_elt;
- void **slot;
+ equiv_hash_elt *an_equiv_elt_p;
+ equiv_hash_elt **slot;
- equiv_hash_elt = XNEW (struct equiv_hash_elt);
- equiv_hash_elt->value = value;
- equiv_hash_elt->equivalences.create (0);
+ an_equiv_elt_p = XNEW (struct equiv_hash_elt);
+ an_equiv_elt_p->value = value;
+ an_equiv_elt_p->equivalences.create (0);
- slot = htab_find_slot (equiv, equiv_hash_elt, INSERT);
+ slot = val_ssa_equiv.find_slot (an_equiv_elt_p, INSERT);
if (*slot == NULL)
- *slot = (void *) equiv_hash_elt;
+ *slot = an_equiv_elt_p;
else
- free (equiv_hash_elt);
+ free (an_equiv_elt_p);
- equiv_hash_elt = (struct equiv_hash_elt *) *slot;
+ an_equiv_elt_p = *slot;
- equiv_hash_elt->equivalences.safe_push (equivalence);
+ an_equiv_elt_p->equivalences.safe_push (equivalence);
}
/* Main driver for un-cprop. */
@@ -364,7 +372,7 @@ tree_ssa_uncprop (void)
associate_equivalences_with_edges ();
/* Create our global data structures. */
- equiv = htab_create (1024, equiv_hash, equiv_eq, equiv_free);
+ val_ssa_equiv.create (1024);
equiv_stack.create (2);
/* We're going to do a dominator walk, so ensure that we have
@@ -392,7 +400,7 @@ tree_ssa_uncprop (void)
/* EQUIV_STACK should already be empty at this point, so we just
need to empty elements out of the hash table, free EQUIV_STACK,
and cleanup the AUX field on the edges. */
- htab_delete (equiv);
+ val_ssa_equiv.dispose ();
equiv_stack.release ();
FOR_EACH_BB (bb)
{
@@ -463,8 +471,8 @@ uncprop_into_successor_phis (basic_block bb)
gimple phi = gsi_stmt (gsi);
tree arg = PHI_ARG_DEF (phi, e->dest_idx);
tree res = PHI_RESULT (phi);
- struct equiv_hash_elt equiv_hash_elt;
- void **slot;
+ equiv_hash_elt an_equiv_elt;
+ equiv_hash_elt **slot;
/* If the argument is not an invariant, and refers to the same
underlying variable as the PHI result, then there's no
@@ -475,13 +483,13 @@ uncprop_into_successor_phis (basic_block bb)
continue;
/* Lookup this argument's value in the hash table. */
- equiv_hash_elt.value = arg;
- equiv_hash_elt.equivalences.create (0);
- slot = htab_find_slot (equiv, &equiv_hash_elt, NO_INSERT);
+ an_equiv_elt.value = arg;
+ an_equiv_elt.equivalences.create (0);
+ slot = val_ssa_equiv.find_slot (&an_equiv_elt, NO_INSERT);
if (slot)
{
- struct equiv_hash_elt *elt = (struct equiv_hash_elt *) *slot;
+ struct equiv_hash_elt *elt = *slot;
int j;
/* Walk every equivalence with the same value. If we find
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index b0619faefd5..15a91766892 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1046,42 +1046,6 @@ err:
internal_error ("verify_ssa failed");
}
-/* Return true if the uid in both int tree maps are equal. */
-
-int
-int_tree_map_eq (const void *va, const void *vb)
-{
- const struct int_tree_map *a = (const struct int_tree_map *) va;
- const struct int_tree_map *b = (const struct int_tree_map *) vb;
- return (a->uid == b->uid);
-}
-
-/* Hash a UID in a int_tree_map. */
-
-unsigned int
-int_tree_map_hash (const void *item)
-{
- return ((const struct int_tree_map *)item)->uid;
-}
-
-/* Return true if the DECL_UID in both trees are equal. */
-
-int
-uid_decl_map_eq (const void *va, const void *vb)
-{
- const_tree a = (const_tree) va;
- const_tree b = (const_tree) vb;
- return (a->decl_minimal.uid == b->decl_minimal.uid);
-}
-
-/* Hash a tree in a uid_decl_map. */
-
-unsigned int
-uid_decl_map_hash (const void *item)
-{
- return ((const_tree)item)->decl_minimal.uid;
-}
-
/* Return true if the DECL_UID in both trees are equal. */
static int
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 579f6032280..b38e96ae0b9 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -1026,27 +1026,6 @@ vect_get_data_access_cost (struct data_reference *dr,
}
-static hashval_t
-vect_peeling_hash (const void *elem)
-{
- const struct _vect_peel_info *peel_info;
-
- peel_info = (const struct _vect_peel_info *) elem;
- return (hashval_t) peel_info->npeel;
-}
-
-
-static int
-vect_peeling_hash_eq (const void *elem1, const void *elem2)
-{
- const struct _vect_peel_info *a, *b;
-
- a = (const struct _vect_peel_info *) elem1;
- b = (const struct _vect_peel_info *) elem2;
- return (a->npeel == b->npeel);
-}
-
-
/* Insert DR into peeling hash table with NPEEL as key. */
static void
@@ -1054,12 +1033,11 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
int npeel)
{
struct _vect_peel_info elem, *slot;
- void **new_slot;
+ _vect_peel_info **new_slot;
bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
elem.npeel = npeel;
- slot = (vect_peel_info) htab_find (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
- &elem);
+ slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo).find (&elem);
if (slot)
slot->count++;
else
@@ -1068,8 +1046,7 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
slot->npeel = npeel;
slot->dr = dr;
slot->count = 1;
- new_slot = htab_find_slot (LOOP_VINFO_PEELING_HTAB (loop_vinfo), slot,
- INSERT);
+ new_slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo).find_slot (slot, INSERT);
*new_slot = slot;
}
@@ -1081,11 +1058,11 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
/* Traverse peeling hash table to find peeling option that aligns maximum
number of data accesses. */
-static int
-vect_peeling_hash_get_most_frequent (void **slot, void *data)
+int
+vect_peeling_hash_get_most_frequent (_vect_peel_info **slot,
+ _vect_peel_extended_info *max)
{
- vect_peel_info elem = (vect_peel_info) *slot;
- vect_peel_extended_info max = (vect_peel_extended_info) data;
+ vect_peel_info elem = *slot;
if (elem->count > max->peel_info.count
|| (elem->count == max->peel_info.count
@@ -1103,11 +1080,11 @@ vect_peeling_hash_get_most_frequent (void **slot, void *data)
/* Traverse peeling hash table and calculate cost for each peeling option.
Find the one with the lowest cost. */
-static int
-vect_peeling_hash_get_lowest_cost (void **slot, void *data)
+int
+vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot,
+ _vect_peel_extended_info *min)
{
- vect_peel_info elem = (vect_peel_info) *slot;
- vect_peel_extended_info min = (vect_peel_extended_info) data;
+ vect_peel_info elem = *slot;
int save_misalignment, dummy;
unsigned int inside_cost = 0, outside_cost = 0, i;
gimple stmt = DR_STMT (elem->dr);
@@ -1187,14 +1164,16 @@ vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo,
{
res.inside_cost = INT_MAX;
res.outside_cost = INT_MAX;
- htab_traverse (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
- vect_peeling_hash_get_lowest_cost, &res);
+ LOOP_VINFO_PEELING_HTAB (loop_vinfo)
+ .traverse <_vect_peel_extended_info *,
+ vect_peeling_hash_get_lowest_cost> (&res);
}
else
{
res.peel_info.count = 0;
- htab_traverse (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
- vect_peeling_hash_get_most_frequent, &res);
+ LOOP_VINFO_PEELING_HTAB (loop_vinfo)
+ .traverse <_vect_peel_extended_info *,
+ vect_peeling_hash_get_most_frequent> (&res);
}
*npeel = res.peel_info.npeel;
@@ -1387,10 +1366,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
size_zero_node) < 0;
/* Save info about DR in the hash table. */
- if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo))
- LOOP_VINFO_PEELING_HTAB (loop_vinfo) =
- htab_create (1, vect_peeling_hash,
- vect_peeling_hash_eq, free);
+ if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo).is_created ())
+ LOOP_VINFO_PEELING_HTAB (loop_vinfo).create (1);
vectype = STMT_VINFO_VECTYPE (stmt_info);
nelements = TYPE_VECTOR_SUBPARTS (vectype);
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 542082f3cf6..c707d76e8af 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -873,7 +873,6 @@ new_loop_vec_info (struct loop *loop)
LOOP_VINFO_REDUCTION_CHAINS (res).create (10);
LOOP_VINFO_SLP_INSTANCES (res).create (10);
LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
- LOOP_VINFO_PEELING_HTAB (res) = NULL;
LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
LOOP_VINFO_OPERANDS_SWAPPED (res) = false;
@@ -954,8 +953,8 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
LOOP_VINFO_REDUCTIONS (loop_vinfo).release ();
LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).release ();
- if (LOOP_VINFO_PEELING_HTAB (loop_vinfo))
- htab_delete (LOOP_VINFO_PEELING_HTAB (loop_vinfo));
+ if (LOOP_VINFO_PEELING_HTAB (loop_vinfo).is_created ())
+ LOOP_VINFO_PEELING_HTAB (loop_vinfo).dispose ();
destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 6c08979e8a6..933245038c8 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -191,6 +191,30 @@ typedef struct _vect_peel_extended_info
stmt_vector_for_cost body_cost_vec;
} *vect_peel_extended_info;
+
+/* Peeling hashtable helpers. */
+
+struct peel_info_hasher : typed_free_remove <_vect_peel_info>
+{
+ typedef _vect_peel_info value_type;
+ typedef _vect_peel_info compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+peel_info_hasher::hash (const value_type *peel_info)
+{
+ return (hashval_t) peel_info->npeel;
+}
+
+inline bool
+peel_info_hasher::equal (const value_type *a, const compare_type *b)
+{
+ return (a->npeel == b->npeel);
+}
+
+
/*-----------------------------------------------------------------*/
/* Info on vectorized loops. */
/*-----------------------------------------------------------------*/
@@ -275,7 +299,7 @@ typedef struct _loop_vec_info {
vec<gimple> reduction_chains;
/* Hash table used to choose the best peeling option. */
- htab_t peeling_htab;
+ hash_table <peel_info_hasher> peeling_htab;
/* Cost data used by the target cost model. */
void *target_cost_data;
diff --git a/gcc/tree.c b/gcc/tree.c
index 65bc15f7637..0955cabc13d 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -11625,4 +11625,95 @@ warn_deprecated_use (tree node, tree attr)
}
}
+
+/* Construct a record builder with the identifier IDENT.
+ It is a union if IS_UNION is true, otherwise it is a RECORD_TYPE.
+ QUAL_RECORD_TYPE is not supported. */
+
+record_builder::record_builder (bool is_union)
+: building_ (lang_hooks.types.make_type (is_union ? UNION_TYPE : RECORD_TYPE)),
+ last_field_ (NULL)
+{
+}
+
+
+/* Add a field with an identifier IDENT and type TYPE to the record. */
+
+void
+record_builder::add_field (tree ident, tree type, source_location loc)
+{
+ tree this_field = build_decl (loc, FIELD_DECL, ident, type);
+ DECL_CONTEXT (this_field) = building_;
+ if (last_field_)
+ DECL_CHAIN (last_field_) = this_field;
+ else
+ TYPE_FIELDS (building_) = this_field;
+ last_field_ = this_field;
+}
+
+void
+record_builder::add_field (const char *ident, tree type, source_location loc)
+{
+ add_field (get_identifier (ident), type, loc);
+}
+
+
+/* Add a TYPE_NAME to the record. This can be a tag name directly from IDENT,
+ or a TYPE_DECL created with the IDENT. */
+
+void
+record_builder::tag_name (tree ident)
+{
+ gcc_assert (TREE_CODE (ident) == IDENTIFIER_NODE);
+ TYPE_NAME (building_) = ident;
+}
+
+void
+record_builder::tag_name (const char *ident)
+{
+ tag_name (get_identifier (ident));
+}
+
+void
+record_builder::decl_name (tree ident, source_location loc)
+{
+ tree type_decl = build_decl (loc, TYPE_DECL, ident, building_);
+ TYPE_NAME (building_) = type_decl;
+}
+
+void
+record_builder::decl_name (const char *ident, source_location loc)
+{
+ decl_name (get_identifier (ident), loc);
+}
+
+
+/* Layout the fields of the record, aligning with ALIGN_TYPE if given.
+ Ensure that you call one of these functions after adding all fields. */
+
+void
+record_builder::layout ()
+{
+ layout_type (building_);
+}
+
+void
+record_builder::layout (tree align_type)
+{
+ TYPE_ALIGN (building_) = TYPE_ALIGN (align_type);
+ TYPE_USER_ALIGN (building_) = TYPE_USER_ALIGN (align_type);
+ layout ();
+}
+
+
+/* Return the record as a tree. You may call this function any time after
+ construction of the builder. */
+
+tree
+record_builder::as_tree ()
+{
+ return building_;
+}
+
+
#include "gt-tree.h"
diff --git a/gcc/tree.h b/gcc/tree.h
index f1b988ca7bb..d3ddf6ccce9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -6546,4 +6546,28 @@ builtin_decl_implicit_p (enum built_in_function fncode)
&& builtin_info.implicit_p[uns_fncode]);
}
+
+/* A class for simplifying the construction of RECORD_TYPE and UNION_TYPE. */
+
+class record_builder
+{
+public:
+ record_builder (bool is_union = false);
+ void add_field (tree ident, tree type,
+ source_location loc = UNKNOWN_LOCATION);
+ void add_field (const char *ident, tree type,
+ source_location loc = UNKNOWN_LOCATION);
+ void layout ();
+ void layout (tree align_type);
+ void tag_name (tree ident);
+ void tag_name (const char *ident);
+ void decl_name (tree ident, source_location loc = UNKNOWN_LOCATION);
+ void decl_name (const char *ident, source_location loc = UNKNOWN_LOCATION);
+ tree as_tree ();
+private:
+ tree building_;
+ tree last_field_;
+}; // class record_builder
+
+
#endif /* GCC_TREE_H */
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 4855fb155b3..baa9092b6f9 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -100,7 +100,7 @@
#include "sbitmap.h"
#include "alloc-pool.h"
#include "fibheap.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "regs.h"
#include "expr.h"
#include "tree-pass.h"
@@ -196,19 +196,43 @@ typedef struct micro_operation_def
declaration. */
typedef void *decl_or_value;
-/* Structure for passing some other parameters to function
- emit_note_insn_var_location. */
-typedef struct emit_note_data_def
+/* Return true if a decl_or_value DV is a DECL or NULL. */
+static inline bool
+dv_is_decl_p (decl_or_value dv)
{
- /* The instruction which the note will be emitted before/after. */
- rtx insn;
+ return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
+}
- /* Where the note will be emitted (before/after insn)? */
- enum emit_note_where where;
+/* Return true if a decl_or_value is a VALUE rtl. */
+static inline bool
+dv_is_value_p (decl_or_value dv)
+{
+ return dv && !dv_is_decl_p (dv);
+}
+
+/* Return the decl in the decl_or_value. */
+static inline tree
+dv_as_decl (decl_or_value dv)
+{
+ gcc_checking_assert (dv_is_decl_p (dv));
+ return (tree) dv;
+}
+
+/* Return the value in the decl_or_value. */
+static inline rtx
+dv_as_value (decl_or_value dv)
+{
+ gcc_checking_assert (dv_is_value_p (dv));
+ return (rtx)dv;
+}
+
+/* Return the opaque pointer in the decl_or_value. */
+static inline void *
+dv_as_opaque (decl_or_value dv)
+{
+ return dv;
+}
- /* The variables and values active at this point. */
- htab_t vars;
-} emit_note_data;
/* Description of location of a part of a variable. The content of a physical
register is described by a chain of these structures.
@@ -229,58 +253,6 @@ 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
-{
- /* Adjustment of stack offset. */
- HOST_WIDE_INT stack_adjust;
-
- /* Attributes for registers (lists of attrs). */
- attrs regs[FIRST_PSEUDO_REGISTER];
-
- /* Variable locations. */
- shared_hash vars;
-
- /* Vars that is being traversed. */
- shared_hash traversed_vars;
-} dataflow_set;
-
-/* The structure (one for each basic block) containing the information
- needed for variable tracking. */
-typedef struct variable_tracking_info_def
-{
- /* The vector of micro operations. */
- vec<micro_operation> mos;
-
- /* The IN and OUT set for dataflow analysis. */
- dataflow_set in;
- dataflow_set out;
-
- /* The permanent-in dataflow set for this block. This is used to
- hold values for which we had to compute entry values. ??? This
- should probably be dynamically allocated, to avoid using more
- memory in non-debug builds. */
- dataflow_set *permp;
-
- /* Has the block been visited in DFS? */
- bool visited;
-
- /* Has the block been flooded in VTA? */
- bool flooded;
-
-} *variable_tracking_info;
-
/* Structure for chaining the locations. */
typedef struct location_chain_def
{
@@ -454,6 +426,146 @@ typedef const struct variable_def *const_variable;
? &VAR_LOC_1PAUX (var)->deps \
: NULL)
+
+
+typedef unsigned int dvuid;
+
+/* Return the uid of DV. */
+
+static inline dvuid
+dv_uid (decl_or_value dv)
+{
+ if (dv_is_value_p (dv))
+ return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
+ else
+ return DECL_UID (dv_as_decl (dv));
+}
+
+/* Compute the hash from the uid. */
+
+static inline hashval_t
+dv_uid2hash (dvuid uid)
+{
+ return uid;
+}
+
+/* The hash function for a mask table in a shared_htab chain. */
+
+static inline hashval_t
+dv_htab_hash (decl_or_value dv)
+{
+ return dv_uid2hash (dv_uid (dv));
+}
+
+static void variable_htab_free (void *);
+
+/* Variable hashtable helpers. */
+
+struct variable_hasher
+{
+ typedef variable_def value_type;
+ typedef void compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+/* The hash function for variable_htab, computes the hash value
+ from the declaration of variable X. */
+
+inline hashval_t
+variable_hasher::hash (const value_type *v)
+{
+ return dv_htab_hash (v->dv);
+}
+
+/* Compare the declaration of variable X with declaration Y. */
+
+inline bool
+variable_hasher::equal (const value_type *v, const compare_type *y)
+{
+ decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
+
+ return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
+}
+
+/* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
+
+inline void
+variable_hasher::remove (value_type *var)
+{
+ variable_htab_free (var);
+}
+
+typedef hash_table <variable_hasher> variable_table_type;
+typedef variable_table_type::iterator variable_iterator_type;
+
+/* Structure for passing some other parameters to function
+ emit_note_insn_var_location. */
+typedef struct emit_note_data_def
+{
+ /* The instruction which the note will be emitted before/after. */
+ rtx insn;
+
+ /* Where the note will be emitted (before/after insn)? */
+ enum emit_note_where where;
+
+ /* The variables and values active at this point. */
+ variable_table_type vars;
+} emit_note_data;
+
+/* 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. */
+ variable_table_type htab;
+} *shared_hash;
+
+/* Structure holding the IN or OUT set for a basic block. */
+typedef struct dataflow_set_def
+{
+ /* Adjustment of stack offset. */
+ HOST_WIDE_INT stack_adjust;
+
+ /* Attributes for registers (lists of attrs). */
+ attrs regs[FIRST_PSEUDO_REGISTER];
+
+ /* Variable locations. */
+ shared_hash vars;
+
+ /* Vars that is being traversed. */
+ shared_hash traversed_vars;
+} dataflow_set;
+
+/* The structure (one for each basic block) containing the information
+ needed for variable tracking. */
+typedef struct variable_tracking_info_def
+{
+ /* The vector of micro operations. */
+ vec<micro_operation> mos;
+
+ /* The IN and OUT set for dataflow analysis. */
+ dataflow_set in;
+ dataflow_set out;
+
+ /* The permanent-in dataflow set for this block. This is used to
+ hold values for which we had to compute entry values. ??? This
+ should probably be dynamically allocated, to avoid using more
+ memory in non-debug builds. */
+ dataflow_set *permp;
+
+ /* Has the block been visited in DFS? */
+ bool visited;
+
+ /* Has the block been flooded in VTA? */
+ bool flooded;
+
+} *variable_tracking_info;
+
/* Alloc pool for struct attrs_def. */
static alloc_pool attrs_pool;
@@ -473,7 +585,7 @@ static alloc_pool shared_hash_pool;
static alloc_pool loc_exp_dep_pool;
/* Changed variables, notes will be emitted for them. */
-static htab_t changed_variables;
+static variable_table_type changed_variables;
/* Shall notes be emitted? */
static bool emit_notes;
@@ -481,7 +593,7 @@ static bool emit_notes;
/* Values whose dynamic location lists have gone empty, but whose
cselib location lists are still usable. Use this to hold the
current location, the backlinks, etc, during emit_notes. */
-static htab_t dropped_values;
+static variable_table_type dropped_values;
/* Empty shared hashtable. */
static shared_hash empty_shared_hash;
@@ -509,9 +621,6 @@ static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
HOST_WIDE_INT *);
static bool vt_stack_adjustments (void);
-static hashval_t variable_htab_hash (const void *);
-static int variable_htab_eq (const void *, const void *);
-static void variable_htab_free (void *);
static void init_attrs_list_set (attrs *);
static void attrs_list_clear (attrs *);
@@ -520,9 +629,9 @@ static void attrs_list_insert (attrs *, decl_or_value, HOST_WIDE_INT, rtx);
static void attrs_list_copy (attrs *, attrs);
static void attrs_list_union (attrs *, attrs);
-static void **unshare_variable (dataflow_set *set, void **slot, variable var,
- enum var_init_status);
-static void vars_copy (htab_t, htab_t);
+static variable_def **unshare_variable (dataflow_set *set, variable_def **slot,
+ variable var, enum var_init_status);
+static void vars_copy (variable_table_type, variable_table_type);
static tree var_debug_decl (tree);
static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
@@ -539,7 +648,7 @@ 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 void dataflow_set_union (dataflow_set *, dataflow_set *);
-static location_chain find_loc_in_1pdv (rtx, variable, htab_t);
+static location_chain find_loc_in_1pdv (rtx, variable, variable_table_type);
static bool canon_value_cmp (rtx, rtx);
static int loc_cmp (rtx, rtx);
static bool variable_part_different_p (variable_part *, variable_part *);
@@ -558,32 +667,27 @@ static bool compute_bb_dataflow (basic_block);
static bool vt_find_locations (void);
static void dump_attrs_list (attrs);
-static int dump_var_slot (void **, void *);
static void dump_var (variable);
-static void dump_vars (htab_t);
+static void dump_vars (variable_table_type);
static void dump_dataflow_set (dataflow_set *);
static void dump_dataflow_sets (void);
static void set_dv_changed (decl_or_value, bool);
static void variable_was_changed (variable, dataflow_set *);
-static void **set_slot_part (dataflow_set *, rtx, void **,
- decl_or_value, HOST_WIDE_INT,
- enum var_init_status, rtx);
+static variable_def **set_slot_part (dataflow_set *, rtx, variable_def **,
+ decl_or_value, HOST_WIDE_INT,
+ enum var_init_status, rtx);
static void set_variable_part (dataflow_set *, rtx,
decl_or_value, HOST_WIDE_INT,
enum var_init_status, rtx, enum insert_option);
-static void **clobber_slot_part (dataflow_set *, rtx,
- void **, HOST_WIDE_INT, rtx);
+static variable_def **clobber_slot_part (dataflow_set *, rtx,
+ variable_def **, HOST_WIDE_INT, rtx);
static void clobber_variable_part (dataflow_set *, rtx,
decl_or_value, HOST_WIDE_INT, rtx);
-static void **delete_slot_part (dataflow_set *, rtx, void **, HOST_WIDE_INT);
+static variable_def **delete_slot_part (dataflow_set *, rtx, variable_def **,
+ HOST_WIDE_INT);
static void delete_variable_part (dataflow_set *, rtx,
decl_or_value, HOST_WIDE_INT);
-static int emit_note_insn_var_location (void **, void *);
-static void emit_notes_for_changes (rtx, enum emit_note_where, shared_hash);
-static int emit_notes_for_differences_1 (void **, void *);
-static int emit_notes_for_differences_2 (void **, void *);
-static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
static void emit_notes_in_bb (basic_block, dataflow_set *);
static void vt_emit_notes (void);
@@ -1188,36 +1292,6 @@ adjust_insn (basic_block bb, rtx insn)
}
}
-/* Return true if a decl_or_value DV is a DECL or NULL. */
-static inline bool
-dv_is_decl_p (decl_or_value dv)
-{
- return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
-}
-
-/* Return true if a decl_or_value is a VALUE rtl. */
-static inline bool
-dv_is_value_p (decl_or_value dv)
-{
- return dv && !dv_is_decl_p (dv);
-}
-
-/* Return the decl in the decl_or_value. */
-static inline tree
-dv_as_decl (decl_or_value dv)
-{
- gcc_checking_assert (dv_is_decl_p (dv));
- return (tree) dv;
-}
-
-/* Return the value in the decl_or_value. */
-static inline rtx
-dv_as_value (decl_or_value dv)
-{
- gcc_checking_assert (dv_is_value_p (dv));
- return (rtx)dv;
-}
-
/* Return the DEBUG_EXPR of a DEBUG_EXPR_DECL or the VALUE in DV. */
static inline rtx
dv_as_rtx (decl_or_value dv)
@@ -1233,13 +1307,6 @@ dv_as_rtx (decl_or_value dv)
return DECL_RTL_KNOWN_SET (decl);
}
-/* Return the opaque pointer in the decl_or_value. */
-static inline void *
-dv_as_opaque (decl_or_value dv)
-{
- return dv;
-}
-
/* Return nonzero if a decl_or_value must not have more than one
variable part. The returned value discriminates among various
kinds of one-part DVs ccording to enum onepart_enum. */
@@ -1327,57 +1394,6 @@ debug_dv (decl_or_value dv)
debug_generic_stmt (dv_as_decl (dv));
}
-typedef unsigned int dvuid;
-
-/* Return the uid of DV. */
-
-static inline dvuid
-dv_uid (decl_or_value dv)
-{
- if (dv_is_value_p (dv))
- return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
- else
- return DECL_UID (dv_as_decl (dv));
-}
-
-/* Compute the hash from the uid. */
-
-static inline hashval_t
-dv_uid2hash (dvuid uid)
-{
- return uid;
-}
-
-/* The hash function for a mask table in a shared_htab chain. */
-
-static inline hashval_t
-dv_htab_hash (decl_or_value dv)
-{
- return dv_uid2hash (dv_uid (dv));
-}
-
-/* The hash function for variable_htab, computes the hash value
- from the declaration of variable X. */
-
-static hashval_t
-variable_htab_hash (const void *x)
-{
- const_variable const v = (const_variable) x;
-
- return dv_htab_hash (v->dv);
-}
-
-/* Compare the declaration of variable X with declaration Y. */
-
-static int
-variable_htab_eq (const void *x, const void *y)
-{
- const_variable const v = (const_variable) x;
- decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
-
- return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
-}
-
static void loc_exp_dep_clear (variable var);
/* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
@@ -1534,7 +1550,7 @@ shared_hash_shared (shared_hash vars)
/* Return the hash table for VARS. */
-static inline htab_t
+static inline variable_table_type
shared_hash_htab (shared_hash vars)
{
return vars->htab;
@@ -1558,9 +1574,7 @@ 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);
+ new_vars->htab.create (vars->htab.elements () + 3);
vars_copy (new_vars->htab, vars->htab);
vars->refcount--;
return new_vars;
@@ -1584,7 +1598,7 @@ shared_hash_destroy (shared_hash vars)
gcc_checking_assert (vars->refcount > 0);
if (--vars->refcount == 0)
{
- htab_delete (vars->htab);
+ vars->htab.dispose ();
pool_free (shared_hash_pool, vars);
}
}
@@ -1592,16 +1606,16 @@ shared_hash_destroy (shared_hash vars)
/* Unshare *PVARS if shared and return slot for DV. If INS is
INSERT, insert it if not already present. */
-static inline void **
+static inline variable_def **
shared_hash_find_slot_unshare_1 (shared_hash *pvars, decl_or_value dv,
hashval_t dvhash, enum insert_option ins)
{
if (shared_hash_shared (*pvars))
*pvars = shared_hash_unshare (*pvars);
- return htab_find_slot_with_hash (shared_hash_htab (*pvars), dv, dvhash, ins);
+ return shared_hash_htab (*pvars).find_slot_with_hash (dv, dvhash, ins);
}
-static inline void **
+static inline variable_def **
shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv,
enum insert_option ins)
{
@@ -1612,15 +1626,15 @@ shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv,
If it is not present, insert it only VARS is not shared, otherwise
return NULL. */
-static inline void **
+static inline variable_def **
shared_hash_find_slot_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
{
- return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
- shared_hash_shared (vars)
- ? NO_INSERT : INSERT);
+ return shared_hash_htab (vars).find_slot_with_hash (dv, dvhash,
+ shared_hash_shared (vars)
+ ? NO_INSERT : INSERT);
}
-static inline void **
+static inline variable_def **
shared_hash_find_slot (shared_hash vars, decl_or_value dv)
{
return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv));
@@ -1628,15 +1642,14 @@ shared_hash_find_slot (shared_hash vars, decl_or_value dv)
/* Return slot for DV only if it is already present in the hash table. */
-static inline void **
+static inline variable_def **
shared_hash_find_slot_noinsert_1 (shared_hash vars, decl_or_value dv,
hashval_t dvhash)
{
- return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
- NO_INSERT);
+ return shared_hash_htab (vars).find_slot_with_hash (dv, dvhash, NO_INSERT);
}
-static inline void **
+static inline variable_def **
shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv)
{
return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv));
@@ -1648,7 +1661,7 @@ shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv)
static inline variable
shared_hash_find_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
{
- return (variable) htab_find_with_hash (shared_hash_htab (vars), dv, dvhash);
+ return shared_hash_htab (vars).find_with_hash (dv, dvhash);
}
static inline variable
@@ -1677,8 +1690,8 @@ static bool dst_can_be_shared;
/* Return a copy of a variable VAR and insert it to dataflow set SET. */
-static void **
-unshare_variable (dataflow_set *set, void **slot, variable var,
+static variable_def **
+unshare_variable (dataflow_set *set, variable_def **slot, variable var,
enum var_init_status initialized)
{
variable new_var;
@@ -1744,8 +1757,8 @@ unshare_variable (dataflow_set *set, void **slot, variable var,
*slot = new_var;
if (var->in_changed_variables)
{
- void **cslot
- = htab_find_slot_with_hash (changed_variables, var->dv,
+ variable_def **cslot
+ = changed_variables.find_slot_with_hash (var->dv,
dv_htab_hash (var->dv), NO_INSERT);
gcc_assert (*cslot == (void *) var);
var->in_changed_variables = false;
@@ -1759,18 +1772,16 @@ unshare_variable (dataflow_set *set, void **slot, variable var,
/* Copy all variables from hash table SRC to hash table DST. */
static void
-vars_copy (htab_t dst, htab_t src)
+vars_copy (variable_table_type dst, variable_table_type src)
{
- htab_iterator hi;
+ variable_iterator_type hi;
variable var;
- FOR_EACH_HTAB_ELEMENT (src, var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (src, var, variable, hi)
{
- void **dstp;
+ variable_def **dstp;
var->refcount++;
- dstp = htab_find_slot_with_hash (dst, var->dv,
- dv_htab_hash (var->dv),
- INSERT);
+ dstp = dst.find_slot_with_hash (var->dv, dv_htab_hash (var->dv), INSERT);
*dstp = var;
}
}
@@ -2057,8 +2068,7 @@ get_addr_from_local_cache (dataflow_set *set, rtx const loc)
}
dv = dv_from_rtx (x);
- var = (variable) htab_find_with_hash (shared_hash_htab (set->vars),
- dv, dv_htab_hash (dv));
+ var = shared_hash_find (set->vars, dv);
if (!var)
return x;
@@ -2198,13 +2208,12 @@ struct overlapping_mems
canonicalized form of COMS->LOC's address, and COMS->LOC must be
canonicalized itself. */
-static int
-drop_overlapping_mem_locs (void **slot, void *data)
+int
+drop_overlapping_mem_locs (variable_def **slot, overlapping_mems *coms)
{
- struct overlapping_mems *coms = (struct overlapping_mems *)data;
dataflow_set *set = coms->set;
rtx mloc = coms->loc, addr = coms->addr;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VALUE)
{
@@ -2224,7 +2233,7 @@ drop_overlapping_mem_locs (void **slot, void *data)
return 1;
slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
gcc_assert (var->n_var_parts == 1);
}
@@ -2282,8 +2291,8 @@ clobber_overlapping_mems (dataflow_set *set, rtx loc)
coms.addr = vt_canonicalize_addr (set, XEXP (loc, 0));
set->traversed_vars = set->vars;
- htab_traverse (shared_hash_htab (set->vars),
- drop_overlapping_mem_locs, &coms);
+ shared_hash_htab (set->vars)
+ .traverse <overlapping_mems*, drop_overlapping_mem_locs> (&coms);
set->traversed_vars = NULL;
}
@@ -2701,7 +2710,7 @@ static int
variable_union (variable src, dataflow_set *set)
{
variable dst;
- void **dstp;
+ variable_def **dstp;
int i, j, k;
dstp = shared_hash_find_slot (set->vars, src->dv);
@@ -2719,7 +2728,7 @@ variable_union (variable src, dataflow_set *set)
return 1;
}
else
- dst = (variable) *dstp;
+ dst = *dstp;
gcc_assert (src->n_var_parts);
gcc_checking_assert (src->onepart == dst->onepart);
@@ -2753,7 +2762,7 @@ variable_union (variable src, dataflow_set *set)
{
dstp = unshare_variable (set, dstp, dst,
VAR_INIT_STATUS_INITIALIZED);
- dst = (variable)*dstp;
+ dst = *dstp;
goto restart_onepart_unshared;
}
@@ -2806,7 +2815,7 @@ variable_union (variable src, dataflow_set *set)
if (dst->n_var_parts != k && shared_var_p (dst, set->vars))
{
dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
- dst = (variable)*dstp;
+ dst = *dstp;
}
i = src->n_var_parts - 1;
@@ -3081,10 +3090,11 @@ dataflow_set_union (dataflow_set *dst, dataflow_set *src)
}
else
{
- htab_iterator hi;
+ variable_iterator_type hi;
variable var;
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (src->vars), var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (src->vars),
+ var, variable, hi)
variable_union (var, dst);
}
}
@@ -3147,7 +3157,7 @@ dv_changed_p (decl_or_value dv)
be in star-canonical form. */
static location_chain
-find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
+find_loc_in_1pdv (rtx loc, variable var, variable_table_type vars)
{
location_chain node;
enum rtx_code loc_code;
@@ -3204,7 +3214,7 @@ find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
gcc_checking_assert (!node->next);
dv = dv_from_value (node->loc);
- rvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ rvar = vars.find_with_hash (dv, dv_htab_hash (dv));
return find_loc_in_1pdv (loc, rvar, vars);
}
@@ -3520,10 +3530,11 @@ loc_cmp (rtx x, rtx y)
#if ENABLE_CHECKING
/* Check the order of entries in one-part variables. */
-static int
-canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+canonicalize_loc_order_check (variable_def **slot,
+ dataflow_set *data ATTRIBUTE_UNUSED)
{
- variable var = (variable) *slot;
+ variable var = *slot;
location_chain node, next;
#ifdef ENABLE_RTL_CHECKING
@@ -3555,11 +3566,10 @@ canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED)
Ensure less likely values can reach more likely neighbors, making
the connections bidirectional. */
-static int
-canonicalize_values_mark (void **slot, void *data)
+int
+canonicalize_values_mark (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *)data;
- variable var = (variable) *slot;
+ variable var = *slot;
decl_or_value dv = var->dv;
rtx val;
location_chain node;
@@ -3579,7 +3589,8 @@ canonicalize_values_mark (void **slot, void *data)
else
{
decl_or_value odv = dv_from_value (node->loc);
- void **oslot = shared_hash_find_slot_noinsert (set->vars, odv);
+ variable_def **oslot;
+ oslot = shared_hash_find_slot_noinsert (set->vars, odv);
set_slot_part (set, val, oslot, odv, 0,
node->init, NULL_RTX);
@@ -3594,16 +3605,15 @@ canonicalize_values_mark (void **slot, void *data)
/* Remove redundant entries from equivalence lists in onepart
variables, canonicalizing equivalence sets into star shapes. */
-static int
-canonicalize_values_star (void **slot, void *data)
+int
+canonicalize_values_star (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *)data;
- variable var = (variable) *slot;
+ variable var = *slot;
decl_or_value dv = var->dv;
location_chain node;
decl_or_value cdv;
rtx val, cval;
- void **cslot;
+ variable_def **cslot;
bool has_value;
bool has_marks;
@@ -3669,7 +3679,7 @@ canonicalize_values_star (void **slot, void *data)
clobber_variable_part (set, NULL, var->dv, 0, NULL);
return 1;
}
- var = (variable)*slot;
+ var = *slot;
gcc_assert (dv_is_value_p (var->dv));
if (var->n_var_parts == 0)
return 1;
@@ -3799,7 +3809,7 @@ canonicalize_values_star (void **slot, void *data)
slot = clobber_slot_part (set, cval, slot, 0, NULL);
/* Variable may have been unshared. */
- var = (variable)*slot;
+ var = *slot;
gcc_checking_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval
&& var->var_part[0].loc_chain->next == NULL);
@@ -3816,16 +3826,15 @@ canonicalize_values_star (void **slot, void *data)
have determined or even seen the canonical value of a set when we
get to a variable that references another member of the set. */
-static int
-canonicalize_vars_star (void **slot, void *data)
+int
+canonicalize_vars_star (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *)data;
- variable var = (variable) *slot;
+ variable var = *slot;
decl_or_value dv = var->dv;
location_chain node;
rtx cval;
decl_or_value cdv;
- void **cslot;
+ variable_def **cslot;
variable cvar;
location_chain cnode;
@@ -3847,7 +3856,7 @@ canonicalize_vars_star (void **slot, void *data)
cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
if (!cslot)
return 1;
- cvar = (variable)*cslot;
+ cvar = *cslot;
gcc_assert (cvar->n_var_parts == 1);
cnode = cvar->var_part[0].loc_chain;
@@ -3879,7 +3888,7 @@ static int
variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
{
dataflow_set *dst = dsm->dst;
- void **dstslot;
+ variable_def **dstslot;
variable s2var, dvar = NULL;
decl_or_value dv = s1var->dv;
onepart_enum_t onepart = s1var->onepart;
@@ -3919,7 +3928,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
if (dstslot)
{
- dvar = (variable)*dstslot;
+ dvar = *dstslot;
gcc_assert (dvar->refcount == 1
&& dvar->onepart == onepart
&& dvar->n_var_parts == 1);
@@ -4017,8 +4026,8 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
nodep = nextp;
}
- if (dvar != (variable)*dstslot)
- dvar = (variable)*dstslot;
+ if (dvar != *dstslot)
+ dvar = *dstslot;
nodep = &dvar->var_part[0].loc_chain;
if (val)
@@ -4040,7 +4049,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
gcc_checking_assert (dstslot
== shared_hash_find_slot_noinsert_1 (dst->vars,
dv, dvhash));
- dvar = (variable)*dstslot;
+ dvar = *dstslot;
}
else
{
@@ -4076,7 +4085,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
if (GET_CODE (node->loc) == VALUE)
{
decl_or_value dv = dv_from_value (node->loc);
- void **slot = NULL;
+ variable_def **slot = NULL;
if (shared_hash_shared (dst->vars))
slot = shared_hash_find_slot_noinsert (dst->vars, dv);
@@ -4108,7 +4117,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
gcc_checking_assert (dstslot
== shared_hash_find_slot_noinsert_1 (dst->vars,
dv, dvhash));
- dvar = (variable)*dstslot;
+ dvar = *dstslot;
}
}
@@ -4144,7 +4153,7 @@ variable_merge_over_src (variable s2var, struct dfset_merge *dsm)
if (!s2var->onepart)
{
- void **dstp = shared_hash_find_slot (dst->vars, dv);
+ variable_def **dstp = shared_hash_find_slot (dst->vars, dv);
*dstp = s2var;
s2var->refcount++;
return 1;
@@ -4165,19 +4174,17 @@ dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
struct dfset_merge dsm;
int i;
size_t src1_elems, src2_elems;
- htab_iterator hi;
+ variable_iterator_type hi;
variable var;
- src1_elems = htab_elements (shared_hash_htab (src1->vars));
- src2_elems = htab_elements (shared_hash_htab (src2->vars));
+ src1_elems = shared_hash_htab (src1->vars).elements ();
+ src2_elems = shared_hash_htab (src2->vars).elements ();
dataflow_set_init (dst);
dst->stack_adjust = cur.stack_adjust;
shared_hash_destroy (dst->vars);
dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
dst->vars->refcount = 1;
- dst->vars->htab
- = htab_create (MAX (src1_elems, src2_elems), variable_htab_hash,
- variable_htab_eq, variable_htab_free);
+ dst->vars->htab.create (MAX (src1_elems, src2_elems));
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);
@@ -4187,9 +4194,11 @@ dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
dsm.cur = src1;
dsm.src_onepart_cnt = 0;
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.src->vars), var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.src->vars),
+ var, variable, hi)
variable_merge_over_src (var, &dsm);
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.cur->vars), var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.cur->vars),
+ var, variable, hi)
variable_merge_over_cur (var, &dsm);
if (dsm.src_onepart_cnt)
@@ -4259,7 +4268,7 @@ dataflow_set_equiv_regs (dataflow_set *set)
if (list->offset == 0 && dv_onepart_p (list->dv))
{
rtx cval = canon[(int)GET_MODE (list->loc)];
- void **slot;
+ variable_def **slot;
if (!cval)
continue;
@@ -4330,12 +4339,11 @@ struct dfset_post_merge
/* Create values for incoming expressions associated with one-part
variables that don't have value numbers for them. */
-static int
-variable_post_merge_new_vals (void **slot, void *info)
+int
+variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm)
{
- struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
dataflow_set *set = dfpm->set;
- variable var = (variable)*slot;
+ variable var = *slot;
location_chain node;
if (!var->onepart || !var->n_var_parts)
@@ -4360,7 +4368,7 @@ variable_post_merge_new_vals (void **slot, void *info)
{
slot = unshare_variable (set, slot, var,
VAR_INIT_STATUS_INITIALIZED);
- var = (variable)*slot;
+ var = *slot;
goto restart;
}
@@ -4467,12 +4475,11 @@ variable_post_merge_new_vals (void **slot, void *info)
/* Reset values in the permanent set that are not associated with the
chosen expression. */
-static int
-variable_post_merge_perm_vals (void **pslot, void *info)
+int
+variable_post_merge_perm_vals (variable_def **pslot, dfset_post_merge *dfpm)
{
- struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
dataflow_set *set = dfpm->set;
- variable pvar = (variable)*pslot, var;
+ variable pvar = *pslot, var;
location_chain pnode;
decl_or_value dv;
attrs att;
@@ -4536,13 +4543,15 @@ dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
dfpm.set = set;
dfpm.permp = permp;
- htab_traverse (shared_hash_htab (set->vars), variable_post_merge_new_vals,
- &dfpm);
+ shared_hash_htab (set->vars)
+ .traverse <dfset_post_merge*, variable_post_merge_new_vals> (&dfpm);
if (*permp)
- htab_traverse (shared_hash_htab ((*permp)->vars),
- variable_post_merge_perm_vals, &dfpm);
- htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set);
- htab_traverse (shared_hash_htab (set->vars), canonicalize_vars_star, set);
+ shared_hash_htab ((*permp)->vars)
+ .traverse <dfset_post_merge*, variable_post_merge_perm_vals> (&dfpm);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, canonicalize_values_star> (set);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, canonicalize_vars_star> (set);
}
/* Return a node whose loc is a MEM that refers to EXPR in the
@@ -4550,7 +4559,7 @@ dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
any values recursively mentioned in the location lists. */
static location_chain
-find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
+find_mem_expr_in_1pdv (tree expr, rtx val, variable_table_type vars)
{
location_chain node;
decl_or_value dv;
@@ -4564,7 +4573,7 @@ find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
&& !VALUE_RECURSED_INTO (val));
dv = dv_from_value (val);
- var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ var = vars.find_with_hash (dv, dv_htab_hash (dv));
if (!var)
return NULL;
@@ -4621,11 +4630,10 @@ mem_dies_at_call (rtx mem)
one-part variable, except those whose MEM attributes map back to
the variable itself, directly or within a VALUE. */
-static int
-dataflow_set_preserve_mem_locs (void **slot, void *data)
+int
+dataflow_set_preserve_mem_locs (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *) data;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VDECL || var->onepart == ONEPART_DEXPR)
{
@@ -4659,7 +4667,7 @@ dataflow_set_preserve_mem_locs (void **slot, void *data)
return 1;
slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
gcc_assert (var->n_var_parts == 1);
}
@@ -4731,11 +4739,10 @@ dataflow_set_preserve_mem_locs (void **slot, void *data)
/* Remove all MEMs from the location list of a hash table entry for a
value. */
-static int
-dataflow_set_remove_mem_locs (void **slot, void *data)
+int
+dataflow_set_remove_mem_locs (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *) data;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VALUE)
{
@@ -4756,7 +4763,7 @@ dataflow_set_remove_mem_locs (void **slot, void *data)
return 1;
slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
gcc_assert (var->n_var_parts == 1);
}
@@ -4816,11 +4823,11 @@ dataflow_set_clear_at_call (dataflow_set *set)
if (MAY_HAVE_DEBUG_INSNS)
{
set->traversed_vars = set->vars;
- htab_traverse (shared_hash_htab (set->vars),
- dataflow_set_preserve_mem_locs, set);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, dataflow_set_preserve_mem_locs> (set);
set->traversed_vars = set->vars;
- htab_traverse (shared_hash_htab (set->vars), dataflow_set_remove_mem_locs,
- set);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, dataflow_set_remove_mem_locs> (set);
set->traversed_vars = NULL;
}
}
@@ -4919,21 +4926,21 @@ variable_different_p (variable var1, variable var2)
static bool
dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
{
- htab_iterator hi;
+ variable_iterator_type hi;
variable var1;
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)))
+ if (shared_hash_htab (old_set->vars).elements ()
+ != shared_hash_htab (new_set->vars).elements ())
return true;
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (old_set->vars), var1, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (old_set->vars),
+ var1, variable, hi)
{
- htab_t htab = shared_hash_htab (new_set->vars);
- variable var2 = (variable) htab_find_with_hash (htab, var1->dv,
- dv_htab_hash (var1->dv));
+ variable_table_type htab = shared_hash_htab (new_set->vars);
+ variable var2 = htab.find_with_hash (var1->dv, dv_htab_hash (var1->dv));
if (!var2)
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -6843,13 +6850,13 @@ compute_bb_dataflow (basic_block bb)
local_get_addr_cache = NULL;
dataflow_set_equiv_regs (out);
- htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
- out);
- htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
- out);
+ shared_hash_htab (out->vars)
+ .traverse <dataflow_set *, canonicalize_values_mark> (out);
+ shared_hash_htab (out->vars)
+ .traverse <dataflow_set *, canonicalize_values_star> (out);
#if ENABLE_CHECKING
- htab_traverse (shared_hash_htab (out->vars),
- canonicalize_loc_order_check, out);
+ shared_hash_htab (out->vars)
+ .traverse <dataflow_set *, canonicalize_loc_order_check> (out);
#endif
}
changed = dataflow_set_different (&old_out, out);
@@ -6921,12 +6928,10 @@ vt_find_locations (void)
if (VTI (bb)->in.vars)
{
htabsz
- -= (htab_size (shared_hash_htab (VTI (bb)->in.vars))
- + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
- oldinsz
- = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
- oldoutsz
- = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
+ -= shared_hash_htab (VTI (bb)->in.vars).size ()
+ + shared_hash_htab (VTI (bb)->out.vars).size ();
+ oldinsz = shared_hash_htab (VTI (bb)->in.vars).elements ();
+ oldoutsz = shared_hash_htab (VTI (bb)->out.vars).elements ();
}
else
oldinsz = oldoutsz = 0;
@@ -6964,9 +6969,9 @@ vt_find_locations (void)
#if ENABLE_CHECKING
/* Merge and merge_adjust should keep entries in
canonical order. */
- htab_traverse (shared_hash_htab (in->vars),
- canonicalize_loc_order_check,
- in);
+ shared_hash_htab (in->vars)
+ .traverse <dataflow_set *,
+ canonicalize_loc_order_check> (in);
#endif
if (dst_can_be_shared)
{
@@ -6986,8 +6991,8 @@ vt_find_locations (void)
}
changed = compute_bb_dataflow (bb);
- htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars))
- + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
+ htabsz += shared_hash_htab (VTI (bb)->in.vars).size ()
+ + shared_hash_htab (VTI (bb)->out.vars).size ();
if (htabmax && htabsz > htabmax)
{
@@ -7034,9 +7039,9 @@ vt_find_locations (void)
fprintf (dump_file,
"BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
bb->index,
- (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
+ (int)shared_hash_htab (VTI (bb)->in.vars).size (),
oldinsz,
- (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
+ (int)shared_hash_htab (VTI (bb)->out.vars).size (),
oldoutsz,
(int)worklist->nodes, (int)pending->nodes, htabsz);
@@ -7084,10 +7089,10 @@ dump_attrs_list (attrs list)
/* Print the information about variable *SLOT to dump file. */
-static int
-dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+dump_var_tracking_slot (variable_def **slot, void *data ATTRIBUTE_UNUSED)
{
- variable var = (variable) *slot;
+ variable var = *slot;
dump_var (var);
@@ -7143,12 +7148,12 @@ dump_var (variable var)
/* Print the information about variables from hash table VARS to dump file. */
static void
-dump_vars (htab_t vars)
+dump_vars (variable_table_type vars)
{
- if (htab_elements (vars) > 0)
+ if (vars.elements () > 0)
{
fprintf (dump_file, "Variables:\n");
- htab_traverse (vars, dump_var_slot, NULL);
+ vars.traverse <void *, dump_var_tracking_slot> (NULL);
}
}
@@ -7196,18 +7201,17 @@ dump_dataflow_sets (void)
static inline variable
variable_from_dropped (decl_or_value dv, enum insert_option insert)
{
- void **slot;
+ variable_def **slot;
variable empty_var;
onepart_enum_t onepart;
- slot = htab_find_slot_with_hash (dropped_values, dv, dv_htab_hash (dv),
- insert);
+ slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv), insert);
if (!slot)
return NULL;
if (*slot)
- return (variable) *slot;
+ return *slot;
gcc_checking_assert (insert == INSERT);
@@ -7267,18 +7271,16 @@ variable_was_changed (variable var, dataflow_set *set)
if (emit_notes)
{
- void **slot;
+ variable_def **slot;
/* Remember this decl or VALUE has been added to changed_variables. */
set_dv_changed (var->dv, true);
- slot = htab_find_slot_with_hash (changed_variables,
- var->dv,
- hash, INSERT);
+ slot = changed_variables.find_slot_with_hash (var->dv, hash, INSERT);
if (*slot)
{
- variable old_var = (variable) *slot;
+ variable old_var = *slot;
gcc_assert (old_var->in_changed_variables);
old_var->in_changed_variables = false;
if (var != old_var && var->onepart)
@@ -7297,14 +7299,14 @@ variable_was_changed (variable var, dataflow_set *set)
{
onepart_enum_t onepart = var->onepart;
variable empty_var = NULL;
- void **dslot = NULL;
+ variable_def **dslot = NULL;
if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR)
{
- dslot = htab_find_slot_with_hash (dropped_values, var->dv,
+ dslot = dropped_values.find_slot_with_hash (var->dv,
dv_htab_hash (var->dv),
INSERT);
- empty_var = (variable) *dslot;
+ empty_var = *dslot;
if (empty_var)
{
@@ -7359,7 +7361,7 @@ variable_was_changed (variable var, dataflow_set *set)
gcc_assert (set);
if (var->n_var_parts == 0)
{
- void **slot;
+ variable_def **slot;
drop_var:
slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
@@ -7368,7 +7370,7 @@ variable_was_changed (variable var, dataflow_set *set)
if (shared_hash_shared (set->vars))
slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
NO_INSERT);
- htab_clear_slot (shared_hash_htab (set->vars), slot);
+ shared_hash_htab (set->vars).clear_slot (slot);
}
}
}
@@ -7418,8 +7420,8 @@ find_variable_location_part (variable var, HOST_WIDE_INT offset,
return -1;
}
-static void **
-set_slot_part (dataflow_set *set, rtx loc, void **slot,
+static variable_def **
+set_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
decl_or_value dv, HOST_WIDE_INT offset,
enum var_init_status initialized, rtx set_src)
{
@@ -7429,7 +7431,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
variable var;
onepart_enum_t onepart;
- var = (variable) *slot;
+ var = *slot;
if (var)
onepart = var->onepart;
@@ -7552,7 +7554,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
if (shared_var_p (var, set->vars))
{
slot = unshare_variable (set, slot, var, initialized);
- var = (variable)*slot;
+ var = *slot;
for (nextp = &var->var_part[0].loc_chain; c;
nextp = &(*nextp)->next)
c--;
@@ -7591,7 +7593,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
if (shared_var_p (var, set->vars))
{
slot = unshare_variable (set, slot, var, initialized);
- var = (variable)*slot;
+ var = *slot;
}
}
}
@@ -7603,7 +7605,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
if (shared_var_p (var, set->vars))
{
slot = unshare_variable (set, slot, var, initialized);
- var = (variable)*slot;
+ var = *slot;
}
/* We track only variables whose size is <= MAX_VAR_PARTS bytes
@@ -7678,7 +7680,7 @@ set_variable_part (dataflow_set *set, rtx loc,
enum var_init_status initialized, rtx set_src,
enum insert_option iopt)
{
- void **slot;
+ variable_def **slot;
if (iopt == NO_INSERT)
slot = shared_hash_find_slot_noinsert (set->vars, dv);
@@ -7696,11 +7698,11 @@ set_variable_part (dataflow_set *set, rtx loc,
The variable part is specified by variable's declaration or value
DV and offset OFFSET. */
-static void **
-clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
+static variable_def **
+clobber_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
HOST_WIDE_INT offset, rtx set_src)
{
- variable var = (variable) *slot;
+ variable var = *slot;
int pos = find_variable_location_part (var, offset, NULL);
if (pos >= 0)
@@ -7759,7 +7761,7 @@ static void
clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
HOST_WIDE_INT offset, rtx set_src)
{
- void **slot;
+ variable_def **slot;
if (!dv_as_opaque (dv)
|| (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
@@ -7776,11 +7778,11 @@ clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
variable part is specified by its SET->vars slot SLOT and offset
OFFSET and the part's location by LOC. */
-static void **
-delete_slot_part (dataflow_set *set, rtx loc, void **slot,
+static variable_def **
+delete_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
HOST_WIDE_INT offset)
{
- variable var = (variable) *slot;
+ variable var = *slot;
int pos = find_variable_location_part (var, offset, NULL);
if (pos >= 0)
@@ -7803,7 +7805,7 @@ delete_slot_part (dataflow_set *set, rtx loc, void **slot,
{
slot = unshare_variable (set, slot, var,
VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
break;
}
}
@@ -7867,7 +7869,7 @@ static void
delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
HOST_WIDE_INT offset)
{
- void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
+ variable_def **slot = shared_hash_find_slot_noinsert (set->vars, dv);
if (!slot)
return;
@@ -7880,7 +7882,7 @@ delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
struct expand_loc_callback_data
{
/* The variables and values active at this point. */
- htab_t vars;
+ variable_table_type vars;
/* Stack of values and debug_exprs under expansion, and their
children. */
@@ -7969,7 +7971,7 @@ loc_exp_dep_clear (variable var)
back-links in VARS. */
static void
-loc_exp_insert_dep (variable var, rtx x, htab_t vars)
+loc_exp_insert_dep (variable var, rtx x, variable_table_type vars)
{
decl_or_value dv;
variable xvar;
@@ -7979,7 +7981,7 @@ loc_exp_insert_dep (variable var, rtx x, htab_t vars)
/* ??? Build a vector of variables parallel to EXPANDING, to avoid
an additional look up? */
- xvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ xvar = vars.find_with_hash (dv, dv_htab_hash (dv));
if (!xvar)
{
@@ -8019,7 +8021,8 @@ loc_exp_insert_dep (variable var, rtx x, htab_t vars)
true if we found any pending-recursion results. */
static bool
-loc_exp_dep_set (variable var, rtx result, rtx *value, int count, htab_t vars)
+loc_exp_dep_set (variable var, rtx result, rtx *value, int count,
+ variable_table_type vars)
{
bool pending_recursion = false;
@@ -8048,7 +8051,7 @@ loc_exp_dep_set (variable var, rtx result, rtx *value, int count, htab_t vars)
attempt to compute a current location. */
static void
-notify_dependents_of_resolved_value (variable ivar, htab_t vars)
+notify_dependents_of_resolved_value (variable ivar, variable_table_type vars)
{
loc_exp_dep *led, *next;
@@ -8086,7 +8089,7 @@ notify_dependents_of_resolved_value (variable ivar, htab_t vars)
continue;
}
- var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ var = vars.find_with_hash (dv, dv_htab_hash (dv));
if (!var)
var = variable_from_dropped (dv, NO_INSERT);
@@ -8330,7 +8333,7 @@ vt_expand_loc_callback (rtx x, bitmap regs,
return NULL;
}
- var = (variable) htab_find_with_hash (elcd->vars, dv, dv_htab_hash (dv));
+ var = elcd->vars.find_with_hash (dv, dv_htab_hash (dv));
if (!var)
{
@@ -8439,7 +8442,7 @@ resolve_expansions_pending_recursion (vec<rtx, va_stack> pending)
equivalences in VARS, updating their CUR_LOCs in the process. */
static rtx
-vt_expand_loc (rtx loc, htab_t vars)
+vt_expand_loc (rtx loc, variable_table_type vars)
{
struct expand_loc_callback_data data;
rtx result;
@@ -8461,7 +8464,7 @@ vt_expand_loc (rtx loc, htab_t vars)
in VARS, updating their CUR_LOCs in the process. */
static rtx
-vt_expand_1pvar (variable var, htab_t vars)
+vt_expand_1pvar (variable var, variable_table_type vars)
{
struct expand_loc_callback_data data;
rtx loc;
@@ -8486,13 +8489,13 @@ vt_expand_1pvar (variable var, htab_t vars)
additional parameters: WHERE specifies whether the note shall be emitted
before or after instruction INSN. */
-static int
-emit_note_insn_var_location (void **varp, void *data)
+int
+emit_note_insn_var_location (variable_def **varp, emit_note_data *data)
{
- variable var = (variable) *varp;
- rtx insn = ((emit_note_data *)data)->insn;
- enum emit_note_where where = ((emit_note_data *)data)->where;
- htab_t vars = ((emit_note_data *)data)->vars;
+ variable var = *varp;
+ rtx insn = data->insn;
+ enum emit_note_where where = data->where;
+ variable_table_type vars = data->vars;
rtx note, note_vl;
int i, j, n_var_parts;
bool complete;
@@ -8709,7 +8712,7 @@ emit_note_insn_var_location (void **varp, void *data)
set_dv_changed (var->dv, false);
gcc_assert (var->in_changed_variables);
var->in_changed_variables = false;
- htab_clear_slot (changed_variables, varp);
+ changed_variables.clear_slot (varp);
/* Continue traversing the hash table. */
return 1;
@@ -8718,11 +8721,11 @@ emit_note_insn_var_location (void **varp, void *data)
/* While traversing changed_variables, push onto DATA (a stack of RTX
values) entries that aren't user variables. */
-static int
-values_to_stack (void **slot, void *data)
+int
+var_track_values_to_stack (variable_def **slot,
+ vec<rtx, va_stack> *changed_values_stack)
{
- vec<rtx, va_stack> *changed_values_stack = (vec<rtx, va_stack> *) data;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VALUE)
changed_values_stack->safe_push (dv_as_value (var->dv));
@@ -8738,14 +8741,14 @@ static void
remove_value_from_changed_variables (rtx val)
{
decl_or_value dv = dv_from_rtx (val);
- void **slot;
+ variable_def **slot;
variable var;
- slot = htab_find_slot_with_hash (changed_variables,
- dv, dv_htab_hash (dv), NO_INSERT);
- var = (variable) *slot;
+ slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv),
+ NO_INSERT);
+ var = *slot;
var->in_changed_variables = false;
- htab_clear_slot (changed_variables, slot);
+ changed_variables.clear_slot (slot);
}
/* If VAL (a value or debug_expr) has backlinks to variables actively
@@ -8754,23 +8757,22 @@ remove_value_from_changed_variables (rtx val)
have dependencies of their own to notify. */
static void
-notify_dependents_of_changed_value (rtx val, htab_t htab,
+notify_dependents_of_changed_value (rtx val, variable_table_type htab,
vec<rtx, va_stack> *changed_values_stack)
{
- void **slot;
+ variable_def **slot;
variable var;
loc_exp_dep *led;
decl_or_value dv = dv_from_rtx (val);
- slot = htab_find_slot_with_hash (changed_variables,
- dv, dv_htab_hash (dv), NO_INSERT);
+ slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv),
+ NO_INSERT);
if (!slot)
- slot = htab_find_slot_with_hash (htab,
- dv, dv_htab_hash (dv), NO_INSERT);
+ slot = htab.find_slot_with_hash (dv, dv_htab_hash (dv), NO_INSERT);
if (!slot)
- slot = htab_find_slot_with_hash (dropped_values,
- dv, dv_htab_hash (dv), NO_INSERT);
- var = (variable) *slot;
+ slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv),
+ NO_INSERT);
+ var = *slot;
while ((led = VAR_LOC_DEP_LST (var)))
{
@@ -8800,14 +8802,14 @@ notify_dependents_of_changed_value (rtx val, htab_t htab,
break;
case ONEPART_VDECL:
- ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
+ ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv));
gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
variable_was_changed (ivar, NULL);
break;
case NOT_ONEPART:
pool_free (loc_exp_dep_pool, led);
- ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
+ ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv));
if (ivar)
{
int i = ivar->n_var_parts;
@@ -8837,7 +8839,7 @@ notify_dependents_of_changed_value (rtx val, htab_t htab,
CHANGED_VARIABLES. */
static void
-process_changed_values (htab_t htab)
+process_changed_values (variable_table_type htab)
{
int i, n;
rtx val;
@@ -8846,7 +8848,9 @@ process_changed_values (htab_t htab)
vec_stack_alloc (rtx, changed_values_stack, 20);
/* Move values from changed_variables to changed_values_stack. */
- htab_traverse (changed_variables, values_to_stack, &changed_values_stack);
+ changed_variables
+ .traverse <vec<rtx, va_stack>*, var_track_values_to_stack>
+ (&changed_values_stack);
/* Back-propagate change notifications in values while popping
them from the stack. */
@@ -8879,9 +8883,9 @@ emit_notes_for_changes (rtx insn, enum emit_note_where where,
shared_hash vars)
{
emit_note_data data;
- htab_t htab = shared_hash_htab (vars);
+ variable_table_type htab = shared_hash_htab (vars);
- if (!htab_elements (changed_variables))
+ if (!changed_variables.elements ())
return;
if (MAY_HAVE_DEBUG_INSNS)
@@ -8891,21 +8895,20 @@ emit_notes_for_changes (rtx insn, enum emit_note_where where,
data.where = where;
data.vars = htab;
- htab_traverse (changed_variables, emit_note_insn_var_location, &data);
+ changed_variables
+ .traverse <emit_note_data*, emit_note_insn_var_location> (&data);
}
/* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
same variable in hash table DATA or is not there at all. */
-static int
-emit_notes_for_differences_1 (void **slot, void *data)
+int
+emit_notes_for_differences_1 (variable_def **slot, variable_table_type new_vars)
{
- htab_t new_vars = (htab_t) data;
variable old_var, new_var;
- old_var = (variable) *slot;
- new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
- dv_htab_hash (old_var->dv));
+ old_var = *slot;
+ new_var = new_vars.find_with_hash (old_var->dv, dv_htab_hash (old_var->dv));
if (!new_var)
{
@@ -8971,15 +8974,13 @@ emit_notes_for_differences_1 (void **slot, void *data)
/* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
table DATA. */
-static int
-emit_notes_for_differences_2 (void **slot, void *data)
+int
+emit_notes_for_differences_2 (variable_def **slot, variable_table_type old_vars)
{
- htab_t old_vars = (htab_t) data;
variable old_var, new_var;
- new_var = (variable) *slot;
- old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
- dv_htab_hash (new_var->dv));
+ new_var = *slot;
+ old_var = old_vars.find_with_hash (new_var->dv, dv_htab_hash (new_var->dv));
if (!old_var)
{
int i;
@@ -8999,12 +9000,12 @@ static void
emit_notes_for_differences (rtx insn, dataflow_set *old_set,
dataflow_set *new_set)
{
- 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));
+ shared_hash_htab (old_set->vars)
+ .traverse <variable_table_type, emit_notes_for_differences_1>
+ (shared_hash_htab (new_set->vars));
+ shared_hash_htab (new_set->vars)
+ .traverse <variable_table_type, emit_notes_for_differences_2>
+ (shared_hash_htab (old_set->vars));
emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
}
@@ -9359,7 +9360,7 @@ vt_emit_notes (void)
basic_block bb;
dataflow_set cur;
- gcc_assert (!htab_elements (changed_variables));
+ gcc_assert (!changed_variables.elements ());
/* Free memory occupied by the out hash tables, as they aren't used
anymore. */
@@ -9372,9 +9373,7 @@ vt_emit_notes (void)
if (MAY_HAVE_DEBUG_INSNS)
{
- dropped_values = htab_create (cselib_get_next_uid () * 2,
- variable_htab_hash, variable_htab_eq,
- variable_htab_free);
+ dropped_values.create (cselib_get_next_uid () * 2);
loc_exp_dep_pool = create_alloc_pool ("loc_exp_dep pool",
sizeof (loc_exp_dep), 64);
}
@@ -9402,14 +9401,14 @@ vt_emit_notes (void)
dataflow_set_clear (&VTI (bb)->in);
}
#ifdef ENABLE_CHECKING
- htab_traverse (shared_hash_htab (cur.vars),
- emit_notes_for_differences_1,
- shared_hash_htab (empty_shared_hash));
+ shared_hash_htab (cur.vars)
+ .traverse <variable_table_type, emit_notes_for_differences_1>
+ (shared_hash_htab (empty_shared_hash));
#endif
dataflow_set_destroy (&cur);
if (MAY_HAVE_DEBUG_INSNS)
- htab_delete (dropped_values);
+ dropped_values.dispose ();
emit_notes = false;
}
@@ -9745,11 +9744,8 @@ vt_initialize (void)
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,
- variable_htab_free);
+ empty_shared_hash->htab.create (1);
+ changed_variables.create (10);
/* Init the IN and OUT sets. */
FOR_ALL_BB (bb)
@@ -10102,8 +10098,8 @@ vt_finalize (void)
}
}
free_aux_for_blocks ();
- htab_delete (empty_shared_hash->htab);
- htab_delete (changed_variables);
+ empty_shared_hash->htab.dispose ();
+ changed_variables.dispose ();
free_alloc_pool (attrs_pool);
free_alloc_pool (var_pool);
free_alloc_pool (loc_chain_pool);