Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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);
68 Source(), value, CompilerState::Current().GetNextDeoptId(),
69 representation);
70 AddInstruction(instr);
71 entry_->set_last_instruction(instr);
72 return instr;
73 }
74
75 Definition* AddParameter(intptr_t index) {
76 const auto [location, representation] =
77 flow_graph_->GetDirectParameterInfoAt(index);
78 return AddParameter(index, representation,
79 with_frame_ ? location : location.ToEntrySpRelative());
80 }
81
82 Definition* AddParameter(intptr_t index,
83 Representation representation,
84 Location location = Location()) {
85 auto normal_entry = flow_graph_->graph_entry()->normal_entry();
87 new ParameterInstr(normal_entry,
88 /*env_index=*/index,
89 /*param_index=*/index, location, representation));
90 }
91
92 TokenPosition TokenPos() const { return source_.token_pos; }
93 const InstructionSource& Source() const { return source_; }
94
96 return flow_graph_->GetConstant(Object::ZoneHandle());
97 }
98
99 Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) {
100 // Unbox floats by first unboxing a double then converting it to a float.
101 auto const unbox_rep = rep == kUnboxedFloat
102 ? kUnboxedDouble
104 Definition* unboxed_value =
106 if (rep != unbox_rep && unboxed_value->IsUnboxInteger()) {
109 // Mark unboxing of small unboxed integer representations as truncating.
110 unboxed_value->AsUnboxInteger()->mark_truncating();
111 }
112 if (is_checked) {
113 // The type of |value| has already been checked and it is safe to
114 // adjust reaching type. This is done manually because there is no type
115 // propagation when building intrinsics.
116 unboxed_value->AsUnbox()->value()->SetReachingType(
118 }
119 if (rep == kUnboxedFloat) {
120 unboxed_value = AddDefinition(
121 new DoubleToFloatInstr(new Value(unboxed_value), DeoptId::kNone));
122 }
123 return unboxed_value;
124 }
125
127 Definition* boxed,
128 bool is_checked) {
129 return AddUnboxInstr(rep, new Value(boxed), is_checked);
130 }
131
133 TargetEntryInstr* true_successor,
134 TargetEntryInstr* false_successor) {
135 auto branch =
136 new BranchInstr(comp, CompilerState::Current().GetNextDeoptId());
137 // Some graph transformations use environments from branches.
138 branch->SetEnvironment(dummy_env_);
139 current_->AppendInstruction(branch);
140 current_ = nullptr;
141
142 *branch->true_successor_address() = true_successor;
143 *branch->false_successor_address() = false_successor;
144
145 return branch;
146 }
147
148 void AddPhi(PhiInstr* phi) {
149 flow_graph_->AllocateSSAIndex(phi);
150 phi->mark_alive();
151 entry_->AsJoinEntry()->InsertPhi(phi);
152 }
153
154 Instruction* last() const { return current_; }
155
156 private:
157 FlowGraph* const flow_graph_;
158 const InstructionSource source_;
159 BlockEntryInstr* entry_;
160 Instruction* current_;
161 Environment* dummy_env_;
162 const bool with_frame_;
163};
164
165} // namespace compiler
166} // namespace dart
167
168#endif // RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
void set_last_instruction(Instruction *instr)
Definition il.h:1681
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)
static Representation ReturnRepresentationOf(const Function &function)
const std::pair< Location, Representation > & GetDirectParameterInfoAt(intptr_t i)
Definition flow_graph.h:573
const Function & function() const
Definition flow_graph.h:130
void AllocateSSAIndex(Definition *def)
Definition flow_graph.h:274
void AddToInitialDefinitions(BlockEntryWithInitialDefs *entry, Definition *defn)
FunctionEntryInstr * normal_entry() const
Definition il.h:1986
Instruction * AppendInstruction(Instruction *tail)
Definition il.cc:1339
static Object & ZoneHandle()
Definition object.h:419
void mark_alive()
Definition il.h:2810
static UnboxInstr * Create(Representation to, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
Definition il.cc:4045
BlockBuilder(FlowGraph *flow_graph, BlockEntryInstr *entry, bool with_frame=true)
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 * AddParameter(intptr_t index, Representation representation, Location location=Location())
BranchInstr * AddBranch(ComparisonInstr *comp, TargetEntryInstr *true_successor, TargetEntryInstr *false_successor)
TokenPosition TokenPos() const
Definition * AddParameter(intptr_t index)
Instruction * last() const
const InstructionSource & Source() const
Definition * AddToInitialDefinitions(Definition *def)
const Function & function() const
#define ASSERT(E)
uint8_t value
Representation
Definition locations.h:66
#define T
static constexpr Representation NativeRepresentation(Representation rep)
Definition il.h:8456
const TokenPosition token_pos
static constexpr size_t ValueSize(Representation rep)
Definition locations.h:112