Revert "Refactor HGraphBuilder and SsaBuilder to remove HLocals"

Bug: 27995065
This reverts commit e3ff7b293be2a6791fe9d135d660c0cffe4bd73f.

Change-Id: I5363c7ce18f47fd422c15eed5423a345a57249d8
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 4f46d5e..50a1334 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -24,14 +24,14 @@
 #include "dex_file-inl.h"
 #include "driver/compiler_driver.h"
 #include "driver/dex_compilation_unit.h"
-#include "instruction_builder.h"
 #include "optimizing_compiler_stats.h"
 #include "primitive.h"
 #include "nodes.h"
-#include "ssa_builder.h"
 
 namespace art {
 
+class Instruction;
+
 class HGraphBuilder : public ValueObject {
  public:
   HGraphBuilder(HGraph* graph,
@@ -42,65 +42,245 @@
                 CompilerDriver* driver,
                 OptimizingCompilerStats* compiler_stats,
                 const uint8_t* interpreter_metadata,
-                Handle<mirror::DexCache> dex_cache,
-                StackHandleScopeCollection* handles)
-      : graph_(graph),
+                Handle<mirror::DexCache> dex_cache)
+      : arena_(graph->GetArena()),
+        locals_(graph->GetArena()->Adapter(kArenaAllocGraphBuilder)),
+        current_block_(nullptr),
+        graph_(graph),
         dex_file_(dex_file),
         code_item_(code_item),
         dex_compilation_unit_(dex_compilation_unit),
         compiler_driver_(driver),
-        compilation_stats_(compiler_stats),
+        outer_compilation_unit_(outer_compilation_unit),
+        return_type_(Primitive::GetType(dex_compilation_unit_->GetShorty()[0])),
+        code_start_(code_item.insns_),
         block_builder_(graph, dex_file, code_item),
-        ssa_builder_(graph, handles),
-        instruction_builder_(graph,
-                             &block_builder_,
-                             &ssa_builder_,
-                             dex_file,
-                             code_item_,
-                             Primitive::GetType(dex_compilation_unit_->GetShorty()[0]),
-                             dex_compilation_unit,
-                             outer_compilation_unit,
-                             driver,
-                             interpreter_metadata,
-                             compiler_stats,
-                             dex_cache) {}
+        latest_result_(nullptr),
+        compilation_stats_(compiler_stats),
+        interpreter_metadata_(interpreter_metadata),
+        dex_cache_(dex_cache) {}
 
   // Only for unit testing.
   HGraphBuilder(HGraph* graph,
                 const DexFile::CodeItem& code_item,
-                StackHandleScopeCollection* handles,
                 Primitive::Type return_type = Primitive::kPrimInt)
-      : graph_(graph),
+      : arena_(graph->GetArena()),
+        locals_(graph->GetArena()->Adapter(kArenaAllocGraphBuilder)),
+        current_block_(nullptr),
+        graph_(graph),
         dex_file_(nullptr),
         code_item_(code_item),
         dex_compilation_unit_(nullptr),
         compiler_driver_(nullptr),
-        null_dex_cache_(),
-        compilation_stats_(nullptr),
+        outer_compilation_unit_(nullptr),
+        return_type_(return_type),
+        code_start_(code_item.insns_),
         block_builder_(graph, nullptr, code_item),
-        ssa_builder_(graph, handles),
-        instruction_builder_(graph,
-                             &block_builder_,
-                             &ssa_builder_,
-                             /* dex_file */ nullptr,
-                             code_item_,
-                             return_type,
-                             /* dex_compilation_unit */ nullptr,
-                             /* outer_compilation_unit */ nullptr,
-                             /* compiler_driver */ nullptr,
-                             /* interpreter_metadata */ nullptr,
-                             /* compiler_stats */ nullptr,
-                             null_dex_cache_) {}
+        latest_result_(nullptr),
+        compilation_stats_(nullptr),
+        interpreter_metadata_(nullptr),
+        null_dex_cache_(),
+        dex_cache_(null_dex_cache_) {}
 
-  GraphAnalysisResult BuildGraph();
+  GraphAnalysisResult BuildGraph(StackHandleScopeCollection* handles);
 
   static constexpr const char* kBuilderPassName = "builder";
 
  private:
-  void MaybeRecordStat(MethodCompilationStat compilation_stat);
+  bool GenerateInstructions();
+  bool AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_pc);
+
+  void FindNativeDebugInfoLocations(ArenaBitVector* locations);
+
+  bool CanDecodeQuickenedInfo() const;
+  uint16_t LookupQuickenedInfo(uint32_t dex_pc);
+
+  HBasicBlock* FindBlockStartingAt(uint32_t dex_pc) const {
+    return block_builder_.GetBlockAt(dex_pc);
+  }
+
+  void InitializeLocals(uint16_t count);
+  HLocal* GetLocalAt(uint32_t register_index) const;
+  void UpdateLocal(uint32_t register_index, HInstruction* instruction, uint32_t dex_pc) const;
+  HInstruction* LoadLocal(uint32_t register_index, Primitive::Type type, uint32_t dex_pc) const;
+  void InitializeParameters(uint16_t number_of_parameters);
+
+  // Returns whether the current method needs access check for the type.
+  // Output parameter finalizable is set to whether the type is finalizable.
+  bool NeedsAccessCheck(uint32_t type_index, /*out*/bool* finalizable) const;
+
+  template<typename T>
+  void Unop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
+
+  template<typename T>
+  void Binop_23x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
+
+  template<typename T>
+  void Binop_23x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
+
+  void Binop_23x_cmp(const Instruction& instruction,
+                     Primitive::Type type,
+                     ComparisonBias bias,
+                     uint32_t dex_pc);
+
+  template<typename T>
+  void Binop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
+
+  template<typename T>
+  void Binop_12x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
+
+  template<typename T>
+  void Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc);
+
+  template<typename T>
+  void Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc);
+
+  template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc);
+  template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc);
+
+  void Conversion_12x(const Instruction& instruction,
+                      Primitive::Type input_type,
+                      Primitive::Type result_type,
+                      uint32_t dex_pc);
+
+  void BuildCheckedDivRem(uint16_t out_reg,
+                          uint16_t first_reg,
+                          int64_t second_reg_or_constant,
+                          uint32_t dex_pc,
+                          Primitive::Type type,
+                          bool second_is_lit,
+                          bool is_div);
+
+  void BuildReturn(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
+
+  // Builds an instance field access node and returns whether the instruction is supported.
+  bool BuildInstanceFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
+
+  void BuildUnresolvedStaticFieldAccess(const Instruction& instruction,
+                                        uint32_t dex_pc,
+                                        bool is_put,
+                                        Primitive::Type field_type);
+  // Builds a static field access node and returns whether the instruction is supported.
+  bool BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
+
+  void BuildArrayAccess(const Instruction& instruction,
+                        uint32_t dex_pc,
+                        bool is_get,
+                        Primitive::Type anticipated_type);
+
+  // Builds an invocation node and returns whether the instruction is supported.
+  bool BuildInvoke(const Instruction& instruction,
+                   uint32_t dex_pc,
+                   uint32_t method_idx,
+                   uint32_t number_of_vreg_arguments,
+                   bool is_range,
+                   uint32_t* args,
+                   uint32_t register_index);
+
+  // Builds a new array node and the instructions that fill it.
+  void BuildFilledNewArray(uint32_t dex_pc,
+                           uint32_t type_index,
+                           uint32_t number_of_vreg_arguments,
+                           bool is_range,
+                           uint32_t* args,
+                           uint32_t register_index);
+
+  void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc);
+
+  // Fills the given object with data as specified in the fill-array-data
+  // instruction. Currently only used for non-reference and non-floating point
+  // arrays.
+  template <typename T>
+  void BuildFillArrayData(HInstruction* object,
+                          const T* data,
+                          uint32_t element_count,
+                          Primitive::Type anticipated_type,
+                          uint32_t dex_pc);
+
+  // Fills the given object with data as specified in the fill-array-data
+  // instruction. The data must be for long and double arrays.
+  void BuildFillWideArrayData(HInstruction* object,
+                              const int64_t* data,
+                              uint32_t element_count,
+                              uint32_t dex_pc);
+
+  // Builds a `HInstanceOf`, or a `HCheckCast` instruction.
+  void BuildTypeCheck(const Instruction& instruction,
+                      uint8_t destination,
+                      uint8_t reference,
+                      uint16_t type_index,
+                      uint32_t dex_pc);
+
+  // Builds an instruction sequence for a switch statement.
+  void BuildSwitch(const Instruction& instruction, uint32_t dex_pc);
+
   bool SkipCompilation(size_t number_of_branches);
 
