summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_arm.cc4
-rw-r--r--compiler/optimizing/code_generator_x86.cc4
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc4
-rw-r--r--compiler/optimizing/dead_code_elimination.cc7
-rw-r--r--compiler/optimizing/register_allocator.cc4
-rw-r--r--compiler/optimizing/register_allocator_test.cc7
-rw-r--r--compiler/optimizing/ssa_liveness_analysis.cc5
-rw-r--r--compiler/optimizing/ssa_liveness_analysis.h1
-rw-r--r--compiler/optimizing/stack_map_test.cc4
9 files changed, 28 insertions, 12 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 7f0be05732..987a6c4ff7 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -55,7 +55,7 @@ static constexpr SRegister kFpuCalleeSaves[] =
// S registers. Therefore there is no need to block it.
static constexpr DRegister DTMP = D31;
-#define __ reinterpret_cast<ArmAssembler*>(codegen->GetAssembler())->
+#define __ down_cast<ArmAssembler*>(codegen->GetAssembler())->
#define QUICK_ENTRY_POINT(x) QUICK_ENTRYPOINT_OFFSET(kArmWordSize, x).Int32Value()
class NullCheckSlowPathARM : public SlowPathCodeARM {
@@ -318,7 +318,7 @@ class DeoptimizationSlowPathARM : public SlowPathCodeARM {
#undef __
#undef __
-#define __ reinterpret_cast<ArmAssembler*>(GetAssembler())->
+#define __ down_cast<ArmAssembler*>(GetAssembler())->
inline Condition ARMCondition(IfCondition cond) {
switch (cond) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 8678428bf3..f63a5d20c0 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -44,7 +44,7 @@ static constexpr int kC2ConditionMask = 0x400;
static constexpr int kFakeReturnRegister = Register(8);
-#define __ reinterpret_cast<X86Assembler*>(codegen->GetAssembler())->
+#define __ down_cast<X86Assembler*>(codegen->GetAssembler())->
class NullCheckSlowPathX86 : public SlowPathCodeX86 {
public:
@@ -324,7 +324,7 @@ class DeoptimizationSlowPathX86 : public SlowPathCodeX86 {
};
#undef __
-#define __ reinterpret_cast<X86Assembler*>(GetAssembler())->
+#define __ down_cast<X86Assembler*>(GetAssembler())->
inline Condition X86Condition(IfCondition cond) {
switch (cond) {
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 78d585115a..ca9a154717 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -46,7 +46,7 @@ static constexpr FloatRegister kFpuCalleeSaves[] = { XMM12, XMM13, XMM14, XMM15
static constexpr int kC2ConditionMask = 0x400;
-#define __ reinterpret_cast<X86_64Assembler*>(codegen->GetAssembler())->
+#define __ down_cast<X86_64Assembler*>(codegen->GetAssembler())->
class NullCheckSlowPathX86_64 : public SlowPathCodeX86_64 {
public:
@@ -343,7 +343,7 @@ class DeoptimizationSlowPathX86_64 : public SlowPathCodeX86_64 {
};
#undef __
-#define __ reinterpret_cast<X86_64Assembler*>(GetAssembler())->
+#define __ down_cast<X86_64Assembler*>(GetAssembler())->
inline Condition X86_64Condition(IfCondition cond) {
switch (cond) {
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index b31de98e25..17a006cc3a 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -122,7 +122,12 @@ void HDeadCodeElimination::RemoveDeadInstructions() {
if (!inst->HasSideEffects()
&& !inst->CanThrow()
&& !inst->IsSuspendCheck()
- && !inst->IsMemoryBarrier() // If we added an explicit barrier then we should keep it.
+ // The current method needs to stay in the graph in case of inlining.
+ // It is always passed anyway, and keeping it in the graph does not
+ // affect the generated code.
+ && !inst->IsCurrentMethod()
+ // If we added an explicit barrier then we should keep it.
+ && !inst->IsMemoryBarrier()
&& !inst->HasUses()) {
block->RemoveInstruction(inst);
MaybeRecordStat(MethodCompilationStat::kRemovedDeadInstruction);
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc
index 5e784d7312..a381315bac 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -802,9 +802,9 @@ bool RegisterAllocator::TryAllocateFreeReg(LiveInterval* current) {
current->SetRegister(reg);
if (!current->IsDeadAt(free_until[reg])) {
// If the register is only available for a subset of live ranges
- // covered by `current`, split `current` at the position where
+ // covered by `current`, split `current` before the position where
// the register is not available anymore.
- LiveInterval* split = Split(current, free_until[reg]);
+ LiveInterval* split = SplitBetween(current, current->GetStart(), free_until[reg]);
DCHECK(split != nullptr);
AddSorted(unhandled_, split);
}
diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc
index d07a14a3e6..b7da36299d 100644
--- a/compiler/optimizing/register_allocator_test.cc
+++ b/compiler/optimizing/register_allocator_test.cc
@@ -426,6 +426,13 @@ TEST(RegisterAllocatorTest, FreeUntil) {
// Add an artifical range to cover the temps that will be put in the unhandled list.
LiveInterval* unhandled = graph->GetEntryBlock()->GetFirstInstruction()->GetLiveInterval();
unhandled->AddLoopRange(0, 60);
+
+ // Populate the instructions in the liveness object, to please the register allocator.
+ for (size_t i = 0; i < 60; ++i) {
+ liveness.instructions_from_lifetime_position_.Add(
+ graph->GetEntryBlock()->GetFirstInstruction());
+ }
+
// For SSA value intervals, only an interval resulted from a split may intersect
// with inactive intervals.
unhandled = register_allocator.Split(unhandled, 5);
diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc
index 250eb04a1c..d5f977feec 100644
--- a/compiler/optimizing/ssa_liveness_analysis.cc
+++ b/compiler/optimizing/ssa_liveness_analysis.cc
@@ -341,6 +341,7 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until,
// starts at. If one location is a register we return it as a hint. This
// will avoid a move between the two blocks.
HBasicBlock* block = liveness.GetBlockFromPosition(GetStart() / 2);
+ size_t next_register_use = FirstRegisterUse();
for (size_t i = 0; i < block->GetPredecessors().Size(); ++i) {
size_t position = block->GetPredecessors().Get(i)->GetLifetimeEnd() - 1;
// We know positions above GetStart() do not have a location yet.
@@ -348,7 +349,9 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until,
LiveInterval* existing = GetParent()->GetSiblingAt(position);
if (existing != nullptr
&& existing->HasRegister()
- && (free_until[existing->GetRegister()] > GetStart())) {
+ // It's worth using that register if it is available until
+ // the next use.
+ && (free_until[existing->GetRegister()] >= next_register_use)) {
return existing->GetRegister();
}
}
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index 4cbe29ae42..4667825a62 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -1219,6 +1219,7 @@ class SsaLivenessAnalysis : public ValueObject {
size_t number_of_ssa_values_;
ART_FRIEND_TEST(RegisterAllocatorTest, SpillInactive);
+ ART_FRIEND_TEST(RegisterAllocatorTest, FreeUntil);
DISALLOW_COPY_AND_ASSIGN(SsaLivenessAnalysis);
};
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc
index 98e14ea9a6..666fb604c0 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -136,7 +136,7 @@ TEST(StackMapTest, Test2) {
ArenaBitVector sp_mask2(&arena, 0, true);
sp_mask2.SetBit(3);
- sp_mask1.SetBit(8);
+ sp_mask2.SetBit(8);
stream.BeginStackMapEntry(1, 128, 0xFF, &sp_mask2, number_of_dex_registers, 0);
stream.AddDexRegisterEntry(Kind::kInRegister, 18); // Short location.
stream.AddDexRegisterEntry(Kind::kInFpuRegister, 3); // Short location.
@@ -148,7 +148,7 @@ TEST(StackMapTest, Test2) {
stream.FillIn(region);
CodeInfo code_info(region);
- ASSERT_EQ(1u, code_info.GetStackMaskSize());
+ ASSERT_EQ(2u, code_info.GetStackMaskSize());
ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
uint32_t number_of_location_catalog_entries =