2009-07-31 04:43:11 +02:00
|
|
|
|
/* Detection of Static Control Parts (SCoP) for Graphite.
|
2017-01-01 13:07:43 +01:00
|
|
|
|
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
2009-07-31 04:43:11 +02:00
|
|
|
|
Contributed by Sebastian Pop <sebastian.pop@amd.com> and
|
|
|
|
|
Tobias Grosser <grosser@fim.uni-passau.de>.
|
|
|
|
|
|
|
|
|
|
This file is part of GCC.
|
|
|
|
|
|
|
|
|
|
GCC 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, or (at your option)
|
|
|
|
|
any later version.
|
|
|
|
|
|
|
|
|
|
GCC 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
|
|
|
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
2015-11-23 15:23:59 +01:00
|
|
|
|
#define USES_ISL
|
|
|
|
|
|
2009-07-31 04:43:11 +02:00
|
|
|
|
#include "config.h"
|
2012-07-02 13:43:46 +02:00
|
|
|
|
|
2014-08-18 17:42:11 +02:00
|
|
|
|
#ifdef HAVE_isl
|
2012-07-02 13:43:46 +02:00
|
|
|
|
|
2009-07-31 04:43:11 +02:00
|
|
|
|
#include "system.h"
|
|
|
|
|
#include "coretypes.h"
|
2015-07-08 02:53:03 +02:00
|
|
|
|
#include "backend.h"
|
2015-07-10 14:13:06 +02:00
|
|
|
|
#include "cfghooks.h"
|
2015-10-05 18:02:59 +02:00
|
|
|
|
#include "domwalk.h"
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
#include "params.h"
|
genattrtab.c (write_header): Include hash-set.h...
2015-01-09 Michael Collison <michael.collison@linaro.org>
* genattrtab.c (write_header): Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
insn-attrtab.c.
* genautomata.c (main) : Include hash-set.h, macInclude hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
insn-automata.c.
* genemit.c (main): Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
insn-emit.c.
* gengtype.c (open_base_files): Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
gtype-desc.c.
* genopinit.c (main): Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
insn-opinit.c.
* genoutput.c (output_prologue): Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
insn-output.c.
* genpeep.c (main): Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
insn-peep.c.
* genpreds.c (write_insn_preds_c): Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
insn-preds.c.
* optc-save-gen-awk: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h when generating
options-save.c.
* opth-gen.awk: Change include guard from GCC_C_COMMON_H to GCC_C_COMMON_C
when generating options.h.
* ada/gcc-interface/cuintp.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h,
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* ada/gcc-interface/decl.c: ditto.
* ada/gcc-interface/misc.c: ditto.
* ada/gcc-interface/targtyps.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h,
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* ada/gcc-interface/trans.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, real.h,
fold-const.h, wide-int.h, inchash.h due to
flattening of tree.h.
* ada/gcc-interface/utils.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h,
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* ada/gcc-interface/utils2.c: ditto.
* alias.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* asan.c: ditto.
* attribs.c: ditto.
* auto-inc-dec.c: ditto.
* auto-profile.c: ditto
* bb-reorder.c: ditto.
* bt-load.c: Include symtab.h due to flattening of tree.h.
* builtins.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* c/c-array-notation.c: ditto.
* c/c-aux-info.c: ditto.
* c/c-convert.c: ditto.
* c/c-decl.c: ditto.
* c/c-errors.c: ditto.
* c/c-lang.c: dittoxs.
* c/c-objc-common.c: ditto.
* c/c-parser.c: ditto.
* c/c-typeck.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, inchash.h, real.h and
fixed-value.h due to flattening of tree.h.
* calls.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* ccmp.c: ditto.
* c-family/array-notation-common.c: ditto.
* c-family/c-ada-spec.c: ditto.
* c-family/c-cilkplus.c: ditto.
* c-family/c-common.c: Include input.h due to flattening of tree.h.
Define macro GCC_C_COMMON_C.
* c-family/c-common.h: Flatten tree.h header files into c-common.h.
Remove include of tree-core.h.
* c-family/c-cppbuiltin.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* c-family/c-dump.c: ditto.
* c-family/c-format.c: Flatten tree.h header files into c-common.h.
* c-family/c-cppbuiltin.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* c-family/c-dump.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* c-family/c-format.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, inchash.h and real.h due to
flattening of tree.h.
* c-family/c-gimplify.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* c-family/cilk.c: ditto.
* c-family/c-lex.c: ditto.
* c-family/c-omp.c: ditto.
* c-family/c-opts.c: ditto.
* c-family/c-pch.c: ditto.
* c-family/c-ppoutput.c: ditto.
* c-family/c-pragma.c: ditto.
* c-family/c-pretty-print.c: ditto.
* c-family/c-semantics.c: ditto.
* c-family/c-ubsan.c: ditto.
* c-family/stub-objc.c: ditto.
* cfgbuild.c: ditto.
* cfg.c: ditto.
* cfgcleanup.c: ditto.
* cfgexpand.c: ditto.
* cfghooks.c: ditto.
* cfgloop.c: Include symtab.h, fold-const.h, and
inchash.h due to flattening of tree.h.
* cfgloopmanip.c: ditto.
* cfgrtl.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* cgraphbuild.c: ditto.
* cgraph.c: ditto.
* cgraphclones.c: ditto.
* cgraphunit.c: ditto.
* cilk-common.c: ditto.
* combine.c: ditto.
* combine-stack-adj.c: Include symbol.h due to flattening of tree.h.
* config/aarch64/aarch64-builtins.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* config/aarch64/aarch64.c: ditto.
* config/alpha/alpha.c: ditto.
* config/arc/arc.c: ditto.
* config/arm/aarch-common.c: ditto.
* config/arm/arm-builtins.c: ditto.
* config/arm/arm.c: ditto.
* config/arm/arm-c.c: ditto.
* config/avr/avr.c: ditto.
* config/avr/avr-c.c: ditto.
* config/avr/avr-log.c: ditto.
* config/bfin/bfin.c: ditto.
* config/c6x/c6x.c: ditto.
* config/cr16/cr16.c: ditto.
* config/cris/cris.c: ditto.
* config/darwin.c: ditto.
* config/darwin-c.c: ditto.
* config/default-c.c: ditto.
* config/epiphany/epiphany.c: ditto.
* config/fr30/fr30.c: ditto.
* config/frv/frv.c: ditto.
* config/glibc-c.c: ditto.
* config/h8300/h8300.c: ditto.
* config/i386/i386.c: ditto.
* config/i386/i386-c.c: ditto.
* config/i386/msformat.c: ditto.
* config/i386/winnt.c: ditto.
* config/i386/winnt-cxx.c: ditto.
* config/i386/winnt-stubs.c: ditto.
* config/ia64/ia64.c: ditto.
* config/ia64/ia64-c.c: ditto.
* config/iq2000/iq2000.c: ditto.
* config/lm32/lm32.c: Include symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* config/m32c/m32c.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* config/m32c/m32c-pragma.c: ditto.
* config/m32c/m32cr.c: ditto.
* config/m68/m68k.c: ditto.
* config/mcore/mcore.c: ditto.
* config/mep/mep.c: ditto.
* config/mep/mep-pragma.c: ditto.
* config/microblaze/microblaze.c: ditto.
* config/microblaze/microblaze-c.c: ditto.
* config/mips/mips.c: ditto.
* config/mmix/mmix.c: Include symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* config/mn10300/mn10300.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* config/moxie/moxie.c: ditto.
* config/msp430/msp430.c: ditto.
* config/msp430/msp430-c.c: ditto.
* config/nds32/nds32.c: ditto.
* config/nds32/nds32-cost.c: ditto.
* config/nds32/nds32-fp-as-gp.c: ditto.
* config/nds32/nds32-intrinsic.c: ditto.
* config/nds32/nds32-isr.c: ditto.
* config/nds32/nds32-md-auxillary.c: ditto.
* config/nds32/nds32-memory-manipulationx.c: ditto.
* config/nds32/nds32-pipelines-auxillary.c: ditto.
* config/nds32/nds32-predicates.c: ditto.
* config/nios2/nios2.c: ditto.
* config/nvptx/nvptx.c: ditto.
* config/pa/pa.c: ditto.
* config/pdp11/pdp11x.c: Include symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* config/rl78/rl78.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* config/rl78/rl78-cx.c: ditto.
* config/rs6000/rs6000.c: ditto.
* config/rs6000/rs6000-c.c: ditto.
* config/rx/rx.c: ditto.
* config/s390/s390.c: ditto.
* config/sh/sh.c: ditto.
* config/sh/sc.c: ditto.
* config/sh/sh-mem.cc: ditto.
* config/sh/sh_treg_combine.cc: Include symtab.h, inchash.h and tree.h
due to flattening of tree.h.
Remove include of tree-core.h.
* config/sol2.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* config/sol2-c.c: ditto.
* config/sol2-cxx.c: ditto.
* config/sol2-stubs.c: ditto.
* config/sparc/sparc.c: ditto.
* config/sparc/sparc-cx.c: ditto.
* config/spu/spu.c: ditto.
* config/spu/spu-c.c: ditto
* config/storym16/stormy16.c: ditto.
* config/tilegx/tilegx.c: Include symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* config/tilepro/gen-mul-tables.cc: Include symtab.h in generated file.
* config/tilegx/tilegx-c.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* config/tilepro/tilepro.c: Include symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* config/tilepro/tilepro-c.c: Include hash-set.h, machmode.h,
vec.h, double-int.h, input.h, alias.h, symtab.h, options.h
fold-const.h, wide-int.h, and inchash.h due to
flattening of tree.h.
* config/v850/v850.c: ditto.
* config/v850/v850-c.c: ditto.
* config/vax/vax.c: ditto.
* config/vms/vms.c: ditto.
* config/vms/vms-c.c: ditto.
* config/vxworks.c: ditto.
* config/winnt-c.c: ditto.
* config/xtensa/xtensa.c: Include symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* convert.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* coverage.c: ditto.
* cp/call.c: ditto.
* cp/class.c: ditto.
* cp/constexpr.c: ditto.
* cp/cp-array-notation.c: ditto.
* cp/cp-gimplify.c: ditto.
* cp/cp-lang.c: ditto.
* cp/cp-objcp-common.c: ditto.
* cp/cvt.c: ditto.
* cp/decl2.c: ditto.
* cp/decl.c: ditto.
* cp/dump.c: ditto.
* cp/error.c: ditto.
* cp/except.c: ditto.
* cp/expr.c: ditto.
* cp/friend.c: ditto.
* cp/init.c: ditto.
* cp/lambda.c: ditto.
* cp/lex.c: ditto.
* cp/mangle.c: ditto.
* cp/name-lookup.c: ditto.
* cp/optimize.c: ditto.
* cp/parser.c: ditto.
* cp/pt.c: ditto.
* cp/ptree.c: ditto.
* cp/repo.c: ditto.
* cp/rtti.c: ditto.
* cp/search.c: ditto.
* cp/semantics.c: ditto.
* cp/tree.c: ditto.
* cp/typeck2.c: ditto.
* cp/typeck.c: ditto.
* cppbuiltin.c: ditto.
* cprop.c: ditto.
* cse.c: Add include of symtab.h due to flattening of tree.h.
* cselib.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* data-streamer.c: ditto.
* data-streamer-in.c: ditto.
* data-streamer-out.c: ditto.
* dbxout.c: ditto.
* dce.c: ditto.
* ddg.c: Add include of symtab.h due to flattening of tree.h.
* debug.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* dfp.c: ditto.
* df-scan.c: ditto.
* dojump.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, inchash.h and real.h due to flattening of tree.h.
* double-int.c: ditto.
* dse.c: ditto.
* dumpfile.c: ditto.
* dwarf2asm.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, inchash.h and real.h due to flattening of tree.h.
* dwarf2cfi.c: ditto.
* dwarf2out.c: ditto.
* emit-rtl.c: ditto.
* except.c: ditto.
* explow.c: ditto.
* expmed.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* expr.c: ditto.
* final.c: ditto.
* fixed-value.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, inchash.h and fixed-value.h due to flattening of tree.h.
* fold-const.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
Relocate inline function convert_to_ptrofftype_loc from tree.h.
Relocate inline function fold_build_pointer_plus_loc from tree.h.
Relocate inline function fold_build_pointer_plus_hwi_loc from tree.h.
* fold-const.h: Relocate macro convert_to_ptrofftype from tree.h.
Relocate macro fold_build_pointer_plus to relocate from tree.h.h.
Relocate macro fold_build_pointer_plus_hwi from tree.h.
Add prototype for convert_to_ptrofftype_loc relocated from tree.h.
Add prototype for fold_build_pointer_plus_loc relocated from tree.h.
Add prototype for fold_build_pointer_plus_hwi_loc relocated from tree.h.
* fortran/convert.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/cpp.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/decl.c: ditto.
* fortran/f95.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/iresolve.c: ditto.
* fortran/match.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/module.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/options.c: ditto.
* fortran/target-memory.c: Include hash-set.h, vec.h,
double-int.h, input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/trans-array.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/trans.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/trans-common.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/trans-const.c: ditto.
* fortran/trans-decl.c: ditto.
* fortran/trans-expr.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/trans-intrinsic.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, inchash.h and real.h due to flattening of tree.h.
* fortran/trans-io.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* fortran/trans-openmp.c: ditto.
* fortran/trans-stmt.c: ditto.
* fortran/trans-types.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, inchash.h and real.h due to flattening of tree.h.
* function.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* gcc-plugin.h: Include statistics.h, double-int.h, real.h, fixed-value.h,
alias.h, flags.h, and symtab.h due to flattening of tree.h
* gcse.c: ditto.
* generic-match-head.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ggc-page.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* gimple-builder.c: ditto.
* gimple.c: ditto.
* gimple-expr.c: ditto.
* gimple-fold.c: ditto.
* gimple-iterator.c: ditto.
* gimple-low.c: ditto.
* gimple-match-head.c: ditto.
* gimple-pretty-print.c: ditto.
* generic-ssa-isolate-paths.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* gimple-ssa-strength-reduction.c: ditto.
* gimple-streamer-in.c: ditto.
* gimple-streamer-out.c: ditto.
* gimple-walk.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* gimplify.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* gimplify-me.c: ditto.
* go/go-gcc.cc: ditto.
* go/go-lang.c: ditto.
* go/gdump.c: ditto.
* graphite-blocking.c: ditto.
* graphite.c: ditto.
* graphite-dependencies.c: ditto.
* graphite-interchange.c: ditto.
* graphite-isl-ast-to-gimple.c: ditto.
* graphite-optimize-isl.c: ditto.
* graphite-poly.c: ditto.
* graphite-scop-detection.c: ditto.
* graphite-sese-to-poly.c: ditto.
* hw-doloop.c: Include symtab.h due to flattening of tree.h.
* ifcvt.c: ditto.
* init-regs.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* internal-fc.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h,options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa.c: ditto.
* ipa-chkp.c: ditto.
* ipa-comdats.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-cp.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h,options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-devirt.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-icf.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h,options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-icf-gimple.c: ditto.
* ipa-inline-analysis.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-inline.c: ditto.
* ipa-inline-transform.c: ditto.
* ipa-polymorhpic-call.c: ditto.
* ipa-profile.c: ditto.
* ipa-prop.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-pure-const.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-ref.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ipa-reference.c: ditto.
* ipa-split.c: ditto.
* ipa-utils.c: ditto.
* ipa-visbility.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* ira.c: ditto.
* ira-color.c: Include hash-set.h due to flattening of tree.h.
* ira-costs.c: ditto.
* ira-emit.c: ditto.
* java/boehm.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* java/builtins.c: ditto.
* java/class.c: ditto.
* java/constants.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* java/decl.c: ditto.
* java/except.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* java/expr.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h,inchash.h and real.h due to flattening of tree.h.
* java/gimplify.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* java/jcf-dump.c: ditto.
* java/jcf-io.c: ditto.
* java/jcf-parse.c: ditto.
* java/jvgenmain.c: ditto.
* java/lang.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* java/mangle.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* java/mangle_name.c: ditto.
* java/resource.c: ditto.
* java/typeck.c: ditto.
* java/verify-glue.c: ditto.
* java/verify-impl.c: ditto.
* jump.c: Include symtab.h due to flattening of tree.h.
* langhooks.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* loop-doloop.c: Include symtab.h due to flattening of tree.h.
* loop-init.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* loop-invariant.c: Include symtab.h due to flattening of tree.h.
* loop-iv.c: ditto.
* loop-unroll.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* lower-subreg.c: ditto.
* lra-assigns.c: Include symtab.h due to flattening of tree.h.
* lra.c: Include symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* lra-coalesce.c: Include symtab.h due to flattening of tree.h.
* lra-constraints.c: ditto.
* lra-eliminations.c: ditto.
* lra-livesc: ditto.
* lra-remat.c: ditto.
* lra-spills.c: ditto.
* lto/lto.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* lto/lto-lang.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* lto/lto-object.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* lto/lto-partition.c: ditto.
* lto/lto-symtab.c: ditto.
* lto-cgraph.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* lto-compress.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* lto-opts.c: ditto.
* lto-section-in.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* lto-section-out.c: ditto.
* lto-streamer.c: ditto.
* lto-streamer-in.c: ditto.
* lto-streamer-out.c: ditto.
* modulo-sched.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* objc/objc-act.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options, fold-const.h,
wide-int.h, and inchash.h due to flattening of tree.h.
* objc/objc-encoding.c: ditto.
* objc/objc-gnu-runtime-abi-01.c: ditto.
* objc/objc-lang.c: ditto.
* objc/objc-map.c: ditto.
* objc/objc-next-runtime-abi-01.c: ditto.
* objc/objc-next-runtime-abi-02.c: ditto.
* objc/objc-runtime-shared-support.c: ditto.
* objcp/objcp-decl.c: ditto.
* objcp/objcp-lang.c: ditto.
* omega.c: ditto.
* omega-low.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* optabs.c: ditto.
* opts-global.c: ditto.
* passes.c: ditto.
* plugin.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* postreload.c: Include symtab.h due to flattening of tree.h.
* postreload-gcse.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* predict.c: ditto.
* print-rtl.c: ditto.
* print-tree.c: ditto.
* profile.c: Include symtab.h, fold-const.h
and inchash.h due to flattening of tree.h.
* real.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* realmpfr.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* recog.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* ree.c: ditto.
* reginfo.c: ditto.
* reg-stack.c: ditto.
* reload1.c: Include symtab.h, fold-const.h, wide-int.h
and inchash.h due to flattening of tree.h.
* reload.c: Include symtab.h due to flattening of tree.h.
* reorg.c: ditto.
* rtlanal.c: Include symtab.h, fold-const.h, wide-int.h
and inchash.h due to flattening of tree.h.
* rtl-chkp.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* rtlhooks.c: Include symtab.h due to flattening of tree.h.
* sanopt.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* sched-deps.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* sched-vis.c: ditto.
* sdbout.c: ditto.
* sel-sched.c: Include symtab.h, fold-const.h, wide-int.h
and inchash.h due to flattening of tree.h.
* sel-sched-ir.c: ditto.
* sese.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* shrink-wrap.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* simplify-rtx.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* stack-ptr-mod.c: ditto.
* stmt.c: ditto.
* store-motion.c: ditto.
* store-layout.c: ditto.
* stringpool.c: ditto.
* symtab.c: ditto.
* target-globals.c: ditto.
* targhooks.c: ditto.
* toplev.c: ditto.
* tracer.c: ditto.
* trans-mem.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-affine.c: ditto.
* tree-browser.c: ditto.
* tree.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-call-cdce.c: Include symtab.h, alias.h, double-int.h,
fold-const.h, wide-int.h, inchash.h and real.h due to
flattening of tree.h.
* tree-cfg.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-cfgcleanup.c: ditto.
* tree-chkp.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-chkp-opt.c: ditto.
* tree-chrec.c: ditto.
* tree-chkp-opt.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, inchash.h and
real.h due to flattening of tree.h.
* tree-core.h: Flatten header file by removing all #include statements.
* tree-data-ref.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-dfa.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, inchash.h and
real.h due to flattening of tree.h.
* tree-diagnostic.c: ditto.
* tree-dump.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, inchash.h, real.h and
fixed-value.h due to flattening of tree.h.
* tree-dfa.c: ditto.
* tree-eh.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, inchash.h and
real.h due to flattening of tree.h.
* tree-emutls.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree.h: Flatten header files by removing all includes except tree-core.h.
Remove inline function convert_to_ptrofftype_loc to relocate to fold-const.c.
Remove macro convert_to_ptrofftype to relocate to fold-const.h.
Remove inline function fold_build_pointer_plus_loc to relocate to fold-const.c.
Remove macro fold_build_pointer_plus to relocate to fold-const.h.
Remove inline function fold_build_pointer_plus_hwi_loc to relocate to fold-const.c.
Remove macro fold_build_pointer_plus_hwi to relocate to fold-const.h.
* tree-if-conv.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, inchash.h, real.h and
fixed-value.h due to flattening of tree.h.
* tree-inline.c: ditto.
* tree-into-ssa.c: ditto.
* tree-iterator.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-loop-distribution.c: ditto.
* tree-nested.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-nrv.c: ditto.
* tree-object-size.c: ditto.
* tree-outof-ssa.c: ditto.
* tree-parloops.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-phinodes.c: ditto.
* tree-predcom.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-pretty-print.c: ditto.
* tree-profile.c: double-int.h, input.h, alias.h, symtab.h,
fold-const.h, wide-int.h and inchash.h due to flattening of tree.h.
* tree-scalar-evolution.c: Include hash-set.h, machmode.h, vec.h,
double-int.h, input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h and inchash.h due to flattening of tree.h.
* tree-sra.c: Include vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, and
inchash.h due to flattening of tree.h.
* tree-ssa-alias.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-ssa.c: ditto.
* tree-ssa-ccp.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, inchash.h
and real.h due to flattening of tree.h.
* tree-ssa-coalesce.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-ssa-copy.c: ditto.
* tree-ssa-copyrename.c: ditto.
* tree-ssa-dce.c: ditto.
* tree-ssa-dom.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h, inchash.h
and real.h due to flattening of tree.h.
* tree-ssa-dse.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-ssa-forwprop.c: ditto.
* tree-ssa-ifcombine.c: ditto.
* tree-ssa-live.c: ditto.
* tree-ssa-loop.c: ditto.
* tree-ssa-loop-ch.c: ditto.
* tree-ssa-loop-im.c: ditto.
* tree-ssa-loop-ivcanon.c: ditto.
* tree-ssa-loop-ivopts.c: ditto.
* tree-ssa-loop-manip.c: ditto.
* tree-ssa-loop-niter.c: ditto.
* tree-ssa-loop-prefetch.c: ditto.
* tree-ssa-loop-unswitch.c: ditto.
* tree-ssa-loop-math-opts.c: ditto.
* tree-ssanames.c: ditto.
* tree-ssa-operands.c: ditto.
* tree-ssa-phiopt.c: ditto.
* tree-ssa-phiprop.c: ditto.
* tree-ssa-pre.c: ditto.
* tree-ssa-propagate.c: ditto.
* tree-ssa-reassoc.c: ditto.
* tree-ssa-sccvn.c: ditto.
* tree-ssa-sink.c: ditto.
* tree-ssa-strlen.c: Include hash-set.h, machmode.h, vec.h,
double-int.h, input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h and inchash.h due to flattening of tree.h.
* tree-ssa-structalias.c: double-int.h, input.h, alias.h, symtab.h,
fold-const.h, wide-int.h and inchash.h due to flattening of tree.h.
* tree-ssa-tail-merge.c: Include hash-set.h, machmode.h, vec.h,
double-int.h, input.h, alias.h, symtab.h, fold-const.h,
wide-int.h and inchash.h due to flattening of tree.h.
* tree-ssa-ter.c: ditto.
* tree-ssa-threadedge.c: ditto.
* tree-ssa-threadupdate.c: Include hash-set.h, machmode.h, vec.h,
double-int.h, input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h and inchash.h due to flattening of tree.h.
* tree-ssa-uncprop.c: Include hash-set.h, machmode.h, vec.h,
double-int.h, input.h, alias.h, symtab.h, fold-const.h,
wide-int.h and inchash.h due to flattening of tree.h.
* tree-ssa-uninit.c: ditto.
* tree-stdarg.c: Include vec.h, double-int.h, input.h, alias.h,
symtab.h, fold-const.h, wide-int.h and inchash.h due to flattening
of tree.h.
* tree-streamer.c: Include vec.h, double-int.h, input.h, alias.h,
symtab.h, options.h, fold-const.h, wide-int.h and
inchash.h due to flattening of tree.h.
* tree-streamer-in.c: Include hash-set.h, machmode.h, vec.h,
double-int.h, input.h, alias.h, symtab.h, options.h, fold-const.h,
wide-int.h, inchash.h, real.h and fixed-value.h due to flattening
of tree.h.
* tree-streamer-out.c: dittoo.
* tree-switch-conversion.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-tailcall.c: ditto.
* tree-vect-data-refs.c: ditto.
* tree-vect-generic.c: Include hash-set.h, machmode.h, vec.h, double-int.h, input.h,
alias.h, symtab.h, options.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-vect-loop.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* tree-vect-loop-manip.c: ditto.
* tree-vectorizer.c: ditto.
* tree-vect-patterns.c: ditto.
* tree-vect-slp.c: ditto.
* tree-vect-stmts.c: ditto.
* tree-vrp.c: ditto.
* tsan.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* ubsan.c: ditto.
* value-prof.c.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* varasm.c: ditto.
* varpool.c: ditto.
* var-tracking.c: ditto.
* vmsdbgout.c: ditto.
* vtable-verify.c: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* wide-int.cc: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
* xcoffout.c: ditto.
* libcc1/plugin.cc: Include hash-set.h, machmode.h, vec.h, double-int.h,
input.h, alias.h, symtab.h, options.h, fold-const.h, wide-int.h and inchash.h
due to flattening of tree.h.
From-SVN: r219402
2015-01-09 21:18:42 +01:00
|
|
|
|
#include "tree.h"
|
2015-07-08 02:53:03 +02:00
|
|
|
|
#include "gimple.h"
|
|
|
|
|
#include "ssa.h"
|
|
|
|
|
#include "fold-const.h"
|
gimple-walk.h: New File.
* gimple-walk.h: New File. Relocate prototypes from gimple.h.
(struct walk_stmt_info): Relocate here from gimple.h.
* gimple-iterator.h: New File. Relocate prototypes from gimple.h.
(struct gimple_stmt_iterator_d): Relocate here from gimple.h.
(gsi_start_1, gsi_none, gsi_start_bb, gsi_last_1, gsi_last_bb,
gsi_end_p, gsi_one_before_end_p, gsi_next, gsi_prev, gsi_stmt,
gsi_after_labels, gsi_next_nondebug, gsi_prev_nondebug,
gsi_start_nondebug_bb, gsi_start_nondebug_after_labels_bb,
gsi_last_nondebug_bb, gsi_bb, gsi_seq): Relocate here from gimple.h.
* gimple.h (struct gimple_stmt_iterator_d): Move to gimple-iterator.h.
(gsi_start_1, gsi_none, gsi_start_bb, gsi_last_1, gsi_last_bb,
gsi_end_p, gsi_one_before_end_p, gsi_next, gsi_prev, gsi_stmt,
gsi_after_labels, gsi_next_nondebug, gsi_prev_nondebug,
gsi_start_nondebug_bb, gsi_start_nondebug_after_labels_bb,
gsi_last_nondebug_bb, gsi_bb, gsi_seq): Move to gimple-iterator.h.
(struct walk_stmt_info): Move to gimple-walk.h.
(gimple_seq_set_location): Move to gimple.c
* gimple-walk.c: New File.
(walk_gimple_seq_mod, walk_gimple_seq, walk_gimple_asm, walk_gimple_op,
walk_gimple_stmt, get_base_loadstore, walk_stmt_load_store_addr_ops,
walk_stmt_load_store_ops): Relocate here from gimple.c.
* gimple-iterator.c: Include gimple-iterator.h.
* gimple.c (walk_gimple_seq_mod, walk_gimple_seq, walk_gimple_asm,
walk_gimple_op, walk_gimple_stmt, get_base_loadstore,
walk_stmt_load_store_addr_ops, walk_stmt_load_store_ops): Move to
gimple-walk.c.
(gimple_seq_set_location): Relocate from gimple.h.
* tree-phinodes.h (set_phi_nodes): Move to tree-phinodes.c.
* tree-phinodes.c (set_phi_nodes): Relocate from tree-phinodes.h.
* gengtype.c (open_base_files): Add gimple-iterator.h to include list.
* Makefile.in (OBJS): Add gimple-walk.o
* asan.c: Update Include list as required for gimple-iterator.h and
gimple-walk.h.
* cfgexpand.c: Likewise.
* cfgloop.c: Likewise.
* cfgloopmanip.c: Likewise.
* cgraph.c: Likewise.
* cgraphbuild.c: Likewise.
* cgraphunit.c: Likewise.
* gimple-fold.c: Likewise.
* gimple-low.c: Likewise.
* gimple-pretty-print.c: Likewise.
* gimple-ssa-isolate-paths.c: Likewise.
* gimple-ssa-strength-reduction.c: Likewise.
* gimple-streamer-in.c: Likewise.
* gimple-streamer-out.c: Likewise.
* gimplify.c: Likewise.
* graphite-blocking.c: Likewise.
* graphite-clast-to-gimple.c: Likewise.
* graphite-dependences.c: Likewise.
* graphite-interchange.c: Likewise.
* graphite-optimize-isl.c: Likewise.
* graphite-poly.c: Likewise.
* graphite-scop-detection.c: Likewise.
* graphite-sese-to-poly.c: Likewise.
* graphite.c: Likewise.
* ipa-inline-analysis.c: Likewise.
* ipa-profile.c: Likewise.
* ipa-prop.c: Likewise.
* ipa-pure-const.c: Likewise.
* ipa-split.c: Likewise.
* lto-streamer-in.c: Likewise.
* lto-streamer-out.c: Likewise.
* omp-low.c: Likewise.
* predict.c: Likewise.
* profile.c: Likewise.
* sese.c: Likewise.
* tracer.c: Likewise.
* trans-mem.c: Likewise.
* tree-call-cdce.c: Likewise.
* tree-cfg.c: Likewise.
* tree-cfgcleanup.c: Likewise.
* tree-complex.c: Likewise.
* tree-data-ref.c: Likewise.
* tree-dfa.c: Likewise.
* tree-eh.c: Likewise.
* tree-emutls.c: Likewise.
* tree-if-conv.c: Likewise.
* tree-inline.c: Likewise.
* tree-into-ssa.c: Likewise.
* tree-loop-distribution.c: Likewise.
* tree-nested.c: Likewise.
* tree-nrv.c: Likewise.
* tree-object-size.c: Likewise.
* tree-outof-ssa.c: Likewise.
* tree-parloops.c: Likewise.
* tree-predcom.c: Likewise.
* tree-profile.c: Likewise.
* tree-scalar-evolution.c: Likewise.
* tree-sra.c: Likewise.
* tree-ssa-ccp.c: Likewise.
* tree-ssa-coalesce.c: Likewise.
* tree-ssa-copy.c: Likewise.
* tree-ssa-copyrename.c: Likewise.
* tree-ssa-dce.c: Likewise.
* tree-ssa-dom.c: Likewise.
* tree-ssa-dse.c: Likewise.
* tree-ssa-forwprop.c: Likewise.
* tree-ssa-ifcombine.c: Likewise.
* tree-ssa-live.c: Likewise.
* tree-ssa-loop-ch.c: Likewise.
* tree-ssa-loop-im.c: Likewise.
* tree-ssa-loop-ivcanon.c: Likewise.
* tree-ssa-loop-ivopts.c: Likewise.
* tree-ssa-loop-manip.c: Likewise.
* tree-ssa-loop-niter.c: Likewise.
* tree-ssa-loop-prefetch.c: Likewise.
* tree-ssa-loop.c: Likewise.
* tree-ssa-math-opts.c: Likewise.
* tree-ssa-phiopt.c: Likewise.
* tree-ssa-phiprop.c: Likewise.
* tree-ssa-pre.c: Likewise.
* tree-ssa-propagate.c: Likewise.
* tree-ssa-reassoc.c: Likewise.
* tree-ssa-sink.c: Likewise.
* tree-ssa-strlen.c: Likewise.
* tree-ssa-structalias.c: Likewise.
* tree-ssa-tail-merge.c: Likewise.
* tree-ssa-ter.c: Likewise.
* tree-ssa-threadedge.c: Likewise.
* tree-ssa-threadupdate.c: Likewise.
* tree-ssa-uncprop.c: Likewise.
* tree-ssa-uninit.c: Likewise.
* tree-ssa.c: Likewise.
* tree-stdarg.c: Likewise.
* tree-switch-conversion.c: Likewise.
* tree-tailcall.c: Likewise.
* tree-vect-data-refs.c: Likewise.
* tree-vect-generic.c: Likewise.
* tree-vect-loop-manip.c: Likewise.
* tree-vect-loop.c: Likewise.
* tree-vect-patterns.c: Likewise.
* tree-vect-slp.c: Likewise.
* tree-vect-stmts.c: Likewise.
* tree-vectorizer.c: Likewise.
* tree-vrp.c: Likewise.
* tree.c: Likewise.
* tsan.c: Likewise.
* value-prof.c: Likewise.
* vtable-verify.c: Likewise.
* config/aarch64/aarch64-builtins.c: Include gimple-iterator.h.
* config/rs6000/rs6000.c: Include gimple-iterator.h and gimple-walk.h.
* testsuite/g++.dg/plugin/selfassign.c: Include gimple-iterator.h.
* testsuite/gcc.dg/plugin/selfassign.c: Likewise.
From-SVN: r204763
2013-11-14 00:54:17 +01:00
|
|
|
|
#include "gimple-iterator.h"
|
2015-10-05 18:02:59 +02:00
|
|
|
|
#include "tree-cfg.h"
|
2013-10-23 20:55:46 +02:00
|
|
|
|
#include "tree-ssa-loop-manip.h"
|
|
|
|
|
#include "tree-ssa-loop-niter.h"
|
2013-10-23 14:16:58 +02:00
|
|
|
|
#include "tree-ssa-loop.h"
|
|
|
|
|
#include "tree-into-ssa.h"
|
tree-ssa.h: New.
* tree-ssa.h: New. Move content from tree-flow.h and
tree-flow-inline.h.
* tree-flow.h (_edge_var_map, edge_var_map_vector): Move to tree-ssa.h.
Move prototypes belonging to tree-ssa.c.
* tree-flow-inline.h (redirect_edge_var_map_def,
redirect_edge_var_map_result, redirect_edge_var_map_location): Move to
tree-ssa.h.
* gimple.h: Adjust prototypes.
* tree-ssa.c (useless_type_conversion_p, types_compatible_p): Move to...
* gimple.c (useless_type_conversion_p, types_compatible_p): Here.
* tree.h: Move prototype to tree-ssa.h.
* gengtype.c (open_base_files): Replace tree-flow.h with tree-ssa.h.
* Makefile.in: (TREE_SSA_H, TREE_FLOW_H): Adjust dependencies.
* alias.c, asan.c, builtins.c, calls.c, cfgexpand.c, cfghooks.c,
cfgloop.c, cfgloopmanip.c, cgraph.c, cgraphbuild.c, cgraphclones.c,
cgraphunit.c, dse.c, except.c, expr.c, final.c, fold-const.c,
ggc-page.c, gimple-fold.c, gimple-iterator.c, gimple-low.c,
gimple-pretty-print.c, gimple-ssa-strength-reduction.c,
gimple-streamer-in.c, gimple-streamer-out.c, gimple.c, gimplify.c,
graphite-blocking.c, graphite-clast-to-gimple.c, graphite-dependences.c,
graphite-interchange.c, graphite-optimize-isl.c, graphite-poly.c,
graphite-scop-detection.c, graphite-sese-to-poly.c, graphite.c,
ipa-cp.c, ipa-inline-analysis.c, ipa-inline-transform.c, ipa-inline.c,
ipa-prop.c, ipa-pure-const.c, ipa-reference.c, ipa-split.c, ipa-utils.c,
loop-init.c, lto-cgraph.c, lto-section-in.c, lto-section-out.c,
lto-streamer-in.c, lto-streamer-out.c, lto-streamer.c, omp-low.c,
passes.c, predict.c, print-tree.c, profile.c, sese.c, targhooks.c,
tracer.c, trans-mem.c, tree-call-cdce.c, tree-cfg.c, tree-cfgcleanup.c,
tree-chrec.c, tree-complex.c, tree-data-ref.c, tree-dfa.c, tree-eh.c,
tree-emutls.c, tree-if-conv.c, tree-inline.c, tree-into-ssa.c,
tree-loop-distribution.c, tree-mudflap.c, tree-nested.c, tree-nrv.c,
tree-object-size.c, tree-optimize.c, tree-outof-ssa.c, tree-parloops.c,
tree-phinodes.c, tree-predcom.c, tree-pretty-print.c, tree-profile.c,
tree-scalar-evolution.c, tree-sra.c, tree-ssa*.c, tree-stdarg.c,
tree-streamer-in.c, tree-switch-conversion.c, tree-tailcall.c,
tree-vect-data-refs.c, tree-vect-generic.c, tree-vect-loop-manip.c,
tree-vect-loop.c, tree-vect-patterns.c, tree-vect-slp.c,
tree-vect-stmts.c, tree-vectorizer.c, tree-vrp.c, tsan.c,
value-prof.c, var-tracking.c,
varpool.c, vtable-verify.c: Replace tree-flow.h with tree-ssa.h
From-SVN: r202523
2013-09-12 15:03:18 +02:00
|
|
|
|
#include "tree-ssa.h"
|
2009-07-31 04:43:11 +02:00
|
|
|
|
#include "cfgloop.h"
|
|
|
|
|
#include "tree-data-ref.h"
|
|
|
|
|
#include "tree-scalar-evolution.h"
|
|
|
|
|
#include "tree-pass.h"
|
2015-07-13 17:41:54 +02:00
|
|
|
|
#include "tree-ssa-propagate.h"
|
2015-07-25 11:22:29 +02:00
|
|
|
|
#include "gimple-pretty-print.h"
|
2015-11-24 18:57:45 +01:00
|
|
|
|
#include "graphite.h"
|
2015-11-23 15:23:59 +01:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
class debug_printer
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
FILE *dump_file;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void
|
|
|
|
|
set_dump_file (FILE *f)
|
|
|
|
|
{
|
|
|
|
|
gcc_assert (f);
|
|
|
|
|
dump_file = f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
friend debug_printer &
|
|
|
|
|
operator<< (debug_printer &output, int i)
|
|
|
|
|
{
|
|
|
|
|
fprintf (output.dump_file, "%d", i);
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
friend debug_printer &
|
|
|
|
|
operator<< (debug_printer &output, const char *s)
|
|
|
|
|
{
|
|
|
|
|
fprintf (output.dump_file, "%s", s);
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
} dp;
|
|
|
|
|
|
|
|
|
|
#define DEBUG_PRINT(args) do \
|
|
|
|
|
{ \
|
|
|
|
|
if (dump_file && (dump_flags & TDF_DETAILS)) { args; } \
|
|
|
|
|
} while (0);
|
|
|
|
|
|
2015-11-04 21:59:12 +01:00
|
|
|
|
/* Pretty print to FILE all the SCoPs in DOT format and mark them with
|
|
|
|
|
different colors. If there are not enough colors, paint the
|
|
|
|
|
remaining SCoPs in gray.
|
|
|
|
|
|
|
|
|
|
Special nodes:
|
|
|
|
|
- "*" after the node number denotes the entry of a SCoP,
|
|
|
|
|
- "#" after the node number denotes the exit of a SCoP,
|
|
|
|
|
- "()" around the node number denotes the entry or the
|
|
|
|
|
exit nodes of the SCOP. These are not part of SCoP. */
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
DEBUG_FUNCTION void
|
|
|
|
|
dot_all_sese (FILE *file, vec<sese_l>& scops)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
{
|
|
|
|
|
/* Disable debugging while printing graph. */
|
|
|
|
|
int tmp_dump_flags = dump_flags;
|
|
|
|
|
dump_flags = 0;
|
|
|
|
|
|
|
|
|
|
fprintf (file, "digraph all {\n");
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
basic_block bb;
|
2015-11-04 21:59:12 +01:00
|
|
|
|
FOR_ALL_BB_FN (bb, cfun)
|
|
|
|
|
{
|
|
|
|
|
int part_of_scop = false;
|
|
|
|
|
|
|
|
|
|
/* Use HTML for every bb label. So we are able to print bbs
|
|
|
|
|
which are part of two different SCoPs, with two different
|
|
|
|
|
background colors. */
|
|
|
|
|
fprintf (file, "%d [label=<\n <TABLE BORDER=\"0\" CELLBORDER=\"1\" ",
|
|
|
|
|
bb->index);
|
|
|
|
|
fprintf (file, "CELLSPACING=\"0\">\n");
|
|
|
|
|
|
|
|
|
|
/* Select color for SCoP. */
|
2015-12-04 22:36:55 +01:00
|
|
|
|
sese_l *region;
|
|
|
|
|
int i;
|
|
|
|
|
FOR_EACH_VEC_ELT (scops, i, region)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
{
|
2015-12-04 22:36:55 +01:00
|
|
|
|
bool sese_in_region = bb_in_sese_p (bb, *region);
|
|
|
|
|
if (sese_in_region || (region->exit->dest == bb)
|
|
|
|
|
|| (region->entry->dest == bb))
|
2015-11-04 21:59:12 +01:00
|
|
|
|
{
|
2015-12-04 22:36:55 +01:00
|
|
|
|
const char *color;
|
2015-11-04 21:59:12 +01:00
|
|
|
|
switch (i % 17)
|
|
|
|
|
{
|
|
|
|
|
case 0: /* red */
|
|
|
|
|
color = "#e41a1c";
|
|
|
|
|
break;
|
|
|
|
|
case 1: /* blue */
|
|
|
|
|
color = "#377eb8";
|
|
|
|
|
break;
|
|
|
|
|
case 2: /* green */
|
|
|
|
|
color = "#4daf4a";
|
|
|
|
|
break;
|
|
|
|
|
case 3: /* purple */
|
|
|
|
|
color = "#984ea3";
|
|
|
|
|
break;
|
|
|
|
|
case 4: /* orange */
|
|
|
|
|
color = "#ff7f00";
|
|
|
|
|
break;
|
|
|
|
|
case 5: /* yellow */
|
|
|
|
|
color = "#ffff33";
|
|
|
|
|
break;
|
|
|
|
|
case 6: /* brown */
|
|
|
|
|
color = "#a65628";
|
|
|
|
|
break;
|
|
|
|
|
case 7: /* rose */
|
|
|
|
|
color = "#f781bf";
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
color = "#8dd3c7";
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
color = "#ffffb3";
|
|
|
|
|
break;
|
|
|
|
|
case 10:
|
|
|
|
|
color = "#bebada";
|
|
|
|
|
break;
|
|
|
|
|
case 11:
|
|
|
|
|
color = "#fb8072";
|
|
|
|
|
break;
|
|
|
|
|
case 12:
|
|
|
|
|
color = "#80b1d3";
|
|
|
|
|
break;
|
|
|
|
|
case 13:
|
|
|
|
|
color = "#fdb462";
|
|
|
|
|
break;
|
|
|
|
|
case 14:
|
|
|
|
|
color = "#b3de69";
|
|
|
|
|
break;
|
|
|
|
|
case 15:
|
|
|
|
|
color = "#fccde5";
|
|
|
|
|
break;
|
|
|
|
|
case 16:
|
|
|
|
|
color = "#bc80bd";
|
|
|
|
|
break;
|
|
|
|
|
default: /* gray */
|
|
|
|
|
color = "#999999";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">",
|
|
|
|
|
color);
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
if (!sese_in_region)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
fprintf (file, " (");
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
if (bb == region->entry->dest && bb == region->exit->dest)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
fprintf (file, " %d*# ", bb->index);
|
2015-12-04 22:36:55 +01:00
|
|
|
|
else if (bb == region->entry->dest)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
fprintf (file, " %d* ", bb->index);
|
2015-12-04 22:36:55 +01:00
|
|
|
|
else if (bb == region->exit->dest)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
fprintf (file, " %d# ", bb->index);
|
|
|
|
|
else
|
|
|
|
|
fprintf (file, " %d ", bb->index);
|
|
|
|
|
|
|
|
|
|
fprintf (file, "{lp_%d}", bb->loop_father->num);
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
if (!sese_in_region)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
fprintf (file, ")");
|
|
|
|
|
|
|
|
|
|
fprintf (file, "</TD></TR>\n");
|
|
|
|
|
part_of_scop = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!part_of_scop)
|
|
|
|
|
{
|
|
|
|
|
fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"#ffffff\">");
|
|
|
|
|
fprintf (file, " %d {lp_%d} </TD></TR>\n", bb->index,
|
|
|
|
|
bb->loop_father->num);
|
|
|
|
|
}
|
|
|
|
|
fprintf (file, " </TABLE>>, shape=box, style=\"setlinewidth(0)\"]\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FOR_ALL_BB_FN (bb, cfun)
|
|
|
|
|
{
|
2015-12-04 22:36:55 +01:00
|
|
|
|
edge e;
|
|
|
|
|
edge_iterator ei;
|
2015-11-04 21:59:12 +01:00
|
|
|
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
|
|
|
|
fprintf (file, "%d -> %d;\n", bb->index, e->dest->index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fputs ("}\n\n", file);
|
|
|
|
|
|
|
|
|
|
/* Enable debugging again. */
|
|
|
|
|
dump_flags = tmp_dump_flags;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
/* Display SCoP on stderr. */
|
2015-11-04 21:59:12 +01:00
|
|
|
|
|
|
|
|
|
DEBUG_FUNCTION void
|
2015-12-04 22:36:55 +01:00
|
|
|
|
dot_sese (sese_l& scop)
|
2015-11-04 21:59:12 +01:00
|
|
|
|
{
|
2015-12-04 22:36:55 +01:00
|
|
|
|
vec<sese_l> scops;
|
|
|
|
|
scops.create (1);
|
2015-11-04 21:59:12 +01:00
|
|
|
|
|
|
|
|
|
if (scop)
|
|
|
|
|
scops.safe_push (scop);
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
dot_all_sese (stderr, scops);
|
2015-11-04 21:59:12 +01:00
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
scops.release ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEBUG_FUNCTION void
|
|
|
|
|
dot_cfg ()
|
|
|
|
|
{
|
|
|
|
|
vec<sese_l> scops;
|
|
|
|
|
scops.create (1);
|
|
|
|
|
dot_all_sese (stderr, scops);
|
|
|
|
|
scops.release ();
|
2015-11-04 21:59:12 +01:00
|
|
|
|
}
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|
|
|
|
|
/* Return true if BB is empty, contains only DEBUG_INSNs. */
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
trivially_empty_bb_p (basic_block bb)
|
|
|
|
|
{
|
|
|
|
|
gimple_stmt_iterator gsi;
|
|
|
|
|
|
|
|
|
|
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
|
|
|
|
if (gimple_code (gsi_stmt (gsi)) != GIMPLE_DEBUG)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns true when P1 and P2 are close phis with the same
|
|
|
|
|
argument. */
|
|
|
|
|
|
|
|
|
|
static inline bool
|
|
|
|
|
same_close_phi_node (gphi *p1, gphi *p2)
|
|
|
|
|
{
|
2016-03-16 10:19:12 +01:00
|
|
|
|
return (types_compatible_p (TREE_TYPE (gimple_phi_result (p1)),
|
|
|
|
|
TREE_TYPE (gimple_phi_result (p2)))
|
|
|
|
|
&& operand_equal_p (gimple_phi_arg_def (p1, 0),
|
|
|
|
|
gimple_phi_arg_def (p2, 0), 0));
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void make_close_phi_nodes_unique (basic_block bb);
|
|
|
|
|
|
|
|
|
|
/* Remove the close phi node at GSI and replace its rhs with the rhs
|
|
|
|
|
of PHI. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_duplicate_close_phi (gphi *phi, gphi_iterator *gsi)
|
|
|
|
|
{
|
|
|
|
|
gimple *use_stmt;
|
|
|
|
|
use_operand_p use_p;
|
|
|
|
|
imm_use_iterator imm_iter;
|
|
|
|
|
tree res = gimple_phi_result (phi);
|
|
|
|
|
tree def = gimple_phi_result (gsi->phi ());
|
|
|
|
|
|
|
|
|
|
gcc_assert (same_close_phi_node (phi, gsi->phi ()));
|
|
|
|
|
|
|
|
|
|
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
|
|
|
|
|
{
|
|
|
|
|
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
|
|
|
|
|
SET_USE (use_p, res);
|
|
|
|
|
|
|
|
|
|
update_stmt (use_stmt);
|
|
|
|
|
|
|
|
|
|
/* It is possible that we just created a duplicate close-phi
|
|
|
|
|
for an already-processed containing loop. Check for this
|
|
|
|
|
case and clean it up. */
|
|
|
|
|
if (gimple_code (use_stmt) == GIMPLE_PHI
|
|
|
|
|
&& gimple_phi_num_args (use_stmt) == 1)
|
|
|
|
|
make_close_phi_nodes_unique (gimple_bb (use_stmt));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
remove_phi_node (gsi, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Removes all the close phi duplicates from BB. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
make_close_phi_nodes_unique (basic_block bb)
|
|
|
|
|
{
|
|
|
|
|
gphi_iterator psi;
|
|
|
|
|
|
|
|
|
|
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
|
|
|
|
|
{
|
|
|
|
|
gphi_iterator gsi = psi;
|
|
|
|
|
gphi *phi = psi.phi ();
|
|
|
|
|
|
|
|
|
|
/* At this point, PHI should be a close phi in normal form. */
|
|
|
|
|
gcc_assert (gimple_phi_num_args (phi) == 1);
|
|
|
|
|
|
|
|
|
|
/* Iterate over the next phis and remove duplicates. */
|
|
|
|
|
gsi_next (&gsi);
|
|
|
|
|
while (!gsi_end_p (gsi))
|
|
|
|
|
if (same_close_phi_node (phi, gsi.phi ()))
|
|
|
|
|
remove_duplicate_close_phi (phi, &gsi);
|
|
|
|
|
else
|
|
|
|
|
gsi_next (&gsi);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-21 03:13:52 +01:00
|
|
|
|
/* Return true when NAME is defined in LOOP. */
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
defined_in_loop_p (tree name, loop_p loop)
|
|
|
|
|
{
|
|
|
|
|
gcc_assert (TREE_CODE (name) == SSA_NAME);
|
|
|
|
|
return loop == loop_containing_stmt (SSA_NAME_DEF_STMT (name));
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Transforms LOOP to the canonical loop closed SSA form. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
canonicalize_loop_closed_ssa (loop_p loop)
|
|
|
|
|
{
|
|
|
|
|
edge e = single_exit (loop);
|
|
|
|
|
basic_block bb;
|
|
|
|
|
|
|
|
|
|
if (!e || e->flags & EDGE_ABNORMAL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bb = e->dest;
|
|
|
|
|
|
|
|
|
|
if (single_pred_p (bb))
|
|
|
|
|
{
|
|
|
|
|
e = split_block_after_labels (bb);
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "Splitting bb_" << bb->index << ".\n");
|
2015-10-05 18:02:59 +02:00
|
|
|
|
make_close_phi_nodes_unique (e->src);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gphi_iterator psi;
|
|
|
|
|
basic_block close = split_edge (e);
|
|
|
|
|
|
|
|
|
|
e = single_succ_edge (close);
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "Splitting edge (" << e->src->index << ","
|
2015-10-05 18:02:59 +02:00
|
|
|
|
<< e->dest->index << ")\n");
|
|
|
|
|
|
|
|
|
|
for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
|
|
|
|
|
{
|
|
|
|
|
gphi *phi = psi.phi ();
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < gimple_phi_num_args (phi); i++)
|
|
|
|
|
if (gimple_phi_arg_edge (phi, i) == e)
|
|
|
|
|
{
|
|
|
|
|
tree res, arg = gimple_phi_arg_def (phi, i);
|
|
|
|
|
use_operand_p use_p;
|
|
|
|
|
gphi *close_phi;
|
|
|
|
|
|
2016-01-21 03:13:52 +01:00
|
|
|
|
/* Only add close phi nodes for SSA_NAMEs defined in LOOP. */
|
|
|
|
|
if (TREE_CODE (arg) != SSA_NAME
|
|
|
|
|
|| !defined_in_loop_p (arg, loop))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
close_phi = create_phi_node (NULL_TREE, close);
|
|
|
|
|
res = create_new_def_for (arg, close_phi,
|
|
|
|
|
gimple_phi_result_ptr (close_phi));
|
|
|
|
|
add_phi_arg (close_phi, arg,
|
|
|
|
|
gimple_phi_arg_edge (close_phi, 0),
|
|
|
|
|
UNKNOWN_LOCATION);
|
|
|
|
|
use_p = gimple_phi_arg_imm_use_ptr (phi, i);
|
|
|
|
|
replace_exp (use_p, res);
|
|
|
|
|
update_stmt (phi);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
make_close_phi_nodes_unique (close);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The code above does not properly handle changes in the post dominance
|
|
|
|
|
information (yet). */
|
|
|
|
|
recompute_all_dominators ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Converts the current loop closed SSA form to a canonical form
|
|
|
|
|
expected by the Graphite code generation.
|
|
|
|
|
|
|
|
|
|
The loop closed SSA form has the following invariant: a variable
|
|
|
|
|
defined in a loop that is used outside the loop appears only in the
|
|
|
|
|
phi nodes in the destination of the loop exit. These phi nodes are
|
|
|
|
|
called close phi nodes.
|
|
|
|
|
|
|
|
|
|
The canonical loop closed SSA form contains the extra invariants:
|
|
|
|
|
|
|
|
|
|
- when the loop contains only one exit, the close phi nodes contain
|
|
|
|
|
only one argument. That implies that the basic block that contains
|
|
|
|
|
the close phi nodes has only one predecessor, that is a basic block
|
|
|
|
|
in the loop.
|
|
|
|
|
|
|
|
|
|
- the basic block containing the close phi nodes does not contain
|
|
|
|
|
other statements.
|
|
|
|
|
|
|
|
|
|
- there exist only one phi node per definition in the loop.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
canonicalize_loop_closed_ssa_form (void)
|
|
|
|
|
{
|
[PATCH 7/9] ENABLE_CHECKING refactoring: middle-end, LTO FE
[PATCH 7/9] ENABLE_CHECKING refactoring: middle-end, LTO FE
gcc/lto/ChangeLog:
2015-10-27 Mikhail Maltsev <maltsevm@gmail.com>
* lto.c (unify_scc): Use flag_checking and remove ENABLE_CHECKING
conditionals.
(lto_fixup_state): Likewise.
(do_whole_program_analysis): Use
symtab_node::checking_verify_symtab_nodes and remove ENABLE_CHECKING
conditionals.
gcc/ChangeLog:
2015-10-27 Mikhail Maltsev <maltsevm@gmail.com>
* attribs.c (check_attribute_tables): New function, broken out from...
(init_attributes): Use it.
* cfgcleanup.c (try_optimize_cfg): Use flag_checking, CHECKING_P
gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* cfgexpand.c (expand_goto, expand_debug_expr): Likewise.
(pass_expand::execute): Likewise.
* cgraphclones.c (symbol_table::materialize_all_clones): Likewise.
* cgraphunit.c (mark_functions_to_output): Likewise.
(cgraph_node::expand_thunk): Likewise.
(symbol_table::compile): Likewise.
* ddg.c (add_cross_iteration_register_deps): Likewise.
(create_ddg_all_sccs): Likewise.
* df-core.c (df_finish_pass, df_analyze): Likewise.
* diagnostic-core.h: Likewise.
* diagnostic.c (diagnostic_report_diagnostic): Likewise.
* dominance.c (calculate_dominance_info): Likewise.
* dwarf2out.c (add_AT_die_ref): Likewise.
(const_ok_for_output_1, mem_loc_descriptor): Likewise.
(loc_list_from_tree, gen_lexical_block_die): Likewise.
gen_type_die_with_usage, gen_type_die): Likewise.
(dwarf2out_decl): Likewise.
* emit-rtl.c (verify_rtx_sharing, reorder_insns_nobb): Likewise.
* except.c (duplicate_eh_regions): Likewise.
* fwprop.c (register_active_defs, update_df_init): Likewise.
(fwprop_init, fwprop_done): Likewise.
(update_uses): Likewise.
* ggc-page.c (ggc_grow): Likewise.
* gimplify.c (gimplify_body): Likewise.
(gimplify_hasher::equal): Likewise.
* graphite-isl-ast-to-gimple.c (graphite_verify): Likewise.
* graphite-scop-detection.c (canonicalize_loop_closed_ssa_form):
Likewise.
* graphite-sese-to-poly.c (rewrite_reductions_out_of_ssa): Likewise.
(rewrite_cross_bb_scalar_deps_out_of_ssa): Likwise.
* hash-table.h (::find_empty_slot_for_expand): Likewise.
* ifcvt.c (if_convert): Likewise.
* ipa-cp.c (ipcp_propagate_stage): Likewise.
* ipa-devirt.c (type_in_anonymous_namespace_p): Likewise.
(odr_type_p, odr_types_equivalent_p): Likewise.
(add_type_duplicate, get_odr_type): Likewise.
* ipa-icf.c (sem_item_optimizer::execute): Likewise.
(sem_item_optimizer::subdivide_classes_by_equality): Likewise.
(sem_item_optimizer::verify_classes): Likewise.
(sem_item_optimizer::traverse_congruence_split): Likewise.
(sem_item_optimizer::checking_verify_classes): New.
* ipa-icf.h (sem_item_optimizer::checking_verify_classes): Add new
method.
* cfgrtl.c (commit_edge_insertions): Likewise.
(fixup_reorder_chain, cfg_layout_finalize): Likewise.
(rtl_flow_call_edges_add): Likewise.
* cgraph.c (symbol_table::create_edge): Likewise.
(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
* cgraph.h (symtab_node): Likewise.
(symtab_node::checking_verify_symtab_nodes): Define.
(cgraph_node::checking_verify_cgraph_nodes): Define.
* cfghooks.h (checking_verify_flow_info): Define.
* cfgloop.h (checking_verify_loop_structure): Define.
* dominance.h (checking_verify_dominators): Define.
* et-forest.c: Fix comment.
* ipa-inline-analysis.c (compute_inline_parameters): Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* ipa-inline-transform.c (save_inline_function_body): Likewise.
* ipa-inline.c (inline_small_functions): Likewise.
(early_inliner): Likewise.
* ipa-inline.h (estimate_edge_growth): Likewise.
* ipa-visibility.c (function_and_variable_visibility): Likewise.
* ipa.c (symbol_table::remove_unreachable_nodes): Likewise.
(ipa_single_use): Likewise.
* ira-int.h: Likewise.
* ira.c (ira): Likewise.
* loop-doloop.c (doloop_optimize_loops): Likewise.
* loop-init.c (loop_optimizer_init, fix_loop_structure): Likewise.
* loop-invariant.c (move_loop_invariants): Likewise.
* lra-assigns.c (lra_assign): Likewise.
* lra-constraints.c (lra_constraints): Likewise.
* lra-eliminations.c (lra_eliminate): Likewise.
* lra-int.h (struct lra_reg): Likewise.
* lra-lives.c (check_pseudos_live_through_calls): Likewise.
(lra_create_live_ranges_1): Likewise.
* lra-remat.c (create_remat_bb_data): Likewise.
* lra.c (lra_update_insn_recog_data, restore_scratches): Likewise.
(lra): Likewise.
(check_rtl): Always define. Remove incorrect guard around
extract_constrain_insn call.
* lto-cgraph.c (input_cgraph_1: Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* lto-streamer-out.c (DFS::DFS): Likewise.
(lto_output): Likewise.
* lto-streamer.c (lto_streamer_init): Likewise.
* omp-low.c (scan_omp_target, expand_omp_taskreg): Likewise.
expand_omp_target, execute_expand_omp): Likewise.
(lower_omp_target): Likewise.
* passes.c (execute_function_todo): Likewise.
(execute_todo, execute_one_pass): Likewise.
(verify_curr_properties): Always define.
* predict.c (tree_estimate_probability: Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
(propagate_freq): Likewise.
* pretty-print.c (pp_format): Likewise.
* real.c (real_to_decimal_for_mode): Likewise.
* recog.c (split_all_insns): Likewise.
* regcprop.c (kill_value_one_regno): Likewise.
(copy_value): Likewise.
(validate_value_data): Define unconditionally.
* reload.c: Fix comment.
* timevar.c: Include options.h
* tree-ssa.h (checking_verify_ssa): Define.
* tree-ssa-loop-manip.h (checking_verify_loop_closed_ssa): Define.
* sched-deps.c (CHECK): Remove unused macro.
(add_or_update_dep_1, sd_add_dep: Use flag_checking, CHECKING_P
gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* sel-sched-ir.c (free_regset_pool, tidy_control_flow): Likewise.
* sel-sched.c (struct moveop_static_params): Likewise.
(find_best_reg_for_expr, move_cond_jump): Likewise.
(move_op_orig_expr_not_found): Likewise.
(code_motion_process_successors, move_op): Likewise.
* ssa-iterators.h (first_readonly_imm_use): Likewise.
(next_readonly_imm_use): Likewise.
* store-motion.c (compute_store_table): Likewise.
* symbol-summary.h (function_summary::function_summary): Likewise.
* target.h (cumulative_args_t): Likewise.
(get_cumulative_args, pack_cumulative_args): Likewise.
* timevar.c: (timer::print): Likewise.
* trans-mem.c (ipa_tm_execute): Likewise.
* tree-cfg.c (move_stmt_op): Likewise.
(move_sese_region_to_fn): Likewise.
(gimple_flow_call_edges_add): Likewise.
* tree-cfgcleanup.c (cleanup_tree_cfg_noloop, repair_loop_structures):
Likewise.
* tree-eh.c (remove_unreachable_handlers): Likewise.
* tree-if-conv.c (pass_if_conversion::execute): Likewise.
* tree-inline.c (expand_call_inline, optimize_inline_calls): Likewise.
* tree-into-ssa.c (update_ssa): Likewise.
* tree-loop-distribution.c (pass_loop_distribution::execute): Likewise.
* tree-outof-ssa.c (eliminate_useless_phis, rewrite_trees): Likewise.
* tree-parloops.c (pass_parallelize_loops::execute): Likewise.
* tree-predcom.c (suitable_component_p): Likewise.
* tree-profile.c (gimple_gen_const_delta_profiler): Likewise.
* tree-ssa-alias.c (refs_may_alias_p_1): Likewise.
* tree-ssa-live.c (verify_live_on_entry): Likewise.
* tree-ssa-live.h (register_ssa_partition): Likewise.
* tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely): Likewise.
* tree-ssa-loop-manip.c (add_exit_phi): Likewise.
(tree_transform_and_unroll_loop): Likewise.
* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree-ssa-propagate.c (replace_exp_1): Likewise.
* tree-ssa-structalias.c (rewrite_constraints): Likewise.
* tree-ssa-ter.c (free_temp_expr_table): Likewise.
* tree-ssa-threadupdate.c (duplicate_thread_path): Likewise.
* tree-ssanames.c (release_ssa_name_fn): Likewise.
* tree-stdarg.c (expand_ifn_va_arg): Likewise.
* tree-vect-loop-manip.c
(slpeel_tree_duplicate_loop_to_edge_cfg): Likewise.
(slpeel_checking_verify_cfg_after_peeling): Likewise.
(vect_do_peeling_for_loop_bound): Likewise.
(vect_do_peeling_for_alignment): Likewise.
* tree-vrp.c (supports_overflow_infinity): Likewise.
(set_value_range): Likewise.
* tree.c (free_lang_data_in_cgraph): Likewise.
* value-prof.c (gimple_remove_histogram_value): Likewise.
(free_hist): Likewise.
* var-tracking.c (canonicalize_values_star): Likewise.
(compute_bb_dataflow, vt_find_locations, vt_emit_notes): Likewise.
From-SVN: r229470
2015-10-28 02:05:53 +01:00
|
|
|
|
checking_verify_loop_closed_ssa (true);
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|
[PATCH 7/9] ENABLE_CHECKING refactoring: middle-end, LTO FE
[PATCH 7/9] ENABLE_CHECKING refactoring: middle-end, LTO FE
gcc/lto/ChangeLog:
2015-10-27 Mikhail Maltsev <maltsevm@gmail.com>
* lto.c (unify_scc): Use flag_checking and remove ENABLE_CHECKING
conditionals.
(lto_fixup_state): Likewise.
(do_whole_program_analysis): Use
symtab_node::checking_verify_symtab_nodes and remove ENABLE_CHECKING
conditionals.
gcc/ChangeLog:
2015-10-27 Mikhail Maltsev <maltsevm@gmail.com>
* attribs.c (check_attribute_tables): New function, broken out from...
(init_attributes): Use it.
* cfgcleanup.c (try_optimize_cfg): Use flag_checking, CHECKING_P
gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* cfgexpand.c (expand_goto, expand_debug_expr): Likewise.
(pass_expand::execute): Likewise.
* cgraphclones.c (symbol_table::materialize_all_clones): Likewise.
* cgraphunit.c (mark_functions_to_output): Likewise.
(cgraph_node::expand_thunk): Likewise.
(symbol_table::compile): Likewise.
* ddg.c (add_cross_iteration_register_deps): Likewise.
(create_ddg_all_sccs): Likewise.
* df-core.c (df_finish_pass, df_analyze): Likewise.
* diagnostic-core.h: Likewise.
* diagnostic.c (diagnostic_report_diagnostic): Likewise.
* dominance.c (calculate_dominance_info): Likewise.
* dwarf2out.c (add_AT_die_ref): Likewise.
(const_ok_for_output_1, mem_loc_descriptor): Likewise.
(loc_list_from_tree, gen_lexical_block_die): Likewise.
gen_type_die_with_usage, gen_type_die): Likewise.
(dwarf2out_decl): Likewise.
* emit-rtl.c (verify_rtx_sharing, reorder_insns_nobb): Likewise.
* except.c (duplicate_eh_regions): Likewise.
* fwprop.c (register_active_defs, update_df_init): Likewise.
(fwprop_init, fwprop_done): Likewise.
(update_uses): Likewise.
* ggc-page.c (ggc_grow): Likewise.
* gimplify.c (gimplify_body): Likewise.
(gimplify_hasher::equal): Likewise.
* graphite-isl-ast-to-gimple.c (graphite_verify): Likewise.
* graphite-scop-detection.c (canonicalize_loop_closed_ssa_form):
Likewise.
* graphite-sese-to-poly.c (rewrite_reductions_out_of_ssa): Likewise.
(rewrite_cross_bb_scalar_deps_out_of_ssa): Likwise.
* hash-table.h (::find_empty_slot_for_expand): Likewise.
* ifcvt.c (if_convert): Likewise.
* ipa-cp.c (ipcp_propagate_stage): Likewise.
* ipa-devirt.c (type_in_anonymous_namespace_p): Likewise.
(odr_type_p, odr_types_equivalent_p): Likewise.
(add_type_duplicate, get_odr_type): Likewise.
* ipa-icf.c (sem_item_optimizer::execute): Likewise.
(sem_item_optimizer::subdivide_classes_by_equality): Likewise.
(sem_item_optimizer::verify_classes): Likewise.
(sem_item_optimizer::traverse_congruence_split): Likewise.
(sem_item_optimizer::checking_verify_classes): New.
* ipa-icf.h (sem_item_optimizer::checking_verify_classes): Add new
method.
* cfgrtl.c (commit_edge_insertions): Likewise.
(fixup_reorder_chain, cfg_layout_finalize): Likewise.
(rtl_flow_call_edges_add): Likewise.
* cgraph.c (symbol_table::create_edge): Likewise.
(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
* cgraph.h (symtab_node): Likewise.
(symtab_node::checking_verify_symtab_nodes): Define.
(cgraph_node::checking_verify_cgraph_nodes): Define.
* cfghooks.h (checking_verify_flow_info): Define.
* cfgloop.h (checking_verify_loop_structure): Define.
* dominance.h (checking_verify_dominators): Define.
* et-forest.c: Fix comment.
* ipa-inline-analysis.c (compute_inline_parameters): Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* ipa-inline-transform.c (save_inline_function_body): Likewise.
* ipa-inline.c (inline_small_functions): Likewise.
(early_inliner): Likewise.
* ipa-inline.h (estimate_edge_growth): Likewise.
* ipa-visibility.c (function_and_variable_visibility): Likewise.
* ipa.c (symbol_table::remove_unreachable_nodes): Likewise.
(ipa_single_use): Likewise.
* ira-int.h: Likewise.
* ira.c (ira): Likewise.
* loop-doloop.c (doloop_optimize_loops): Likewise.
* loop-init.c (loop_optimizer_init, fix_loop_structure): Likewise.
* loop-invariant.c (move_loop_invariants): Likewise.
* lra-assigns.c (lra_assign): Likewise.
* lra-constraints.c (lra_constraints): Likewise.
* lra-eliminations.c (lra_eliminate): Likewise.
* lra-int.h (struct lra_reg): Likewise.
* lra-lives.c (check_pseudos_live_through_calls): Likewise.
(lra_create_live_ranges_1): Likewise.
* lra-remat.c (create_remat_bb_data): Likewise.
* lra.c (lra_update_insn_recog_data, restore_scratches): Likewise.
(lra): Likewise.
(check_rtl): Always define. Remove incorrect guard around
extract_constrain_insn call.
* lto-cgraph.c (input_cgraph_1: Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* lto-streamer-out.c (DFS::DFS): Likewise.
(lto_output): Likewise.
* lto-streamer.c (lto_streamer_init): Likewise.
* omp-low.c (scan_omp_target, expand_omp_taskreg): Likewise.
expand_omp_target, execute_expand_omp): Likewise.
(lower_omp_target): Likewise.
* passes.c (execute_function_todo): Likewise.
(execute_todo, execute_one_pass): Likewise.
(verify_curr_properties): Always define.
* predict.c (tree_estimate_probability: Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
(propagate_freq): Likewise.
* pretty-print.c (pp_format): Likewise.
* real.c (real_to_decimal_for_mode): Likewise.
* recog.c (split_all_insns): Likewise.
* regcprop.c (kill_value_one_regno): Likewise.
(copy_value): Likewise.
(validate_value_data): Define unconditionally.
* reload.c: Fix comment.
* timevar.c: Include options.h
* tree-ssa.h (checking_verify_ssa): Define.
* tree-ssa-loop-manip.h (checking_verify_loop_closed_ssa): Define.
* sched-deps.c (CHECK): Remove unused macro.
(add_or_update_dep_1, sd_add_dep: Use flag_checking, CHECKING_P
gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* sel-sched-ir.c (free_regset_pool, tidy_control_flow): Likewise.
* sel-sched.c (struct moveop_static_params): Likewise.
(find_best_reg_for_expr, move_cond_jump): Likewise.
(move_op_orig_expr_not_found): Likewise.
(code_motion_process_successors, move_op): Likewise.
* ssa-iterators.h (first_readonly_imm_use): Likewise.
(next_readonly_imm_use): Likewise.
* store-motion.c (compute_store_table): Likewise.
* symbol-summary.h (function_summary::function_summary): Likewise.
* target.h (cumulative_args_t): Likewise.
(get_cumulative_args, pack_cumulative_args): Likewise.
* timevar.c: (timer::print): Likewise.
* trans-mem.c (ipa_tm_execute): Likewise.
* tree-cfg.c (move_stmt_op): Likewise.
(move_sese_region_to_fn): Likewise.
(gimple_flow_call_edges_add): Likewise.
* tree-cfgcleanup.c (cleanup_tree_cfg_noloop, repair_loop_structures):
Likewise.
* tree-eh.c (remove_unreachable_handlers): Likewise.
* tree-if-conv.c (pass_if_conversion::execute): Likewise.
* tree-inline.c (expand_call_inline, optimize_inline_calls): Likewise.
* tree-into-ssa.c (update_ssa): Likewise.
* tree-loop-distribution.c (pass_loop_distribution::execute): Likewise.
* tree-outof-ssa.c (eliminate_useless_phis, rewrite_trees): Likewise.
* tree-parloops.c (pass_parallelize_loops::execute): Likewise.
* tree-predcom.c (suitable_component_p): Likewise.
* tree-profile.c (gimple_gen_const_delta_profiler): Likewise.
* tree-ssa-alias.c (refs_may_alias_p_1): Likewise.
* tree-ssa-live.c (verify_live_on_entry): Likewise.
* tree-ssa-live.h (register_ssa_partition): Likewise.
* tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely): Likewise.
* tree-ssa-loop-manip.c (add_exit_phi): Likewise.
(tree_transform_and_unroll_loop): Likewise.
* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree-ssa-propagate.c (replace_exp_1): Likewise.
* tree-ssa-structalias.c (rewrite_constraints): Likewise.
* tree-ssa-ter.c (free_temp_expr_table): Likewise.
* tree-ssa-threadupdate.c (duplicate_thread_path): Likewise.
* tree-ssanames.c (release_ssa_name_fn): Likewise.
* tree-stdarg.c (expand_ifn_va_arg): Likewise.
* tree-vect-loop-manip.c
(slpeel_tree_duplicate_loop_to_edge_cfg): Likewise.
(slpeel_checking_verify_cfg_after_peeling): Likewise.
(vect_do_peeling_for_loop_bound): Likewise.
(vect_do_peeling_for_alignment): Likewise.
* tree-vrp.c (supports_overflow_infinity): Likewise.
(set_value_range): Likewise.
* tree.c (free_lang_data_in_cgraph): Likewise.
* value-prof.c (gimple_remove_histogram_value): Likewise.
(free_hist): Likewise.
* var-tracking.c (canonicalize_values_star): Likewise.
(compute_bb_dataflow, vt_find_locations, vt_emit_notes): Likewise.
From-SVN: r229470
2015-10-28 02:05:53 +01:00
|
|
|
|
loop_p loop;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
FOR_EACH_LOOP (loop, 0)
|
|
|
|
|
canonicalize_loop_closed_ssa (loop);
|
|
|
|
|
|
|
|
|
|
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
|
|
|
|
|
update_ssa (TODO_update_ssa);
|
|
|
|
|
|
[PATCH 7/9] ENABLE_CHECKING refactoring: middle-end, LTO FE
[PATCH 7/9] ENABLE_CHECKING refactoring: middle-end, LTO FE
gcc/lto/ChangeLog:
2015-10-27 Mikhail Maltsev <maltsevm@gmail.com>
* lto.c (unify_scc): Use flag_checking and remove ENABLE_CHECKING
conditionals.
(lto_fixup_state): Likewise.
(do_whole_program_analysis): Use
symtab_node::checking_verify_symtab_nodes and remove ENABLE_CHECKING
conditionals.
gcc/ChangeLog:
2015-10-27 Mikhail Maltsev <maltsevm@gmail.com>
* attribs.c (check_attribute_tables): New function, broken out from...
(init_attributes): Use it.
* cfgcleanup.c (try_optimize_cfg): Use flag_checking, CHECKING_P
gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* cfgexpand.c (expand_goto, expand_debug_expr): Likewise.
(pass_expand::execute): Likewise.
* cgraphclones.c (symbol_table::materialize_all_clones): Likewise.
* cgraphunit.c (mark_functions_to_output): Likewise.
(cgraph_node::expand_thunk): Likewise.
(symbol_table::compile): Likewise.
* ddg.c (add_cross_iteration_register_deps): Likewise.
(create_ddg_all_sccs): Likewise.
* df-core.c (df_finish_pass, df_analyze): Likewise.
* diagnostic-core.h: Likewise.
* diagnostic.c (diagnostic_report_diagnostic): Likewise.
* dominance.c (calculate_dominance_info): Likewise.
* dwarf2out.c (add_AT_die_ref): Likewise.
(const_ok_for_output_1, mem_loc_descriptor): Likewise.
(loc_list_from_tree, gen_lexical_block_die): Likewise.
gen_type_die_with_usage, gen_type_die): Likewise.
(dwarf2out_decl): Likewise.
* emit-rtl.c (verify_rtx_sharing, reorder_insns_nobb): Likewise.
* except.c (duplicate_eh_regions): Likewise.
* fwprop.c (register_active_defs, update_df_init): Likewise.
(fwprop_init, fwprop_done): Likewise.
(update_uses): Likewise.
* ggc-page.c (ggc_grow): Likewise.
* gimplify.c (gimplify_body): Likewise.
(gimplify_hasher::equal): Likewise.
* graphite-isl-ast-to-gimple.c (graphite_verify): Likewise.
* graphite-scop-detection.c (canonicalize_loop_closed_ssa_form):
Likewise.
* graphite-sese-to-poly.c (rewrite_reductions_out_of_ssa): Likewise.
(rewrite_cross_bb_scalar_deps_out_of_ssa): Likwise.
* hash-table.h (::find_empty_slot_for_expand): Likewise.
* ifcvt.c (if_convert): Likewise.
* ipa-cp.c (ipcp_propagate_stage): Likewise.
* ipa-devirt.c (type_in_anonymous_namespace_p): Likewise.
(odr_type_p, odr_types_equivalent_p): Likewise.
(add_type_duplicate, get_odr_type): Likewise.
* ipa-icf.c (sem_item_optimizer::execute): Likewise.
(sem_item_optimizer::subdivide_classes_by_equality): Likewise.
(sem_item_optimizer::verify_classes): Likewise.
(sem_item_optimizer::traverse_congruence_split): Likewise.
(sem_item_optimizer::checking_verify_classes): New.
* ipa-icf.h (sem_item_optimizer::checking_verify_classes): Add new
method.
* cfgrtl.c (commit_edge_insertions): Likewise.
(fixup_reorder_chain, cfg_layout_finalize): Likewise.
(rtl_flow_call_edges_add): Likewise.
* cgraph.c (symbol_table::create_edge): Likewise.
(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
* cgraph.h (symtab_node): Likewise.
(symtab_node::checking_verify_symtab_nodes): Define.
(cgraph_node::checking_verify_cgraph_nodes): Define.
* cfghooks.h (checking_verify_flow_info): Define.
* cfgloop.h (checking_verify_loop_structure): Define.
* dominance.h (checking_verify_dominators): Define.
* et-forest.c: Fix comment.
* ipa-inline-analysis.c (compute_inline_parameters): Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* ipa-inline-transform.c (save_inline_function_body): Likewise.
* ipa-inline.c (inline_small_functions): Likewise.
(early_inliner): Likewise.
* ipa-inline.h (estimate_edge_growth): Likewise.
* ipa-visibility.c (function_and_variable_visibility): Likewise.
* ipa.c (symbol_table::remove_unreachable_nodes): Likewise.
(ipa_single_use): Likewise.
* ira-int.h: Likewise.
* ira.c (ira): Likewise.
* loop-doloop.c (doloop_optimize_loops): Likewise.
* loop-init.c (loop_optimizer_init, fix_loop_structure): Likewise.
* loop-invariant.c (move_loop_invariants): Likewise.
* lra-assigns.c (lra_assign): Likewise.
* lra-constraints.c (lra_constraints): Likewise.
* lra-eliminations.c (lra_eliminate): Likewise.
* lra-int.h (struct lra_reg): Likewise.
* lra-lives.c (check_pseudos_live_through_calls): Likewise.
(lra_create_live_ranges_1): Likewise.
* lra-remat.c (create_remat_bb_data): Likewise.
* lra.c (lra_update_insn_recog_data, restore_scratches): Likewise.
(lra): Likewise.
(check_rtl): Always define. Remove incorrect guard around
extract_constrain_insn call.
* lto-cgraph.c (input_cgraph_1: Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* lto-streamer-out.c (DFS::DFS): Likewise.
(lto_output): Likewise.
* lto-streamer.c (lto_streamer_init): Likewise.
* omp-low.c (scan_omp_target, expand_omp_taskreg): Likewise.
expand_omp_target, execute_expand_omp): Likewise.
(lower_omp_target): Likewise.
* passes.c (execute_function_todo): Likewise.
(execute_todo, execute_one_pass): Likewise.
(verify_curr_properties): Always define.
* predict.c (tree_estimate_probability: Use flag_checking,
CHECKING_P gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
(propagate_freq): Likewise.
* pretty-print.c (pp_format): Likewise.
* real.c (real_to_decimal_for_mode): Likewise.
* recog.c (split_all_insns): Likewise.
* regcprop.c (kill_value_one_regno): Likewise.
(copy_value): Likewise.
(validate_value_data): Define unconditionally.
* reload.c: Fix comment.
* timevar.c: Include options.h
* tree-ssa.h (checking_verify_ssa): Define.
* tree-ssa-loop-manip.h (checking_verify_loop_closed_ssa): Define.
* sched-deps.c (CHECK): Remove unused macro.
(add_or_update_dep_1, sd_add_dep: Use flag_checking, CHECKING_P
gcc_checking_assert and checking_* functions to eliminate
ENABLE_CHECKING conditionals.
* sel-sched-ir.c (free_regset_pool, tidy_control_flow): Likewise.
* sel-sched.c (struct moveop_static_params): Likewise.
(find_best_reg_for_expr, move_cond_jump): Likewise.
(move_op_orig_expr_not_found): Likewise.
(code_motion_process_successors, move_op): Likewise.
* ssa-iterators.h (first_readonly_imm_use): Likewise.
(next_readonly_imm_use): Likewise.
* store-motion.c (compute_store_table): Likewise.
* symbol-summary.h (function_summary::function_summary): Likewise.
* target.h (cumulative_args_t): Likewise.
(get_cumulative_args, pack_cumulative_args): Likewise.
* timevar.c: (timer::print): Likewise.
* trans-mem.c (ipa_tm_execute): Likewise.
* tree-cfg.c (move_stmt_op): Likewise.
(move_sese_region_to_fn): Likewise.
(gimple_flow_call_edges_add): Likewise.
* tree-cfgcleanup.c (cleanup_tree_cfg_noloop, repair_loop_structures):
Likewise.
* tree-eh.c (remove_unreachable_handlers): Likewise.
* tree-if-conv.c (pass_if_conversion::execute): Likewise.
* tree-inline.c (expand_call_inline, optimize_inline_calls): Likewise.
* tree-into-ssa.c (update_ssa): Likewise.
* tree-loop-distribution.c (pass_loop_distribution::execute): Likewise.
* tree-outof-ssa.c (eliminate_useless_phis, rewrite_trees): Likewise.
* tree-parloops.c (pass_parallelize_loops::execute): Likewise.
* tree-predcom.c (suitable_component_p): Likewise.
* tree-profile.c (gimple_gen_const_delta_profiler): Likewise.
* tree-ssa-alias.c (refs_may_alias_p_1): Likewise.
* tree-ssa-live.c (verify_live_on_entry): Likewise.
* tree-ssa-live.h (register_ssa_partition): Likewise.
* tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely): Likewise.
* tree-ssa-loop-manip.c (add_exit_phi): Likewise.
(tree_transform_and_unroll_loop): Likewise.
* tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
* tree-ssa-operands.c (get_expr_operands): Likewise.
* tree-ssa-propagate.c (replace_exp_1): Likewise.
* tree-ssa-structalias.c (rewrite_constraints): Likewise.
* tree-ssa-ter.c (free_temp_expr_table): Likewise.
* tree-ssa-threadupdate.c (duplicate_thread_path): Likewise.
* tree-ssanames.c (release_ssa_name_fn): Likewise.
* tree-stdarg.c (expand_ifn_va_arg): Likewise.
* tree-vect-loop-manip.c
(slpeel_tree_duplicate_loop_to_edge_cfg): Likewise.
(slpeel_checking_verify_cfg_after_peeling): Likewise.
(vect_do_peeling_for_loop_bound): Likewise.
(vect_do_peeling_for_alignment): Likewise.
* tree-vrp.c (supports_overflow_infinity): Likewise.
(set_value_range): Likewise.
* tree.c (free_lang_data_in_cgraph): Likewise.
* value-prof.c (gimple_remove_histogram_value): Likewise.
(free_hist): Likewise.
* var-tracking.c (canonicalize_values_star): Likewise.
(compute_bb_dataflow, vt_find_locations, vt_emit_notes): Likewise.
From-SVN: r229470
2015-10-28 02:05:53 +01:00
|
|
|
|
checking_verify_loop_closed_ssa (true);
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Can all ivs be represented by a signed integer?
|
2015-12-17 19:50:05 +01:00
|
|
|
|
As isl might generate negative values in its expressions, signed loop ivs
|
2015-10-05 18:02:59 +02:00
|
|
|
|
are required in the backend. */
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
loop_ivs_can_be_represented (loop_p loop)
|
|
|
|
|
{
|
|
|
|
|
unsigned type_long_long = TYPE_PRECISION (long_long_integer_type_node);
|
|
|
|
|
for (gphi_iterator psi = gsi_start_phis (loop->header); !gsi_end_p (psi);
|
|
|
|
|
gsi_next (&psi))
|
|
|
|
|
{
|
|
|
|
|
gphi *phi = psi.phi ();
|
|
|
|
|
tree res = PHI_RESULT (phi);
|
|
|
|
|
tree type = TREE_TYPE (res);
|
|
|
|
|
|
|
|
|
|
if (TYPE_UNSIGNED (type) && TYPE_PRECISION (type) >= type_long_long)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns a COND_EXPR statement when BB has a single predecessor, the
|
|
|
|
|
edge between BB and its predecessor is not a loop exit edge, and
|
|
|
|
|
the last statement of the single predecessor is a COND_EXPR. */
|
|
|
|
|
|
|
|
|
|
static gcond *
|
|
|
|
|
single_pred_cond_non_loop_exit (basic_block bb)
|
|
|
|
|
{
|
|
|
|
|
if (single_pred_p (bb))
|
|
|
|
|
{
|
|
|
|
|
edge e = single_pred_edge (bb);
|
|
|
|
|
basic_block pred = e->src;
|
|
|
|
|
gimple *stmt;
|
|
|
|
|
|
|
|
|
|
if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
stmt = last_stmt (pred);
|
|
|
|
|
|
|
|
|
|
if (stmt && gimple_code (stmt) == GIMPLE_COND)
|
|
|
|
|
return as_a<gcond *> (stmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* Build the maximal scop containing LOOPs and add it to SCOPS. */
|
|
|
|
|
|
|
|
|
|
class scop_detection
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
scop_detection () : scops (vNULL) {}
|
|
|
|
|
|
2015-11-13 13:28:54 +01:00
|
|
|
|
~scop_detection ()
|
|
|
|
|
{
|
|
|
|
|
scops.release ();
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* A marker for invalid sese_l. */
|
|
|
|
|
static sese_l invalid_sese;
|
|
|
|
|
|
|
|
|
|
/* Return the SCOPS in this SCOP_DETECTION. */
|
|
|
|
|
|
|
|
|
|
vec<sese_l>
|
|
|
|
|
get_scops ()
|
|
|
|
|
{
|
|
|
|
|
return scops;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return an sese_l around the LOOP. */
|
|
|
|
|
|
|
|
|
|
sese_l get_sese (loop_p loop);
|
|
|
|
|
|
|
|
|
|
/* Return the closest dominator with a single entry edge. In case of a
|
|
|
|
|
back-loop the back-edge is not counted. */
|
|
|
|
|
|
|
|
|
|
static edge get_nearest_dom_with_single_entry (basic_block dom);
|
|
|
|
|
|
|
|
|
|
/* Return the closest post-dominator with a single exit edge. In case of a
|
|
|
|
|
back-loop the back-edge is not counted. */
|
|
|
|
|
|
|
|
|
|
static edge get_nearest_pdom_with_single_exit (basic_block dom);
|
|
|
|
|
|
|
|
|
|
/* Merge scops at same loop depth and returns the new sese.
|
|
|
|
|
Returns a new SESE when merge was successful, INVALID_SESE otherwise. */
|
|
|
|
|
|
|
|
|
|
sese_l merge_sese (sese_l first, sese_l second) const;
|
|
|
|
|
|
|
|
|
|
/* Build scop outer->inner if possible. */
|
|
|
|
|
|
|
|
|
|
sese_l build_scop_depth (sese_l s, loop_p loop);
|
|
|
|
|
|
|
|
|
|
/* If loop and loop->next are valid scops, try to merge them. */
|
|
|
|
|
|
|
|
|
|
sese_l build_scop_breadth (sese_l s1, loop_p loop);
|
|
|
|
|
|
|
|
|
|
/* Return true when LOOP is a valid scop, that is a Static Control Part, a
|
|
|
|
|
region of code that can be represented in the polyhedral model. SCOP
|
|
|
|
|
defines the region we analyse. */
|
|
|
|
|
|
2016-01-21 03:13:05 +01:00
|
|
|
|
bool loop_is_valid_in_scop (loop_p loop, sese_l scop) const;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|
|
|
|
|
/* Return true when BEGIN is the preheader edge of a loop with a single exit
|
|
|
|
|
END. */
|
|
|
|
|
|
|
|
|
|
static bool region_has_one_loop (sese_l s);
|
|
|
|
|
|
|
|
|
|
/* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END. */
|
|
|
|
|
|
|
|
|
|
void add_scop (sese_l s);
|
|
|
|
|
|
|
|
|
|
/* Returns true if S1 subsumes/surrounds S2. */
|
|
|
|
|
static bool subsumes (sese_l s1, sese_l s2);
|
|
|
|
|
|
|
|
|
|
/* Remove a SCoP which is subsumed by S1. */
|
|
|
|
|
void remove_subscops (sese_l s1);
|
|
|
|
|
|
|
|
|
|
/* Returns true if S1 intersects with S2. Since we already know that S1 does
|
|
|
|
|
not subsume S2 or vice-versa, we only check for entry bbs. */
|
|
|
|
|
|
|
|
|
|
static bool intersects (sese_l s1, sese_l s2);
|
|
|
|
|
|
|
|
|
|
/* Remove one of the scops when it intersects with any other. */
|
|
|
|
|
|
|
|
|
|
void remove_intersecting_scops (sese_l s1);
|
|
|
|
|
|
|
|
|
|
/* Return true when the body of LOOP has statements that can be represented
|
|
|
|
|
as a valid scop. */
|
|
|
|
|
|
|
|
|
|
bool loop_body_is_valid_scop (loop_p loop, sese_l scop) const;
|
|
|
|
|
|
|
|
|
|
/* Return true when BB contains a harmful operation for a scop: that
|
|
|
|
|
can be a function call with side effects, the induction variables
|
|
|
|
|
are not linear with respect to SCOP, etc. The current open
|
|
|
|
|
scop should end before this statement. */
|
|
|
|
|
|
|
|
|
|
bool harmful_stmt_in_bb (sese_l scop, basic_block bb) const;
|
|
|
|
|
|
|
|
|
|
/* Return true when a statement in SCOP cannot be represented by Graphite.
|
|
|
|
|
The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
|
|
|
|
|
Limit the number of bbs between adjacent loops to
|
|
|
|
|
PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS. */
|
|
|
|
|
|
2016-01-21 03:13:05 +01:00
|
|
|
|
bool harmful_loop_in_region (sese_l scop) const;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|
|
|
|
|
/* Return true only when STMT is simple enough for being handled by Graphite.
|
|
|
|
|
This depends on SCOP, as the parameters are initialized relatively to
|
|
|
|
|
this basic block, the linear functions are initialized based on the
|
|
|
|
|
outermost loop containing STMT inside the SCOP. BB is the place where we
|
|
|
|
|
try to evaluate the STMT. */
|
|
|
|
|
|
|
|
|
|
bool stmt_simple_for_scop_p (sese_l scop, gimple *stmt,
|
|
|
|
|
basic_block bb) const;
|
|
|
|
|
|
|
|
|
|
/* Something like "n * m" is not allowed. */
|
|
|
|
|
|
|
|
|
|
static bool graphite_can_represent_init (tree e);
|
|
|
|
|
|
|
|
|
|
/* Return true when SCEV can be represented in the polyhedral model.
|
|
|
|
|
|
|
|
|
|
An expression can be represented, if it can be expressed as an
|
|
|
|
|
affine expression. For loops (i, j) and parameters (m, n) all
|
|
|
|
|
affine expressions are of the form:
|
|
|
|
|
|
|
|
|
|
x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z
|
|
|
|
|
|
|
|
|
|
1 i + 20 j + (-2) m + 25
|
|
|
|
|
|
|
|
|
|
Something like "i * n" or "n * m" is not allowed. */
|
|
|
|
|
|
|
|
|
|
static bool graphite_can_represent_scev (tree scev);
|
|
|
|
|
|
|
|
|
|
/* Return true when EXPR can be represented in the polyhedral model.
|
|
|
|
|
|
|
|
|
|
This means an expression can be represented, if it is linear with respect
|
|
|
|
|
to the loops and the strides are non parametric. LOOP is the place where
|
|
|
|
|
the expr will be evaluated. SCOP defines the region we analyse. */
|
|
|
|
|
|
|
|
|
|
static bool graphite_can_represent_expr (sese_l scop, loop_p loop,
|
|
|
|
|
tree expr);
|
|
|
|
|
|
|
|
|
|
/* Return true if the data references of STMT can be represented by Graphite.
|
|
|
|
|
We try to analyze the data references in a loop contained in the SCOP. */
|
|
|
|
|
|
|
|
|
|
static bool stmt_has_simple_data_refs_p (sese_l scop, gimple *stmt);
|
|
|
|
|
|
|
|
|
|
/* Remove the close phi node at GSI and replace its rhs with the rhs
|
|
|
|
|
of PHI. */
|
|
|
|
|
|
|
|
|
|
static void remove_duplicate_close_phi (gphi *phi, gphi_iterator *gsi);
|
|
|
|
|
|
|
|
|
|
/* Returns true when Graphite can represent LOOP in SCOP.
|
|
|
|
|
FIXME: For the moment, graphite cannot be used on loops that iterate using
|
|
|
|
|
induction variables that wrap. */
|
|
|
|
|
|
|
|
|
|
static bool can_represent_loop_1 (loop_p loop, sese_l scop);
|
|
|
|
|
|
|
|
|
|
/* Return true when all the loops within LOOP can be represented by
|
|
|
|
|
Graphite. */
|
|
|
|
|
|
|
|
|
|
static bool can_represent_loop (loop_p loop, sese_l scop);
|
|
|
|
|
|
|
|
|
|
/* Returns the number of pbbs that are in loops contained in SCOP. */
|
|
|
|
|
|
|
|
|
|
static int nb_pbbs_in_loops (scop_p scop);
|
|
|
|
|
|
|
|
|
|
static bool graphite_can_represent_stmt (sese_l, gimple *, basic_block);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
vec<sese_l> scops;
|
|
|
|
|
};
|
|
|
|
|
|
2015-10-21 20:53:17 +02:00
|
|
|
|
sese_l scop_detection::invalid_sese (NULL, NULL);
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|
|
|
|
|
/* Return an sese_l around the LOOP. */
|
|
|
|
|
|
|
|
|
|
sese_l
|
|
|
|
|
scop_detection::get_sese (loop_p loop)
|
|
|
|
|
{
|
|
|
|
|
if (!loop)
|
|
|
|
|
return invalid_sese;
|
|
|
|
|
|
|
|
|
|
if (!loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
|
|
|
|
|
return invalid_sese;
|
|
|
|
|
edge scop_end = single_exit (loop);
|
|
|
|
|
if (!scop_end)
|
|
|
|
|
return invalid_sese;
|
|
|
|
|
edge scop_begin = loop_preheader_edge (loop);
|
|
|
|
|
sese_l s (scop_begin, scop_end);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the closest dominator with a single entry edge. */
|
|
|
|
|
|
|
|
|
|
edge
|
|
|
|
|
scop_detection::get_nearest_dom_with_single_entry (basic_block dom)
|
|
|
|
|
{
|
|
|
|
|
if (!dom->preds)
|
|
|
|
|
return NULL;
|
2015-12-24 17:41:46 +01:00
|
|
|
|
|
|
|
|
|
/* If any of the dominators has two predecessors but one of them is a back
|
|
|
|
|
edge, then that basic block also qualifies as a dominator with single
|
|
|
|
|
entry. */
|
2015-10-05 18:02:59 +02:00
|
|
|
|
if (dom->preds->length () == 2)
|
|
|
|
|
{
|
2015-12-24 17:41:46 +01:00
|
|
|
|
/* If e1->src dominates e2->src then e1->src will also dominate dom. */
|
2015-10-05 18:02:59 +02:00
|
|
|
|
edge e1 = (*dom->preds)[0];
|
|
|
|
|
edge e2 = (*dom->preds)[1];
|
2015-12-04 22:36:55 +01:00
|
|
|
|
loop_p l = dom->loop_father;
|
|
|
|
|
loop_p l1 = e1->src->loop_father;
|
|
|
|
|
loop_p l2 = e2->src->loop_father;
|
2015-12-24 17:41:46 +01:00
|
|
|
|
if (l != l1 && l == l2
|
2015-12-04 22:36:55 +01:00
|
|
|
|
&& dominated_by_p (CDI_DOMINATORS, e2->src, e1->src))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return e1;
|
2015-12-24 17:41:46 +01:00
|
|
|
|
if (l != l2 && l == l1
|
2015-12-04 22:36:55 +01:00
|
|
|
|
&& dominated_by_p (CDI_DOMINATORS, e1->src, e2->src))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return e2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (dom->preds->length () != 1)
|
|
|
|
|
{
|
|
|
|
|
if (dom->preds->length () < 1)
|
|
|
|
|
return NULL;
|
|
|
|
|
dom = get_immediate_dominator (CDI_DOMINATORS, dom);
|
|
|
|
|
if (!dom->preds)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return (*dom->preds)[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the closest post-dominator with a single exit edge. In case of a
|
|
|
|
|
back-loop the back-edge is not counted. */
|
|
|
|
|
|
|
|
|
|
edge
|
2015-12-04 22:36:55 +01:00
|
|
|
|
scop_detection::get_nearest_pdom_with_single_exit (basic_block pdom)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-12-04 22:36:55 +01:00
|
|
|
|
if (!pdom->succs)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return NULL;
|
2015-12-24 17:41:46 +01:00
|
|
|
|
|
|
|
|
|
/* If any of the post-dominators has two successors but one of them is a back
|
|
|
|
|
edge, then that basic block also qualifies as a post-dominator with single
|
|
|
|
|
exit. */
|
2015-12-04 22:36:55 +01:00
|
|
|
|
if (pdom->succs->length () == 2)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-12-24 17:41:46 +01:00
|
|
|
|
/* If e1->dest post-dominates e2->dest then e1->dest will also
|
|
|
|
|
post-dominate pdom. */
|
2015-12-04 22:36:55 +01:00
|
|
|
|
edge e1 = (*pdom->succs)[0];
|
|
|
|
|
edge e2 = (*pdom->succs)[1];
|
|
|
|
|
loop_p l = pdom->loop_father;
|
|
|
|
|
loop_p l1 = e1->dest->loop_father;
|
|
|
|
|
loop_p l2 = e2->dest->loop_father;
|
2015-12-24 17:41:46 +01:00
|
|
|
|
if (l != l1 && l == l2
|
2015-12-04 22:36:55 +01:00
|
|
|
|
&& dominated_by_p (CDI_POST_DOMINATORS, e2->dest, e1->dest))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return e1;
|
2015-12-24 17:41:46 +01:00
|
|
|
|
if (l != l2 && l == l1
|
2015-12-04 22:36:55 +01:00
|
|
|
|
&& dominated_by_p (CDI_POST_DOMINATORS, e1->dest, e2->dest))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return e2;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
while (pdom->succs->length () != 1)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-12-04 22:36:55 +01:00
|
|
|
|
if (pdom->succs->length () < 1)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return NULL;
|
2015-12-04 22:36:55 +01:00
|
|
|
|
pdom = get_immediate_dominator (CDI_POST_DOMINATORS, pdom);
|
|
|
|
|
if (!pdom->succs)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-04 22:36:55 +01:00
|
|
|
|
return (*pdom->succs)[0];
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Merge scops at same loop depth and returns the new sese.
|
|
|
|
|
Returns a new SESE when merge was successful, INVALID_SESE otherwise. */
|
|
|
|
|
|
|
|
|
|
sese_l
|
|
|
|
|
scop_detection::merge_sese (sese_l first, sese_l second) const
|
|
|
|
|
{
|
|
|
|
|
/* In the trivial case first/second may be NULL. */
|
|
|
|
|
if (!first)
|
|
|
|
|
return second;
|
|
|
|
|
if (!second)
|
|
|
|
|
return first;
|
|
|
|
|
|
2016-01-21 03:13:05 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection] try merging sese s1: ";
|
|
|
|
|
print_sese (dump_file, first);
|
|
|
|
|
dp << "[scop-detection] try merging sese s2: ";
|
2015-10-05 18:02:59 +02:00
|
|
|
|
print_sese (dump_file, second));
|
|
|
|
|
|
|
|
|
|
/* Assumption: Both the sese's should be at the same loop depth or one scop
|
|
|
|
|
should subsume the other like in case of nested loops. */
|
|
|
|
|
|
|
|
|
|
/* Find the common dominators for entry,
|
|
|
|
|
and common post-dominators for the exit. */
|
|
|
|
|
basic_block dom = nearest_common_dominator (CDI_DOMINATORS,
|
2015-10-07 17:40:17 +02:00
|
|
|
|
get_entry_bb (first),
|
|
|
|
|
get_entry_bb (second));
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|
|
|
|
|
edge entry = get_nearest_dom_with_single_entry (dom);
|
2015-11-06 21:43:40 +01:00
|
|
|
|
|
|
|
|
|
if (!entry || (entry->flags & EDGE_IRREDUCIBLE_LOOP))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return invalid_sese;
|
|
|
|
|
|
|
|
|
|
basic_block pdom = nearest_common_dominator (CDI_POST_DOMINATORS,
|
2015-10-07 17:40:17 +02:00
|
|
|
|
get_exit_bb (first),
|
|
|
|
|
get_exit_bb (second));
|
2015-10-05 18:02:59 +02:00
|
|
|
|
pdom = nearest_common_dominator (CDI_POST_DOMINATORS, dom, pdom);
|
|
|
|
|
|
|
|
|
|
edge exit = get_nearest_pdom_with_single_exit (pdom);
|
2015-11-06 21:43:40 +01:00
|
|
|
|
|
|
|
|
|
if (!exit || (exit->flags & EDGE_IRREDUCIBLE_LOOP))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return invalid_sese;
|
|
|
|
|
|
|
|
|
|
sese_l combined (entry, exit);
|
|
|
|
|
|
2016-01-21 03:13:05 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection] checking combined sese: ";
|
2015-12-04 22:36:55 +01:00
|
|
|
|
print_sese (dump_file, combined));
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* FIXME: We could iterate to find the dom which dominates pdom, and pdom
|
|
|
|
|
which post-dominates dom, until it stabilizes. Also, ENTRY->SRC and
|
|
|
|
|
EXIT->DEST should be in the same loop nest. */
|
|
|
|
|
if (!dominated_by_p (CDI_DOMINATORS, pdom, dom)
|
|
|
|
|
|| loop_depth (entry->src->loop_father)
|
2015-12-24 17:41:46 +01:00
|
|
|
|
!= loop_depth (exit->dest->loop_father))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return invalid_sese;
|
|
|
|
|
|
2017-03-09 17:19:37 +01:00
|
|
|
|
/* For now we just bail out when there is a loop exit in the region
|
|
|
|
|
that is not also the exit of the region. We could enlarge the
|
|
|
|
|
region to cover the loop that region exits to. See PR79977. */
|
|
|
|
|
if (loop_outer (entry->src->loop_father))
|
|
|
|
|
{
|
|
|
|
|
vec<edge> exits = get_loop_exit_edges (entry->src->loop_father);
|
|
|
|
|
for (unsigned i = 0; i < exits.length (); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (exits[i] != exit
|
|
|
|
|
&& bb_in_region (exits[i]->src, entry->dest, exit->src))
|
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] cannot merge seses.\n");
|
|
|
|
|
exits.release ();
|
|
|
|
|
return invalid_sese;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
exits.release ();
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* For now we just want to bail out when exit does not post-dominate entry.
|
|
|
|
|
TODO: We might just add a basic_block at the exit to make exit
|
|
|
|
|
post-dominate entry (the entire region). */
|
2015-10-07 17:40:17 +02:00
|
|
|
|
if (!dominated_by_p (CDI_POST_DOMINATORS, get_entry_bb (combined),
|
|
|
|
|
get_exit_bb (combined))
|
|
|
|
|
|| !dominated_by_p (CDI_DOMINATORS, get_exit_bb (combined),
|
|
|
|
|
get_entry_bb (combined)))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] cannot merge seses.\n");
|
|
|
|
|
return invalid_sese;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIXME: We should remove this piece of code once
|
|
|
|
|
canonicalize_loop_closed_ssa has been removed, because that function
|
|
|
|
|
adds a BB with single exit. */
|
2015-10-07 17:40:17 +02:00
|
|
|
|
if (!trivially_empty_bb_p (get_exit_bb (combined)))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
|
|
|
|
/* Find the first empty succ (with single exit) of combined.exit. */
|
|
|
|
|
basic_block imm_succ = combined.exit->dest;
|
2016-03-16 10:19:23 +01:00
|
|
|
|
if (single_succ_p (imm_succ)
|
|
|
|
|
&& single_pred_p (imm_succ)
|
|
|
|
|
&& trivially_empty_bb_p (imm_succ))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
combined.exit = single_succ_edge (imm_succ);
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] Discarding SCoP because "
|
2015-10-05 18:02:59 +02:00
|
|
|
|
<< "no single exit (empty succ) for sese exit";
|
|
|
|
|
print_sese (dump_file, combined));
|
|
|
|
|
return invalid_sese;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Analyze all the BBs in new sese. */
|
2016-01-21 03:13:05 +01:00
|
|
|
|
if (harmful_loop_in_region (combined))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return invalid_sese;
|
|
|
|
|
|
|
|
|
|
DEBUG_PRINT (dp << "[merged-sese] s1: "; print_sese (dump_file, combined));
|
|
|
|
|
|
|
|
|
|
return combined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Build scop outer->inner if possible. */
|
|
|
|
|
|
|
|
|
|
sese_l
|
|
|
|
|
scop_detection::build_scop_depth (sese_l s, loop_p loop)
|
|
|
|
|
{
|
|
|
|
|
if (!loop)
|
|
|
|
|
return s;
|
|
|
|
|
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[Depth loop_" << loop->num << "]\n");
|
2015-10-05 18:02:59 +02:00
|
|
|
|
s = build_scop_depth (s, loop->inner);
|
|
|
|
|
|
|
|
|
|
sese_l s2 = merge_sese (s, get_sese (loop));
|
|
|
|
|
if (!s2)
|
|
|
|
|
{
|
|
|
|
|
/* s might be a valid scop, so return it and start analyzing from the
|
|
|
|
|
adjacent loop. */
|
|
|
|
|
build_scop_depth (invalid_sese, loop->next);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-21 03:13:05 +01:00
|
|
|
|
if (!loop_is_valid_in_scop (loop, s2))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return build_scop_depth (invalid_sese, loop->next);
|
|
|
|
|
|
|
|
|
|
return build_scop_breadth (s2, loop);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If loop and loop->next are valid scops, try to merge them. */
|
|
|
|
|
|
|
|
|
|
sese_l
|
|
|
|
|
scop_detection::build_scop_breadth (sese_l s1, loop_p loop)
|
|
|
|
|
{
|
|
|
|
|
if (!loop)
|
|
|
|
|
return s1;
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[Breadth loop_" << loop->num << "]\n");
|
2015-10-05 18:02:59 +02:00
|
|
|
|
gcc_assert (s1);
|
|
|
|
|
|
|
|
|
|
loop_p l = loop;
|
|
|
|
|
sese_l s2 = build_scop_depth (invalid_sese, l->next);
|
|
|
|
|
if (!s2)
|
|
|
|
|
{
|
|
|
|
|
if (s1)
|
|
|
|
|
add_scop (s1);
|
|
|
|
|
return s1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sese_l combined = merge_sese (s1, s2);
|
|
|
|
|
|
2017-02-08 09:30:48 +01:00
|
|
|
|
/* Combining adjacent loops may add unrelated loops into the
|
|
|
|
|
region so we have to check all sub-loops of the outer loop
|
|
|
|
|
that are in the combined region. */
|
|
|
|
|
if (combined)
|
|
|
|
|
for (l = loop_outer (loop)->inner; l; l = l->next)
|
|
|
|
|
if (bb_in_sese_p (l->header, combined)
|
|
|
|
|
&& ! loop_is_valid_in_scop (l, combined))
|
|
|
|
|
{
|
|
|
|
|
combined = invalid_sese;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (combined)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
s1 = combined;
|
|
|
|
|
else
|
|
|
|
|
add_scop (s2);
|
|
|
|
|
|
|
|
|
|
if (s1)
|
|
|
|
|
add_scop (s1);
|
|
|
|
|
return s1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns true when Graphite can represent LOOP in SCOP.
|
|
|
|
|
FIXME: For the moment, graphite cannot be used on loops that iterate using
|
|
|
|
|
induction variables that wrap. */
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
scop_detection::can_represent_loop_1 (loop_p loop, sese_l scop)
|
|
|
|
|
{
|
|
|
|
|
tree niter;
|
|
|
|
|
struct tree_niter_desc niter_desc;
|
|
|
|
|
|
|
|
|
|
return single_exit (loop)
|
2015-11-06 21:43:40 +01:00
|
|
|
|
&& !(loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
&& number_of_iterations_exit (loop, single_exit (loop), &niter_desc, false)
|
|
|
|
|
&& niter_desc.control.no_overflow
|
|
|
|
|
&& (niter = number_of_latch_executions (loop))
|
|
|
|
|
&& !chrec_contains_undetermined (niter)
|
2017-02-01 09:02:50 +01:00
|
|
|
|
&& !chrec_contains_undetermined (scalar_evolution_in_region (scop,
|
|
|
|
|
loop, niter))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
&& graphite_can_represent_expr (scop, loop, niter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return true when all the loops within LOOP can be represented by
|
|
|
|
|
Graphite. */
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
scop_detection::can_represent_loop (loop_p loop, sese_l scop)
|
|
|
|
|
{
|
|
|
|
|
if (!can_represent_loop_1 (loop, scop))
|
|
|
|
|
return false;
|
|
|
|
|
if (loop->inner && !can_represent_loop (loop->inner, scop))
|
|
|
|
|
return false;
|
|
|
|
|
if (loop->next && !can_represent_loop (loop->next, scop))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return true when LOOP is a valid scop, that is a Static Control Part, a
|
|
|
|
|
region of code that can be represented in the polyhedral model. SCOP
|
|
|
|
|
defines the region we analyse. */
|
|
|
|
|
|
|
|
|
|
bool
|
2016-01-21 03:13:05 +01:00
|
|
|
|
scop_detection::loop_is_valid_in_scop (loop_p loop, sese_l scop) const
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
|
|
|
|
if (!scop)
|
|
|
|
|
return false;
|
|
|
|
|
|
2015-11-06 21:43:52 +01:00
|
|
|
|
if (!optimize_loop_nest_for_speed_p (loop))
|
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] loop_"
|
|
|
|
|
<< loop->num << " is not on a hot path.\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
if (!can_represent_loop (loop, scop))
|
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] cannot represent loop_"
|
|
|
|
|
<< loop->num << "\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (loop_body_is_valid_scop (loop, scop))
|
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[valid-scop] loop_" << loop->num
|
2015-11-30 21:29:15 +01:00
|
|
|
|
<< " is a valid scop.\n");
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return true when BEGIN is the preheader edge of a loop with a single exit
|
|
|
|
|
END. */
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
scop_detection::region_has_one_loop (sese_l s)
|
|
|
|
|
{
|
|
|
|
|
edge begin = s.entry;
|
|
|
|
|
edge end = s.exit;
|
|
|
|
|
/* Check for a single perfectly nested loop. */
|
|
|
|
|
if (begin->dest->loop_father->inner)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/* Otherwise, check whether we have adjacent loops. */
|
|
|
|
|
return begin->dest->loop_father == end->src->loop_father;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
scop_detection::add_scop (sese_l s)
|
|
|
|
|
{
|
|
|
|
|
gcc_assert (s);
|
|
|
|
|
|
|
|
|
|
/* Do not add scops with only one loop. */
|
|
|
|
|
if (region_has_one_loop (s))
|
|
|
|
|
{
|
2016-01-21 03:13:05 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] Discarding one loop SCoP: ";
|
2015-10-05 18:02:59 +02:00
|
|
|
|
print_sese (dump_file, s));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 17:40:17 +02:00
|
|
|
|
if (get_exit_bb (s) == EXIT_BLOCK_PTR_FOR_FN (cfun))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] "
|
2016-01-21 03:13:05 +01:00
|
|
|
|
<< "Discarding SCoP exiting to return: ";
|
2015-10-05 18:02:59 +02:00
|
|
|
|
print_sese (dump_file, s));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remove all the scops which are subsumed by s. */
|
|
|
|
|
remove_subscops (s);
|
|
|
|
|
|
2015-12-24 17:41:46 +01:00
|
|
|
|
/* Remove intersecting scops. FIXME: It will be a good idea to keep
|
|
|
|
|
the non-intersecting part of the scop already in the list. */
|
2015-10-05 18:02:59 +02:00
|
|
|
|
remove_intersecting_scops (s);
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
scops.safe_push (s);
|
2016-01-21 03:13:05 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection] Adding SCoP: "; print_sese (dump_file, s));
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Return true when a statement in SCOP cannot be represented by Graphite.
|
|
|
|
|
The assumptions are that L1 dominates L2, and SCOP->entry dominates L1.
|
|
|
|
|
Limit the number of bbs between adjacent loops to
|
|
|
|
|
PARAM_SCOP_MAX_NUM_BBS_BETWEEN_LOOPS. */
|
|
|
|
|
|
|
|
|
|
bool
|
2016-01-21 03:13:05 +01:00
|
|
|
|
scop_detection::harmful_loop_in_region (sese_l scop) const
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
2015-10-07 17:40:17 +02:00
|
|
|
|
basic_block exit_bb = get_exit_bb (scop);
|
|
|
|
|
basic_block entry_bb = get_entry_bb (scop);
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "[checking-harmful-bbs] ";
|
2015-10-05 18:02:59 +02:00
|
|
|
|
print_sese (dump_file, scop));
|
|
|
|
|
gcc_assert (dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb));
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2017-02-09 08:47:07 +01:00
|
|
|
|
auto_vec<basic_block> worklist;
|
|
|
|
|
auto_bitmap loops;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2017-02-09 08:47:07 +01:00
|
|
|
|
worklist.safe_push (entry_bb);
|
|
|
|
|
while (! worklist.is_empty ())
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2017-02-09 08:47:07 +01:00
|
|
|
|
basic_block bb = worklist.pop ();
|
2015-11-20 00:06:18 +01:00
|
|
|
|
DEBUG_PRINT (dp << "Visiting bb_" << bb->index << "\n");
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-11-06 21:43:40 +01:00
|
|
|
|
/* The basic block should not be part of an irreducible loop. */
|
|
|
|
|
if (bb->flags & BB_IRREDUCIBLE_LOOP)
|
2017-02-09 08:47:07 +01:00
|
|
|
|
return true;
|
2015-11-06 21:43:40 +01:00
|
|
|
|
|
2016-01-21 03:13:42 +01:00
|
|
|
|
/* Check for unstructured control flow: CFG not generated by structured
|
|
|
|
|
if-then-else. */
|
|
|
|
|
if (bb->succs->length () > 1)
|
|
|
|
|
{
|
|
|
|
|
edge e;
|
|
|
|
|
edge_iterator ei;
|
|
|
|
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
|
|
|
|
if (!dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest)
|
|
|
|
|
&& !dominated_by_p (CDI_DOMINATORS, e->dest, bb))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-21 03:13:05 +01:00
|
|
|
|
/* Collect all loops in the current region. */
|
|
|
|
|
loop_p loop = bb->loop_father;
|
|
|
|
|
if (loop_in_sese_p (loop, scop))
|
|
|
|
|
bitmap_set_bit (loops, loop->num);
|
|
|
|
|
else
|
2015-11-13 13:28:54 +01:00
|
|
|
|
{
|
2016-01-21 03:13:05 +01:00
|
|
|
|
/* We only check for harmful statements in basic blocks not part of
|
|
|
|
|
any loop fully contained in the scop: other bbs are checked below
|
|
|
|
|
in loop_is_valid_in_scop. */
|
|
|
|
|
if (harmful_stmt_in_bb (scop, bb))
|
2017-02-09 08:47:07 +01:00
|
|
|
|
return true;
|
2016-01-21 03:13:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-09 08:47:07 +01:00
|
|
|
|
if (bb != exit_bb)
|
|
|
|
|
for (basic_block dom = first_dom_son (CDI_DOMINATORS, bb);
|
|
|
|
|
dom;
|
|
|
|
|
dom = next_dom_son (CDI_DOMINATORS, dom))
|
|
|
|
|
worklist.safe_push (dom);
|
2016-01-21 03:13:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Go through all loops and check that they are still valid in the combined
|
|
|
|
|
scop. */
|
|
|
|
|
unsigned j;
|
|
|
|
|
bitmap_iterator bi;
|
|
|
|
|
EXECUTE_IF_SET_IN_BITMAP (loops, 0, j, bi)
|
|
|
|
|
{
|
|
|
|
|
loop_p loop = (*current_loops->larray)[j];
|
|
|
|
|
gcc_assert (loop->num == (int) j);
|
|
|
|
|
|
|
|
|
|
if (!loop_is_valid_in_scop (loop, scop))
|
2017-02-09 08:47:07 +01:00
|
|
|
|
return true;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-13 13:28:54 +01:00
|
|
|
|
return false;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns true if S1 subsumes/surrounds S2. */
|
|
|
|
|
bool
|
|
|
|
|
scop_detection::subsumes (sese_l s1, sese_l s2)
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
2015-10-07 17:40:17 +02:00
|
|
|
|
if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
|
|
|
|
|
get_entry_bb (s1))
|
|
|
|
|
&& dominated_by_p (CDI_POST_DOMINATORS, s2.exit->dest,
|
|
|
|
|
s1.exit->dest))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Remove a SCoP which is subsumed by S1. */
|
|
|
|
|
void
|
|
|
|
|
scop_detection::remove_subscops (sese_l s1)
|
|
|
|
|
{
|
|
|
|
|
int j;
|
2015-10-21 20:53:17 +02:00
|
|
|
|
sese_l *s2;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
FOR_EACH_VEC_ELT_REVERSE (scops, j, s2)
|
|
|
|
|
{
|
2015-10-21 20:53:17 +02:00
|
|
|
|
if (subsumes (s1, *s2))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "Removing sub-SCoP";
|
2015-10-21 20:53:17 +02:00
|
|
|
|
print_sese (dump_file, *s2));
|
2015-10-05 18:02:59 +02:00
|
|
|
|
scops.unordered_remove (j);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Returns true if S1 intersects with S2. Since we already know that S1 does
|
|
|
|
|
not subsume S2 or vice-versa, we only check for entry bbs. */
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
scop_detection::intersects (sese_l s1, sese_l s2)
|
|
|
|
|
{
|
2015-10-07 17:40:17 +02:00
|
|
|
|
if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
|
|
|
|
|
get_entry_bb (s1))
|
|
|
|
|
&& !dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
|
|
|
|
|
get_exit_bb (s1)))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return true;
|
|
|
|
|
if ((s1.exit == s2.entry) || (s2.exit == s1.entry))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Remove one of the scops when it intersects with any other. */
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
void
|
|
|
|
|
scop_detection::remove_intersecting_scops (sese_l s1)
|
|
|
|
|
{
|
|
|
|
|
int j;
|
2015-10-21 20:53:17 +02:00
|
|
|
|
sese_l *s2;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
FOR_EACH_VEC_ELT_REVERSE (scops, j, s2)
|
|
|
|
|
{
|
2015-10-21 20:53:17 +02:00
|
|
|
|
if (intersects (s1, *s2))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-11-30 21:29:15 +01:00
|
|
|
|
DEBUG_PRINT (dp << "Removing intersecting SCoP";
|
|
|
|
|
print_sese (dump_file, *s2);
|
|
|
|
|
dp << "Intersects with:";
|
2015-10-05 18:02:59 +02:00
|
|
|
|
print_sese (dump_file, s1));
|
|
|
|
|
scops.unordered_remove (j);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2009-07-31 04:43:11 +02:00
|
|
|
|
/* Something like "n * m" is not allowed. */
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::graphite_can_represent_init (tree e)
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
|
|
|
|
switch (TREE_CODE (e))
|
|
|
|
|
{
|
|
|
|
|
case POLYNOMIAL_CHREC:
|
|
|
|
|
return graphite_can_represent_init (CHREC_LEFT (e))
|
|
|
|
|
&& graphite_can_represent_init (CHREC_RIGHT (e));
|
|
|
|
|
|
|
|
|
|
case MULT_EXPR:
|
|
|
|
|
if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
|
2009-12-09 16:18:22 +01:00
|
|
|
|
return graphite_can_represent_init (TREE_OPERAND (e, 0))
|
cuintp.c: Replace host_integerp (..., 0) with tree_fits_shwi_p throughout.
gcc/ada/
* gcc-interface/cuintp.c: Replace host_integerp (..., 0) with
tree_fits_shwi_p throughout.
gcc/c-family/
* c-ada-spec.c, c-common.c, c-format.c, c-pretty-print.c: Replace
host_integerp (..., 0) with tree_fits_shwi_p throughout.
gcc/c/
* c-parser.c: Replace host_integerp (..., 0) with tree_fits_shwi_p
throughout.
gcc/cp/
* error.c, init.c, parser.c, semantics.c: Replace
host_integerp (..., 0) with tree_fits_shwi_p throughout.
gcc/go/
* gofrontend/expressions.cc: Replace host_integerp (..., 0) with
tree_fits_shwi_p throughout.
gcc/java/
* class.c, expr.c: Replace host_integerp (..., 0) with
tree_fits_shwi_p throughout.
gcc/
* builtins.c, config/alpha/alpha.c, config/c6x/predicates.md,
config/ia64/predicates.md, config/iq2000/iq2000.c, config/mips/mips.c,
config/s390/s390.c, dbxout.c, dwarf2out.c, except.c, explow.c, expr.c,
expr.h, fold-const.c, gimple-fold.c, gimple-ssa-strength-reduction.c,
gimple.c, godump.c, graphite-scop-detection.c, graphite-sese-to-poly.c,
omp-low.c, predict.c, rtlanal.c, sdbout.c, simplify-rtx.c,
stor-layout.c, tree-data-ref.c, tree-dfa.c, tree-pretty-print.c,
tree-sra.c, tree-ssa-alias.c, tree-ssa-forwprop.c,
tree-ssa-loop-ivopts.c, tree-ssa-loop-prefetch.c, tree-ssa-math-opts.c,
tree-ssa-phiopt.c, tree-ssa-reassoc.c, tree-ssa-sccvn.c,
tree-ssa-strlen.c, tree-ssa-structalias.c, tree-vect-data-refs.c,
tree-vect-patterns.c, tree-vectorizer.h, tree.c, var-tracking.c,
varasm.c: Replace host_integerp (..., 0) with tree_fits_shwi_p
throughout.
From-SVN: r204955
2013-11-18 15:51:10 +01:00
|
|
|
|
&& tree_fits_shwi_p (TREE_OPERAND (e, 1));
|
2009-07-31 04:43:11 +02:00
|
|
|
|
else
|
2009-12-09 16:18:22 +01:00
|
|
|
|
return graphite_can_represent_init (TREE_OPERAND (e, 1))
|
cuintp.c: Replace host_integerp (..., 0) with tree_fits_shwi_p throughout.
gcc/ada/
* gcc-interface/cuintp.c: Replace host_integerp (..., 0) with
tree_fits_shwi_p throughout.
gcc/c-family/
* c-ada-spec.c, c-common.c, c-format.c, c-pretty-print.c: Replace
host_integerp (..., 0) with tree_fits_shwi_p throughout.
gcc/c/
* c-parser.c: Replace host_integerp (..., 0) with tree_fits_shwi_p
throughout.
gcc/cp/
* error.c, init.c, parser.c, semantics.c: Replace
host_integerp (..., 0) with tree_fits_shwi_p throughout.
gcc/go/
* gofrontend/expressions.cc: Replace host_integerp (..., 0) with
tree_fits_shwi_p throughout.
gcc/java/
* class.c, expr.c: Replace host_integerp (..., 0) with
tree_fits_shwi_p throughout.
gcc/
* builtins.c, config/alpha/alpha.c, config/c6x/predicates.md,
config/ia64/predicates.md, config/iq2000/iq2000.c, config/mips/mips.c,
config/s390/s390.c, dbxout.c, dwarf2out.c, except.c, explow.c, expr.c,
expr.h, fold-const.c, gimple-fold.c, gimple-ssa-strength-reduction.c,
gimple.c, godump.c, graphite-scop-detection.c, graphite-sese-to-poly.c,
omp-low.c, predict.c, rtlanal.c, sdbout.c, simplify-rtx.c,
stor-layout.c, tree-data-ref.c, tree-dfa.c, tree-pretty-print.c,
tree-sra.c, tree-ssa-alias.c, tree-ssa-forwprop.c,
tree-ssa-loop-ivopts.c, tree-ssa-loop-prefetch.c, tree-ssa-math-opts.c,
tree-ssa-phiopt.c, tree-ssa-reassoc.c, tree-ssa-sccvn.c,
tree-ssa-strlen.c, tree-ssa-structalias.c, tree-vect-data-refs.c,
tree-vect-patterns.c, tree-vectorizer.h, tree.c, var-tracking.c,
varasm.c: Replace host_integerp (..., 0) with tree_fits_shwi_p
throughout.
From-SVN: r204955
2013-11-18 15:51:10 +01:00
|
|
|
|
&& tree_fits_shwi_p (TREE_OPERAND (e, 0));
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
|
|
|
|
case PLUS_EXPR:
|
|
|
|
|
case POINTER_PLUS_EXPR:
|
|
|
|
|
case MINUS_EXPR:
|
|
|
|
|
return graphite_can_represent_init (TREE_OPERAND (e, 0))
|
|
|
|
|
&& graphite_can_represent_init (TREE_OPERAND (e, 1));
|
|
|
|
|
|
|
|
|
|
case NEGATE_EXPR:
|
|
|
|
|
case BIT_NOT_EXPR:
|
|
|
|
|
CASE_CONVERT:
|
|
|
|
|
case NON_LVALUE_EXPR:
|
|
|
|
|
return graphite_can_represent_init (TREE_OPERAND (e, 0));
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
default:
|
|
|
|
|
break;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return true when SCEV can be represented in the polyhedral model.
|
|
|
|
|
|
|
|
|
|
An expression can be represented, if it can be expressed as an
|
|
|
|
|
affine expression. For loops (i, j) and parameters (m, n) all
|
|
|
|
|
affine expressions are of the form:
|
|
|
|
|
|
|
|
|
|
x1 * i + x2 * j + x3 * m + x4 * n + x5 * 1 where x1..x5 element of Z
|
|
|
|
|
|
|
|
|
|
1 i + 20 j + (-2) m + 25
|
|
|
|
|
|
2010-09-30 23:18:09 +02:00
|
|
|
|
Something like "i * n" or "n * m" is not allowed. */
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::graphite_can_represent_scev (tree scev)
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
|
|
|
|
if (chrec_contains_undetermined (scev))
|
|
|
|
|
return false;
|
|
|
|
|
|
2014-08-14 16:53:59 +02:00
|
|
|
|
/* We disable the handling of pointer types, because it’s currently not
|
2015-12-17 19:50:05 +01:00
|
|
|
|
supported by Graphite with the isl AST generator. SSA_NAME nodes are
|
2014-08-14 16:53:59 +02:00
|
|
|
|
the only nodes, which are disabled in case they are pointers to object
|
|
|
|
|
types, but this can be changed. */
|
|
|
|
|
|
2015-04-14 14:33:57 +02:00
|
|
|
|
if (POINTER_TYPE_P (TREE_TYPE (scev)) && TREE_CODE (scev) == SSA_NAME)
|
2014-08-14 16:53:59 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
2009-12-23 08:50:00 +01:00
|
|
|
|
switch (TREE_CODE (scev))
|
|
|
|
|
{
|
2014-04-14 10:09:06 +02:00
|
|
|
|
case NEGATE_EXPR:
|
|
|
|
|
case BIT_NOT_EXPR:
|
|
|
|
|
CASE_CONVERT:
|
|
|
|
|
case NON_LVALUE_EXPR:
|
|
|
|
|
return graphite_can_represent_scev (TREE_OPERAND (scev, 0));
|
|
|
|
|
|
2009-12-23 08:50:00 +01:00
|
|
|
|
case PLUS_EXPR:
|
2014-04-14 10:09:06 +02:00
|
|
|
|
case POINTER_PLUS_EXPR:
|
2009-12-23 08:50:00 +01:00
|
|
|
|
case MINUS_EXPR:
|
2010-09-30 23:18:09 +02:00
|
|
|
|
return graphite_can_represent_scev (TREE_OPERAND (scev, 0))
|
|
|
|
|
&& graphite_can_represent_scev (TREE_OPERAND (scev, 1));
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2009-12-23 08:50:00 +01:00
|
|
|
|
case MULT_EXPR:
|
|
|
|
|
return !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 0)))
|
|
|
|
|
&& !CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (scev, 1)))
|
|
|
|
|
&& !(chrec_contains_symbols (TREE_OPERAND (scev, 0))
|
|
|
|
|
&& chrec_contains_symbols (TREE_OPERAND (scev, 1)))
|
2010-02-11 20:42:51 +01:00
|
|
|
|
&& graphite_can_represent_init (scev)
|
2010-09-30 23:18:09 +02:00
|
|
|
|
&& graphite_can_represent_scev (TREE_OPERAND (scev, 0))
|
|
|
|
|
&& graphite_can_represent_scev (TREE_OPERAND (scev, 1));
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2009-12-23 08:50:00 +01:00
|
|
|
|
case POLYNOMIAL_CHREC:
|
|
|
|
|
/* Check for constant strides. With a non constant stride of
|
|
|
|
|
'n' we would have a value of 'iv * n'. Also check that the
|
|
|
|
|
initial value can represented: for example 'n * m' cannot be
|
|
|
|
|
represented. */
|
|
|
|
|
if (!evolution_function_right_is_integer_cst (scev)
|
|
|
|
|
|| !graphite_can_represent_init (scev))
|
|
|
|
|
return false;
|
2014-04-14 10:09:06 +02:00
|
|
|
|
return graphite_can_represent_scev (CHREC_LEFT (scev));
|
2009-12-23 08:50:00 +01:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
|
|
|
|
/* Only affine functions can be represented. */
|
2015-10-05 18:02:59 +02:00
|
|
|
|
if (tree_contains_chrecs (scev, NULL) || !scev_is_linear_expression (scev))
|
2009-07-31 04:43:11 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
2010-09-30 23:17:26 +02:00
|
|
|
|
return true;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return true when EXPR can be represented in the polyhedral model.
|
|
|
|
|
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
This means an expression can be represented, if it is linear with respect to
|
|
|
|
|
the loops and the strides are non parametric. LOOP is the place where the
|
|
|
|
|
expr will be evaluated. SCOP defines the region we analyse. */
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
|
|
|
|
|
tree expr)
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
2015-10-07 17:40:17 +02:00
|
|
|
|
tree scev = scalar_evolution_in_region (scop, loop, expr);
|
2010-09-30 23:18:09 +02:00
|
|
|
|
return graphite_can_represent_scev (scev);
|
2009-07-31 04:43:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
/* Return true if the data references of STMT can be represented by Graphite.
|
|
|
|
|
We try to analyze the data references in a loop contained in the SCOP. */
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::stmt_has_simple_data_refs_p (sese_l scop, gimple *stmt)
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
2015-10-07 17:40:17 +02:00
|
|
|
|
loop_p nest = outermost_loop_in_sese (scop, gimple_bb (stmt));
|
2015-10-01 17:17:58 +02:00
|
|
|
|
loop_p loop = loop_containing_stmt (stmt);
|
2012-11-20 22:21:30 +01:00
|
|
|
|
vec<data_reference_p> drs = vNULL;
|
2012-01-10 10:14:51 +01:00
|
|
|
|
|
2015-10-01 17:17:58 +02:00
|
|
|
|
graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
|
|
|
|
|
|
|
|
|
|
int j;
|
|
|
|
|
data_reference_p dr;
|
|
|
|
|
FOR_EACH_VEC_ELT (drs, j, dr)
|
2012-01-10 10:14:51 +01:00
|
|
|
|
{
|
2015-10-01 17:17:58 +02:00
|
|
|
|
int nb_subscripts = DR_NUM_DIMENSIONS (dr);
|
2015-10-02 00:04:07 +02:00
|
|
|
|
|
|
|
|
|
if (nb_subscripts < 1)
|
|
|
|
|
{
|
|
|
|
|
free_data_refs (drs);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-01 17:17:58 +02:00
|
|
|
|
tree ref = DR_REF (dr);
|
2012-01-10 10:14:51 +01:00
|
|
|
|
|
2015-10-01 17:17:58 +02:00
|
|
|
|
for (int i = nb_subscripts - 1; i >= 0; i--)
|
2015-07-17 18:34:21 +02:00
|
|
|
|
{
|
2015-10-01 17:17:58 +02:00
|
|
|
|
if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|| (TREE_CODE (ref) != ARRAY_REF && TREE_CODE (ref) != MEM_REF
|
2015-10-01 17:17:58 +02:00
|
|
|
|
&& TREE_CODE (ref) != COMPONENT_REF))
|
2012-01-10 10:14:51 +01:00
|
|
|
|
{
|
2015-10-01 17:17:58 +02:00
|
|
|
|
free_data_refs (drs);
|
|
|
|
|
return false;
|
2012-01-10 10:14:51 +01:00
|
|
|
|
}
|
|
|
|
|
|
2015-10-01 17:17:58 +02:00
|
|
|
|
ref = TREE_OPERAND (ref, 0);
|
|
|
|
|
}
|
2012-01-10 10:14:51 +01:00
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
free_data_refs (drs);
|
|
|
|
|
return true;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-10-02 17:28:23 +02:00
|
|
|
|
/* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
|
|
|
|
|
Calls have side-effects, except those to const or pure
|
|
|
|
|
functions. */
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
|
|
|
|
static bool
|
2015-10-02 17:28:23 +02:00
|
|
|
|
stmt_has_side_effects (gimple *stmt)
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
|
|
|
|
if (gimple_has_volatile_ops (stmt)
|
|
|
|
|
|| (gimple_code (stmt) == GIMPLE_CALL
|
|
|
|
|
&& !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
|
|
|
|
|
|| (gimple_code (stmt) == GIMPLE_ASM))
|
2015-07-25 11:22:29 +02:00
|
|
|
|
{
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] "
|
2015-10-02 17:28:23 +02:00
|
|
|
|
<< "Statement has side-effects:\n";
|
2015-10-05 18:02:59 +02:00
|
|
|
|
print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS));
|
2015-10-02 17:28:23 +02:00
|
|
|
|
return true;
|
2015-07-25 11:22:29 +02:00
|
|
|
|
}
|
2015-10-02 17:28:23 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-02 17:28:23 +02:00
|
|
|
|
/* Returns true if STMT can be represented in polyhedral model. LABEL,
|
|
|
|
|
simple COND stmts, pure calls, and assignments can be repesented. */
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::graphite_can_represent_stmt (sese_l scop, gimple *stmt,
|
|
|
|
|
basic_block bb)
|
2015-10-02 17:28:23 +02:00
|
|
|
|
{
|
|
|
|
|
loop_p loop = bb->loop_father;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
switch (gimple_code (stmt))
|
|
|
|
|
{
|
|
|
|
|
case GIMPLE_LABEL:
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
case GIMPLE_COND:
|
|
|
|
|
{
|
|
|
|
|
/* We can handle all binary comparisons. Inequalities are
|
|
|
|
|
also supported as they can be represented with union of
|
|
|
|
|
polyhedra. */
|
2015-10-02 17:28:23 +02:00
|
|
|
|
enum tree_code code = gimple_cond_code (stmt);
|
|
|
|
|
if (!(code == LT_EXPR
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|| code == GT_EXPR
|
|
|
|
|
|| code == LE_EXPR
|
|
|
|
|
|| code == GE_EXPR
|
|
|
|
|
|| code == EQ_EXPR
|
|
|
|
|
|| code == NE_EXPR))
|
2015-10-02 17:28:23 +02:00
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] "
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
<< "Graphite cannot handle cond stmt:\n";
|
2015-10-05 18:02:59 +02:00
|
|
|
|
print_gimple_stmt (dump_file, stmt, 0,
|
|
|
|
|
TDF_VOPS | TDF_MEMSYMS));
|
2015-07-25 11:22:29 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2014-04-03 15:43:23 +02:00
|
|
|
|
for (unsigned i = 0; i < 2; ++i)
|
|
|
|
|
{
|
|
|
|
|
tree op = gimple_op (stmt, i);
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
if (!graphite_can_represent_expr (scop, loop, op)
|
2015-08-24 22:50:12 +02:00
|
|
|
|
/* We can only constrain on integer type. */
|
|
|
|
|
|| (TREE_CODE (TREE_TYPE (op)) != INTEGER_TYPE))
|
2015-07-25 11:22:29 +02:00
|
|
|
|
{
|
2015-10-05 18:02:59 +02:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] "
|
|
|
|
|
<< "Graphite cannot represent stmt:\n";
|
|
|
|
|
print_gimple_stmt (dump_file, stmt, 0,
|
|
|
|
|
TDF_VOPS | TDF_MEMSYMS));
|
2015-07-25 11:22:29 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2014-04-03 15:43:23 +02:00
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case GIMPLE_ASSIGN:
|
|
|
|
|
case GIMPLE_CALL:
|
2010-01-08 17:07:18 +01:00
|
|
|
|
return true;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
/* These nodes cut a new scope. */
|
2015-10-05 18:02:59 +02:00
|
|
|
|
DEBUG_PRINT (
|
|
|
|
|
dp << "[scop-detection-fail] "
|
|
|
|
|
<< "Gimple stmt not handled in Graphite:\n";
|
|
|
|
|
print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS));
|
2009-07-31 04:43:11 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2015-10-02 17:28:23 +02:00
|
|
|
|
}
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-02 17:28:23 +02:00
|
|
|
|
/* Return true only when STMT is simple enough for being handled by Graphite.
|
|
|
|
|
This depends on SCOP, as the parameters are initialized relatively to
|
|
|
|
|
this basic block, the linear functions are initialized based on the outermost
|
|
|
|
|
loop containing STMT inside the SCOP. BB is the place where we try to
|
|
|
|
|
evaluate the STMT. */
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::stmt_simple_for_scop_p (sese_l scop, gimple *stmt,
|
|
|
|
|
basic_block bb) const
|
2015-10-02 17:28:23 +02:00
|
|
|
|
{
|
|
|
|
|
gcc_assert (scop);
|
|
|
|
|
|
|
|
|
|
if (is_gimple_debug (stmt))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (stmt_has_side_effects (stmt))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!stmt_has_simple_data_refs_p (scop, stmt))
|
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] "
|
|
|
|
|
<< "Graphite cannot handle data-refs in stmt:\n";
|
|
|
|
|
print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS|TDF_MEMSYMS););
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return graphite_can_represent_stmt (scop, stmt, bb);
|
2009-07-31 04:43:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
/* Return true when BB contains a harmful operation for a scop: that
|
2009-07-31 04:43:11 +02:00
|
|
|
|
can be a function call with side effects, the induction variables
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
are not linear with respect to SCOP, etc. The current open
|
|
|
|
|
scop should end before this statement. */
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::harmful_stmt_in_bb (sese_l scop, basic_block bb) const
|
2009-07-31 04:43:11 +02:00
|
|
|
|
{
|
|
|
|
|
gimple_stmt_iterator gsi;
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
|
|
|
|
if (!stmt_simple_for_scop_p (scop, gsi_stmt (gsi), bb))
|
|
|
|
|
return true;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return false;
|
2009-07-31 04:43:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
/* Return true when the body of LOOP has statements that can be represented as a
|
|
|
|
|
valid scop. */
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
bool
|
|
|
|
|
scop_detection::loop_body_is_valid_scop (loop_p loop, sese_l scop) const
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
{
|
2015-10-02 18:04:00 +02:00
|
|
|
|
if (!loop_ivs_can_be_represented (loop))
|
|
|
|
|
{
|
2015-10-05 18:02:59 +02:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] loop_" << loop->num
|
|
|
|
|
<< "IV cannot be represented.\n");
|
2015-10-02 18:04:00 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
if (!loop_nest_has_data_refs (loop))
|
|
|
|
|
{
|
2015-10-05 18:02:59 +02:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] loop_" << loop->num
|
|
|
|
|
<< "does not have any data reference.\n");
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
basic_block *bbs = get_loop_body (loop);
|
|
|
|
|
for (unsigned i = 0; i < loop->num_nodes; i++)
|
|
|
|
|
{
|
|
|
|
|
basic_block bb = bbs[i];
|
|
|
|
|
|
|
|
|
|
if (harmful_stmt_in_bb (scop, bb))
|
2016-01-21 03:13:24 +01:00
|
|
|
|
{
|
|
|
|
|
free (bbs);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
}
|
|
|
|
|
free (bbs);
|
2015-10-01 17:17:51 +02:00
|
|
|
|
|
|
|
|
|
if (loop->inner)
|
|
|
|
|
{
|
|
|
|
|
loop = loop->inner;
|
|
|
|
|
while (loop)
|
|
|
|
|
{
|
|
|
|
|
if (!loop_body_is_valid_scop (loop, scop))
|
|
|
|
|
return false;
|
|
|
|
|
loop = loop->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Returns the number of pbbs that are in loops contained in SCOP. */
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
int
|
|
|
|
|
scop_detection::nb_pbbs_in_loops (scop_p scop)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
poly_bb_p pbb;
|
|
|
|
|
int res = 0;
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-07 21:25:35 +02:00
|
|
|
|
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
|
2015-10-21 20:53:17 +02:00
|
|
|
|
if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), scop->scop_info->region))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
res++;
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return res;
|
|
|
|
|
}
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:03:09 +02:00
|
|
|
|
/* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
|
|
|
|
|
Otherwise returns -1. */
|
|
|
|
|
|
|
|
|
|
static inline int
|
2015-10-07 17:40:17 +02:00
|
|
|
|
parameter_index_in_region_1 (tree name, sese_info_p region)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
tree p;
|
|
|
|
|
|
|
|
|
|
gcc_assert (TREE_CODE (name) == SSA_NAME);
|
|
|
|
|
|
2015-11-12 01:37:47 +01:00
|
|
|
|
FOR_EACH_VEC_ELT (region->params, i, p)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
if (p == name)
|
|
|
|
|
return i;
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* When the parameter NAME is in REGION, returns its index in
|
|
|
|
|
SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
|
|
|
|
|
and returns the index of NAME. */
|
|
|
|
|
|
|
|
|
|
static int
|
2015-10-07 17:40:17 +02:00
|
|
|
|
parameter_index_in_region (tree name, sese_info_p region)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
gcc_assert (TREE_CODE (name) == SSA_NAME);
|
|
|
|
|
|
|
|
|
|
/* Cannot constrain on anything else than INTEGER_TYPE parameters. */
|
|
|
|
|
if (TREE_CODE (TREE_TYPE (name)) != INTEGER_TYPE)
|
|
|
|
|
return -1;
|
|
|
|
|
|
2015-10-21 23:18:27 +02:00
|
|
|
|
if (!invariant_in_sese_p_rec (name, region->region, NULL))
|
2015-10-05 18:03:09 +02:00
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
i = parameter_index_in_region_1 (name, region);
|
|
|
|
|
if (i != -1)
|
|
|
|
|
return i;
|
|
|
|
|
|
2015-11-12 01:37:47 +01:00
|
|
|
|
i = region->params.length ();
|
|
|
|
|
region->params.safe_push (name);
|
2015-10-05 18:03:09 +02:00
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* In the context of sese S, scan the expression E and translate it to
|
|
|
|
|
a linear expression C. When parsing a symbolic multiplication, K
|
|
|
|
|
represents the constant multiplier of an expression containing
|
|
|
|
|
parameters. */
|
|
|
|
|
|
|
|
|
|
static void
|
2015-10-07 17:40:17 +02:00
|
|
|
|
scan_tree_for_params (sese_info_p s, tree e)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
{
|
|
|
|
|
if (e == chrec_dont_know)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
switch (TREE_CODE (e))
|
|
|
|
|
{
|
|
|
|
|
case POLYNOMIAL_CHREC:
|
|
|
|
|
scan_tree_for_params (s, CHREC_LEFT (e));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case MULT_EXPR:
|
|
|
|
|
if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
|
|
|
|
|
scan_tree_for_params (s, TREE_OPERAND (e, 0));
|
|
|
|
|
else
|
|
|
|
|
scan_tree_for_params (s, TREE_OPERAND (e, 1));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PLUS_EXPR:
|
|
|
|
|
case POINTER_PLUS_EXPR:
|
|
|
|
|
case MINUS_EXPR:
|
|
|
|
|
scan_tree_for_params (s, TREE_OPERAND (e, 0));
|
|
|
|
|
scan_tree_for_params (s, TREE_OPERAND (e, 1));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NEGATE_EXPR:
|
|
|
|
|
case BIT_NOT_EXPR:
|
|
|
|
|
CASE_CONVERT:
|
|
|
|
|
case NON_LVALUE_EXPR:
|
|
|
|
|
scan_tree_for_params (s, TREE_OPERAND (e, 0));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SSA_NAME:
|
|
|
|
|
parameter_index_in_region (e, s);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case INTEGER_CST:
|
|
|
|
|
case ADDR_EXPR:
|
|
|
|
|
case REAL_CST:
|
|
|
|
|
case COMPLEX_CST:
|
|
|
|
|
case VECTOR_CST:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
gcc_unreachable ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find parameters with respect to REGION in BB. We are looking in memory
|
|
|
|
|
access functions, conditions and loop bounds. */
|
|
|
|
|
|
|
|
|
|
static void
|
2015-10-07 17:40:17 +02:00
|
|
|
|
find_params_in_bb (sese_info_p region, gimple_poly_bb_p gbb)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
{
|
2015-10-06 17:56:03 +02:00
|
|
|
|
/* Find parameters in the access functions of data references. */
|
2015-10-05 18:03:09 +02:00
|
|
|
|
int i;
|
|
|
|
|
data_reference_p dr;
|
|
|
|
|
FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
|
2015-10-06 17:56:03 +02:00
|
|
|
|
for (unsigned j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
|
|
|
|
|
|
|
|
|
|
/* Find parameters in conditional statements. */
|
2015-10-06 17:56:03 +02:00
|
|
|
|
gimple *stmt;
|
|
|
|
|
loop_p loop = GBB_BB (gbb)->loop_father;
|
2015-10-05 18:03:09 +02:00
|
|
|
|
FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
|
|
|
|
|
{
|
2015-10-07 17:40:17 +02:00
|
|
|
|
tree lhs = scalar_evolution_in_region (region->region, loop,
|
2015-10-05 18:03:09 +02:00
|
|
|
|
gimple_cond_lhs (stmt));
|
2015-10-07 17:40:17 +02:00
|
|
|
|
tree rhs = scalar_evolution_in_region (region->region, loop,
|
2015-10-05 18:03:09 +02:00
|
|
|
|
gimple_cond_rhs (stmt));
|
|
|
|
|
|
|
|
|
|
scan_tree_for_params (region, lhs);
|
|
|
|
|
scan_tree_for_params (region, rhs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Record the parameters used in the SCOP. A variable is a parameter
|
|
|
|
|
in a scop if it does not vary during the execution of that scop. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
find_scop_parameters (scop_p scop)
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
2015-10-21 20:53:17 +02:00
|
|
|
|
sese_info_p region = scop->scop_info;
|
2015-10-05 18:03:09 +02:00
|
|
|
|
struct loop *loop;
|
|
|
|
|
|
|
|
|
|
/* Find the parameters used in the loop bounds. */
|
2015-11-12 01:37:47 +01:00
|
|
|
|
FOR_EACH_VEC_ELT (region->loop_nest, i, loop)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
{
|
|
|
|
|
tree nb_iters = number_of_latch_executions (loop);
|
|
|
|
|
|
|
|
|
|
if (!chrec_contains_symbols (nb_iters))
|
|
|
|
|
continue;
|
|
|
|
|
|
2015-10-07 17:40:17 +02:00
|
|
|
|
nb_iters = scalar_evolution_in_region (region->region, loop, nb_iters);
|
2015-10-05 18:03:09 +02:00
|
|
|
|
scan_tree_for_params (region, nb_iters);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find the parameters used in data accesses. */
|
2015-10-06 17:56:03 +02:00
|
|
|
|
poly_bb_p pbb;
|
2015-10-07 21:25:35 +02:00
|
|
|
|
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
|
2015-10-05 18:03:09 +02:00
|
|
|
|
find_params_in_bb (region, PBB_BLACK_BOX (pbb));
|
|
|
|
|
|
2015-10-06 17:56:03 +02:00
|
|
|
|
int nbp = sese_nb_params (region);
|
2015-10-05 18:03:09 +02:00
|
|
|
|
scop_set_nb_params (scop, nbp);
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-12 01:37:47 +01:00
|
|
|
|
/* Record DEF if it is used in other bbs different than DEF_BB in the SCOP. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
build_cross_bb_scalars_def (scop_p scop, tree def, basic_block def_bb,
|
|
|
|
|
vec<tree> *writes)
|
|
|
|
|
{
|
2016-05-07 08:47:07 +02:00
|
|
|
|
if (!def || !is_gimple_reg (def))
|
2015-11-12 01:37:47 +01:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Do not gather scalar variables that can be analyzed by SCEV as they can be
|
|
|
|
|
generated out of the induction variables. */
|
|
|
|
|
if (scev_analyzable_p (def, scop->scop_info->region))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
gimple *use_stmt;
|
|
|
|
|
imm_use_iterator imm_iter;
|
|
|
|
|
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
|
|
|
|
|
if (def_bb != gimple_bb (use_stmt) && !is_gimple_debug (use_stmt))
|
|
|
|
|
{
|
|
|
|
|
writes->safe_push (def);
|
2015-12-16 18:24:25 +01:00
|
|
|
|
DEBUG_PRINT (dp << "Adding scalar write: ";
|
2015-11-12 01:37:47 +01:00
|
|
|
|
print_generic_expr (dump_file, def, 0);
|
2015-12-16 18:24:25 +01:00
|
|
|
|
dp << "\nFrom stmt: ";
|
2015-11-12 01:37:47 +01:00
|
|
|
|
print_gimple_stmt (dump_file,
|
|
|
|
|
SSA_NAME_DEF_STMT (def), 0, 0));
|
|
|
|
|
/* This is required by the FOR_EACH_IMM_USE_STMT when we want to break
|
|
|
|
|
before all the uses have been visited. */
|
|
|
|
|
BREAK_FROM_IMM_USE_STMT (imm_iter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Record DEF if it is used in other bbs different than DEF_BB in the SCOP. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
build_cross_bb_scalars_use (scop_p scop, tree use, gimple *use_stmt,
|
|
|
|
|
vec<scalar_use> *reads)
|
|
|
|
|
{
|
|
|
|
|
gcc_assert (use);
|
|
|
|
|
if (!is_gimple_reg (use))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Do not gather scalar variables that can be analyzed by SCEV as they can be
|
|
|
|
|
generated out of the induction variables. */
|
|
|
|
|
if (scev_analyzable_p (use, scop->scop_info->region))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
gimple *def_stmt = SSA_NAME_DEF_STMT (use);
|
|
|
|
|
if (gimple_bb (def_stmt) != gimple_bb (use_stmt))
|
|
|
|
|
{
|
2015-12-16 18:24:25 +01:00
|
|
|
|
DEBUG_PRINT (dp << "Adding scalar read: ";
|
2015-11-12 01:37:47 +01:00
|
|
|
|
print_generic_expr (dump_file, use, 0);
|
2015-12-16 18:24:25 +01:00
|
|
|
|
dp << "\nFrom stmt: ";
|
2015-11-12 01:37:47 +01:00
|
|
|
|
print_gimple_stmt (dump_file, use_stmt, 0, 0));
|
|
|
|
|
reads->safe_push (std::make_pair (use_stmt, use));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Record all scalar variables that are defined and used in different BBs of the
|
|
|
|
|
SCOP. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
graphite_find_cross_bb_scalar_vars (scop_p scop, gimple *stmt,
|
|
|
|
|
vec<scalar_use> *reads, vec<tree> *writes)
|
|
|
|
|
{
|
|
|
|
|
tree def;
|
|
|
|
|
|
|
|
|
|
if (gimple_code (stmt) == GIMPLE_ASSIGN)
|
|
|
|
|
def = gimple_assign_lhs (stmt);
|
|
|
|
|
else if (gimple_code (stmt) == GIMPLE_CALL)
|
|
|
|
|
def = gimple_call_lhs (stmt);
|
|
|
|
|
else if (gimple_code (stmt) == GIMPLE_PHI)
|
|
|
|
|
def = gimple_phi_result (stmt);
|
|
|
|
|
else
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
build_cross_bb_scalars_def (scop, def, gimple_bb (stmt), writes);
|
|
|
|
|
|
|
|
|
|
ssa_op_iter iter;
|
|
|
|
|
use_operand_p use_p;
|
|
|
|
|
FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
|
|
|
|
|
{
|
|
|
|
|
tree use = USE_FROM_PTR (use_p);
|
|
|
|
|
build_cross_bb_scalars_use (scop, use, stmt, reads);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-07 21:25:35 +02:00
|
|
|
|
/* Generates a polyhedral black box only if the bb contains interesting
|
|
|
|
|
information. */
|
|
|
|
|
|
|
|
|
|
static gimple_poly_bb_p
|
|
|
|
|
try_generate_gimple_bb (scop_p scop, basic_block bb)
|
|
|
|
|
{
|
2015-11-13 13:28:54 +01:00
|
|
|
|
vec<data_reference_p> drs = vNULL;
|
|
|
|
|
vec<tree> writes = vNULL;
|
|
|
|
|
vec<scalar_use> reads = vNULL;
|
2015-11-12 01:37:47 +01:00
|
|
|
|
|
2015-10-21 20:53:17 +02:00
|
|
|
|
sese_l region = scop->scop_info->region;
|
2015-10-07 21:25:35 +02:00
|
|
|
|
loop_p nest = outermost_loop_in_sese (region, bb);
|
|
|
|
|
|
|
|
|
|
loop_p loop = bb->loop_father;
|
|
|
|
|
if (!loop_in_sese_p (loop, region))
|
|
|
|
|
loop = nest;
|
|
|
|
|
|
2015-11-12 01:37:47 +01:00
|
|
|
|
for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
|
|
|
|
|
gsi_next (&gsi))
|
2015-10-07 21:25:35 +02:00
|
|
|
|
{
|
|
|
|
|
gimple *stmt = gsi_stmt (gsi);
|
|
|
|
|
if (is_gimple_debug (stmt))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
|
2015-11-12 01:37:47 +01:00
|
|
|
|
graphite_find_cross_bb_scalar_vars (scop, stmt, &reads, &writes);
|
2015-10-07 21:25:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-11-12 01:37:47 +01:00
|
|
|
|
for (gphi_iterator psi = gsi_start_phis (bb); !gsi_end_p (psi);
|
|
|
|
|
gsi_next (&psi))
|
|
|
|
|
if (!virtual_operand_p (gimple_phi_result (psi.phi ())))
|
|
|
|
|
graphite_find_cross_bb_scalar_vars (scop, psi.phi (), &reads, &writes);
|
|
|
|
|
|
|
|
|
|
if (drs.is_empty () && writes.is_empty () && reads.is_empty ())
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return new_gimple_poly_bb (bb, drs, reads, writes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute alias-sets for all data references in DRS. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
build_alias_set (scop_p scop)
|
|
|
|
|
{
|
|
|
|
|
int num_vertices = scop->drs.length ();
|
|
|
|
|
struct graph *g = new_graph (num_vertices);
|
|
|
|
|
dr_info *dr1, *dr2;
|
|
|
|
|
int i, j;
|
|
|
|
|
int *all_vertices;
|
|
|
|
|
|
|
|
|
|
FOR_EACH_VEC_ELT (scop->drs, i, dr1)
|
|
|
|
|
for (j = i+1; scop->drs.iterate (j, &dr2); j++)
|
|
|
|
|
if (dr_may_alias_p (dr1->dr, dr2->dr, true))
|
|
|
|
|
{
|
|
|
|
|
add_edge (g, i, j);
|
|
|
|
|
add_edge (g, j, i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
all_vertices = XNEWVEC (int, num_vertices);
|
|
|
|
|
for (i = 0; i < num_vertices; i++)
|
|
|
|
|
all_vertices[i] = i;
|
|
|
|
|
|
|
|
|
|
graphds_dfs (g, all_vertices, num_vertices, NULL, true, NULL);
|
|
|
|
|
free (all_vertices);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < g->n_vertices; i++)
|
|
|
|
|
scop->drs[i].alias_set = g->vertices[i].component + 1;
|
|
|
|
|
|
|
|
|
|
free_graph (g);
|
2015-10-07 21:25:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Gather BBs and conditions for a SCOP. */
|
|
|
|
|
class gather_bbs : public dom_walker
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
|
|
|
|
public:
|
2015-10-07 21:25:35 +02:00
|
|
|
|
gather_bbs (cdi_direction, scop_p);
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-12-10 18:14:07 +01:00
|
|
|
|
virtual edge before_dom_children (basic_block);
|
2015-10-05 18:02:59 +02:00
|
|
|
|
virtual void after_dom_children (basic_block);
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
private:
|
2015-10-07 21:25:35 +02:00
|
|
|
|
auto_vec<gimple *, 3> conditions, cases;
|
|
|
|
|
scop_p scop;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
};
|
|
|
|
|
}
|
2015-10-07 21:25:35 +02:00
|
|
|
|
gather_bbs::gather_bbs (cdi_direction direction, scop_p scop)
|
|
|
|
|
: dom_walker (direction), scop (scop)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
|
|
|
|
}
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2016-01-21 03:13:14 +01:00
|
|
|
|
/* Record in execution order the loops fully contained in the region. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
record_loop_in_sese (basic_block bb, sese_info_p region)
|
|
|
|
|
{
|
|
|
|
|
loop_p father = bb->loop_father;
|
|
|
|
|
if (loop_in_sese_p (father, region->region))
|
|
|
|
|
{
|
|
|
|
|
bool found = false;
|
|
|
|
|
loop_p loop0;
|
|
|
|
|
int j;
|
|
|
|
|
FOR_EACH_VEC_ELT (region->loop_nest, j, loop0)
|
|
|
|
|
if (father == loop0)
|
|
|
|
|
{
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!found)
|
|
|
|
|
region->loop_nest.safe_push (father);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Call-back for dom_walk executed before visiting the dominated
|
|
|
|
|
blocks. */
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-12-10 18:14:07 +01:00
|
|
|
|
edge
|
2015-10-07 21:25:35 +02:00
|
|
|
|
gather_bbs::before_dom_children (basic_block bb)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2016-01-21 03:13:14 +01:00
|
|
|
|
sese_info_p region = scop->scop_info;
|
|
|
|
|
if (!bb_in_sese_p (bb, region->region))
|
2015-12-10 18:14:07 +01:00
|
|
|
|
return NULL;
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2016-01-21 03:13:14 +01:00
|
|
|
|
record_loop_in_sese (bb, region);
|
|
|
|
|
|
2015-10-07 21:25:35 +02:00
|
|
|
|
gcond *stmt = single_pred_cond_non_loop_exit (bb);
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
if (stmt)
|
|
|
|
|
{
|
|
|
|
|
edge e = single_pred_edge (bb);
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-07 21:25:35 +02:00
|
|
|
|
conditions.safe_push (stmt);
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
if (e->flags & EDGE_TRUE_VALUE)
|
2015-10-07 21:25:35 +02:00
|
|
|
|
cases.safe_push (stmt);
|
2015-10-05 18:02:59 +02:00
|
|
|
|
else
|
2015-10-07 21:25:35 +02:00
|
|
|
|
cases.safe_push (NULL);
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-21 20:53:17 +02:00
|
|
|
|
scop->scop_info->bbs.safe_push (bb);
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-07 21:25:35 +02:00
|
|
|
|
gimple_poly_bb_p gbb = try_generate_gimple_bb (scop, bb);
|
2015-11-12 01:37:47 +01:00
|
|
|
|
if (!gbb)
|
2015-12-10 18:14:07 +01:00
|
|
|
|
return NULL;
|
2015-11-12 01:37:47 +01:00
|
|
|
|
|
2015-10-07 21:25:35 +02:00
|
|
|
|
GBB_CONDITIONS (gbb) = conditions.copy ();
|
|
|
|
|
GBB_CONDITION_CASES (gbb) = cases.copy ();
|
|
|
|
|
|
|
|
|
|
poly_bb_p pbb = new_poly_bb (scop, gbb);
|
|
|
|
|
scop->pbbs.safe_push (pbb);
|
2015-11-12 01:37:47 +01:00
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
data_reference_p dr;
|
|
|
|
|
FOR_EACH_VEC_ELT (gbb->data_refs, i, dr)
|
2015-12-16 18:24:25 +01:00
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "Adding memory ";
|
|
|
|
|
if (dr->is_read)
|
|
|
|
|
dp << "read: ";
|
|
|
|
|
else
|
|
|
|
|
dp << "write: ";
|
|
|
|
|
print_generic_expr (dump_file, dr->ref, 0);
|
|
|
|
|
dp << "\nFrom stmt: ";
|
|
|
|
|
print_gimple_stmt (dump_file, dr->stmt, 0, 0));
|
|
|
|
|
|
|
|
|
|
scop->drs.safe_push (dr_info (dr, pbb));
|
|
|
|
|
}
|
2015-12-10 18:14:07 +01:00
|
|
|
|
|
|
|
|
|
return NULL;
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Call-back for dom_walk executed after visiting the dominated
|
|
|
|
|
blocks. */
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
void
|
2015-10-07 21:25:35 +02:00
|
|
|
|
gather_bbs::after_dom_children (basic_block bb)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-10-21 20:53:17 +02:00
|
|
|
|
if (!bb_in_sese_p (bb, scop->scop_info->region))
|
2015-10-05 18:02:59 +02:00
|
|
|
|
return;
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
if (single_pred_cond_non_loop_exit (bb))
|
|
|
|
|
{
|
2015-10-07 21:25:35 +02:00
|
|
|
|
conditions.pop ();
|
|
|
|
|
cases.pop ();
|
2015-10-05 18:02:59 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
|
|
|
|
|
/* Find Static Control Parts (SCoP) in the current function and pushes
|
|
|
|
|
them to SCOPS. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
build_scops (vec<scop_p> *scops)
|
|
|
|
|
{
|
|
|
|
|
if (dump_file)
|
|
|
|
|
dp.set_dump_file (dump_file);
|
|
|
|
|
|
|
|
|
|
canonicalize_loop_closed_ssa_form ();
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
scop_detection sb;
|
|
|
|
|
sb.build_scop_depth (scop_detection::invalid_sese, current_loops->tree_root);
|
2015-10-02 00:04:20 +02:00
|
|
|
|
|
|
|
|
|
/* Now create scops from the lightweight SESEs. */
|
|
|
|
|
vec<sese_l> scops_l = sb.get_scops ();
|
|
|
|
|
int i;
|
2015-10-21 20:53:17 +02:00
|
|
|
|
sese_l *s;
|
2015-10-02 00:04:20 +02:00
|
|
|
|
FOR_EACH_VEC_ELT (scops_l, i, s)
|
2015-10-05 18:02:59 +02:00
|
|
|
|
{
|
2015-10-21 20:53:17 +02:00
|
|
|
|
scop_p scop = new_scop (s->entry, s->exit);
|
2015-10-05 18:02:59 +02:00
|
|
|
|
|
2015-10-07 21:25:35 +02:00
|
|
|
|
/* Record all basic blocks and their conditions in REGION. */
|
|
|
|
|
gather_bbs (CDI_DOMINATORS, scop).walk (cfun->cfg->x_entry_block_ptr);
|
|
|
|
|
|
2015-11-12 01:37:47 +01:00
|
|
|
|
build_alias_set (scop);
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
/* Do not optimize a scop containing only PBBs that do not belong
|
|
|
|
|
to any loops. */
|
|
|
|
|
if (sb.nb_pbbs_in_loops (scop) == 0)
|
|
|
|
|
{
|
2015-10-05 18:03:09 +02:00
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] no data references.\n");
|
|
|
|
|
free_scop (scop);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-21 23:18:17 +02:00
|
|
|
|
unsigned max_arrays = PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP);
|
|
|
|
|
if (scop->drs.length () >= max_arrays)
|
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] too many data references: "
|
|
|
|
|
<< scop->drs.length ()
|
|
|
|
|
<< " is larger than --param graphite-max-arrays-per-scop="
|
|
|
|
|
<< max_arrays << ".\n");
|
|
|
|
|
free_scop (scop);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:03:09 +02:00
|
|
|
|
find_scop_parameters (scop);
|
|
|
|
|
graphite_dim_t max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
|
|
|
|
|
|
|
|
|
|
if (scop_nb_params (scop) > max_dim)
|
|
|
|
|
{
|
|
|
|
|
DEBUG_PRINT (dp << "[scop-detection-fail] too many parameters: "
|
2015-12-24 17:41:46 +01:00
|
|
|
|
<< scop_nb_params (scop)
|
|
|
|
|
<< " larger than --param graphite-max-nb-scop-params="
|
|
|
|
|
<< max_dim << ".\n");
|
2015-10-05 18:02:59 +02:00
|
|
|
|
free_scop (scop);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scops->safe_push (scop);
|
|
|
|
|
}
|
|
|
|
|
|
Redesign Graphite scop detection
Redesign Graphite scop detection for faster compiler time and detecting more SCoPs.
Existing algorithm for SCoP detection in graphite was based on dominator tree
where a tree (CFG) traversal was required for analyzing an SESE. The tree
traversal is linear in the number of basic blocks and SCoP detection is
(probably) linear in number of instructions. That algorithm utilized a generic
infrastructure of SESE which does not directly represent loops. With regards to
graphite framework, we are only interested in subtrees with loops. The new
algorithm is geared towards tree traversal on loop structure. The algorithm is
linear in number of loops which is faster than the previous algorithm.
Briefly, we start the traversal at a loop-nest and analyze it recursively for
validity. Once a valid loop is found we find a valid adjacent loop. If an
adjacent loop is found and is valid, we merge both loop nests otherwise we form
a SCoP from the previous loop nest, and resume the algorithm from the adjacent
loop nest. The data structure to represent an SESE is an ordered pair of edges
(entry, exit). The new algoritm can extend a SCoP in both the directions. With
this approach, the number of instructions to be analyzed for validity reduces to
a minimal set. We start by analyzing those statements which are inside a loop,
because validity of those statements is necessary for the validity of loop. The
statements outside the loop nest can be just excluded from the SESE if they are
not valid.
This patch depends on: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg02024.html
Passes (c,c++,fortran) regtest and bootstrap.
gcc/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* graphite-optimize-isl.c (optimize_isl):
* graphite-scop-detection.c (struct sese_l): New type.
(get_entry_bb): API for getting entry bb of SESE.
(get_exit_bb): API for getting exit bb of SESE.
(class debug_printer): New type. Simple printer in debug mode.
(trivially_empty_bb_p): New. Return true when BB is empty or
contains only debug instructions.
(graphite_can_represent_expr): Call scalar_evoution_in_region
instead of analyze_scalar_evolution. Pass in scop instead of only
the scop entry.
(stmt_has_simple_data_refs_p): Pass in scop instead of only the
scop entry.
(stmt_simple_for_scop_p): Same.
(harmful_stmt_in_bb): Same.
(graphite_can_represent_loop): Deleted.
(struct scopdet_info): Deleted.
(scopdet_basic_block_info): Deleted.
(build_scops_1): Deleted.
(bb_in_sd_region): Deleted.
(find_single_entry_edge): Deleted.
(find_single_exit_edge): Deleted.
(create_single_entry_edge): Deleted.
(sd_region_without_exit): Deleted.
(create_single_exit_edge): Deleted.
(unmark_exit_edges): Deleted.
(mark_exit_edges): Deleted.
(create_sese_edges): Deleted.
(build_graphite_scops): Deleted.
(canonicalize_loop_closed_ssa): Recompute all dominators at the
end.
(build_scops): Use the new scop_builder to build scops.
(dot_all_scops_1): Use the new pretty printer. Print loop father
as well.
(loop_body_is_valid_scop): New. Return true if loop body is a
valid scop.
(class scop_builder): New. Builds SCoPs for polyhedral
optimizatios.
(scop_builder): New. Constructor.
(static sese_l invalid_sese): sese_l with invalid edges.
(get_sese): Get an sese (from a loop) if possible, invalid_sese
otherwise.
(get_nearest_dom_with_single_entry): Get nearest dominator of a
basic_block with single entry. Return NULL if we get to the
beginning of a function.
(get_nearest_pdom_with_single_exit): Get nearest post-dominator of
a basic_block with single exit. Return NULL if we get to the
beginning of a function.
(print_sese): Pretty-print SESE.
(merge_sese): Merge two SESEs if possible and return the new SESE.
(build_scop_depth): Start building the SCoP within a loop nest.
(build_scop_breadth): Start building the SCoP at a single loop
depth. Merge adjacent SESEs if valid.
(can_represent_loop_1): Returns true if Graphite can represent
loop inside SCoP. Helper for can_represent_loop.
(can_represent_loop): Returns true if Graphite can represent LOOP
and all its nested loops in SCoP.
(loop_is_valid_scop): Returns true if LOOP and all its nests
constitute a valid SCoP.
(region_has_one_loop): Returns true of a region has only one loop.
(add_scop): Add SCoP to the list of valid scops. Removes an
already existing scop if it intersects with or subsumed by this
one.
(harmful_stmt_in_region): Returns true if SCoP has any statment
which cannot be represented by Graphite.
(subsumes): Returns true of SCoP S1 subsumes SCoP S2.
(remove_subscops): Remove any SCoP from the list of already found
SCoPs, if subsumed by S1.
(intersects): Return true if region bounded by SCoPs S1 and S2
intersect.
(remove_intersecting_scops): Remove any SCoP which intersects with
S1.
* graphite.c (print_graphite_scop_statistics):
(print_graphite_statistics): Print SCoP info while debugging.
(graphite_initialize): Early exit in case number of loops in a
function is less than PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION or
basic blocks are more than PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION.
(graphite_finalize):
* params.def: Add PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION.
* sese.h (sese_loop_depth): Remove unnecessary gcc_assert.
(recompute_all_dominators): Recalculate POST_DOMINATORS.
* tree-cfg.c (print_loops): Print the function name while printing
loops.
gcc/testsuite/ChangeLog:
2015-09-27 Aditya Kumar <hiraditya@msn.com>
Sebastian Pop <s.pop@samsung.com>
* gcc.dg/graphite/block-1.c: Modified to match the pattern.
* gcc.dg/graphite/block-3.c: Same.
* gcc.dg/graphite/block-4.c: Same.
* gcc.dg/graphite/block-5.c: Same.
* gcc.dg/graphite/block-6.c: Same.
* gcc.dg/graphite/block-7.c: Same.
* gcc.dg/graphite/block-8.c: Same.
* gcc.dg/graphite/block-pr47654.c: Same.
* gcc.dg/graphite/interchange-0.c: Same.
* gcc.dg/graphite/interchange-1.c: Same.
* gcc.dg/graphite/interchange-10.c: Same.
* gcc.dg/graphite/interchange-11.c: Same.
* gcc.dg/graphite/interchange-12.c: Same.
* gcc.dg/graphite/interchange-13.c: Same.
* gcc.dg/graphite/interchange-14.c: Same.
* gcc.dg/graphite/interchange-15.c: Same.
* gcc.dg/graphite/interchange-3.c: Same.
* gcc.dg/graphite/interchange-4.c: Same.
* gcc.dg/graphite/interchange-5.c: Same.
* gcc.dg/graphite/interchange-6.c: Same.
* gcc.dg/graphite/interchange-7.c: Same.
* gcc.dg/graphite/interchange-8.c: Same.
* gcc.dg/graphite/interchange-9.c: Same.
* gcc.dg/graphite/interchange-mvt.c: Same.
* gcc.dg/graphite/pr35356-1.c (foo): Same.
* gcc.dg/graphite/pr35356-3.c: Same.
* gcc.dg/graphite/pr37485.c: Same.
* gcc/testsuite/gcc.dg/graphite/run-id-pr67700-1.c: New test case.
* gcc.dg/graphite/scop-1.c (int toto): Modified to match the pattern.
* gcc.dg/graphite/scop-11.c: Same.
* gcc.dg/graphite/scop-5.c: Same.
* gcc.dg/graphite/uns-block-1.c: Same.
* gcc.dg/graphite/uns-interchange-9.c: Same.
* gfortran.dg/graphite/block-1.f90: Same.
* gfortran.dg/graphite/interchange-3.f90: Same.
* gfortran.dg/graphite/pr14741.f90: Same.
From-SVN: r228215
2015-09-28 19:30:09 +02:00
|
|
|
|
DEBUG_PRINT (dp << "number of SCoPs: " << (scops ? scops->length () : 0););
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:02:59 +02:00
|
|
|
|
#endif /* HAVE_isl */
|