Merge "Fix formatting"
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 2da3176..a912d4c 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -231,8 +231,7 @@
}
}
-bool HGraphBuilder::SkipCompilation(size_t number_of_dex_instructions,
- size_t number_of_blocks ATTRIBUTE_UNUSED,
+bool HGraphBuilder::SkipCompilation(const DexFile::CodeItem& code_item,
size_t number_of_branches) {
const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions();
CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
@@ -240,19 +239,20 @@
return false;
}
- if (compiler_options.IsHugeMethod(number_of_dex_instructions)) {
+ if (compiler_options.IsHugeMethod(code_item.insns_size_in_code_units_)) {
VLOG(compiler) << "Skip compilation of huge method "
<< PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
- << ": " << number_of_dex_instructions << " dex instructions";
+ << ": " << code_item.insns_size_in_code_units_ << " code units";
MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod);
return true;
}
// If it's large and contains no branches, it's likely to be machine generated initialization.
- if (compiler_options.IsLargeMethod(number_of_dex_instructions) && (number_of_branches == 0)) {
+ if (compiler_options.IsLargeMethod(code_item.insns_size_in_code_units_)
+ && (number_of_branches == 0)) {
VLOG(compiler) << "Skip compilation of large method with no branch "
<< PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
- << ": " << number_of_dex_instructions << " dex instructions";
+ << ": " << code_item.insns_size_in_code_units_ << " code units";
MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches);
return true;
}
@@ -279,18 +279,14 @@
// Compute the number of dex instructions, blocks, and branches. We will
// check these values against limits given to the compiler.
- size_t number_of_dex_instructions = 0;
- size_t number_of_blocks = 0;
size_t number_of_branches = 0;
// To avoid splitting blocks, we compute ahead of time the instructions that
// start a new block, and create these blocks.
- ComputeBranchTargets(
- code_ptr, code_end, &number_of_dex_instructions, &number_of_blocks, &number_of_branches);
+ ComputeBranchTargets(code_ptr, code_end, &number_of_branches);
// Note that the compiler driver is null when unit testing.
- if ((compiler_driver_ != nullptr)
- && SkipCompilation(number_of_dex_instructions, number_of_blocks, number_of_branches)) {
+ if ((compiler_driver_ != nullptr) && SkipCompilation(code_item, number_of_branches)) {
return false;
}
@@ -356,8 +352,6 @@
void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
const uint16_t* code_end,
- size_t* number_of_dex_instructions,
- size_t* number_of_blocks,
size_t* number_of_branches) {
branch_targets_.SetSize(code_end - code_ptr);
@@ -370,7 +364,6 @@
// the locations these instructions branch to.
uint32_t dex_pc = 0;
while (code_ptr < code_end) {
- (*number_of_dex_instructions)++;
const Instruction& instruction = *Instruction::At(code_ptr);
if (instruction.IsBranch()) {
(*number_of_branches)++;
@@ -379,14 +372,12 @@
if (FindBlockStartingAt(target) == nullptr) {
block = new (arena_) HBasicBlock(graph_, target);
branch_targets_.Put(target, block);
- (*number_of_blocks)++;
}
dex_pc += instruction.SizeInCodeUnits();
code_ptr += instruction.SizeInCodeUnits();
if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) {
block = new (arena_) HBasicBlock(graph_, dex_pc);
branch_targets_.Put(dex_pc, block);
- (*number_of_blocks)++;
}
} else if (instruction.IsSwitch()) {
SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH);
@@ -404,14 +395,12 @@
if (FindBlockStartingAt(target) == nullptr) {
block = new (arena_) HBasicBlock(graph_, target);
branch_targets_.Put(target, block);
- (*number_of_blocks)++;
}
// The next case gets its own block.
if (i < num_entries) {
block = new (arena_) HBasicBlock(graph_, target);
branch_targets_.Put(table.GetDexPcForIndex(i), block);
- (*number_of_blocks)++;
}
}
@@ -421,7 +410,6 @@
if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) {
block = new (arena_) HBasicBlock(graph_, dex_pc);
branch_targets_.Put(dex_pc, block);
- (*number_of_blocks)++;
}
} else {
code_ptr += instruction.SizeInCodeUnits();
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 6a0738a..dc6d97e 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -90,8 +90,6 @@
// branches.
void ComputeBranchTargets(const uint16_t* start,
const uint16_t* end,
- size_t* number_of_dex_instructions,
- size_t* number_of_block,
size_t* number_of_branches);
void MaybeUpdateCurrentBlock(size_t index);
HBasicBlock* FindBlockStartingAt(int32_t index) const;
@@ -217,9 +215,7 @@
HInstruction* value, int32_t case_value_int,
int32_t target_offset, uint32_t dex_pc);
- bool SkipCompilation(size_t number_of_dex_instructions,
- size_t number_of_blocks,
- size_t number_of_branches);
+ bool SkipCompilation(const DexFile::CodeItem& code_item, size_t number_of_branches);
void MaybeRecordStat(MethodCompilationStat compilation_stat);
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 32ada38..03d3445 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -394,6 +394,10 @@
isa_features_(isa_features) {
// Save the link register (containing the return address) to mimic Quick.
AddAllocatedRegister(LocationFrom(lr));
+
+ // Workaround for valgrind undefined recommended_checkpoint_.
+ // This won't do anything, as the literal pool is empty, but initialize the field.
+ GetVIXLAssembler()->EmitLiteralPool(LiteralPool::EmitOption::kNoBranchRequired);
}
#undef __
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index 2c624d2..f555de5 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -23,8 +23,8 @@
#include "nodes.h"
#include "parallel_move_resolver.h"
#include "utils/arm64/assembler_arm64.h"
-#include "a64/disasm-a64.h"
-#include "a64/macro-assembler-a64.h"
+#include "vixl/a64/disasm-a64.h"
+#include "vixl/a64/macro-assembler-a64.h"
#include "arch/arm64/quick_method_frame_info_arm64.h"
namespace art {
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index fd8c0c6..966165b 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -20,8 +20,8 @@
#include "locations.h"
#include "nodes.h"
#include "utils/arm64/assembler_arm64.h"
-#include "a64/disasm-a64.h"
-#include "a64/macro-assembler-a64.h"
+#include "vixl/a64/disasm-a64.h"
+#include "vixl/a64/macro-assembler-a64.h"
namespace art {
namespace arm64 {
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 72d303c..d1176c4 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -28,8 +28,8 @@
#include "utils/arm64/assembler_arm64.h"
#include "utils/arm64/constants_arm64.h"
-#include "a64/disasm-a64.h"
-#include "a64/macro-assembler-a64.h"
+#include "vixl/a64/disasm-a64.h"
+#include "vixl/a64/macro-assembler-a64.h"
using namespace vixl; // NOLINT(build/namespaces)
diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc
index 2d9a2bf..0161984 100644
--- a/compiler/optimizing/prepare_for_register_allocation.cc
+++ b/compiler/optimizing/prepare_for_register_allocation.cc
@@ -60,7 +60,7 @@
void PrepareForRegisterAllocation::VisitCondition(HCondition* condition) {
bool needs_materialization = false;
- if (!condition->GetUses().HasOnlyOneUse()) {
+ if (!condition->GetUses().HasOnlyOneUse() || !condition->GetEnvUses().IsEmpty()) {
needs_materialization = true;
} else {
HInstruction* user = condition->GetUses().GetFirst()->GetUser();
diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h
index a69be25..2031fe4 100644
--- a/compiler/utils/arm64/assembler_arm64.h
+++ b/compiler/utils/arm64/assembler_arm64.h
@@ -31,8 +31,8 @@
// TODO: make vixl clean wrt -Wshadow.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
-#include "a64/macro-assembler-a64.h"
-#include "a64/disasm-a64.h"
+#include "vixl/a64/macro-assembler-a64.h"
+#include "vixl/a64/disasm-a64.h"
#pragma GCC diagnostic pop
namespace art {
diff --git a/disassembler/disassembler_arm64.h b/disassembler/disassembler_arm64.h
index 3fb5c7f..44fa53f 100644
--- a/disassembler/disassembler_arm64.h
+++ b/disassembler/disassembler_arm64.h
@@ -21,8 +21,8 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
-#include "a64/decoder-a64.h"
-#include "a64/disasm-a64.h"
+#include "vixl/a64/decoder-a64.h"
+#include "vixl/a64/disasm-a64.h"
#pragma GCC diagnostic pop
namespace art {
diff --git a/test/469-condition-materialization-regression/expected.txt b/test/469-condition-materialization-regression/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/469-condition-materialization-regression/expected.txt
diff --git a/test/469-condition-materialization-regression/info.txt b/test/469-condition-materialization-regression/info.txt
new file mode 100644
index 0000000..59290f0
--- /dev/null
+++ b/test/469-condition-materialization-regression/info.txt
@@ -0,0 +1,2 @@
+Regression test for optimizing's code generator which wouldn't
+materialize a condition when used only by an environment.
diff --git a/test/469-condition-materialization-regression/src/Main.java b/test/469-condition-materialization-regression/src/Main.java
new file mode 100644
index 0000000..0be386a
--- /dev/null
+++ b/test/469-condition-materialization-regression/src/Main.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+
+ // This tests a specific situation when condition ends up
+ // not getting materialized if only used by an environment.
+
+ private static Object obj;
+
+ private static int useValue(boolean value) {
+ return 42;
+ }
+
+ private static int runTest(boolean input1) {
+ boolean negation = !input1;
+ // Need the negation to appear in front of an If, and
+ // its condition to disappear. 'javac' will generate
+ // "if (!input1)" here and GVN will collapse the two
+ // conditions.
+ if (input1) {
+ // Generates an environment use of 'negation'.
+ obj = new Object();
+ }
+ // Uses 'negation' but disappears with inlining.
+ return useValue(negation);
+ }
+
+ public static void main(String[] args) throws Exception {
+ int result = runTest(true);
+ if (result != 42) {
+ throw new Error("Expected 42, got " + result);
+ }
+ }
+}