Flutter Engine
The Flutter Engine
constant_propagator.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_
6#define RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
14
15namespace dart {
16
17// Sparse conditional constant propagation and unreachable code elimination.
18// Assumes that use lists are computed and preserves them.
20 public:
22 const GrowableArray<BlockEntryInstr*>& ignored);
23
24 static void Optimize(FlowGraph* graph);
25
26 // (1) Visit branches to optimize away unreachable blocks discovered by range
27 // analysis.
28 // (2) Eliminate branches that have the same true- and false-target: For
29 // example, this occurs after expressions like
30 //
31 // if (a == null || b == null) {
32 // ...
33 // }
34 //
35 // where b is known to be null.
36 static void OptimizeBranches(FlowGraph* graph);
37
38 // Used to initialize the abstract value of definitions.
39 static ObjectPtr Unknown() { return Object::unknown_constant().ptr(); }
40
41 private:
42 void InsertRedefinitionsAfterEqualityComparisons();
43 void Analyze();
44 void Transform();
45 // Tries to replace uses of [defn] with a constant, returns true if
46 // successful. The [value] is used as a temporary handle.
47 bool TransformDefinition(Definition* defn);
48 void EliminateRedundantBranches();
49
50 void SetReachable(BlockEntryInstr* block);
51 bool SetValue(Definition* definition, const Object& value);
52
53 // Phi might be viewed as redundant based on current reachability of
54 // predecessor blocks (i.e. the same definition is flowing from all
55 // reachable predecessors). We can use this information to constant
56 // fold phi(x) == x and phi(x) != x comparisons.
57 Definition* UnwrapPhi(Definition* defn);
58 void MarkUnwrappedPhi(Definition* defn);
59
60 // Assign the join (least upper bound) of a pair of abstract values to the
61 // first one.
62 void Join(Object* left, const Object& right);
63
64 bool IsUnknown(const Object& value) { return value.ptr() == unknown_.ptr(); }
65 bool IsNonConstant(const Object& value) {
66 return value.ptr() == non_constant_.ptr();
67 }
68 bool IsConstant(const Object& value) {
69 return !IsNonConstant(value) && !IsUnknown(value);
70 }
71
72 void VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op);
73 void VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op);
74
75 virtual void VisitBlocks() { UNREACHABLE(); }
76
77#define DECLARE_VISIT(type, attrs) virtual void Visit##type(type##Instr* instr);
79
80#undef DECLARE_VISIT
81 // Structure tracking visit counts for phis. Used to detect infinite loops.
82 struct PhiInfo {
83 PhiInstr* phi;
84 intptr_t visit_count;
85 };
86
87 // Returns PhiInfo associated with the given phi. Note that this
88 // pointer can be invalidated by subsequent call to GetPhiInfo and
89 // thus should not be stored anywhere.
90 PhiInfo* GetPhiInfo(PhiInstr* phi);
91
92 FlowGraph* graph_;
93
94 // Sentinels for unknown constant and non-constant values.
95 const Object& unknown_;
96 const Object& non_constant_;
97
98 // Temporary handle used in [TransformDefinition].
99 Object& constant_value_;
100
101 // Analysis results. For each block, a reachability bit. Indexed by
102 // preorder number.
103 BitVector* reachable_;
104
105 // Bitvector of phis that were "unwrapped" into one of their inputs
106 // when visiting one of their uses. These uses of these phis
107 // should be revisited if reachability of the predecessor blocks
108 // changes even if that does not change constant value of the phi.
109 BitVector* unwrapped_phis_;
110
111 // List of visited phis indexed by their id (stored as pass specific id on
112 // a phi instruction).
113 GrowableArray<PhiInfo> phis_;
114
115 // Worklists of blocks and definitions.
116 GrowableArray<BlockEntryInstr*> block_worklist_;
117 DefinitionWorklist definition_worklist_;
118};
119
120} // namespace dart
121
122#endif // RUNTIME_VM_COMPILER_BACKEND_CONSTANT_PROPAGATOR_H_
#define UNREACHABLE()
Definition: assert.h:248
static void Optimize(FlowGraph *graph)
static ObjectPtr Unknown()
ConstantPropagator(FlowGraph *graph, const GrowableArray< BlockEntryInstr * > &ignored)
static void OptimizeBranches(FlowGraph *graph)
ObjectPtr ptr() const
Definition: object.h:332
#define DECLARE_VISIT(type, attrs)
uint8_t value
#define FOR_EACH_INSTRUCTION(M)
Definition: il.h:405
Definition: dart_vm.cc:33