Sync patch from openeuler/gcc - 20220808 (cherry picked from commit 3d663928609a23db4fc8b4ba1039a53a943ac1ed)
666 lines
16 KiB
Diff
666 lines
16 KiB
Diff
From f8308a2b440efe124cd6ff59924f135e85e53888 Mon Sep 17 00:00:00 2001
|
|
From: Mingchuan Wu <wumingchuan1992@foxmail.com>
|
|
Date: Sat, 18 Jun 2022 17:51:04 +0800
|
|
Subject: [PATCH 08/12] [DFE] Fix bugs
|
|
|
|
Fix bugs:
|
|
1. Fixed a bug in check replace type.
|
|
2. Use new to update field access for ref.
|
|
3. We now replace the dead fields in stmt by creating a new ssa.
|
|
4. The replaced type is no longer optimized in NORMAL mode.
|
|
|
|
Also we added 5 dejaGNU test cases.
|
|
---
|
|
gcc/ipa-struct-reorg/ipa-struct-reorg.c | 77 ++++++---
|
|
gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c | 56 ++++++
|
|
gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c | 162 ++++++++++++++++++
|
|
gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c | 126 ++++++++++++++
|
|
.../gcc.dg/struct/dfe_extr_tcp_usrreq.c | 58 +++++++
|
|
.../gcc.dg/struct/dfe_extr_ui_main.c | 61 +++++++
|
|
6 files changed, 516 insertions(+), 24 deletions(-)
|
|
create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c
|
|
create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c
|
|
create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c
|
|
create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c
|
|
create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c
|
|
|
|
diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|
index 2fa560239..00dc4bf1d 100644
|
|
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
|
|
@@ -252,6 +252,7 @@ enum struct_layout_opt_level
|
|
|
|
static bool is_result_of_mult (tree arg, tree *num, tree struct_size);
|
|
bool isptrptr (tree type);
|
|
+void get_base (tree &base, tree expr);
|
|
|
|
srmode current_mode;
|
|
|
|
@@ -631,7 +632,15 @@ srtype::analyze (void)
|
|
into 2 different structures. In future we intend to add profile
|
|
info and/or static heuristics to differentiate splitting process. */
|
|
if (fields.length () == 2)
|
|
- fields[1]->clusternum = 1;
|
|
+ {
|
|
+ for (hash_map<tree, tree>::iterator it = replace_type_map.begin ();
|
|
+ it != replace_type_map.end (); ++it)
|
|
+ {
|
|
+ if (types_compatible_p ((*it).second, this->type))
|
|
+ return;
|
|
+ }
|
|
+ fields[1]->clusternum = 1;
|
|
+ }
|
|
|
|
/* Otherwise we do nothing. */
|
|
if (fields.length () >= 3)
|
|
@@ -3278,12 +3287,33 @@ ipa_struct_reorg::find_vars (gimple *stmt)
|
|
/* Update field_access in srfield. */
|
|
|
|
static void
|
|
-update_field_access (tree record, tree field, unsigned access, void *data)
|
|
+update_field_access (tree node, tree op, unsigned access, void *data)
|
|
{
|
|
- srtype *this_srtype = ((ipa_struct_reorg *)data)->find_type (record);
|
|
+ HOST_WIDE_INT offset = 0;
|
|
+ switch (TREE_CODE (op))
|
|
+ {
|
|
+ case COMPONENT_REF:
|
|
+ {
|
|
+ offset = int_byte_position (TREE_OPERAND (op, 1));
|
|
+ break;
|
|
+ }
|
|
+ case MEM_REF:
|
|
+ {
|
|
+ offset = tree_to_uhwi (TREE_OPERAND (op, 1));
|
|
+ break;
|
|
+ }
|
|
+ default:
|
|
+ return;
|
|
+ }
|
|
+ tree base = node;
|
|
+ get_base (base, node);
|
|
+ srdecl *this_srdecl = ((ipa_struct_reorg *)data)->find_decl (base);
|
|
+ if (this_srdecl == NULL)
|
|
+ return;
|
|
+ srtype *this_srtype = this_srdecl->type;
|
|
if (this_srtype == NULL)
|
|
return;
|
|
- srfield *this_srfield = this_srtype->find_field (int_byte_position (field));
|
|
+ srfield *this_srfield = this_srtype->find_field (offset);
|
|
if (this_srfield == NULL)
|
|
return;
|
|
|
|
@@ -3291,9 +3321,9 @@ update_field_access (tree record, tree field, unsigned access, void *data)
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
{
|
|
fprintf (dump_file, "record field access %d:", access);
|
|
- print_generic_expr (dump_file, record);
|
|
+ print_generic_expr (dump_file, this_srtype->type);
|
|
fprintf (dump_file, " field:");
|
|
- print_generic_expr (dump_file, field);
|
|
+ print_generic_expr (dump_file, this_srfield->fielddecl);
|
|
fprintf (dump_file, "\n");
|
|
}
|
|
return;
|
|
@@ -3302,15 +3332,10 @@ update_field_access (tree record, tree field, unsigned access, void *data)
|
|
/* A callback for walk_stmt_load_store_ops to visit store. */
|
|
|
|
static bool
|
|
-find_field_p_store (gimple *, tree node, tree op, void *data)
|
|
+find_field_p_store (gimple *stmt ATTRIBUTE_UNUSED,
|
|
+ tree node, tree op, void *data)
|
|
{
|
|
- if (TREE_CODE (op) != COMPONENT_REF)
|
|
- return false;
|
|
- tree node_type = TREE_TYPE (node);
|
|
- if (!handled_type (node_type))
|
|
- return false;
|
|
-
|
|
- update_field_access (node_type, TREE_OPERAND (op, 1), WRITE_FIELD, data);
|
|
+ update_field_access (node, op, WRITE_FIELD, data);
|
|
|
|
return false;
|
|
}
|
|
@@ -3318,15 +3343,10 @@ find_field_p_store (gimple *, tree node, tree op, void *data)
|
|
/* A callback for walk_stmt_load_store_ops to visit load. */
|
|
|
|
static bool
|
|
-find_field_p_load (gimple *, tree node, tree op, void *data)
|
|
+find_field_p_load (gimple *stmt ATTRIBUTE_UNUSED,
|
|
+ tree node, tree op, void *data)
|
|
{
|
|
- if (TREE_CODE (op) != COMPONENT_REF)
|
|
- return false;
|
|
- tree node_type = TREE_TYPE (node);
|
|
- if (!handled_type (node_type))
|
|
- return false;
|
|
-
|
|
- update_field_access (node_type, TREE_OPERAND (op, 1), READ_FIELD, data);
|
|
+ update_field_access (node, op, READ_FIELD, data);
|
|
|
|
return false;
|
|
}
|
|
@@ -4629,7 +4649,7 @@ ipa_struct_reorg::check_other_side (srdecl *decl, tree other, gimple *stmt, vec<
|
|
|
|
return;
|
|
}
|
|
- if (!is_replace_type (t1->type, type->type))
|
|
+ if (!is_replace_type (inner_type (t), type->type))
|
|
{
|
|
if (t1)
|
|
t1->mark_escape (escape_cast_another_ptr, stmt);
|
|
@@ -5898,7 +5918,16 @@ ipa_struct_reorg::rewrite_assign (gassign *stmt, gimple_stmt_iterator *gsi)
|
|
fprintf (dump_file, "\n rewriting statement (remove): \n");
|
|
print_gimple_stmt (dump_file, stmt, 0);
|
|
}
|
|
- return true;
|
|
+ /* Replace the dead field in stmt by creating a dummy ssa. */
|
|
+ tree dummy_ssa = make_ssa_name (TREE_TYPE (gimple_assign_lhs (stmt)));
|
|
+ gimple_assign_set_lhs (stmt, dummy_ssa);
|
|
+ update_stmt (stmt);
|
|
+ if (dump_file && (dump_flags & TDF_DETAILS))
|
|
+ {
|
|
+ fprintf (dump_file, "To: \n");
|
|
+ print_gimple_stmt (dump_file, stmt, 0);
|
|
+ }
|
|
+ return false;
|
|
}
|
|
|
|
if (gimple_clobber_p (stmt))
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c
|
|
new file mode 100644
|
|
index 000000000..13a226ee8
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_dtrace.c
|
|
@@ -0,0 +1,56 @@
|
|
+/* { dg-do compile} */
|
|
+
|
|
+#define NULL ((void*)0)
|
|
+typedef unsigned long size_t;
|
|
+typedef long intptr_t;
|
|
+typedef unsigned long uintptr_t;
|
|
+typedef long scalar_t__;
|
|
+typedef int bool;
|
|
+#define false 0
|
|
+#define true 1
|
|
+
|
|
+typedef struct TYPE_4__ TYPE_2__;
|
|
+typedef struct TYPE_3__ TYPE_1__;
|
|
+
|
|
+typedef int uint8_t;
|
|
+typedef int uint16_t;
|
|
+
|
|
+struct TYPE_4__
|
|
+{
|
|
+ size_t cpu_id;
|
|
+};
|
|
+
|
|
+struct TYPE_3__
|
|
+{
|
|
+ int cpuc_dtrace_flags;
|
|
+};
|
|
+
|
|
+TYPE_2__ *CPU;
|
|
+volatile int CPU_DTRACE_FAULT;
|
|
+TYPE_1__ *cpu_core;
|
|
+scalar_t__ dtrace_load8 (uintptr_t);
|
|
+
|
|
+__attribute__((used)) static int
|
|
+dtrace_bcmp (const void *s1, const void *s2, size_t len)
|
|
+{
|
|
+ volatile uint16_t *flags;
|
|
+ flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
|
|
+ if (s1 == s2)
|
|
+ return (0);
|
|
+ if (s1 == NULL || s2 == NULL)
|
|
+ return (1);
|
|
+ if (s1 != s2 && len != 0)
|
|
+ {
|
|
+ const uint8_t *ps1 = s1;
|
|
+ const uint8_t *ps2 = s2;
|
|
+ do
|
|
+ {
|
|
+ if (dtrace_load8 ((uintptr_t)ps1++) != *ps2++)
|
|
+ return (1);
|
|
+ }
|
|
+ while (--len != 0 && !(*flags & CPU_DTRACE_FAULT));
|
|
+ }
|
|
+ return (0);
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_layout" } } */
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c
|
|
new file mode 100644
|
|
index 000000000..1fff2cb9d
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_gc.c
|
|
@@ -0,0 +1,162 @@
|
|
+/* { dg-do compile} */
|
|
+
|
|
+#define NULL ((void*)0)
|
|
+typedef unsigned long size_t;
|
|
+typedef long intptr_t;
|
|
+typedef unsigned long uintptr_t;
|
|
+typedef long scalar_t__;
|
|
+typedef int bool;
|
|
+#define false 0
|
|
+#define true 1
|
|
+
|
|
+struct mrb_context
|
|
+{
|
|
+ size_t stack;
|
|
+ size_t stbase;
|
|
+ size_t stend;
|
|
+ size_t eidx;
|
|
+ int *ci;
|
|
+ int *cibase;
|
|
+ int status;
|
|
+};
|
|
+
|
|
+struct RObject
|
|
+{
|
|
+ int dummy;
|
|
+};
|
|
+
|
|
+struct RHash
|
|
+{
|
|
+ int dummy;
|
|
+};
|
|
+
|
|
+struct RFiber
|
|
+{
|
|
+ struct mrb_context *cxt;
|
|
+};
|
|
+
|
|
+struct RClass
|
|
+{
|
|
+ int dummy;
|
|
+};
|
|
+
|
|
+struct RBasic
|
|
+{
|
|
+ int tt;
|
|
+};
|
|
+
|
|
+struct RArray
|
|
+{
|
|
+ int dummy;
|
|
+};
|
|
+
|
|
+typedef int mrb_state;
|
|
+typedef int mrb_gc;
|
|
+typedef int mrb_callinfo;
|
|
+size_t ARY_LEN (struct RArray *);
|
|
+size_t MRB_ENV_STACK_LEN (struct RBasic *);
|
|
+int MRB_FIBER_TERMINATED;
|
|
+
|
|
+#define MRB_TT_ARRAY 140
|
|
+#define MRB_TT_CLASS 139
|
|
+#define MRB_TT_DATA 138
|
|
+#define MRB_TT_ENV 137
|
|
+#define MRB_TT_EXCEPTION 136
|
|
+#define MRB_TT_FIBER 135
|
|
+#define MRB_TT_HASH 134
|
|
+#define MRB_TT_ICLASS 133
|
|
+#define MRB_TT_MODULE 132
|
|
+#define MRB_TT_OBJECT 131
|
|
+#define MRB_TT_PROC 130
|
|
+#define MRB_TT_RANGE 129
|
|
+#define MRB_TT_SCLASS 128
|
|
+
|
|
+size_t ci_nregs (int *);
|
|
+int gc_mark_children (int *, int *, struct RBasic *);
|
|
+size_t mrb_gc_mark_hash_size (int *, struct RHash *);
|
|
+size_t mrb_gc_mark_iv_size (int *, struct RObject *);
|
|
+size_t mrb_gc_mark_mt_size (int *, struct RClass *);
|
|
+
|
|
+__attribute__((used)) static size_t
|
|
+gc_gray_mark (mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
|
|
+{
|
|
+ size_t children = 0;
|
|
+ gc_mark_children (mrb, gc, obj);
|
|
+ switch (obj->tt)
|
|
+ {
|
|
+ case MRB_TT_ICLASS:
|
|
+ children++;
|
|
+ break;
|
|
+
|
|
+ case MRB_TT_CLASS:
|
|
+ case MRB_TT_SCLASS:
|
|
+ case MRB_TT_MODULE:
|
|
+ {
|
|
+ struct RClass *c = (struct RClass *)obj;
|
|
+ children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj);
|
|
+ children += mrb_gc_mark_mt_size (mrb, c);
|
|
+ children ++;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case MRB_TT_OBJECT:
|
|
+ case MRB_TT_DATA:
|
|
+ case MRB_TT_EXCEPTION:
|
|
+ children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj);
|
|
+ break;
|
|
+
|
|
+ case MRB_TT_ENV:
|
|
+ children += MRB_ENV_STACK_LEN (obj);
|
|
+ break;
|
|
+
|
|
+ case MRB_TT_FIBER:
|
|
+ {
|
|
+ struct mrb_context *c = ((struct RFiber *)obj)->cxt;
|
|
+ size_t i;
|
|
+ mrb_callinfo *ci;
|
|
+ if (!c || c->status == MRB_FIBER_TERMINATED)
|
|
+ break;
|
|
+
|
|
+ i = c->stack - c->stbase;
|
|
+ if (c->ci)
|
|
+ {
|
|
+ i += ci_nregs (c->ci);
|
|
+ }
|
|
+ if (c->stbase + i > c->stend)
|
|
+ i = c->stend - c->stbase;
|
|
+
|
|
+ children += i;
|
|
+ children += c->eidx;
|
|
+ if (c->cibase)
|
|
+ {
|
|
+ for (i = 0, ci = c->cibase; ci <= c->ci; i++, ci++)
|
|
+ ;
|
|
+ }
|
|
+ children += i;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case MRB_TT_ARRAY:
|
|
+ {
|
|
+ struct RArray *a = (struct RArray *)obj;
|
|
+ children += ARY_LEN (a);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case MRB_TT_HASH:
|
|
+ children += mrb_gc_mark_iv_size (mrb, (struct RObject *)obj);
|
|
+ children += mrb_gc_mark_hash_size (mrb, (struct RHash *)obj);
|
|
+ break;
|
|
+
|
|
+ case MRB_TT_PROC:
|
|
+ case MRB_TT_RANGE:
|
|
+ children += 2;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return children;
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_layout" } } */
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c
|
|
new file mode 100644
|
|
index 000000000..0f577667c
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_hpsa.c
|
|
@@ -0,0 +1,126 @@
|
|
+/* { dg-do compile} */
|
|
+
|
|
+#define NULL ((void*)0)
|
|
+typedef unsigned long size_t;
|
|
+typedef long intptr_t;
|
|
+typedef unsigned long uintptr_t;
|
|
+typedef long scalar_t__;
|
|
+typedef int bool;
|
|
+#define false 0
|
|
+#define true 1
|
|
+
|
|
+typedef struct TYPE_6__ TYPE_3__;
|
|
+typedef struct TYPE_5__ TYPE_2__;
|
|
+typedef struct TYPE_4__ TYPE_1__;
|
|
+
|
|
+struct io_accel2_cmd
|
|
+{
|
|
+ int dummy;
|
|
+};
|
|
+
|
|
+struct hpsa_tmf_struct
|
|
+{
|
|
+ int it_nexus;
|
|
+};
|
|
+
|
|
+struct hpsa_scsi_dev_t
|
|
+{
|
|
+ int nphysical_disks;
|
|
+ int ioaccel_handle;
|
|
+ struct hpsa_scsi_dev_t **phys_disk;
|
|
+};
|
|
+
|
|
+struct ctlr_info
|
|
+{
|
|
+ TYPE_3__ *pdev;
|
|
+ struct io_accel2_cmd *ioaccel2_cmd_pool;
|
|
+};
|
|
+struct TYPE_4__
|
|
+{
|
|
+ int LunAddrBytes;
|
|
+};
|
|
+
|
|
+struct TYPE_5__
|
|
+{
|
|
+ TYPE_1__ LUN;
|
|
+};
|
|
+
|
|
+struct CommandList
|
|
+{
|
|
+ size_t cmdindex;
|
|
+ int cmd_type;
|
|
+ struct hpsa_scsi_dev_t *phys_disk;
|
|
+ TYPE_2__ Header;
|
|
+};
|
|
+
|
|
+struct TYPE_6__
|
|
+{
|
|
+ int dev;
|
|
+};
|
|
+
|
|
+int BUG ();
|
|
+#define CMD_IOACCEL1 132
|
|
+#define CMD_IOACCEL2 131
|
|
+#define CMD_IOCTL_PEND 130
|
|
+#define CMD_SCSI 129
|
|
+#define IOACCEL2_TMF 128
|
|
+int dev_err (int *, char *, int);
|
|
+scalar_t__ hpsa_is_cmd_idle (struct CommandList *);
|
|
+int le32_to_cpu (int);
|
|
+int test_memcmp (unsigned char *, int *, int);
|
|
+
|
|
+__attribute__((used)) static bool
|
|
+hpsa_cmd_dev_match (struct ctlr_info *h, struct CommandList *c,
|
|
+ struct hpsa_scsi_dev_t *dev, unsigned char *scsi3addr)
|
|
+{
|
|
+ int i;
|
|
+ bool match = false;
|
|
+ struct io_accel2_cmd * c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
|
|
+ struct hpsa_tmf_struct *ac = (struct hpsa_tmf_struct *)c2;
|
|
+
|
|
+ if (hpsa_is_cmd_idle (c))
|
|
+ return false;
|
|
+
|
|
+ switch (c->cmd_type)
|
|
+ {
|
|
+ case CMD_SCSI:
|
|
+ case CMD_IOCTL_PEND:
|
|
+ match = !test_memcmp (scsi3addr, &c->Header.LUN.LunAddrBytes,
|
|
+ sizeof (c->Header.LUN.LunAddrBytes));
|
|
+ break;
|
|
+
|
|
+ case CMD_IOACCEL1:
|
|
+ case CMD_IOACCEL2:
|
|
+ if (c->phys_disk == dev)
|
|
+ {
|
|
+ match = true;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ for (i = 0; i < dev->nphysical_disks && !match; i++)
|
|
+ {
|
|
+ match = dev->phys_disk[i] == c->phys_disk;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case IOACCEL2_TMF:
|
|
+ for (i = 0; i < dev->nphysical_disks && !match; i++)
|
|
+ {
|
|
+ match = dev->phys_disk[i]->ioaccel_handle ==
|
|
+ le32_to_cpu (ac->it_nexus);
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case 0:
|
|
+ match = false;
|
|
+ break;
|
|
+ default:
|
|
+ dev_err (&h->pdev->dev, "unexpected cmd_type: %d\n", c->cmd_type);
|
|
+ BUG ();
|
|
+ }
|
|
+
|
|
+ return match;
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_layout" } } */
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c
|
|
new file mode 100644
|
|
index 000000000..5570c762e
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_tcp_usrreq.c
|
|
@@ -0,0 +1,58 @@
|
|
+/* { dg-do compile} */
|
|
+
|
|
+#define NULL ((void*)0)
|
|
+typedef unsigned long size_t;
|
|
+typedef long intptr_t;
|
|
+typedef unsigned long uintptr_t;
|
|
+typedef long scalar_t__;
|
|
+typedef int bool;
|
|
+#define false 0
|
|
+#define true 1
|
|
+
|
|
+struct tcpcb
|
|
+{
|
|
+ int t_state;
|
|
+};
|
|
+
|
|
+struct socket
|
|
+{
|
|
+ int dummy;
|
|
+};
|
|
+
|
|
+struct proc
|
|
+{
|
|
+ int dummy;
|
|
+};
|
|
+
|
|
+struct inpcb
|
|
+{
|
|
+ scalar_t__ inp_lport;
|
|
+};
|
|
+
|
|
+int COMMON_END (int);
|
|
+int COMMON_START ();
|
|
+int PRU_LISTEN;
|
|
+int TCPS_LISTEN;
|
|
+int in_pcbbind (struct inpcb *, int *, struct proc *);
|
|
+struct inpcb* sotoinpcb (struct socket *);
|
|
+
|
|
+__attribute__((used)) static void
|
|
+tcp_usr_listen (struct socket *so, struct proc *p)
|
|
+{
|
|
+ int error = 0;
|
|
+ struct inpcb *inp = sotoinpcb (so);
|
|
+ struct tcpcb *tp;
|
|
+
|
|
+ COMMON_START ();
|
|
+ if (inp->inp_lport == 0)
|
|
+ {
|
|
+ error = in_pcbbind (inp, NULL, p);
|
|
+ }
|
|
+ if (error == 0)
|
|
+ {
|
|
+ tp->t_state = TCPS_LISTEN;
|
|
+ }
|
|
+ COMMON_END (PRU_LISTEN);
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_layout" } } */
|
|
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c b/gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c
|
|
new file mode 100644
|
|
index 000000000..50ab9cc24
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/struct/dfe_extr_ui_main.c
|
|
@@ -0,0 +1,61 @@
|
|
+/* { dg-do compile} */
|
|
+
|
|
+#define NULL ((void*)0)
|
|
+typedef unsigned long size_t;
|
|
+typedef long intptr_t;
|
|
+typedef unsigned long uintptr_t;
|
|
+typedef long scalar_t__;
|
|
+typedef int bool;
|
|
+#define false 0
|
|
+#define true 1
|
|
+
|
|
+typedef struct TYPE_4__ TYPE_2__;
|
|
+typedef struct TYPE_3__ TYPE_1__;
|
|
+
|
|
+struct TYPE_4__
|
|
+{
|
|
+ size_t modCount;
|
|
+ TYPE_1__ *modList;
|
|
+};
|
|
+
|
|
+struct TYPE_3__
|
|
+{
|
|
+ void *modDescr;
|
|
+ void *modName;
|
|
+};
|
|
+
|
|
+size_t MAX_MODS;
|
|
+void *String_Alloc (char *);
|
|
+int test_strlen (char *);
|
|
+int trap_FD_GetFileList (char *, char *, char *, int);
|
|
+TYPE_2__ uiInfo;
|
|
+
|
|
+__attribute__((used)) static void
|
|
+UI_LoadMods ()
|
|
+{
|
|
+ int numdirs;
|
|
+ char dirlist[2048];
|
|
+ char *dirptr;
|
|
+ char *descptr;
|
|
+ int i;
|
|
+ int dirlen;
|
|
+
|
|
+ uiInfo.modCount = 0;
|
|
+ numdirs = trap_FD_GetFileList ("$modelist", "", dirlist, sizeof (dirlist));
|
|
+ dirptr = dirlist;
|
|
+ for (i = 0; i < numdirs; i++)
|
|
+ {
|
|
+ dirlen = test_strlen (dirptr) + 1;
|
|
+ descptr = dirptr + dirlen;
|
|
+ uiInfo.modList[uiInfo.modCount].modName = String_Alloc (dirptr);
|
|
+ uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc (descptr);
|
|
+ dirptr += dirlen + test_strlen (descptr) + 1;
|
|
+ uiInfo.modCount++;
|
|
+ if (uiInfo.modCount >= MAX_MODS)
|
|
+ {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-ipa-dump-times "Dead field elimination" 1 "struct_layout" } } */
|
|
--
|
|
2.27.0.windows.1
|
|
|