From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id E54563858439 for ; Tue, 19 Jul 2022 08:40:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E54563858439 Received: by mail-ej1-x62d.google.com with SMTP id tk8so14456596ejc.7 for ; Tue, 19 Jul 2022 01:40:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=6o9LiNctZ1QEkElnuPS4PKk9D8oo38RqvDz2CnG1jvc=; b=U3QLc2jFNHdSvEzdiuZm84a4O3i2+5HLlzHdsHvF3QyiGaJH3ZimIGyCt8nfLJ5ZkP m3rbn2SZ7zpfxPwDbblzrpat7T86gKc9HMsKTAKfcoPJEhrTX0XVvbmS3pomPoRQsObW nM0QkOeDo+dtDVG1G/W/DxvgYbW5AZIXAnAiOx5kU0kThYZqdM/ypIKkiI/uUEjtozPL BjQK4VBGVwoASXV0kq1E7n0fpK+u6/E4thbpZfZkXpUg45yyLat8JkEjs008NbE7/Hbb 96aQyt5DJiDqXrc4jw+hcAfVE3T0rJgI5oMxQ0ncRCiPoM4Q82jfNlNi9OIB2x6yLUMC PgLQ== X-Gm-Message-State: AJIora/hWBUc0dG8Y5rUqoipkFP75wcHqpyqkDenROgLdVU0XbBIw6Bl sYM61WtCQph1uRlJPlv4kErwWIJLfM64Cwrd6+g= X-Google-Smtp-Source: AGRyM1tKNw4MUKMfroHbNVsvJ+BLtEWkzYef2yJL9bS6urcXIUEwts3IdfN+kvbk/T9YFB3T/Y144fW7X5ZMtpBNY+c= X-Received: by 2002:a17:907:6295:b0:703:92b8:e113 with SMTP id nd21-20020a170907629500b0070392b8e113mr29802250ejc.594.1658220018564; Tue, 19 Jul 2022 01:40:18 -0700 (PDT) MIME-Version: 1.0 References: <20220114182047.6270-3-amonakov@ispras.ru> <84dba16-ab1a-f362-48-8f42ebc14d2b@ispras.ru> In-Reply-To: From: Richard Biener Date: Tue, 19 Jul 2022 10:40:06 +0200 Message-ID: Subject: Re: [PATCH 2/3] tree-cfg: do not duplicate returns_twice calls To: Alexander Monakov Cc: GCC Patches Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-8.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Jul 2022 08:40:22 -0000 On Thu, Jul 14, 2022 at 10:12 PM Alexander Monakov wrote: > > > On Thu, 14 Jul 2022, Richard Biener wrote: > > > Indeed. Guess that's what __builtin_setjmp[_receiver] for SJLJ_EH got "right". > > > > When copying a block we do not copy labels so any "jumps" remain to the original > > block and thus we are indeed able to isolate normal control flow. Given that > > returns_twice functions _do_ seem to be special, and also special as to how > > we handle other abnormal receivers in duplicate_block. > > We do? Sorry, I don't see what you mean here, can you point me to specific lines? I'm referring to stmt = gsi_stmt (gsi); if (gimple_code (stmt) == GIMPLE_LABEL) continue; but indeed, looking again we do _not_ skip a __builtin_setjmp_receiver (but I don't exactly remember the CFG setup with SJLJ EH and setjmp_{receiver,setup}. > > So it might indeed make sense to special-case them in can_duplicate_block_p > > ... (sorry for going back-and-forth ...) > > > > Note that I think this detail of duplicate_block (the function) and the hook > > needs to be better documented (the semantics on incoming edges, not duplicating > > labels used for incoming control flow). > > > > Can you see as to how to adjust the RTL side for this? It looks like at least > > some places set a REG_SETJMP note on call_insns (emit_call_1), I wonder > > if in rtl_verify_flow_info[_1] (or its callees) we can check that such > > calls come > > first ... they might not since IIRC we do _not_ preserve abnormal edges when > > expanding RTL (there's some existing bug about this and how this breaks some > > setjmp tests) (but we try to recompute them?). > > No, we emit arguments/return value handling before/after a REG_SETJMP call, > and yeah, we don't always properly recompute abnormal edges, so improving > RTL in this respect seems hopeless. :/ (but yes, nobody got to fixing PR57067 in the last 10 years) > For example, it is easy enough to create > a testcase where bb-reordering duplicates a returns_twice call, although it > runs so late that perhaps later passes don't care: > > // gcc -O2 --param=max-grow-copy-bb-insns=100 > __attribute__((returns_twice)) > int rtwice(int); > int g1(int), g2(int); > void f(int i) > { > do { > i = i%2 ? g1(i) : g2(i); > } while (i = rtwice(i)); > } > > FWIW, I also investigated https://gcc.gnu.org/PR101347 > > > Sorry about the back-and-forth again ... your original patch looks OK for the > > GIMPLE side but can you amend the cfghooks.{cc,h} documentation to > > summarize our findings and > > the desired semantics of duplicate_block in this respect? > > Like below? Yes. Thanks and sorry for the back and forth - this _is_ a mightly complicated area ... Richard. > ---8<--- > > Subject: [PATCH v3] tree-cfg: do not duplicate returns_twice calls > > A returns_twice call may have associated abnormal edges that correspond > to the "second return" from the call. If the call is duplicated, the > copies of those edges also need to be abnormal, but e.g. tracer does not > enforce that. Just prohibit the (unlikely to be useful) duplication. > > gcc/ChangeLog: > > * cfghooks.cc (duplicate_block): Expand comment. > * tree-cfg.cc (gimple_can_duplicate_bb_p): Reject blocks with > calls that may return twice. > --- > gcc/cfghooks.cc | 13 ++++++++++--- > gcc/tree-cfg.cc | 7 +++++-- > 2 files changed, 15 insertions(+), 5 deletions(-) > > diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc > index e435891fa..c6ac9532c 100644 > --- a/gcc/cfghooks.cc > +++ b/gcc/cfghooks.cc > @@ -1086,9 +1086,16 @@ can_duplicate_block_p (const_basic_block bb) > return cfg_hooks->can_duplicate_block_p (bb); > } > > -/* Duplicates basic block BB and redirects edge E to it. Returns the > - new basic block. The new basic block is placed after the basic block > - AFTER. */ > +/* Duplicate basic block BB, place it after AFTER (if non-null) and redirect > + edge E to it (if non-null). Return the new basic block. > + > + If BB contains a returns_twice call, the caller is responsible for recreating > + incoming abnormal edges corresponding to the "second return" for the copy. > + gimple_can_duplicate_bb_p rejects such blocks, while RTL likes to live > + dangerously. > + > + If BB has incoming abnormal edges for some other reason, their destinations > + should be tied to label(s) of the original BB and not the copy. */ > > basic_block > duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id) > diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc > index f846dc2d8..5bcf78198 100644 > --- a/gcc/tree-cfg.cc > +++ b/gcc/tree-cfg.cc > @@ -6346,12 +6346,15 @@ gimple_can_duplicate_bb_p (const_basic_block bb) > { > gimple *g = gsi_stmt (gsi); > > - /* An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be > + /* Prohibit duplication of returns_twice calls, otherwise associated > + abnormal edges also need to be duplicated properly. > + An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be > duplicated as part of its group, or not at all. > The IFN_GOMP_SIMT_VOTE_ANY and IFN_GOMP_SIMT_XCHG_* are part of such a > group, so the same holds there. */ > if (is_gimple_call (g) > - && (gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC) > + && (gimple_call_flags (g) & ECF_RETURNS_TWICE > + || gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC) > || gimple_call_internal_p (g, IFN_GOMP_SIMT_EXIT) > || gimple_call_internal_p (g, IFN_GOMP_SIMT_VOTE_ANY) > || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_BFLY) > -- > 2.35.1 >