mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 12:34:32 +02:00
8136469: OptimizeStringConcat fails on pre-sized StringBuilder shapes
Cut off dead if branch already during parsing (GVN). Reviewed-by: shade, kvn, roland
This commit is contained in:
parent
69b52aa28b
commit
0e1b2cd198
3 changed files with 19 additions and 10 deletions
|
@ -1530,13 +1530,16 @@ Node* IfNode::search_identical(int dist) {
|
||||||
Node* IfProjNode::Identity(PhaseGVN* phase) {
|
Node* IfProjNode::Identity(PhaseGVN* phase) {
|
||||||
// Can only optimize if cannot go the other way
|
// Can only optimize if cannot go the other way
|
||||||
const TypeTuple *t = phase->type(in(0))->is_tuple();
|
const TypeTuple *t = phase->type(in(0))->is_tuple();
|
||||||
if (t == TypeTuple::IFNEITHER ||
|
if (t == TypeTuple::IFNEITHER || (always_taken(t) &&
|
||||||
// kill dead branch first otherwise the IfNode's control will
|
// During parsing (GVN) we don't remove dead code aggressively.
|
||||||
// have 2 control uses (the IfNode that doesn't go away because
|
// Cut off dead branch and let PhaseRemoveUseless take care of it.
|
||||||
// it still has uses and this branch of the
|
(!phase->is_IterGVN() ||
|
||||||
// If). Node::has_special_unique_user() will cause this node to
|
// During IGVN, first wait for the dead branch to be killed.
|
||||||
// be reprocessed once the dead branch is killed.
|
// Otherwise, the IfNode's control will have two control uses (the IfNode
|
||||||
(always_taken(t) && in(0)->outcnt() == 1)) {
|
// that doesn't go away because it still has uses and this branch of the
|
||||||
|
// If) which breaks other optimizations. Node::has_special_unique_user()
|
||||||
|
// will cause this node to be reprocessed once the dead branch is killed.
|
||||||
|
in(0)->outcnt() == 1))) {
|
||||||
// IfNode control
|
// IfNode control
|
||||||
return in(0)->in(0);
|
return in(0)->in(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ void PhaseMacroExpand::eliminate_card_mark(Node* p2x) {
|
||||||
} else {
|
} else {
|
||||||
// G1 pre/post barriers
|
// G1 pre/post barriers
|
||||||
assert(p2x->outcnt() <= 2, "expects 1 or 2 users: Xor and URShift nodes");
|
assert(p2x->outcnt() <= 2, "expects 1 or 2 users: Xor and URShift nodes");
|
||||||
// It could be only one user, URShift node, in Object.clone() instrinsic
|
// It could be only one user, URShift node, in Object.clone() intrinsic
|
||||||
// but the new allocation is passed to arraycopy stub and it could not
|
// but the new allocation is passed to arraycopy stub and it could not
|
||||||
// be scalar replaced. So we don't check the case.
|
// be scalar replaced. So we don't check the case.
|
||||||
|
|
||||||
|
|
|
@ -822,11 +822,10 @@ bool StringConcat::validate_mem_flow() {
|
||||||
}
|
}
|
||||||
} else if (ctrl->is_IfTrue()) { // null checks, class checks
|
} else if (ctrl->is_IfTrue()) { // null checks, class checks
|
||||||
iff = ctrl->in(0)->as_If();
|
iff = ctrl->in(0)->as_If();
|
||||||
assert(iff->is_If(), "must be if");
|
|
||||||
// Verify that the other arm is an uncommon trap
|
// Verify that the other arm is an uncommon trap
|
||||||
Node* otherproj = iff->proj_out(1 - ctrl->as_Proj()->_con);
|
Node* otherproj = iff->proj_out(1 - ctrl->as_Proj()->_con);
|
||||||
CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
|
CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
|
||||||
assert(strcmp(call->_name, "uncommon_trap") == 0, "must be uncommond trap");
|
assert(strcmp(call->_name, "uncommon_trap") == 0, "must be uncommon trap");
|
||||||
ctrl = iff->in(0);
|
ctrl = iff->in(0);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -914,6 +913,13 @@ bool StringConcat::validate_control_flow() {
|
||||||
BoolNode* b = iff->in(1)->isa_Bool();
|
BoolNode* b = iff->in(1)->isa_Bool();
|
||||||
|
|
||||||
if (b == NULL) {
|
if (b == NULL) {
|
||||||
|
#ifndef PRODUCT
|
||||||
|
if (PrintOptimizeStringConcat) {
|
||||||
|
tty->print_cr("unexpected input to IfNode");
|
||||||
|
iff->in(1)->dump();
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
fail = true;
|
fail = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue