xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/hw-doloop.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Code to analyze doloop loops in order for targets to perform late
21debfc3dSmrg    optimizations converting doloops to other forms of hardware loops.
3*8feb0f0bSmrg    Copyright (C) 2011-2020 Free Software Foundation, Inc.
41debfc3dSmrg 
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg 
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg 
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg 
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3.  If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>.  */
201debfc3dSmrg 
211debfc3dSmrg #ifndef GCC_HW_DOLOOP_H
221debfc3dSmrg #define GCC_HW_DOLOOP_H
231debfc3dSmrg 
241debfc3dSmrg /* We need to keep a vector of loops */
251debfc3dSmrg typedef struct hwloop_info_d *hwloop_info;
261debfc3dSmrg 
271debfc3dSmrg /* Information about a loop we have found (or are in the process of
281debfc3dSmrg    finding).  */
291debfc3dSmrg struct GTY (()) hwloop_info_d
301debfc3dSmrg {
311debfc3dSmrg   /* loop number, for dumps */
321debfc3dSmrg   int loop_no;
331debfc3dSmrg 
341debfc3dSmrg   /* Next loop in the graph. */
351debfc3dSmrg   hwloop_info next;
361debfc3dSmrg 
371debfc3dSmrg   /* Vector of blocks only within the loop, including those within
381debfc3dSmrg      inner loops.  */
391debfc3dSmrg   vec<basic_block> blocks;
401debfc3dSmrg 
411debfc3dSmrg   /* Same information in a bitmap.  */
421debfc3dSmrg   bitmap block_bitmap;
431debfc3dSmrg 
441debfc3dSmrg   /* Vector of inner loops within this loop.  Includes loops of every
451debfc3dSmrg      nesting level.  */
461debfc3dSmrg   vec<hwloop_info> loops;
471debfc3dSmrg 
481debfc3dSmrg   /* All edges that jump into the loop.  */
491debfc3dSmrg   vec<edge, va_gc> *incoming;
501debfc3dSmrg 
511debfc3dSmrg   /* The ports currently using this infrastructure can typically
521debfc3dSmrg      handle two cases: all incoming edges have the same destination
531debfc3dSmrg      block, or all incoming edges have the same source block.  These
541debfc3dSmrg      two members are set to the common source or destination we found,
551debfc3dSmrg      or NULL if different blocks were found.  If both are NULL the
561debfc3dSmrg      loop can't be optimized.  */
571debfc3dSmrg   basic_block incoming_src;
581debfc3dSmrg   basic_block incoming_dest;
591debfc3dSmrg 
601debfc3dSmrg   /* First block in the loop.  This is the one branched to by the loop_end
611debfc3dSmrg      insn.  */
621debfc3dSmrg   basic_block head;
631debfc3dSmrg 
641debfc3dSmrg   /* Last block in the loop (the one with the loop_end insn).  */
651debfc3dSmrg   basic_block tail;
661debfc3dSmrg 
671debfc3dSmrg   /* The successor block of the loop.  This is the one the loop_end insn
681debfc3dSmrg      falls into.  */
691debfc3dSmrg   basic_block successor;
701debfc3dSmrg 
711debfc3dSmrg   /* The last instruction in the tail.  */
721debfc3dSmrg   rtx_insn *last_insn;
731debfc3dSmrg 
741debfc3dSmrg   /* The loop_end insn.  */
751debfc3dSmrg   rtx_insn *loop_end;
761debfc3dSmrg 
771debfc3dSmrg   /* The iteration register.  */
781debfc3dSmrg   rtx iter_reg;
791debfc3dSmrg 
801debfc3dSmrg   /* The new label placed at the beginning of the loop. */
811debfc3dSmrg   rtx_insn *start_label;
821debfc3dSmrg 
831debfc3dSmrg   /* The new label placed at the end of the loop. */
841debfc3dSmrg   rtx end_label;
851debfc3dSmrg 
861debfc3dSmrg   /* The length of the loop.  */
871debfc3dSmrg   int length;
881debfc3dSmrg 
891debfc3dSmrg   /* The nesting depth of the loop.  Innermost loops are given a depth
901debfc3dSmrg      of 1.  Only successfully optimized doloops are counted; if an inner
911debfc3dSmrg      loop was marked as bad, it does not increase the depth of its parent
921debfc3dSmrg      loop.
931debfc3dSmrg      This value is valid when the target's optimize function is called.  */
941debfc3dSmrg   int depth;
951debfc3dSmrg 
961debfc3dSmrg   /* True if we can't optimize this loop.  */
971debfc3dSmrg   bool bad;
981debfc3dSmrg 
991debfc3dSmrg   /* True if we have visited this loop during the optimization phase.  */
1001debfc3dSmrg   bool visited;
1011debfc3dSmrg 
1021debfc3dSmrg   /* The following values are collected before calling the target's optimize
1031debfc3dSmrg      function and are not valid earlier.  */
1041debfc3dSmrg 
1051debfc3dSmrg   /* Record information about control flow: whether the loop has calls
1061debfc3dSmrg      or asm statements, whether it has edges that jump out of the loop,
1071debfc3dSmrg      or edges that jump within the loop.  */
1081debfc3dSmrg   bool has_call;
1091debfc3dSmrg   bool has_asm;
1101debfc3dSmrg   bool jumps_within;
1111debfc3dSmrg   bool jumps_outof;
1121debfc3dSmrg 
1131debfc3dSmrg   /* True if there is an instruction other than the doloop_end which uses the
1141debfc3dSmrg      iteration register.  */
1151debfc3dSmrg   bool iter_reg_used;
1161debfc3dSmrg   /* True if the iteration register lives past the doloop instruction.  */
1171debfc3dSmrg   bool iter_reg_used_outside;
1181debfc3dSmrg 
1191debfc3dSmrg   /* Hard registers set at any point in the loop, except for the loop counter
1201debfc3dSmrg      register's set in the doloop_end instruction.  */
1211debfc3dSmrg   HARD_REG_SET regs_set_in_loop;
1221debfc3dSmrg };
1231debfc3dSmrg 
1241debfc3dSmrg /* A set of hooks to be defined by a target that wants to use the reorg_loops
1251debfc3dSmrg    functionality.
1261debfc3dSmrg 
1271debfc3dSmrg    reorg_loops is intended to handle cases where special hardware loop
1281debfc3dSmrg    setup instructions are required before the loop, for example to set
1291debfc3dSmrg    up loop counter registers that are not exposed to the register
1301debfc3dSmrg    allocator, or to inform the hardware about loop bounds.
1311debfc3dSmrg 
1321debfc3dSmrg    reorg_loops performs analysis to discover loop_end patterns created
1331debfc3dSmrg    by the earlier loop-doloop pass, and sets up a hwloop_info
1341debfc3dSmrg    structure for each such insn it finds.  It then tries to discover
1351debfc3dSmrg    the basic blocks containing the loop by tracking the lifetime of
1361debfc3dSmrg    the iteration register.
1371debfc3dSmrg 
1381debfc3dSmrg    If a valid loop can't be found, the FAIL function is called;
1391debfc3dSmrg    otherwise the OPT function is called for each loop, visiting
1401debfc3dSmrg    innermost loops first and ascending.  */
1411debfc3dSmrg struct hw_doloop_hooks
1421debfc3dSmrg {
1431debfc3dSmrg   /* Examine INSN.  If it is a suitable doloop_end pattern, return the
1441debfc3dSmrg      iteration register, which should be a single hard register.
1451debfc3dSmrg      Otherwise, return NULL_RTX.  */
1461debfc3dSmrg   rtx (*end_pattern_reg) (rtx_insn *insn);
1471debfc3dSmrg   /* Optimize LOOP.  The target should perform any additional analysis
1481debfc3dSmrg      (e.g. checking that the loop isn't too long), and then perform
1491debfc3dSmrg      its transformations.  Return true if successful, false if the
1501debfc3dSmrg      loop should be marked bad.  If it returns false, the FAIL
1511debfc3dSmrg      function is called.  */
1521debfc3dSmrg   bool (*opt) (hwloop_info loop);
1531debfc3dSmrg   /* Handle a loop that was marked bad for any reason.  This could be
1541debfc3dSmrg      used to split the doloop_end pattern.  */
1551debfc3dSmrg   void (*fail) (hwloop_info loop);
1561debfc3dSmrg };
1571debfc3dSmrg 
1581debfc3dSmrg extern void reorg_loops (bool, struct hw_doloop_hooks *);
1591debfc3dSmrg 
1601debfc3dSmrg #endif /* GCC_HW_DOLOOP_H */
161