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

#include <type_propagator.h>

Inheritance diagram for dart::FlowGraphTypePropagator:
dart::FlowGraphVisitor dart::InstructionVisitor dart::ValueObject

Static Public Member Functions

static void Propagate (FlowGraph *flow_graph)
 

Private Member Functions

virtual void VisitJoinEntry (JoinEntryInstr *instr)
 
virtual void VisitCheckSmi (CheckSmiInstr *instr)
 
virtual void VisitCheckArrayBound (CheckArrayBoundInstr *instr)
 
virtual void VisitCheckClass (CheckClassInstr *instr)
 
virtual void VisitCheckClassId (CheckClassIdInstr *instr)
 
virtual void VisitCheckNull (CheckNullInstr *instr)
 
virtual void VisitGuardFieldClass (GuardFieldClassInstr *instr)
 
virtual void VisitAssertAssignable (AssertAssignableInstr *instr)
 
virtual void VisitAssertBoolean (AssertBooleanInstr *instr)
 
virtual void VisitAssertSubtype (AssertSubtypeInstr *instr)
 
virtual void VisitInstanceCall (InstanceCallInstr *instr)
 
virtual void VisitPolymorphicInstanceCall (PolymorphicInstanceCallInstr *instr)
 
virtual void VisitBranch (BranchInstr *instr)
 

Additional Inherited Members

- Public Member Functions inherited from dart::FlowGraphVisitor
 FlowGraphVisitor (const GrowableArray< BlockEntryInstr * > &block_order)
 
virtual ~FlowGraphVisitor ()
 
ForwardInstructionIteratorcurrent_iterator () const
 
virtual void VisitBlocks ()
 
- Public Member Functions inherited from dart::InstructionVisitor
 InstructionVisitor ()
 
virtual ~InstructionVisitor ()
 
- Public Member Functions inherited from dart::ValueObject
 ValueObject ()
 
 ~ValueObject ()
 
- Protected Member Functions inherited from dart::FlowGraphVisitor
void set_block_order (const GrowableArray< BlockEntryInstr * > &block_order)
 
- Protected Attributes inherited from dart::FlowGraphVisitor
ForwardInstructionIteratorcurrent_iterator_
 

Detailed Description

Definition at line 17 of file type_propagator.h.

Member Function Documentation

◆ Propagate()

void dart::FlowGraphTypePropagator::Propagate ( FlowGraph flow_graph)
static

Definition at line 41 of file type_propagator.cc.

41 {
42 TIMELINE_DURATION(flow_graph->thread(), CompilerVerbose,
43 "FlowGraphTypePropagator");
44 FlowGraphTypePropagator propagator(flow_graph);
45 propagator.Propagate();
46}
#define TIMELINE_DURATION(thread, stream, name)
Definition: timeline.h:39

◆ VisitAssertAssignable()

void dart::FlowGraphTypePropagator::VisitAssertAssignable ( AssertAssignableInstr instr)
privatevirtual

Definition at line 368 of file type_propagator.cc.

369 {
370 auto defn = check->value()->definition();
371 SetTypeOf(defn, new (zone()) CompileType(check->ComputeType()));
372 if (check->ssa_temp_index() == -1) {
373 flow_graph_->AllocateSSAIndex(check);
374 GrowTypes(check->ssa_temp_index() + 1);
375 }
377}
#define check(reporter, ref, unref, make, kill)
Definition: RefCntTest.cpp:85
void AllocateSSAIndex(Definition *def)
Definition: flow_graph.h:274
static void RenameDominatedUses(Definition *def, Instruction *dom, Definition *other)
Definition: flow_graph.cc:2642

◆ VisitAssertBoolean()

void dart::FlowGraphTypePropagator::VisitAssertBoolean ( AssertBooleanInstr instr)
privatevirtual

Definition at line 379 of file type_propagator.cc.

379 {
380 SetTypeOf(instr->value()->definition(),
381 new (zone()) CompileType(CompileType::Bool()));
382}
static CompileType Bool()

◆ VisitAssertSubtype()

void dart::FlowGraphTypePropagator::VisitAssertSubtype ( AssertSubtypeInstr instr)
privatevirtual

Definition at line 384 of file type_propagator.cc.

384{}

◆ VisitBranch()

void dart::FlowGraphTypePropagator::VisitBranch ( BranchInstr instr)
privatevirtual

Definition at line 386 of file type_propagator.cc.

