diff options
author | 2017-04-18 09:37:23 -0700 | |
---|---|---|
committer | 2017-05-18 14:14:13 +0000 | |
commit | 79d8fa7c52c1810d4618c9bd1d43994be5abb53d (patch) | |
tree | 411a76dec2adf4139328d5e607b498b72c9aa2af /compiler/optimizing/code_sinking.cc | |
parent | acac09dad3d5aa3922e6cdf54ff2e4fa6f176484 (diff) |
optimizing: Build HConstructorFence for HNewArray/HNewInstance nodes
Also fixes:
* LSE, code_sinking to keep optimizing new-instance if it did so before
* Various tests to expect constructor fences after new-instance
Sidenote: new-instance String does not get a ConstructorFence; the
special StringFactory calls are assumed to be self-fencing.
Metric changes on go/lem:
* CodeSize -0.262% in ART-Compile (ARMv8)
* RunTime -0.747% for all (linux-armv8)
(No changes expected to x86, constructor fences are no-op).
The RunTime regression is temporary until art_quick_alloc_* entrypoints have their
DMBs removed in a follow up CL.
Test: art/test.py
Bug: 36656456
Change-Id: I6a936a6e51c623e1c6b5b22eee5c3c72bebbed35
Diffstat (limited to 'compiler/optimizing/code_sinking.cc')
-rw-r--r-- | compiler/optimizing/code_sinking.cc | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc index 0b4dcd30a1..e598e19b67 100644 --- a/compiler/optimizing/code_sinking.cc +++ b/compiler/optimizing/code_sinking.cc @@ -56,6 +56,17 @@ static bool IsInterestingInstruction(HInstruction* instruction) { return true; } + // Check it is safe to move ConstructorFence. + // (Safe to move ConstructorFence for only protecting the new-instance but not for finals.) + if (instruction->IsConstructorFence()) { + HConstructorFence* ctor_fence = instruction->AsConstructorFence(); + + // A fence with "0" inputs is dead and should've been removed in a prior pass. + DCHECK_NE(0u, ctor_fence->InputCount()); + + return ctor_fence->GetAssociatedAllocation() != nullptr; + } + // All other instructions that can throw cannot be moved. if (instruction->CanThrow()) { return false; @@ -134,11 +145,11 @@ static bool ShouldFilterUse(HInstruction* instruction, HInstruction* user, const ArenaBitVector& post_dominated) { if (instruction->IsNewInstance()) { - return user->IsInstanceFieldSet() && + return (user->IsInstanceFieldSet() || user->IsConstructorFence()) && (user->InputAt(0) == instruction) && !post_dominated.IsBitSet(user->GetBlock()->GetBlockId()); } else if (instruction->IsNewArray()) { - return user->IsArraySet() && + return (user->IsArraySet() || user->IsConstructorFence()) && (user->InputAt(0) == instruction) && !post_dominated.IsBitSet(user->GetBlock()->GetBlockId()); } @@ -372,7 +383,9 @@ void CodeSinking::SinkCodeToUncommonBranch(HBasicBlock* end_block) { // Step (3): Try to move sinking candidates. for (HInstruction* instruction : move_in_order) { HInstruction* position = nullptr; - if (instruction->IsArraySet() || instruction->IsInstanceFieldSet()) { + if (instruction->IsArraySet() + || instruction->IsInstanceFieldSet() + || instruction->IsConstructorFence()) { if (!instructions_that_can_move.IsBitSet(instruction->InputAt(0)->GetId())) { // A store can trivially move, but it can safely do so only if the heap // location it stores to can also move. |