code_generator.h revision da40309f61f98c16d7d58e4c34cc0f5eef626f93
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 326d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain// Binary encoding of 2^32 for type double. 336d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillainstatic int64_t constexpr k2Pow32EncodingForDouble = INT64_C(0x41F0000000000000); 346d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain// Binary encoding of 2^31 for type double. 356d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillainstatic int64_t constexpr k2Pow31EncodingForDouble = INT64_C(0x41E0000000000000); 366d0e483dd2e0b63e952de060738c10e2abd12ff7Roland Levillain 373f8f936aff35f29d86183d31c20597ea17e9789dRoland Levillain// Maximum value for a primitive integer. 383f8f936aff35f29d86183d31c20597ea17e9789dRoland Levillainstatic int32_t constexpr kPrimIntMax = 0x7fffffff; 39624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillain// Maximum value for a primitive long. 40624279f3c70f9904cbaf428078981b05d3b324c0Roland Levillainstatic int64_t constexpr kPrimLongMax = 0x7fffffffffffffff; 413f8f936aff35f29d86183d31c20597ea17e9789dRoland Levillain 4292a73aef279be78e3c2b04db1713076183933436Nicolas Geoffrayclass Assembler; 43e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffrayclass CodeGenerator; 4492cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffrayclass DexCompilationUnit; 45f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffrayclass ParallelMoveResolver; 46e21dc3db191df04c100620965bee4617b3b24397Andreas Gampeclass SrcMapElem; 47e21dc3db191df04c100620965bee4617b3b24397Andreas Gampetemplate <class Alloc> 48e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass SrcMap; 49e21dc3db191df04c100620965bee4617b3b24397Andreas Gampeusing DefaultSrcMap = SrcMap<std::allocator<SrcMapElem>>; 5092cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray 51d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffrayclass CodeAllocator { 52d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public: 53e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray CodeAllocator() {} 54e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray virtual ~CodeAllocator() {} 55d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 56d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual uint8_t* Allocate(size_t size) = 0; 57d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 58d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray private: 59d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(CodeAllocator); 60d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}; 61d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 628ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffraystruct PcInfo { 638ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t dex_pc; 648ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uintptr_t native_pc; 658ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray}; 668ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray 676a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersclass SlowPathCode : public ArenaObject<kArenaAllocSlowPaths> { 68e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray public: 69eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray SlowPathCode() { 70eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray for (size_t i = 0; i < kMaximumNumberOfExpectedRegisters; ++i) { 71eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray saved_core_stack_offsets_[i] = kRegisterNotSaved; 72eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray saved_fpu_stack_offsets_[i] = kRegisterNotSaved; 73eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray } 74eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray } 75eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray 76e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray virtual ~SlowPathCode() {} 77e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 78e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray virtual void EmitNativeCode(CodeGenerator* codegen) = 0; 79e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 80da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu virtual void SaveLiveRegisters(CodeGenerator* codegen, LocationSummary* locations); 81da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu virtual void RestoreLiveRegisters(CodeGenerator* codegen, LocationSummary* locations); 82a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray void RecordPcInfo(CodeGenerator* codegen, HInstruction* instruction, uint32_t dex_pc); 83a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray 84eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray bool IsCoreRegisterSaved(int reg) const { 85eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray return saved_core_stack_offsets_[reg] != kRegisterNotSaved; 86eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray } 87eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray 88eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray bool IsFpuRegisterSaved(int reg) const { 89eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray return saved_fpu_stack_offsets_[reg] != kRegisterNotSaved; 90eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray } 91eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray 92eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray uint32_t GetStackOffsetOfCoreRegister(int reg) const { 93eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray return saved_core_stack_offsets_[reg]; 94eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray } 95eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray 96eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray uint32_t GetStackOffsetOfFpuRegister(int reg) const { 97eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray return saved_fpu_stack_offsets_[reg]; 98eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray } 99eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray 100da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu protected: 101eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray static constexpr size_t kMaximumNumberOfExpectedRegisters = 32; 102eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray static constexpr uint32_t kRegisterNotSaved = -1; 103eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray uint32_t saved_core_stack_offsets_[kMaximumNumberOfExpectedRegisters]; 104eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray uint32_t saved_fpu_stack_offsets_[kMaximumNumberOfExpectedRegisters]; 105da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu 106da40309f61f98c16d7d58e4c34cc0f5eef626f93Zheng Xu private: 107e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray DISALLOW_COPY_AND_ASSIGN(SlowPathCode); 108e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray}; 109e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 11012df9ebf72255544b0147c81b1dca6644a29764eNicolas Geoffrayclass CodeGenerator { 111d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray public: 112d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray // Compiles the graph to executable instructions. Returns whether the compilation 113d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray // succeeded. 11473e80c3ae76fafdb53afe3a85306dcb491fb5b00Nicolas Geoffray void CompileBaseline(CodeAllocator* allocator, bool is_leaf = false); 11586dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray void CompileOptimized(CodeAllocator* allocator); 11612df9ebf72255544b0147c81b1dca6644a29764eNicolas Geoffray static CodeGenerator* Create(HGraph* graph, 1173416601a9e9be81bb7494864287fd3602d18ef13Calin Juravle InstructionSet instruction_set, 118cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const InstructionSetFeatures& isa_features, 119cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& compiler_options); 12012df9ebf72255544b0147c81b1dca6644a29764eNicolas Geoffray virtual ~CodeGenerator() {} 121d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 122787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray HGraph* GetGraph() const { return graph_; } 123d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 124dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray HBasicBlock* GetNextBlockToEmit() const; 125dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray HBasicBlock* FirstNonEmptyBlock(HBasicBlock* block) const; 126bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray bool GoesToNextBlock(HBasicBlock* current, HBasicBlock* next) const; 127bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray 12886dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray size_t GetStackSlotOfParameter(HParameterValue* parameter) const { 12986dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray // Note that this follows the current calling convention. 13086dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray return GetFrameSize() 13186dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray + kVRegSize // Art method 132e27f31a81636ad74bd3376ee39cf215941b85c0eNicolas Geoffray + parameter->GetIndex() * kVRegSize; 13386dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray } 13486dbb9a12119273039ce272b41c809fa548b37b6Nicolas Geoffray 13592a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray virtual void Initialize() = 0; 13632f5b4d2c8c9b52e9522941c159577b21752d0faSerban Constantinescu virtual void Finalize(CodeAllocator* allocator); 137d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual void GenerateFrameEntry() = 0; 138d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray virtual void GenerateFrameExit() = 0; 13992a73aef279be78e3c2b04db1713076183933436Nicolas Geoffray virtual void Bind(HBasicBlock* block) = 0; 1404a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray virtual void Move(HInstruction* instruction, Location location, HInstruction* move_for) = 0; 141787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray virtual Assembler* GetAssembler() = 0; 142707c809f661554713edfacf338365adca8dfd3a3Nicolas Geoffray virtual size_t GetWordSize() const = 0; 143f85a9ca9859ad843dc03d3a2b600afbaf2e9bbddMark Mendell virtual size_t GetFloatingPointSpillSlotSize() const = 0; 144de58ab2c03ff8112b07ab827c8fa38f670dfc656Nicolas Geoffray virtual uintptr_t GetAddressOf(HBasicBlock* block) const = 0; 1454c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray void InitializeCodeGeneration(size_t number_of_spill_slots, 1464c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray size_t maximum_number_of_live_core_registers, 1474c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray size_t maximum_number_of_live_fp_registers, 1484c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray size_t number_of_out_slots, 1494c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray const GrowableArray<HBasicBlock*>& block_order); 150ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray int32_t GetStackSlot(HLocal* local) const; 151ab032bc1ff57831106fdac6a91a136293609401fNicolas Geoffray Location GetTemporaryLocation(HTemporary* temp) const; 152787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 153787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray uint32_t GetFrameSize() const { return frame_size_; } 154787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray void SetFrameSize(uint32_t size) { frame_size_ = size; } 1558ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t GetCoreSpillMask() const { return core_spill_mask_; } 156d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray uint32_t GetFpuSpillMask() const { return fpu_spill_mask_; } 1578ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray 15871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t GetNumberOfCoreRegisters() const { return number_of_core_registers_; } 15971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t GetNumberOfFloatingPointRegisters() const { return number_of_fpu_registers_; } 160988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray virtual void SetupBlockedRegisters(bool is_baseline) const = 0; 16171175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray 1624dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray virtual void ComputeSpillMask() { 1634dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray core_spill_mask_ = allocated_registers_.GetCoreRegisters() & core_callee_save_mask_; 1644dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray DCHECK_NE(core_spill_mask_, 0u) << "At least the return address register must be saved"; 1654dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray fpu_spill_mask_ = allocated_registers_.GetFloatingPointRegisters() & fpu_callee_save_mask_; 1664dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray } 1674dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray 1684dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray static uint32_t ComputeRegisterMask(const int* registers, size_t length) { 1694dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray uint32_t mask = 0; 1704dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray for (size_t i = 0, e = length; i < e; ++i) { 1714dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray mask |= (1 << registers[i]); 1724dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray } 1734dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray return mask; 1744dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray } 1754dee636d21d9ce54386cdfbb824e5eb2a9c1af0dNicolas Geoffray 176a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray virtual void DumpCoreRegister(std::ostream& stream, int reg) const = 0; 177a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray virtual void DumpFloatingPointRegister(std::ostream& stream, int reg) const = 0; 178412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray virtual InstructionSet GetInstructionSet() const = 0; 179cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle 180cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& GetCompilerOptions() const { return compiler_options_; } 181cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle 182102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray // Saves the register in the stack. Returns the size taken on stack. 183102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray virtual size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) = 0; 184102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray // Restores the register from the stack. Returns the size taken on stack. 185102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray virtual size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) = 0; 186234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray 187234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray virtual size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) = 0; 188234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray virtual size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) = 0; 189234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray 190840e5461a85f8908f51e7f6cd562a9129ff0e7ceNicolas Geoffray virtual bool NeedsTwoRegisters(Primitive::Type type) const = 0; 191234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray // Returns whether we should split long moves in parallel moves. 192234d69d075d1608f80adb647f7935077b62b6376Nicolas Geoffray virtual bool ShouldSplitLongMoves() const { return false; } 193a7062e05e6048c7f817d784a5b94e3122e25b1ecNicolas Geoffray 194988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray bool IsCoreCalleeSaveRegister(int reg) const { 195988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray return (core_callee_save_mask_ & (1 << reg)) != 0; 196988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray } 197988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray 198988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray bool IsFloatingPointCalleeSaveRegister(int reg) const { 199988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray return (fpu_callee_save_mask_ & (1 << reg)) != 0; 200988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray } 201988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray 202eeefa1276e83776f08704a3db4237423b0627e20Nicolas Geoffray void RecordPcInfo(HInstruction* instruction, uint32_t dex_pc, SlowPathCode* slow_path = nullptr); 20377520bca97ec44e3758510cebd0f20e3bb4584eaCalin Juravle bool CanMoveNullCheckToUser(HNullCheck* null_check); 20477520bca97ec44e3758510cebd0f20e3bb4584eaCalin Juravle void MaybeRecordImplicitNullCheck(HInstruction* instruction); 205787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 206e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray void AddSlowPath(SlowPathCode* slow_path) { 207e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray slow_paths_.Add(slow_path); 208e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray } 209e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray 210c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky void BuildSourceMap(DefaultSrcMap* src_map) const; 211c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky void BuildMappingTable(std::vector<uint8_t>* vector) const; 2128ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray void BuildVMapTable(std::vector<uint8_t>* vector) const; 21392cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray void BuildNativeGCMap( 21492cf83e001357329cbf41fa15a6e053fab6f4933Nicolas Geoffray std::vector<uint8_t>* vector, const DexCompilationUnit& dex_compilation_unit) const; 2153946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray void BuildStackMaps(std::vector<uint8_t>* vector); 216787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray 217f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray bool IsLeafMethod() const { 218f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray return is_leaf_; 219f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray } 220f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray 221f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray void MarkNotLeaf() { 222f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray is_leaf_ = false; 223c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray requires_current_method_ = true; 224c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray } 225c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray 226c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray void SetRequiresCurrentMethod() { 227c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray requires_current_method_ = true; 228c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray } 229c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray 230c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray bool RequiresCurrentMethod() const { 231c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray return requires_current_method_; 232f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray } 233f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray 2343c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // Clears the spill slots taken by loop phis in the `LocationSummary` of the 2353c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // suspend check. This is called when the code generator generates code 2363c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // for the suspend check at the back edge (instead of where the suspend check 2373c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // is, which is the loop entry). At this point, the spill slots for the phis 2383c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray // have not been written to. 2393c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray void ClearSpillSlotsFromLoopPhisInStackMap(HSuspendCheck* suspend_check) const; 2403c04974a90b0e03f4b509010bff49f0b2a3da57fNicolas Geoffray 24171175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* GetBlockedCoreRegisters() const { return blocked_core_registers_; } 242102cbed1e52b7c5f09458b44903fe97bb3e14d5fNicolas Geoffray bool* GetBlockedFloatingPointRegisters() const { return blocked_fpu_registers_; } 24371175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray 24419a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray // Helper that returns the pointer offset of an index in an object array. 24519a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray // Note: this method assumes we always have the same pointer size, regardless 24619a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray // of the architecture. 24719a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray static size_t GetCacheOffset(uint32_t index); 24819a19cffd197a28ae4c9c3e59eff6352fd392241Nicolas Geoffray 2499021825d1e73998b99c81e89c73796f6f2845471Nicolas Geoffray void EmitParallelMoves(Location from1, 2509021825d1e73998b99c81e89c73796f6f2845471Nicolas Geoffray Location to1, 2519021825d1e73998b99c81e89c73796f6f2845471Nicolas Geoffray Primitive::Type type1, 2529021825d1e73998b99c81e89c73796f6f2845471Nicolas Geoffray Location from2, 2539021825d1e73998b99c81e89c73796f6f2845471Nicolas Geoffray Location to2, 2549021825d1e73998b99c81e89c73796f6f2845471Nicolas Geoffray Primitive::Type type2); 255f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray 256af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray static bool StoreNeedsWriteBarrier(Primitive::Type type, HInstruction* value) { 257522e2241f5b5f331d0aa2f8508f4c97973f7f012David Brazdil // Check that null value is not represented as an integer constant. 258522e2241f5b5f331d0aa2f8508f4c97973f7f012David Brazdil DCHECK(type != Primitive::kPrimNot || !value->IsIntConstant()); 259522e2241f5b5f331d0aa2f8508f4c97973f7f012David Brazdil return type == Primitive::kPrimNot && !value->IsNullConstant(); 260af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray } 261af07bc121121d7bd7e8329c55dfe24782207b561Nicolas Geoffray 262988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray void AddAllocatedRegister(Location location) { 263988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray allocated_registers_.Add(location); 264988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray } 265988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray 266c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray void AllocateLocations(HInstruction* instruction); 267c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray 268aa9b7c48069699e2aabedc6c0f62cb131fee0c73Roland Levillain // Tells whether the stack frame of the compiled method is 269aa9b7c48069699e2aabedc6c0f62cb131fee0c73Roland Levillain // considered "empty", that is either actually having a size of zero, 270aa9b7c48069699e2aabedc6c0f62cb131fee0c73Roland Levillain // or just containing the saved return address register. 271aa9b7c48069699e2aabedc6c0f62cb131fee0c73Roland Levillain bool HasEmptyFrame() const { 272aa9b7c48069699e2aabedc6c0f62cb131fee0c73Roland Levillain return GetFrameSize() == (CallPushesPC() ? GetWordSize() : 0); 273aa9b7c48069699e2aabedc6c0f62cb131fee0c73Roland Levillain } 274aa9b7c48069699e2aabedc6c0f62cb131fee0c73Roland Levillain 275d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray static int32_t GetInt32ValueOf(HConstant* constant) { 276d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray if (constant->IsIntConstant()) { 277d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray return constant->AsIntConstant()->GetValue(); 278d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } else if (constant->IsNullConstant()) { 279d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray return 0; 280d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } else { 281d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray DCHECK(constant->IsFloatConstant()); 282da4d79bc9a4aeb9da7c6259ce4c9c1c3bf545eb8Roland Levillain return bit_cast<int32_t, float>(constant->AsFloatConstant()->GetValue()); 283d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } 284d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } 285d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray 286d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray static int64_t GetInt64ValueOf(HConstant* constant) { 287d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray if (constant->IsIntConstant()) { 288d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray return constant->AsIntConstant()->GetValue(); 289d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } else if (constant->IsNullConstant()) { 290d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray return 0; 291d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } else if (constant->IsFloatConstant()) { 292da4d79bc9a4aeb9da7c6259ce4c9c1c3bf545eb8Roland Levillain return bit_cast<int32_t, float>(constant->AsFloatConstant()->GetValue()); 293d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } else if (constant->IsLongConstant()) { 294d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray return constant->AsLongConstant()->GetValue(); 295d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } else { 296d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray DCHECK(constant->IsDoubleConstant()); 297da4d79bc9a4aeb9da7c6259ce4c9c1c3bf545eb8Roland Levillain return bit_cast<int64_t, double>(constant->AsDoubleConstant()->GetValue()); 298d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } 299d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray } 300d6138ef1ea13d07ae555542f8898b30d89e9ac9aNicolas Geoffray 301a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray size_t GetFirstRegisterSlotInSlowPath() const { 302a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray return first_register_slot_in_slow_path_; 303a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray } 304a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray 305a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray uint32_t FrameEntrySpillSize() const { 306a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray return GetFpuSpillSize() + GetCoreSpillSize(); 307a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray } 308a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray 309a8ac9130b872c080299afacf5dcaab513d13ea87Nicolas Geoffray 310787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray protected: 31171175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray CodeGenerator(HGraph* graph, 31271175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_core_registers, 31371175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_fpu_registers, 314cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle size_t number_of_register_pairs, 315988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray uint32_t core_callee_save_mask, 316988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray uint32_t fpu_callee_save_mask, 317cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& compiler_options) 318c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray : frame_size_(0), 3194361beff5bc540c43ab7c072c99994adc4ed78f9Nicolas Geoffray core_spill_mask_(0), 320d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray fpu_spill_mask_(0), 3213bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray first_register_slot_in_slow_path_(0), 32271175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray blocked_core_registers_(graph->GetArena()->AllocArray<bool>(number_of_core_registers)), 32371175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray blocked_fpu_registers_(graph->GetArena()->AllocArray<bool>(number_of_fpu_registers)), 32471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray blocked_register_pairs_(graph->GetArena()->AllocArray<bool>(number_of_register_pairs)), 32571175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray number_of_core_registers_(number_of_core_registers), 32671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray number_of_fpu_registers_(number_of_fpu_registers), 32771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray number_of_register_pairs_(number_of_register_pairs), 328988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray core_callee_save_mask_(core_callee_save_mask), 329988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray fpu_callee_save_mask_(fpu_callee_save_mask), 330787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray graph_(graph), 331cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle compiler_options_(compiler_options), 332a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray pc_infos_(graph->GetArena(), 32), 333e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray slow_paths_(graph->GetArena(), 8), 3344c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray block_order_(nullptr), 3354c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray current_block_index_(0), 3363946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray is_leaf_(true), 337c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray requires_current_method_(false), 3383946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray stack_map_stream_(graph->GetArena()) {} 339d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 340a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray // Register allocation logic. 341a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray void AllocateRegistersLocally(HInstruction* instruction) const; 342a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 343a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray // Backend specific implementation for allocating a register. 34471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray virtual Location AllocateFreeRegister(Primitive::Type type) const = 0; 345a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 34671175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray static size_t FindFreeEntry(bool* array, size_t length); 3473c03503d66df3b4440f851ae7d0c4fae5e7872dfNicolas Geoffray static size_t FindTwoFreeConsecutiveAlignedEntries(bool* array, size_t length); 348a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 349a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray virtual Location GetStackLocation(HLoadLocal* load) const = 0; 350a7aca370a7d62ca04a1e24423d90e8020d6f1a58Nicolas Geoffray 351f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray virtual ParallelMoveResolver* GetMoveResolver() = 0; 352c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray virtual HGraphVisitor* GetLocationBuilder() = 0; 353c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray virtual HGraphVisitor* GetInstructionVisitor() = 0; 354f0e3937b87453234d0d7970b8712082062709b8dNicolas Geoffray 355d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray // Returns the location of the first spilled entry for floating point registers, 356d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray // relative to the stack pointer. 357d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray uint32_t GetFpuSpillStart() const { 358d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray return GetFrameSize() - FrameEntrySpillSize(); 359d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray } 360d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray 361d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray uint32_t GetFpuSpillSize() const { 362d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray return POPCOUNT(fpu_spill_mask_) * GetFloatingPointSpillSlotSize(); 363d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray } 364d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray 365d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray uint32_t GetCoreSpillSize() const { 366d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray return POPCOUNT(core_spill_mask_) * GetWordSize(); 367d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray } 368d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray 369c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray bool HasAllocatedCalleeSaveRegisters() const { 370c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray // We check the core registers against 1 because it always comprises the return PC. 371c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray return (POPCOUNT(allocated_registers_.GetCoreRegisters() & core_callee_save_mask_) != 1) 372c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray || (POPCOUNT(allocated_registers_.GetFloatingPointRegisters() & fpu_callee_save_mask_) != 0); 373c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray } 374c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray 375c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray bool CallPushesPC() const { 376c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray InstructionSet instruction_set = GetInstructionSet(); 377c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray return instruction_set == kX86 || instruction_set == kX86_64; 378c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray } 379c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray 380dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray // Arm64 has its own type for a label, so we need to templatize this method 381dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray // to share the logic. 382dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray template <typename T> 383dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray T* CommonGetLabelOf(T* raw_pointer_to_labels_array, HBasicBlock* block) const { 384dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray block = FirstNonEmptyBlock(block); 385dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray return raw_pointer_to_labels_array + block->GetBlockId(); 386dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray } 387dc23d8318db08cb42e20f1d16dbc416798951a8bNicolas Geoffray 3888ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray // Frame size required for this method. 3898ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t frame_size_; 3908ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray uint32_t core_spill_mask_; 391d97dc40d186aec46bfd318b6a2026a98241d7e9cNicolas Geoffray uint32_t fpu_spill_mask_; 3923bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray uint32_t first_register_slot_in_slow_path_; 3938ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray 394988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray // Registers that were allocated during linear scan. 395988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray RegisterSet allocated_registers_; 396988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray 39771175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray // Arrays used when doing register allocation to know which 39871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray // registers we can allocate. `SetupBlockedRegisters` updates the 39971175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray // arrays. 40071175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* const blocked_core_registers_; 40171175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* const blocked_fpu_registers_; 40271175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray bool* const blocked_register_pairs_; 40371175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_core_registers_; 40471175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_fpu_registers_; 40571175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray size_t number_of_register_pairs_; 406988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray const uint32_t core_callee_save_mask_; 407988939683c26c0b1c8808fc206add6337319509aNicolas Geoffray const uint32_t fpu_callee_save_mask_; 40871175b7f19a4f6cf9cc264feafd820dbafa371fbNicolas Geoffray 409bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray private: 410c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray void InitLocationsBaseline(HInstruction* instruction); 4113bca0df855f0e575c6ee020ed016999fc8f14122Nicolas Geoffray size_t GetStackOffsetOfSavedRegister(size_t index); 4124c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray void CompileInternal(CodeAllocator* allocator, bool is_baseline); 4135f8741860d465410bfed495dbb5f794590d338daMark Mendell void BlockIfInRegister(Location location, bool is_out = false) const; 414d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 415787c3076635cf117eb646c5a89a9014b2072fb44Nicolas Geoffray HGraph* const graph_; 416cd6dffedf1bd8e6dfb3fb0c933551f9a90f7de3fCalin Juravle const CompilerOptions& compiler_options_; 417d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 4188ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray GrowableArray<PcInfo> pc_infos_; 419e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray GrowableArray<SlowPathCode*> slow_paths_; 420d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 4214c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray // The order to use for code generation. 4224c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray const GrowableArray<HBasicBlock*>* block_order_; 4234c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray 4244c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray // The current block index in `block_order_` of the block 4254c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray // we are generating code for. 4264c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray size_t current_block_index_; 4274c204bafbc8d596894f8cb8ec696f5be1c6f12d8Nicolas Geoffray 428c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray // Whether the method is a leaf method. 429f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray bool is_leaf_; 430f12feb8e0e857f2832545b3f28d31bad5a9d3903Nicolas Geoffray 431c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray // Whether an instruction in the graph accesses the current method. 432c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray bool requires_current_method_; 433c0572a451944f78397619dec34a38c36c11e9d2aNicolas Geoffray 4343946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray StackMapStream stack_map_stream_; 4353946844c34ad965515f677084b07d663d70ad1b8Nicolas Geoffray 436c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky friend class OptimizingCFITest; 437c6b4dd8980350aaf250f0185f73e9c42ec17cd57David Srbecky 438d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(CodeGenerator); 439d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray}; 440d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 4417fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffraytemplate <typename C, typename F> 4424a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffrayclass CallingConvention { 4434a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray public: 4447fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray CallingConvention(const C* registers, 4457fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t number_of_registers, 4467fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const F* fpu_registers, 4477fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t number_of_fpu_registers) 4487fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray : registers_(registers), 4497fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray number_of_registers_(number_of_registers), 4507fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray fpu_registers_(fpu_registers), 4517fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray number_of_fpu_registers_(number_of_fpu_registers) {} 4524a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 4534a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray size_t GetNumberOfRegisters() const { return number_of_registers_; } 4547fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t GetNumberOfFpuRegisters() const { return number_of_fpu_registers_; } 4554a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 4567fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray C GetRegisterAt(size_t index) const { 4574a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray DCHECK_LT(index, number_of_registers_); 4584a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray return registers_[index]; 4594a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray } 4604a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 4617fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray F GetFpuRegisterAt(size_t index) const { 4627fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray DCHECK_LT(index, number_of_fpu_registers_); 4637fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray return fpu_registers_[index]; 4647fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray } 4657fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray 4667fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray size_t GetStackOffsetOf(size_t index) const { 4674a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray // We still reserve the space for parameters passed by registers. 4689cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray // Add one for the method pointer. 4699cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray return (index + 1) * kVRegSize; 4704a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray } 4714a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 4724a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray private: 4737fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const C* registers_; 4744a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray const size_t number_of_registers_; 4757fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const F* fpu_registers_; 4767fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray const size_t number_of_fpu_registers_; 4774a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 4784a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray DISALLOW_COPY_AND_ASSIGN(CallingConvention); 4794a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray}; 4804a34a428c6a2588e0857ef6baf88f1b73ce65958Nicolas Geoffray 481d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray} // namespace art 482d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray 483d4dd255db1d110ceb5551f6d95ff31fb57420994Nicolas Geoffray#endif // ART_COMPILER_OPTIMIZING_CODE_GENERATOR_H_ 484