From patchwork Wed Oct 26 17:58:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Monakov X-Patchwork-Id: 121957 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 37F701007DA for ; Thu, 27 Oct 2011 04:59:08 +1100 (EST) Received: (qmail 23587 invoked by alias); 26 Oct 2011 17:59:06 -0000 Received: (qmail 23576 invoked by uid 22791); 26 Oct 2011 17:59:05 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp.ispras.ru (HELO smtp.ispras.ru) (83.149.198.202) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 26 Oct 2011 17:58:50 +0000 Received: from ispserv.ispras.ru (ispserv.ispras.ru [83.149.198.72]) by smtp.ispras.ru (Postfix) with ESMTP id E6C245D4034; Wed, 26 Oct 2011 21:43:56 +0400 (MSD) Received: from monoid.intra.ispras.ru (winnie.ispras.ru [83.149.198.236]) by ispserv.ispras.ru (Postfix) with ESMTP id 43FED3FC48; Wed, 26 Oct 2011 21:58:49 +0400 (MSD) Date: Wed, 26 Oct 2011 21:58:49 +0400 (MSD) From: Alexander Monakov To: gcc-patches@gcc.gnu.org cc: "Vladimir N. Makarov" Subject: Re: [PATCH 3/3, RFC] Fixup COND_EXECs before reload In-Reply-To: Message-ID: References: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 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 This RFC patch implements conversion of COND_EXEC instructions to control flow for pre-RA selective scheduler. Something like this is needed to employ predication support before reload. Each COND_EXEC is converted separately to a new basic block with the unconditional variant of the instruction, and a conditional jump around it. I'm not sure what would be an acceptable approach here. I'm also not sure about the recommended way to emit JUMPs. 2011-10-26 Sergey Grechanik * sel-sched.c (convert_cond_execs): New. Use it... (sel_global_finish): ... here. diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index f5c6f8b..b8f2663 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see #include "rtlhooks-def.h" #include "output.h" #include "emit-rtl.h" +#include "cfghooks.h" #ifdef INSN_SCHEDULING #include "sel-sched-ir.h" @@ -7978,6 +7979,60 @@ sel_global_init (void) init_hard_regs_data (); } +/* Convert cond_execs to jumps before reload. */ +static void +convert_cond_execs (void) +{ + basic_block bb; + rtx insn; + + if (reload_completed) + return; + + FOR_EACH_BB (bb) + /* We don't need the safe variant because we break immediately after + removing the current instruction. */ + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == COND_EXEC) + { + rtx jump; + rtx cond = COND_EXEC_TEST (PATTERN (insn)); + rtx rcond = reversed_comparison (cond, GET_MODE (cond)); + rtx unpredicated = copy_rtx (COND_EXEC_CODE (PATTERN (insn))); + + /* Split bb into BB, NEW_BB, NEXT_BB (in that order). */ + edge e1 = split_block (bb, insn); + basic_block next_bb = e1->dest; + edge e2 = split_block (bb, insn); + basic_block new_bb = e2->dest; + + /* Emit conditional jump at the end of bb. */ + rtx label = block_label (next_bb); + + /* FIXME There should be a better way. */ + rtx jump_pat + = gen_rtx_SET (GET_MODE (pc_rtx), pc_rtx, + gen_rtx_IF_THEN_ELSE (GET_MODE (pc_rtx), + rcond, + gen_rtx_LABEL_REF (VOIDmode, + label), + pc_rtx)); + + make_edge (bb, next_bb, 0); + jump = emit_jump_insn_after (jump_pat, BB_END (bb)); + JUMP_LABEL (jump) = label; + LABEL_NUSES (label)++; + + emit_insn_after_noloc (unpredicated, BB_HEAD (new_bb), new_bb); + + delete_insn (insn); + break; + } +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif +} + /* Free the global data of the scheduler. */ static void sel_global_finish (void) @@ -7998,6 +8053,8 @@ sel_global_finish (void) free_sched_pools (); free_dominance_info (CDI_DOMINATORS); + + convert_cond_execs (); } /* Return true when we need to skip selective scheduling. Used for debugging. */