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

#include <redundancy_elimination.h>

Inheritance diagram for dart::AllocationSinking:
dart::ZoneAllocated

Public Member Functions

 AllocationSinking (FlowGraph *flow_graph)
 
const GrowableArray< Definition * > & candidates () const
 
MaterializeObjectInstrMaterializationFor (Definition *alloc, Instruction *exit)
 
void Optimize ()
 
void DetachMaterializations ()
 
- Public Member Functions inherited from dart::ZoneAllocated
 ZoneAllocated ()
 
void * operator new (size_t size)
 
void * operator new (size_t size, Zone *zone)
 
void operator delete (void *pointer)
 

Detailed Description

Definition at line 19 of file redundancy_elimination.h.

Constructor & Destructor Documentation

◆ AllocationSinking()

dart::AllocationSinking::AllocationSinking ( FlowGraph flow_graph)
inlineexplicit

Definition at line 21 of file redundancy_elimination.h.

22 : flow_graph_(flow_graph), candidates_(5), materializations_(5) {}

Member Function Documentation

◆ candidates()

const GrowableArray< Definition * > & dart::AllocationSinking::candidates ( ) const
inline

Definition at line 24 of file redundancy_elimination.h.

24{ return candidates_; }

◆ DetachMaterializations()

void dart::AllocationSinking::DetachMaterializations ( )

Definition at line 3767 of file redundancy_elimination.cc.

3767 {
3768 for (MaterializeObjectInstr* mat : materializations_) {
3769 mat->previous()->LinkTo(mat->next());
3770 mat->set_next(nullptr);
3771 mat->set_previous(nullptr);
3772 }
3773}

◆ MaterializationFor()

MaterializeObjectInstr * dart::AllocationSinking::MaterializationFor ( Definition alloc,
Instruction exit 
)

Definition at line 3803 of file redundancy_elimination.cc.

3805 {
3806 if (exit->IsMaterializeObject()) {
3807 exit = ExitForMaterialization(exit->AsMaterializeObject());
3808 }
3809
3810 for (MaterializeObjectInstr* mat = exit->previous()->AsMaterializeObject();
3811 mat != nullptr; mat = mat->previous()->AsMaterializeObject()) {
3812 if (mat->allocation() == alloc) {
3813 return mat;
3814 }
3815 }
3816
3817 return nullptr;
3818}
exit(kErrorExitCode)
static Instruction * ExitForMaterialization(MaterializeObjectInstr *mat)

◆ Optimize()

void dart::AllocationSinking::Optimize ( )

Definition at line 3689 of file redundancy_elimination.cc.

3689 {
3690 // Allocation sinking depends on load forwarding, so give up early if load
3691 // forwarding is disabled.
3692 if (!FLAG_load_cse || flow_graph_->is_huge_method()) {
3693 return;
3694 }
3695
3696 CollectCandidates();
3697
3698 // Insert MaterializeObject instructions that will describe the state of the
3699 // object at all deoptimization points. Each inserted materialization looks
3700 // like this (where v_0 is allocation that we are going to eliminate):
3701 // v_1 <- LoadField(v_0, field_1)
3702 // ...
3703 // v_N <- LoadField(v_0, field_N)
3704 // v_{N+1} <- MaterializeObject(field_1 = v_1, ..., field_N = v_N)
3705 //
3706 // For typed data objects materialization looks like this:
3707 // v_1 <- LoadIndexed(v_0, index_1)
3708 // ...
3709 // v_N <- LoadIndexed(v_0, index_N)
3710 // v_{N+1} <- MaterializeObject([index_1] = v_1, ..., [index_N] = v_N)
3711 //
3712 // For arrays materialization looks like this:
3713 // v_1 <- LoadIndexed(v_0, index_1)
3714 // ...
3715 // v_N <- LoadIndexed(v_0, index_N)
3716 // v_{N+1} <- LoadField(v_0, Array.type_arguments)
3717 // v_{N+2} <- MaterializeObject([index_1] = v_1, ..., [index_N] = v_N,
3718 // type_arguments = v_{N+1})
3719 //
3720 for (intptr_t i = 0; i < candidates_.length(); i++) {
3721 InsertMaterializations(candidates_[i]);
3722 }
3723
3724 // Run load forwarding to eliminate LoadField/LoadIndexed instructions
3725 // inserted above.
3726 //
3727 // All loads will be successfully eliminated because:
3728 // a) they use fields/constant indices and thus provide precise aliasing
3729 // information
3730 // b) candidate does not escape and thus its fields/elements are not
3731 // affected by external effects from calls.
3732 LoadOptimizer::OptimizeGraph(flow_graph_);
3733
3734 NormalizeMaterializations();
3735
3736 RemoveUnusedMaterializations();
3737
3738 // If any candidates are no longer eligible for allocation sinking abort
3739 // the optimization for them and undo any changes we did in preparation.
3740 DiscoverFailedCandidates();
3741
3742 // At this point we have computed the state of object at each deoptimization
3743 // point and we can eliminate it. Loads inserted above were forwarded so there
3744 // are no uses of the allocation outside other candidates to eliminate, just
3745 // as in the beginning of the pass.
3746 for (intptr_t i = 0; i < candidates_.length(); i++) {
3747 EliminateAllocation(candidates_[i]);
3748 }
3749
3750 // Process materializations and unbox their arguments: materializations
3751 // are part of the environment and can materialize boxes for double/mint/simd
3752 // values when needed.
3753 // TODO(vegorov): handle all box types here.
3754 for (intptr_t i = 0; i < materializations_.length(); i++) {
3755 MaterializeObjectInstr* mat = materializations_[i];
3756 for (intptr_t j = 0; j < mat->InputCount(); j++) {
3757 Definition* defn = mat->InputAt(j)->definition();
3758 if (defn->IsBox()) {
3759 mat->InputAt(j)->BindTo(defn->InputAt(0)->definition());
3760 }
3761 }
3762 }
3763}
bool is_huge_method() const
Definition: flow_graph.h:423
static bool OptimizeGraph(FlowGraph *graph)

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