LCOV - code coverage report
Current view: top level - gcc - graphite-optimize-isl.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 98 99 99.0 %
Date: 2020-04-04 11:58:09 Functions: 4 4 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* A scheduling optimizer for Graphite
       2                 :            :    Copyright (C) 2012-2020 Free Software Foundation, Inc.
       3                 :            :    Contributed by Tobias Grosser <tobias@grosser.es>.
       4                 :            : 
       5                 :            : This file is part of GCC.
       6                 :            : 
       7                 :            : GCC is free software; you can redistribute it and/or modify
       8                 :            : it under the terms of the GNU General Public License as published by
       9                 :            : the Free Software Foundation; either version 3, or (at your option)
      10                 :            : any later version.
      11                 :            : 
      12                 :            : GCC is distributed in the hope that it will be useful,
      13                 :            : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            : GNU General Public License for more details.
      16                 :            : 
      17                 :            : You should have received a copy of the GNU General Public License
      18                 :            : along with GCC; see the file COPYING3.  If not see
      19                 :            : <http://www.gnu.org/licenses/>.  */
      20                 :            : 
      21                 :            : #define USES_ISL
      22                 :            : 
      23                 :            : #include "config.h"
      24                 :            : 
      25                 :            : #ifdef HAVE_isl
      26                 :            : 
      27                 :            : #include "system.h"
      28                 :            : #include "coretypes.h"
      29                 :            : #include "backend.h"
      30                 :            : #include "cfghooks.h"
      31                 :            : #include "tree.h"
      32                 :            : #include "gimple.h"
      33                 :            : #include "fold-const.h"
      34                 :            : #include "gimple-iterator.h"
      35                 :            : #include "tree-ssa-loop.h"
      36                 :            : #include "cfgloop.h"
      37                 :            : #include "tree-data-ref.h"
      38                 :            : #include "dumpfile.h"
      39                 :            : #include "tree-vectorizer.h"
      40                 :            : #include "graphite.h"
      41                 :            : 
      42                 :            : 
      43                 :            : /* get_schedule_for_node_st - Improve schedule for the schedule node.
      44                 :            :    Only Simple loop tiling is considered.  */
      45                 :            : 
      46                 :            : static __isl_give isl_schedule_node *
      47                 :       1269 : get_schedule_for_node_st (__isl_take isl_schedule_node *node, void *user)
      48                 :            : {
      49                 :       1269 :   if (user)
      50                 :            :     return node;
      51                 :            : 
      52                 :       1269 :   if (isl_schedule_node_get_type (node) != isl_schedule_node_band
      53                 :       1269 :       || isl_schedule_node_n_children (node) != 1)
      54                 :       1016 :     return node;
      55                 :            : 
      56                 :        253 :   isl_space *space = isl_schedule_node_band_get_space (node);
      57                 :        253 :   unsigned dims = isl_space_dim (space, isl_dim_set);
      58                 :        253 :   isl_schedule_node *child = isl_schedule_node_get_child (node, 0);
      59                 :        253 :   isl_schedule_node_type type = isl_schedule_node_get_type (child);
      60                 :        253 :   isl_space_free (space);
      61                 :        253 :   isl_schedule_node_free (child);
      62                 :            : 
      63                 :        253 :   if (type != isl_schedule_node_leaf)
      64                 :            :     return node;
      65                 :            : 
      66                 :         88 :   long tile_size = param_loop_block_tile_size;
      67                 :         88 :   if (dims <= 1
      68                 :         88 :       || tile_size == 0
      69                 :         88 :       || !isl_schedule_node_band_get_permutable (node))
      70                 :            :     {
      71                 :         36 :       if (dump_file && dump_flags)
      72                 :          5 :         fprintf (dump_file, "not tiled\n");
      73                 :         36 :       return node;
      74                 :            :     }
      75                 :            : 
      76                 :            :   /* Tile loops.  */
      77                 :         52 :   space = isl_schedule_node_band_get_space (node);
      78                 :         52 :   isl_multi_val *sizes = isl_multi_val_zero (space);
      79                 :         52 :   isl_ctx *ctx = isl_schedule_node_get_ctx (node);
      80                 :            : 
      81                 :        162 :   for (unsigned i = 0; i < dims; i++)
      82                 :            :     {
      83                 :        110 :       sizes = isl_multi_val_set_val (sizes, i,
      84                 :            :                                      isl_val_int_from_si (ctx, tile_size));
      85                 :        110 :       if (dump_file && dump_flags)
      86                 :         53 :         fprintf (dump_file, "tiled by %ld\n", tile_size);
      87                 :            :     }
      88                 :            : 
      89                 :         52 :   node = isl_schedule_node_band_tile (node, sizes);
      90                 :         52 :   node = isl_schedule_node_child (node, 0);
      91                 :            : 
      92                 :         52 :   return node;
      93                 :            : }
      94                 :            : 
      95                 :            : static isl_union_set *
      96                 :        112 : scop_get_domains (scop_p scop)
      97                 :            : {
      98                 :        112 :   int i;
      99                 :        112 :   poly_bb_p pbb;
     100                 :        112 :   isl_space *space = isl_set_get_space (scop->param_context);
     101                 :        112 :   isl_union_set *res = isl_union_set_empty (space);
     102                 :            : 
     103                 :        475 :   FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
     104                 :        363 :     res = isl_union_set_add_set (res, isl_set_copy (pbb->domain));
     105                 :            : 
     106                 :        112 :   return res;
     107                 :            : }
     108                 :            : 
     109                 :            : /* Compute the schedule for SCOP based on its parameters, domain and set of
     110                 :            :    constraints.  Then apply the schedule to SCOP.  */
     111                 :            : 
     112                 :            : static bool
     113                 :        112 : optimize_isl (scop_p scop)
     114                 :            : {
     115                 :        112 :   int old_err = isl_options_get_on_error (scop->isl_context);
     116                 :        112 :   int old_max_operations = isl_ctx_get_max_operations (scop->isl_context);
     117                 :        112 :   int max_operations = param_max_isl_operations;
     118                 :        112 :   if (max_operations)
     119                 :        112 :     isl_ctx_set_max_operations (scop->isl_context, max_operations);
     120                 :        112 :   isl_options_set_on_error (scop->isl_context, ISL_ON_ERROR_CONTINUE);
     121                 :            : 
     122                 :        112 :   isl_union_set *domain = scop_get_domains (scop);
     123                 :            : 
     124                 :            :   /* Simplify the dependences on the domain.  */
     125                 :        112 :   scop_get_dependences (scop);
     126                 :        112 :   isl_union_map *dependences
     127                 :        112 :     = isl_union_map_gist_domain (isl_union_map_copy (scop->dependence),
     128                 :            :                                  isl_union_set_copy (domain));
     129                 :        112 :   isl_union_map *validity
     130                 :        112 :     = isl_union_map_gist_range (dependences, isl_union_set_copy (domain));
     131                 :            : 
     132                 :            :   /* FIXME: proximity should not be validity.  */
     133                 :        112 :   isl_union_map *proximity = isl_union_map_copy (validity);
     134                 :            : 
     135                 :        112 :   isl_schedule_constraints *sc = isl_schedule_constraints_on_domain (domain);
     136                 :        112 :   sc = isl_schedule_constraints_set_proximity (sc, proximity);
     137                 :        112 :   sc = isl_schedule_constraints_set_validity (sc, isl_union_map_copy (validity));
     138                 :        112 :   sc = isl_schedule_constraints_set_coincidence (sc, validity);
     139                 :            : 
     140                 :        112 :   isl_options_set_schedule_serialize_sccs (scop->isl_context, 0);
     141                 :        112 :   isl_options_set_schedule_maximize_band_depth (scop->isl_context, 1);
     142                 :        112 :   isl_options_set_schedule_max_constant_term (scop->isl_context, 20);
     143                 :        112 :   isl_options_set_schedule_max_coefficient (scop->isl_context, 20);
     144                 :        112 :   isl_options_set_tile_scale_tile_loops (scop->isl_context, 0);
     145                 :            :   /* Generate loop upper bounds that consist of the current loop iterator, an
     146                 :            :      operator (< or <=) and an expression not involving the iterator.  If this
     147                 :            :      option is not set, then the current loop iterator may appear several times
     148                 :            :      in the upper bound.  See the isl manual for more details.  */
     149                 :        112 :   isl_options_set_ast_build_atomic_upper_bound (scop->isl_context, 1);
     150                 :            : 
     151                 :        112 :   scop->transformed_schedule = isl_schedule_constraints_compute_schedule (sc);
     152                 :        224 :   scop->transformed_schedule =
     153                 :        112 :     isl_schedule_map_schedule_node_bottom_up (scop->transformed_schedule,
     154                 :            :                                               get_schedule_for_node_st, NULL);
     155                 :            : 
     156                 :        112 :   isl_options_set_on_error (scop->isl_context, old_err);
     157                 :        112 :   isl_ctx_reset_operations (scop->isl_context);
     158                 :        112 :   isl_ctx_set_max_operations (scop->isl_context, old_max_operations);
     159                 :        112 :   if (!scop->transformed_schedule
     160                 :        112 :       || isl_ctx_last_error (scop->isl_context) != isl_error_none)
     161                 :            :     {
     162                 :          1 :       if (dump_enabled_p ())
     163                 :            :         {
     164                 :          1 :           dump_user_location_t loc = find_loop_location
     165                 :          1 :             (scop->scop_info->region.entry->dest->loop_father);
     166                 :          1 :           if (isl_ctx_last_error (scop->isl_context) == isl_error_quota)
     167                 :          1 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
     168                 :            :                              "loop nest not optimized, optimization timed out "
     169                 :            :                              "after %d operations [--param max-isl-operations]\n",
     170                 :            :                              max_operations);
     171                 :            :           else
     172                 :          0 :             dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
     173                 :            :                              "loop nest not optimized, ISL signalled an error\n");
     174                 :            :         }
     175                 :          1 :       return false;
     176                 :            :     }
     177                 :            : 
     178                 :        111 :   gcc_assert (scop->original_schedule);
     179                 :        111 :   isl_union_map *original = isl_schedule_get_map (scop->original_schedule);
     180                 :        111 :   isl_union_map *transformed = isl_schedule_get_map (scop->transformed_schedule);
     181                 :        111 :   bool same_schedule = isl_union_map_is_equal (original, transformed);
     182                 :        111 :   isl_union_map_free (original);
     183                 :        111 :   isl_union_map_free (transformed);
     184                 :            : 
     185                 :        111 :   if (same_schedule)
     186                 :            :     {
     187                 :          7 :       if (dump_enabled_p ())
     188                 :            :         {
     189                 :          1 :           dump_user_location_t loc = find_loop_location
     190                 :          1 :             (scop->scop_info->region.entry->dest->loop_father);
     191                 :          1 :           dump_printf_loc (MSG_NOTE, loc,
     192                 :            :                            "loop nest not optimized, optimized schedule is "
     193                 :            :                            "identical to original schedule\n");
     194                 :            :         }
     195                 :          7 :       if (dump_file)
     196                 :          1 :         print_schedule_ast (dump_file, scop->original_schedule, scop);
     197                 :          7 :       isl_schedule_free (scop->transformed_schedule);
     198                 :          7 :       scop->transformed_schedule = isl_schedule_copy (scop->original_schedule);
     199                 :         14 :       return flag_graphite_identity || flag_loop_parallelize_all;
     200                 :            :     }
     201                 :            : 
     202                 :            :   return true;
     203                 :            : }
     204                 :            : 
     205                 :            : /* Apply graphite transformations to all the basic blocks of SCOP.  */
     206                 :            : 
     207                 :            : bool
     208                 :        176 : apply_poly_transforms (scop_p scop)
     209                 :            : {
     210                 :        176 :   if (flag_loop_nest_optimize)
     211                 :        112 :     return optimize_isl (scop);
     212                 :            : 
     213                 :         64 :   if (!flag_graphite_identity && !flag_loop_parallelize_all)
     214                 :            :     return false;
     215                 :            : 
     216                 :            :   /* Generate code even if we did not apply any real transformation.
     217                 :            :      This also allows to check the performance for the identity
     218                 :            :      transformation: GIMPLE -> GRAPHITE -> GIMPLE.  */
     219                 :         41 :   gcc_assert (scop->original_schedule);
     220                 :         41 :   scop->transformed_schedule = isl_schedule_copy (scop->original_schedule);
     221                 :         41 :   return true;
     222                 :            : }
     223                 :            : 
     224                 :            : #endif /* HAVE_isl */

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.