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