tree-ssa-math-opts.c revision 169689
141120Sjdp/* Global, SSA-based optimizations using mathematical identities. 2103976Spst Copyright (C) 2005 Free Software Foundation, Inc. 341120Sjdp 441120SjdpThis file is part of GCC. 541120Sjdp 641120SjdpGCC is free software; you can redistribute it and/or modify it 741120Sjdpunder the terms of the GNU General Public License as published by the 841120SjdpFree Software Foundation; either version 2, or (at your option) any 941120Sjdplater version. 1041120Sjdp 1141120SjdpGCC is distributed in the hope that it will be useful, but WITHOUT 1241120SjdpANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1341120SjdpFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1441120Sjdpfor more details. 1541120Sjdp 1641120SjdpYou should have received a copy of the GNU General Public License 1741120Sjdpalong with GCC; see the file COPYING. If not, write to the Free 1841120SjdpSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 1941120Sjdp02110-1301, USA. */ 2041120Sjdp 2141120Sjdp/* Currently, the only mini-pass in this file tries to CSE reciprocal 2241120Sjdp operations. These are common in sequences such as this one: 2341120Sjdp 2441120Sjdp modulus = sqrt(x*x + y*y + z*z); 2541120Sjdp x = x / modulus; 2641120Sjdp y = y / modulus; 2784222Sdillon z = z / modulus; 2884222Sdillon 2984222Sdillon that can be optimized to 3041120Sjdp 3141120Sjdp modulus = sqrt(x*x + y*y + z*z); 3241120Sjdp rmodulus = 1.0 / modulus; 3341120Sjdp x = x * rmodulus; 3441120Sjdp y = y * rmodulus; 3541120Sjdp z = z * rmodulus; 3641120Sjdp 3741120Sjdp We do this for loop invariant divisors, and with this pass whenever 3841120Sjdp we notice that a division has the same divisor multiple times. 3941120Sjdp 4041120Sjdp Of course, like in PRE, we don't insert a division if a dominator 4141120Sjdp already has one. However, this cannot be done as an extension of 4241120Sjdp PRE for several reasons. 4341120Sjdp 4441120Sjdp First of all, with some experiments it was found out that the 4541120Sjdp transformation is not always useful if there are only two divisions 4641120Sjdp hy the same divisor. This is probably because modern processors 4741120Sjdp can pipeline the divisions; on older, in-order processors it should 4841120Sjdp still be effective to optimize two divisions by the same number. 4941120Sjdp We make this a param, and it shall be called N in the remainder of 5041120Sjdp this comment. 5141120Sjdp 5241120Sjdp Second, if trapping math is active, we have less freedom on where 5341120Sjdp to insert divisions: we can only do so in basic blocks that already 54103976Spst contain one. (If divisions don't trap, instead, we can insert 5541120Sjdp divisions elsewhere, which will be in blocks that are common dominators 5641120Sjdp of those that have the division). 5741120Sjdp 5841120Sjdp We really don't want to compute the reciprocal unless a division will 5941120Sjdp be found. To do this, we won't insert the division in a basic block 6041120Sjdp that has less than N divisions *post-dominating* it. 6141120Sjdp 6241120Sjdp The algorithm constructs a subset of the dominator tree, holding the 6341120Sjdp blocks containing the divisions and the common dominators to them, 6441120Sjdp and walk it twice. The first walk is in post-order, and it annotates 6541120Sjdp each block with the number of divisions that post-dominate it: this 66103976Spst gives information on where divisions can be inserted profitably. 67103976Spst The second walk is in pre-order, and it inserts divisions as explained 6841120Sjdp above, and replaces divisions by multiplications. 6941120Sjdp 7041120Sjdp In the best case, the cost of the pass is O(n_statements). In the 7141120Sjdp worst-case, the cost is due to creating the dominator tree subset, 7241120Sjdp with a cost of O(n_basic_blocks ^ 2); however this can only happen 7341120Sjdp for n_statements / n_basic_blocks statements. So, the amortized cost 7441120Sjdp of creating the dominator tree subset is O(n_basic_blocks) and the 7541120Sjdp worst-case cost of the pass is O(n_statements * n_basic_blocks). 7641120Sjdp 7741120Sjdp More practically, the cost will be small because there are few 7841120Sjdp divisions, and they tend to be in the same basic block, so insert_bb 79103976Spst is called very few times. 80103976Spst 8141120Sjdp If we did this using domwalk.c, an efficient implementation would have 8241120Sjdp to work on all the variables in a single pass, because we could not 8341120Sjdp work on just a subset of the dominator tree, as we do now, and the 8441120Sjdp cost would also be something like O(n_statements * n_basic_blocks). 8541120Sjdp The data structures would be more complex in order to work on all the 8641120Sjdp variables in a single pass. */ 8741120Sjdp 8841120Sjdp#include "config.h" 8941120Sjdp#include "system.h" 9041120Sjdp#include "coretypes.h" 9141120Sjdp#include "tm.h" 9241120Sjdp#include "flags.h" 9341120Sjdp#include "tree.h" 9441120Sjdp#include "tree-flow.h" 9541120Sjdp#include "real.h" 9641120Sjdp#include "timevar.h" 9741120Sjdp#include "tree-pass.h" 9841120Sjdp#include "alloc-pool.h" 9941120Sjdp#include "basic-block.h" 10041120Sjdp#include "target.h" 10141120Sjdp 10241120Sjdp 10341120Sjdp/* This structure represents one basic block that either computes a 10441120Sjdp division, or is a common dominator for basic block that compute a 10541120Sjdp division. */ 10641120Sjdpstruct occurrence { 10741120Sjdp /* The basic block represented by this structure. */ 10841120Sjdp basic_block bb; 10941120Sjdp 11041120Sjdp /* If non-NULL, the SSA_NAME holding the definition for a reciprocal 11141120Sjdp inserted in BB. */ 11241120Sjdp tree recip_def; 11341120Sjdp 11441120Sjdp /* If non-NULL, the MODIFY_EXPR for a reciprocal computation that 11541120Sjdp was inserted in BB. */ 11641120Sjdp tree recip_def_stmt; 11741120Sjdp 11841120Sjdp /* Pointer to a list of "struct occurrence"s for blocks dominated 11941120Sjdp by BB. */ 12041120Sjdp struct occurrence *children; 12141120Sjdp 12241120Sjdp /* Pointer to the next "struct occurrence"s in the list of blocks 12341120Sjdp sharing a common dominator. */ 12441120Sjdp struct occurrence *next; 12541120Sjdp 12641120Sjdp /* The number of divisions that are in BB before compute_merit. The 12741120Sjdp number of divisions that are in BB or post-dominate it after 12841120Sjdp compute_merit. */ 12941120Sjdp int num_divisions; 13041120Sjdp 13141120Sjdp /* True if the basic block has a division, false if it is a common 13241120Sjdp dominator for basic blocks that do. If it is false and trapping 13341120Sjdp math is active, BB is not a candidate for inserting a reciprocal. */ 13441120Sjdp bool bb_has_division; 13541120Sjdp}; 13641120Sjdp 13741120Sjdp 13841120Sjdp/* The instance of "struct occurrence" representing the highest 13941120Sjdp interesting block in the dominator tree. */ 14041120Sjdpstatic struct occurrence *occ_head; 14141120Sjdp 14241120Sjdp/* Allocation pool for getting instances of "struct occurrence". */ 143103976Spststatic alloc_pool occ_pool; 14441120Sjdp 145103976Spst 14641120Sjdp 147103976Spst/* Allocate and return a new struct occurrence for basic block BB, and 148103976Spst whose children list is headed by CHILDREN. */ 149103976Spststatic struct occurrence * 150103976Spstocc_new (basic_block bb, struct occurrence *children) 151103976Spst{ 152103976Spst struct occurrence *occ; 15341120Sjdp 154103976Spst occ = bb->aux = pool_alloc (occ_pool); 155103976Spst memset (occ, 0, sizeof (struct occurrence)); 156103976Spst 157103976Spst occ->bb = bb; 158103976Spst occ->children = children; 159103976Spst return occ; 16041120Sjdp} 161103976Spst 162103976Spst 16341120Sjdp/* Insert NEW_OCC into our subset of the dominator tree. P_HEAD points to a 164103976Spst list of "struct occurrence"s, one per basic block, having IDOM as 165103976Spst their common dominator. 16641120Sjdp 167103976Spst We try to insert NEW_OCC as deep as possible in the tree, and we also 168103976Spst insert any other block that is a common dominator for BB and one 169103976Spst block already in the tree. */ 170103976Spst 17141120Sjdpstatic void 172103976Spstinsert_bb (struct occurrence *new_occ, basic_block idom, 17341120Sjdp struct occurrence **p_head) 174103976Spst{ 175103976Spst struct occurrence *occ, **p_occ; 17641120Sjdp 177103976Spst for (p_occ = p_head; (occ = *p_occ) != NULL; ) 178103976Spst { 179103976Spst basic_block bb = new_occ->bb, occ_bb = occ->bb; 180103976Spst basic_block dom = nearest_common_dominator (CDI_DOMINATORS, occ_bb, bb); 181103976Spst if (dom == bb) 182103976Spst { 183103976Spst /* BB dominates OCC_BB. OCC becomes NEW_OCC's child: remove OCC 184103976Spst from its list. */ 185103976Spst *p_occ = occ->next; 186103976Spst occ->next = new_occ->children; 187103976Spst new_occ->children = occ; 188103976Spst 189103976Spst /* Try the next block (it may as well be dominated by BB). */ 190103976Spst } 191103976Spst 192103976Spst else if (dom == occ_bb) 193103976Spst { 194103976Spst /* OCC_BB dominates BB. Tail recurse to look deeper. */ 195103976Spst insert_bb (new_occ, dom, &occ->children); 196103976Spst return; 197103976Spst } 198103976Spst 199103976Spst else if (dom != idom) 200103976Spst { 201103976Spst gcc_assert (!dom->aux); 202103976Spst 203103976Spst /* There is a dominator between IDOM and BB, add it and make 204103976Spst two children out of NEW_OCC and OCC. First, remove OCC from 205103976Spst its list. */ 206103976Spst *p_occ = occ->next; 207103976Spst new_occ->next = occ; 208103976Spst occ->next = NULL; 209103976Spst 21041120Sjdp /* None of the previous blocks has DOM as a dominator: if we tail 211103976Spst recursed, we would reexamine them uselessly. Just switch BB with 212103976Spst DOM, and go on looking for blocks dominated by DOM. */ 21341120Sjdp new_occ = occ_new (dom, new_occ); 21441120Sjdp } 215103976Spst 216103976Spst else 217103976Spst { 21841120Sjdp /* Nothing special, go on with the next element. */ 219103976Spst p_occ = &occ->next; 22041120Sjdp } 22141120Sjdp } 222103976Spst 22341120Sjdp /* No place was found as a child of IDOM. Make BB a sibling of IDOM. */ 22441120Sjdp new_occ->next = *p_head; 22541120Sjdp *p_head = new_occ; 22641120Sjdp} 22741120Sjdp 22841120Sjdp/* Register that we found a division in BB. */ 22941120Sjdp 23041120Sjdpstatic inline void 23141120Sjdpregister_division_in (basic_block bb) 23241120Sjdp{ 23341120Sjdp struct occurrence *occ; 23441120Sjdp 23541120Sjdp occ = (struct occurrence *) bb->aux; 23641120Sjdp if (!occ) 23741120Sjdp { 23841120Sjdp occ = occ_new (bb, NULL); 23941120Sjdp insert_bb (occ, ENTRY_BLOCK_PTR, &occ_head); 24041120Sjdp } 24141120Sjdp 24241120Sjdp occ->bb_has_division = true; 24341120Sjdp occ->num_divisions++; 24441120Sjdp} 24541120Sjdp 24641120Sjdp 24741120Sjdp/* Compute the number of divisions that postdominate each block in OCC and 24841120Sjdp its children. */ 24941120Sjdp 25041120Sjdpstatic void 25141120Sjdpcompute_merit (struct occurrence *occ) 25241120Sjdp{ 25341120Sjdp struct occurrence *occ_child; 25441120Sjdp basic_block dom = occ->bb; 25541120Sjdp 25641120Sjdp for (occ_child = occ->children; occ_child; occ_child = occ_child->next) 25741120Sjdp { 25841120Sjdp basic_block bb; 259141918Sstefanf if (occ_child->children) 26041120Sjdp compute_merit (occ_child); 26141120Sjdp 26241120Sjdp if (flag_exceptions) 26341120Sjdp bb = single_noncomplex_succ (dom); 26441120Sjdp else 26541120Sjdp bb = dom; 26641120Sjdp 26741120Sjdp if (dominated_by_p (CDI_POST_DOMINATORS, bb, occ_child->bb)) 26841120Sjdp occ->num_divisions += occ_child->num_divisions; 26941120Sjdp } 27041120Sjdp} 27141120Sjdp 27241120Sjdp 27341120Sjdp/* Return whether USE_STMT is a floating-point division by DEF. */ 27441120Sjdpstatic inline bool 27541120Sjdpis_division_by (tree use_stmt, tree def) 27641120Sjdp{ 27741120Sjdp return TREE_CODE (use_stmt) == MODIFY_EXPR 27841120Sjdp && TREE_CODE (TREE_OPERAND (use_stmt, 1)) == RDIV_EXPR 27941120Sjdp && TREE_OPERAND (TREE_OPERAND (use_stmt, 1), 1) == def; 28041120Sjdp} 28141120Sjdp 28241120Sjdp/* Walk the subset of the dominator tree rooted at OCC, setting the 28341120Sjdp RECIP_DEF field to a definition of 1.0 / DEF that can be used in 28441120Sjdp the given basic block. The field may be left NULL, of course, 28541120Sjdp if it is not possible or profitable to do the optimization. 28641120Sjdp 28741120Sjdp DEF_BSI is an iterator pointing at the statement defining DEF. 28841120Sjdp If RECIP_DEF is set, a dominator already has a computation that can 28941120Sjdp be used. */ 29041120Sjdp 29141120Sjdpstatic void 29241120Sjdpinsert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ, 29341120Sjdp tree def, tree recip_def, int threshold) 29441120Sjdp{ 29541120Sjdp tree type, new_stmt; 29641120Sjdp block_stmt_iterator bsi; 29741120Sjdp struct occurrence *occ_child; 29841120Sjdp 29941120Sjdp if (!recip_def 30041120Sjdp && (occ->bb_has_division || !flag_trapping_math) 30141120Sjdp && occ->num_divisions >= threshold) 30241120Sjdp { 30341120Sjdp /* Make a variable with the replacement and substitute it. */ 30441120Sjdp type = TREE_TYPE (def); 30541120Sjdp recip_def = make_rename_temp (type, "reciptmp"); 30641120Sjdp new_stmt = build2 (MODIFY_EXPR, void_type_node, recip_def, 30741120Sjdp fold_build2 (RDIV_EXPR, type, build_one_cst (type), 30841120Sjdp def)); 30941120Sjdp 31041120Sjdp 31141120Sjdp if (occ->bb_has_division) 31241120Sjdp { 31341120Sjdp /* Case 1: insert before an existing division. */ 31441120Sjdp bsi = bsi_after_labels (occ->bb); 31541120Sjdp while (!bsi_end_p (bsi) && !is_division_by (bsi_stmt (bsi), def)) 31641120Sjdp bsi_next (&bsi); 31741120Sjdp 31841120Sjdp bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT); 31941120Sjdp } 32041120Sjdp else if (def_bsi && occ->bb == def_bsi->bb) 32141120Sjdp { 32241120Sjdp /* Case 2: insert right after the definition. Note that this will 32341120Sjdp never happen if the definition statement can throw, because in 32441120Sjdp that case the sole successor of the statement's basic block will 32541120Sjdp dominate all the uses as well. */ 32641120Sjdp bsi_insert_after (def_bsi, new_stmt, BSI_NEW_STMT); 32741120Sjdp } 32841120Sjdp else 32941120Sjdp { 33041120Sjdp /* Case 3: insert in a basic block not containing defs/uses. */ 33141120Sjdp bsi = bsi_after_labels (occ->bb); 33241120Sjdp bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT); 33341120Sjdp } 33441120Sjdp 33541120Sjdp occ->recip_def_stmt = new_stmt; 33641120Sjdp } 33741120Sjdp 33841120Sjdp occ->recip_def = recip_def; 33941120Sjdp for (occ_child = occ->children; occ_child; occ_child = occ_child->next) 34041120Sjdp insert_reciprocals (def_bsi, occ_child, def, recip_def, threshold); 34141120Sjdp} 34241120Sjdp 34341120Sjdp 34441120Sjdp/* Replace the division at USE_P with a multiplication by the reciprocal, if 34541120Sjdp possible. */ 34641120Sjdp 34741120Sjdpstatic inline void 34841120Sjdpreplace_reciprocal (use_operand_p use_p) 34941120Sjdp{ 35041120Sjdp tree use_stmt = USE_STMT (use_p); 35141120Sjdp basic_block bb = bb_for_stmt (use_stmt); 35241120Sjdp struct occurrence *occ = (struct occurrence *) bb->aux; 35341120Sjdp 35441120Sjdp if (occ->recip_def && use_stmt != occ->recip_def_stmt) 35541120Sjdp { 35641120Sjdp TREE_SET_CODE (TREE_OPERAND (use_stmt, 1), MULT_EXPR); 35741120Sjdp SET_USE (use_p, occ->recip_def); 35841120Sjdp fold_stmt_inplace (use_stmt); 35941120Sjdp update_stmt (use_stmt); 36041120Sjdp } 36141120Sjdp} 36241120Sjdp 36341120Sjdp 36441120Sjdp/* Free OCC and return one more "struct occurrence" to be freed. */ 36541120Sjdp 36641120Sjdpstatic struct occurrence * 36741120Sjdpfree_bb (struct occurrence *occ) 36841120Sjdp{ 36941120Sjdp struct occurrence *child, *next; 37041120Sjdp 37141120Sjdp /* First get the two pointers hanging off OCC. */ 37241120Sjdp next = occ->next; 37341120Sjdp child = occ->children; 37441120Sjdp occ->bb->aux = NULL; 37541120Sjdp pool_free (occ_pool, occ); 37641120Sjdp 37741120Sjdp /* Now ensure that we don't recurse unless it is necessary. */ 37841120Sjdp if (!child) 37941120Sjdp return next; 38041120Sjdp else 38141120Sjdp { 38241120Sjdp while (next) 38341120Sjdp next = free_bb (next); 38441120Sjdp 38541120Sjdp return child; 38641120Sjdp } 38741120Sjdp} 38841120Sjdp 38941120Sjdp 39041120Sjdp/* Look for floating-point divisions among DEF's uses, and try to 39141120Sjdp replace them by multiplications with the reciprocal. Add 39241120Sjdp as many statements computing the reciprocal as needed. 39341120Sjdp 39441120Sjdp DEF must be a GIMPLE register of a floating-point type. */ 39541120Sjdp 39641120Sjdpstatic void 39741120Sjdpexecute_cse_reciprocals_1 (block_stmt_iterator *def_bsi, tree def) 39841120Sjdp{ 39941120Sjdp use_operand_p use_p; 40041120Sjdp imm_use_iterator use_iter; 40141120Sjdp struct occurrence *occ; 40241120Sjdp int count = 0, threshold; 40341120Sjdp 40441120Sjdp gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && is_gimple_reg (def)); 40541120Sjdp 40641120Sjdp FOR_EACH_IMM_USE_FAST (use_p, use_iter, def) 40741120Sjdp { 40841120Sjdp tree use_stmt = USE_STMT (use_p); 40941120Sjdp if (is_division_by (use_stmt, def)) 41041120Sjdp { 41141120Sjdp register_division_in (bb_for_stmt (use_stmt)); 41241120Sjdp count++; 41341120Sjdp } 41441120Sjdp } 41541120Sjdp 41641120Sjdp /* Do the expensive part only if we can hope to optimize something. */ 41741120Sjdp threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def))); 41841120Sjdp if (count >= threshold) 41941120Sjdp { 42041120Sjdp tree use_stmt; 42141120Sjdp for (occ = occ_head; occ; occ = occ->next) 42241120Sjdp { 42341120Sjdp compute_merit (occ); 42441120Sjdp insert_reciprocals (def_bsi, occ, def, NULL, threshold); 42541120Sjdp } 42641120Sjdp 42741120Sjdp FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def) 42841120Sjdp { 42941120Sjdp if (is_division_by (use_stmt, def)) 43041120Sjdp { 43141120Sjdp FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter) 43241120Sjdp replace_reciprocal (use_p); 43341120Sjdp } 43441120Sjdp } 43541120Sjdp } 43641120Sjdp 43741120Sjdp for (occ = occ_head; occ; ) 43841120Sjdp occ = free_bb (occ); 43941120Sjdp 44041120Sjdp occ_head = NULL; 44141120Sjdp} 44241120Sjdp 443103976Spst 444103976Spststatic bool 445103976Spstgate_cse_reciprocals (void) 446103976Spst{ 447103976Spst return optimize && !optimize_size && flag_unsafe_math_optimizations; 448103976Spst} 449103976Spst 450103976Spst 45141120Sjdp/* Go through all the floating-point SSA_NAMEs, and call 45241120Sjdp execute_cse_reciprocals_1 on each of them. */ 45341120Sjdpstatic unsigned int 45441120Sjdpexecute_cse_reciprocals (void) 45541120Sjdp{ 45641120Sjdp basic_block bb; 457103976Spst tree arg; 458103976Spst 45941120Sjdp occ_pool = create_alloc_pool ("dominators for recip", 46041120Sjdp sizeof (struct occurrence), 461103976Spst n_basic_blocks / 3 + 1); 462103976Spst 463103976Spst calculate_dominance_info (CDI_DOMINATORS); 46441120Sjdp calculate_dominance_info (CDI_POST_DOMINATORS); 46541120Sjdp 46641120Sjdp#ifdef ENABLE_CHECKING 46741120Sjdp FOR_EACH_BB (bb) 46841120Sjdp gcc_assert (!bb->aux); 46941120Sjdp#endif 47041120Sjdp 47141120Sjdp for (arg = DECL_ARGUMENTS (cfun->decl); arg; arg = TREE_CHAIN (arg)) 47241120Sjdp if (default_def (arg) 47341120Sjdp && FLOAT_TYPE_P (TREE_TYPE (arg)) 47441120Sjdp && is_gimple_reg (arg)) 47541120Sjdp execute_cse_reciprocals_1 (NULL, default_def (arg)); 47641120Sjdp 47741120Sjdp FOR_EACH_BB (bb) 47841120Sjdp { 47941120Sjdp block_stmt_iterator bsi; 48041120Sjdp tree phi, def; 48141120Sjdp 48241120Sjdp for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) 48341120Sjdp { 48441120Sjdp def = PHI_RESULT (phi); 48541120Sjdp if (FLOAT_TYPE_P (TREE_TYPE (def)) 48641120Sjdp && is_gimple_reg (def)) 48741120Sjdp execute_cse_reciprocals_1 (NULL, def); 48841120Sjdp } 48941120Sjdp 49041120Sjdp for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi)) 49141120Sjdp { 49241120Sjdp tree stmt = bsi_stmt (bsi); 49341120Sjdp if (TREE_CODE (stmt) == MODIFY_EXPR 49441120Sjdp && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL 49541120Sjdp && FLOAT_TYPE_P (TREE_TYPE (def)) 49641120Sjdp && TREE_CODE (def) == SSA_NAME) 49741120Sjdp execute_cse_reciprocals_1 (&bsi, def); 49841120Sjdp } 49941120Sjdp } 50041120Sjdp 50141120Sjdp free_dominance_info (CDI_DOMINATORS); 50241120Sjdp free_dominance_info (CDI_POST_DOMINATORS); 50341120Sjdp free_alloc_pool (occ_pool); 50441120Sjdp return 0; 50541120Sjdp} 50641120Sjdp 50741120Sjdpstruct tree_opt_pass pass_cse_reciprocals = 50841120Sjdp{ 50941120Sjdp "recip", /* name */ 51041120Sjdp gate_cse_reciprocals, /* gate */ 51141120Sjdp execute_cse_reciprocals, /* execute */ 51241120Sjdp NULL, /* sub */ 51341120Sjdp NULL, /* next */ 51441120Sjdp 0, /* static_pass_number */ 51541120Sjdp 0, /* tv_id */ 51641120Sjdp PROP_ssa, /* properties_required */ 51741120Sjdp 0, /* properties_provided */ 51841120Sjdp 0, /* properties_destroyed */ 51941120Sjdp 0, /* todo_flags_start */ 52041120Sjdp TODO_dump_func | TODO_update_ssa | TODO_verify_ssa 52141120Sjdp | TODO_verify_stmts, /* todo_flags_finish */ 52241120Sjdp 0 /* letter */ 52341120Sjdp}; 52441120Sjdp