code_generator.h revision 77520bca97ec44e3758510cebd0f20e3bb4584ea
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 20d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h" 213416601a9e9be81bb7494864287fd3602d18ef13Calin Juravle#include "arch/instruction_set_features.h" 2201bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray#include "base/bit_field.h" 23cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle#include "driver/compiler_options.h" 24bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray#include "globals.h" 254e3d23aa1523718ea1fdf3a32516d2f9d81e84feNicolas Geoffray#include "locations.h" 26d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "memory_region.h" 27d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#include "nodes.h" 283946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray#include "stack_map_stream.h" 29d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 30d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffraynamespace art { 31d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 32a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffraystatic size_t constexpr kVRegSize = 4; 3386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffraystatic size_t constexpr kUninitializedFrameSize = 0; 34a747a392fb5f88d2ecc4c6021edf9f1f6615ba16Nicolas Geoffray 356d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain// Binary encoding of 2^32 for type double. 366d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillainstatic int64_t constexpr k2Pow32EncodingForDouble = INT64_C(0x41F0000000000000); 376d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain// Binary encoding of 2^31 for type double. 386d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillainstatic int64_t constexpr k2Pow31EncodingForDouble = INT64_C(0x41E0000000000000); 396d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain 403f8f936aff35f29d86183d31c20597ea17e9789dRoland Levillain// Maximum value for a primitive integer. 413f8f936aff35f29d86183d31c20597ea17e9789dRoland Levillainstatic int32_t constexpr kPrimIntMax = 0x7fffffff; 42624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain// Maximum value for a primitive long. 43624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainstatic int64_t constexpr kPrimLongMax = 0x7fffffffffffffff; 443f8f936aff35f29d86183d31c20597ea17e9789dRoland Levillain 4592a73aef279be78e3c2b04db1713076183933436Nicolas Geoffrayclass Assembler; 46e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffrayclass CodeGenerator; 4792cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffrayclass DexCompilationUnit; 48f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffrayclass ParallelMoveResolver; 49e21dc3db191df04c100620965bee4617b3b24397Andreas Gampeclass SrcMapElem; 50e21dc3db191df04c100620965bee4617b3b24397Andreas Gampetemplate <class Alloc> 51e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass SrcMap; 52e21dc3db191df04c100620965bee4617b3b24397Andreas Gampeusing DefaultSrcMap = SrcMap<std::allocator<SrcMapElem>>; 5392cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray 54d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffrayclass CodeAllocator { 55d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public: 56e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray CodeAllocator() {} 57e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray virtual ~CodeAllocator() {} 58d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 59d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual uint8_t* Allocate(size_t size) = 0; 60d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 61d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray private: 62d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(CodeAllocator); 63d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}; 64d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 658ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffraystruct PcInfo { 668ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t dex_pc; 678ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uintptr_t native_pc; 688ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray}; 698ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray 706a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersclass SlowPathCode : public ArenaObject<kArenaAllocSlowPaths> { 71e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray public: 7292a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray SlowPathCode() {} 73e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray virtual ~SlowPathCode() {} 74e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 75e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray virtual void EmitNativeCode(CodeGenerator* codegen) = 0; 76e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 77e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray private: 78e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray DISALLOW_COPY_AND_ASSIGN(SlowPathCode); 79e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray}; 80e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 8112df9ebf72255544b0147c81b1dca6644a29764eNicolas Geoffrayclass CodeGenerator { 82d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public: 83d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray // Compiles the graph to executable instructions. Returns whether the compilation 84d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray // succeeded. 8573e80c3ae76fafdb53afe3a85306dcb491fb5b00Nicolas Geoffray void CompileBaseline(CodeAllocator* allocator, bool is_leaf = false); 8686dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void CompileOptimized(CodeAllocator* allocator); 8712df9ebf72255544b0147c81b1dca6644a29764eNicolas Geoffray static CodeGenerator* Create(HGraph* graph, 883416601a9e9be81bb7494864287fd3602d18ef13Calin Juravle InstructionSet instruction_set, 89cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const InstructionSetFeatures& isa_features, 90cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& compiler_options); 9112df9ebf72255544b0147c81b1dca6644a29764eNicolas Geoffray virtual ~CodeGenerator() {} 92d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 93787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray HGraph* GetGraph() const { return graph_; } 94d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 95bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray bool GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const; 96bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 9786dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray size_t GetStackSlotOfParameter(HParameterValue* parameter) const { 9886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray // Note that this follows the current calling convention. 9986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray return GetFrameSize() 10086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray + kVRegSize // Art method 101e27f31a81636ad74bd3376ee39cf215941b85c0eNicolas Geoffray + parameter->GetIndex() * kVRegSize; 10286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 10386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 10492a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray virtual void Initialize() = 0; 10532f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu virtual void Finalize(CodeAllocator* allocator); 106d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual void GenerateFrameEntry() = 0; 107d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual void GenerateFrameExit() = 0; 10892a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray virtual void Bind(HBasicBlock* block) = 0; 1094a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) = 0; 110bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray virtual HGraphVisitor* GetLocationBuilder() = 0; 111787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray virtual HGraphVisitor* GetInstructionVisitor() = 0; 112787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray virtual Assembler* GetAssembler() = 0; 113707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray virtual size_t GetWordSize() const = 0; 114f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell virtual size_t GetFloatingPointSpillSlotSize() const = 0; 115de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray virtual uintptr_t GetAddressOf(HBasicBlock* block) const = 0; 1163bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray void ComputeFrameSize(size_t number_of_spill_slots, 117f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell size_t maximum_number_of_live_core_registers, 118f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell size_t maximum_number_of_live_fp_registers, 1193bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray size_t number_of_out_slots); 120ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray virtual size_t FrameEntrySpillSize() const = 0; 121ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray int32_t GetStackSlot(HLocal* local) const; 122ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray Location GetTemporaryLocation(HTemporary* temp) const; 123787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 124787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray uint32_t GetFrameSize() const { return frame_size_; } 125787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray void SetFrameSize(uint32_t size) { frame_size_ = size; } 1268ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t GetCoreSpillMask() const { return core_spill_mask_; } 1278ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray 12871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t GetNumberOfCoreRegisters() const { return number_of_core_registers_; } 12971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t GetNumberOfFloatingPointRegisters() const { return number_of_fpu_registers_; } 13071175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray virtual void SetupBlockedRegisters() const = 0; 13171175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray 132a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray virtual void DumpCoreRegister(std::ostream& stream, int reg) const = 0; 133a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const = 0; 134412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray virtual InstructionSet GetInstructionSet() const = 0; 135cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle 136cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& GetCompilerOptions() const { return compiler_options_; } 137cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle 138102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray // Saves the register in the stack. Returns the size taken on stack. 139102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray virtual size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) = 0; 140102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray // Restores the register from the stack. Returns the size taken on stack. 141102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray virtual size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) = 0; 142102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray virtual size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) { 1436a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(stack_index, reg_id); 1446a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNIMPLEMENTED(FATAL); 1456a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNREACHABLE(); 146102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray } 147102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray virtual size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) { 1486a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(stack_index, reg_id); 1496a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNIMPLEMENTED(FATAL); 1506a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNREACHABLE(); 151102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray } 152840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray virtual bool NeedsTwoRegisters(Primitive::Type type) const = 0; 153a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray 1543946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray void RecordPcInfo(HInstruction* instruction, uint32_t dex_pc); 15577520bca97ec44e3758510cebd0f20e3bb4584eaCalin Juravle bool CanMoveNullCheckToUser(HNullCheck* null_check); 15677520bca97ec44e3758510cebd0f20e3bb4584eaCalin Juravle void MaybeRecordImplicitNullCheck(HInstruction* instruction); 157787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 158e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray void AddSlowPath(SlowPathCode* slow_path) { 159e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray slow_paths_.Add(slow_path); 160e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray } 161e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 162e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray void GenerateSlowPaths(); 163e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 164e21dc3db191df04c100620965bee4617b3b24397Andreas Gampe void BuildMappingTable(std::vector<uint8_t>* vector, DefaultSrcMap* src_map) const; 1658ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray void BuildVMapTable(std::vector<uint8_t>* vector) const; 16692cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray void BuildNativeGCMap( 16792cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray std::vector<uint8_t>* vector, const DexCompilationUnit& dex_compilation_unit) const; 1683946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray void BuildStackMaps(std::vector<uint8_t>* vector); 1693bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray void SaveLiveRegisters(LocationSummary* locations); 1703bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray void RestoreLiveRegisters(LocationSummary* locations); 171787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 172f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray bool IsLeafMethod() const { 173f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray return is_leaf_; 174f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray } 175f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray 176f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray void MarkNotLeaf() { 177f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray is_leaf_ = false; 178f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray } 179f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray 1803c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // Clears the spill slots taken by loop phis in the `LocationSummary` of the 1813c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // suspend check. This is called when the code generator generates code 1823c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // for the suspend check at the back edge (instead of where the suspend check 1833c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // is, which is the loop entry). At this point, the spill slots for the phis 1843c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // have not been written to. 1853c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray void ClearSpillSlotsFromLoopPhisInStackMap(HSuspendCheck* suspend_check) const; 1863c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray 18771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* GetBlockedCoreRegisters() const { return blocked_core_registers_; } 188102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray bool* GetBlockedFloatingPointRegisters() const { return blocked_fpu_registers_; } 18971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray 19019a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray // Helper that returns the pointer offset of an index in an object array. 19119a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray // Note: this method assumes we always have the same pointer size, regardless 19219a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray // of the architecture. 19319a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray static size_t GetCacheOffset(uint32_t index); 19419a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray 195f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray void EmitParallelMoves(Location from1, Location to1, Location from2, Location to2); 196f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray 197af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray static bool StoreNeedsWriteBarrier(Primitive::Type type, HInstruction* value) { 198af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray if (kIsDebugBuild) { 199af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray if (type == Primitive::kPrimNot && value->IsIntConstant()) { 200900f6eb15db5215deeea23e4e087b553b4f696f7Nicolas Geoffray CHECK_EQ(value->AsIntConstant()->GetValue(), 0); 201af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray } 202af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray } 203af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray return type == Primitive::kPrimNot && !value->IsIntConstant(); 204af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray } 205af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray 206787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray protected: 20771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray CodeGenerator(HGraph* graph, 20871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_core_registers, 20971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_fpu_registers, 210cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle size_t number_of_register_pairs, 211cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& compiler_options) 21286dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray : frame_size_(kUninitializedFrameSize), 2134361beff5bc540c43ab7c072c99994adc4ed78f9Nicolas Geoffray core_spill_mask_(0), 2143bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray first_register_slot_in_slow_path_(0), 21571175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray blocked_core_registers_(graph->GetArena()->AllocArray<bool>(number_of_core_registers)), 21671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray blocked_fpu_registers_(graph->GetArena()->AllocArray<bool>(number_of_fpu_registers)), 21771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray blocked_register_pairs_(graph->GetArena()->AllocArray<bool>(number_of_register_pairs)), 21871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray number_of_core_registers_(number_of_core_registers), 21971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray number_of_fpu_registers_(number_of_fpu_registers), 22071175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray number_of_register_pairs_(number_of_register_pairs), 221787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray graph_(graph), 222cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle compiler_options_(compiler_options), 223a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray pc_infos_(graph->GetArena(), 32), 224e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray slow_paths_(graph->GetArena(), 8), 2253946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray is_leaf_(true), 2263946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray stack_map_stream_(graph->GetArena()) {} 227d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 228a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray // Register allocation logic. 229a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray void AllocateRegistersLocally(HInstruction* instruction) const; 230a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 231a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray // Backend specific implementation for allocating a register. 23271175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray virtual Location AllocateFreeRegister(Primitive::Type type) const = 0; 233a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 23471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray static size_t FindFreeEntry(bool* array, size_t length); 2353c03503d66df3b4440f851ae7d0c4fae5e7872dfNicolas Geoffray static size_t FindTwoFreeConsecutiveAlignedEntries(bool* array, size_t length); 236a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 237a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray virtual Location GetStackLocation(HLoadLocal* load) const = 0; 238a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 239f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray virtual ParallelMoveResolver* GetMoveResolver() = 0; 240f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray 2418ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray // Frame size required for this method. 2428ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t frame_size_; 2438ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t core_spill_mask_; 2443bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray uint32_t first_register_slot_in_slow_path_; 2458ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray 24671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray // Arrays used when doing register allocation to know which 24771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray // registers we can allocate. `SetupBlockedRegisters` updates the 24871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray // arrays. 24971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* const blocked_core_registers_; 25071175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* const blocked_fpu_registers_; 25171175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* const blocked_register_pairs_; 25271175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_core_registers_; 25371175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_fpu_registers_; 25471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_register_pairs_; 25571175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray 256bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray private: 257bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray void InitLocations(HInstruction* instruction); 2583bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray size_t GetStackOffsetOfSavedRegister(size_t index); 259d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 260787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray HGraph* const graph_; 261cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& compiler_options_; 262d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2638ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray GrowableArray<PcInfo> pc_infos_; 264e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray GrowableArray<SlowPathCode*> slow_paths_; 265d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 266f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray bool is_leaf_; 267f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray 2683946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray StackMapStream stack_map_stream_; 2693946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray 270d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(CodeGenerator); 271d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}; 272d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 2737fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffraytemplate <typename C, typename F> 2744a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffrayclass CallingConvention { 2754a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray public: 2767fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray CallingConvention(const C* registers, 2777fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t number_of_registers, 2787fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const F* fpu_registers, 2797fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t number_of_fpu_registers) 2807fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray : registers_(registers), 2817fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray number_of_registers_(number_of_registers), 2827fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray fpu_registers_(fpu_registers), 2837fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray number_of_fpu_registers_(number_of_fpu_registers) {} 2844a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 2854a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray size_t GetNumberOfRegisters() const { return number_of_registers_; } 2867fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t GetNumberOfFpuRegisters() const { return number_of_fpu_registers_; } 2874a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 2887fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray C GetRegisterAt(size_t index) const { 2894a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray DCHECK_LT(index, number_of_registers_); 2904a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray return registers_[index]; 2914a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray } 2924a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 2937fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray F GetFpuRegisterAt(size_t index) const { 2947fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray DCHECK_LT(index, number_of_fpu_registers_); 2957fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray return fpu_registers_[index]; 2967fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray } 2977fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray 2987fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t GetStackOffsetOf(size_t index) const { 2994a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray // We still reserve the space for parameters passed by registers. 3009cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray // Add one for the method pointer. 3019cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray return (index + 1) * kVRegSize; 3024a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray } 3034a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 3044a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray private: 3057fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const C* registers_; 3064a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray const size_t number_of_registers_; 3077fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const F* fpu_registers_; 3087fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const size_t number_of_fpu_registers_; 3094a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 3104a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(CallingConvention); 3114a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray}; 3124a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 313d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} // namespace art 314d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 315d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_ 316