From patchwork Wed Sep 26 21:15:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 975403 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-486513-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="yr0VM5UW"; 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 42L9jF5P6kz9s3l for ; Thu, 27 Sep 2018 07:16:17 +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 :subject:from:to:cc:references:date:mime-version:in-reply-to :content-type:content-transfer-encoding:message-id; q=dns; s= default; b=uMNKCUuUFUqJU7mpcf/Jb3a2l9/wqdLbUBKI0k5mPqEj1VLhNWK+v A8cfj6SRNe4HkGpVOBzB8TXQvN+4cjUGAJuRFvAH41nlhONuNmTbyMHDyn78gTk+ aabj2ypj8O9XBpCHhiUSUx9USooBI6NN6+kqnMlEbt3O6/P3vI3eCs= 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 :subject:from:to:cc:references:date:mime-version:in-reply-to :content-type:content-transfer-encoding:message-id; s=default; bh=mgWQkRWPqg27POhamZx/aKBxYGY=; b=yr0VM5UWqhbTSjd41pQlOHywEH77 MBBteOzy7B5WmSSDQPo9kys3kFm9wlg9IlMExS2aZ6gTYpFt7d3x4S3mVDmkhkjk M2wCFsVMuCZfnyI3dO7vwpRTNgNwykWaT8PZw4GOSLBQnc6614XXBsjORaG6Rd0j jimzDy9LGbKhbLc= Received: (qmail 53531 invoked by alias); 26 Sep 2018 21:16:08 -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 53394 invoked by uid 89); 26 Sep 2018 21:15:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-12.6 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS, TIME_LIMIT_EXCEEDED autolearn=unavailable version=3.3.2 spammy=birth, 2999, H*Ad:U*vmakarov X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 26 Sep 2018 21:15:27 +0000 Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w8QL9E5l043790 for ; Wed, 26 Sep 2018 17:15:23 -0400 Received: from e12.ny.us.ibm.com (e12.ny.us.ibm.com [129.33.205.202]) by mx0a-001b2d01.pphosted.com with ESMTP id 2mrf8r7561-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 26 Sep 2018 17:15:23 -0400 Received: from localhost by e12.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 26 Sep 2018 17:15:22 -0400 Received: from b01cxnp22036.gho.pok.ibm.com (9.57.198.26) by e12.ny.us.ibm.com (146.89.104.199) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 26 Sep 2018 17:15:20 -0400 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp22036.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w8QLFJ3Y37486836 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 26 Sep 2018 21:15:19 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B5BC0B206A; Wed, 26 Sep 2018 17:13:38 -0400 (EDT) Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5C81FB2066; Wed, 26 Sep 2018 17:13:38 -0400 (EDT) Received: from otta.local (unknown [9.80.200.29]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP; Wed, 26 Sep 2018 17:13:38 -0400 (EDT) Subject: [PATCH 1/2][IRA, LRA] Fix PR86939, IRA incorrectly creates an interference between a pseudo register and a hard register From: Peter Bergner To: GCC Patches Cc: Vladimir N Makarov , Jeff Law References: Date: Wed, 26 Sep 2018 16:15:18 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: x-cbid: 18092621-0060-0000-0000-000002B6DE63 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009777; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000267; SDB=6.01094081; UDB=6.00565530; IPR=6.00874119; MB=3.00023520; MTD=3.00000008; XFM=3.00000015; UTC=2018-09-26 21:15:21 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18092621-0061-0000-0000-000046A583B1 Message-Id: <0b45089c-f53d-14c0-6a71-3bc4b76572f0@linux.ibm.com> X-IsSubscribed: yes gcc/ * ira-lives.c (make_hard_regno_born): Rename from this... (make_hard_regno_live): ... to this. Remove update to conflict information. Update function comment. (make_hard_regno_dead): Add conflict information update. Update function comment. (make_object_born): Rename from this... (make_object_live): ... to this. Remove update to conflict information. Update function comment. (make_object_dead): Add conflict information update. Update function comment. (mark_pseudo_regno_live): Call make_object_live. (mark_pseudo_regno_subword_live): Likewise. (mark_hard_reg_dead): Update function comment. (mark_hard_reg_live): Call make_hard_regno_live. (process_bb_node_lives): Likewise. * lra-lives.c (make_hard_regno_born): Rename from this... (make_hard_regno_live): ... to this. Remove update to conflict information. Remove now uneeded check_pic_pseudo_p argument. Update function comment. (make_hard_regno_dead): Add check_pic_pseudo_p argument and add update to conflict information. Update function comment. (mark_pseudo_live): Remove update to conflict information. Update function comment. (mark_pseudo_dead): Add conflict information update. (mark_regno_live): Call make_hard_regno_live. (mark_regno_dead): Call make_hard_regno_dead with new arguement. (process_bb_lives): Call make_hard_regno_live and make_hard_regno_dead. Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c (revision 263506) +++ gcc/ira-lives.c (working copy) @@ -84,14 +84,19 @@ static int *allocno_saved_at_call; supplemental to recog_data. */ static alternative_mask preferred_alternatives; -/* Record the birth of hard register REGNO, updating hard_regs_live and - hard reg conflict information for living allocnos. */ +/* Record hard register REGNO as now being live. */ static void -make_hard_regno_born (int regno) +make_hard_regno_live (int regno) { - unsigned int i; - SET_HARD_REG_BIT (hard_regs_live, regno); +} + +/* Process the definition of hard register REGNO. This updates + hard_regs_live and hard reg conflict information for living allocnos. */ +static void +make_hard_regno_dead (int regno) +{ + unsigned int i; EXECUTE_IF_SET_IN_SPARSESET (objects_live, i) { ira_object_t obj = ira_object_id_map[i]; @@ -99,28 +104,17 @@ make_hard_regno_born (int regno) SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno); SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno); } -} - -/* Process the death of hard register REGNO. This updates - hard_regs_live. */ -static void -make_hard_regno_dead (int regno) -{ CLEAR_HARD_REG_BIT (hard_regs_live, regno); } -/* Record the birth of object OBJ. Set a bit for it in objects_live, - start a new live range for it if necessary and update hard register - conflicts. */ +/* Record object OBJ as now being live. Set a bit for it in objects_live, + and start a new live range for it if necessary. */ static void -make_object_born (ira_object_t obj) +make_object_live (ira_object_t obj) { - live_range_t lr = OBJECT_LIVE_RANGES (obj); - sparseset_set_bit (objects_live, OBJECT_CONFLICT_ID (obj)); - IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live); - IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live); + live_range_t lr = OBJECT_LIVE_RANGES (obj); if (lr == NULL || (lr->finish != curr_point && lr->finish + 1 != curr_point)) ira_add_live_range_to_object (obj, curr_point, -1); @@ -154,14 +148,18 @@ update_allocno_pressure_excess_length (i } } -/* Process the death of object OBJ, which is associated with allocno - A. This finishes the current live range for it. */ +/* Process the definition of object OBJ, which is associated with allocno A. + This finishes the current live range for it. */ static void make_object_dead (ira_object_t obj) { live_range_t lr; sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (obj)); + + IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live); + IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live); + lr = OBJECT_LIVE_RANGES (obj); ira_assert (lr != NULL); lr->finish = curr_point; @@ -290,7 +288,7 @@ mark_pseudo_regno_live (int regno) continue; inc_register_pressure (pclass, nregs); - make_object_born (obj); + make_object_live (obj); } } @@ -327,7 +325,7 @@ mark_pseudo_regno_subword_live (int regn return; inc_register_pressure (pclass, 1); - make_object_born (obj); + make_object_live (obj); } /* Mark the register REG as live. Store a 1 in hard_regs_live for @@ -351,7 +349,7 @@ mark_hard_reg_live (rtx reg) aclass = ira_hard_regno_allocno_class[regno]; pclass = ira_pressure_class_translate[aclass]; inc_register_pressure (pclass, 1); - make_hard_regno_born (regno); + make_hard_regno_live (regno); } regno++; } @@ -457,8 +455,8 @@ mark_pseudo_regno_subword_dead (int regn make_object_dead (obj); } -/* Mark the hard register REG as dead. Store a 0 in hard_regs_live for the - register. */ +/* Process the definition of hard register REG. This updates hard_regs_live + and hard reg conflict information for living allocnos. */ static void mark_hard_reg_dead (rtx reg) { @@ -1298,7 +1296,7 @@ process_bb_node_lives (ira_loop_tree_nod unsigned int regno = EH_RETURN_DATA_REGNO (j); if (regno == INVALID_REGNUM) break; - make_hard_regno_born (regno); + make_hard_regno_live (regno); } /* Allocnos can't go in stack regs at the start of a basic block @@ -1317,7 +1315,7 @@ process_bb_node_lives (ira_loop_tree_nod ALLOCNO_TOTAL_NO_STACK_REG_P (a) = true; } for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++) - make_hard_regno_born (px); + make_hard_regno_live (px); #endif /* No need to record conflicts for call clobbered regs if we have nonlocal labels around, as we don't ever try to @@ -1340,7 +1338,7 @@ process_bb_node_lives (ira_loop_tree_nod && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) #endif ) - make_hard_regno_born (px); + make_hard_regno_live (px); } EXECUTE_IF_SET_IN_SPARSESET (objects_live, i) Index: gcc/lra-lives.c =================================================================== --- gcc/lra-lives.c (revision 263506) +++ gcc/lra-lives.c (working copy) @@ -223,42 +223,41 @@ lra_intersected_live_ranges_p (lra_live_ /* The corresponding bitmaps of BB currently being processed. */ static bitmap bb_killed_pseudos, bb_gen_pseudos; -/* The function processing birth of hard register REGNO. It updates - living hard regs, START_LIVING, and conflict hard regs for living - pseudos. Conflict hard regs for the pic pseudo is not updated if - REGNO is REAL_PIC_OFFSET_TABLE_REGNUM and CHECK_PIC_PSEUDO_P is - true. */ +/* Record hard register REGNO as now being live. It updates + living hard regs and START_LIVING. */ static void -make_hard_regno_born (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED) +make_hard_regno_live (int regno) { - unsigned int i; - lra_assert (regno < FIRST_PSEUDO_REGISTER); if (TEST_HARD_REG_BIT (hard_regs_live, regno)) return; SET_HARD_REG_BIT (hard_regs_live, regno); sparseset_set_bit (start_living, regno); - EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) -#ifdef REAL_PIC_OFFSET_TABLE_REGNUM - if (! check_pic_pseudo_p - || regno != REAL_PIC_OFFSET_TABLE_REGNUM - || pic_offset_table_rtx == NULL - || i != REGNO (pic_offset_table_rtx)) -#endif - SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno)) bitmap_set_bit (bb_gen_pseudos, regno); } -/* Process the death of hard register REGNO. This updates - hard_regs_live and START_DYING. */ +/* Process the definition of hard register REGNO. This updates + hard_regs_live, START_DYING and conflict hard regs for living + pseudos. Conflict hard regs for the pic pseudo is not updated if + REGNO is REAL_PIC_OFFSET_TABLE_REGNUM and CHECK_PIC_PSEUDO_P is + true. */ static void -make_hard_regno_dead (int regno) +make_hard_regno_dead (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED) { lra_assert (regno < FIRST_PSEUDO_REGISTER); if (! TEST_HARD_REG_BIT (hard_regs_live, regno)) return; sparseset_set_bit (start_dying, regno); + unsigned int i; + EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) +#ifdef REAL_PIC_OFFSET_TABLE_REGNUM + if (! check_pic_pseudo_p + || regno != REAL_PIC_OFFSET_TABLE_REGNUM + || pic_offset_table_rtx == NULL + || i != REGNO (pic_offset_table_rtx)) +#endif + SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); CLEAR_HARD_REG_BIT (hard_regs_live, regno); if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno)) { @@ -267,9 +266,9 @@ make_hard_regno_dead (int regno) } } -/* Mark pseudo REGNO as living at program point POINT, update conflicting - hard registers of the pseudo and START_LIVING, and start a new live - range for the pseudo corresponding to REGNO if it is necessary. */ +/* Mark pseudo REGNO as living at program point POINT, update START_LIVING + and start a new live range for the pseudo corresponding to REGNO if it + is necessary. */ static void mark_pseudo_live (int regno, int point) { @@ -278,7 +277,6 @@ mark_pseudo_live (int regno, int point) lra_assert (regno >= FIRST_PSEUDO_REGISTER); lra_assert (! sparseset_bit_p (pseudos_live, regno)); sparseset_set_bit (pseudos_live, regno); - IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); if ((complete_info_p || lra_get_regno_hard_regno (regno) < 0) && ((p = lra_reg_info[regno].live_ranges) == NULL @@ -301,6 +299,9 @@ mark_pseudo_dead (int regno, int point) lra_assert (sparseset_bit_p (pseudos_live, regno)); sparseset_clear_bit (pseudos_live, regno); sparseset_set_bit (start_dying, regno); + + IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); + if (complete_info_p || lra_get_regno_hard_regno (regno) < 0) { p = lra_reg_info[regno].live_ranges; @@ -322,7 +323,7 @@ mark_regno_live (int regno, machine_mode if (regno < FIRST_PSEUDO_REGISTER) { for (last = end_hard_regno (mode, regno); regno < last; regno++) - make_hard_regno_born (regno, false); + make_hard_regno_live (regno); } else { @@ -349,7 +350,7 @@ mark_regno_dead (int regno, machine_mode if (regno < FIRST_PSEUDO_REGISTER) { for (last = end_hard_regno (mode, regno); regno < last; regno++) - make_hard_regno_dead (regno); + make_hard_regno_dead (regno, false); } else { @@ -834,13 +835,13 @@ process_bb_lives (basic_block bb, int &c for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN) - make_hard_regno_born (reg->regno, false); + make_hard_regno_live (reg->regno); if (curr_id->arg_hard_regs != NULL) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno >= FIRST_PSEUDO_REGISTER) /* It is a clobber. */ - make_hard_regno_born (regno - FIRST_PSEUDO_REGISTER, false); + make_hard_regno_live (regno - FIRST_PSEUDO_REGISTER); sparseset_copy (unused_set, start_living); @@ -857,13 +858,14 @@ process_bb_lives (basic_block bb, int &c for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p) - make_hard_regno_dead (reg->regno); + make_hard_regno_dead (reg->regno, false); if (curr_id->arg_hard_regs != NULL) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno >= FIRST_PSEUDO_REGISTER) - /* It is a clobber. */ - make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER); + /* It is a clobber. Don't create conflict of used + REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ + make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER, true); if (call_p) { @@ -920,14 +922,14 @@ process_bb_lives (basic_block bb, int &c for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_IN) - make_hard_regno_born (reg->regno, false); + make_hard_regno_live (reg->regno); if (curr_id->arg_hard_regs != NULL) /* Make argument hard registers live. Don't create conflict of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno < FIRST_PSEUDO_REGISTER) - make_hard_regno_born (regno, true); + make_hard_regno_live (regno); sparseset_and_compl (dead_set, start_living, start_dying); @@ -952,7 +954,7 @@ process_bb_lives (basic_block bb, int &c if (reg2->type != OP_OUT && reg2->regno == reg->regno) break; if (reg2 == NULL) - make_hard_regno_dead (reg->regno); + make_hard_regno_dead (reg->regno, false); } if (need_curr_point_incr) @@ -995,7 +997,7 @@ process_bb_lives (basic_block bb, int &c if (regno == INVALID_REGNUM) break; - make_hard_regno_born (regno, false); + make_hard_regno_live (regno); } /* Pseudos can't go in stack regs at the start of a basic block that @@ -1009,7 +1011,7 @@ process_bb_lives (basic_block bb, int &c EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, px) lra_reg_info[px].no_stack_p = true; for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++) - make_hard_regno_born (px, false); + make_hard_regno_live (px); #endif /* No need to record conflicts for call clobbered regs if we have nonlocal labels around, as we don't ever try to @@ -1029,7 +1031,7 @@ process_bb_lives (basic_block bb, int &c && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) #endif ) - make_hard_regno_born (px, false); + make_hard_regno_live (px); } bool live_change_p = false; From patchwork Wed Sep 26 21:16:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 975404 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-486514-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="tB2/a77X"; 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 42L9jc6zcjz9s3l for ; Thu, 27 Sep 2018 07:16:36 +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 :subject:from:to:cc:references:date:mime-version:in-reply-to :content-type:content-transfer-encoding:message-id; q=dns; s= default; b=b1B5aHVXa3t1EAjX5H4C4U7SqyICJOwzwUHzYoElRL97HE6SeX98A Bu3feqPgCXjWdamA3PtrMywyXGkGbujE7h2qGSTXpOi+tvoU3HnifEF658g0vHBh 9kAPmWXrqJlAdsXEc18Mr2+DfT2qKkqZ+N4AtOrPbfsb53s6XXRD1k= 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 :subject:from:to:cc:references:date:mime-version:in-reply-to :content-type:content-transfer-encoding:message-id; s=default; bh=aTuKGdFU2amEbXxdRgdBDQnhdQs=; b=tB2/a77XQ95bJK7MfPuEcTsFMgOt DkrVBmTXYh2gmBl0Lg7GEC3uSI/gixSHeKoHJbi6JrhmCMqMOdNOEcyNyaSwdknD KZHt73yVowiQ0tAGhrgPn/QVu+Uw/goe9N3n0SfLEpQ0BQjTWTgXS5B7+B/HYqLS lomxKM4UdB4OCiQ= Received: (qmail 56632 invoked by alias); 26 Sep 2018 21:16:29 -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 56602 invoked by uid 89); 26 Sep 2018 21:16:28 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=H*Ad:U*vmakarov X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 26 Sep 2018 21:16:26 +0000 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w8QL9awj135641 for ; Wed, 26 Sep 2018 17:16:24 -0400 Received: from e17.ny.us.ibm.com (e17.ny.us.ibm.com [129.33.205.207]) by mx0a-001b2d01.pphosted.com with ESMTP id 2mrhr5raea-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 26 Sep 2018 17:16:24 -0400 Received: from localhost by e17.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 26 Sep 2018 17:16:23 -0400 Received: from b01cxnp23033.gho.pok.ibm.com (9.57.198.28) by e17.ny.us.ibm.com (146.89.104.204) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 26 Sep 2018 17:16:21 -0400 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp23033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w8QLGK7i25362522 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 26 Sep 2018 21:16:20 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4E326B2066; Wed, 26 Sep 2018 17:14:40 -0400 (EDT) Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E1DE7B206A; Wed, 26 Sep 2018 17:14:39 -0400 (EDT) Received: from otta.local (unknown [9.80.200.29]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP; Wed, 26 Sep 2018 17:14:39 -0400 (EDT) Subject: [PATCH 2/2][IRA, LRA] Fix PR86939, IRA incorrectly creates an interference between a pseudo register and a hard register From: Peter Bergner To: GCC Patches Cc: Vladimir N Makarov , Jeff Law References: Date: Wed, 26 Sep 2018 16:16:20 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: x-cbid: 18092621-0040-0000-0000-00000476CA6A X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009777; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000267; SDB=6.01094082; UDB=6.00565530; IPR=6.00874119; MB=3.00023520; MTD=3.00000008; XFM=3.00000015; UTC=2018-09-26 21:16:23 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18092621-0041-0000-0000-0000087ECFA7 Message-Id: <9b46a22e-607d-981d-7686-7d25cace39e9@linux.ibm.com> X-IsSubscribed: yes gcc/ * ira.h (copy_insn_p): New prototype. * ira-lives.c (ignore_reg_for_conflicts): New static variable. (make_hard_regno_dead): Don't add conflicts for register ignore_reg_for_conflicts. (make_object_dead): Likewise. (copy_insn_p): New function. (process_bb_node_lives): Set ignore_reg_for_conflicts for copies. * lra-lives.c (ignore_reg_for_conflicts): New static variable. (make_hard_regno_dead): Don't add conflicts for register ignore_reg_for_conflicts. (mark_pseudo_dead): Likewise. (process_bb_lives): Set ignore_reg_for_conflicts for copies. gcc/testsuite/ * gcc.target/powerpc/pr86939.c: New test. Index: gcc/ira.h =================================================================== --- gcc/ira.h (revision 263506) +++ gcc/ira.h (working copy) @@ -210,6 +210,9 @@ extern void ira_adjust_equiv_reg_cost (u /* ira-costs.c */ extern void ira_costs_c_finalize (void); +/* ira-lives.c */ +extern rtx copy_insn_p (rtx_insn *); + /* Spilling static chain pseudo may result in generation of wrong non-local goto code using frame-pointer to address saved stack pointer value after restoring old frame pointer value. The Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c (revision 263506) +++ gcc/ira-lives.c (working copy) @@ -84,6 +84,10 @@ static int *allocno_saved_at_call; supplemental to recog_data. */ static alternative_mask preferred_alternatives; +/* If non-NULL, the source operand of a register to register copy for which + we should not add a conflict with the copy's destination operand. */ +static rtx ignore_reg_for_conflicts; + /* Record hard register REGNO as now being live. */ static void make_hard_regno_live (int regno) @@ -101,6 +105,11 @@ make_hard_regno_dead (int regno) { ira_object_t obj = ira_object_id_map[i]; + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) + == (unsigned int) ALLOCNO_REGNO (OBJECT_ALLOCNO (obj))) + continue; + SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno); SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno); } @@ -154,12 +163,38 @@ static void make_object_dead (ira_object_t obj) { live_range_t lr; + int ignore_regno = -1; + int last_regno = -1; sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (obj)); + /* Check whether any part of IGNORE_REG_FOR_CONFLICTS already conflicts + with OBJ. */ + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) < FIRST_PSEUDO_REGISTER) + { + last_regno = END_REGNO (ignore_reg_for_conflicts); + int src_regno = ignore_regno = REGNO (ignore_reg_for_conflicts); + + while (src_regno < last_regno) + { + if (TEST_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), src_regno)) + { + ignore_regno = last_regno = -1; + break; + } + src_regno++; + } + } + IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live); IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live); + /* If IGNORE_REG_FOR_CONFLICTS did not already conflict with OBJ, make + sure it still doesn't. */ + for (; ignore_regno < last_regno; ignore_regno++) + CLEAR_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), ignore_regno); + lr = OBJECT_LIVE_RANGES (obj); ira_assert (lr != NULL); lr->finish = curr_point; @@ -1022,6 +1057,38 @@ find_call_crossed_cheap_reg (rtx_insn *i return cheap_reg; } +/* Determine whether INSN is a register to register copy of the type where + we do not need to make the source and destiniation registers conflict. + If this is a copy instruction, then return the source reg. Otherwise, + return NULL_RTX. */ +rtx +copy_insn_p (rtx_insn *insn) +{ + rtx set; + + /* Disallow anything other than a simple register to register copy + that has no side effects. */ + if ((set = single_set (insn)) == NULL_RTX + || !REG_P (SET_DEST (set)) + || !REG_P (SET_SRC (set)) + || side_effects_p (set)) + return NULL_RTX; + + int dst_regno = REGNO (SET_DEST (set)); + int src_regno = REGNO (SET_SRC (set)); + machine_mode mode = GET_MODE (SET_DEST (set)); + + /* Computing conflicts for register pairs is difficult to get right, so + for now, disallow it. */ + if ((dst_regno < FIRST_PSEUDO_REGISTER + && hard_regno_nregs (dst_regno, mode) != 1) + || (src_regno < FIRST_PSEUDO_REGISTER + && hard_regno_nregs (src_regno, mode) != 1)) + return NULL_RTX; + + return SET_SRC (set); +} + /* Process insns of the basic block given by its LOOP_TREE_NODE to update allocno live ranges, allocno hard register conflicts, intersected calls, and register pressure info for allocnos for the @@ -1107,6 +1174,7 @@ process_bb_node_lives (ira_loop_tree_nod curr_point); call_p = CALL_P (insn); + ignore_reg_for_conflicts = copy_insn_p (insn); #ifdef REAL_PIC_OFFSET_TABLE_REGNUM int regno; bool clear_pic_use_conflict_p = false; @@ -1289,6 +1357,7 @@ process_bb_node_lives (ira_loop_tree_nod #endif curr_point++; } + ignore_reg_for_conflicts = NULL_RTX; if (bb_has_eh_pred (bb)) for (j = 0; ; ++j) Index: gcc/ira-lives.c =================================================================== --- gcc/lra-lives.c (revision 263506) +++ gcc/lra-lives.c (working copy) @@ -96,6 +96,10 @@ static bitmap_head temp_bitmap; /* Pool for pseudo live ranges. */ static object_allocator lra_live_range_pool ("live ranges"); +/* If non-NULL, the source operand of a register to register copy for which + we should not add a conflict with the copy's destination operand. */ +static rtx ignore_reg_for_conflicts; + /* Free live range list LR. */ static void free_live_range_list (lra_live_range_t lr) @@ -251,13 +255,18 @@ make_hard_regno_dead (int regno, bool ch sparseset_set_bit (start_dying, regno); unsigned int i; EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) + { + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) == i) + continue; #ifdef REAL_PIC_OFFSET_TABLE_REGNUM - if (! check_pic_pseudo_p - || regno != REAL_PIC_OFFSET_TABLE_REGNUM - || pic_offset_table_rtx == NULL - || i != REGNO (pic_offset_table_rtx)) + if (! check_pic_pseudo_p + || regno != REAL_PIC_OFFSET_TABLE_REGNUM + || pic_offset_table_rtx == NULL + || i != REGNO (pic_offset_table_rtx)) #endif - SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); + SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); + } CLEAR_HARD_REG_BIT (hard_regs_live, regno); if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno)) { @@ -294,14 +303,41 @@ static void mark_pseudo_dead (int regno, int point) { lra_live_range_t p; + int ignore_regno = -1; + int last_regno = -1; lra_assert (regno >= FIRST_PSEUDO_REGISTER); lra_assert (sparseset_bit_p (pseudos_live, regno)); sparseset_clear_bit (pseudos_live, regno); sparseset_set_bit (start_dying, regno); + /* Check whether any part of IGNORE_REG_FOR_CONFLICTS already conflicts + with REGNO. */ + if (ignore_reg_for_conflicts != NULL_RTX + && REGNO (ignore_reg_for_conflicts) < FIRST_PSEUDO_REGISTER) + { + last_regno = END_REGNO (ignore_reg_for_conflicts); + int src_regno = ignore_regno = REGNO (ignore_reg_for_conflicts); + + while (src_regno < last_regno) + { + if (TEST_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, + src_regno)) + { + ignore_regno = last_regno = -1; + break; + } + src_regno++; + } + } + IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); + /* If IGNORE_REG_FOR_CONFLICTS did not already conflict with REGNO, make + sure it still doesn't. */ + for (; ignore_regno < last_regno; ignore_regno++) + CLEAR_HARD_REG_BIT (lra_reg_info[regno].conflict_hard_regs, ignore_regno); + if (complete_info_p || lra_get_regno_hard_regno (regno) < 0) { p = lra_reg_info[regno].live_ranges; @@ -747,6 +783,7 @@ process_bb_lives (basic_block bb, int &c } call_p = CALL_P (curr_insn); + ignore_reg_for_conflicts = copy_insn_p (curr_insn); src_regno = (set != NULL_RTX && REG_P (SET_SRC (set)) ? REGNO (SET_SRC (set)) : -1); dst_regno = (set != NULL_RTX && REG_P (SET_DEST (set)) @@ -989,6 +1026,7 @@ process_bb_lives (basic_block bb, int &c EXECUTE_IF_SET_IN_SPARSESET (unused_set, j) add_reg_note (curr_insn, REG_UNUSED, regno_reg_rtx[j]); } + ignore_reg_for_conflicts = NULL_RTX; if (bb_has_eh_pred (bb)) for (j = 0; ; ++j) Index: gcc/testsuite/gcc.target/powerpc/pr86939.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr86939.c (nonexistent) +++ gcc/testsuite/gcc.target/powerpc/pr86939.c (working copy) @@ -0,0 +1,12 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-options "-O2" } */ + +typedef long (*fptr_t) (void); +long +func (fptr_t *p) +{ + if (p) + return (*p) (); + return 0; +} +/* { dg-final { scan-assembler-not {mr %?r?12,} } } */