From patchwork Thu Mar 24 14:38:30 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 88207 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 E5319B6F84 for ; Fri, 25 Mar 2011 01:43:10 +1100 (EST) Received: (qmail 3741 invoked by alias); 24 Mar 2011 14:43:08 -0000 Received: (qmail 3732 invoked by uid 22791); 24 Mar 2011 14:43:07 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 24 Mar 2011 14:43:01 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id BE4DD29000B for ; Thu, 24 Mar 2011 15:43:00 +0100 (CET) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3a5rxxw+xSTH for ; Thu, 24 Mar 2011 15:42:57 +0100 (CET) Received: from [192.168.1.2] (bon31-9-83-155-120-49.fbx.proxad.net [83.155.120.49]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id A07DE290027 for ; Thu, 24 Mar 2011 15:42:57 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Do not generate useless branches for multi-word comparison Date: Thu, 24 Mar 2011 15:38:30 +0100 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Message-Id: <201103241538.30183.ebotcazou@adacore.com> Content-Disposition: inline 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 Hi, this improves the RTL generated for multi-word comparison to avoid generating useless branches. In do_jump_by_parts_greater_rtx: 1) do not generate the last cond jump, 2) do not generate the uncond branch to the drop-through label, if any, 3) generate only one comparison for the special (0 > x) case. Tested on i586-suse-linux, OK for the mainline? 2011-03-24 Eric Botcazou * dojump.c (do_jump_by_parts_greater_rtx): Optimize in specific cases. Index: dojump.c =================================================================== --- dojump.c (revision 171345) +++ dojump.c (working copy) @@ -637,14 +637,32 @@ do_jump_by_parts_greater_rtx (enum machi { int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); rtx drop_through_label = 0; + bool drop_through_if_true = false, drop_through_if_false = false; + enum rtx_code code = GT; int i; if (! if_true_label || ! if_false_label) drop_through_label = gen_label_rtx (); if (! if_true_label) - if_true_label = drop_through_label; + { + if_true_label = drop_through_label; + drop_through_if_true = true; + } if (! if_false_label) - if_false_label = drop_through_label; + { + if_false_label = drop_through_label; + drop_through_if_false = true; + } + + /* Deal with the special case 0 > x: only one comparison is necessary and + we reverse it to avoid jumping to the drop-through label. */ + if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false) + { + code = LE; + if_true_label = if_false_label; + if_false_label = drop_through_label; + drop_through_if_false = true; + } /* Compare a word at a time, high order first. */ for (i = 0; i < nwords; i++) @@ -663,17 +681,20 @@ do_jump_by_parts_greater_rtx (enum machi } /* All but high-order word must be compared as unsigned. */ - do_compare_rtx_and_jump (op0_word, op1_word, GT, - (unsignedp || i > 0), word_mode, NULL_RTX, - NULL_RTX, if_true_label, prob); + do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0), + word_mode, NULL_RTX, NULL_RTX, if_true_label, + prob); + + /* Emit only one comparison for 0. Do not emit the last cond jump. */ + if (op0 == const0_rtx || i == nwords - 1) + break; /* Consider lower words only if these are equal. */ do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, - NULL_RTX, NULL_RTX, if_false_label, - inv (prob)); + NULL_RTX, NULL_RTX, if_false_label, inv (prob)); } - if (if_false_label) + if (!drop_through_if_false) emit_jump (if_false_label); if (drop_through_label) emit_label (drop_through_label);