From patchwork Fri Nov 16 10:45:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 998850 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-490237-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="L+DtsCUs"; 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 42xFJW0w4zz9s1c for ; Fri, 16 Nov 2018 21:46:02 +1100 (AEDT) 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=NLGMdJY9Yyxro/bS VoFOZghKpEagiNwp3hNZO0XKWnI+pFUidXTQ4XldNW1HtCgSguRSIdebvtfdq22i y2W4mJfIaotnuuDjPM5NbgiwObxVKxaaVSQGrBDdAMPR7qmZjcWSkfN5Vc6sbB/V tHUyjso/9clvd4VFVW5zutD7CMs= 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=w8SUNAe/w7jFeBarbBa2lk 8Kvy4=; b=L+DtsCUs/q4M8EN1lBicPipNQN2GL0vODjY/+adtINJcKmWHVdHr3h jRHN1OkYgaxYU8LmmRug+CoZXLvsz2cYjb7bDzXRmS+j0pH1Lzgp6wBeG0n4i1Mx 92kAupK+7xFBD7uzIdS82dD9n0xoWHVlDCQCMNiDQlMgk3Rra/OoQ= Received: (qmail 80070 invoked by alias); 16 Nov 2018 10:45:55 -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 80041 invoked by uid 89); 16 Nov 2018 10:45:54 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=5667, aux, U*ebotcazou, ebotcazouadacorecom 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; Fri, 16 Nov 2018 10:45:51 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id E794B8220F for ; Fri, 16 Nov 2018 11:45:48 +0100 (CET) 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 94ROntTlC-QZ for ; Fri, 16 Nov 2018 11:45:48 +0100 (CET) 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 B302D81F6E for ; Fri, 16 Nov 2018 11:45:48 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Propagate location into decision tree for switches Date: Fri, 16 Nov 2018 11:45:46 +0100 Message-ID: <2680718.7XLNcfSzcx@polaris> MIME-Version: 1.0 Hi, since the expansion of switches statement into decision trees was moved from RTL to GIMPLE, the location information of the comparison statements has been lost, i.e. GIMPLE generates comparison statements with UNKNOWN_LOCATION and they are expanded as-is into RTL. Now this can be problematic for coverage analysis because the statements can inherit a wrong location in the assembly. Therefore the attached patch propagates the location from the switch statement to every comparison statement generated for the decision tree. Tested on x86_64-suse-linux, OK for mainline and 8 branch? 2018-11-16 Eric Botcazou * tree-switch-conversion.h (switch_decision_tree::emit_case_nodes): Add location_t parameter. (switch_decision_tree::emit_cmp_and_jump_insns): Likewise. (switch_decision_tree::do_jump_if_equal): Likewise. * tree-switch-conversion.c (switch_decision_tree::emit): Pass location of switch statement to emit_case_nodes. (switch_decision_tree::emit_cmp_and_jump_insns): Add LOC parameter and set it on the newly built GIMPLE comparison statement. (switch_decision_tree::do_jump_if_equal): Likewise. (switch_decision_tree::emit_case_nodes): Add LOC parameter and pass it into calls to do_jump_if_equal as well as recursive calls. Index: tree-switch-conversion.c =================================================================== --- tree-switch-conversion.c (revision 266178) +++ tree-switch-conversion.c (working copy) @@ -1942,7 +1942,8 @@ switch_decision_tree::emit (basic_block dump_case_nodes (dump_file, m_case_list, indent_step, 0); } - bb = emit_case_nodes (bb, index_expr, m_case_list, default_prob, index_type); + bb = emit_case_nodes (bb, index_expr, m_case_list, default_prob, index_type, + gimple_location (m_switch)); if (bb) emit_jump (bb, m_default_bb); @@ -2085,12 +2086,14 @@ basic_block switch_decision_tree::emit_cmp_and_jump_insns (basic_block bb, tree op0, tree op1, tree_code comparison, basic_block label_bb, - profile_probability prob) + profile_probability prob, + location_t loc) { // TODO: it's once called with lhs != index. op1 = fold_convert (TREE_TYPE (op0), op1); gcond *cond = gimple_build_cond (comparison, op0, op1, NULL_TREE, NULL_TREE); + gimple_set_location (cond, loc); gimple_stmt_iterator gsi = gsi_last_bb (bb); gsi_insert_after (&gsi, cond, GSI_NEW_STMT); @@ -2114,11 +2117,13 @@ switch_decision_tree::emit_cmp_and_jump_ basic_block switch_decision_tree::do_jump_if_equal (basic_block bb, tree op0, tree op1, basic_block label_bb, - profile_probability prob) + profile_probability prob, + location_t loc) { op1 = fold_convert (TREE_TYPE (op0), op1); gcond *cond = gimple_build_cond (EQ_EXPR, op0, op1, NULL_TREE, NULL_TREE); + gimple_set_location (cond, loc); gimple_stmt_iterator gsi = gsi_last_bb (bb); gsi_insert_before (&gsi, cond, GSI_SAME_STMT); @@ -2145,7 +2150,7 @@ basic_block switch_decision_tree::emit_case_nodes (basic_block bb, tree index, case_tree_node *node, profile_probability default_prob, - tree index_type) + tree index_type, location_t loc) { profile_probability p; @@ -2160,7 +2165,7 @@ switch_decision_tree::emit_case_nodes (b this node and then check our children, if any. */ p = node->m_c->m_prob / (node->m_c->m_subtree_prob + default_prob); bb = do_jump_if_equal (bb, index, node->m_c->get_low (), - node->m_c->m_case_bb, p); + node->m_c->m_case_bb, p, loc); /* Since this case is taken at this point, reduce its weight from subtree_weight. */ node->m_c->m_subtree_prob -= p; @@ -2181,12 +2186,12 @@ switch_decision_tree::emit_case_nodes (b p = (node->m_right->m_c->m_prob / (node->m_c->m_subtree_prob + default_prob)); bb = do_jump_if_equal (bb, index, node->m_right->m_c->get_low (), - node->m_right->m_c->m_case_bb, p); + node->m_right->m_c->m_case_bb, p, loc); p = (node->m_left->m_c->m_prob / (node->m_c->m_subtree_prob + default_prob)); bb = do_jump_if_equal (bb, index, node->m_left->m_c->get_low (), - node->m_left->m_c->m_case_bb, p); + node->m_left->m_c->m_case_bb, p, loc); } else { @@ -2199,12 +2204,12 @@ switch_decision_tree::emit_case_nodes (b + default_prob.apply_scale (1, 2)) / (node->m_c->m_subtree_prob + default_prob)); bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (), - GT_EXPR, test_bb, p); + GT_EXPR, test_bb, p, loc); default_prob = default_prob.apply_scale (1, 2); /* Handle the left-hand subtree. */ bb = emit_case_nodes (bb, index, node->m_left, - default_prob, index_type); + default_prob, index_type, loc); /* If the left-hand subtree fell through, don't let it fall into the right-hand subtree. */ @@ -2212,7 +2217,7 @@ switch_decision_tree::emit_case_nodes (b emit_jump (bb, m_default_bb); bb = emit_case_nodes (test_bb, index, node->m_right, - default_prob, index_type); + default_prob, index_type, loc); } } else if (node->m_left == NULL && node->m_right != NULL) @@ -2232,11 +2237,11 @@ switch_decision_tree::emit_case_nodes (b p = (default_prob.apply_scale (1, 2) / (node->m_c->m_subtree_prob + default_prob)); bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_low (), - LT_EXPR, m_default_bb, p); + LT_EXPR, m_default_bb, p, loc); default_prob = default_prob.apply_scale (1, 2); bb = emit_case_nodes (bb, index, node->m_right, default_prob, - index_type); + index_type, loc); } else { @@ -2246,7 +2251,7 @@ switch_decision_tree::emit_case_nodes (b p = (node->m_right->m_c->m_subtree_prob / (node->m_c->m_subtree_prob + default_prob)); bb = do_jump_if_equal (bb, index, node->m_right->m_c->get_low (), - node->m_right->m_c->m_case_bb, p); + node->m_right->m_c->m_case_bb, p, loc); } } else if (node->m_left != NULL && node->m_right == NULL) @@ -2259,11 +2264,11 @@ switch_decision_tree::emit_case_nodes (b p = (default_prob.apply_scale (1, 2) / (node->m_c->m_subtree_prob + default_prob)); bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (), - GT_EXPR, m_default_bb, p); + GT_EXPR, m_default_bb, p, loc); default_prob = default_prob.apply_scale (1, 2); bb = emit_case_nodes (bb, index, node->m_left, default_prob, - index_type); + index_type, loc); } else { @@ -2273,7 +2278,7 @@ switch_decision_tree::emit_case_nodes (b p = (node->m_left->m_c->m_subtree_prob / (node->m_c->m_subtree_prob + default_prob)); bb = do_jump_if_equal (bb, index, node->m_left->m_c->get_low (), - node->m_left->m_c->m_case_bb, p); + node->m_left->m_c->m_case_bb, p, loc); } } } @@ -2297,17 +2302,17 @@ switch_decision_tree::emit_case_nodes (b / (node->m_c->m_subtree_prob + default_prob)); bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (), - GT_EXPR, test_bb, p); + GT_EXPR, test_bb, p, loc); default_prob = default_prob.apply_scale (1, 2); /* Value belongs to this node or to the left-hand subtree. */ p = node->m_c->m_prob / (node->m_c->m_subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_low (), - GE_EXPR, node->m_c->m_case_bb, p); + GE_EXPR, node->m_c->m_case_bb, p, loc); /* Handle the left-hand subtree. */ bb = emit_case_nodes (bb, index, node->m_left, - default_prob, index_type); + default_prob, index_type, loc); /* If the left-hand subtree fell through, don't let it fall into the right-hand subtree. */ @@ -2315,7 +2320,7 @@ switch_decision_tree::emit_case_nodes (b emit_jump (bb, m_default_bb); bb = emit_case_nodes (test_bb, index, node->m_right, - default_prob, index_type); + default_prob, index_type, loc); } else { @@ -2328,7 +2333,7 @@ switch_decision_tree::emit_case_nodes (b p = default_prob / (node->m_c->m_subtree_prob + default_prob); bb = emit_cmp_and_jump_insns (bb, lhs, rhs, GT_EXPR, - m_default_bb, p); + m_default_bb, p, loc); emit_jump (bb, node->m_c->m_case_bb); return NULL; Index: tree-switch-conversion.h =================================================================== --- tree-switch-conversion.h (revision 266178) +++ tree-switch-conversion.h (working copy) @@ -566,7 +566,7 @@ struct switch_decision_tree basic_block emit_case_nodes (basic_block bb, tree index, case_tree_node *node, profile_probability default_prob, - tree index_type); + tree index_type, location_t); /* Take an ordered list of case nodes and transform them into a near optimal binary tree, @@ -594,13 +594,15 @@ struct switch_decision_tree static basic_block emit_cmp_and_jump_insns (basic_block bb, tree op0, tree op1, tree_code comparison, basic_block label_bb, - profile_probability prob); + profile_probability prob, + location_t); /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB is the probability of jumping to LABEL_BB. */ static basic_block do_jump_if_equal (basic_block bb, tree op0, tree op1, basic_block label_bb, - profile_probability prob); + profile_probability prob, + location_t); /* Reset the aux field of all outgoing edges of switch basic block. */ static inline void reset_out_edges_aux (gswitch *swtch);