summaryrefslogtreecommitdiff
path: root/compiler/optimizing/inliner.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2017-03-23 14:37:26 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2017-03-27 15:14:40 +0100
commit6f8e2c9913b24f746a154dda700f609cee3095f9 (patch)
tree463b5925a1c87ef75ceab807e4c238a3e44a555a /compiler/optimizing/inliner.cc
parent3bd2346db702894ef6c61372e7a83930b1c613ac (diff)
Make data dependency around HDeoptimize correct.
We use HDeoptimize in a few places, but when it comes to data dependency we either: - don't have any (BCE, CHA), in which case we should make sure no code that the deoptimzation guards moves before the HDeoptimize - have one on the receiver (inline cache), in which case we can update the dominated users with the HDeoptimize to get the data dependency correct. bug:35661819 bug:36371709 test: 644-checker-deopt Change-Id: I4820c6710b06939e7f5a59606971693e995fb958
Diffstat (limited to 'compiler/optimizing/inliner.cc')
-rw-r--r--compiler/optimizing/inliner.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 62f5114e59..19f24db3ec 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -646,7 +646,8 @@ void HInliner::AddCHAGuard(HInstruction* invoke_instruction,
HShouldDeoptimizeFlag(graph_->GetArena(), dex_pc);
HInstruction* compare = new (graph_->GetArena()) HNotEqual(
deopt_flag, graph_->GetIntConstant(0, dex_pc));
- HInstruction* deopt = new (graph_->GetArena()) HDeoptimize(compare, dex_pc);
+ HInstruction* deopt = new (graph_->GetArena()) HDeoptimize(
+ graph_->GetArena(), compare, HDeoptimize::Kind::kInline, dex_pc);
if (cursor != nullptr) {
bb_cursor->InsertInstructionAfter(deopt_flag, cursor);
@@ -710,9 +711,16 @@ HInstruction* HInliner::AddTypeGuard(HInstruction* receiver,
bb_cursor->InsertInstructionAfter(compare, load_class);
if (with_deoptimization) {
HDeoptimize* deoptimize = new (graph_->GetArena()) HDeoptimize(
- compare, invoke_instruction->GetDexPc());
+ graph_->GetArena(),
+ compare,
+ receiver,
+ HDeoptimize::Kind::kInline,
+ invoke_instruction->GetDexPc());
bb_cursor->InsertInstructionAfter(deoptimize, compare);
deoptimize->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
+ DCHECK_EQ(invoke_instruction->InputAt(0), receiver);
+ receiver->ReplaceUsesDominatedBy(deoptimize, deoptimize);
+ deoptimize->SetReferenceTypeInfo(receiver->GetReferenceTypeInfo());
}
return compare;
}
@@ -988,13 +996,19 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget(
CreateDiamondPatternForPolymorphicInline(compare, return_replacement, invoke_instruction);
} else {
HDeoptimize* deoptimize = new (graph_->GetArena()) HDeoptimize(
- compare, invoke_instruction->GetDexPc());
+ graph_->GetArena(),
+ compare,
+ receiver,
+ HDeoptimize::Kind::kInline,
+ invoke_instruction->GetDexPc());
bb_cursor->InsertInstructionAfter(deoptimize, compare);
deoptimize->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
if (return_replacement != nullptr) {
invoke_instruction->ReplaceWith(return_replacement);
}
+ receiver->ReplaceUsesDominatedBy(deoptimize, deoptimize);
invoke_instruction->GetBlock()->RemoveInstruction(invoke_instruction);
+ deoptimize->SetReferenceTypeInfo(receiver->GetReferenceTypeInfo());
}
// Run type propagation to get the guard typed.