loopnode.hpp revision 3059
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * This code is free software; you can redistribute it and/or modify it
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * under the terms of the GNU General Public License version 2 only, as
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * published by the Free Software Foundation.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * This code is distributed in the hope that it will be useful, but WITHOUT
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * version 2 for more details (a copy is included in the LICENSE file that
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * accompanied this code).
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * You should have received a copy of the GNU General Public License version
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * 2 along with this work; if not, write to the Free Software Foundation,
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * or visit www.oracle.com if you need additional information or have any
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara * questions.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// I D E A L I Z E D L O O P S
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// Idealized loops are the set of loops I perform more interesting
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// transformations on, beyond simple hoisting.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara//------------------------------LoopNode---------------------------------------
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// Simple loop header. Fall in path on left, loop-back path on right.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara // Size is bigger to hold the flags. However, the flags do not change
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara // the semantics so it does not appear in the hash & cmp functions.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara virtual uint size_of() const { return sizeof(*this); }
d34249725651766137db53597def104789089482jvergara // Names for flag bitfields
d34249725651766137db53597def104789089482jvergara enum { Normal=0, Pre=1, Main=2, Post=3, PreMainPostFlagsMask=3,
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara // Names for edge indices
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara int is_inner_loop() const { return _loop_flags & InnerLoop; }
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara void set_inner_loop() { _loop_flags |= InnerLoop; }
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara int is_partial_peel_loop() const { return _loop_flags & PartialPeelLoop; }
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara void set_partial_peel_loop() { _loop_flags |= PartialPeelLoop; }
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara int partial_peel_has_failed() const { return _loop_flags & PartialPeelFailed; }
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; }
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara assert (val <= unswitch_max(), "too many unswitches");
d34249725651766137db53597def104789089482jvergara LoopNode( Node *entry, Node *backedge ) : RegionNode(3), _loop_flags(0), _unswitch_count(0) {
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara virtual int Opcode() const;
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara bool can_be_counted_loop(PhaseTransform* phase) const {
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara in(1) != NULL && phase->type(in(1)) != Type::TOP &&
81436082c2366c10d135c69654ca44b9c1618f7ejvergara//------------------------------Counted Loops----------------------------------
81436082c2366c10d135c69654ca44b9c1618f7ejvergara// Counted loops are all trip-counted loops, with exactly 1 trip-counter exit
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// path (and maybe some other exit paths). The trip-counter exit is always
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// last in the loop. The trip-counter have to stride by a constant;
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// the exit value is also loop invariant.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// CountedLoopNodes and CountedLoopEndNodes come in matched pairs. The
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// CountedLoopNode has the incoming loop control and the loop-back-control
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// which is always the IfTrue before the matching CountedLoopEndNode. The
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// CountedLoopEndNode has an incoming control (possibly not the
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// CountedLoopNode if there is control flow in the loop), the post-increment
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// trip-counter value, and the limit. The trip-counter value is always of
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// the form (Op old-trip-counter stride). The old-trip-counter is produced
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// by a Phi connected to the CountedLoopNode. The stride is constant.
27f8adec83293fb8bd3bfa37175322b0ee3bb933jvergara// The Op is any commutable opcode, including Add, Mul, Xor. The
float _profile_trip_cnt;
int _unrolled_count_log2;
virtual int Opcode() const;
int stride_con() const;
bool stride_is_con() const;
static Node* match_incr_with_optional_truncation(Node* expr, Node** trunc1, Node** trunc2, const TypeInt** trunc_type);
void set_pre_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Pre ; _main_idx = main->_idx; }
void set_post_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Post; _main_idx = main->_idx; }
void set_nonexact_trip_count() {
#ifndef PRODUCT
virtual int Opcode() const;
int stride_con() const;
#ifndef PRODUCT
return NULL;
inline Node *CountedLoopNode::init_trip() const { return loopexit() ? loopexit()->init_trip() : NULL; }
inline int CountedLoopNode::stride_con() const { return loopexit() ? loopexit()->stride_con() : 0; }
inline bool CountedLoopNode::stride_is_con() const { return loopexit() && loopexit()->stride_is_con(); }
C->add_macro_node(this);
virtual int Opcode() const;
_allow_optimizations(true),
void DCE_loop_body();
void record_for_igvn();
#ifndef PRODUCT
friend class IdealLoopTree;
friend class SuperWord;
bool _verify_only;
void allocate_preorders() {
void reallocate_preorders() {
void check_grow_preorders( ) {
void init_dom_lca_tags();
void clear_dom_lca_tags();
return find_non_split_ctrl(n);
return ctrl;
if (has_ctrl(n))
return get_ctrl(n);
if (!n->in(0)) {
} while (!n->in(0));
n = find_non_split_ctrl(n);
return has_node(n);
void build_loop_tree();
void recompute_dom_depth();
_verify_only(true) {
build_and_optimize(false, false);
void Dominators();
_verify_only(false) {
_verify_only(false) {
build_and_optimize(false, false);
#ifdef ASSERT
bool _has_irreducible_loops;
Node *clone_up_backedge_goo( Node *back_ctrl, Node *preheader_ctrl, Node *n, VectorSet &visited, Node_Stack &clones );
bool clone_limit_check,
void collect_potentially_useful_predicates(IdealLoopTree *loop, Unique_Node_List &predicate_opaque1);
void eliminate_useless_predicates();
void add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit );
Node* adjust_limit( int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl );
// Insert phi(lp_entry_val, back_edge_val) at use->in(idx) for loop lp if phi does not already exist
void insert_phi_for_loop( Node* use, uint idx, Node* lp_entry_val, Node* back_edge_val, LoopNode* lp );
#ifdef ASSERT
bool is_valid_loop_partition( IdealLoopTree *loop, VectorSet& peel, Node_List& peel_list, VectorSet& not_peel );
ProjNode* insert_if_before_proj(Node* left, bool Signed, BoolTest::mask relop, Node* right, ProjNode* proj);
void dominated_by( Node *prevdom, Node *iff, bool flip = false, bool exclude_loop_predicate = false );
bool do_intrinsify_fill();
Node *spinup( Node *iff, Node *new_false, Node *new_true, Node *region, Node *phi, small_cache *cache );
Node *find_use_block( Node *use, Node *def, Node *old_false, Node *new_false, Node *old_true, Node *new_true );
void handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true );
bool _created_loop_node;
#ifdef ASSERT
#ifndef PRODUCT
void dump( ) const;
static void print_statistics();
_tail = n;
// IdealLoopTree* lpt = iter.current();