reference_type_propagation.h revision 16e528957869c7debb1f6758c9a364819e15ee1a
1184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray/* 210e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle * Copyright (C) 2015 The Android Open Source Project 3184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * 4184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License"); 5184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * you may not use this file except in compliance with the License. 6184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * You may obtain a copy of the License at 7184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * 8184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * http://www.apache.org/licenses/LICENSE-2.0 9184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * 10184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software 11184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS, 12184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * See the License for the specific language governing permissions and 14184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray * limitations under the License. 15184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray */ 16184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 1710e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle#ifndef ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_PROPAGATION_H_ 1810e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle#define ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_PROPAGATION_H_ 19184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 202aaa4b5532d30c4e65d8892b556400bb61f9dc8cVladimir Marko#include "base/arena_containers.h" 21acf735c13998ad2a175f5a17e7bfce220073279dCalin Juravle#include "driver/dex_compilation_unit.h" 22acf735c13998ad2a175f5a17e7bfce220073279dCalin Juravle#include "handle_scope-inl.h" 23184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray#include "nodes.h" 243398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier#include "obj_ptr.h" 2510e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle#include "optimization.h" 26b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle#include "optimizing_compiler_stats.h" 27184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 28184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffraynamespace art { 29184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 3010e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle/** 3110e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle * Propagates reference types to instructions. 3210e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle */ 336c0c4f230f417ed484bae5c01b79551af7659389Calin Juravleclass ReferenceTypePropagation : public HOptimization { 34184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray public: 35a5ae3c3f468ffe3a317b498d7fde1f8e9325346aCalin Juravle ReferenceTypePropagation(HGraph* graph, 368d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko Handle<mirror::ClassLoader> class_loader, 37456307a47336e3d6576ed6d8563b67573a4238d3Vladimir Marko Handle<mirror::DexCache> hint_dex_cache, 38e8a3c576301fd531d5f73a65fc8b84a63619d580Mathieu Chartier VariableSizedHandleScope* handles, 39d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray bool is_first_run, 402e76830f0b3f23825677436c0633714402715099Calin Juravle const char* name = kReferenceTypePropagationPassName); 41184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 42be10e8e99a78caae01fb65769218800d465144aeVladimir Marko // Visit a single instruction. 43be10e8e99a78caae01fb65769218800d465144aeVladimir Marko void Visit(HInstruction* instruction); 44be10e8e99a78caae01fb65769218800d465144aeVladimir Marko 4510e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle void Run() OVERRIDE; 46184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 4794ab38f01dc2cf3ed0c6e73e2a6b594c14758d67David Brazdil // Returns true if klass is admissible to the propagation: non-null and resolved. 4894ab38f01dc2cf3ed0c6e73e2a6b594c14758d67David Brazdil // For an array type, we also check if the component type is admissible. 49b45528c1f1b83ca8c970f439b54fbfcfda6908eaVladimir Marko static bool IsAdmissible(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) { 5094ab38f01dc2cf3ed0c6e73e2a6b594c14758d67David Brazdil return klass != nullptr && 5194ab38f01dc2cf3ed0c6e73e2a6b594c14758d67David Brazdil klass->IsResolved() && 5294ab38f01dc2cf3ed0c6e73e2a6b594c14758d67David Brazdil (!klass->IsArrayClass() || IsAdmissible(klass->GetComponentType())); 5394ab38f01dc2cf3ed0c6e73e2a6b594c14758d67David Brazdil } 5494ab38f01dc2cf3ed0c6e73e2a6b594c14758d67David Brazdil 557c3952f423b8213083d60596a5f0bf4237ca3f7bAndreas Gampe static constexpr const char* kReferenceTypePropagationPassName = "reference_type_propagation"; 567c3952f423b8213083d60596a5f0bf4237ca3f7bAndreas Gampe 5716e528957869c7debb1f6758c9a364819e15ee1aMads Ager // Fix the reference type for an instruction whose inputs have changed. 5816e528957869c7debb1f6758c9a364819e15ee1aMads Ager // For a select instruction, the reference types of the inputs are merged 5916e528957869c7debb1f6758c9a364819e15ee1aMads Ager // and the resulting reference type is set on the select instruction. 6016e528957869c7debb1f6758c9a364819e15ee1aMads Ager static void FixUpInstructionType(HInstruction* instruction, 6116e528957869c7debb1f6758c9a364819e15ee1aMads Ager VariableSizedHandleScope* handle_scope); 6216e528957869c7debb1f6758c9a364819e15ee1aMads Ager 63184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray private: 647d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko class HandleCache { 657d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko public: 66e8a3c576301fd531d5f73a65fc8b84a63619d580Mathieu Chartier explicit HandleCache(VariableSizedHandleScope* handles) : handles_(handles) { } 677d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko 687d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko template <typename T> 69bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe MutableHandle<T> NewHandle(T* object) REQUIRES_SHARED(Locks::mutator_lock_) { 707d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko return handles_->NewHandle(object); 717d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko } 727d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko 733398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier template <typename T> 743398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier MutableHandle<T> NewHandle(ObjPtr<T> object) REQUIRES_SHARED(Locks::mutator_lock_) { 753398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier return handles_->NewHandle(object); 763398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier } 773398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier 787d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle GetObjectClassHandle(); 797d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle GetClassClassHandle(); 807d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle GetStringClassHandle(); 817d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle GetThrowableClassHandle(); 827d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko 837d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko private: 84e8a3c576301fd531d5f73a65fc8b84a63619d580Mathieu Chartier VariableSizedHandleScope* handles_; 857d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko 867d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle object_class_handle_; 877d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle class_class_handle_; 887d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle string_class_handle_; 897d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko ReferenceTypeInfo::TypeHandle throwable_class_handle_; 907d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko }; 917d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko 927d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko class RTPVisitor; 937d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko 94b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle void VisitPhi(HPhi* phi); 95184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray void VisitBasicBlock(HBasicBlock* block); 96bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe void UpdateBoundType(HBoundType* bound_type) REQUIRES_SHARED(Locks::mutator_lock_); 97bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe void UpdatePhi(HPhi* phi) REQUIRES_SHARED(Locks::mutator_lock_); 9861d544bfb812d79f5c9ddad171198836cea719dbCalin Juravle void BoundTypeForIfNotNull(HBasicBlock* block); 99b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle void BoundTypeForIfInstanceOf(HBasicBlock* block); 100184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray void ProcessWorklist(); 101b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle void AddToWorklist(HInstruction* instr); 102b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle void AddDependentInstructionsToWorklist(HInstruction* instr); 103b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle 104b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle bool UpdateNullability(HInstruction* instr); 105b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle bool UpdateReferenceTypeInfo(HInstruction* instr); 106b1498f67b444c897fa8f1530777ef118e05aa631Calin Juravle 1077d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko static void UpdateArrayGet(HArrayGet* instr, HandleCache* handle_cache) 108bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 1097d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko 11016e528957869c7debb1f6758c9a364819e15ee1aMads Ager static ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, 11116e528957869c7debb1f6758c9a364819e15ee1aMads Ager const ReferenceTypeInfo& b, 11216e528957869c7debb1f6758c9a364819e15ee1aMads Ager HandleCache* handle_cache) 113bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 114acf735c13998ad2a175f5a17e7bfce220073279dCalin Juravle 115cdfed3dc422d0e1a9a0a948863308e58c39d01baCalin Juravle void ValidateTypes(); 116cdfed3dc422d0e1a9a0a948863308e58c39d01baCalin Juravle 1178d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko Handle<mirror::ClassLoader> class_loader_; 1188d6768d47b66a688d35399d524ad5a5450e9d9d4Vladimir Marko 119456307a47336e3d6576ed6d8563b67573a4238d3Vladimir Marko // Note: hint_dex_cache_ is usually, but not necessarily, the dex cache associated with 120456307a47336e3d6576ed6d8563b67573a4238d3Vladimir Marko // graph_->GetDexFile(). Since we may look up also in other dex files, it's used only 121456307a47336e3d6576ed6d8563b67573a4238d3Vladimir Marko // as a hint, to reduce the number of calls to the costly ClassLinker::FindDexCache(). 122456307a47336e3d6576ed6d8563b67573a4238d3Vladimir Marko Handle<mirror::DexCache> hint_dex_cache_; 1237d1fbf38412078090e81e9d9fa502635d8541707Vladimir Marko HandleCache handle_cache_; 124184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 1252aaa4b5532d30c4e65d8892b556400bb61f9dc8cVladimir Marko ArenaVector<HInstruction*> worklist_; 126184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 127d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray // Whether this reference type propagation is the first run we are doing. 128d9994f069dfeaa32ba929ca78816b5b83e2a4134Nicolas Geoffray const bool is_first_run_; 1292e76830f0b3f23825677436c0633714402715099Calin Juravle 130184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray static constexpr size_t kDefaultWorklistSize = 8; 131184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 1328b3f9b246d5bdbf67faeb2b872b75b8d72777bc0Aart Bik friend class ReferenceTypePropagationTest; 1338b3f9b246d5bdbf67faeb2b872b75b8d72777bc0Aart Bik 13410e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle DISALLOW_COPY_AND_ASSIGN(ReferenceTypePropagation); 135184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray}; 136184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 137184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray} // namespace art 138184d640d2a3ac86d871dab58386a50cc9bb973f9Nicolas Geoffray 13910e244f9e7f6d96a95c910a2bedef5bd3810c637Calin Juravle#endif // ART_COMPILER_OPTIMIZING_REFERENCE_TYPE_PROPAGATION_H_ 140