From 9d9c740d1efcd1bd597ef4734227996a8f69151d Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Thu, 7 Jul 2011 15:42:41 +0000 Subject: hw-doloop.c: New file. * hw-doloop.c: New file. * hw-doloop.h: New file. * Makefile.in (OBJS): Add hw-doloop.o. (hw-doloop.o): New rule. ($(obj_out_file)): Add hw-doloop.h dependency. * config/bfin/bfin.c: Include "hw-doloop.h". (loop_info, DEF_VEC_P for loop_info, loop_info_d): Remove. (bfin_dump_loops, bfin_bb_in_loop, bfin_scan_loop): Remove. (hwloop_optimize): Renamed from bfin_optimize_loop. Argument type changed to hwloop_info. Return bool, true if the loop was successfully optimized. Remove code that was moved to hw-doloop.c, and adjust other parts. (hwloop_fail): New static function, containing parts that used to be in bfin_optimize_loop. (bfin_discover_loop, bfin_discover_loops, free_loops, bfin_reorder_loops): Remove. (hwloop_pattern_reg): New static function. (bfin_doloop_hooks): New variable. (bfin_reorg_loops): Remove most code, call reorg_loops. * config/bfin/bfin.md (doloop_end splitter): Also enable if loop counter is a memory_operand. From-SVN: r175985 --- gcc/hw-doloop.h | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 gcc/hw-doloop.h (limited to 'gcc/hw-doloop.h') diff --git a/gcc/hw-doloop.h b/gcc/hw-doloop.h new file mode 100644 index 00000000000..006b67953b2 --- /dev/null +++ b/gcc/hw-doloop.h @@ -0,0 +1,157 @@ +/* Code to analyze doloop loops in order for targets to perform late + optimizations converting doloops to other forms of hardware loops. + Copyright (C) 2011 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 +. */ + +/* We need to keep a vector of loops */ +typedef struct hwloop_info_d *hwloop_info; +DEF_VEC_P (hwloop_info); +DEF_VEC_ALLOC_P (hwloop_info,heap); + +/* 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, heap) *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, heap) *loops; + + /* All edges that jump into the loop. */ + VEC(edge, 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 *); -- cgit v1.2.3