1 /* Header file for the value range relational processing.
2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 Contributed by Andrew MacLeod <amacleod@redhat.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
29 #include "gimple-range.h"
30 #include "tree-pretty-print.h"
31 #include "gimple-pretty-print.h"
32 #include "alloc-pool.h"
33 #include "dominance.h"
35 // These VREL codes are arranged such that VREL_NONE is the first
36 // code, and all the rest are contiguous up to and including VREL_LAST.
38 #define VREL_FIRST VREL_NONE
39 #define VREL_LAST NE_EXPR
40 #define VREL_COUNT (VREL_LAST - VREL_FIRST + 1)
42 // vrel_range_assert will either assert that the tree code passed is valid,
43 // or mark invalid codes as unreachable to help with table optimation.
45 #define vrel_range_assert(c) \
46 gcc_checking_assert ((c) >= VREL_FIRST && (c) <= VREL_LAST)
48 #define vrel_range_assert(c) \
49 if ((c) < VREL_FIRST || (c) > VREL_LAST) \
53 static const char *kind_string
[VREL_COUNT
] =
54 { "none", "<", "<=", ">", ">=", "empty", "==", "!=" };
56 // Print a relation_kind REL to file F.
59 print_relation (FILE *f
, relation_kind rel
)
61 vrel_range_assert (rel
);
62 fprintf (f
, " %s ", kind_string
[rel
- VREL_FIRST
]);
65 // This table is used to negate the operands. op1 REL op2 -> !(op1 REL op2).
66 relation_kind rr_negate_table
[VREL_COUNT
] = {
67 // NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR
68 VREL_NONE
, GE_EXPR
, GT_EXPR
, LE_EXPR
, LT_EXPR
, VREL_EMPTY
, NE_EXPR
, EQ_EXPR
};
70 // Negate the relation, as in logical negation.
73 relation_negate (relation_kind r
)
75 vrel_range_assert (r
);
76 return rr_negate_table
[r
- VREL_FIRST
];
79 // This table is used to swap the operands. op1 REL op2 -> op2 REL op1.
80 relation_kind rr_swap_table
[VREL_COUNT
] = {
81 // NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR
82 VREL_NONE
, GT_EXPR
, GE_EXPR
, LT_EXPR
, LE_EXPR
, VREL_EMPTY
, EQ_EXPR
, NE_EXPR
};
84 // Return the relation as if the operands were swapped.
87 relation_swap (relation_kind r
)
89 vrel_range_assert (r
);
90 return rr_swap_table
[r
- VREL_FIRST
];
93 // This table is used to perform an intersection between 2 relations.
95 relation_kind rr_intersect_table
[VREL_COUNT
][VREL_COUNT
] = {
96 // NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR
98 { VREL_NONE
, LT_EXPR
, LE_EXPR
, GT_EXPR
, GE_EXPR
, VREL_EMPTY
, EQ_EXPR
, NE_EXPR
},
100 { LT_EXPR
, LT_EXPR
, LT_EXPR
, VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
, LT_EXPR
},
102 { LE_EXPR
, LT_EXPR
, LE_EXPR
, VREL_EMPTY
, EQ_EXPR
, VREL_EMPTY
, EQ_EXPR
, LT_EXPR
},
104 { GT_EXPR
, VREL_EMPTY
, VREL_EMPTY
, GT_EXPR
, GT_EXPR
, VREL_EMPTY
, VREL_EMPTY
, GT_EXPR
},
106 { GE_EXPR
, VREL_EMPTY
, EQ_EXPR
, GT_EXPR
, GE_EXPR
, VREL_EMPTY
, EQ_EXPR
, GT_EXPR
},
108 { VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
, VREL_EMPTY
},
110 { EQ_EXPR
, VREL_EMPTY
, EQ_EXPR
, VREL_EMPTY
, EQ_EXPR
, VREL_EMPTY
, EQ_EXPR
, VREL_EMPTY
},
112 { NE_EXPR
, LT_EXPR
, LT_EXPR
, GT_EXPR
, GT_EXPR
, VREL_EMPTY
, VREL_EMPTY
, NE_EXPR
} };
115 // Intersect relation R! with relation R2 and return the resulting relation.
118 relation_intersect (relation_kind r1
, relation_kind r2
)
120 vrel_range_assert (r1
);
121 vrel_range_assert (r2
);
122 return rr_intersect_table
[r1
- VREL_FIRST
][r2
- VREL_FIRST
];
126 // This table is used to perform a union between 2 relations.
128 relation_kind rr_union_table
[VREL_COUNT
][VREL_COUNT
] = {
129 // NONE, LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EMPTY, EQ_EXPR, NE_EXPR
131 { VREL_NONE
, VREL_NONE
, VREL_NONE
, VREL_NONE
, VREL_NONE
, VREL_NONE
, VREL_NONE
, VREL_NONE
},
133 { VREL_NONE
, LT_EXPR
, LE_EXPR
, NE_EXPR
, VREL_NONE
, LT_EXPR
, LE_EXPR
, NE_EXPR
},
135 { VREL_NONE
, LE_EXPR
, LE_EXPR
, VREL_NONE
, VREL_NONE
, LE_EXPR
, LE_EXPR
, VREL_NONE
},
137 { VREL_NONE
, NE_EXPR
, VREL_NONE
, GT_EXPR
, GE_EXPR
, GT_EXPR
, GE_EXPR
, NE_EXPR
},
139 { VREL_NONE
, VREL_NONE
, VREL_NONE
, GE_EXPR
, GE_EXPR
, GE_EXPR
, GE_EXPR
, VREL_NONE
},
141 { VREL_NONE
, LT_EXPR
, LE_EXPR
, GT_EXPR
, GE_EXPR
, VREL_EMPTY
, EQ_EXPR
, NE_EXPR
},
143 { VREL_NONE
, LE_EXPR
, LE_EXPR
, GE_EXPR
, GE_EXPR
, EQ_EXPR
, EQ_EXPR
, VREL_NONE
},
145 { VREL_NONE
, NE_EXPR
, VREL_NONE
, NE_EXPR
, VREL_NONE
, NE_EXPR
, VREL_NONE
, NE_EXPR
} };
147 // Union relation R1 with relation R2 and return the result.
150 relation_union (relation_kind r1
, relation_kind r2
)
152 vrel_range_assert (r1
);
153 vrel_range_assert (r2
);
154 return rr_union_table
[r1
- VREL_FIRST
][r2
- VREL_FIRST
];
158 // -------------------------------------------------------------------------
160 // This class represents an equivalency set, and contains a link to the next
161 // one in the list to be searched.
163 // The very first element in the m_equiv chain is actually just a summary
164 // element in which the m_names bitmap is used to indicate that an ssa_name
165 // has an equivalence set in this block.
166 // This allows for much faster traversal of the DOM chain, as a search for
167 // SSA_NAME simply requires walking the DOM chain until a block is found
168 // which has the bit for SSA_NAME set. Then scan for the equivalency set in
169 // that block. No previous blcoks need be searched.
174 bitmap m_names
; // ssa-names in equiv set.
175 basic_block m_bb
; // Block this belongs to
176 equiv_chain
*m_next
; // Next in block list.
177 void dump (FILE *f
) const; // Show names in this list.
181 // Dump the names in this equivalence set.
184 equiv_chain::dump (FILE *f
) const
191 fprintf (f
, "Equivalence set : [");
193 EXECUTE_IF_SET_IN_BITMAP (m_names
, 0, i
, bi
)
199 print_generic_expr (f
, ssa_name (i
), TDF_SLIM
);
205 // Instantiate an equivalency oracle.
207 equiv_oracle::equiv_oracle ()
209 bitmap_obstack_initialize (&m_bitmaps
);
211 m_equiv
.safe_grow_cleared (last_basic_block_for_fn (cfun
) + 1);
212 m_equiv_set
= BITMAP_ALLOC (&m_bitmaps
);
213 obstack_init (&m_chain_obstack
);
216 // Destruct an equivalency oracle.
218 equiv_oracle::~equiv_oracle ()
220 obstack_free (&m_chain_obstack
, NULL
);
222 bitmap_obstack_release (&m_bitmaps
);
225 // Find and return the equivalency set for SSA along the dominators of BB.
226 // This is the external API.
229 equiv_oracle::equiv_set (tree ssa
, basic_block bb
) const
231 // Search the dominator tree for an equivalency.
232 equiv_chain
*equiv
= find_equiv_dom (ssa
, bb
);
234 return equiv
->m_names
;
240 // If SSA has an equivalence in block BB, find and return it.
241 // Otherwise return NULL.
244 equiv_oracle::find_equiv_block (unsigned ssa
, int bb
) const
246 equiv_chain
*ptr
= NULL
;
247 if (bb
>= (int)m_equiv
.length ())
250 // If there are equiv sets and SSA is in one in this block, find it.
251 // Otherwise return NULL.
252 if (m_equiv
[bb
] && bitmap_bit_p (m_equiv
[bb
]->m_names
, ssa
))
254 for (ptr
= m_equiv
[bb
]->m_next
; ptr
; ptr
= ptr
->m_next
)
255 if (bitmap_bit_p (ptr
->m_names
, ssa
))
261 // Starting at block BB, walk the dominator chain looking for the nearest
262 // equivalence set containing NAME.
265 equiv_oracle::find_equiv_dom (tree name
, basic_block bb
) const
267 unsigned v
= SSA_NAME_VERSION (name
);
268 // Short circuit looking for names which have no equivalences.
269 // Saves time looking for something which does not exist.
270 if (!bitmap_bit_p (m_equiv_set
, v
))
273 // NAME has at least once equivalence set, check to see if it has one along
274 // the dominator tree.
275 for ( ; bb
; bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
))
277 equiv_chain
*ptr
= find_equiv_block (v
, bb
->index
);
284 // Register equivalance between ssa_name V and set EQUIV in block BB,
287 equiv_oracle::register_equiv (basic_block bb
, unsigned v
, equiv_chain
*equiv
)
289 // V will have an equivalency now.
290 bitmap_set_bit (m_equiv_set
, v
);
292 // If that equiv chain is in this block, simply use it.
293 if (equiv
->m_bb
== bb
)
295 bitmap_set_bit (equiv
->m_names
, v
);
296 bitmap_set_bit (m_equiv
[bb
->index
]->m_names
, v
);
300 // Otherwise create an equivalence for this block which is a copy
301 // of equiv, the add V to the set.
302 bitmap b
= BITMAP_ALLOC (&m_bitmaps
);
303 bitmap_copy (b
, equiv
->m_names
);
304 bitmap_set_bit (b
, v
);
308 // Register equivalence between set equiv_1 and equiv_2 in block BB.
309 // Return NULL if either name can be merged with the other. Otherwise
310 // return a pointer to the combined bitmap of names. This allows the
311 // caller to do any setup required for a new element.
314 equiv_oracle::register_equiv (basic_block bb
, equiv_chain
*equiv_1
,
315 equiv_chain
*equiv_2
)
317 // If equiv_1 is alreayd in BB, use it as the combined set.
318 if (equiv_1
->m_bb
== bb
)
320 bitmap_ior_into (equiv_1
->m_names
, equiv_2
->m_names
);
321 // Its hard to delete from a single linked list, so
322 // just clear the second one.
323 if (equiv_2
->m_bb
== bb
)
324 bitmap_clear (equiv_2
->m_names
);
326 // Ensure equiv_2s names are in the summary for BB.
327 bitmap_ior_into (m_equiv
[bb
->index
]->m_names
, equiv_2
->m_names
);
330 // If equiv_2 is in BB, use it for the combined set.
331 if (equiv_2
->m_bb
== bb
)
333 bitmap_ior_into (equiv_2
->m_names
, equiv_1
->m_names
);
334 // Add equiv_1 names into the summary.
335 bitmap_ior_into (m_equiv
[bb
->index
]->m_names
, equiv_1
->m_names
);
339 // At this point, neither equivalence is from this block.
340 bitmap b
= BITMAP_ALLOC (&m_bitmaps
);
341 bitmap_copy (b
, equiv_1
->m_names
);
342 bitmap_ior_into (b
, equiv_2
->m_names
);
347 // Register an equivalence between SSA1 and SSA2 in block BB.
348 // The equivalence oracle maintains a vector of equivalencies indexed by basic
349 // block. When an equivalence bteween SSA1 and SSA2 is registered in block BB,
350 // a query is made as to what equivalences both names have already, and
351 // any preexisting equivalences are merged to create a single equivalence
352 // containing all the ssa_names in this basic block.
355 equiv_oracle::register_equiv (basic_block bb
, tree ssa1
, tree ssa2
)
357 unsigned v1
= SSA_NAME_VERSION (ssa1
);
358 unsigned v2
= SSA_NAME_VERSION (ssa2
);
359 equiv_chain
*equiv_1
= find_equiv_dom (ssa1
, bb
);
360 equiv_chain
*equiv_2
= find_equiv_dom (ssa2
, bb
);
362 // Check if they are the same set
363 if (equiv_1
&& equiv_1
== equiv_2
)
368 // Case where we have 2 SSA_NAMEs that are not in any set.
369 if (!equiv_1
&& !equiv_2
)
371 bitmap_set_bit (m_equiv_set
, v1
);
372 bitmap_set_bit (m_equiv_set
, v2
);
374 equiv_set
= BITMAP_ALLOC (&m_bitmaps
);
375 bitmap_set_bit (equiv_set
, v1
);
376 bitmap_set_bit (equiv_set
, v2
);
378 else if (!equiv_1
&& equiv_2
)
379 equiv_set
= register_equiv (bb
, v1
, equiv_2
);
380 else if (equiv_1
&& !equiv_2
)
381 equiv_set
= register_equiv (bb
, v2
, equiv_1
);
383 equiv_set
= register_equiv (bb
, equiv_1
, equiv_2
);
385 // A non-null return is a bitmap that is to be added to the current
386 // block as a new equivalence.
392 // Check if this is the first time a block has an equivalence added.
393 // and create a header block. And set the summary for this block.
394 if (!m_equiv
[bb
->index
])
396 ptr
= (equiv_chain
*) obstack_alloc (&m_chain_obstack
,
397 sizeof (equiv_chain
));
398 ptr
->m_names
= BITMAP_ALLOC (&m_bitmaps
);
399 bitmap_copy (ptr
->m_names
, equiv_set
);
402 m_equiv
[bb
->index
] = ptr
;
405 // Now create the element for this equiv set and initialize it.
406 ptr
= (equiv_chain
*) obstack_alloc (&m_chain_obstack
, sizeof (equiv_chain
));
407 ptr
->m_names
= equiv_set
;
409 gcc_checking_assert (bb
->index
< (int)m_equiv
.length ());
410 ptr
->m_next
= m_equiv
[bb
->index
]->m_next
;
411 m_equiv
[bb
->index
]->m_next
= ptr
;
412 bitmap_ior_into (m_equiv
[bb
->index
]->m_names
, equiv_set
);
415 // Make sure the BB vector is big enough and grow it if needed.
418 equiv_oracle::limit_check (basic_block bb
)
420 int i
= (bb
) ? bb
->index
: last_basic_block_for_fn (cfun
);
421 if (i
>= (int)m_equiv
.length ())
422 m_equiv
.safe_grow_cleared (last_basic_block_for_fn (cfun
) + 1);
425 // Dump the equivalence sets in BB to file F.
428 equiv_oracle::dump (FILE *f
, basic_block bb
) const
430 if (bb
->index
>= (int)m_equiv
.length ())
432 if (!m_equiv
[bb
->index
])
435 equiv_chain
*ptr
= m_equiv
[bb
->index
]->m_next
;
436 for (; ptr
; ptr
= ptr
->m_next
)
440 // Dump all equivalence sets known to the oracle.
443 equiv_oracle::dump (FILE *f
) const
445 fprintf (f
, "Equivalency dump\n");
446 for (unsigned i
= 0; i
< m_equiv
.length (); i
++)
447 if (m_equiv
[i
] && BASIC_BLOCK_FOR_FN (cfun
, i
))
449 fprintf (f
, "BB%d\n", i
);
450 dump (f
, BASIC_BLOCK_FOR_FN (cfun
, i
));
455 // --------------------------------------------------------------------------
457 // The value-relation class is used to encapsulate the represention of an
458 // individual relation between 2 ssa-names, and to facilitate operating on
465 value_relation (relation_kind kind
, tree n1
, tree n2
);
466 void set_relation (relation_kind kind
, tree n1
, tree n2
);
468 inline relation_kind
kind () const { return related
; }
469 inline tree
op1 () const { return name1
; }
470 inline tree
op2 () const { return name2
; }
472 bool union_ (value_relation
&p
);
473 bool intersect (value_relation
&p
);
477 void dump (FILE *f
) const;
479 relation_kind related
;
483 // Set relation R between ssa_name N1 and N2.
486 value_relation::set_relation (relation_kind r
, tree n1
, tree n2
)
488 gcc_checking_assert (SSA_NAME_VERSION (n1
) != SSA_NAME_VERSION (n2
));
494 // Default constructor.
497 value_relation::value_relation ()
504 // Constructor for relation R between SSA version N1 nd N2.
507 value_relation::value_relation (relation_kind kind
, tree n1
, tree n2
)
509 set_relation (kind
, n1
, n2
);
512 // Negate the current relation.
515 value_relation::negate ()
517 related
= relation_negate (related
);
520 // Modify the relation as if the operands were being swapped.
523 value_relation::swap ()
525 related
= relation_swap (related
);
528 // Perform an intersection between 2 relations. *this &&= p.
531 value_relation::intersect (value_relation
&p
)
533 // Save previous value
534 relation_kind old
= related
;
536 if (p
.op1 () == op1 () && p
.op2 () == op2 ())
537 related
= relation_intersect (kind (), p
.kind ());
538 else if (p
.op2 () == op1 () && p
.op1 () == op2 ())
539 related
= relation_intersect (kind (), relation_swap (p
.kind ()));
543 return old
!= related
;
546 // Perform a union between 2 relations. *this ||= p.
549 value_relation::union_ (value_relation
&p
)
551 // Save previous value
552 relation_kind old
= related
;
554 if (p
.op1 () == op1 () && p
.op2 () == op2 ())
555 related
= relation_union (kind(), p
.kind());
556 else if (p
.op2 () == op1 () && p
.op1 () == op2 ())
557 related
= relation_union (kind(), relation_swap (p
.kind ()));
561 return old
!= related
;
565 // Dump the relation to file F.
568 value_relation::dump (FILE *f
) const
570 if (!name1
|| !name2
)
572 fprintf (f
, "uninitialized");
576 print_generic_expr (f
, op1 (), TDF_SLIM
);
577 print_relation (f
, kind ());
578 print_generic_expr (f
, op2 (), TDF_SLIM
);
582 // This container is used to link relations in a chain.
584 class relation_chain
: public value_relation
587 relation_chain
*m_next
;
590 // ------------------------------------------------------------------------
592 // Instantiate a relation oracle.
594 relation_oracle::relation_oracle ()
596 m_relations
.create (0);
597 m_relations
.safe_grow_cleared (last_basic_block_for_fn (cfun
) + 1);
598 m_relation_set
= BITMAP_ALLOC (&m_bitmaps
);
599 m_tmp
= BITMAP_ALLOC (&m_bitmaps
);
602 // Destruct a relation oracle.
604 relation_oracle::~relation_oracle ()
606 m_relations
.release ();
609 // Register relation K between ssa_name OP1 and OP2 on STMT.
612 relation_oracle::register_relation (gimple
*stmt
, relation_kind k
, tree op1
,
615 gcc_checking_assert (TREE_CODE (op1
) == SSA_NAME
);
616 gcc_checking_assert (TREE_CODE (op2
) == SSA_NAME
);
617 gcc_checking_assert (stmt
&& gimple_bb (stmt
));
619 // Don't register lack of a relation.
623 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
625 value_relation
vr (k
, op1
, op2
);
626 fprintf (dump_file
, " Registering value_relation ");
628 fprintf (dump_file
, " (bb%d) at ", gimple_bb (stmt
)->index
);
629 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
632 // This relation applies to the entire block, use STMT's block.
633 // Equivalencies are handled by the equivalence oracle.
635 register_equiv (gimple_bb (stmt
), op1
, op2
);
637 register_relation (gimple_bb (stmt
), k
, op1
, op2
);
640 // Register relation K between ssa_name OP1 and OP2 on edge E.
643 relation_oracle::register_relation (edge e
, relation_kind k
, tree op1
,
646 gcc_checking_assert (TREE_CODE (op1
) == SSA_NAME
);
647 gcc_checking_assert (TREE_CODE (op2
) == SSA_NAME
);
649 // Do not register lack of relation, or blocks which have more than
650 // edge E for a predecessor.
651 if (k
== VREL_NONE
|| !single_pred_p (e
->dest
))
654 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
656 value_relation
vr (k
, op1
, op2
);
657 fprintf (dump_file
, " Registering value_relation ");
659 fprintf (dump_file
, " on (%d->%d)\n", e
->src
->index
, e
->dest
->index
);
662 // Equivalencies are handled by the equivalence oracle.
664 register_equiv (e
->dest
, op1
, op2
);
666 register_relation (e
->dest
, k
, op1
, op2
);
669 // Register relation K between OP! and OP2 in block BB.
670 // This creates the record and searches for existing records in the dominator
671 // tree to merge with.
674 relation_oracle::register_relation (basic_block bb
, relation_kind k
, tree op1
,
677 gcc_checking_assert (k
!= VREL_NONE
);
679 value_relation
vr(k
, op1
, op2
);
682 if (bbi
>= (int)m_relations
.length())
683 m_relations
.safe_grow_cleared (last_basic_block_for_fn (cfun
) + 1);
685 // Summary bitmap indicating what ssa_names have relations in this BB.
686 bitmap bm
= m_relations
[bbi
].m_names
;
688 bm
= m_relations
[bbi
].m_names
= BITMAP_ALLOC (&m_bitmaps
);
689 unsigned v1
= SSA_NAME_VERSION (op1
);
690 unsigned v2
= SSA_NAME_VERSION (op2
);
694 curr
= find_relation_block (bbi
, v1
, v2
, &ptr
);
695 // There is an existing relation in this block, just intersect with it.
696 if (curr
!= VREL_NONE
)
698 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
700 fprintf (dump_file
, " Intersecting with existing ");
701 ptr
->dump (dump_file
);
703 // Check into whether we can simply replace the relation rather than
704 // intersecting it. THis may help with some optimistic iterative
705 // updating algorithms.
707 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
709 fprintf (dump_file
, " to produce ");
710 ptr
->dump (dump_file
);
711 fprintf (dump_file
, "\n");
716 // Check for an existing relation further up the DOM chain.
717 // By including dominating relations, The first one found in any search
718 // will be the aggregate of all the previous ones.
719 curr
= find_relation_dom (bb
, v1
, v2
);
720 if (curr
!= VREL_NONE
)
721 k
= relation_intersect (curr
, k
);
723 bitmap_set_bit (bm
, v1
);
724 bitmap_set_bit (bm
, v2
);
725 bitmap_set_bit (m_relation_set
, v1
);
726 bitmap_set_bit (m_relation_set
, v2
);
728 ptr
= (relation_chain
*) obstack_alloc (&m_chain_obstack
,
729 sizeof (relation_chain
));
730 ptr
->set_relation (k
, op1
, op2
);
731 ptr
->m_next
= m_relations
[bbi
].m_head
;
732 m_relations
[bbi
].m_head
= ptr
;;
735 // Find the relation between any ssa_name in B1 and any name in B2 in block BB.
736 // This will allow equivalencies to be applied to any SSA_NAME in a relation.
739 relation_oracle::find_relation_block (unsigned bb
, const_bitmap b1
,
743 if (bb
>= m_relations
.length())
746 bm
= m_relations
[bb
].m_names
;
750 // If both b1 and b2 aren't referenced in thie block, cant be a relation
751 if (!bitmap_intersect_p (bm
, b1
) || !bitmap_intersect_p (bm
, b2
))
754 // Search for the fiorst relation that contains BOTH an element from B1
755 // and B2, and return that relation.
756 for (relation_chain
*ptr
= m_relations
[bb
].m_head
; ptr
; ptr
= ptr
->m_next
)
758 unsigned op1
= SSA_NAME_VERSION (ptr
->op1 ());
759 unsigned op2
= SSA_NAME_VERSION (ptr
->op2 ());
760 if (bitmap_bit_p (b1
, op1
) && bitmap_bit_p (b2
, op2
))
762 if (bitmap_bit_p (b1
, op2
) && bitmap_bit_p (b2
, op1
))
763 return relation_swap (ptr
->kind ());
769 // Search the DOM tree for a relation between an element of B1 and B2, starting
773 relation_oracle::find_relation_dom (basic_block bb
, const_bitmap b1
,
777 // If either name does not occur in a relation anywhere, there isnt one.
778 if (!bitmap_intersect_p (m_relation_set
, b1
)
779 || !bitmap_intersect_p (m_relation_set
, b2
))
782 // Search each block in the DOM tree checking.
783 for ( ; bb
; bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
))
785 r
= find_relation_block (bb
->index
, b1
, b2
);
793 // Find a relation in block BB between ssa version V1 and V2. If a relation
794 // is found, return a pointer to the chain object in OBJ.
797 relation_oracle::find_relation_block (int bb
, unsigned v1
, unsigned v2
,
798 relation_chain
**obj
)
800 if (bb
>= (int)m_relations
.length())
803 const_bitmap bm
= m_relations
[bb
].m_names
;
807 // If both b1 and b2 aren't referenced in thie block, cant be a relation
808 if (!bitmap_bit_p (bm
, v1
) || !bitmap_bit_p (bm
, v2
))
812 for (ptr
= m_relations
[bb
].m_head
; ptr
; ptr
= ptr
->m_next
)
814 unsigned op1
= SSA_NAME_VERSION (ptr
->op1 ());
815 unsigned op2
= SSA_NAME_VERSION (ptr
->op2 ());
816 if (v1
== op1
&& v2
== op2
)
822 if (v1
== op2
&& v2
== op1
)
826 return relation_swap (ptr
->kind ());
833 // Find a relation between SSA version V1 and V2 in the dominator tree
834 // starting with block BB
837 relation_oracle::find_relation_dom (basic_block bb
, unsigned v1
, unsigned v2
)
840 // IF either name does not occur in a relation anywhere, there isnt one.
841 if (!bitmap_bit_p (m_relation_set
, v1
) || !bitmap_bit_p (m_relation_set
, v2
))
844 for ( ; bb
; bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
))
846 r
= find_relation_block (bb
->index
, v1
, v2
);
854 // Query if there is a relation between SSA1 and SS2 in block BB or a
858 relation_oracle::query_relation (basic_block bb
, tree ssa1
, tree ssa2
)
861 unsigned v1
= SSA_NAME_VERSION (ssa1
);
862 unsigned v2
= SSA_NAME_VERSION (ssa2
);
866 // Check for equivalence first.
867 const_bitmap equiv1
= equiv_set (ssa1
, bb
);
868 if (equiv1
&& bitmap_bit_p (equiv1
, v2
))
871 // Initially look for a direct relationship and just return that.
872 kind
= find_relation_dom (bb
, v1
, v2
);
873 if (kind
!= VREL_NONE
)
876 // If v2 isn't in v1s equiv set, then v1 shouldn't be in v2's set either.
877 // It is possible for out-of-order dominator processing to have an out of
878 // sync set of equivalences.. Down the road, when we do full updates,
879 // change this to an assert to ensure everything is in sync.
880 const_bitmap equiv2
= equiv_set (ssa2
, bb
);
881 if (equiv2
&& bitmap_bit_p (equiv2
, v1
))
884 // If not equal, see if there is a relationship between equivalences.
885 if (!equiv1
&& !equiv2
)
889 bitmap_clear (m_tmp
);
890 bitmap_set_bit (m_tmp
, v1
);
891 kind
= find_relation_dom (bb
, m_tmp
, equiv2
);
895 bitmap_clear (m_tmp
);
896 bitmap_set_bit (m_tmp
, v2
);
897 kind
= find_relation_dom (bb
, equiv1
, m_tmp
);
900 kind
= find_relation_dom (bb
, equiv1
, equiv2
);
904 // Dump all the relations in block BB to file F.
907 relation_oracle::dump (FILE *f
, basic_block bb
) const
909 equiv_oracle::dump (f
,bb
);
911 if (bb
->index
>= (int)m_relations
.length ())
913 if (!m_relations
[bb
->index
].m_names
)
916 relation_chain
*ptr
= m_relations
[bb
->index
].m_head
;
917 for (; ptr
; ptr
= ptr
->m_next
)
919 fprintf (f
, "Relational : ");
925 // Dump all the relations known to file F.
928 relation_oracle::dump (FILE *f
) const
930 fprintf (f
, "Relation dump\n");
931 for (unsigned i
= 0; i
< m_relations
.length (); i
++)
932 if (BASIC_BLOCK_FOR_FN (cfun
, i
))
934 fprintf (f
, "BB%d\n", i
);
935 dump (f
, BASIC_BLOCK_FOR_FN (cfun
, i
));