aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2002-11-04 19:00:26 +0000
committerGeoffrey Keating <geoffk@apple.com>2002-11-04 19:00:26 +0000
commit92a019b57f2a61311b796d08e7c5df1210149bd5 (patch)
treef921b74e09ca70de19caed229173afb074e01504
parentaa34836eb675ae4789fc9712ab2f5dbbfffc0612 (diff)
Index: ChangeLog
2002-11-01 Geoffrey Keating <geoffk@apple.com> * gengtype.c (adjust_field_rtx_def): Don't use skip on valid fields. (write_array): Remove warning. * gengtype.c (contains_scalar_p): New. (finish_root_table): Add the table to all languages, even if it's empty. (write_roots): Output gt_pch_scalar_rtab. * ggc-common.c (gt_pch_save): Write out scalars. (gt_pch_restore): Read scalars back. * ggc-page.c (OBJECTS_IN_PAGE): New macro. (struct page_entry): Delete pch_page field. (ggc_recalculate_in_use_p): Use OBJECTS_IN_PAGE. (clear_marks): Likewise. (sweep_pages): Likewise. (poison_pages): Likewise. (ggc_print_statistics): Likewise. (ggc_pch_read): Don't free objects read from a PCH. Properly set up in_use_p and page_tails. Index: testsuite/ChangeLog 2002-11-01 Geoffrey Keating <geoffk@apple.com> * common-1.c: New. * common-1.h: New. * decl-1.c: New. * decl-1.h: New. * decl-2.c: New. * decl-2.h: New. * decl-3.c: New. * decl-3.h: New. * decl-4.c: New. * decl-4.h: New. * decl-5.c: New. * decl-5.h: New. * global-1.c: New. * global-1.h: New. * inline-1.c: New. * inline-1.h: New. * inline-2.c: New. * inline-2.h: New. * static-1.c: New. * static-1.h: New. * static-2.c: New. * static-2.h: New. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/pch-branch@58798 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/gengtype.c100
-rw-r--r--gcc/ggc-common.c12
-rw-r--r--gcc/ggc-page.c69
-rw-r--r--gcc/testsuite/ChangeLog25
-rw-r--r--gcc/testsuite/gcc.dg/pch/common-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pch/common-1.h3
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-1.h1
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-2.h3
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-3.c12
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-3.h3
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-4.c10
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-4.h7
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-5.c3
-rw-r--r--gcc/testsuite/gcc.dg/pch/decl-5.h1
-rw-r--r--gcc/testsuite/gcc.dg/pch/global-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/pch/global-1.h1
-rw-r--r--gcc/testsuite/gcc.dg/pch/inline-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/pch/inline-1.h5
-rw-r--r--gcc/testsuite/gcc.dg/pch/inline-2.c13
-rw-r--r--gcc/testsuite/gcc.dg/pch/inline-2.h5
-rw-r--r--gcc/testsuite/gcc.dg/pch/static-1.c7
-rw-r--r--gcc/testsuite/gcc.dg/pch/static-1.h5
-rw-r--r--gcc/testsuite/gcc.dg/pch/static-2.c7
-rw-r--r--gcc/testsuite/gcc.dg/pch/static-2.h5
27 files changed, 300 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e038f725f5a..90a0e741e00 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2002-11-04 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (adjust_field_rtx_def): Don't use skip on valid fields.
+ (write_array): Remove warning.
+
+ * gengtype.c (contains_scalar_p): New.
+ (finish_root_table): Add the table to all languages, even if it's
+ empty.
+ (write_roots): Output gt_pch_scalar_rtab.
+ * ggc-common.c (gt_pch_save): Write out scalars.
+ (gt_pch_restore): Read scalars back.
+
+ * ggc-page.c (OBJECTS_IN_PAGE): New macro.
+ (struct page_entry): Delete pch_page field.
+ (ggc_recalculate_in_use_p): Use OBJECTS_IN_PAGE.
+ (clear_marks): Likewise.
+ (sweep_pages): Likewise.
+ (poison_pages): Likewise.
+ (ggc_print_statistics): Likewise.
+ (ggc_pch_read): Don't free objects read from a PCH.
+ Properly set up in_use_p and page_tails.
+
2002-10-25 Geoffrey Keating <geoffk@apple.com>
* gengtype.c (struct write_types_data): New.
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 116b1894716..29b3e4abe8a 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -600,14 +600,6 @@ adjust_field_rtx_def (t, opt)
subfields->opt->name = "skip";
subfields->opt->info = NULL;
}
- else if ((size_t) rtx_next[i] == aindex)
- {
- /* The 'next' field will be marked by the chain_next option. */
- subfields->opt = xmalloc (sizeof (*subfields->opt));
- subfields->opt->next = nodot;
- subfields->opt->name = "skip";
- subfields->opt->info = NULL;
- }
else
subfields->opt = nodot;
}
@@ -1404,6 +1396,7 @@ static void write_local_func_for_structure
static void write_local PARAMS ((type_p structures,
type_p param_structs));
static void write_enum_defn PARAMS ((type_p structures, type_p param_structs));
+static int contains_scalar_p PARAMS ((type_p t));
static void put_mangled_filename PARAMS ((outf_p , const char *));
static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
const char *tname, const char *lastname,
@@ -2376,6 +2369,25 @@ write_enum_defn (structures, param_structs)
oprintf (header_file, "};\n");
}
+/* Might T contain any non-pointer elements? */
+
+static int
+contains_scalar_p (t)
+ type_p t;
+{
+ switch (t->kind)
+ {
+ case TYPE_STRING:
+ case TYPE_POINTER:
+ return 0;
+ case TYPE_ARRAY:
+ return contains_scalar_p (t->u.a.p);
+ default:
+ /* Could also check for structures that have no non-pointer
+ fields, but there aren't enough of those to worry about. */
+ return 1;
+ }
+}
/* Mangle FN and print it to F. */
@@ -2405,7 +2417,6 @@ finish_root_table (flp, pfx, lastname, tname, name)
const char *name;
{
struct flist *fli2;
- unsigned started_bitmap = 0;
for (fli2 = flp; fli2; fli2 = fli2->next)
if (fli2->started_p)
@@ -2430,6 +2441,15 @@ finish_root_table (flp, pfx, lastname, tname, name)
oprintf (base_files[fnum], "[];\n");
}
}
+
+ {
+ int fnum;
+ for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
+ oprintf (base_files [fnum],
+ "const struct %s * const %s[] = {\n",
+ tname, name);
+ }
+
for (fli2 = flp; fli2; fli2 = fli2->next)
if (fli2->started_p)
@@ -2442,13 +2462,6 @@ finish_root_table (flp, pfx, lastname, tname, name)
for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
if (bitmap & 1)
{
- if (! (started_bitmap & (1 << fnum)))
- {
- oprintf (base_files [fnum],
- "const struct %s * const %s[] = {\n",
- tname, name);
- started_bitmap |= 1 << fnum;
- }
oprintf (base_files[fnum], " gt_%s_", pfx);
put_mangled_filename (base_files[fnum], fli2->name);
oprintf (base_files[fnum], ",\n");
@@ -2456,15 +2469,12 @@ finish_root_table (flp, pfx, lastname, tname, name)
}
{
- unsigned bitmap;
int fnum;
-
- for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
- if (bitmap & 1)
- {
- oprintf (base_files[fnum], " NULL\n");
- oprintf (base_files[fnum], "};\n");
- }
+ for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
+ {
+ oprintf (base_files[fnum], " NULL\n");
+ oprintf (base_files[fnum], "};\n");
+ }
}
}
@@ -2634,6 +2644,7 @@ write_array (f, v, wtd)
const struct write_types_data *wtd;
{
struct walk_type_data d;
+ char *prevval3;
memset (&d, 0, sizeof (d));
d.of = f;
@@ -2644,7 +2655,7 @@ write_array (f, v, wtd)
d.bitmap = get_base_file_bitmap (v->line.file);
d.param = NULL;
- d.prev_val[3] = xasprintf ("&%s", v->name);
+ d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
if (wtd->param_prefix)
{
@@ -2673,7 +2684,7 @@ write_array (f, v, wtd)
d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
d.process_field = write_types_process_field;
walk_type (v->type, &d);
- free (d.prev_val[3]);
+ free (prevval3);
oprintf (f, "}\n\n");
}
@@ -2887,6 +2898,43 @@ write_roots (variables)
finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
"gt_pch_cache_rtab");
+
+ for (v = variables; v; v = v->next)
+ {
+ outf_p f = get_output_file_with_visibility (v->line.file);
+ struct flist *fli;
+ int skip_p = 0;
+ options_p o;
+
+ for (o = v->opt; o; o = o->next)
+ if (strcmp (o->name, "deletable") == 0
+ || strcmp (o->name, "if_marked") == 0)
+ skip_p = 1;
+
+ if (skip_p)
+ continue;
+
+ if (! contains_scalar_p (v->type))
+ continue;
+
+ for (fli = flp; fli; fli = fli->next)
+ if (fli->f == f)
+ break;
+ if (! fli->started_p)
+ {
+ fli->started_p = 1;
+
+ oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
+ put_mangled_filename (f, v->line.file);
+ oprintf (f, "[] = {\n");
+ }
+
+ oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
+ v->name, v->name);
+ }
+
+ finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+ "gt_pch_scalar_rtab");
}
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 4576abce573..db7cece5e2d 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -425,6 +425,12 @@ gt_pch_save (f)
htab_traverse (saving_htab, call_alloc, &state);
qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data);
+ /* Write out all the scalar variables. */
+ for (rt = gt_pch_scalar_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ if (fwrite (rti->base, rti->stride, 1, f) != 1)
+ fatal_io_error ("can't write PCH file");
+
/* Write out all the global pointers, after translation. */
write_pch_globals (gt_ggc_rtab, &state);
write_pch_globals (gt_pch_cache_rtab, &state);
@@ -490,6 +496,12 @@ gt_pch_restore (f)
for (rti = *rt; rti->base != NULL; rti++)
memset (rti->base, 0, rti->stride);
+ /* Read in all the scalar variables. */
+ for (rt = gt_pch_scalar_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ if (fread (rti->base, rti->stride, 1, f) != 1)
+ fatal_io_error ("can't read PCH file");
+
/* Read in all the global pointers, in 6 easy loops. */
for (rt = gt_ggc_rtab; *rt; rt++)
for (rti = *rt; rti->base != NULL; rti++)
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index 9912f58e065..a0ddcdc20b2 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -155,6 +155,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
the indicated ORDER. */
#define OBJECTS_PER_PAGE(ORDER) objects_per_page_table[ORDER]
+/* The number of objects in P. */
+#define OBJECTS_IN_PAGE(P) ((P)->bytes / OBJECT_SIZE ((P)->order))
+
/* The size of an object on a page of the indicated ORDER. */
#define OBJECT_SIZE(ORDER) object_size_table[ORDER]
@@ -275,9 +278,6 @@ typedef struct page_entry
/* The lg of size of objects allocated from this page. */
unsigned char order;
- /* Nonzero if the objects on this page never get freed. */
- unsigned char pch_page;
-
/* A bit vector indicating whether or not objects are in use. The
Nth bit is one if the Nth object on this page is allocated. This
array is dynamically sized. */
@@ -1232,7 +1232,7 @@ ggc_recalculate_in_use_p (p)
/* Because the past-the-end bit in in_use_p is always set, we
pretend there is one additional object. */
- num_objects = OBJECTS_PER_PAGE (p->order) + 1;
+ num_objects = OBJECTS_IN_PAGE (p) + 1;
/* Reset the free object count. */
p->num_free_objects = num_objects;
@@ -1301,12 +1301,13 @@ clear_marks ()
for (order = 2; order < NUM_ORDERS; order++)
{
- size_t num_objects = OBJECTS_PER_PAGE (order);
- size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
page_entry *p;
for (p = G.pages[order]; p != NULL; p = p->next)
{
+ size_t num_objects = OBJECTS_IN_PAGE (p);
+ size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
+
#ifdef ENABLE_CHECKING
/* The data should be page-aligned. */
if ((size_t) p->page & (G.pagesize - 1))
@@ -1349,7 +1350,7 @@ sweep_pages ()
placed at the end of the list. */
page_entry * const last = G.page_tails[order];
- size_t num_objects = OBJECTS_PER_PAGE (order);
+ size_t num_objects;
size_t live_objects;
page_entry *p, *previous;
int done;
@@ -1365,6 +1366,8 @@ sweep_pages ()
/* Loop until all entries have been examined. */
done = (p == last);
+
+ num_objects = OBJECTS_IN_PAGE (p);
/* Add all live objects on this page to the count of
allocated memory. */
@@ -1452,12 +1455,12 @@ poison_pages ()
for (order = 2; order < NUM_ORDERS; order++)
{
- size_t num_objects = OBJECTS_PER_PAGE (order);
size_t size = OBJECT_SIZE (order);
page_entry *p;
for (p = G.pages[order]; p != NULL; p = p->next)
{
+ size_t num_objects;
size_t i;
if (p->context_depth != G.context_depth)
@@ -1467,6 +1470,7 @@ poison_pages ()
contexts. */
continue;
+ num_objects = OBJECTS_IN_PAGE (p);
for (i = 0; i < num_objects; i++)
{
size_t word, bit;
@@ -1575,11 +1579,11 @@ ggc_print_statistics ()
for (p = G.pages[i]; p; p = p->next)
{
allocated += p->bytes;
- in_use +=
- (OBJECTS_PER_PAGE (i) - p->num_free_objects) * OBJECT_SIZE (i);
+ in_use +=
+ (OBJECTS_IN_PAGE (p) - p->num_free_objects) * OBJECT_SIZE (i);
overhead += (sizeof (page_entry) - sizeof (long)
- + BITMAP_SIZE (OBJECTS_PER_PAGE (i) + 1));
+ + BITMAP_SIZE (OBJECTS_IN_PAGE (p) + 1));
}
fprintf (stderr, "%-5lu %10lu%c %10lu%c %10lu%c\n",
(unsigned long) OBJECT_SIZE (i),
@@ -1751,6 +1755,21 @@ ggc_pch_read (f, addr)
poison_pages ();
#endif
+ /* No object read from a PCH file should ever be freed. So, set the
+ context depth to 1, and set the depth of all the currently-allocated
+ pages to be 1 too. PCH pages will have depth 0. */
+ if (G.context_depth != 0)
+ abort ();
+ G.context_depth = 1;
+ for (i = 0; i < NUM_ORDERS; i++)
+ {
+ page_entry *p;
+ for (p = G.pages[i]; p != NULL; p = p->next)
+ p->context_depth = G.context_depth;
+ }
+
+ /* Allocate the appropriate page-table entries for the pages read from
+ the PCH file. */
if (fread (&d, sizeof (d), 1, f) != 1)
fatal_io_error ("can't read PCH file");
@@ -1758,27 +1777,43 @@ ggc_pch_read (f, addr)
{
struct page_entry *entry;
char *pte;
+ size_t bytes;
size_t bmap_size;
+ size_t num_objs;
+ size_t j;
if (d.totals[i] == 0)
continue;
- bmap_size = BITMAP_SIZE (d.totals[i] + 1);
+ bytes = ROUND_UP (d.totals[i] * OBJECT_SIZE (i), G.pagesize);
+ num_objs = bytes / OBJECT_SIZE (i);
entry = xcalloc (1, (sizeof (struct page_entry)
- sizeof (long)
- + bmap_size));
- entry->bytes = ROUND_UP (d.totals[i] * OBJECT_SIZE (i), G.pagesize);
+ + BITMAP_SIZE (num_objs + 1)));
+ entry->bytes = bytes;
entry->page = offs;
- offs += entry->bytes;
+ entry->context_depth = 0;
+ offs += bytes;
entry->num_free_objects = 0;
entry->order = i;
- entry->pch_page = 1;
- memset (entry->in_use_p, -1, bmap_size);
+ for (j = 0;
+ j + HOST_BITS_PER_LONG <= num_objs + 1;
+ j += HOST_BITS_PER_LONG)
+ entry->in_use_p[j / HOST_BITS_PER_LONG] = -1;
+ for (; j < num_objs + 1; j++)
+ entry->in_use_p[j / HOST_BITS_PER_LONG]
+ |= 1L << (j % HOST_BITS_PER_LONG);
for (pte = entry->page;
pte < entry->page + entry->bytes;
pte += G.pagesize)
set_page_table_entry (pte, entry);
+
+ if (G.page_tails[i] != NULL)
+ G.page_tails[i]->next = entry;
+ else
+ G.pages[i] = entry;
+ G.page_tails[i] = entry;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e0c66e496b9..8d47b301513 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,28 @@
+2002-11-04 Geoffrey Keating <geoffk@apple.com>
+
+ * common-1.c: New.
+ * common-1.h: New.
+ * decl-1.c: New.
+ * decl-1.h: New.
+ * decl-2.c: New.
+ * decl-2.h: New.
+ * decl-3.c: New.
+ * decl-3.h: New.
+ * decl-4.c: New.
+ * decl-4.h: New.
+ * decl-5.c: New.
+ * decl-5.h: New.
+ * global-1.c: New.
+ * global-1.h: New.
+ * inline-1.c: New.
+ * inline-1.h: New.
+ * inline-2.c: New.
+ * inline-2.h: New.
+ * static-1.c: New.
+ * static-1.h: New.
+ * static-2.c: New.
+ * static-2.h: New.
+
2002-09-01 Geoffrey Keating <geoffk@redhat.com>
* g++.dg/pch/pch.exp: Better handle failing testcases.
diff --git a/gcc/testsuite/gcc.dg/pch/common-1.c b/gcc/testsuite/gcc.dg/pch/common-1.c
new file mode 100644
index 00000000000..f158b4d4018
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/common-1.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+#include "common-1.h"
+int foo2 = 3;
+int zz = 2;
diff --git a/gcc/testsuite/gcc.dg/pch/common-1.h b/gcc/testsuite/gcc.dg/pch/common-1.h
new file mode 100644
index 00000000000..971e1996a24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/common-1.h
@@ -0,0 +1,3 @@
+static int foo1 = 9;
+int foo2;
+extern int zz;
diff --git a/gcc/testsuite/gcc.dg/pch/decl-1.c b/gcc/testsuite/gcc.dg/pch/decl-1.c
new file mode 100644
index 00000000000..a3e3ebbfb72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-1.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+#include "decl-1.h"
+int main(void) { return foo; }
diff --git a/gcc/testsuite/gcc.dg/pch/decl-1.h b/gcc/testsuite/gcc.dg/pch/decl-1.h
new file mode 100644
index 00000000000..399f5d3e7f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-1.h
@@ -0,0 +1 @@
+extern int foo;
diff --git a/gcc/testsuite/gcc.dg/pch/decl-2.c b/gcc/testsuite/gcc.dg/pch/decl-2.c
new file mode 100644
index 00000000000..e2d5ddecda4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-2.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+#include "decl-2.h"
+int main(void) { return fun (1, 2); }
diff --git a/gcc/testsuite/gcc.dg/pch/decl-2.h b/gcc/testsuite/gcc.dg/pch/decl-2.h
new file mode 100644
index 00000000000..99c37269097
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-2.h
@@ -0,0 +1,3 @@
+extern int fun (int a, int b);
+
+
diff --git a/gcc/testsuite/gcc.dg/pch/decl-3.c b/gcc/testsuite/gcc.dg/pch/decl-3.c
new file mode 100644
index 00000000000..9be907b1005
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+#include "decl-3.h"
+
+foo_p bar (void)
+{
+ return foop;
+}
+
+struct foo *bar2 (void)
+{
+ return foop;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/decl-3.h b/gcc/testsuite/gcc.dg/pch/decl-3.h
new file mode 100644
index 00000000000..787d480f208
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-3.h
@@ -0,0 +1,3 @@
+struct foo;
+typedef struct foo *foo_p;
+extern foo_p foop;
diff --git a/gcc/testsuite/gcc.dg/pch/decl-4.c b/gcc/testsuite/gcc.dg/pch/decl-4.c
new file mode 100644
index 00000000000..1a10e9b2589
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+#include "decl-4.h"
+
+int bar (foo_p f)
+{
+ if (f->a + foop->a)
+ return f->c->b + foop->b;
+ else
+ return foop->c->b + f->a;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/decl-4.h b/gcc/testsuite/gcc.dg/pch/decl-4.h
new file mode 100644
index 00000000000..3fb220032e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-4.h
@@ -0,0 +1,7 @@
+typedef struct foo {
+ int a;
+ char b;
+ struct foo *c;
+} foo_s;
+typedef struct foo *foo_p;
+extern foo_p foop;
diff --git a/gcc/testsuite/gcc.dg/pch/decl-5.c b/gcc/testsuite/gcc.dg/pch/decl-5.c
new file mode 100644
index 00000000000..cd0edc0f771
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-5.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+#include "decl-5.h"
+static int (*t)(void) = foo;
diff --git a/gcc/testsuite/gcc.dg/pch/decl-5.h b/gcc/testsuite/gcc.dg/pch/decl-5.h
new file mode 100644
index 00000000000..914983c4963
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/decl-5.h
@@ -0,0 +1 @@
+extern int foo(void);
diff --git a/gcc/testsuite/gcc.dg/pch/global-1.c b/gcc/testsuite/gcc.dg/pch/global-1.c
new file mode 100644
index 00000000000..9594a3302d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/global-1.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+#include "global-1.h"
+const int bar = 3;
diff --git a/gcc/testsuite/gcc.dg/pch/global-1.h b/gcc/testsuite/gcc.dg/pch/global-1.h
new file mode 100644
index 00000000000..26efffcb2bb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/global-1.h
@@ -0,0 +1 @@
+const int foo = 2;
diff --git a/gcc/testsuite/gcc.dg/pch/inline-1.c b/gcc/testsuite/gcc.dg/pch/inline-1.c
new file mode 100644
index 00000000000..f49122ae0d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/inline-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+#include "inline-1.h"
+int bar(int a, int b)
+{
+ return foo(a) + b;
+}
+
+int baz(void)
+{
+ return foo(3);
+}
diff --git a/gcc/testsuite/gcc.dg/pch/inline-1.h b/gcc/testsuite/gcc.dg/pch/inline-1.h
new file mode 100644
index 00000000000..e8f1d6f138f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/inline-1.h
@@ -0,0 +1,5 @@
+extern inline int
+foo(int a)
+{
+ return a * 2 + 1;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/inline-2.c b/gcc/testsuite/gcc.dg/pch/inline-2.c
new file mode 100644
index 00000000000..382351fc74c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/inline-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+#include "inline-2.h"
+extern inline char
+bar(int a)
+{
+ return foo(a)[0];
+}
+
+extern inline char
+baz(void)
+{
+ return foo(0)[0];
+}
diff --git a/gcc/testsuite/gcc.dg/pch/inline-2.h b/gcc/testsuite/gcc.dg/pch/inline-2.h
new file mode 100644
index 00000000000..7d90c63deb9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/inline-2.h
@@ -0,0 +1,5 @@
+extern inline const char *
+foo(int a)
+{
+ return "abcdefgh"+a;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/static-1.c b/gcc/testsuite/gcc.dg/pch/static-1.c
new file mode 100644
index 00000000000..10fa1f39bc0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/static-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+#include "static-1.h"
+static int bar(void)
+{
+ static int counter;
+ return counter++;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/static-1.h b/gcc/testsuite/gcc.dg/pch/static-1.h
new file mode 100644
index 00000000000..08cc4395d0e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/static-1.h
@@ -0,0 +1,5 @@
+static int foo(void)
+{
+ static int counter;
+ return counter++;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/static-2.c b/gcc/testsuite/gcc.dg/pch/static-2.c
new file mode 100644
index 00000000000..cfa8e90ca54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/static-2.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+#include "static-2.h"
+int bar(void)
+{
+ static int counter;
+ return counter++;
+}
diff --git a/gcc/testsuite/gcc.dg/pch/static-2.h b/gcc/testsuite/gcc.dg/pch/static-2.h
new file mode 100644
index 00000000000..08cc4395d0e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pch/static-2.h
@@ -0,0 +1,5 @@
+static int foo(void)
+{
+ static int counter;
+ return counter++;
+}