blob: 2dae9c2de04f6294d8e90bec23c494c7417f50c8 [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
26static 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 */
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010050class SsaBuilder : public HGraphVisitor {
51 public:
Nicolas Geoffray15bd2282016-01-05 15:55:41 +000052 SsaBuilder(HGraph* graph, StackHandleScopeCollection* handles)
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010053 : HGraphVisitor(graph),
David Brazdil4833f5a2015-12-16 10:37:39 +000054 handles_(handles),
55 agets_fixed_(false),
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010056 current_locals_(nullptr),
Vladimir Marko71bf8092015-09-15 15:33:14 +010057 loop_headers_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
David Brazdil4833f5a2015-12-16 10:37:39 +000058 ambiguous_agets_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
David Brazdil15693bf2015-12-16 10:30:45 +000059 ambiguous_asets_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
David Brazdil65902e82016-01-15 09:35:13 +000060 uninitialized_strings_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
Vladimir Marko71bf8092015-09-15 15:33:14 +010061 locals_for_(graph->GetBlocks().size(),
62 ArenaVector<HInstruction*>(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
63 graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
64 loop_headers_.reserve(kDefaultNumberOfLoops);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010065 }
66
Nicolas Geoffray15bd2282016-01-05 15:55:41 +000067 GraphAnalysisResult BuildSsa();
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010068
David Brazdileead0712015-09-18 14:58:57 +010069 // Returns locals vector for `block`. If it is a catch block, the vector will be
70 // prepopulated with catch phis for vregs which are defined in `current_locals_`.
71 ArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010072 HInstruction* ValueOfLocal(HBasicBlock* block, size_t local);
73
David Brazdil6de19382016-01-08 17:37:10 +000074 void VisitBasicBlock(HBasicBlock* block) OVERRIDE;
75 void VisitLoadLocal(HLoadLocal* load) OVERRIDE;
76 void VisitStoreLocal(HStoreLocal* store) OVERRIDE;
77 void VisitInstruction(HInstruction* instruction) OVERRIDE;
David Brazdil6de19382016-01-08 17:37:10 +000078 void VisitArrayGet(HArrayGet* aget) OVERRIDE;
79 void VisitArraySet(HArraySet* aset) OVERRIDE;
80 void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE;
Nicolas Geoffrayd6138ef2015-02-18 14:48:53 +000081
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010082 private:
David Brazdil809d70f2015-11-19 10:29:39 +000083 void SetLoopHeaderPhiInputs();
David Brazdil4833f5a2015-12-16 10:37:39 +000084 void FixEnvironmentPhis();
Calin Juravlea4f88312015-04-16 12:57:19 +010085 void FixNullConstantType();
86 void EquivalentPhisCleanup();
David Brazdil4833f5a2015-12-16 10:37:39 +000087 void RunPrimitiveTypePropagation();
Calin Juravlea4f88312015-04-16 12:57:19 +010088
David Brazdil15693bf2015-12-16 10:30:45 +000089 // Attempts to resolve types of aget(-wide) instructions and type values passed
90 // to aput(-wide) instructions from reference type information on the array
91 // input. Returns false if the type of an array is unknown.
92 bool FixAmbiguousArrayOps();
David Brazdil4833f5a2015-12-16 10:37:39 +000093
94 bool TypeInputsOfPhi(HPhi* phi, ArenaVector<HPhi*>* worklist);
95 bool UpdatePrimitiveType(HPhi* phi, ArenaVector<HPhi*>* worklist);
96 void ProcessPrimitiveTypePropagationWorklist(ArenaVector<HPhi*>* worklist);
97
98 HInstruction* GetFloatOrDoubleEquivalent(HInstruction* instruction, Primitive::Type type);
99 HInstruction* GetReferenceTypeEquivalent(HInstruction* instruction);
100
101 HFloatConstant* GetFloatEquivalent(HIntConstant* constant);
102 HDoubleConstant* GetDoubleEquivalent(HLongConstant* constant);
103 HPhi* GetFloatDoubleOrReferenceEquivalentOfPhi(HPhi* phi, Primitive::Type type);
104 HArrayGet* GetFloatOrDoubleEquivalentOfArrayGet(HArrayGet* aget);
105
David Brazdil65902e82016-01-15 09:35:13 +0000106 void RemoveRedundantUninitializedStrings();
107
David Brazdil4833f5a2015-12-16 10:37:39 +0000108 StackHandleScopeCollection* const handles_;
109
110 // True if types of ambiguous ArrayGets have been resolved.
111 bool agets_fixed_;
David Brazdil8d5b8b22015-03-24 10:51:52 +0000112
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100113 // Locals for the current block being visited.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100114 ArenaVector<HInstruction*>* current_locals_;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100115
116 // Keep track of loop headers found. The last phase of the analysis iterates
117 // over these blocks to set the inputs of their phis.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100118 ArenaVector<HBasicBlock*> loop_headers_;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100119
David Brazdil4833f5a2015-12-16 10:37:39 +0000120 ArenaVector<HArrayGet*> ambiguous_agets_;
David Brazdil15693bf2015-12-16 10:30:45 +0000121 ArenaVector<HArraySet*> ambiguous_asets_;
David Brazdil65902e82016-01-15 09:35:13 +0000122 ArenaVector<HNewInstance*> uninitialized_strings_;
David Brazdil4833f5a2015-12-16 10:37:39 +0000123
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100124 // HEnvironment for each block.
Vladimir Marko71bf8092015-09-15 15:33:14 +0100125 ArenaVector<ArenaVector<HInstruction*>> locals_for_;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100126
127 DISALLOW_COPY_AND_ASSIGN(SsaBuilder);
128};
129
130} // namespace art
131
132#endif // ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_