From patchwork Fri Jun 27 18:07:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Yang X-Patchwork-Id: 365095 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 1E9A2140078 for ; Sat, 28 Jun 2014 04:08:11 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=vncJwXNV09DOcg2dBHW70mnkqCiDO29F8H2PA0sGgcL m4UexDhFPFSYxxveGsawnTDzAN419fXsfHfoqDIY4nbPHU6jzraZe3jVW760HPxA 2dXZIuSRl8+ufxj4KFMZ2tz/xHChAhyLoJandz5PuXrndga2qp/25APd6HCiD2Uo = 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 :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=fl7H0V1kopGzThuzI3iqHjPNNNU=; b=Ae2jQFsWNt6sYGnxh svhN3MP7CRyAmWB6F73us1m4mc63VBi65vi39R9Pjg0RI2OPN8FOhF551n3d2xTQ 3xN2UVhB/m3DjIO1qhp4xMxUOju2vsUuI0D4FOa7GvBadICLQ7koYhBBrzEW8QaZ YPY3BsH8Tut+VwyHkbo6JqcQsE= Received: (qmail 13917 invoked by alias); 27 Jun 2014 18:08:04 -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 13899 invoked by uid 89); 27 Jun 2014 18:08:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-ig0-f181.google.com Received: from mail-ig0-f181.google.com (HELO mail-ig0-f181.google.com) (209.85.213.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 27 Jun 2014 18:08:00 +0000 Received: by mail-ig0-f181.google.com with SMTP id h15so2239896igd.14 for ; Fri, 27 Jun 2014 11:07:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc :content-type; bh=19cXBrtbRzXh2GBllhnqSODgS8YPx2iw3/NVW7QXC18=; b=TQFbw72bVj9L663OXvqO9X1QHirZ7Aahb0negvhvJWS9i9LZiEqj+zMfL3jPwGhj8l raQXe3QdKMGO0FOfulJDnb2D8gqwM9o5fYNHequOdSInPlyjbjyGwEnKyRrdKtO2yQeA eJ4zV/s35OlYx1ckm1IXVXLL9guIpOkc57OY8ASODQl4lwebwpKKCg1j0c8gXd8IeD8z p3/jvs3DkV/TuwcyQriYqATPrlHIUQ+s+Kx/24EjOlQ8YmTeKTu/+hBI6iL6ZMQkQYfd ZJT5f4r3rrw/VBbBHTPHT+rI2/8J2mDAORv94DWgwGI6GJF4e+T/9eOuKbwhOOdVBwCX smCw== X-Gm-Message-State: ALoCoQnUxu8TUJIzznvZ36f8J71kOnb8y83SoFwgCo+rn4dVx8YIEOtuONy4VFS11r/66py18O6o X-Received: by 10.43.179.73 with SMTP id oz9mr22119677icc.18.1403892477993; Fri, 27 Jun 2014 11:07:57 -0700 (PDT) MIME-Version: 1.0 Received: by 10.64.19.200 with HTTP; Fri, 27 Jun 2014 11:07:37 -0700 (PDT) From: Yi Yang Date: Fri, 27 Jun 2014 11:07:37 -0700 Message-ID: Subject: [GOOGLE] Report the difference between profiled and guessed or annotated branch probabilities. To: gcc-patches@gcc.gnu.org Cc: Dehao Chen X-IsSubscribed: yes Hi, This patch adds an option. When the option is enabled, GCC will add a record about it in an elf section called ".gnu.switches.text.branch.annotation" for every branch. gcc/ 2014-06-27 Yi Yang * auto-profile.c: Main comparison and reporting logic. * cfg-flags.def: Add an extra flag representing an edge's probability is predicted by annotations. * predict.c: Set up the extra flag on an edge when appropriate. * common.opt: Add an extra GCC option to turn on this report mechanism diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c index 74d3d1d..f7698cd 100644 --- a/gcc/auto-profile.c +++ b/gcc/auto-profile.c @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see #include "opts.h" /* for in_fnames. */ #include "tree-pass.h" /* for ipa pass. */ #include "cfgloop.h" /* for loop_optimizer_init. */ +#include "md5.h" /* for hashing function names. */ #include "gimple.h" #include "cgraph.h" #include "tree-flow.h" @@ -1367,6 +1368,80 @@ afdo_propagate (void) } } +struct locus_information_t { + char filename[1024]; + unsigned lineno; + unsigned function_lineno; + char function_hash[33]; +}; + +static bool +get_locus_information (location_t locus, locus_information_t* li) { + if (locus == UNKNOWN_LOCATION || !LOCATION_FILE(locus)) + return false; + snprintf(li->filename, 1024, "%s", LOCATION_FILE(locus)); + li->lineno = LOCATION_LINE(locus); + + tree block = LOCATION_BLOCK (locus); + tree function_decl = current_function_decl; + + if (block && TREE_CODE (block) == BLOCK) + { + for (block = BLOCK_SUPERCONTEXT (block); + block && (TREE_CODE (block) == BLOCK); + block = BLOCK_SUPERCONTEXT (block)) + { + location_t tmp_locus = BLOCK_SOURCE_LOCATION (block); + if (LOCATION_LOCUS (tmp_locus) == UNKNOWN_LOCATION) + continue; + + tree decl = get_function_decl_from_block (block); + function_decl = decl; + break; + } + } + + if (!(function_decl && TREE_CODE (function_decl) == FUNCTION_DECL)) + return false; + unsigned function_length = 0; + function *f = DECL_STRUCT_FUNCTION(function_decl); + + li->function_lineno = LOCATION_LINE(DECL_SOURCE_LOCATION(function_decl)); + + if (f) + { + function_length = LOCATION_LINE(f->function_end_locus) - + li->function_lineno; + } + + const char *fn_name = fndecl_name(function_decl); + unsigned char md5_result[16]; + + md5_ctx ctx; + + md5_init_ctx(&ctx); + md5_process_bytes(fn_name, strlen(fn_name), &ctx); + md5_process_bytes(&function_length, sizeof(function_length), &ctx); + md5_finish_ctx(&ctx, md5_result); + + for (int i = 0; i < 16; ++i) + { + sprintf(li->function_hash + i*2, "%02x", md5_result[i]); + } + + return true; +} + +void +fill_invalid_locus_information(locus_information_t* li) { + snprintf(li->filename, 1024, ""); + li->lineno = 0; + li->function_lineno = 0; + for (int i = 0; i < 32; ++i) + li->function_hash[i] = '0'; + li->function_hash[32] = '\0'; +} + /* Propagate counts on control flow graph and calculate branch probabilities. */ @@ -1407,8 +1482,62 @@ afdo_calculate_branch_prob (void) if (num_unknown_succ == 0 && total_count > 0) { FOR_EACH_EDGE (e, ei, bb->succs) - e->probability = - (double) e->count * REG_BR_PROB_BASE / total_count; + { + double probability = + (double) e->count * REG_BR_PROB_BASE / total_count; + + if (flag_check_branch_annotation && + bb->succs->length() == 2 && + maybe_hot_count_p (cfun, bb->count) && + bb->count >= 100) + { + gimple_stmt_iterator gsi; + gimple last = NULL; + + for (gsi = gsi_last_nondebug_bb (bb); + !gsi_end_p (gsi); + gsi_prev_nondebug (&gsi)) + { + last = gsi_stmt (gsi); + + if (gimple_has_location (last)) + break; + } + + struct locus_information_t li; + bool annotated; + + if (e->flags & EDGE_PREDICTED_BY_EXPECT) + annotated = true; + else + annotated = false; + + if (get_locus_information(e->goto_locus, &li)) + ; + else if (get_locus_information(gimple_location(last), &li)) + ; + else + fill_invalid_locus_information(&li); + + switch_to_section (get_section ( + ".gnu.switches.text.branch.annotation", + SECTION_DEBUG | SECTION_MERGE | + SECTION_STRINGS | (SECTION_ENTSIZE & 1), + NULL)); + char buf[1024]; + snprintf (buf, 1024, "%s;%u;%d;" + HOST_WIDEST_INT_PRINT_DEC";%.6lf;%.6lf;%s;%u", + li.filename, li.lineno, bb->count, annotated?1:0, + probability/REG_BR_PROB_BASE, + e->probability/(double)REG_BR_PROB_BASE, + li.function_hash, li.function_lineno); + dw2_asm_output_nstring (buf, (size_t)-1, NULL); + + break; + } + + e->probability = probability; + } } } FOR_ALL_BB (bb) @@ -1417,8 +1546,11 @@ afdo_calculate_branch_prob (void) edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->succs) - e->count = - (double) bb->count * e->probability / REG_BR_PROB_BASE; + { + e->count = + (double) bb->count * e->probability / REG_BR_PROB_BASE; + e->flags &= ~EDGE_PREDICTED_BY_EXPECT; + } bb->aux = NULL; } @@ -1542,9 +1674,9 @@ afdo_annotate_cfg (const stmt_set &promoted_stmts) afdo_source_profile->mark_annotated (cfun->function_end_locus); if (max_count > 0) { + profile_status = PROFILE_READ; afdo_calculate_branch_prob (); counts_to_freqs (); - profile_status = PROFILE_READ; } if (flag_value_profile_transformations) gimple_value_profile_transformations (); diff --git a/gcc/cfg-flags.def b/gcc/cfg-flags.def index 42a0473..5904d8d 100644 --- a/gcc/cfg-flags.def +++ b/gcc/cfg-flags.def @@ -186,6 +186,9 @@ DEF_EDGE_FLAG(TM_ABORT, 16) /* Annotated during AutoFDO profile attribution. */ DEF_EDGE_FLAG(ANNOTATED, 17) +/* Edge probability predicted by __builtin_expect. */ +DEF_EDGE_FLAG(PREDICTED_BY_EXPECT, 18) + #endif /* diff --git a/gcc/common.opt b/gcc/common.opt index 4305c89..5ac159e 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -950,6 +950,10 @@ fauto-profile-record-coverage-in-elf Common Report Var(flag_auto_profile_record_coverage_in_elf) Optimization Whether to record annotation coverage info in elf. +fcheck-branch-annotation +Common Report Var(flag_check_branch_annotation) +Record branch prediction information in elf. + ; -fcheck-bounds causes gcc to generate array bounds checks. ; For C, C++ and ObjC: defaults off. ; For Java: defaults to on. diff --git a/gcc/predict.c b/gcc/predict.c index f27c58c..cecc801 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -1014,6 +1014,11 @@ combine_predictions_for_bb (basic_block bb) { first->probability = combined_probability; second->probability = REG_BR_PROB_BASE - combined_probability; + if (first_match && best_predictor == PRED_BUILTIN_EXPECT) + { + first->flags |= EDGE_PREDICTED_BY_EXPECT; + second->flags |= EDGE_PREDICTED_BY_EXPECT; + } } } --