aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/hw-doloop.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/hw-doloop.h')
-rw-r--r--gcc-4.9/gcc/hw-doloop.h155
1 files changed, 155 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/hw-doloop.h b/gcc-4.9/gcc/hw-doloop.h
new file mode 100644
index 000000000..9fc3c15e3
--- /dev/null
+++ b/gcc-4.9/gcc/hw-doloop.h
@@ -0,0 +1,155 @@
+/* Code to analyze doloop loops in order for targets to perform late
+ optimizations converting doloops to other forms of hardware loops.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
+
+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/>. */
+
+/* We need to keep a vector of loops */
+typedef struct hwloop_info_d *hwloop_info;
+
+/* Information about a loop we have found (or are in the process of
+ finding). */
+struct GTY (()) hwloop_info_d
+{
+ /* loop number, for dumps */
+ int loop_no;
+
+ /* Next loop in the graph. */
+ hwloop_info next;
+
+ /* Vector of blocks only within the loop, including those within
+ inner loops. */
+ vec<basic_block> blocks;
+
+ /* Same information in a bitmap. */
+ bitmap block_bitmap;
+
+ /* Vector of inner loops within this loop. Includes loops of every
+ nesting level. */
+ vec<hwloop_info> loops;
+
+ /* All edges that jump into the loop. */
+ vec<edge, va_gc> *incoming;
+
+ /* The ports currently using this infrastructure can typically
+ handle two cases: all incoming edges have the same destination
+ block, or all incoming edges have the same source block. These
+ two members are set to the common source or destination we found,
+ or NULL if different blocks were found. If both are NULL the
+ loop can't be optimized. */
+ basic_block incoming_src;
+ basic_block incoming_dest;
+
+ /* First block in the loop. This is the one branched to by the loop_end
+ insn. */
+ basic_block head;
+
+ /* Last block in the loop (the one with the loop_end insn). */
+ basic_block tail;
+
+ /* The successor block of the loop. This is the one the loop_end insn
+ falls into. */
+ basic_block successor;
+
+ /* The last instruction in the tail. */
+ rtx last_insn;
+
+ /* The loop_end insn. */
+ rtx loop_end;
+
+ /* The iteration register. */
+ rtx iter_reg;
+
+ /* The new label placed at the beginning of the loop. */
+ rtx start_label;
+
+ /* The new label placed at the end of the loop. */
+ rtx end_label;
+
+ /* The length of the loop. */
+ int length;
+
+ /* The nesting depth of the loop. Innermost loops are given a depth
+ of 1. Only successfully optimized doloops are counted; if an inner
+ loop was marked as bad, it does not increase the depth of its parent
+ loop.
+ This value is valid when the target's optimize function is called. */
+ int depth;
+
+ /* True if we can't optimize this loop. */
+ bool bad;
+
+ /* True if we have visited this loop during the optimization phase. */
+ bool visited;
+
+ /* The following values are collected before calling the target's optimize
+ function and are not valid earlier. */
+
+ /* Record information about control flow: whether the loop has calls
+ or asm statements, whether it has edges that jump out of the loop,
+ or edges that jump within the loop. */
+ bool has_call;
+ bool has_asm;
+ bool jumps_within;
+ bool jumps_outof;
+
+ /* True if there is an instruction other than the doloop_end which uses the
+ iteration register. */
+ bool iter_reg_used;
+ /* True if the iteration register lives past the doloop instruction. */
+ bool iter_reg_used_outside;
+
+ /* Hard registers set at any point in the loop, except for the loop counter
+ register's set in the doloop_end instruction. */
+ HARD_REG_SET regs_set_in_loop;
+};
+
+/* A set of hooks to be defined by a target that wants to use the reorg_loops
+ functionality.
+
+ reorg_loops is intended to handle cases where special hardware loop
+ setup instructions are required before the loop, for example to set
+ up loop counter registers that are not exposed to the register
+ allocator, or to inform the hardware about loop bounds.
+
+ reorg_loops performs analysis to discover loop_end patterns created
+ by the earlier loop-doloop pass, and sets up a hwloop_info
+ structure for each such insn it finds. It then tries to discover
+ the basic blocks containing the loop by tracking the lifetime of
+ the iteration register.
+
+ If a valid loop can't be found, the FAIL function is called;
+ otherwise the OPT function is called for each loop, visiting
+ innermost loops first and ascending. */
+struct hw_doloop_hooks
+{
+ /* Examine INSN. If it is a suitable doloop_end pattern, return the
+ iteration register, which should be a single hard register.
+ Otherwise, return NULL_RTX. */
+ rtx (*end_pattern_reg) (rtx insn);
+ /* Optimize LOOP. The target should perform any additional analysis
+ (e.g. checking that the loop isn't too long), and then perform
+ its transformations. Return true if successful, false if the
+ loop should be marked bad. If it returns false, the FAIL
+ function is called. */
+ bool (*opt) (hwloop_info loop);
+ /* Handle a loop that was marked bad for any reason. This could be
+ used to split the doloop_end pattern. */
+ void (*fail) (hwloop_info loop);
+};
+
+extern void reorg_loops (bool, struct hw_doloop_hooks *);