From patchwork Thu Apr 28 23:18:30 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xinliang David Li X-Patchwork-Id: 93349 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 5010FB6F7D for ; Fri, 29 Apr 2011 09:19:35 +1000 (EST) Received: (qmail 10131 invoked by alias); 28 Apr 2011 23:19:16 -0000 Received: (qmail 9997 invoked by uid 22791); 28 Apr 2011 23:19:01 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_CP, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (74.125.121.67) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 28 Apr 2011 23:18:36 +0000 Received: from hpaq6.eem.corp.google.com (hpaq6.eem.corp.google.com [172.25.149.6]) by smtp-out.google.com with ESMTP id p3SNIYbh015252; Thu, 28 Apr 2011 16:18:34 -0700 Received: from aples.mtv.corp.google.com (aples.mtv.corp.google.com [172.18.118.47]) by hpaq6.eem.corp.google.com with ESMTP id p3SNIVO9001538; Thu, 28 Apr 2011 16:18:32 -0700 Received: by aples.mtv.corp.google.com (Postfix, from userid 74076) id 0DC0A1B4093; Thu, 28 Apr 2011 16:18:30 -0700 (PDT) To: reply@codereview.appspotmail.com, xur@google.com, gcc-patches@gcc.gnu.org Subject: [google] LIPO regression tests and bug fixes (issue4444076) Message-Id: <20110428231831.0DC0A1B4093@aples.mtv.corp.google.com> Date: Thu, 28 Apr 2011 16:18:30 -0700 (PDT) From: davidxl@google.com (David Li) X-System-Of-Record: true X-IsSubscribed: yes 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 patch added regression tests for LIPO in google/main and fixes a couple of bugs found in app testing: 1) duplicate assembler labels in .s file 2) missing icall profling for static functions indirect called 3) assertion in type 'merging' 4) gcov-dump bug. Bootstrap compiler, regression test, and SPEC06 LIPO build. Will commit to google/main. Thanks, David 2011-04-28 David Li * testsuite/gcc.dg/tree-prof/lipo/inliner-1.c (revision 0): New test. * testsuite/gcc.dg/tree-prof/lipo/gdb_cmd (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/stringop-1.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/pr34999.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/stringop-2.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/update-loopch.c (revision 0): * testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.040i.tree_profile_ipa (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/lipo.exp (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/tracer-1.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/pr45354.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/pr47187.c (revision 0): Ditto. * testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c (revision 0): Ditto. * testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C (revision 0): Ditto. * testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C (revision 0): Ditto. * testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C (revision 0): Ditto. * testsuite/g++.dg/tree-prof/lipo/partition1.C (revision 0): Ditto. * testsuite/g++.dg/tree-prof/lipo/partition2.C (revision 0): Ditto. * testsuite/g++.dg/tree-prof/lipo/partition3.C (revision 0): Ditto. * testsuite/g++.dg/tree-prof/lipo/lipo.exp (revision 0): Ditto. * final.c (revision 173136) (profile_function): Use FUNC_LABEL_ID. * dwarf2out.c (revision 173136) (dwarf2out_vms_end_prologue): Ditto. (dwarf2out_vms_begin_epilogue): Ditto. (dwarf2out_vms_debug_main_pointer): Ditto. * cgraphunit.c (revision 173136) (cgraph_finalize_compilation_unit): Remove eq type alias set computation. * tree-profile.c (revision 173136) (gimple_gen_ic_func_profiler): (gimple_gen_ic_func_topn_profiler): Do not skip any functions. (tree_profiling): Add type alias merging. * l-ipo.c (revision 173136) (restore_post_parsing_states): Use max funcdef_no. (pop_module_scope): Use max funcdef_no. * gcov-dump.c (revision 173136) (tag_function): Fix a bug in function read. --- This patch is available for review at http://codereview.appspot.com/4444076 Index: final.c =================================================================== --- final.c (revision 173136) +++ final.c (working copy) @@ -1623,7 +1623,7 @@ profile_function (FILE *file ATTRIBUTE_U int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE); switch_to_section (data_section); ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); - targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no); + targetm.asm_out.internal_label (file, "LP", FUNC_LABEL_ID (cfun)); assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1); } @@ -1636,7 +1636,7 @@ profile_function (FILE *file ATTRIBUTE_U ASM_OUTPUT_REG_PUSH (file, REGNO (chain)); #endif - FUNCTION_PROFILER (file, current_function_funcdef_no); + FUNCTION_PROFILER (file, FUNC_LABEL_ID (cfun)); #ifdef ASM_OUTPUT_REG_PUSH if (chain && REG_P (chain)) Index: cgraphunit.c =================================================================== --- cgraphunit.c (revision 173136) +++ cgraphunit.c (working copy) @@ -1117,11 +1117,6 @@ cgraph_finalize_compilation_unit (void) /* Gimplify and lower thunks. */ cgraph_analyze_functions (); - /* LIPO support */ - /* Recognize equivalent types across modules and - merge their alias sets. */ - cgraph_unify_type_alias_sets (); - /* Finally drive the pass manager. */ cgraph_optimize (); Index: testsuite/gcc.dg/tree-prof/lipo/inliner-1.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/inliner-1.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/inliner-1.c (revision 0) @@ -0,0 +1,42 @@ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +int a; +int b[100]; +void abort (void); + +inline void +cold_function () +{ + int i; + for (i = 0; i < 99; i++) + if (b[i] / (b[i+1] + 1)) + abort (); +} + +inline void +hot_function () +{ + int i; + for (i = 0; i < 99; i++) + if (b[i] / (b[i+1] + 1)) + abort (); +} + +main () +{ + int i; + for (i = 0; i < 100; i++) + { + if (a) + cold_function (); + else + hot_function (); + } + return 0; +} + +/* cold function should be inlined, while hot function should not. + Look for "cold_function () [tail call];" call statement not for the + declaration or other apperances of the string in dump. */ +/* { dg-final-use { scan-tree-dump "cold_function ..;" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "hot_function ..;" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/gdb_cmd =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/gdb_cmd (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/gdb_cmd (revision 0) @@ -0,0 +1,5 @@ +file /usr/local/google/davidxl/dev/gcc/gcc-gmain-native_64-linux/libexec/gcc/x86_64-linux/4.6.0-google-main/cc1 +set args -quiet -v indir-call-prof.c -march=core2 -mcx16 -msahf --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=4096 -mtune=core2 -quiet -dumpbase indir-call-prof.c -auxbase indir-call-prof -g -O2 -version -fprofile-generate -fripa -fdump-ipa-tree_profile_ipa -fdump-tree-optimized-blocks -o /tmp/ccdBoNgb.s +b main +b internal_error +b fancy_abort Index: testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c (revision 0) @@ -0,0 +1,39 @@ +/* { dg-require-effective-target freorder } */ +/* { dg-options "-O2 -freorder-blocks-and-partition" } */ + +#include + +#define SIZE 1000 +int t0 = 0; +const char *t2[SIZE]; +char buf[SIZE]; + +void +foo (void) +{ + char *s = buf; + t0 = 1; + + for (;;) + { + if (*s == '\0') + break; + else + { + t2[t0] = s; + t0++; + } + *s++ = '\0'; + } + t2[t0] = NULL; +} + + +int +main () +{ + strcpy (buf, "hello"); + foo (); + return 0; +} + Index: testsuite/gcc.dg/tree-prof/lipo/stringop-1.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/stringop-1.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/stringop-1.c (revision 0) @@ -0,0 +1,22 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ +int a[1000]; +int b[1000]; +int size=1; +int max=10000; +main() +{ + int i; + for (i=0;i direct call p.0_3=> a1 (module_id:1, func_id:1) +Transformation on insn: +p.0_3 (); +==> +a1 (); +hist->count 9 hist->all 10 +Analyzing function body size: main + freq: 10001 size: 3 time: 12 setp (&p, i_1); + freq: 10001 size: 1 time: 1 p.0_3 = p; + freq: 10001 size: 0 time: 0 PROF.1_10 = p.0_3; + freq: 10001 size: 0 time: 0 PROF.1_11 = (void *) a1; + freq: 10001 size: 2 time: 2 if (PROF.1_11 == PROF.1_10) + freq: 9001 size: 2 time: 11 a1 (); + freq: 1000 size: 2 time: 11 p.0_3 (); + freq: 10001 size: 1 time: 1 i_4 = i_1 + 1; + freq: 11001 size: 2 time: 2 if (i_1 <= 9) + freq: 1000 size: 1 time: 2 return 0; +Overall function body time: 294-2 size: 16-3 +With function call overhead time: 294-13 size: 16-5 +Abnormal edge 5 to 1 put to tree +Normal edge 0 to 2 put to tree +Normal edge 2 to 3 put to tree +Normal edge 2 to 4 put to tree +6 basic blocks +6 edges +0 ignored edges +Merged 1 profiles with maximal count 10. + +Read edge from 3 to 5, count:1 +Read edge from 4 to 5, count:9 +2 edge counts read + +6 basic blocks, 6 edges. + +Basic block 0 , next 2, loop_depth 0, count 10, freq 10000, maybe hot. +Predecessors: +Successors: 2 [100.0%] count:10 (fallthru,exec) + +Basic block 2 , prev 0, next 3, loop_depth 0, count 10, freq 10000, maybe hot. +Predecessors: ENTRY [100.0%] count:10 (fallthru,exec) +Successors: 3 [39.0%] count:1 (true,exec) 4 [61.0%] count:9 (false,exec) + +Basic block 3 , prev 2, next 4, loop_depth 0, count 1, freq 3900, maybe hot. +Predecessors: 2 [39.0%] count:1 (true,exec) +Successors: 5 [100.0%] count:1 (fallthru,exec) + +Basic block 4 , prev 3, next 5, loop_depth 0, count 9, freq 6100, maybe hot. +Predecessors: 2 [61.0%] count:9 (false,exec) +Successors: 5 [100.0%] count:9 (fallthru,exec) + +Basic block 5 , prev 4, next 1, loop_depth 0, count 10, freq 10000, maybe hot. +Predecessors: 3 [100.0%] count:1 (fallthru,exec) 4 [100.0%] count:9 (fallthru,exec) +Successors: EXIT [100.0%] count:10 + +Basic block 1 , prev 5, loop_depth 0, count 10, freq 10000, maybe hot. +Predecessors: 5 [100.0%] count:10 +Successors: + +Graph solving took 3 passes. + +1 branches +0% branches in range 0-5% +0% branches in range 5-10% +100% branches in range 10-15% +0% branches in range 15-20% +0% branches in range 20-25% +0% branches in range 25-30% +0% branches in range 30-35% +0% branches in range 35-40% +0% branches in range 40-45% +0% branches in range 45-50% + + +Abnormal edge 2 to 1 put to tree +3 basic blocks +2 edges +0 ignored edges +Merged 1 profiles with maximal count 10. + +Read edge from 0 to 2, count:1 +1 edge counts read + +3 basic blocks, 2 edges. + +Basic block 0 , next 2, loop_depth 0, count 1, freq 10000, maybe hot. +Predecessors: +Successors: 2 [100.0%] count:1 (fallthru,exec) + +Basic block 2 , prev 0, next 1, loop_depth 0, count 1, freq 10000, maybe hot. +Predecessors: ENTRY [100.0%] count:1 (fallthru,exec) +Successors: EXIT [100.0%] count:1 + +Basic block 1 , prev 2, loop_depth 0, count 1, freq 10000, maybe hot. +Predecessors: 2 [100.0%] count:1 +Successors: + +Graph solving took 3 passes. + +0 branches + + +Abnormal edge 2 to 1 put to tree +3 basic blocks +2 edges +0 ignored edges +Merged 1 profiles with maximal count 10. + +Read edge from 0 to 2, count:9 +1 edge counts read + +3 basic blocks, 2 edges. + +Basic block 0 , next 2, loop_depth 0, count 9, freq 10000, maybe hot. +Predecessors: +Successors: 2 [100.0%] count:9 (fallthru,exec) + +Basic block 2 , prev 0, next 1, loop_depth 0, count 9, freq 10000, maybe hot. +Predecessors: ENTRY [100.0%] count:9 (fallthru,exec) +Successors: EXIT [100.0%] count:9 + +Basic block 1 , prev 2, loop_depth 0, count 9, freq 10000, maybe hot. +Predecessors: 2 [100.0%] count:9 +Successors: + +Graph solving took 3 passes. + +0 branches + + + + +Symbols to be put in SSA form + +{ .MEM } + + +Incremental SSA update started at block: 0 + +Number of blocks in CFG: 11 +Number of blocks to update: 10 ( 91%) + + + +main () +{ + void * PROF.1; + int i; + int (*) (void) p; + int (*) (void) p.0; + +: + goto ; + +: + setp (&p, i_1); + +: + p.0_3 = p; + PROF.1_10 = p.0_3; + PROF.1_11 = (void *) a1; + if (PROF.1_11 == PROF.1_10) + goto ; + else + goto ; + +: + a1 (); + goto ; + +: + p.0_3 (); + +: + +: + i_4 = i_1 + 1; + +: + # i_1 = PHI <0(2), i_4(5)> + if (i_1 <= 9) + goto ; + else + goto ; + +: + return 0; + +} + + +setp (int (*) (void) * pp, int i) +{ + int (*tp) (void) D.4264; + int D.4263; + int D.4262; + int (*tp) (void) D.4260; + +: + if (i_1(D) == 0) + goto ; + else + goto ; + +: + D.4260_2 = aa[i_1(D)]; + *pp_3(D) = D.4260_2; + goto ; + +: + D.4262_4 = i_1(D) & 2; + D.4263_5 = D.4262_4 + 1; + D.4264_6 = aa[D.4263_5]; + *pp_3(D) = D.4264_6; + +: + return; + +} + + +a2 () +{ +: + return 0; + +} + + +a1 () +{ +: + return 10; + +} + + Index: testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c (revision 0) @@ -0,0 +1,19 @@ +/* { dg-options "-O2 -fdump-ipa-tree_profile_ipa" } */ +/* { dg-additional-sources "ic-misattribution-1a.c" } */ + +extern void other_caller (void); + +void +callee (void) +{ + return; +} + +void +caller(void (*func) (void)) +{ + func (); +} + +/* { dg-final-use { scan-ipa-dump "hist->count 1 hist->all 1" "tree_profile_ipa" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c (revision 0) @@ -0,0 +1,20 @@ +/* { dg-options "-O2 -fdump-tree-tailc -fdump-tree-optimized" } */ +__attribute__ ((noinline)) +int factorial(int x) +{ + if (x == 1) + return 1; + else + return x*factorial(--x); +} +int gbl; +int +main() +{ + gbl = factorial(100); + return 0; +} +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "tailc"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "tailc" } } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c (revision 0) @@ -0,0 +1,22 @@ +/* { dg-options "-DEMPTY" } */ +/* This file is only needed in combination with ic-misattribution-1.c + but there's no easy way to make this file ignored. */ +extern void callee (void); +extern void caller (void (*func) (void)); + +typedef void (*func_t) (void); +func_t func; + +int +main () +{ +#ifdef EMPTY +#else + func = callee; + caller (callee); + func (); +#endif + return 0; +} + +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/lipo.exp =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/lipo.exp (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/lipo.exp (revision 0) @@ -0,0 +1,54 @@ +# Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Test the functionality of programs compiled with profile-directed block +# ordering using -fprofile-generate followed by -fbranch-use. + +load_lib target-supports.exp + +# Some targets don't support tree profiling. +if { ![check_profiling_available ""] } { + return +} + +# The procedures in profopt.exp need these parameters. +set tool gcc +set prof_ext "gcda" + +# Override the list defined in profopt.exp. +set PROFOPT_OPTIONS [list {}] + +if $tracelevel then { + strace $tracelevel +} + +# Load support procs. +load_lib profopt.exp + +# These are globals used by profopt-execute. The first is options +# needed to generate profile data, the second is options to use the +# profile data. +set profile_option "-fprofile-generate -fripa -D_PROFILE_GENERATE" +set feedback_option "-fprofile-use -fripa -D_PROFILE_USE" + +foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $src] then { + continue + } + profopt-execute $src +} Index: testsuite/gcc.dg/tree-prof/lipo/tracer-1.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/tracer-1.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/tracer-1.c (revision 0) @@ -0,0 +1,18 @@ +/* { dg-options "-O2 -ftracer -fdump-tree-tracer" } */ +volatile int a, b, c; +int main () +{ + int i; + for (i = 0; i < 1000; i++) + { + if (i % 17) + a++; + else + b++; + c++; + } + return 0; +} +/* Superblock formation should produce two copies of the increment of c */ +/* { dg-final-generate { scan-tree-dump-times "c =" 2 "tracer" } } */ +/* { dg-final-use { cleanup-tree-dump "tracer" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized (revision 0) @@ -0,0 +1,229 @@ + +;; Function a1 (a1)[1:1] (unlikely executed) + +a1 () +{ + # BLOCK 2 freq:10000 + # PRED: ENTRY [100.0%] count:9 (fallthru,exec) + return 10; + # SUCC: EXIT [100.0%] + +} + + + +;; Function a2 (a2)[1:2] + +a2 () +{ + # BLOCK 2 freq:10000 count:1 + # PRED: ENTRY [100.0%] count:1 (fallthru,exec) + return 0; + # SUCC: EXIT [100.0%] count:1 + +} + + + +;; Function setp (setp)[1:3] + +Merging blocks 3 and 5 +Merging blocks 4 and 6 +setp (int (*) (void) * pp, int i) +{ + int (*tp) (void) D.4264; + int D.4263; + int D.4262; + + # BLOCK 2 freq:10000 count:10 + # PRED: ENTRY [100.0%] count:10 (fallthru,exec) + if (i_1(D) == 0) + goto ; + else + goto ; + # SUCC: 3 [10.0%] count:1 (true,exec) 4 [90.0%] count:9 (false,exec) + + # BLOCK 3 freq:1000 count:1 + # PRED: 2 [10.0%] count:1 (true,exec) + *pp_3(D) = a2; + return; + # SUCC: EXIT [100.0%] count:1 + + # BLOCK 4 freq:9000 count:9 + # PRED: 2 [90.0%] count:9 (false,exec) + D.4262_4 = i_1(D) & 2; + D.4263_5 = D.4262_4 + 1; + D.4264_6 = aa[D.4263_5]; + *pp_3(D) = D.4264_6; + return; + # SUCC: EXIT [100.0%] count:9 + +} + + + +;; Function main (main)[1:4] (executed once) + +main () +{ + int (*) (void) p; + int (*) (void) p.0; + + # BLOCK 2 freq:909 count:1 + # PRED: ENTRY [100.0%] count:1 (fallthru,exec) + setp (&p, 0); + p.0_18 = p; + if (p.0_18 == a1) + goto ; + else + goto ; + # SUCC: 4 [90.0%] count:1 (true,exec) 3 [10.0%] (false,exec) + + # BLOCK 3 freq:91 + # PRED: 2 [10.0%] (false,exec) + p.0_18 (); + # SUCC: 4 [100.0%] (fallthru,exec) + + # BLOCK 4 freq:909 count:1 + # PRED: 2 [90.0%] count:1 (true,exec) 3 [100.0%] (fallthru,exec) + setp (&p, 1); + p.0_27 = p; + if (p.0_27 == a1) + goto ; + else + goto ; + # SUCC: 6 [90.0%] count:1 (true,exec) 5 [10.0%] (false,exec) + + # BLOCK 5 freq:91 + # PRED: 4 [10.0%] (false,exec) + p.0_27 (); + # SUCC: 6 [100.0%] (fallthru,exec) + + # BLOCK 6 freq:909 count:1 + # PRED: 4 [90.0%] count:1 (true,exec) 5 [100.0%] (fallthru,exec) + setp (&p, 2); + p.0_36 = p; + if (p.0_36 == a1) + goto ; + else + goto ; + # SUCC: 8 [90.0%] count:1 (true,exec) 7 [10.0%] (false,exec) + + # BLOCK 7 freq:91 + # PRED: 6 [10.0%] (false,exec) + p.0_36 (); + # SUCC: 8 [100.0%] (fallthru,exec) + + # BLOCK 8 freq:909 count:1 + # PRED: 6 [90.0%] count:1 (true,exec) 7 [100.0%] (fallthru,exec) + setp (&p, 3); + p.0_45 = p; + if (p.0_45 == a1) + goto ; + else + goto ; + # SUCC: 10 [90.0%] count:1 (true,exec) 9 [10.0%] (false,exec) + + # BLOCK 9 freq:91 + # PRED: 8 [10.0%] (false,exec) + p.0_45 (); + # SUCC: 10 [100.0%] (fallthru,exec) + + # BLOCK 10 freq:909 count:1 + # PRED: 8 [90.0%] count:1 (true,exec) 9 [100.0%] (fallthru,exec) + setp (&p, 4); + p.0_54 = p; + if (p.0_54 == a1) + goto ; + else + goto ; + # SUCC: 12 [90.0%] count:1 (true,exec) 11 [10.0%] (false,exec) + + # BLOCK 11 freq:91 + # PRED: 10 [10.0%] (false,exec) + p.0_54 (); + # SUCC: 12 [100.0%] (fallthru,exec) + + # BLOCK 12 freq:909 count:1 + # PRED: 10 [90.0%] count:1 (true,exec) 11 [100.0%] (fallthru,exec) + setp (&p, 5); + p.0_63 = p; + if (p.0_63 == a1) + goto ; + else + goto ; + # SUCC: 14 [90.0%] count:1 (true,exec) 13 [10.0%] (false,exec) + + # BLOCK 13 freq:91 + # PRED: 12 [10.0%] (false,exec) + p.0_63 (); + # SUCC: 14 [100.0%] (fallthru,exec) + + # BLOCK 14 freq:909 count:1 + # PRED: 12 [90.0%] count:1 (true,exec) 13 [100.0%] (fallthru,exec) + setp (&p, 6); + p.0_72 = p; + if (p.0_72 == a1) + goto ; + else + goto ; + # SUCC: 16 [90.0%] count:1 (true,exec) 15 [10.0%] (false,exec) + + # BLOCK 15 freq:91 + # PRED: 14 [10.0%] (false,exec) + p.0_72 (); + # SUCC: 16 [100.0%] (fallthru,exec) + + # BLOCK 16 freq:909 count:1 + # PRED: 14 [90.0%] count:1 (true,exec) 15 [100.0%] (fallthru,exec) + setp (&p, 7); + p.0_81 = p; + if (p.0_81 == a1) + goto ; + else + goto ; + # SUCC: 18 [90.0%] count:1 (true,exec) 17 [10.0%] (false,exec) + + # BLOCK 17 freq:91 + # PRED: 16 [10.0%] (false,exec) + p.0_81 (); + # SUCC: 18 [100.0%] (fallthru,exec) + + # BLOCK 18 freq:909 count:1 + # PRED: 16 [90.0%] count:1 (true,exec) 17 [100.0%] (fallthru,exec) + setp (&p, 8); + p.0_90 = p; + if (p.0_90 == a1) + goto ; + else + goto ; + # SUCC: 20 [90.0%] count:1 (true,exec) 19 [10.0%] (false,exec) + + # BLOCK 19 freq:91 + # PRED: 18 [10.0%] (false,exec) + p.0_90 (); + # SUCC: 20 [100.0%] (fallthru,exec) + + # BLOCK 20 freq:909 count:1 + # PRED: 18 [90.0%] count:1 (true,exec) 19 [100.0%] (fallthru,exec) + setp (&p, 9); + p.0_3 = p; + if (p.0_3 == a1) + goto ; + else + goto ; + # SUCC: 22 [90.0%] count:1 (true,exec) 21 [10.0%] (false,exec) + + # BLOCK 21 freq:91 + # PRED: 20 [10.0%] (false,exec) + p.0_3 (); + # SUCC: 22 [100.0%] (fallthru,exec) + + # BLOCK 22 freq:909 count:1 + # PRED: 21 [100.0%] (fallthru,exec) 20 [90.0%] count:1 (true,exec) + return 0; + # SUCC: EXIT [100.0%] count:1 + +} + + Index: testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c (revision 0) @@ -0,0 +1,43 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ + +static int a1 (void) +{ + return 10; +} + +static int a2 (void) +{ + return 0; +} + +typedef int (*tp) (void); + +static tp aa [] = {a2, a1, a1, a1, a1}; + +__attribute__((noinline)) void setp (int (**pp) (void), int i) +{ + if (!i) + *pp = aa [i]; + else + *pp = aa [(i & 2) + 1]; +} + +int +main (void) +{ + int (*p) (void); + int i; + + for (i = 0; i < 10; i ++) + { + setp (&p, i); + p (); + } + + return 0; +} + +/* { dg-final-use { scan-ipa-dump "Indirect call -> direct call.* a1" "tree_profile_ipa"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c (revision 0) @@ -0,0 +1,22 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ +int a[1000]; +int b = 256; +int c = 257; +main () +{ + int i; + int n; + for (i = 0; i < 1000; i++) + { + if (i % 17) + n = c; + else n = b; + a[i] /= n; + } + return 0; +} +/* { dg-final-use { scan-ipa-dump "Div.mod by constant n_\[0-9\]*=257 transformation on insn" "tree_profile_ipa"} } */ +/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* != 257\\)" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c (revision 0) @@ -0,0 +1,20 @@ +/* { dg-options "-O2 -Wno-coverage-mismatch" } */ + +int __attribute__((noinline)) bar (void) +{ +} + +int foo (int i) +{ +#ifdef _PROFILE_USE + if (i) + bar (); +#endif + return 0; +} + +int main(int argc, char **argv) +{ + foo (argc); + return 0; +} Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c (revision 0) @@ -0,0 +1,32 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ +unsigned int a[1000]; +unsigned int b = 256; +unsigned int c = 1024; +unsigned int d = 17; +main () +{ + int i; + unsigned int n; + for (i = 0; i < 1000; i++) + { + a[i]=100*i; + } + for (i = 0; i < 1000; i++) + { + if (i % 2) + n = b; + else if (i % 3) + n = c; + else + n = d; + a[i] %= n; + } + return 0; +} +/* { dg-final-use { scan-ipa-dump "Mod power of 2 transformation on insn" "tree_profile_ipa" } } */ +/* This is part of code checking that n is power of 2, so we are sure that the transformation + didn't get optimized out. */ +/* { dg-final-use { scan-tree-dump "n_\[0-9\]* \\+ 0xffff" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/pr45354.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/pr45354.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/pr45354.c (revision 0) @@ -0,0 +1,43 @@ +/* { dg-require-effective-target freorder } */ +/* { dg-options "-O -freorder-blocks-and-partition -fschedule-insns -fselective-scheduling" { target powerpc*-*-* ia64-*-* x86_64-*-* } } */ + +extern void abort (void); + +int ifelse_val2; + +int __attribute__((noinline)) +test_ifelse2 (int i) +{ + int result = 0; + if (!i) /* count(6) */ + result = 1; /* count(1) */ + if (i == 1) /* count(6) */ + result = 1024; + if (i == 2) /* count(6) */ + result = 2; /* count(3) */ + if (i == 3) /* count(6) */ + return 8; /* count(2) */ + if (i == 4) /* count(4) */ + return 2048; + return result; /* count(4) */ +} + +void __attribute__((noinline)) +call_ifelse () +{ + ifelse_val2 += test_ifelse2 (0); + ifelse_val2 += test_ifelse2 (2); + ifelse_val2 += test_ifelse2 (2); + ifelse_val2 += test_ifelse2 (2); + ifelse_val2 += test_ifelse2 (3); + ifelse_val2 += test_ifelse2 (3); +} + +int +main() +{ + call_ifelse (); + if (ifelse_val2 != 23) + abort (); + return 0; +} Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c (revision 0) @@ -0,0 +1,32 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ +unsigned int a[1000]; +unsigned int b = 257; +unsigned int c = 1023; +unsigned int d = 19; +main () +{ + int i; + unsigned int n; + for (i = 0; i < 1000; i++) + { + a[i]=18; + } + for (i = 0; i < 1000; i++) + { + if (i % 2) + n = b; + else if (i % 3) + n = c; + else + n = d; + a[i] %= n; + } + return 0; +} +/* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" "tree_profile_ipa" } } */ +/* This is part of code checking that n is greater than the divisor so we are sure that it + didn't get optimized out. */ +/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c (revision 0) @@ -0,0 +1,32 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ +unsigned int a[1000]; +unsigned int b = 999; +unsigned int c = 1002; +unsigned int d = 1003; +main () +{ + int i; + unsigned int n; + for (i = 0; i < 1000; i++) + { + a[i]=1000+i; + } + for (i = 0; i < 1000; i++) + { + if (i % 2) + n = b; + else if (i % 3) + n = c; + else + n = d; + a[i] %= n; + } + return 0; +} +/* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" "tree_profile_ipa" } } */ +/* This is part of code checking that n is greater than the divisor so we are sure that it + didn't get optimized out. */ +/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c (revision 0) @@ -0,0 +1,17 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ +int a[1000]; +int b=997; +main() +{ + int i; + for (i = 0; i < 1000; i++) + if (a[i]) + a[i]/=b; + else + a[i]/=b; + return 0; +} +/* { dg-final-use { scan-ipa-dump "Div.mod by constant b.*=997 transformation on insn" "tree_profile_ipa" } } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c (revision 0) @@ -0,0 +1,20 @@ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +char a[1000]; +char b[1000]; +int size=1000; +__attribute__ ((noinline)) +t(int size) +{ + __builtin_memcpy(a,b,size); +} +int +main() +{ + int i; + for (i=0; i < size; i++) + t(i); + return 0; +} +/* { dg-final-use { scan-tree-dump "Average value sum:499500" "optimized"} } */ +/* { dg-final-use { scan-tree-dump "IOR value" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c (revision 0) @@ -0,0 +1,26 @@ +/* { dg-options "-O2 -fdump-ipa-tree_profile_ipa -mtune=core2" } */ +/* { dg-skip-if "" { ! { i?86-*-* x86_64-*-* } } { "*" } { "" } } */ + +#include + +int foo(int len) +{ + char array[1000]; + bzero(array, len); + return 0; +} + +int main() { + int i; + for (i = 0; i < 1000; i++) + { + if (i > 990) + foo(16); + else + foo(8); + } + return 0; +} + +/* { dg-final-use { scan-ipa-dump "Single value 8 stringop transformation on bzero" "tree_profile_ipa" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.gcda.imports =================================================================== Index: testsuite/gcc.dg/tree-prof/lipo/pr47187.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/pr47187.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/pr47187.c (revision 0) @@ -0,0 +1,23 @@ +/* PR bootstrap/47187 */ +/* { dg-options "-O2" } */ + +char buf[64]; +char buf2[64]; + +void * +foo (char *p, long size) +{ + return __builtin_memcpy (buf, p, size); +} + +int +main (void) +{ + long i; + for (i = 0; i < 65536; i++) + if (foo ("abcdefghijkl", 12) != buf) + __builtin_abort (); + if (foo (buf2, 64) != buf) + __builtin_abort (); + return 0; +} Index: testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c =================================================================== --- testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c (revision 0) +++ testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c (revision 0) @@ -0,0 +1,21 @@ + +/* { dg-options "-O2 -fdump-tree-optimized-blocks" } */ +int a[8]; +__attribute__ ((noinline)) +int t() +{ + int i; + for (i = 0; i < 3; i++) + if (a[i]) + break; + return i; +} +main () +{ + int i; + for (i = 0; i < 1000; i++) + t (); + return 0; +} +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ Index: testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C =================================================================== --- testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C (revision 0) +++ testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C (revision 0) @@ -0,0 +1,36 @@ +/* { dg-options "-O2 -fdump-tree-einline" } */ +class DocId { + public: + DocId() { } + DocId(const DocId &other) { } +}; + +int g; +class Base { + public: + virtual void Foo(DocId id) { g++; } +}; + +class Super: public Base { + public: + void Foo(DocId id) { } + void Bar(Base *base, DocId id) __attribute__((noinline)); +}; + +void Super::Bar(Base *base, DocId id) { + Super::Foo(id); // direct call is inlined + base->Foo(id); // indirect call is marked do not inline +} + +int main(void) +{ + Base bah; + Super baz; + DocId gid; + + baz.Bar(&baz, gid); + return 0; +} +/* { dg-final-use { scan-tree-dump "Inlining .*Super::Foo" "einline" } } */ +/* { dg-final-use { scan-tree-dump-not "mismatched arguments" "einline" } } */ +/* { dg-final-use { cleanup-tree-dump "einline" } } */ Index: testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C =================================================================== --- testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C (revision 0) +++ testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C (revision 0) @@ -0,0 +1,35 @@ +/* { dg-options "-O" } */ + +int foo1(void) { return 0; } +int bar1(void) { throw 1; } +void foo2(void) { } +void bar2(void) { throw 1; } +void __attribute__((noinline,noclone)) test1(void (*f)(void)) { (*f)(); } +void __attribute__((noinline,noclone)) test2(void (*f)(void)) { (*f)(); } +int __attribute__((noinline,noclone)) test3(int (*f)(void)) { return (*f)(); } +int __attribute__((noinline,noclone)) test4(int (*f)(void)) { return (*f)(); } +int __attribute__((noinline,noclone)) test5(int (*f)(void), int x) { return x ? x : (*f)(); } +int __attribute__((noinline,noclone)) test6(int (*f)(void), int x) { return x ? x : (*f)(); } +void __attribute__((noinline,noclone)) test7(void (*f)(void)) { try { (*f)(); } catch (...) {} } +void __attribute__((noinline,noclone)) test8(void (*f)(void)) { try { (*f)(); } catch (...) {}} +int __attribute__((noinline,noclone)) test9(int (*f)(void)) { try { return (*f)(); } catch (...) {return 0;} } +int __attribute__((noinline,noclone)) test10(int (*f)(void)) { try { return (*f)(); } catch (...) {return 0;} } +int __attribute__((noinline,noclone)) test11(int (*f)(void), int x) { try { return x ? x : (*f)(); } catch (...) {return 0;} } +int __attribute__((noinline,noclone)) test12(int (*f)(void), int x) { try { return x ? x : (*f)(); } catch (...) {return 0;} } + +int main() +{ + for (int i = 0; i < 100; ++i) test1(foo2); + for (int i = 0; i < 100; ++i) try { test2(bar2); } catch (...) {} + for (int i = 0; i < 100; ++i) test3(foo1); + for (int i = 0; i < 100; ++i) try { test4(bar1); } catch (...) {} + for (int i = 0; i < 100; ++i) test5(foo1, 0); + for (int i = 0; i < 100; ++i) try { test6(bar1, 0); } catch (...) {} + for (int i = 0; i < 100; ++i) test7(foo2); + for (int i = 0; i < 100; ++i) try { test8(bar2); } catch (...) {} + for (int i = 0; i < 100; ++i) test9(foo1); + for (int i = 0; i < 100; ++i) try { test10(bar1); } catch (...) {} + for (int i = 0; i < 100; ++i) test11(foo1, 0); + for (int i = 0; i < 100; ++i) try { test12(bar1, 0); } catch (...) {} + return 0; +} Index: testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C =================================================================== --- testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C (revision 0) +++ testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C (revision 0) @@ -0,0 +1,39 @@ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */ + +struct A { + A () {} + + virtual int AA (void) + { return 0; } + +}; + +struct B : public A { + B () {} + + virtual int AA (void) + { return 1; } +}; + +void * __attribute__((noinline,noclone)) wrap (void *p) { return p; } +int +main (void) +{ + A a; + B b; + + A* p; + + p = (A *)wrap ((void *)&a); + p->AA (); + + p = (B *)wrap ((void *)&b); + p->AA (); + + return 0; +} + +/* { dg-final-use { scan-ipa-dump "Indirect call -> direct call.* AA " "tree_profile_ipa" } } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized" } } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ +/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */ Index: testsuite/g++.dg/tree-prof/lipo/partition1.C =================================================================== --- testsuite/g++.dg/tree-prof/lipo/partition1.C (revision 0) +++ testsuite/g++.dg/tree-prof/lipo/partition1.C (revision 0) @@ -0,0 +1,54 @@ +/* { dg-require-effective-target freorder } */ +/* { dg-options "-O2 -freorder-blocks-and-partition" } */ +/* { dg-skip-if "PR target/47683" { mips-sgi-irix* } } */ + +struct A { A () __attribute__((noinline)); ~A () __attribute__((noinline)); }; +A::A () { asm volatile ("" : : : "memory"); } +A::~A () { asm volatile ("" : : : "memory"); } + +int bar () __attribute__((noinline)); +void foo () __attribute__((noinline)); + +volatile int k, l; + +int bar (int i) +{ + void *p = __builtin_alloca (i); + asm volatile ("" : : "r" (i), "r" (p) : "memory"); + if (k) throw 6; + return ++l; +} + +void foo () +{ + A a; + try { + A b; + int i = bar (5); + try { throw 6; } catch (int) {} + if (__builtin_expect (i < 4500, 0)) { + bar (7); + try { bar (8); } catch (long) {} + bar (10); + if (__builtin_expect (i < 0, 0)) { + try { bar (12); } catch (...) {} + bar (16); + bar (122); + } else { + try { bar (bar (7)); } catch (int) {} + } + } else { + try { bar (bar (bar (9))); } catch (...) {} + bar (5); + } + } catch (...) { + } +} + +int +main () +{ + int i; + for (i = 0; i < 10000; i++) + foo (); +} Index: testsuite/g++.dg/tree-prof/lipo/partition2.C =================================================================== --- testsuite/g++.dg/tree-prof/lipo/partition2.C (revision 0) +++ testsuite/g++.dg/tree-prof/lipo/partition2.C (revision 0) @@ -0,0 +1,16 @@ +// PR middle-end/45458 +// { dg-require-effective-target freorder } +// { dg-options "-fnon-call-exceptions -freorder-blocks-and-partition" } +// { dg-skip-if "PR target/47683" { mips-sgi-irix* } } + +int +main () +{ + try + { + throw 6; + } + catch (...) + { + } +} Index: testsuite/g++.dg/tree-prof/lipo/partition3.C =================================================================== --- testsuite/g++.dg/tree-prof/lipo/partition3.C (revision 0) +++ testsuite/g++.dg/tree-prof/lipo/partition3.C (revision 0) @@ -0,0 +1,18 @@ +// PR middle-end/45566 +// { dg-require-effective-target freorder } +// { dg-options "-O -fnon-call-exceptions -freorder-blocks-and-partition" } + +int k; + +int +main () +{ + try + { + if (k) + throw 6; + } + catch (...) + { + } +} Index: testsuite/g++.dg/tree-prof/lipo/lipo.exp =================================================================== --- testsuite/g++.dg/tree-prof/lipo/lipo.exp (revision 0) +++ testsuite/g++.dg/tree-prof/lipo/lipo.exp (revision 0) @@ -0,0 +1,54 @@ +# Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# Test the functionality of programs compiled with profile-directed block +# ordering using -fprofile-generate followed by -fprofile-use. + +load_lib target-supports.exp + +# Some targets don't support tree profiling. +if { ![check_profiling_available ""] } { + return +} + +# The procedures in profopt.exp need these parameters. +set tool g++ +set prof_ext "gcda" + +# Override the list defined in profopt.exp. +set PROFOPT_OPTIONS [list {}] + +if $tracelevel then { + strace $tracelevel +} + +# Load support procs. +load_lib profopt.exp + +# These are globals used by profopt-execute. The first is options +# needed to generate profile data, the second is options to use the +# profile data. +set profile_option "-fprofile-generate -fripa" +set feedback_option "-fprofile-use -fripa" + +foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.C]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $src] then { + continue + } + profopt-execute $src +} Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 173136) +++ dwarf2out.c (working copy) @@ -4184,9 +4184,9 @@ dwarf2out_vms_end_prologue (unsigned int /* Output a label to mark the endpoint of the code generated for this function. */ ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, PROLOGUE_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); fde = &fde_table[fde_table_in_use - 1]; fde->dw_fde_vms_end_prologue = xstrdup (label); } @@ -4209,9 +4209,9 @@ dwarf2out_vms_begin_epilogue (unsigned i /* Output a label to mark the endpoint of the code generated for this function. */ ASM_GENERATE_INTERNAL_LABEL (label, EPILOGUE_BEGIN_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, EPILOGUE_BEGIN_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); fde->dw_fde_vms_begin_epilogue = xstrdup (label); } @@ -17918,7 +17918,7 @@ dwarf2out_vms_debug_main_pointer (void) die->die_tag = DW_TAG_subprogram; add_name_attribute (die, VMS_DEBUG_MAIN_POINTER); ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, - current_function_funcdef_no); + FUNC_LABEL_ID (cfun)); add_AT_lbl_id (die, DW_AT_entry_pc, label); /* Make it the first child of comp_unit_die (). */ Index: tree-profile.c =================================================================== --- tree-profile.c (revision 173136) +++ tree-profile.c (working copy) @@ -473,7 +473,6 @@ gimple_gen_ic_func_profiler (void) static void gimple_gen_ic_func_topn_profiler (void) { - struct cgraph_node * c_node = cgraph_node (current_function_decl); gimple_stmt_iterator gsi; gimple stmt1; tree cur_func, gcov_info, cur_func_id; @@ -483,16 +482,6 @@ gimple_gen_ic_func_topn_profiler (void) || DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (current_function_decl)) return; - /* We want to make sure template functions are instrumented even though - it is not 'needed' in this module. It is possible that the function - is needed (e.g, as icall target) in another module. Note that for - functions in comdat groups, there is no guarantee which copy will be - picked up by the linker. */ - - if (!c_node->needed - && (!c_node->reachable || !DECL_COMDAT (c_node->decl))) - return; - gimple_init_edge_profiler (); gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR)); @@ -659,6 +648,7 @@ tree_profiling (void) /* Now perform link to allow cross module inlining. */ cgraph_do_link (); varpool_do_link (); + cgraph_unify_type_alias_sets (); init_node_map(); Index: l-ipo.c =================================================================== --- l-ipo.c (revision 173136) +++ l-ipo.c (working copy) @@ -42,7 +42,12 @@ struct GTY(()) saved_module_scope static GTY (()) struct saved_module_scope *current_module_scope; static GTY ((param_is (struct saved_module_scope))) htab_t saved_module_scope_map; -static int primary_module_last_fundef_no = 0; +static int primary_module_last_funcdef_no = 0; +/* Function id space for each module are qualified by the module id. After all the files + are parsed, we need to reset the funcdef_no to the max value from all module so that + the function clones do not assigned with ids colliding with some other orignal function + in the same module. */ +static int max_funcdef_no = 0; static location_t primary_module_last_loc; /* Primary module pending templates. */ /* Referenced asm ids in primary module. */ @@ -348,7 +353,7 @@ restore_post_parsing_states (void) { current_module_id = primary_module_id; current_module_scope = get_module_scope (primary_module_id); - set_funcdef_no (primary_module_last_fundef_no); + set_funcdef_no (max_funcdef_no); input_location = primary_module_last_loc; restore_assembler_name_reference_bit (); @@ -364,6 +369,8 @@ void pop_module_scope (void) { bool is_last = false; + int last_funcdef_no; + if (!flag_dyn_ipa || !L_IPO_COMP_MODE) return; @@ -379,13 +386,17 @@ pop_module_scope (void) is_last = is_last_module (current_module_id); + last_funcdef_no = get_last_funcdef_no (); + if (last_funcdef_no > max_funcdef_no) + max_funcdef_no = last_funcdef_no; + lang_hooks.l_ipo.save_built_in_decl_post_module_parsing (); /* Save primary module state if needed (when module group size > 1) */ if (L_IPO_IS_PRIMARY_MODULE && num_in_fnames > 1) { save_assembler_name_reference_bit (); - primary_module_last_fundef_no = get_last_funcdef_no (); + primary_module_last_funcdef_no = last_funcdef_no; } if (!is_last) Index: gcov-dump.c =================================================================== --- gcov-dump.c (revision 173136) +++ gcov-dump.c (working copy) @@ -326,14 +326,15 @@ tag_function (const char *filename ATTRI unsigned tag ATTRIBUTE_UNUSED, unsigned length) { unsigned long pos = gcov_position (); - const char *name; printf (" ident=%u", gcov_read_unsigned ()); printf (", checksum=0x%08x", gcov_read_unsigned ()); - name = gcov_read_string (); - printf (", `%s'", name ? name : "NULL"); if (gcov_position () - pos < length) { + const char *name; + + name = gcov_read_string (); + printf (", `%s'", name ? name : "NULL"); name = gcov_read_string (); printf (" %s", name ? name : "NULL"); printf (":%u", gcov_read_unsigned ());