Flutter Engine
The Flutter Engine
Public Member Functions | Private Member Functions | List of all members
dart::SSALivenessAnalysis Class Reference

#include <linearscan.h>

Inheritance diagram for dart::SSALivenessAnalysis:
dart::LivenessAnalysis dart::ValueObject

Public Member Functions

 SSALivenessAnalysis (const FlowGraph &flow_graph)
 
- Public Member Functions inherited from dart::LivenessAnalysis
 LivenessAnalysis (intptr_t variable_count, const GrowableArray< BlockEntryInstr * > &postorder)
 
void Analyze ()
 
virtual ~LivenessAnalysis ()
 
BitVectorGetLiveInSetAt (intptr_t postorder_number) const
 
BitVectorGetLiveOutSetAt (intptr_t postorder_number) const
 
BitVectorGetLiveInSet (BlockEntryInstr *block) const
 
BitVectorGetKillSet (BlockEntryInstr *block) const
 
BitVectorGetLiveOutSet (BlockEntryInstr *block) const
 
void Dump ()
 
- Public Member Functions inherited from dart::ValueObject
 ValueObject ()
 
 ~ValueObject ()
 

Private Member Functions

virtual void ComputeInitialSets ()
 

Additional Inherited Members

- Protected Member Functions inherited from dart::LivenessAnalysis
virtual void ComputeInitialSets ()=0
 
bool UpdateLiveOut (const BlockEntryInstr &instr)
 
bool UpdateLiveIn (const BlockEntryInstr &instr)
 
void ComputeLiveInAndLiveOutSets ()
 
Zonezone () const
 
- Protected Attributes inherited from dart::LivenessAnalysis
Zonezone_
 
const intptr_t variable_count_
 
const GrowableArray< BlockEntryInstr * > & postorder_
 
GrowableArray< BitVector * > live_out_
 
GrowableArray< BitVector * > kill_
 
GrowableArray< BitVector * > live_in_
 

Detailed Description

Definition at line 39 of file linearscan.h.

Constructor & Destructor Documentation

◆ SSALivenessAnalysis()

dart::SSALivenessAnalysis::SSALivenessAnalysis ( const FlowGraph flow_graph)
inlineexplicit

Definition at line 41 of file linearscan.h.

42 : LivenessAnalysis(flow_graph.max_vreg(), flow_graph.postorder()),
43 graph_entry_(flow_graph.graph_entry()) {}
LivenessAnalysis(intptr_t variable_count, const GrowableArray< BlockEntryInstr * > &postorder)
Definition: flow_graph.cc:679

Member Function Documentation

◆ ComputeInitialSets()

void dart::SSALivenessAnalysis::ComputeInitialSets ( )
privatevirtual

Implements dart::LivenessAnalysis.

Definition at line 171 of file linearscan.cc.

