Skip to content

Commit 619b68c

Browse files
committed
8294540: Remove Opaque2Node: it is broken and triggers assert
Reviewed-by: chagedorn, kvn
1 parent 82561de commit 619b68c

11 files changed

+16
-187
lines changed

src/hotspot/share/opto/classes.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ macro(OnSpinWait)
268268
macro(Opaque1)
269269
macro(OpaqueLoopInit)
270270
macro(OpaqueLoopStride)
271-
macro(Opaque2)
272271
macro(Opaque3)
273272
macro(Opaque4)
274273
macro(ProfileBoolean)

src/hotspot/share/opto/compile.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -3161,7 +3161,6 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
31613161
frc.inc_double_count();
31623162
break;
31633163
case Op_Opaque1: // Remove Opaque Nodes before matching
3164-
case Op_Opaque2: // Remove Opaque Nodes before matching
31653164
case Op_Opaque3:
31663165
n->subsume_by(n->in(1), this);
31673166
break;

src/hotspot/share/opto/loopTransform.cpp

+1-30
Original file line numberDiff line numberDiff line change
@@ -2287,18 +2287,7 @@ void PhaseIdealLoop::do_unroll(IdealLoopTree *loop, Node_List &old_new, bool adj
22872287
set_ctrl(new_limit, C->root());
22882288
} else {
22892289
// Limit is not constant.
2290-
if (loop_head->unrolled_count() == 1) { // only for first unroll
2291-
// Separate limit by Opaque node in case it is an incremented
2292-
// variable from previous loop to avoid using pre-incremented
2293-
// value which could increase register pressure.
2294-
// Otherwise reorg_offsets() optimization will create a separate
2295-
// Opaque node for each use of trip-counter and as result
2296-
// zero trip guard limit will be different from loop limit.
2297-
assert(has_ctrl(opaq), "should have it");
2298-
Node* opaq_ctrl = get_ctrl(opaq);
2299-
limit = new Opaque2Node(C, limit);
2300-
register_new_node(limit, opaq_ctrl);
2301-
}
2290+
assert(loop_head->unrolled_count() != 1 || has_ctrl(opaq), "should have opaque for first unroll");
23022291
if ((stride_con > 0 && (java_subtract(limit_type->_lo, stride_con) < limit_type->_lo)) ||
23032292
(stride_con < 0 && (java_subtract(limit_type->_hi, stride_con) > limit_type->_hi))) {
23042293
// No underflow.
@@ -2346,20 +2335,6 @@ void PhaseIdealLoop::do_unroll(IdealLoopTree *loop, Node_List &old_new, bool adj
23462335
new_limit = new CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT);
23472336
}
23482337
register_new_node(new_limit, ctrl);
2349-
if (loop_head->unrolled_count() == 1) {
2350-
// The Opaque2 node created above (in the case of the first unrolling) hides the type of the loop limit.
2351-
// As a result, if the iv Phi constant folds (because it captured the iteration range), the exit test won't
2352-
// constant fold and the graph contains a broken counted loop.
2353-
const Type* new_limit_t;
2354-
if (stride_con > 0) {
2355-
new_limit_t = TypeInt::make(min_jint, limit_type->_hi, limit_type->_widen);
2356-
} else {
2357-
assert(stride_con < 0, "stride can't be 0");
2358-
new_limit_t = TypeInt::make(limit_type->_lo, max_jint, limit_type->_widen);
2359-
}
2360-
new_limit = new CastIINode(new_limit, new_limit_t);
2361-
register_new_node(new_limit, ctrl);
2362-
}
23632338
}
23642339

23652340
assert(new_limit != NULL, "");
@@ -3940,10 +3915,6 @@ bool IdealLoopTree::iteration_split(PhaseIdealLoop* phase, Node_List &old_new) {
39403915
}
39413916
}
39423917

3943-
// Minor offset re-organization to remove loop-fallout uses of
3944-
// trip counter when there was no major reshaping.
3945-
phase->reorg_offsets(this);
3946-
39473918
if (_next && !_next->iteration_split(phase, old_new)) {
39483919
return false;
39493920
}

src/hotspot/share/opto/loopnode.hpp

-6
Original file line numberDiff line numberDiff line change
@@ -1522,12 +1522,6 @@ class PhaseIdealLoop : public PhaseTransform {
15221522
// Attempt to use a conditional move instead of a phi/branch
15231523
Node *conditional_move( Node *n );
15241524

1525-
// Reorganize offset computations to lower register pressure.
1526-
// Mostly prevent loop-fallout uses of the pre-incremented trip counter
1527-
// (which are then alive with the post-incremented trip counter
1528-
// forcing an extra register move)
1529-
void reorg_offsets( IdealLoopTree *loop );
1530-
15311525
// Check for aggressive application of 'split-if' optimization,
15321526
// using basic block level info.
15331527
void split_if_with_blocks ( VectorSet &visited, Node_Stack &nstack);

src/hotspot/share/opto/loopopts.cpp

+1-96
Original file line numberDiff line numberDiff line change
@@ -1023,8 +1023,7 @@ Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) {
10231023
if (n->is_CFG() || n->is_LoadStore()) {
10241024
return n;
10251025
}
1026-
if (n->is_Opaque1() || // Opaque nodes cannot be mod'd
1027-
n_op == Op_Opaque2) {
1026+
if (n->is_Opaque1()) { // Opaque nodes cannot be mod'd
10281027
if (!C->major_progress()) { // If chance of no more loop opts...
10291028
_igvn._worklist.push(n); // maybe we'll remove them
10301029
}
@@ -1426,14 +1425,6 @@ void PhaseIdealLoop::split_if_with_blocks_post(Node *n) {
14261425
try_sink_out_of_loop(n);
14271426

14281427
try_move_store_after_loop(n);
1429-
1430-
// Check for Opaque2's who's loop has disappeared - who's input is in the
1431-
// same loop nest as their output. Remove 'em, they are no longer useful.
1432-
if( n_op == Op_Opaque2 &&
1433-
n->in(1) != NULL &&
1434-
get_loop(get_ctrl(n)) == get_loop(get_ctrl(n->in(1))) ) {
1435-
_igvn.replace_node( n, n->in(1) );
1436-
}
14371428
}
14381429

14391430
// Transform:
@@ -4106,89 +4097,3 @@ bool PhaseIdealLoop::duplicate_loop_backedge(IdealLoopTree *loop, Node_List &old
41064097

41074098
return true;
41084099
}
4109-
4110-
//------------------------------reorg_offsets----------------------------------
4111-
// Reorganize offset computations to lower register pressure. Mostly
4112-
// prevent loop-fallout uses of the pre-incremented trip counter (which are
4113-
// then alive with the post-incremented trip counter forcing an extra
4114-
// register move):
4115-
//
4116-
// iv Phi iv Phi
4117-
// | |
4118-
// | AddI (+stride)
4119-
// | |
4120-
// | Opaque2 # Blocks IGVN from folding these nodes until loop opts are over.
4121-
// | ====> |
4122-
// | AddI (-stride)
4123-
// | |
4124-
// | CastII # Preserve type of iv Phi
4125-
// | |
4126-
// Outside Use Outside Use
4127-
//
4128-
void PhaseIdealLoop::reorg_offsets(IdealLoopTree *loop) {
4129-
// Perform it only for canonical counted loops.
4130-
// Loop's shape could be messed up by iteration_split_impl.
4131-
if (!loop->_head->is_CountedLoop())
4132-
return;
4133-
if (!loop->_head->as_Loop()->is_valid_counted_loop(T_INT))
4134-
return;
4135-
4136-
CountedLoopNode *cl = loop->_head->as_CountedLoop();
4137-
CountedLoopEndNode *cle = cl->loopexit();
4138-
Node *exit = cle->proj_out(false);
4139-
Node *phi = cl->phi();
4140-
4141-
// Check for the special case when using the pre-incremented trip-counter on
4142-
// the fall-out path (forces the pre-incremented and post-incremented trip
4143-
// counter to be live at the same time). Fix this by adjusting to use the
4144-
// post-increment trip counter.
4145-
4146-
bool progress = true;
4147-
while (progress) {
4148-
progress = false;
4149-
for (DUIterator_Fast imax, i = phi->fast_outs(imax); i < imax; i++) {
4150-
Node* use = phi->fast_out(i); // User of trip-counter
4151-
if (!has_ctrl(use)) continue;
4152-
Node *u_ctrl = get_ctrl(use);
4153-
if (use->is_Phi()) {
4154-
u_ctrl = NULL;
4155-
for (uint j = 1; j < use->req(); j++)
4156-
if (use->in(j) == phi)
4157-
u_ctrl = dom_lca(u_ctrl, use->in(0)->in(j));
4158-
}
4159-
IdealLoopTree *u_loop = get_loop(u_ctrl);
4160-
// Look for loop-invariant use
4161-
if (u_loop == loop) continue;
4162-
if (loop->is_member(u_loop)) continue;
4163-
// Check that use is live out the bottom. Assuming the trip-counter
4164-
// update is right at the bottom, uses of of the loop middle are ok.
4165-
if (dom_lca(exit, u_ctrl) != exit) continue;
4166-
// Hit! Refactor use to use the post-incremented tripcounter.
4167-
// Compute a post-increment tripcounter.
4168-
Node* c = exit;
4169-
if (cl->is_strip_mined()) {
4170-
IdealLoopTree* outer_loop = get_loop(cl->outer_loop());
4171-
if (!outer_loop->is_member(u_loop)) {
4172-
c = cl->outer_loop_exit();
4173-
}
4174-
}
4175-
Node *opaq = new Opaque2Node(C, cle->incr());
4176-
register_new_node(opaq, c);
4177-
Node *neg_stride = _igvn.intcon(-cle->stride_con());
4178-
set_ctrl(neg_stride, C->root());
4179-
Node *post = new AddINode(opaq, neg_stride);
4180-
register_new_node(post, c);
4181-
post = new CastIINode(post, phi->bottom_type()); // preserve the iv phi's type
4182-
register_new_node(post, c);
4183-
_igvn.rehash_node_delayed(use);
4184-
for (uint j = 1; j < use->req(); j++) {
4185-
if (use->in(j) == phi)
4186-
use->set_req(j, post);
4187-
}
4188-
// Since DU info changed, rerun loop
4189-
progress = true;
4190-
break;
4191-
}
4192-
}
4193-
4194-
}

src/hotspot/share/opto/macro.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -2371,7 +2371,6 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
23712371
break;
23722372
default:
23732373
assert(n->Opcode() == Op_LoopLimit ||
2374-
n->Opcode() == Op_Opaque2 ||
23752374
n->Opcode() == Op_Opaque3 ||
23762375
n->Opcode() == Op_Opaque4 ||
23772376
BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(n),
@@ -2414,7 +2413,7 @@ bool PhaseMacroExpand::expand_macro_nodes() {
24142413
C->remove_macro_node(n);
24152414
_igvn._worklist.push(n);
24162415
success = true;
2417-
} else if (n->is_Opaque1() || n->Opcode() == Op_Opaque2) {
2416+
} else if (n->is_Opaque1()) {
24182417
_igvn.replace_node(n, n->in(1));
24192418
success = true;
24202419
#if INCLUDE_RTM_OPT

src/hotspot/share/opto/opaquenode.cpp

+4-16
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,8 @@ Node* Opaque1Node::Identity(PhaseGVN* phase) {
4444
return this;
4545
}
4646

47-
//=============================================================================
48-
// A node to prevent unwanted optimizations. Allows constant folding. Stops
49-
// value-numbering, most Ideal calls or Identity functions. This Node is
50-
// specifically designed to prevent the pre-increment value of a loop trip
51-
// counter from being live out of the bottom of the loop (hence causing the
52-
// pre- and post-increment values both being live and thus requiring an extra
53-
// temp register and an extra move). If we "accidentally" optimize through
54-
// this kind of a Node, we'll get slightly pessimal, but correct, code. Thus
55-
// it's OK to be slightly sloppy on optimizations here.
56-
57-
// Do NOT remove the opaque node until no more loop opts can happen. Opaque1
58-
// and Opaque2 nodes are removed together in order to optimize loops away
59-
// before macro expansion.
60-
Node* Opaque2Node::Identity(PhaseGVN* phase) {
47+
// Do NOT remove the opaque node until no more loop opts can happen.
48+
Node* Opaque3Node::Identity(PhaseGVN* phase) {
6149
if (phase->C->post_loop_opts_phase()) {
6250
return in(1);
6351
} else {
@@ -67,8 +55,8 @@ Node* Opaque2Node::Identity(PhaseGVN* phase) {
6755
}
6856

6957
// Do not allow value-numbering
70-
uint Opaque2Node::hash() const { return NO_HASH; }
71-
bool Opaque2Node::cmp( const Node &n ) const {
58+
uint Opaque3Node::hash() const { return NO_HASH; }
59+
bool Opaque3Node::cmp(const Node &n) const {
7260
return (&n == this); // Always fail except on self
7361
}
7462

src/hotspot/share/opto/opaquenode.hpp

+9-24
Original file line numberDiff line numberDiff line change
@@ -70,38 +70,23 @@ class OpaqueLoopStrideNode : public Opaque1Node {
7070
virtual int Opcode() const;
7171
};
7272

73-
//------------------------------Opaque2Node------------------------------------
74-
// A node to prevent unwanted optimizations. Allows constant folding. Stops
75-
// value-numbering, most Ideal calls or Identity functions. This Node is
76-
// specifically designed to prevent the pre-increment value of a loop trip
77-
// counter from being live out of the bottom of the loop (hence causing the
78-
// pre- and post-increment values both being live and thus requiring an extra
79-
// temp register and an extra move). If we "accidentally" optimize through
80-
// this kind of a Node, we'll get slightly pessimal, but correct, code. Thus
81-
// it's OK to be slightly sloppy on optimizations here.
82-
class Opaque2Node : public Node {
83-
virtual uint hash() const ; // { return NO_HASH; }
84-
virtual bool cmp( const Node &n ) const;
73+
//------------------------------Opaque3Node------------------------------------
74+
// A node to prevent unwanted optimizations. Will be optimized only during
75+
// macro nodes expansion.
76+
class Opaque3Node : public Node {
77+
int _opt; // what optimization it was used for
78+
virtual uint hash() const;
79+
virtual bool cmp(const Node &n) const;
8580
public:
86-
Opaque2Node( Compile* C, Node *n ) : Node(0,n) {
81+
enum { RTM_OPT };
82+
Opaque3Node(Compile* C, Node* n, int opt) : Node(0, n), _opt(opt) {
8783
// Put it on the Macro nodes list to removed during macro nodes expansion.
8884
init_flags(Flag_is_macro);
8985
C->add_macro_node(this);
9086
}
9187
virtual int Opcode() const;
9288
virtual const Type* bottom_type() const { return TypeInt::INT; }
9389
virtual Node* Identity(PhaseGVN* phase);
94-
};
95-
96-
//------------------------------Opaque3Node------------------------------------
97-
// A node to prevent unwanted optimizations. Will be optimized only during
98-
// macro nodes expansion.
99-
class Opaque3Node : public Opaque2Node {
100-
int _opt; // what optimization it was used for
101-
public:
102-
enum { RTM_OPT };
103-
Opaque3Node(Compile* C, Node *n, int opt) : Opaque2Node(C, n), _opt(opt) {}
104-
virtual int Opcode() const;
10590
bool rtm_opt() const { return (_opt == RTM_OPT); }
10691
};
10792

src/hotspot/share/opto/phaseX.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -2116,7 +2116,6 @@ Node *PhaseCCP::transform_once( Node *n ) {
21162116
case Op_CountedLoop:
21172117
case Op_Conv2B:
21182118
case Op_Opaque1:
2119-
case Op_Opaque2:
21202119
_worklist.push(n);
21212120
break;
21222121
default:

src/hotspot/share/opto/subnode.cpp

-9
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,6 @@ Node* SubNode::Identity(PhaseGVN* phase) {
6969
if (in(1)->in(1) == in(2)) {
7070
return in(1)->in(2);
7171
}
72-
73-
// Also catch: "(X + Opaque2(Y)) - Y". In this case, 'Y' is a loop-varying
74-
// trip counter and X is likely to be loop-invariant (that's how O2 Nodes
75-
// are originally used, although the optimizer sometimes jiggers things).
76-
// This folding through an O2 removes a loop-exit use of a loop-varying
77-
// value and generally lowers register pressure in and around the loop.
78-
if (in(1)->in(2)->Opcode() == Op_Opaque2 && in(1)->in(2)->in(1) == in(2)) {
79-
return in(1)->in(1);
80-
}
8172
}
8273

8374
return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this;

src/hotspot/share/runtime/vmStructs.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -1570,7 +1570,6 @@
15701570
declare_c2_type(InitializeNode, MemBarNode) \
15711571
declare_c2_type(ThreadLocalNode, Node) \
15721572
declare_c2_type(Opaque1Node, Node) \
1573-
declare_c2_type(Opaque2Node, Node) \
15741573
declare_c2_type(PartialSubtypeCheckNode, Node) \
15751574
declare_c2_type(MoveI2FNode, Node) \
15761575
declare_c2_type(MoveL2DNode, Node) \

0 commit comments

Comments
 (0)