+  void MaybeRecordStat(MethodCompilationStat compilation_stat);
+
+  // Returns the outer-most compiling method's class.
+  mirror::Class* GetOutermostCompilingClass() const;
+
+  // Returns the class whose method is being compiled.
+  mirror::Class* GetCompilingClass() const;
+
+  // Returns whether `type_index` points to the outer-most compiling method's class.
+  bool IsOutermostCompilingClass(uint16_t type_index) const;
+
+  void PotentiallySimplifyFakeString(uint16_t original_dex_register,
+                                     uint32_t dex_pc,
+                                     HInvoke* invoke);
+
+  bool SetupInvokeArguments(HInvoke* invoke,
+                            uint32_t number_of_vreg_arguments,
+                            uint32_t* args,
+                            uint32_t register_index,
+                            bool is_range,
+                            const char* descriptor,
+                            size_t start_index,
+                            size_t* argument_index);
+
+  bool HandleInvoke(HInvoke* invoke,
+                    uint32_t number_of_vreg_arguments,
+                    uint32_t* args,
+                    uint32_t register_index,
+                    bool is_range,
+                    const char* descriptor,
+                    HClinitCheck* clinit_check);
+
+  bool HandleStringInit(HInvoke* invoke,
+                        uint32_t number_of_vreg_arguments,
+                        uint32_t* args,
+                        uint32_t register_index,
+                        bool is_range,
+                        const char* descriptor);
+
+  HClinitCheck* ProcessClinitCheckForInvoke(
+      uint32_t dex_pc,
+      ArtMethod* method,
+      uint32_t method_idx,
+      HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement)
+      SHARED_REQUIRES(Locks::mutator_lock_);
+
+  // Build a HNewInstance instruction.
+  bool BuildNewInstance(uint16_t type_index, uint32_t dex_pc);
+
+  // Return whether the compiler can assume `cls` is initialized.
+  bool IsInitialized(Handle<mirror::Class> cls) const
+      SHARED_REQUIRES(Locks::mutator_lock_);
+
+  // Try to resolve a method using the class linker. Return null if a method could
+  // not be resolved.
+  ArtMethod* ResolveMethod(uint16_t method_idx, InvokeType invoke_type);
+
+  ArenaAllocator* const arena_;
+
+  ArenaVector<HLocal*> locals_;
+
+  HBasicBlock* current_block_;
   HGraph* const graph_;