171 {
172 const intptr_t block_count = postorder_.length();
173 for (intptr_t i = 0; i < block_count; i++) {
174 BlockEntryInstr* block = postorder_[i];
175
176 BitVector* kill = kill_[i];
177 BitVector* live_in = live_in_[i];
178
179 // Iterate backwards starting at the last instruction.
180 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) {
181 Instruction* current = it.Current();
182
183 // Initialize location summary for instruction.
184 current->InitializeLocationSummary(zone(), true); // opt
185
186 LocationSummary* locs = current->locs();
187#if defined(DEBUG)
188 locs->DiscoverWritableInputs();
189#endif
190
191 // Handle definitions.
192 Definition* current_def = current->AsDefinition();
193 if ((current_def != nullptr) && current_def->HasSSATemp()) {
194 kill->Add(current_def->vreg(0));
195 live_in->Remove(current_def->vreg(0));
196 if (current_def->HasPairRepresentation()) {
197 kill->Add(current_def->vreg(1));
198 live_in->Remove(current_def->vreg(1));
199 }
200 }
201
202 // Handle uses.
203 ASSERT(locs->input_count() == current->InputCount());
204 for (intptr_t j = 0; j < current->InputCount(); j++) {
205 Value* input = current->InputAt(j);
206
207 ASSERT(!locs->in(j).IsConstant() || input->BindsToConstant());
208 if (locs->in(j).IsConstant()) continue;
209
210 live_in->Add(input->definition()->vreg(0));
211 if (input->definition()->HasPairRepresentation()) {
212 live_in->Add(input->definition()->vreg(1));
213 }
214 }
215
216 // Process detached MoveArguments interpreting them as
217 // fixed register inputs.
218 if (current->ArgumentCount() != 0) {
219 auto move_arguments = current->GetMoveArguments();
220 for (auto move : *move_arguments) {
221 if (move->is_register_move()) {
222 auto input = move->value();
223
224 live_in->Add(input->definition()->vreg(0));
225 if (input->definition()->HasPairRepresentation()) {
226 live_in->Add(input->definition()->vreg(1));
227 }
228 }
229 }
230 }
231
232 // Add non-argument uses from the deoptimization environment (pushed
233 // arguments are not allocated by the register allocator).
234 if (current->env() != nullptr) {
235 for (Environment::DeepIterator env_it(current->env()); !env_it.Done();
236 env_it.Advance()) {
237 Definition* defn = env_it.CurrentValue()->definition();
238 if (defn->IsMaterializeObject()) {
239 // MaterializeObject instruction is not in the graph.
240 // Treat its inputs as part of the environment.
241 DeepLiveness(defn->AsMaterializeObject(), live_in);
242 } else if (!defn->IsMoveArgument() && !defn->IsConstant()) {
243 live_in->Add(defn->vreg(0));
244 if (defn->HasPairRepresentation()) {
245 live_in->Add(defn->vreg(1));
246 }
247 }
248 }
249 }
250 }
251
252 // Handle phis.
253 if (block->IsJoinEntry()) {
254 JoinEntryInstr* join = block->AsJoinEntry();
255 for (PhiIterator it(join); !it.Done(); it.Advance()) {
256 PhiInstr* phi = it.Current();
257 ASSERT(phi != nullptr);
258 kill->Add(phi->vreg(0));
259 live_in->Remove(phi->vreg(0));
260 if (phi->HasPairRepresentation()) {
261 kill->Add(phi->vreg(1));
262 live_in->Remove(phi->vreg(1));
263 }
264
265 // If a phi input is not defined by the corresponding predecessor it
266 // must be marked live-in for that predecessor.
267 for (intptr_t k = 0; k < phi->InputCount(); k++) {
268 Value* val = phi->InputAt(k);
269 if (val->BindsToConstant()) continue;
270
271 BlockEntryInstr* pred = block->PredecessorAt(k);
272 const intptr_t use = val->definition()->vreg(0);
273 if (!kill_[pred->postorder_number()]->Contains(use)) {
274 live_in_[pred->postorder_number()]->Add(use);
275 }
276 if (phi->HasPairRepresentation()) {
277 const intptr_t second_use = val->definition()->vreg(1);
278 if (!kill_[pred->postorder_number()]->Contains(second_use)) {
279 live_in_[pred->postorder_number()]->Add(second_use);
280 }
281 }
282 }
283 }
284 } else if (auto entry = block->AsBlockEntryWithInitialDefs()) {
285 // Initialize location summary for instruction if needed.
286 if (entry->IsCatchBlockEntry()) {
287 entry->InitializeLocationSummary(zone(), true); // opt
288 }
289
290 // Process initial definitions, i.e. parameters and special parameters.
291 for (intptr_t i = 0; i < entry->initial_definitions()->length(); i++) {
292 Definition* def = (*entry->initial_definitions())[i];
293 const intptr_t vreg = def->vreg(0);
294 kill_[entry->postorder_number()]->Add(vreg);
295 live_in_[entry->postorder_number()]->Remove(vreg);
296 if (def->HasPairRepresentation()) {
297 kill_[entry->postorder_number()]->Add(def->vreg(1));
298 live_in_[entry->postorder_number()]->Remove(def->vreg(1));
299 }
300 }
301 }
302 }
303}
static int block_count(const SkSBlockAllocator< N > &pool)
GrowableArray< BitVector * > kill_
Definition: flow_graph.h:815
Zone * zone() const
Definition: flow_graph.h:799
GrowableArray< BitVector * > live_in_
Definition: flow_graph.h:819
const GrowableArray< BlockEntryInstr * > & postorder_
Definition: flow_graph.h:805
#define ASSERT(E)
size_t length
static void DeepLiveness(MaterializeObjectInstr *mat, BitVector *live_in)
Definition: linearscan.cc:151
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741

The documentation for this class was generated from the following files: