mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-04 13:10:15 +00:00
8349584: Improve compiler processing
Reviewed-by: rhalade, ahgross, epeter, thartmann
This commit is contained in:
parent
d3429ada8f
commit
a56cd371a2
@ -2851,6 +2851,7 @@ void PhaseCCP::push_more_uses(Unique_Node_List& worklist, Node* parent, const No
|
||||
push_and(worklist, parent, use);
|
||||
push_cast_ii(worklist, parent, use);
|
||||
push_opaque_zero_trip_guard(worklist, use);
|
||||
push_bool_with_cmpu_and_mask(worklist, use);
|
||||
}
|
||||
|
||||
|
||||
@ -2897,6 +2898,57 @@ void PhaseCCP::push_cmpu(Unique_Node_List& worklist, const Node* use) const {
|
||||
}
|
||||
}
|
||||
|
||||
// Look for the following shape, which can be optimized by BoolNode::Value_cmpu_and_mask() (i.e. corresponds to case
|
||||
// (1b): "(m & x) <u (m + 1))".
|
||||
// If any of the inputs on the level (%%) change, we need to revisit Bool because we could have prematurely found that
|
||||
// the Bool is constant (i.e. case (1b) can be applied) which could become invalid with new type information during CCP.
|
||||
//
|
||||
// m x m 1 (%%)
|
||||
// \ / \ /
|
||||
// AndI AddI
|
||||
// \ /
|
||||
// CmpU
|
||||
// |
|
||||
// Bool
|
||||
//
|
||||
void PhaseCCP::push_bool_with_cmpu_and_mask(Unique_Node_List& worklist, const Node* use) const {
|
||||
uint use_op = use->Opcode();
|
||||
if (use_op != Op_AndI && (use_op != Op_AddI || use->in(2)->find_int_con(0) != 1)) {
|
||||
// Not "m & x" or "m + 1"
|
||||
return;
|
||||
}
|
||||
for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) {
|
||||
Node* cmpu = use->fast_out(i);
|
||||
if (cmpu->Opcode() == Op_CmpU) {
|
||||
push_bool_matching_case1b(worklist, cmpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Push any Bool below 'cmpu' that matches case (1b) of BoolNode::Value_cmpu_and_mask().
|
||||
void PhaseCCP::push_bool_matching_case1b(Unique_Node_List& worklist, const Node* cmpu) const {
|
||||
assert(cmpu->Opcode() == Op_CmpU, "must be");
|
||||
for (DUIterator_Fast imax, i = cmpu->fast_outs(imax); i < imax; i++) {
|
||||
Node* bol = cmpu->fast_out(i);
|
||||
if (!bol->is_Bool() || bol->as_Bool()->_test._test != BoolTest::lt) {
|
||||
// Not a Bool with "<u"
|
||||
continue;
|
||||
}
|
||||
Node* andI = cmpu->in(1);
|
||||
Node* addI = cmpu->in(2);
|
||||
if (andI->Opcode() != Op_AndI || addI->Opcode() != Op_AddI || addI->in(2)->find_int_con(0) != 1) {
|
||||
// Not "m & x" and "m + 1"
|
||||
continue;
|
||||
}
|
||||
|
||||
Node* m = addI->in(1);
|
||||
if (m == andI->in(1) || m == andI->in(2)) {
|
||||
// Is "m" shared? Matched (1b) and thus we revisit Bool.
|
||||
push_if_not_bottom_type(worklist, bol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If n is used in a counted loop exit condition, then the type of the counted loop's Phi depends on the type of 'n'.
|
||||
// Seem PhiNode::Value().
|
||||
void PhaseCCP::push_counted_loop_phi(Unique_Node_List& worklist, Node* parent, const Node* use) {
|
||||
|
||||
@ -638,6 +638,8 @@ class PhaseCCP : public PhaseIterGVN {
|
||||
void push_and(Unique_Node_List& worklist, const Node* parent, const Node* use) const;
|
||||
void push_cast_ii(Unique_Node_List& worklist, const Node* parent, const Node* use) const;
|
||||
void push_opaque_zero_trip_guard(Unique_Node_List& worklist, const Node* use) const;
|
||||
void push_bool_with_cmpu_and_mask(Unique_Node_List& worklist, const Node* use) const;
|
||||
void push_bool_matching_case1b(Unique_Node_List& worklist, const Node* cmpu) const;
|
||||
|
||||
public:
|
||||
PhaseCCP( PhaseIterGVN *igvn ); // Compute conditional constants
|
||||
|
||||
@ -1880,7 +1880,7 @@ const Type* BoolNode::Value_cmpu_and_mask(PhaseValues* phase) const {
|
||||
// (1b) "(x & m) <u m + 1" and "(m & x) <u m + 1", cmp2 = m + 1
|
||||
Node* rhs_m = cmp2->in(1);
|
||||
const TypeInt* rhs_m_type = phase->type(rhs_m)->isa_int();
|
||||
if (rhs_m_type->_lo > -1 || rhs_m_type->_hi < -1) {
|
||||
if (rhs_m_type != nullptr && (rhs_m_type->_lo > -1 || rhs_m_type->_hi < -1)) {
|
||||
// Exclude any case where m == -1 is possible.
|
||||
m = rhs_m;
|
||||
}
|
||||
@ -1898,12 +1898,16 @@ const Type* BoolNode::Value_cmpu_and_mask(PhaseValues* phase) const {
|
||||
// Simplify a Bool (convert condition codes to boolean (1 or 0)) node,
|
||||
// based on local information. If the input is constant, do it.
|
||||
const Type* BoolNode::Value(PhaseGVN* phase) const {
|
||||
const Type* input_type = phase->type(in(1));
|
||||
if (input_type == Type::TOP) {
|
||||
return Type::TOP;
|
||||
}
|
||||
const Type* t = Value_cmpu_and_mask(phase);
|
||||
if (t != nullptr) {
|
||||
return t;
|
||||
}
|
||||
|
||||
return _test.cc2logical( phase->type( in(1) ) );
|
||||
return _test.cc2logical(input_type);
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user