From patchwork Mon May 7 10:23:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 909667 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-477300-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="PPNpl5jL"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40fdzn0TqTz9ryk for ; Mon, 7 May 2018 20:25:24 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=yG+NPC35E8+ve56o WHGGClo9HyBkyXzz9iJ13S3qAfXIj9EcqZFL6eSZIS47cnAvjx4H3haLMZ0VmoyU GG8TOHljbJ6vVjHkQwWL8jDUaTBCaUSBmxw+EwLgfXEqDeQxTZuxx3riAveOMlnN wlIAsuhWrvdJ3fHv5HtGYVhIEXQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=ZlMN0IOl6i9BeuoIYgKI6Q PleTk=; b=PPNpl5jLRJIHrhcFOIIqjCZFcSB8RCVm9lQhP5CFXF9kpXxJGg0SU6 A0Ixu7jr3o01WaSO9saIPexfcYMICUJB7EEUhF1paJJ+i8mVYAeBuhg8HwRfXCfi gNkxEKlfPMKE3665TOmNp8WYs0co/F5F912R3FfCO2mprf2I+k6l4= Received: (qmail 68108 invoked by alias); 7 May 2018 10:24:57 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 67954 invoked by uid 89); 7 May 2018 10:24:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-15.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=aux, forwarder, pads, BB_END X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 07 May 2018 10:24:53 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 045BE81388 for ; Mon, 7 May 2018 12:24:51 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id W5qRI3N4usxF for ; Mon, 7 May 2018 12:24:50 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id C976281386 for ; Mon, 7 May 2018 12:24:50 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix PR rtl-optimization/85638 Date: Mon, 07 May 2018 12:23:58 +0200 Message-ID: <3478647.Rd1DFDxtzv@polaris> MIME-Version: 1.0 Hi, this is the build failure of the Ada runtime on platforms with SJLJ exceptions like 32-bit x86/Windows, a regression present on the mainline and 8 branch and caused by enabling -freorder-blocks-and-partition by default for x86. The CFG is somewhat different for EH regions in SJLJ mode because there is a single landing pad label, hence landing pad block, common for all EH regions, so the fix_up_crossing_landing_pad logic must be tailored to this mode. Tested on x86-64/Linux and x86/Windows, OK for mainline and 8 branch? 2018-05-07 Eric Botcazou PR rtl-optimization/85638 * bb-reorder.c: Include common/common-target.h. (create_forwarder_block): New function extracted from... (fix_up_crossing_landing_pad): ...here. Rename into... (dw2_fix_up_crossing_landing_pad): ...this. Call create_forwarder_block. (sjlj_fix_up_crossing_landing_pad): New function. (find_rarely_executed_basic_blocks_and_crossing_edges): In SJLJ mode, call sjlj_fix_up_crossing_landing_pad if there are incoming EH edges from both partitions and exit the loop after one iteration. Index: bb-reorder.c =================================================================== --- bb-reorder.c (revision 259642) +++ bb-reorder.c (working copy) @@ -117,6 +117,7 @@ #include "fibonacci_heap.h" #include "stringpool.h" #include "attribs.h" +#include "common/common-target.h" /* The number of rounds. In most cases there will only be 4 rounds, but when partitioning hot and cold basic blocks into separate sections of @@ -1408,17 +1409,95 @@ get_uncond_jump_length (void) return length; } +/* Create a forwarder block to OLD_BB starting with NEW_LABEL and in the + other partition wrt OLD_BB. */ + +static basic_block +create_forwarder_block (rtx_code_label *new_label, basic_block old_bb) +{ + /* Put the new label and a jump in the new basic block. */ + rtx_insn *label = emit_label (new_label); + rtx_code_label *old_label = block_label (old_bb); + rtx_insn *jump = emit_jump_insn (targetm.gen_jump (old_label)); + JUMP_LABEL (jump) = old_label; + + /* Create the new basic block and put it in last position. */ + basic_block last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; + basic_block new_bb = create_basic_block (label, jump, last_bb); + new_bb->aux = last_bb->aux; + new_bb->count = old_bb->count; + last_bb->aux = new_bb; + + emit_barrier_after_bb (new_bb); + + make_single_succ_edge (new_bb, old_bb, 0); + + /* Make sure the new basic block is in the other partition. */ + unsigned new_partition = BB_PARTITION (old_bb); + new_partition ^= BB_HOT_PARTITION | BB_COLD_PARTITION; + BB_SET_PARTITION (new_bb, new_partition); + + return new_bb; +} + +/* The common landing pad in block OLD_BB has edges from both partitions. + Add a new landing pad that will just jump to the old one and split the + edges so that no EH edge crosses partitions. */ + +static void +sjlj_fix_up_crossing_landing_pad (basic_block old_bb) +{ + const unsigned lp_len = cfun->eh->lp_array->length (); + edge_iterator ei; + edge e; + + /* Generate the new common landing-pad label. */ + rtx_code_label *new_label = gen_label_rtx (); + LABEL_PRESERVE_P (new_label) = 1; + + /* Create the forwarder block. */ + basic_block new_bb = create_forwarder_block (new_label, old_bb); + + /* Create the map from old to new lp index and initialize it. */ + unsigned *index_map = (unsigned *) alloca (lp_len * sizeof (unsigned)); + memset (index_map, 0, lp_len * sizeof (unsigned)); + + /* Fix up the edges. */ + for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; ) + if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb)) + { + rtx_insn *insn = BB_END (e->src); + rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); + + gcc_assert (note != NULL); + const unsigned old_index = INTVAL (XEXP (note, 0)); + + /* Generate the new landing-pad structure. */ + if (index_map[old_index] == 0) + { + eh_landing_pad old_lp = (*cfun->eh->lp_array)[old_index]; + eh_landing_pad new_lp = gen_eh_landing_pad (old_lp->region); + new_lp->post_landing_pad = old_lp->post_landing_pad; + new_lp->landing_pad = new_label; + index_map[old_index] = new_lp->index; + } + XEXP (note, 0) = GEN_INT (index_map[old_index]); + + /* Adjust the edge to the new destination. */ + redirect_edge_succ (e, new_bb); + } + else + ei_next (&ei); +} + /* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions. Add a new landing pad that will just jump to the old one and split the edges so that no EH edge crosses partitions. */ static void -fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb) +dw2_fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb) { eh_landing_pad new_lp; - basic_block new_bb, last_bb; - rtx_insn *jump; - unsigned new_partition; edge_iterator ei; edge e; @@ -1428,32 +1507,12 @@ fix_up_crossing_landing_pad (eh_landing_ new_lp->landing_pad = gen_label_rtx (); LABEL_PRESERVE_P (new_lp->landing_pad) = 1; - /* Put appropriate instructions in new bb. */ - rtx_code_label *new_label = emit_label (new_lp->landing_pad); - - rtx_code_label *old_label = block_label (old_bb); - jump = emit_jump_insn (targetm.gen_jump (old_label)); - JUMP_LABEL (jump) = old_label; - - /* Create new basic block to be dest for lp. */ - last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; - new_bb = create_basic_block (new_label, jump, last_bb); - new_bb->aux = last_bb->aux; - new_bb->count = old_bb->count; - last_bb->aux = new_bb; - - emit_barrier_after_bb (new_bb); - - make_single_succ_edge (new_bb, old_bb, 0); - - /* Make sure new bb is in the other partition. */ - new_partition = BB_PARTITION (old_bb); - new_partition ^= BB_HOT_PARTITION | BB_COLD_PARTITION; - BB_SET_PARTITION (new_bb, new_partition); + /* Create the forwarder block. */ + basic_block new_bb = create_forwarder_block (new_lp->landing_pad, old_bb); /* Fix up the edges. */ for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; ) - if (e->src != new_bb && BB_PARTITION (e->src) == new_partition) + if (e->src != new_bb && BB_PARTITION (e->src) == BB_PARTITION (new_bb)) { rtx_insn *insn = BB_END (e->src); rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); @@ -1651,9 +1710,11 @@ find_rarely_executed_basic_blocks_and_cr /* The format of .gcc_except_table does not allow landing pads to be in a different partition as the throw. Fix this by either - moving or duplicating the landing pads. */ + moving the landing pads or inserting forwarder landing pads. */ if (cfun->eh->lp_array) { + const bool sjlj + = (targetm_common.except_unwind_info (&global_options) == UI_SJLJ); unsigned i; eh_landing_pad lp; @@ -1685,13 +1746,18 @@ find_rarely_executed_basic_blocks_and_cr which ^= BB_HOT_PARTITION | BB_COLD_PARTITION; BB_SET_PARTITION (bb, which); } + else if (sjlj) + sjlj_fix_up_crossing_landing_pad (bb); else - fix_up_crossing_landing_pad (lp, bb); + dw2_fix_up_crossing_landing_pad (lp, bb); + + /* There is a single, common landing pad in SJLJ mode. */ + if (sjlj) + break; } } /* Mark every edge that crosses between sections. */ - FOR_EACH_BB_FN (bb, cfun) FOR_EACH_EDGE (e, ei, bb->succs) {