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);
+    }
+  }
+}