blob: 83da3781b4315542a4dc7816a57871b610daf514 [file] [log] [blame]
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +01001/*
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_SSA_BUILDER_H_
18#define ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_
19
Vladimir Marko71bf8092015-09-15 15:33:14 +010020#include "base/arena_containers.h"
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010021#include "nodes.h"
Nicolas Geoffray31596742014-11-24 15:28:45 +000022#include "optimization.h"
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010023
24namespace art {
25
David Brazdil60328912016-04-04 17:47:42 +000026static constexpr int kDefaultNumberOfLoops = 2;
27
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000028/**
29 * Transforms a graph into SSA form. The liveness guarantees of
30 * this transformation are listed below. A DEX register
31 * being killed means its value at a given position in the code
32 * will not be available to its environment uses. A merge in the
33 * following text is materialized as a `HPhi`.
34 *
35 * (a) Dex registers that do not require merging (that is, they do not
36 * have different values at a join block) are available to all their
Nicolas Geoffray915b9d02015-03-11 15:11:19 +000037 * environment uses. Note that it does not imply the instruction will
38 * have a physical location after register allocation. See the
39 * SsaLivenessAnalysis phase.
Nicolas Geoffraye0fe7ae2015-03-09 10:02:49 +000040 *
41 * (b) Dex registers that require merging, and the merging gives
42 * incompatible types, will be killed for environment uses of that merge.
43 *
44 * (c) When the `debuggable` flag is passed to the compiler, Dex registers
45 * that require merging and have a proper type after the merge, are
46 * available to all their environment uses. If the `debuggable` flag
47 * is not set, values of Dex registers only used by environments
48 * are killed.
49 */
David Brazdil60328912016-04-04 17:47:42 +000050class SsaBuilder : public HGraphVisitor {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010051 public:
David Brazdil60328912016-04-04 17:47:42 +000052 SsaBuilder(HGraph* graph, const DexFile::CodeItem& code_item, StackHandleScopeCollection* handles)
53 : HGraphVisitor(graph),
54 code_item_(code_item),
David Brazdil4833f5a2015-12-16 10:37:39 +000055 handles_(handles),
56 agets_fixed_(false),
David Brazdil60328912016-04-04 17:47:42 +000057 current_locals_(nullptr),
58 loop_headers_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
59 ambiguous_agets_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
60 ambiguous_asets_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
61 uninitialized_strings_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
62 locals_for_(graph->GetBlocks().size(),
63 ArenaVector<HInstruction*>(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
64 graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
65 loop_headers_.reserve(kDefaultNumberOfLoops);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010066 }
67
Nicolas Geoffray15bd2282016-01-05 15:55:41 +000068 GraphAnalysisResult BuildSsa();
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010069
David Brazdil60328912016-04-04 17:47:42 +000070 // Returns locals vector for `block`. If it is a catch block, the vector will be
71 // prepopulated with catch phis for vregs which are defined in `current_locals_`.
72 ArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block);
73 HInstruction* ValueOfLocal(HBasicBlock* block, size_t local);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010074
David Brazdil60328912016-04-04 17:47:42 +000075 void VisitBasicBlock(HBasicBlock* block) OVERRIDE;
76 void VisitLoadLocal(HLoadLocal* load) OVERRIDE;
77 void VisitStoreLocal(HStoreLocal* store) OVERRIDE;
78 void VisitInstruction(HInstruction* instruction) OVERRIDE;
79 void VisitArrayGet(HArrayGet* aget) OVERRIDE;
80 void VisitArraySet(HArraySet* aset) OVERRIDE;
81 void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE;
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +000082
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010083 private:
David Brazdil809d70f2015-11-19 10:29:39 +000084 void SetLoopHeaderPhiInputs();
David Brazdil4833f5a2015-12-16 10:37:39 +000085 void FixEnvironmentPhis();
Calin Juravlea4f88312015-04-16 12:57:19 +010086 void FixNullConstantType();
87 void EquivalentPhisCleanup();
David Brazdil4833f5a2015-12-16 10:37:39 +000088 void RunPrimitiveTypePropagation();
Calin Juravlea4f88312015-04-16 12:57:19 +010089
David Brazdil15693bf2015-12-16 10:30:45 +000090 // Attempts to resolve types of aget(-wide) instructions and type values passed
91 // to aput(-wide) instructions from reference type information on the array
92 // input. Returns false if the type of an array is unknown.
93 bool FixAmbiguousArrayOps();
David Brazdil4833f5a2015-12-16 10:37:39 +000094
95 bool TypeInputsOfPhi(HPhi* phi, ArenaVector<HPhi*>* worklist);
96 bool UpdatePrimitiveType(HPhi* phi, ArenaVector<HPhi*>* worklist);
97 void ProcessPrimitiveTypePropagationWorklist(ArenaVector<HPhi*>* worklist);
98
David Brazdil60328912016-04-04 17:47:42 +000099 HInstruction* GetFloatOrDoubleEquivalent(HInstruction* instruction, Primitive::Type type);
100 HInstruction* GetReferenceTypeEquivalent(HInstruction* instruction);
101
David Brazdil4833f5a2015-12-16 10:37:39 +0000102 HFloatConstant* GetFloatEquivalent(HIntConstant* constant);
103 HDoubleConstant* GetDoubleEquivalent(HLongConstant* constant);
104 HPhi* GetFloatDoubleOrReferenceEquivalentOfPhi(HPhi* phi, Primitive::Type type);
105 HArrayGet* GetFloatOrDoubleEquivalentOfArrayGet(HArrayGet* aget);
106
David Brazdil65902e82016-01-15 09:35:13 +0000107 void RemoveRedundantUninitializedStrings();
108
David Brazdil60328912016-04-04 17:47:42 +0000109 // Returns whether `instruction` is the first generated HInstruction for its
110 // dex_pc position.
111 bool IsFirstAtThrowingDexPc(HInstruction* instruction) const;
112
113 const DexFile::CodeItem& code_item_;
David Brazdil4833f5a2015-12-16 10:37:39 +0000114 StackHandleScopeCollection* const handles_;
115
116 // True if types of ambiguous ArrayGets have been resolved.
117 bool agets_fixed_;
David Brazdil8d5b8b22015-03-24 10:51:52 +0000118
David Brazdil60328912016-04-04 17:47:42 +0000119 // Locals for the current block being visited.
120 ArenaVector<HInstruction*>* current_locals_;
121
122 // Keep track of loop headers found. The last phase of the analysis iterates
123 // over these blocks to set the inputs of their phis.
124 ArenaVector<HBasicBlock*> loop_headers_;
125
David Brazdil4833f5a2015-12-16 10:37:39 +0000126 ArenaVector<HArrayGet*> ambiguous_agets_;
David Brazdil15693bf2015-12-16 10:30:45 +0000127 ArenaVector<HArraySet*> ambiguous_asets_;
David Brazdil65902e82016-01-15 09:35:13 +0000128 ArenaVector<HNewInstance*> uninitialized_strings_;
David Brazdil4833f5a2015-12-16 10:37:39 +0000129
David Brazdil60328912016-04-04 17:47:42 +0000130 // HEnvironment for each block.
131 ArenaVector<ArenaVector<HInstruction*>> locals_for_;
132
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100133 DISALLOW_COPY_AND_ASSIGN(SsaBuilder);
134};
135
136} // namespace art
137
138#endif // ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_