386 {
387 StrictCompareInstr* comparison = instr->comparison()->AsStrictCompare();
388 if (comparison == nullptr) return;
389 bool negated = comparison->kind() == Token::kNE_STRICT;
390 LoadClassIdInstr* load_cid =
391 comparison->InputAt(0)->definition()->AsLoadClassId();
392 InstanceCallInstr* call =
393 comparison->InputAt(0)->definition()->AsInstanceCall();
394 InstanceOfInstr* instance_of =
395 comparison->InputAt(0)->definition()->AsInstanceOf();
396 bool is_simple_instance_of =
397 (call != nullptr) && call->MatchesCoreName(Symbols::_simpleInstanceOf());
398 if (load_cid != nullptr && comparison->InputAt(1)->BindsToConstant()) {
399 intptr_t cid = Smi::Cast(comparison->InputAt(1)->BoundConstant()).Value();
400 BlockEntryInstr* true_successor =
401 negated ? instr->false_successor() : instr->true_successor();
402 EnsureMoreAccurateRedefinition(true_successor,
403 load_cid->object()->definition(),
405 } else if ((is_simple_instance_of || (instance_of != nullptr)) &&
406 comparison->InputAt(1)->BindsToConstant() &&
407 comparison->InputAt(1)->BoundConstant().IsBool()) {
408 if (comparison->InputAt(1)->BoundConstant().ptr() == Bool::False().ptr()) {
409 negated = !negated;
410 }
411 BlockEntryInstr* true_successor =
412 negated ? instr->false_successor() : instr->true_successor();
413 const AbstractType* type = nullptr;
414 Definition* left = nullptr;
415 if (is_simple_instance_of) {
416 ASSERT(call->ArgumentAt(1)->IsConstant());
417 const Object& type_obj = call->ArgumentAt(1)->AsConstant()->value();
418 if (!type_obj.IsType()) {
419 return;
420 }
421 type = &Type::Cast(type_obj);
422 left = call->ArgumentAt(0);
423 } else {
424 type = &(instance_of->type());
425 left = instance_of->value()->definition();
426 }
427 if (!type->IsTopTypeForInstanceOf()) {
428 const bool is_nullable = (type->IsNullable() || type->IsTypeParameter())
431 EnsureMoreAccurateRedefinition(
432 true_successor, left,
435 }
436 } else if (comparison->InputAt(0)->BindsToConstant() &&
437 comparison->InputAt(0)->BoundConstant().IsNull()) {
438 // Handle for expr != null.
439 BlockEntryInstr* true_successor =
440 negated ? instr->true_successor() : instr->false_successor();
441 EnsureMoreAccurateRedefinition(
442 true_successor, comparison->InputAt(1)->definition(),
443 comparison->InputAt(1)->Type()->CopyNonNullable());
444
445 } else if (comparison->InputAt(1)->BindsToConstant() &&
446 comparison->InputAt(1)->BoundConstant().IsNull()) {
447 // Handle for null != expr.
448 BlockEntryInstr* true_successor =
449 negated ? instr->true_successor() : instr->false_successor();
450 EnsureMoreAccurateRedefinition(
451 true_successor, comparison->InputAt(0)->definition(),
452 comparison->InputAt(0)->Type()->CopyNonNullable());
453 } else if (comparison->InputAt(0)->BindsToConstant() &&
454 comparison->InputAt(0)->BoundConstant().ptr() ==
455 Object::sentinel().ptr()) {
456 // Handle for expr != sentinel.
457 BlockEntryInstr* true_successor =
458 negated ? instr->true_successor() : instr->false_successor();
459 EnsureMoreAccurateRedefinition(
460 true_successor, comparison->InputAt(1)->definition(),
461 comparison->InputAt(1)->Type()->CopyNonSentinel());
462
463 } else if (comparison->InputAt(1)->BindsToConstant() &&
464 comparison->InputAt(1)->BoundConstant().ptr() ==
465 Object::sentinel().ptr()) {
466 // Handle for sentinel != expr.
467 BlockEntryInstr* true_successor =
468 negated ? instr->true_successor() : instr->false_successor();
469 EnsureMoreAccurateRedefinition(
470 true_successor, comparison->InputAt(0)->definition(),
471 comparison->InputAt(0)->Type()->CopyNonSentinel());
472 }
473 // TODO(fschneider): Add propagation for generic is-tests.
474}
GLenum type
static const Bool & False()
Definition: object.h:10799
static CompileType FromCid(intptr_t cid)
static constexpr bool kCannotBeSentinel
Definition: compile_type.h:49
static constexpr bool kCannotBeNull
Definition: compile_type.h:46
static constexpr bool kCanBeNull
Definition: compile_type.h:45
static CompileType FromAbstractType(const AbstractType &type, bool can_be_null, bool can_be_sentinel)
ObjectPtr ptr() const
Definition: object.h:332
#define ASSERT(E)
const intptr_t cid
def call(args)
Definition: dom.py:159

◆ VisitCheckArrayBound()

void dart::FlowGraphTypePropagator::VisitCheckArrayBound ( CheckArrayBoundInstr instr)
privatevirtual

Definition at line 242 of file type_propagator.cc.

243 {
244 // Array bounds checks also test index for smi.
245 SetCid(check->index()->definition(), kSmiCid);
246}

◆ VisitCheckClass()

void dart::FlowGraphTypePropagator::VisitCheckClass ( CheckClassInstr instr)
privatevirtual

Definition at line 248 of file type_propagator.cc.

248 {
249 // Use a monomorphic cid directly.
250 const Cids& cids = check->cids();
251 if (cids.IsMonomorphic()) {
252 SetCid(check->value()->definition(), cids.MonomorphicReceiverCid());
253 return;
254 }
255 // Take the union of polymorphic cids.
256 CompileType result = CompileType::None();
257 for (intptr_t i = 0, n = cids.length(); i < n; i++) {
258 CidRange* cid_range = cids.At(i);
259 ASSERT(!cid_range->IsIllegalRange());
260 for (intptr_t cid = cid_range->cid_start; cid <= cid_range->cid_end;
261 cid++) {
262 CompileType tp = CompileType::FromCid(cid);
263 result.Union(&tp);
264 }
265 }
266 if (!result.IsNone()) {
267 SetTypeOf(check->value()->definition(), new (zone()) CompileType(result));
268 }
269}
static CompileType None()
Definition: compile_type.h:155
GAsyncResult * result

◆ VisitCheckClassId()

void dart::FlowGraphTypePropagator::VisitCheckClassId ( CheckClassIdInstr instr)
privatevirtual

Definition at line 271 of file type_propagator.cc.

271 {
272 LoadClassIdInstr* load_cid =
273 check->value()->definition()->OriginalDefinition()->AsLoadClassId();
274 if (load_cid != nullptr && check->cids().IsSingleCid()) {
275 SetCid(load_cid->object()->definition(), check->cids().cid_start);
276 }
277}

◆ VisitCheckNull()

void dart::FlowGraphTypePropagator::VisitCheckNull ( CheckNullInstr instr)
privatevirtual

Definition at line 279 of file type_propagator.cc.

279 {
280 Definition* receiver = check->value()->definition();
281 CompileType* type = TypeOf(receiver);
282 if (type->is_nullable()) {
283 // If the type is nullable, translate an implicit control
284 // dependence to an explicit data dependence at this point
285 // to guard against invalid code motion later. Valid code
286 // motion of the check may still enable valid code motion
287 // of the checked code.
288 if (check->ssa_temp_index() == -1) {
289 flow_graph_->AllocateSSAIndex(check);
290 GrowTypes(check->ssa_temp_index() + 1);
291 }
293 // Set non-nullable type on check itself (but avoid None()).
294 CompileType result = type->CopyNonNullable();
295 if (!result.IsNone()) {
296 SetTypeOf(check, new (zone()) CompileType(result));
297 }
298 }
299}

◆ VisitCheckSmi()

void dart::FlowGraphTypePropagator::VisitCheckSmi ( CheckSmiInstr instr)
privatevirtual

Definition at line 238 of file type_propagator.cc.

238 {
239 SetCid(check->value()->definition(), kSmiCid);
240}

◆ VisitGuardFieldClass()

void dart::FlowGraphTypePropagator::VisitGuardFieldClass ( GuardFieldClassInstr instr)
privatevirtual

Definition at line 349 of file type_propagator.cc.

350 {
351 const intptr_t cid = guard->field().guarded_cid();
352 if ((cid == kIllegalCid) || (cid == kDynamicCid)) {
353 return;
354 }
355
356 Definition* def = guard->value()->definition();
357 CompileType* current = TypeOf(def);
358 if (current->IsNone() || (current->ToCid() != cid) ||
359 (current->is_nullable() && !guard->field().is_nullable())) {
360 const bool is_nullable =
361 guard->field().is_nullable() && current->is_nullable();
362 SetTypeOf(def,
363 new (zone()) CompileType(
364 is_nullable, CompileType::kCannotBeSentinel, cid, nullptr));
365 }
366}
@ kIllegalCid
Definition: class_id.h:214
@ kDynamicCid
Definition: class_id.h:253

◆ VisitInstanceCall()

void dart::FlowGraphTypePropagator::VisitInstanceCall ( InstanceCallInstr instr)
privatevirtual

Definition at line 328 of file type_propagator.cc.

328 {
329 if (instr->has_unique_selector()) {
330 SetCid(instr->Receiver()->definition(),
331 instr->ic_data()->GetReceiverClassIdAt(0));
332 return;
333 }
334 CheckNonNullSelector(instr, instr->Receiver()->definition(),
335 instr->function_name());
336}

◆ VisitJoinEntry()

void dart::FlowGraphTypePropagator::VisitJoinEntry ( JoinEntryInstr instr)
privatevirtual

Definition at line 232 of file type_propagator.cc.

232 {
233 for (PhiIterator it(join); !it.Done(); it.Advance()) {
234 worklist_.Add(it.Current());
235 }
236}
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741

◆ VisitPolymorphicInstanceCall()

void dart::FlowGraphTypePropagator::VisitPolymorphicInstanceCall ( PolymorphicInstanceCallInstr instr)
privatevirtual

Definition at line 338 of file type_propagator.cc.

339 {
340 if (instr->has_unique_selector()) {
341 SetCid(instr->Receiver()->definition(),
342 instr->targets().MonomorphicReceiverCid());
343 return;
344 }
345 CheckNonNullSelector(instr, instr->Receiver()->definition(),
346 instr->function_name());
347}

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