Flutter Engine
The Flutter Engine
block_builder.h
Go to the documentation of this file.
1// Copyright (c) 2019, 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_BLOCK_BUILDER_H_
6#define RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_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 {
16namespace compiler {
17
18// Helper class for building basic blocks in SSA form.
19class BlockBuilder : public ValueObject {
20 public:
22 BlockEntryInstr* entry,
23 bool with_frame = true)
24 : flow_graph_(flow_graph),
25 source_(InstructionSource(flow_graph_->function().token_pos(),
26 flow_graph->inlining_id())),
27 entry_(entry),
28 current_(entry),
29 dummy_env_(new Environment(0, 0, 0, flow_graph->function(), nullptr)),
30 with_frame_(with_frame) {
31 // Some graph transformations use environments from block entries.
32 entry->SetEnvironment(dummy_env_);
33 }
34
36 flow_graph_->AllocateSSAIndex(def);
37 auto normal_entry = flow_graph_->graph_entry()->normal_entry();
38 flow_graph_->AddToInitialDefinitions(normal_entry, def);
39 return def;
40 }
41
42 template <typename T>
43 T* AddDefinition(T* def) {
44 flow_graph_->AllocateSSAIndex(def);
45 AddInstruction(def);
46 return def;
47 }
48
49 template <typename T>
50 T* AddInstruction(T* instr) {
51 if (instr->ComputeCanDeoptimize() ||
52 instr->ComputeCanDeoptimizeAfterCall() ||
53 instr->CanBecomeDeoptimizationTarget()) {
54 // All instructions that can deoptimize must have an environment attached
55 // to them.
56 instr->SetEnvironment(dummy_env_);
57 }
58 current_ = current_->AppendInstruction(instr);
59 return instr;
60 }
61
62 const Function& function() const { return flow_graph_->function(); }
63
65 const auto& function = flow_graph_->function();
66 const auto representation = FlowGraph::ReturnRepresentationOf(function);
67 return AddReturn(value, representation);
68 }
69
72 Source(), value, CompilerState::Current().GetNextDeoptId(),
73 representation);
74 AddInstruction(instr);
75 entry_->set_last_instruction(instr);
76 return instr;
77 }
78
79 Definition* AddParameter(intptr_t index) {
80 const auto [location, representation] =
81 flow_graph_->GetDirectParameterInfoAt(index);
82 return AddParameter(index, representation,
83 with_frame_ ? location : location.ToEntrySpRelative());
84 }
85
86 Definition* AddParameter(intptr_t index,
87 Representation representation,
88 Location location = Location()) {
89 auto normal_entry = flow_graph_->graph_entry()->normal_entry();
91 new ParameterInstr(normal_entry,
92 /*env_index=*/index,
93 /*param_index=*/index, location, representation));
94 }
95
96 TokenPosition TokenPos() const { return source_.token_pos; }
97 const InstructionSource& Source() const { return source_; }
98
100 return flow_graph_->GetConstant(Object::ZoneHandle());
101 }
102
104 // Unbox floats by first unboxing a double then converting it to a float.
105 auto const unbox_rep = rep == kUnboxedFloat
106 ? kUnboxedDouble
108 Definition* unboxed_value =
110 if (rep != unbox_rep && unboxed_value->IsUnboxInteger()) {
113 // Mark unboxing of small unboxed integer representations as truncating.
114 unboxed_value->AsUnboxInteger()->mark_truncating();
115 }
116 if (is_checked) {
117 // The type of |value| has already been checked and it is safe to
118 // adjust reaching type. This is done manually because there is no type
119 // propagation when building intrinsics.
120 unboxed_value->AsUnbox()->value()->SetReachingType(
122 }
123 if (rep == kUnboxedFloat) {
124 unboxed_value = AddDefinition(
125 new DoubleToFloatInstr(new Value(unboxed_value), DeoptId::kNone));
126 }
127 return unboxed_value;
128 }
129
131 Definition* boxed,
132 bool is_checked) {
133 return AddUnboxInstr(rep, new Value(boxed), is_checked);
134 }
135
137 TargetEntryInstr* true_successor,
138 TargetEntryInstr* false_successor) {
139 auto branch =
140 new BranchInstr(comp, CompilerState::Current().GetNextDeoptId());
141 // Some graph transformations use environments from branches.
142 branch->SetEnvironment(dummy_env_);
143 current_->AppendInstruction(branch);
144 current_ = nullptr;
145
146 *branch->true_successor_address() = true_successor;
147 *branch->false_successor_address() = false_successor;
148
149 return branch;
150 }
151
152 void AddPhi(PhiInstr* phi) {
153 flow_graph_->AllocateSSAIndex(phi);
154 phi->mark_alive();
155 entry_->AsJoinEntry()->InsertPhi(phi);
156 }
157
158 Instruction* last() const { return current_; }
159
160 private:
161 FlowGraph* const flow_graph_;
162 const InstructionSource source_;
163 BlockEntryInstr* entry_;
164 Instruction* current_;
165 Environment* dummy_env_;
166 const bool with_frame_;
167};
168
169} // namespace compiler
170} // namespace dart
171
172#endif // RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
void set_last_instruction(Instruction *instr)
Definition: il.h:1687
static CompileType FromUnboxedRepresentation(Representation rep)
static CompilerState & Current()
static constexpr intptr_t kNone
Definition: deopt_id.h:27
GraphEntryInstr * graph_entry() const
Definition: flow_graph.h:268
ConstantInstr * GetConstant(const Object &object, Representation representation=kTagged)
Definition: flow_graph.cc:187
static Representation ReturnRepresentationOf(const Function &function)
Definition: flow_graph.cc:125
const std::pair< Location, Representation > & GetDirectParameterInfoAt(intptr_t i)
Definition: flow_graph.h:571
const Function & function() const
Definition: flow_graph.h:130
void AllocateSSAIndex(Definition *def)
Definition: flow_graph.h:274
void AddToInitialDefinitions(BlockEntryWithInitialDefs *entry, Definition *defn)
Definition: flow_graph.cc:263
FunctionEntryInstr * normal_entry() const
Definition: il.h:2001
void SetEnvironment(Environment *deopt_env)
Definition: il.cc:1272
Instruction * AppendInstruction(Instruction *tail)
Definition: il.cc:1341
static Object & ZoneHandle()
Definition: object.h:419
void mark_alive()
Definition: il.h:2828
static UnboxInstr * Create(Representation to, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
Definition: il.cc:4043
Definition: il.h:75
BlockBuilder(FlowGraph *flow_graph, BlockEntryInstr *entry, bool with_frame=true)
Definition: block_builder.h:21
DartReturnInstr * AddReturn(Value *value, Representation representation)
Definition: block_builder.h:70
Definition * AddUnboxInstr(Representation rep, Value *value, bool is_checked)
Definition * AddUnboxInstr(Representation rep, Definition *boxed, bool is_checked)
void AddPhi(PhiInstr *phi)
DartReturnInstr * AddReturn(Value *value)
Definition: block_builder.h:64
Definition * AddParameter(intptr_t index, Representation representation, Location location=Location())
Definition: block_builder.h:86
BranchInstr * AddBranch(ComparisonInstr *comp, TargetEntryInstr *true_successor, TargetEntryInstr *false_successor)
TokenPosition TokenPos() const
Definition: block_builder.h:96
Definition * AddParameter(intptr_t index)
Definition: block_builder.h:79
Definition * AddNullDefinition()
Definition: block_builder.h:99
Instruction * last() const
const InstructionSource & Source() const
Definition: block_builder.h:97
Definition * AddToInitialDefinitions(Definition *def)
Definition: block_builder.h:35
const Function & function() const
Definition: block_builder.h:62
#define ASSERT(E)
uint8_t value
Definition: dart_vm.cc:33
Representation
Definition: locations.h:66
#define T
Definition: precompiler.cc:65
static constexpr Representation NativeRepresentation(Representation rep)
Definition: il.h:8504
const TokenPosition token_pos
static constexpr size_t ValueSize(Representation rep)
Definition: locations.h:112