+
+  // The dex file where the method being compiled is, and the bytecode data.
   const DexFile* const dex_file_;
   const DexFile::CodeItem& code_item_;
 
@@ -110,13 +290,31 @@
 
   CompilerDriver* const compiler_driver_;
 
-  ScopedNullHandle<mirror::DexCache> null_dex_cache_;
+  // The compilation unit of the outermost method being compiled. That is the
+  // method being compiled (and not inlined), and potentially inlining other
+  // methods.
+  const DexCompilationUnit* const outer_compilation_unit_;
+
+  // The return type of the method being compiled.
+  const Primitive::Type return_type_;
+
+  // The pointer in the dex file where the instructions of the code item
+  // being currently compiled start.
+  const uint16_t* code_start_;
+
+  HBasicBlockBuilder block_builder_;
+
+  // The last invoke or fill-new-array being built. Only to be
+  // used by move-result instructions.
+  HInstruction* latest_result_;
 
   OptimizingCompilerStats* compilation_stats_;
 
-  HBasicBlockBuilder block_builder_;
-  SsaBuilder ssa_builder_;
-  HInstructionBuilder instruction_builder_;
+  const uint8_t* interpreter_metadata_;
+
+  // Dex cache for dex_file_.
+  ScopedNullHandle<mirror::DexCache> null_dex_cache_;
+  Handle<mirror::DexCache> dex_cache_;
 
   DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
 };