Update baseline symbols for hppa-linux.
[official-gcc.git] / gcc / gimple-range-gori.cc
blob610a5295e6287f4bdb91065d34e59923772e57ec
1 /* Gimple range GORI functions.
2 Copyright (C) 2017-2022 Free Software Foundation, Inc.
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
4 and Aldy Hernandez <aldyh@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "ssa.h"
29 #include "gimple-pretty-print.h"
30 #include "gimple-range.h"
32 // Return TRUE if GS is a logical && or || expression.
34 static inline bool
35 is_gimple_logical_p (const gimple *gs)
37 // Look for boolean and/or condition.
38 if (is_gimple_assign (gs))
39 switch (gimple_expr_code (gs))
41 case TRUTH_AND_EXPR:
42 case TRUTH_OR_EXPR:
43 return true;
45 case BIT_AND_EXPR:
46 case BIT_IOR_EXPR:
47 // Bitwise operations on single bits are logical too.
48 if (types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (gs)),
49 boolean_type_node))
50 return true;
51 break;
53 default:
54 break;
56 return false;
59 /* RANGE_DEF_CHAIN is used to determine which SSA names in a block can
60 have range information calculated for them, and what the
61 dependencies on each other are.
63 Information for a basic block is calculated once and stored. It is
64 only calculated the first time a query is made, so if no queries
65 are made, there is little overhead.
67 The def_chain bitmap is indexed by SSA_NAME_VERSION. Bits are set
68 within this bitmap to indicate SSA names that are defined in the
69 SAME block and used to calculate this SSA name.
72 <bb 2> :
73 _1 = x_4(D) + -2;
74 _2 = _1 * 4;
75 j_7 = foo ();
76 q_5 = _2 + 3;
77 if (q_5 <= 13)
79 _1 : x_4(D)
80 _2 : 1 x_4(D)
81 q_5 : _1 _2 x_4(D)
83 This dump indicates the bits set in the def_chain vector.
84 as well as demonstrates the def_chain bits for the related ssa_names.
86 Checking the chain for _2 indicates that _1 and x_4 are used in
87 its evaluation.
89 Def chains also only include statements which are valid gimple
90 so a def chain will only span statements for which the range
91 engine implements operations for. */
94 // Construct a range_def_chain.
96 range_def_chain::range_def_chain ()
98 bitmap_obstack_initialize (&m_bitmaps);
99 m_def_chain.create (0);
100 m_def_chain.safe_grow_cleared (num_ssa_names);
101 m_logical_depth = 0;
104 // Destruct a range_def_chain.
106 range_def_chain::~range_def_chain ()
108 m_def_chain.release ();
109 bitmap_obstack_release (&m_bitmaps);
112 // Return true if NAME is in the def chain of DEF. If BB is provided,
113 // only return true if the defining statement of DEF is in BB.
115 bool
116 range_def_chain::in_chain_p (tree name, tree def)
118 gcc_checking_assert (gimple_range_ssa_p (def));
119 gcc_checking_assert (gimple_range_ssa_p (name));
121 // Get the defintion chain for DEF.
122 bitmap chain = get_def_chain (def);
124 if (chain == NULL)
125 return false;
126 return bitmap_bit_p (chain, SSA_NAME_VERSION (name));
129 // Add either IMP or the import list B to the import set of DATA.
131 void
132 range_def_chain::set_import (struct rdc &data, tree imp, bitmap b)
134 // If there are no imports, just return
135 if (imp == NULL_TREE && !b)
136 return;
137 if (!data.m_import)
138 data.m_import = BITMAP_ALLOC (&m_bitmaps);
139 if (imp != NULL_TREE)
140 bitmap_set_bit (data.m_import, SSA_NAME_VERSION (imp));
141 else
142 bitmap_ior_into (data.m_import, b);
145 // Return the import list for NAME.
147 bitmap
148 range_def_chain::get_imports (tree name)
150 if (!has_def_chain (name))
151 get_def_chain (name);
152 bitmap i = m_def_chain[SSA_NAME_VERSION (name)].m_import;
153 return i;
156 // Return true if IMPORT is an import to NAMEs def chain.
158 bool
159 range_def_chain::chain_import_p (tree name, tree import)
161 bitmap b = get_imports (name);
162 if (b)
163 return bitmap_bit_p (b, SSA_NAME_VERSION (import));
164 return false;
167 // Build def_chains for NAME if it is in BB. Copy the def chain into RESULT.
169 void
170 range_def_chain::register_dependency (tree name, tree dep, basic_block bb)
172 if (!gimple_range_ssa_p (dep))
173 return;
175 unsigned v = SSA_NAME_VERSION (name);
176 if (v >= m_def_chain.length ())
177 m_def_chain.safe_grow_cleared (num_ssa_names + 1);
178 struct rdc &src = m_def_chain[v];
179 gimple *def_stmt = SSA_NAME_DEF_STMT (dep);
180 unsigned dep_v = SSA_NAME_VERSION (dep);
181 bitmap b;
183 // Set the direct dependency cache entries.
184 if (!src.ssa1)
185 src.ssa1 = dep;
186 else if (!src.ssa2 && src.ssa1 != dep)
187 src.ssa2 = dep;
189 // Don't calculate imports or export/dep chains if BB is not provided.
190 // This is usually the case for when the temporal cache wants the direct
191 // dependencies of a stmt.
192 if (!bb)
193 return;
195 if (!src.bm)
196 src.bm = BITMAP_ALLOC (&m_bitmaps);
198 // Add this operand into the result.
199 bitmap_set_bit (src.bm, dep_v);
201 if (gimple_bb (def_stmt) == bb && !is_a<gphi *>(def_stmt))
203 // Get the def chain for the operand.
204 b = get_def_chain (dep);
205 // If there was one, copy it into result. Access def_chain directly
206 // as the get_def_chain request above could reallocate the vector.
207 if (b)
208 bitmap_ior_into (m_def_chain[v].bm, b);
209 // And copy the import list.
210 set_import (m_def_chain[v], NULL_TREE, get_imports (dep));
212 else
213 // Originated outside the block, so it is an import.
214 set_import (src, dep, NULL);
217 bool
218 range_def_chain::def_chain_in_bitmap_p (tree name, bitmap b)
220 bitmap a = get_def_chain (name);
221 if (a && b)
222 return bitmap_intersect_p (a, b);
223 return false;
226 void
227 range_def_chain::add_def_chain_to_bitmap (bitmap b, tree name)
229 bitmap r = get_def_chain (name);
230 if (r)
231 bitmap_ior_into (b, r);
235 // Return TRUE if NAME has been processed for a def_chain.
237 inline bool
238 range_def_chain::has_def_chain (tree name)
240 // Ensure there is an entry in the internal vector.
241 unsigned v = SSA_NAME_VERSION (name);
242 if (v >= m_def_chain.length ())
243 m_def_chain.safe_grow_cleared (num_ssa_names + 1);
244 return (m_def_chain[v].ssa1 != 0);
249 // Calculate the def chain for NAME and all of its dependent
250 // operands. Only using names in the same BB. Return the bitmap of
251 // all names in the m_def_chain. This only works for supported range
252 // statements.
254 bitmap
255 range_def_chain::get_def_chain (tree name)
257 tree ssa[3];
258 unsigned v = SSA_NAME_VERSION (name);
260 // If it has already been processed, just return the cached value.
261 if (has_def_chain (name) && m_def_chain[v].bm)
262 return m_def_chain[v].bm;
264 // No definition chain for default defs.
265 if (SSA_NAME_IS_DEFAULT_DEF (name))
267 // A Default def is always an import.
268 set_import (m_def_chain[v], name, NULL);
269 return NULL;
272 gimple *stmt = SSA_NAME_DEF_STMT (name);
273 unsigned count = gimple_range_ssa_names (ssa, 3, stmt);
274 if (count == 0)
276 // Stmts not understood or with no operands are always imports.
277 set_import (m_def_chain[v], name, NULL);
278 return NULL;
281 // Terminate the def chains if we see too many cascading stmts.
282 if (m_logical_depth == param_ranger_logical_depth)
283 return NULL;
285 // Increase the depth if we have a pair of ssa-names.
286 if (count > 1)
287 m_logical_depth++;
289 for (unsigned x = 0; x < count; x++)
290 register_dependency (name, ssa[x], gimple_bb (stmt));
292 if (count > 1)
293 m_logical_depth--;
295 return m_def_chain[v].bm;
298 // Dump what we know for basic block BB to file F.
300 void
301 range_def_chain::dump (FILE *f, basic_block bb, const char *prefix)
303 unsigned x, y;
304 bitmap_iterator bi;
306 // Dump the def chain for each SSA_NAME defined in BB.
307 for (x = 1; x < num_ssa_names; x++)
309 tree name = ssa_name (x);
310 if (!name)
311 continue;
312 gimple *stmt = SSA_NAME_DEF_STMT (name);
313 if (!stmt || (bb && gimple_bb (stmt) != bb))
314 continue;
315 bitmap chain = (has_def_chain (name) ? get_def_chain (name) : NULL);
316 if (chain && !bitmap_empty_p (chain))
318 fprintf (f, prefix);
319 print_generic_expr (f, name, TDF_SLIM);
320 fprintf (f, " : ");
322 bitmap imports = get_imports (name);
323 EXECUTE_IF_SET_IN_BITMAP (chain, 0, y, bi)
325 print_generic_expr (f, ssa_name (y), TDF_SLIM);
326 if (imports && bitmap_bit_p (imports, y))
327 fprintf (f, "(I)");
328 fprintf (f, " ");
330 fprintf (f, "\n");
336 // -------------------------------------------------------------------
338 /* GORI_MAP is used to accumulate what SSA names in a block can
339 generate range information, and provides tools for the block ranger
340 to enable it to efficiently calculate these ranges.
342 GORI stands for "Generates Outgoing Range Information."
344 It utilizes the range_def_chain class to contruct def_chains.
345 Information for a basic block is calculated once and stored. It is
346 only calculated the first time a query is made. If no queries are
347 made, there is little overhead.
349 one bitmap is maintained for each basic block:
350 m_outgoing : a set bit indicates a range can be generated for a name.
352 Generally speaking, the m_outgoing vector is the union of the
353 entire def_chain of all SSA names used in the last statement of the
354 block which generate ranges. */
357 // Initialize a gori-map structure.
359 gori_map::gori_map ()
361 m_outgoing.create (0);
362 m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
363 m_incoming.create (0);
364 m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
365 m_maybe_variant = BITMAP_ALLOC (&m_bitmaps);
368 // Free any memory the GORI map allocated.
370 gori_map::~gori_map ()
372 m_incoming.release ();
373 m_outgoing.release ();
376 // Return the bitmap vector of all export from BB. Calculate if necessary.
378 bitmap
379 gori_map::exports (basic_block bb)
381 if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index])
382 calculate_gori (bb);
383 return m_outgoing[bb->index];
386 // Return the bitmap vector of all imports to BB. Calculate if necessary.
388 bitmap
389 gori_map::imports (basic_block bb)
391 if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index])
392 calculate_gori (bb);
393 return m_incoming[bb->index];
396 // Return true if NAME is can have ranges generated for it from basic
397 // block BB.
399 bool
400 gori_map::is_export_p (tree name, basic_block bb)
402 // If no BB is specified, test if it is exported anywhere in the IL.
403 if (!bb)
404 return bitmap_bit_p (m_maybe_variant, SSA_NAME_VERSION (name));
405 return bitmap_bit_p (exports (bb), SSA_NAME_VERSION (name));
408 // Set or clear the m_maybe_variant bit to determine if ranges will be tracked
409 // for NAME. A clear bit means they will NOT be tracked.
411 void
412 gori_map::set_range_invariant (tree name, bool invariant)
414 if (invariant)
415 bitmap_clear_bit (m_maybe_variant, SSA_NAME_VERSION (name));
416 else
417 bitmap_set_bit (m_maybe_variant, SSA_NAME_VERSION (name));
420 // Return true if NAME is an import to block BB.
422 bool
423 gori_map::is_import_p (tree name, basic_block bb)
425 // If no BB is specified, test if it is exported anywhere in the IL.
426 return bitmap_bit_p (imports (bb), SSA_NAME_VERSION (name));
429 // If NAME is non-NULL and defined in block BB, calculate the def
430 // chain and add it to m_outgoing.
432 void
433 gori_map::maybe_add_gori (tree name, basic_block bb)
435 if (name)
437 // Check if there is a def chain, regardless of the block.
438 add_def_chain_to_bitmap (m_outgoing[bb->index], name);
439 // Check for any imports.
440 bitmap imp = get_imports (name);
441 // If there were imports, add them so we can recompute
442 if (imp)
443 bitmap_ior_into (m_incoming[bb->index], imp);
444 // This name is always an import.
445 if (gimple_bb (SSA_NAME_DEF_STMT (name)) != bb)
446 bitmap_set_bit (m_incoming[bb->index], SSA_NAME_VERSION (name));
448 // Def chain doesn't include itself, and even if there isn't a
449 // def chain, this name should be added to exports.
450 bitmap_set_bit (m_outgoing[bb->index], SSA_NAME_VERSION (name));
454 // Calculate all the required information for BB.
456 void
457 gori_map::calculate_gori (basic_block bb)
459 tree name;
460 if (bb->index >= (signed int)m_outgoing.length ())
462 m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
463 m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
465 gcc_checking_assert (m_outgoing[bb->index] == NULL);
466 m_outgoing[bb->index] = BITMAP_ALLOC (&m_bitmaps);
467 m_incoming[bb->index] = BITMAP_ALLOC (&m_bitmaps);
469 if (single_succ_p (bb))
470 return;
472 // If this block's last statement may generate range informaiton, go
473 // calculate it.
474 gimple *stmt = gimple_outgoing_range_stmt_p (bb);
475 if (!stmt)
476 return;
477 if (is_a<gcond *> (stmt))
479 gcond *gc = as_a<gcond *>(stmt);
480 name = gimple_range_ssa_p (gimple_cond_lhs (gc));
481 maybe_add_gori (name, gimple_bb (stmt));
483 name = gimple_range_ssa_p (gimple_cond_rhs (gc));
484 maybe_add_gori (name, gimple_bb (stmt));
486 else
488 // Do not process switches if they are too large.
489 if (EDGE_COUNT (bb->succs) > (unsigned)param_evrp_switch_limit)
490 return;
491 gswitch *gs = as_a<gswitch *>(stmt);
492 name = gimple_range_ssa_p (gimple_switch_index (gs));
493 maybe_add_gori (name, gimple_bb (stmt));
495 // Add this bitmap to the aggregate list of all outgoing names.
496 bitmap_ior_into (m_maybe_variant, m_outgoing[bb->index]);
499 // Dump the table information for BB to file F.
501 void
502 gori_map::dump (FILE *f, basic_block bb, bool verbose)
504 // BB was not processed.
505 if (!m_outgoing[bb->index] || bitmap_empty_p (m_outgoing[bb->index]))
506 return;
508 tree name;
510 bitmap imp = imports (bb);
511 if (!bitmap_empty_p (imp))
513 if (verbose)
514 fprintf (f, "bb<%u> Imports: ",bb->index);
515 else
516 fprintf (f, "Imports: ");
517 FOR_EACH_GORI_IMPORT_NAME (*this, bb, name)
519 print_generic_expr (f, name, TDF_SLIM);
520 fprintf (f, " ");
522 fputc ('\n', f);
525 if (verbose)
526 fprintf (f, "bb<%u> Exports: ",bb->index);
527 else
528 fprintf (f, "Exports: ");
529 // Dump the export vector.
530 FOR_EACH_GORI_EXPORT_NAME (*this, bb, name)
532 print_generic_expr (f, name, TDF_SLIM);
533 fprintf (f, " ");
535 fputc ('\n', f);
537 range_def_chain::dump (f, bb, " ");
540 // Dump the entire GORI map structure to file F.
542 void
543 gori_map::dump (FILE *f)
545 basic_block bb;
546 FOR_EACH_BB_FN (bb, cfun)
547 dump (f, bb);
550 DEBUG_FUNCTION void
551 debug (gori_map &g)
553 g.dump (stderr);
556 // -------------------------------------------------------------------
558 // Construct a gori_compute object.
560 gori_compute::gori_compute (int not_executable_flag)
561 : outgoing (param_evrp_switch_limit), tracer ("GORI ")
563 m_not_executable_flag = not_executable_flag;
564 // Create a boolean_type true and false range.
565 m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node);
566 m_bool_one = int_range<2> (boolean_true_node, boolean_true_node);
567 if (dump_file && (param_ranger_debug & RANGER_DEBUG_GORI))
568 tracer.enable_trace ();
571 // Given the switch S, return an evaluation in R for NAME when the lhs
572 // evaluates to LHS. Returning false means the name being looked for
573 // was not resolvable.
575 bool
576 gori_compute::compute_operand_range_switch (vrange &r, gswitch *s,
577 const vrange &lhs,
578 tree name, fur_source &src)
580 tree op1 = gimple_switch_index (s);
582 // If name matches, the range is simply the range from the edge.
583 // Empty ranges are viral as they are on a path which isn't
584 // executable.
585 if (op1 == name || lhs.undefined_p ())
587 r = lhs;
588 return true;
591 // If op1 is in the defintion chain, pass lhs back.
592 if (gimple_range_ssa_p (op1) && in_chain_p (name, op1))
593 return compute_operand_range (r, SSA_NAME_DEF_STMT (op1), lhs, name, src);
595 return false;
599 // Return an evaluation for NAME as it would appear in STMT when the
600 // statement's lhs evaluates to LHS. If successful, return TRUE and
601 // store the evaluation in R, otherwise return FALSE.
603 bool
604 gori_compute::compute_operand_range (vrange &r, gimple *stmt,
605 const vrange &lhs, tree name,
606 fur_source &src, value_relation *rel)
608 value_relation vrel;
609 value_relation *vrel_ptr = rel;
610 // If the lhs doesn't tell us anything, neither will unwinding further.
611 if (lhs.varying_p ())
612 return false;
614 // Empty ranges are viral as they are on an unexecutable path.
615 if (lhs.undefined_p ())
617 r.set_undefined ();
618 return true;
620 if (is_a<gswitch *> (stmt))
621 return compute_operand_range_switch (r, as_a<gswitch *> (stmt), lhs, name,
622 src);
623 gimple_range_op_handler handler (stmt);
624 if (!handler)
625 return false;
627 tree op1 = gimple_range_ssa_p (handler.operand1 ());
628 tree op2 = gimple_range_ssa_p (handler.operand2 ());
630 // If there is a relation, use it instead of any passed in. This will allow
631 // multiple relations to be processed in compound logicals.
632 if (op1 && op2)
634 relation_kind k = handler.op1_op2_relation (lhs);
635 if (k != VREL_VARYING)
637 vrel.set_relation (k, op1, op2);
638 vrel_ptr = &vrel;
642 // Handle end of lookup first.
643 if (op1 == name)
644 return compute_operand1_range (r, handler, lhs, name, src, vrel_ptr);
645 if (op2 == name)
646 return compute_operand2_range (r, handler, lhs, name, src, vrel_ptr);
648 // NAME is not in this stmt, but one of the names in it ought to be
649 // derived from it.
650 bool op1_in_chain = op1 && in_chain_p (name, op1);
651 bool op2_in_chain = op2 && in_chain_p (name, op2);
653 // If neither operand is derived, then this stmt tells us nothing.
654 if (!op1_in_chain && !op2_in_chain)
655 return false;
657 bool res;
658 // Process logicals as they have special handling.
659 if (is_gimple_logical_p (stmt))
661 unsigned idx;
662 if ((idx = tracer.header ("compute_operand ")))
664 print_generic_expr (dump_file, name, TDF_SLIM);
665 fprintf (dump_file, " with LHS = ");
666 lhs.dump (dump_file);
667 fprintf (dump_file, " at stmt ");
668 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
671 tree type = TREE_TYPE (name);
672 Value_Range op1_trange (type), op1_frange (type);
673 Value_Range op2_trange (type), op2_frange (type);
674 compute_logical_operands (op1_trange, op1_frange, handler,
675 as_a <irange> (lhs),
676 name, src, op1, op1_in_chain);
677 compute_logical_operands (op2_trange, op2_frange, handler,
678 as_a <irange> (lhs),
679 name, src, op2, op2_in_chain);
680 res = logical_combine (r,
681 gimple_expr_code (stmt),
682 as_a <irange> (lhs),
683 op1_trange, op1_frange, op2_trange, op2_frange);
684 if (idx)
685 tracer.trailer (idx, "compute_operand", res, name, r);
687 // Follow the appropriate operands now.
688 else if (op1_in_chain && op2_in_chain)
689 res = compute_operand1_and_operand2_range (r, handler, lhs, name, src,
690 vrel_ptr);
691 else if (op1_in_chain)
692 res = compute_operand1_range (r, handler, lhs, name, src, vrel_ptr);
693 else if (op2_in_chain)
694 res = compute_operand2_range (r, handler, lhs, name, src, vrel_ptr);
695 else
696 gcc_unreachable ();
698 // If neither operand is derived, this statement tells us nothing.
699 return res;
703 // Return TRUE if range R is either a true or false compatible range.
705 static bool
706 range_is_either_true_or_false (const irange &r)
708 if (r.undefined_p ())
709 return false;
711 // This is complicated by the fact that Ada has multi-bit booleans,
712 // so true can be ~[0, 0] (i.e. [1,MAX]).
713 tree type = r.type ();
714 gcc_checking_assert (range_compatible_p (type, boolean_type_node));
715 return (r.singleton_p () || !r.contains_p (build_zero_cst (type)));
718 // Evaluate a binary logical expression by combining the true and
719 // false ranges for each of the operands based on the result value in
720 // the LHS.
722 bool
723 gori_compute::logical_combine (vrange &r, enum tree_code code,
724 const irange &lhs,
725 const vrange &op1_true, const vrange &op1_false,
726 const vrange &op2_true, const vrange &op2_false)
728 if (op1_true.varying_p () && op1_false.varying_p ()
729 && op2_true.varying_p () && op2_false.varying_p ())
730 return false;
732 unsigned idx;
733 if ((idx = tracer.header ("logical_combine")))
735 switch (code)
737 case TRUTH_OR_EXPR:
738 case BIT_IOR_EXPR:
739 fprintf (dump_file, " || ");
740 break;
741 case TRUTH_AND_EXPR:
742 case BIT_AND_EXPR:
743 fprintf (dump_file, " && ");
744 break;
745 default:
746 break;
748 fprintf (dump_file, " with LHS = ");
749 lhs.dump (dump_file);
750 fputc ('\n', dump_file);
752 tracer.print (idx, "op1_true = ");
753 op1_true.dump (dump_file);
754 fprintf (dump_file, " op1_false = ");
755 op1_false.dump (dump_file);
756 fputc ('\n', dump_file);
757 tracer.print (idx, "op2_true = ");
758 op2_true.dump (dump_file);
759 fprintf (dump_file, " op2_false = ");
760 op2_false.dump (dump_file);
761 fputc ('\n', dump_file);
764 // This is not a simple fold of a logical expression, rather it
765 // determines ranges which flow through the logical expression.
767 // Assuming x_8 is an unsigned char, and relational statements:
768 // b_1 = x_8 < 20
769 // b_2 = x_8 > 5
770 // consider the logical expression and branch:
771 // c_2 = b_1 && b_2
772 // if (c_2)
774 // To determine the range of x_8 on either edge of the branch, one
775 // must first determine what the range of x_8 is when the boolean
776 // values of b_1 and b_2 are both true and false.
777 // b_1 TRUE x_8 = [0, 19]
778 // b_1 FALSE x_8 = [20, 255]
779 // b_2 TRUE x_8 = [6, 255]
780 // b_2 FALSE x_8 = [0,5].
782 // These ranges are then combined based on the expected outcome of
783 // the branch. The range on the TRUE side of the branch must satisfy
784 // b_1 == true && b_2 == true
786 // In terms of x_8, that means both x_8 == [0, 19] and x_8 = [6, 255]
787 // must be true. The range of x_8 on the true side must be the
788 // intersection of both ranges since both must be true. Thus the
789 // range of x_8 on the true side is [6, 19].
791 // To determine the ranges on the FALSE side, all 3 combinations of
792 // failing ranges must be considered, and combined as any of them
793 // can cause the false result.
795 // If the LHS can be TRUE or FALSE, then evaluate both a TRUE and
796 // FALSE results and combine them. If we fell back to VARYING any
797 // range restrictions that have been discovered up to this point
798 // would be lost.
799 if (!range_is_either_true_or_false (lhs))
801 bool res;
802 Value_Range r1 (r);
803 if (logical_combine (r1, code, m_bool_zero, op1_true, op1_false,
804 op2_true, op2_false)
805 && logical_combine (r, code, m_bool_one, op1_true, op1_false,
806 op2_true, op2_false))
808 r.union_ (r1);
809 res = true;
811 else
812 res = false;
813 if (idx && res)
815 tracer.print (idx, "logical_combine produced ");
816 r.dump (dump_file);
817 fputc ('\n', dump_file);
821 switch (code)
823 // A logical AND combines ranges from 2 boolean conditions.
824 // c_2 = b_1 && b_2
825 case TRUTH_AND_EXPR:
826 case BIT_AND_EXPR:
827 if (!lhs.zero_p ())
829 // The TRUE side is the intersection of the 2 true ranges.
830 r = op1_true;
831 r.intersect (op2_true);
833 else
835 // The FALSE side is the union of the other 3 cases.
836 Value_Range ff (op1_false);
837 ff.intersect (op2_false);
838 Value_Range tf (op1_true);
839 tf.intersect (op2_false);
840 Value_Range ft (op1_false);
841 ft.intersect (op2_true);
842 r = ff;
843 r.union_ (tf);
844 r.union_ (ft);
846 break;
847 // A logical OR combines ranges from 2 boolean conditons.
848 // c_2 = b_1 || b_2
849 case TRUTH_OR_EXPR:
850 case BIT_IOR_EXPR:
851 if (lhs.zero_p ())
853 // An OR operation will only take the FALSE path if both
854 // operands are false simlulateously, which means they should
855 // be intersected. !(x || y) == !x && !y
856 r = op1_false;
857 r.intersect (op2_false);
859 else
861 // The TRUE side of an OR operation will be the union of
862 // the other three combinations.
863 Value_Range tt (op1_true);
864 tt.intersect (op2_true);
865 Value_Range tf (op1_true);
866 tf.intersect (op2_false);
867 Value_Range ft (op1_false);
868 ft.intersect (op2_true);
869 r = tt;
870 r.union_ (tf);
871 r.union_ (ft);
873 break;
874 default:
875 gcc_unreachable ();
878 if (idx)
879 tracer.trailer (idx, "logical_combine", true, NULL_TREE, r);
880 return true;
884 // Given a logical STMT, calculate true and false ranges for each
885 // potential path of NAME, assuming NAME came through the OP chain if
886 // OP_IN_CHAIN is true.
888 void
889 gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range,
890 gimple_range_op_handler &handler,
891 const irange &lhs,
892 tree name, fur_source &src,
893 tree op, bool op_in_chain)
895 gimple *stmt = handler.stmt ();
896 gimple *src_stmt = gimple_range_ssa_p (op) ? SSA_NAME_DEF_STMT (op) : NULL;
897 if (!op_in_chain || !src_stmt || chain_import_p (handler.lhs (), op))
899 // If op is not in the def chain, or defined in this block,
900 // use its known value on entry to the block.
901 src.get_operand (true_range, name);
902 false_range = true_range;
903 unsigned idx;
904 if ((idx = tracer.header ("logical_operand")))
906 print_generic_expr (dump_file, op, TDF_SLIM);
907 fprintf (dump_file, " not in computation chain. Queried.\n");
908 tracer.trailer (idx, "logical_operand", true, NULL_TREE, true_range);
910 return;
913 enum tree_code code = gimple_expr_code (stmt);
914 // Optimize [0 = x | y], since neither operand can ever be non-zero.
915 if ((code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) && lhs.zero_p ())
917 if (!compute_operand_range (false_range, src_stmt, m_bool_zero, name,
918 src))
919 src.get_operand (false_range, name);
920 true_range = false_range;
921 return;
924 // Optimize [1 = x & y], since neither operand can ever be zero.
925 if ((code == BIT_AND_EXPR || code == TRUTH_AND_EXPR) && lhs == m_bool_one)
927 if (!compute_operand_range (true_range, src_stmt, m_bool_one, name, src))
928 src.get_operand (true_range, name);
929 false_range = true_range;
930 return;
933 // Calculate ranges for true and false on both sides, since the false
934 // path is not always a simple inversion of the true side.
935 if (!compute_operand_range (true_range, src_stmt, m_bool_one, name, src))
936 src.get_operand (true_range, name);
937 if (!compute_operand_range (false_range, src_stmt, m_bool_zero, name, src))
938 src.get_operand (false_range, name);
942 // This routine will try to refine the ranges of OP1 and OP2 given a relation
943 // K between them. In order to perform this refinement, one of the operands
944 // must be in the definition chain of the other. The use is refined using
945 // op1/op2_range on the statement, and the defintion is then recalculated
946 // using the relation.
948 bool
949 gori_compute::refine_using_relation (tree op1, vrange &op1_range,
950 tree op2, vrange &op2_range,
951 fur_source &src, relation_kind k)
953 gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
954 gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
955 gcc_checking_assert (k != VREL_VARYING && k != VREL_UNDEFINED);
957 bool change = false;
958 bool op1_def_p = in_chain_p (op2, op1);
959 if (!op1_def_p)
960 if (!in_chain_p (op1, op2))
961 return false;
963 tree def_op = op1_def_p ? op1 : op2;
964 tree use_op = op1_def_p ? op2 : op1;
966 if (!op1_def_p)
967 k = relation_swap (k);
969 // op1_def is true if we want to look up op1, otherwise we want op2.
970 // if neither is the case, we returned in the above check.
972 gimple *def_stmt = SSA_NAME_DEF_STMT (def_op);
973 gimple_range_op_handler op_handler (def_stmt);
974 if (!op_handler)
975 return false;
976 tree def_op1 = op_handler.operand1 ();
977 tree def_op2 = op_handler.operand2 ();
978 // if the def isn't binary, the relation will not be useful.
979 if (!def_op2)
980 return false;
982 // Determine if op2 is directly referenced as an operand.
983 if (def_op1 == use_op)
985 // def_stmt has op1 in the 1st operand position.
986 Value_Range other_op (TREE_TYPE (def_op2));
987 src.get_operand (other_op, def_op2);
989 // Using op1_range as the LHS, and relation REL, evaluate op2.
990 tree type = TREE_TYPE (def_op1);
991 Value_Range new_result (type);
992 if (!op_handler.op1_range (new_result, type,
993 op1_def_p ? op1_range : op2_range,
994 other_op, relation_trio::lhs_op2 (k)))
995 return false;
996 if (op1_def_p)
998 change |= op2_range.intersect (new_result);
999 // Recalculate op2.
1000 if (op_handler.fold_range (new_result, type, op2_range, other_op))
1002 change |= op1_range.intersect (new_result);
1005 else
1007 change |= op1_range.intersect (new_result);
1008 // Recalculate op1.
1009 if (op_handler.fold_range (new_result, type, op1_range, other_op))
1011 change |= op2_range.intersect (new_result);
1015 else if (def_op2 == use_op)
1017 // def_stmt has op1 in the 1st operand position.
1018 Value_Range other_op (TREE_TYPE (def_op1));
1019 src.get_operand (other_op, def_op1);
1021 // Using op1_range as the LHS, and relation REL, evaluate op2.
1022 tree type = TREE_TYPE (def_op2);
1023 Value_Range new_result (type);
1024 if (!op_handler.op2_range (new_result, type,
1025 op1_def_p ? op1_range : op2_range,
1026 other_op, relation_trio::lhs_op1 (k)))
1027 return false;
1028 if (op1_def_p)
1030 change |= op2_range.intersect (new_result);
1031 // Recalculate op1.
1032 if (op_handler.fold_range (new_result, type, other_op, op2_range))
1034 change |= op1_range.intersect (new_result);
1037 else
1039 change |= op1_range.intersect (new_result);
1040 // Recalculate op2.
1041 if (op_handler.fold_range (new_result, type, other_op, op1_range))
1043 change |= op2_range.intersect (new_result);
1047 return change;
1050 // Calculate a range for NAME from the operand 1 position of STMT
1051 // assuming the result of the statement is LHS. Return the range in
1052 // R, or false if no range could be calculated.
1054 bool
1055 gori_compute::compute_operand1_range (vrange &r,
1056 gimple_range_op_handler &handler,
1057 const vrange &lhs, tree name,
1058 fur_source &src, value_relation *rel)
1060 gimple *stmt = handler.stmt ();
1061 tree op1 = handler.operand1 ();
1062 tree op2 = handler.operand2 ();
1063 tree lhs_name = gimple_get_lhs (stmt);
1065 Value_Range op1_range (TREE_TYPE (op1));
1066 Value_Range tmp (TREE_TYPE (op1));
1067 Value_Range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
1069 // Fetch the known range for op1 in this block.
1070 src.get_operand (op1_range, op1);
1072 // Now range-op calcuate and put that result in r.
1073 if (op2)
1075 src.get_operand (op2_range, op2);
1076 relation_kind k = VREL_VARYING;
1077 relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING;
1078 if (rel)
1080 if (lhs_name == rel->op1 () && op1 == rel->op2 ())
1081 k = rel->kind ();
1082 else if (lhs_name == rel->op2 () && op1 == rel->op1 ())
1083 k = relation_swap (rel->kind ());
1084 else if (op1 == rel->op1 () && op2 == rel->op2 ())
1086 op_op = rel->kind ();
1087 refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
1089 else if (op1 == rel->op2 () && op2 == rel->op1 ())
1091 op_op = relation_swap (rel->kind ());
1092 refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
1095 if (!handler.calc_op1 (tmp, lhs, op2_range, relation_trio (VREL_VARYING,
1096 k, op_op)))
1097 return false;
1099 else
1101 // We pass op1_range to the unary operation. Nomally it's a
1102 // hidden range_for_type parameter, but sometimes having the
1103 // actual range can result in better information.
1104 if (!handler.calc_op1 (tmp, lhs, op1_range, TRIO_VARYING))
1105 return false;
1108 unsigned idx;
1109 if ((idx = tracer.header ("compute op 1 (")))
1111 print_generic_expr (dump_file, op1, TDF_SLIM);
1112 fprintf (dump_file, ") at ");
1113 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1114 tracer.print (idx, "LHS =");
1115 lhs.dump (dump_file);
1116 if (op2 && TREE_CODE (op2) == SSA_NAME)
1118 fprintf (dump_file, ", ");
1119 print_generic_expr (dump_file, op2, TDF_SLIM);
1120 fprintf (dump_file, " = ");
1121 op2_range.dump (dump_file);
1123 fprintf (dump_file, "\n");
1124 tracer.print (idx, "Computes ");
1125 print_generic_expr (dump_file, op1, TDF_SLIM);
1126 fprintf (dump_file, " = ");
1127 tmp.dump (dump_file);
1128 fprintf (dump_file, " intersect Known range : ");
1129 op1_range.dump (dump_file);
1130 fputc ('\n', dump_file);
1132 // Intersect the calculated result with the known result and return if done.
1133 if (op1 == name)
1135 tmp.intersect (op1_range);
1136 r = tmp;
1137 if (idx)
1138 tracer.trailer (idx, "produces ", true, name, r);
1139 return true;
1141 // If the calculation continues, we're using op1_range as the new LHS.
1142 op1_range.intersect (tmp);
1144 if (idx)
1145 tracer.trailer (idx, "produces ", true, op1, op1_range);
1146 gimple *src_stmt = SSA_NAME_DEF_STMT (op1);
1147 gcc_checking_assert (src_stmt);
1149 // Then feed this range back as the LHS of the defining statement.
1150 return compute_operand_range (r, src_stmt, op1_range, name, src, rel);
1154 // Calculate a range for NAME from the operand 2 position of S
1155 // assuming the result of the statement is LHS. Return the range in
1156 // R, or false if no range could be calculated.
1158 bool
1159 gori_compute::compute_operand2_range (vrange &r,
1160 gimple_range_op_handler &handler,
1161 const vrange &lhs, tree name,
1162 fur_source &src, value_relation *rel)
1164 gimple *stmt = handler.stmt ();
1165 tree op1 = handler.operand1 ();
1166 tree op2 = handler.operand2 ();
1167 tree lhs_name = gimple_get_lhs (stmt);
1169 Value_Range op1_range (TREE_TYPE (op1));
1170 Value_Range op2_range (TREE_TYPE (op2));
1171 Value_Range tmp (TREE_TYPE (op2));
1173 src.get_operand (op1_range, op1);
1174 src.get_operand (op2_range, op2);
1175 relation_kind k = VREL_VARYING;
1176 relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING;
1177 if (rel)
1179 if (lhs_name == rel->op1 () && op2 == rel->op2 ())
1180 k = rel->kind ();
1181 else if (lhs_name == rel->op2 () && op2 == rel->op1 ())
1182 k = relation_swap (rel->kind ());
1183 else if (op1 == rel->op1 () && op2 == rel->op2 ())
1185 op_op = rel->kind ();
1186 refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
1188 else if (op1 == rel->op2 () && op2 == rel->op1 ())
1190 op_op = relation_swap (rel->kind ());
1191 refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
1195 // Intersect with range for op2 based on lhs and op1.
1196 if (!handler.calc_op2 (tmp, lhs, op1_range, relation_trio (k, VREL_VARYING,
1197 op_op)))
1198 return false;
1200 unsigned idx;
1201 if ((idx = tracer.header ("compute op 2 (")))
1203 print_generic_expr (dump_file, op2, TDF_SLIM);
1204 fprintf (dump_file, ") at ");
1205 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1206 tracer.print (idx, "LHS = ");
1207 lhs.dump (dump_file);
1208 if (TREE_CODE (op1) == SSA_NAME)
1210 fprintf (dump_file, ", ");
1211 print_generic_expr (dump_file, op1, TDF_SLIM);
1212 fprintf (dump_file, " = ");
1213 op1_range.dump (dump_file);
1215 fprintf (dump_file, "\n");
1216 tracer.print (idx, "Computes ");
1217 print_generic_expr (dump_file, op2, TDF_SLIM);
1218 fprintf (dump_file, " = ");
1219 tmp.dump (dump_file);
1220 fprintf (dump_file, " intersect Known range : ");
1221 op2_range.dump (dump_file);
1222 fputc ('\n', dump_file);
1224 // Intersect the calculated result with the known result and return if done.
1225 if (op2 == name)
1227 tmp.intersect (op2_range);
1228 r = tmp;
1229 if (idx)
1230 tracer.trailer (idx, " produces ", true, NULL_TREE, r);
1231 return true;
1233 // If the calculation continues, we're using op2_range as the new LHS.
1234 op2_range.intersect (tmp);
1236 if (idx)
1237 tracer.trailer (idx, " produces ", true, op2, op2_range);
1238 gimple *src_stmt = SSA_NAME_DEF_STMT (op2);
1239 gcc_checking_assert (src_stmt);
1240 // gcc_checking_assert (!is_import_p (op2, find.bb));
1242 // Then feed this range back as the LHS of the defining statement.
1243 return compute_operand_range (r, src_stmt, op2_range, name, src, rel);
1246 // Calculate a range for NAME from both operand positions of S
1247 // assuming the result of the statement is LHS. Return the range in
1248 // R, or false if no range could be calculated.
1250 bool
1251 gori_compute::compute_operand1_and_operand2_range (vrange &r,
1252 gimple_range_op_handler
1253 &handler,
1254 const vrange &lhs,
1255 tree name,
1256 fur_source &src,
1257 value_relation *rel)
1259 Value_Range op_range (TREE_TYPE (name));
1261 // Calculate a good a range for op2. Since op1 == op2, this will
1262 // have already included whatever the actual range of name is.
1263 if (!compute_operand2_range (op_range, handler, lhs, name, src, rel))
1264 return false;
1266 // Now get the range thru op1.
1267 if (!compute_operand1_range (r, handler, lhs, name, src, rel))
1268 return false;
1270 // Both operands have to be simultaneously true, so perform an intersection.
1271 r.intersect (op_range);
1272 return true;
1275 // Return TRUE if NAME can be recomputed on any edge exiting BB. If any
1276 // direct dependant is exported, it may also change the computed value of NAME.
1278 bool
1279 gori_compute::may_recompute_p (tree name, basic_block bb)
1281 tree dep1 = depend1 (name);
1282 tree dep2 = depend2 (name);
1284 // If the first dependency is not set, there is no recompuation.
1285 if (!dep1)
1286 return false;
1288 // Don't recalculate PHIs or statements with side_effects.
1289 gimple *s = SSA_NAME_DEF_STMT (name);
1290 if (is_a<gphi *> (s) || gimple_has_side_effects (s))
1291 return false;
1293 // If edge is specified, check if NAME can be recalculated on that edge.
1294 if (bb)
1295 return ((is_export_p (dep1, bb))
1296 || (dep2 && is_export_p (dep2, bb)));
1298 return (is_export_p (dep1)) || (dep2 && is_export_p (dep2));
1301 // Return TRUE if NAME can be recomputed on edge E. If any direct dependant
1302 // is exported on edge E, it may change the computed value of NAME.
1304 bool
1305 gori_compute::may_recompute_p (tree name, edge e)
1307 gcc_checking_assert (e);
1308 return may_recompute_p (name, e->src);
1312 // Return TRUE if a range can be calculated or recomputed for NAME on any
1313 // edge exiting BB.
1315 bool
1316 gori_compute::has_edge_range_p (tree name, basic_block bb)
1318 // Check if NAME is an export or can be recomputed.
1319 if (bb)
1320 return is_export_p (name, bb) || may_recompute_p (name, bb);
1322 // If no block is specified, check for anywhere in the IL.
1323 return is_export_p (name) || may_recompute_p (name);
1326 // Return TRUE if a range can be calculated or recomputed for NAME on edge E.
1328 bool
1329 gori_compute::has_edge_range_p (tree name, edge e)
1331 gcc_checking_assert (e);
1332 return has_edge_range_p (name, e->src);
1335 // Calculate a range on edge E and return it in R. Try to evaluate a
1336 // range for NAME on this edge. Return FALSE if this is either not a
1337 // control edge or NAME is not defined by this edge.
1339 bool
1340 gori_compute::outgoing_edge_range_p (vrange &r, edge e, tree name,
1341 range_query &q)
1343 unsigned idx;
1345 if ((e->flags & m_not_executable_flag))
1347 r.set_undefined ();
1348 if (dump_file && (dump_flags & TDF_DETAILS))
1349 fprintf (dump_file, "Outgoing edge %d->%d unexecutable.\n",
1350 e->src->index, e->dest->index);
1351 return true;
1354 gcc_checking_assert (gimple_range_ssa_p (name));
1355 int_range_max lhs;
1356 // Determine if there is an outgoing edge.
1357 gimple *stmt = outgoing.edge_range_p (lhs, e);
1358 if (!stmt)
1359 return false;
1361 fur_stmt src (stmt, &q);
1362 // If NAME can be calculated on the edge, use that.
1363 if (is_export_p (name, e->src))
1365 bool res;
1366 if ((idx = tracer.header ("outgoing_edge")))
1368 fprintf (dump_file, " for ");
1369 print_generic_expr (dump_file, name, TDF_SLIM);
1370 fprintf (dump_file, " on edge %d->%d\n",
1371 e->src->index, e->dest->index);
1373 if ((res = compute_operand_range (r, stmt, lhs, name, src)))
1375 // Sometimes compatible types get interchanged. See PR97360.
1376 // Make sure we are returning the type of the thing we asked for.
1377 if (!r.undefined_p () && r.type () != TREE_TYPE (name))
1379 gcc_checking_assert (range_compatible_p (r.type (),
1380 TREE_TYPE (name)));
1381 range_cast (r, TREE_TYPE (name));
1384 if (idx)
1385 tracer.trailer (idx, "outgoing_edge", res, name, r);
1386 return res;
1388 // If NAME isn't exported, check if it can be recomputed.
1389 else if (may_recompute_p (name, e))
1391 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
1393 if ((idx = tracer.header ("recomputation")))
1395 fprintf (dump_file, " attempt on edge %d->%d for ",
1396 e->src->index, e->dest->index);
1397 print_gimple_stmt (dump_file, def_stmt, 0, TDF_SLIM);
1399 // Simply calculate DEF_STMT on edge E using the range query Q.
1400 fold_range (r, def_stmt, e, &q);
1401 if (idx)
1402 tracer.trailer (idx, "recomputation", true, name, r);
1403 return true;
1405 return false;
1408 // Given COND ? OP1 : OP2 with ranges R1 for OP1 and R2 for OP2, Use gori
1409 // to further resolve R1 and R2 if there are any dependencies between
1410 // OP1 and COND or OP2 and COND. All values can are to be calculated using SRC
1411 // as the origination source location for operands..
1412 // Effectively, use COND an the edge condition and solve for OP1 on the true
1413 // edge and OP2 on the false edge.
1415 bool
1416 gori_compute::condexpr_adjust (vrange &r1, vrange &r2, gimple *, tree cond,
1417 tree op1, tree op2, fur_source &src)
1419 tree ssa1 = gimple_range_ssa_p (op1);
1420 tree ssa2 = gimple_range_ssa_p (op2);
1421 if (!ssa1 && !ssa2)
1422 return false;
1423 if (TREE_CODE (cond) != SSA_NAME)
1424 return false;
1425 gassign *cond_def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (cond));
1426 if (!cond_def
1427 || TREE_CODE_CLASS (gimple_assign_rhs_code (cond_def)) != tcc_comparison)
1428 return false;
1429 tree type = TREE_TYPE (gimple_assign_rhs1 (cond_def));
1430 if (!range_compatible_p (type, TREE_TYPE (gimple_assign_rhs2 (cond_def))))
1431 return false;
1432 range_op_handler hand (gimple_assign_rhs_code (cond_def), type);
1433 if (!hand)
1434 return false;
1436 tree c1 = gimple_range_ssa_p (gimple_assign_rhs1 (cond_def));
1437 tree c2 = gimple_range_ssa_p (gimple_assign_rhs2 (cond_def));
1439 // Only solve if there is one SSA name in the condition.
1440 if ((!c1 && !c2) || (c1 && c2))
1441 return false;
1443 // Pick up the current values of each part of the condition.
1444 tree rhs1 = gimple_assign_rhs1 (cond_def);
1445 tree rhs2 = gimple_assign_rhs2 (cond_def);
1446 Value_Range cl (TREE_TYPE (rhs1));
1447 Value_Range cr (TREE_TYPE (rhs2));
1448 src.get_operand (cl, rhs1);
1449 src.get_operand (cr, rhs2);
1451 tree cond_name = c1 ? c1 : c2;
1452 gimple *def_stmt = SSA_NAME_DEF_STMT (cond_name);
1454 // Evaluate the value of COND_NAME on the true and false edges, using either
1455 // the op1 or op2 routines based on its location.
1456 Value_Range cond_true (type), cond_false (type);
1457 if (c1)
1459 if (!hand.op1_range (cond_false, type, m_bool_zero, cr))
1460 return false;
1461 if (!hand.op1_range (cond_true, type, m_bool_one, cr))
1462 return false;
1463 cond_false.intersect (cl);
1464 cond_true.intersect (cl);
1466 else
1468 if (!hand.op2_range (cond_false, type, m_bool_zero, cl))
1469 return false;
1470 if (!hand.op2_range (cond_true, type, m_bool_one, cl))
1471 return false;
1472 cond_false.intersect (cr);
1473 cond_true.intersect (cr);
1476 unsigned idx;
1477 if ((idx = tracer.header ("cond_expr evaluation : ")))
1479 fprintf (dump_file, " range1 = ");
1480 r1.dump (dump_file);
1481 fprintf (dump_file, ", range2 = ");
1482 r1.dump (dump_file);
1483 fprintf (dump_file, "\n");
1486 // Now solve for SSA1 or SSA2 if they are in the dependency chain.
1487 if (ssa1 && in_chain_p (ssa1, cond_name))
1489 Value_Range tmp1 (TREE_TYPE (ssa1));
1490 if (compute_operand_range (tmp1, def_stmt, cond_true, ssa1, src))
1491 r1.intersect (tmp1);
1493 if (ssa2 && in_chain_p (ssa2, cond_name))
1495 Value_Range tmp2 (TREE_TYPE (ssa2));
1496 if (compute_operand_range (tmp2, def_stmt, cond_false, ssa2, src))
1497 r2.intersect (tmp2);
1499 if (idx)
1501 tracer.print (idx, "outgoing: range1 = ");
1502 r1.dump (dump_file);
1503 fprintf (dump_file, ", range2 = ");
1504 r1.dump (dump_file);
1505 fprintf (dump_file, "\n");
1506 tracer.trailer (idx, "cond_expr", true, cond_name, cond_true);
1508 return true;
1511 // Dump what is known to GORI computes to listing file F.
1513 void
1514 gori_compute::dump (FILE *f)
1516 gori_map::dump (f);
1519 // ------------------------------------------------------------------------
1520 // GORI iterator. Although we have bitmap iterators, don't expose that it
1521 // is currently a bitmap. Use an export iterator to hide future changes.
1523 // Construct a basic iterator over an export bitmap.
1525 gori_export_iterator::gori_export_iterator (bitmap b)
1527 bm = b;
1528 if (b)
1529 bmp_iter_set_init (&bi, b, 1, &y);
1533 // Move to the next export bitmap spot.
1535 void
1536 gori_export_iterator::next ()
1538 bmp_iter_next (&bi, &y);
1542 // Fetch the name of the next export in the export list. Return NULL if
1543 // iteration is done.
1545 tree
1546 gori_export_iterator::get_name ()
1548 if (!bm)
1549 return NULL_TREE;
1551 while (bmp_iter_set (&bi, &y))
1553 tree t = ssa_name (y);
1554 if (t)
1555 return t;
1556 next ();
1558 return NULL_TREE;