-
Notifications
You must be signed in to change notification settings - Fork 6.3k
8381872: C2: assert before block local scheduling failed with UseCompactObjectHeaders #30762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -338,6 +338,29 @@ bool Peephole::lea_remove_redundant(Block* block, int block_index, PhaseCFG* cfg | |||||
| } | ||||||
|
|
||||||
| // We now have verified that the decode is redundant and can be removed with a peephole. | ||||||
|
|
||||||
| // Before rewiring, check that the new base won't create a register conflict. | ||||||
| // The new base (lea_address) might share a register with a dependant_lea. | ||||||
| // If the dependant_lea overwrites that register and the base is still live | ||||||
| // (used in successor blocks), this creates a conflict detected by verify_good_schedule. | ||||||
| Node* new_base = lea_derived_oop->in(AddPNode::Address); | ||||||
| OptoReg::Name new_base_reg = ra_->get_reg_first(new_base); | ||||||
| if (OptoReg::is_valid(new_base_reg)) { | ||||||
| for (DUIterator_Fast imax, i = decode->fast_outs(imax); i < imax; i++) { | ||||||
| Node* dependant_lea = decode->fast_out(i); | ||||||
| if (dependant_lea->is_Mach() && dependant_lea->as_Mach()->ideal_Opcode() == Op_AddP) { | ||||||
| OptoReg::Name lea_reg = ra_->get_reg_first(dependant_lea); | ||||||
| OptoReg::Name lea_reg2 = ra_->get_reg_second(dependant_lea); | ||||||
| // If the new base register overlaps with any register slot of | ||||||
| // the dependant lea's output, the rewiring would create a conflict | ||||||
| // when the lea overwrites the base pointer's register. | ||||||
| if (new_base_reg == lea_reg || new_base_reg == lea_reg2) { | ||||||
| return false; | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| // Remove the projection | ||||||
| block->find_remove(proj); | ||||||
| cfg_->map_node_to_block(proj, nullptr); | ||||||
|
|
@@ -346,7 +369,7 @@ bool Peephole::lea_remove_redundant(Block* block, int block_index, PhaseCFG* cfg | |||||
| for (DUIterator_Fast imax, i = decode->fast_outs(imax); i < imax; i++) { | ||||||
| Node* dependant_lea = decode->fast_out(i); | ||||||
| if (dependant_lea->is_Mach() && dependant_lea->as_Mach()->ideal_Opcode() == Op_AddP) { | ||||||
| dependant_lea->set_req(AddPNode::Base, lea_derived_oop->in(AddPNode::Address)); | ||||||
| dependant_lea->set_req(AddPNode::Base, new_base); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You are absolutely right, @merykitty. The The following does the trick (inspired by
Suggested change
By not introducing a dependency, there will also not be a conflict. |
||||||
| // This deleted something in the out array, hence adjust i, imax. | ||||||
| --i; | ||||||
| --imax; | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I experimented with this so I could understand it better, and something seems to be off. The above code disables the optimization even if the only dependant_lea is the lone lea_derived_oop, in which case it would seem to be OK because we aren't replacing the base with a "new base".
Also, I tried disabling the above change, and the test below still passes.