inliner.h revision 354efa6cdf558b2331e8fec539893fa51763806e
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_OPTIMIZING_INLINER_H_
18#define ART_COMPILER_OPTIMIZING_INLINER_H_
19
20#include "invoke_type.h"
21#include "optimization.h"
22
23namespace art {
24
25class CodeGenerator;
26class CompilerDriver;
27class DexCompilationUnit;
28class HGraph;
29class HInvoke;
30class InlineCache;
31class OptimizingCompilerStats;
32
33class HInliner : public HOptimization {
34 public:
35  HInliner(HGraph* outer_graph,
36           HGraph* outermost_graph,
37           CodeGenerator* codegen,
38           const DexCompilationUnit& outer_compilation_unit,
39           const DexCompilationUnit& caller_compilation_unit,
40           CompilerDriver* compiler_driver,
41           StackHandleScopeCollection* handles,
42           OptimizingCompilerStats* stats,
43           size_t total_number_of_dex_registers,
44           size_t depth)
45      : HOptimization(outer_graph, kInlinerPassName, stats),
46        outermost_graph_(outermost_graph),
47        outer_compilation_unit_(outer_compilation_unit),
48        caller_compilation_unit_(caller_compilation_unit),
49        codegen_(codegen),
50        compiler_driver_(compiler_driver),
51        total_number_of_dex_registers_(total_number_of_dex_registers),
52        depth_(depth),
53        number_of_inlined_instructions_(0),
54        handles_(handles) {}
55
56  void Run() OVERRIDE;
57
58  static constexpr const char* kInlinerPassName = "inliner";
59
60 private:
61  bool TryInline(HInvoke* invoke_instruction);
62
63  // Try to inline `resolved_method` in place of `invoke_instruction`. `do_rtp` is whether
64  // reference type propagation can run after the inlining.
65  bool TryInline(HInvoke* invoke_instruction, ArtMethod* resolved_method, bool do_rtp = true)
66    SHARED_REQUIRES(Locks::mutator_lock_);
67
68  // Try to recognize known simple patterns and replace invoke call with appropriate instructions.
69  bool TryPatternSubstitution(HInvoke* invoke_instruction, ArtMethod* resolved_method, bool do_rtp)
70    SHARED_REQUIRES(Locks::mutator_lock_);
71
72  // Create a new HInstanceFieldGet.
73  HInstanceFieldGet* CreateInstanceFieldGet(Handle<mirror::DexCache> dex_cache,
74                                            uint32_t field_index,
75                                            HInstruction* obj);
76  // Create a new HInstanceFieldSet.
77  HInstanceFieldSet* CreateInstanceFieldSet(Handle<mirror::DexCache> dex_cache,
78                                            uint32_t field_index,
79                                            HInstruction* obj,
80                                            HInstruction* value);
81
82  // Try to inline the target of a monomorphic call. If successful, the code
83  // in the graph will look like:
84  // if (receiver.getClass() != ic.GetMonomorphicType()) deopt
85  // ... // inlined code
86  bool TryInlineMonomorphicCall(HInvoke* invoke_instruction,
87                                ArtMethod* resolved_method,
88                                const InlineCache& ic)
89    SHARED_REQUIRES(Locks::mutator_lock_);
90
91  // Try to inline targets of a polymorphic call. Currently unimplemented.
92  bool TryInlinePolymorphicCall(HInvoke* invoke_instruction,
93                                ArtMethod* resolved_method,
94                                const InlineCache& ic)
95    SHARED_REQUIRES(Locks::mutator_lock_);
96
97  bool TryBuildAndInline(ArtMethod* resolved_method,
98                         HInvoke* invoke_instruction,
99                         bool same_dex_file,
100                         bool do_rtp = true);
101
102  HInstanceFieldGet* BuildGetReceiverClass(ClassLinker* class_linker,
103                                           HInstruction* receiver,
104                                           uint32_t dex_pc) const
105    SHARED_REQUIRES(Locks::mutator_lock_);
106
107  void FixUpReturnReferenceType(ArtMethod* resolved_method,
108                                HInvoke* invoke_instruction,
109                                HInstruction* return_replacement,
110                                bool do_rtp)
111    SHARED_REQUIRES(Locks::mutator_lock_);
112
113  HGraph* const outermost_graph_;
114  const DexCompilationUnit& outer_compilation_unit_;
115  const DexCompilationUnit& caller_compilation_unit_;
116  CodeGenerator* const codegen_;
117  CompilerDriver* const compiler_driver_;
118  const size_t total_number_of_dex_registers_;
119  const size_t depth_;
120  size_t number_of_inlined_instructions_;
121  StackHandleScopeCollection* const handles_;
122
123  DISALLOW_COPY_AND_ASSIGN(HInliner);
124};
125
126}  // namespace art
127
128#endif  // ART_COMPILER_OPTIMIZING_INLINER_H_
129