code_generator.h revision 19a19cffd197a28ae4c9c3e59eff6352fd392241
1d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray/*
2d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
3d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *
4d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * you may not use this file except in compliance with the License.
6d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * You may obtain a copy of the License at
7d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *
8d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray *
10d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * See the License for the specific language governing permissions and
14d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray * limitations under the License.
15d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray */
16d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
17d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_
18d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#define ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_
19d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
2001bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray#include "base/bit_field.h"
21bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray#include "globals.h"
22d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "instruction_set.h"
234e3d23aa1523718ea1fdf3a32516d2f9d81e84feNicolas Geoffray#include "locations.h"
24d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "memory_region.h"
25d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "nodes.h"
263946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray#include "stack_map_stream.h"
27d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
28d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffraynamespace art {
29d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
30a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffraystatic size_t constexpr kVRegSize = 4;
3186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffraystatic size_t constexpr kUninitializedFrameSize = 0;
32a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray
3392a73aef279be78e3c2b04db1713076183933436Nicolas Geoffrayclass Assembler;
34e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffrayclass CodeGenerator;
3592cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffrayclass DexCompilationUnit;
36e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass SrcMap;
3792cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray
38d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffrayclass CodeAllocator {
39d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public:
40e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  CodeAllocator() {}
41e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  virtual ~CodeAllocator() {}
42d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
43d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  virtual uint8_t* Allocate(size_t size) = 0;
44d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
45d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray private:
46d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(CodeAllocator);
47d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray};
48d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
498ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffraystruct PcInfo {
508ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  uint32_t dex_pc;
518ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  uintptr_t native_pc;
528ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray};
538ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray
54e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffrayclass SlowPathCode : public ArenaObject {
55e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray public:
5692a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray  SlowPathCode() {}
57e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  virtual ~SlowPathCode() {}
58e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray
59e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  virtual void EmitNativeCode(CodeGenerator* codegen) = 0;
60e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray
61e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray private:
62e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(SlowPathCode);
63e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray};
64e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray
65787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffrayclass CodeGenerator : public ArenaObject {
66d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public:
67d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  // Compiles the graph to executable instructions. Returns whether the compilation
68d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  // succeeded.
6973e80c3ae76fafdb53afe3a85306dcb491fb5b00Nicolas Geoffray  void CompileBaseline(CodeAllocator* allocator, bool is_leaf = false);
7086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  void CompileOptimized(CodeAllocator* allocator);
71787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  static CodeGenerator* Create(ArenaAllocator* allocator,
72787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray                               HGraph* graph,
73787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray                               InstructionSet instruction_set);
74d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
75787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  HGraph* GetGraph() const { return graph_; }
76d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
77bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  bool GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const;
78bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray
7986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  size_t GetStackSlotOfParameter(HParameterValue* parameter) const {
8086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    // Note that this follows the current calling convention.
8186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray    return GetFrameSize()
8286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray        + kVRegSize  // Art method
83e27f31a81636ad74bd3376ee39cf215941b85c0eNicolas Geoffray        + parameter->GetIndex() * kVRegSize;
8486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  }
8586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray
8692a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray  virtual void Initialize() = 0;
87d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  virtual void GenerateFrameEntry() = 0;
88d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  virtual void GenerateFrameExit() = 0;
8992a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray  virtual void Bind(HBasicBlock* block) = 0;
904a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) = 0;
91bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  virtual HGraphVisitor* GetLocationBuilder() = 0;
92787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  virtual HGraphVisitor* GetInstructionVisitor() = 0;
93787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  virtual Assembler* GetAssembler() = 0;
94707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray  virtual size_t GetWordSize() const = 0;
953bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray  void ComputeFrameSize(size_t number_of_spill_slots,
963bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray                        size_t maximum_number_of_live_registers,
973bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray                        size_t number_of_out_slots);
98ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray  virtual size_t FrameEntrySpillSize() const = 0;
99ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray  int32_t GetStackSlot(HLocal* local) const;
100ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray  Location GetTemporaryLocation(HTemporary* temp) const;
101787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
102787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  uint32_t GetFrameSize() const { return frame_size_; }
103787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  void SetFrameSize(uint32_t size) { frame_size_ = size; }
1048ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  uint32_t GetCoreSpillMask() const { return core_spill_mask_; }
1058ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray
10671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  size_t GetNumberOfCoreRegisters() const { return number_of_core_registers_; }
10771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  size_t GetNumberOfFloatingPointRegisters() const { return number_of_fpu_registers_; }
10871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  virtual void SetupBlockedRegisters() const = 0;
10971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray
110a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  virtual void DumpCoreRegister(std::ostream& stream, int reg) const = 0;
111a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray  virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const = 0;
112412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  virtual InstructionSet GetInstructionSet() const = 0;
113102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  // Saves the register in the stack. Returns the size taken on stack.
114102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  virtual size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) = 0;
115102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  // Restores the register from the stack. Returns the size taken on stack.
116102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  virtual size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) = 0;
117102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  virtual size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) {
118102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray    LOG(FATAL) << "Unimplemented";
119102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray    return 0u;
120102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  }
121102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  virtual size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) {
122102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray    LOG(FATAL) << "Unimplemented";
123102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray    return 0u;
124102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  }
125a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray
1263946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray  void RecordPcInfo(HInstruction* instruction, uint32_t dex_pc);
127787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
128e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  void AddSlowPath(SlowPathCode* slow_path) {
129e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray    slow_paths_.Add(slow_path);
130e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  }
131e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray
132e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  void GenerateSlowPaths();
133e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray
134e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  void BuildMappingTable(std::vector<uint8_t>* vector, SrcMap* src_map) const;
1358ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  void BuildVMapTable(std::vector<uint8_t>* vector) const;
13692cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray  void BuildNativeGCMap(
13792cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray      std::vector<uint8_t>* vector, const DexCompilationUnit& dex_compilation_unit) const;
1383946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray  void BuildStackMaps(std::vector<uint8_t>* vector);
1393bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray  void SaveLiveRegisters(LocationSummary* locations);
1403bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray  void RestoreLiveRegisters(LocationSummary* locations);
141787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray
142f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  bool IsLeafMethod() const {
143f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray    return is_leaf_;
144f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  }
145f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
146f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  void MarkNotLeaf() {
147f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray    is_leaf_ = false;
148f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  }
149f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
1503c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  // Clears the spill slots taken by loop phis in the `LocationSummary` of the
1513c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  // suspend check. This is called when the code generator generates code
1523c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  // for the suspend check at the back edge (instead of where the suspend check
1533c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  // is, which is the loop entry). At this point, the spill slots for the phis
1543c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  // have not been written to.
1553c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray  void ClearSpillSlotsFromLoopPhisInStackMap(HSuspendCheck* suspend_check) const;
1563c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray
15771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  bool* GetBlockedCoreRegisters() const { return blocked_core_registers_; }
158102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray  bool* GetBlockedFloatingPointRegisters() const { return blocked_fpu_registers_; }
15971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray
16019a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  // Helper that returns the pointer offset of an index in an object array.
16119a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  // Note: this method assumes we always have the same pointer size, regardless
16219a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  // of the architecture.
16319a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray  static size_t GetCacheOffset(uint32_t index);
16419a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray
165787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray protected:
16671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  CodeGenerator(HGraph* graph,
16771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray                size_t number_of_core_registers,
16871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray                size_t number_of_fpu_registers,
16971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray                size_t number_of_register_pairs)
17086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray      : frame_size_(kUninitializedFrameSize),
1714361beff5bc540c43ab7c072c99994adc4ed78f9Nicolas Geoffray        core_spill_mask_(0),
1723bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray        first_register_slot_in_slow_path_(0),
17371175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray        blocked_core_registers_(graph->GetArena()->AllocArray<bool>(number_of_core_registers)),
17471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray        blocked_fpu_registers_(graph->GetArena()->AllocArray<bool>(number_of_fpu_registers)),
17571175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray        blocked_register_pairs_(graph->GetArena()->AllocArray<bool>(number_of_register_pairs)),
17671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray        number_of_core_registers_(number_of_core_registers),
17771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray        number_of_fpu_registers_(number_of_fpu_registers),
17871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray        number_of_register_pairs_(number_of_register_pairs),
179787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray        graph_(graph),
180a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray        pc_infos_(graph->GetArena(), 32),
181e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray        slow_paths_(graph->GetArena(), 8),
1823946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray        is_leaf_(true),
1833946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray        stack_map_stream_(graph->GetArena()) {}
18486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray  ~CodeGenerator() {}
185d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
186a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  // Register allocation logic.
187a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  void AllocateRegistersLocally(HInstruction* instruction) const;
188a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray
189a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  // Backend specific implementation for allocating a register.
19071175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  virtual Location AllocateFreeRegister(Primitive::Type type) const = 0;
191a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray
19271175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  static size_t FindFreeEntry(bool* array, size_t length);
1931ba0f596e9e4ddd778ab431237d11baa85594ebaNicolas Geoffray  static size_t FindTwoFreeConsecutiveEntries(bool* array, size_t length);
194a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray
195a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray  virtual Location GetStackLocation(HLoadLocal* load) const = 0;
196a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray
1978ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  // Frame size required for this method.
1988ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  uint32_t frame_size_;
1998ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  uint32_t core_spill_mask_;
2003bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray  uint32_t first_register_slot_in_slow_path_;
2018ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray
20271175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  // Arrays used when doing register allocation to know which
20371175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  // registers we can allocate. `SetupBlockedRegisters` updates the
20471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  // arrays.
20571175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  bool* const blocked_core_registers_;
20671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  bool* const blocked_fpu_registers_;
20771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  bool* const blocked_register_pairs_;
20871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  size_t number_of_core_registers_;
20971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  size_t number_of_fpu_registers_;
21071175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray  size_t number_of_register_pairs_;
21171175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray
212bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray private:
213bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  void InitLocations(HInstruction* instruction);
2143bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray  size_t GetStackOffsetOfSavedRegister(size_t index);
215d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
216787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray  HGraph* const graph_;
217d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
2188ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  GrowableArray<PcInfo> pc_infos_;
219e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  GrowableArray<SlowPathCode*> slow_paths_;
220d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
221f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray  bool is_leaf_;
222f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray
2233946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray  StackMapStream stack_map_stream_;
2243946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray
225d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
226d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray};
227d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
2287fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffraytemplate <typename C, typename F>
2294a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffrayclass CallingConvention {
2304a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray public:
2317fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  CallingConvention(const C* registers,
2327fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray                    size_t number_of_registers,
2337fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray                    const F* fpu_registers,
2347fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray                    size_t number_of_fpu_registers)
2357fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray      : registers_(registers),
2367fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        number_of_registers_(number_of_registers),
2377fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        fpu_registers_(fpu_registers),
2387fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        number_of_fpu_registers_(number_of_fpu_registers) {}
2394a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray
2404a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  size_t GetNumberOfRegisters() const { return number_of_registers_; }
2417fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  size_t GetNumberOfFpuRegisters() const { return number_of_fpu_registers_; }
2424a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray
2437fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  C GetRegisterAt(size_t index) const {
2444a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray    DCHECK_LT(index, number_of_registers_);
2454a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray    return registers_[index];
2464a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  }
2474a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray
2487fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  F GetFpuRegisterAt(size_t index) const {
2497fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray    DCHECK_LT(index, number_of_fpu_registers_);
2507fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray    return fpu_registers_[index];
2517fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  }
2527fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
2537fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  size_t GetStackOffsetOf(size_t index) const {
2544a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray    // We still reserve the space for parameters passed by registers.
2559cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray    // Add one for the method pointer.
2569cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray    return (index + 1) * kVRegSize;
2574a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  }
2584a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray
2594a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray private:
2607fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  const C* registers_;
2614a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  const size_t number_of_registers_;
2627fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  const F* fpu_registers_;
2637fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  const size_t number_of_fpu_registers_;
2644a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray
2654a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(CallingConvention);
2664a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray};
2674a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray
268d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}  // namespace art
269d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray
270d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#endif  // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_
271