Flutter Engine
The Flutter Engine
Public Member Functions | Private Member Functions | List of all members
dart::VariableLivenessAnalysis Class Reference
Inheritance diagram for dart::VariableLivenessAnalysis:
dart::LivenessAnalysis dart::ValueObject

Public Member Functions

 VariableLivenessAnalysis (FlowGraph *flow_graph)
 
const GrowableArray< BitVector * > & ComputeAssignedVars ()
 
bool IsStoreAlive (BlockEntryInstr *block, StoreLocalInstr *store)
 
bool IsLastLoad (BlockEntryInstr *block, LoadLocalInstr *load)
 
- 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 771 of file flow_graph.cc.

Constructor & Destructor Documentation

◆ VariableLivenessAnalysis()

dart::VariableLivenessAnalysis::VariableLivenessAnalysis ( FlowGraph flow_graph)
inlineexplicit

Definition at line 773 of file flow_graph.cc.

774 : LivenessAnalysis(flow_graph->variable_count(), flow_graph->postorder()),
775 flow_graph_(flow_graph),
776 assigned_vars_() {}
LivenessAnalysis(intptr_t variable_count, const GrowableArray< BlockEntryInstr * > &postorder)
Definition: flow_graph.cc:679

Member Function Documentation

◆ ComputeAssignedVars()

const GrowableArray< BitVector * > & dart::VariableLivenessAnalysis::ComputeAssignedVars ( )
inline

Definition at line 780 of file flow_graph.cc.

780 {
781 // We can't directly return kill_ because it uses postorder numbering while
782 // SSA construction uses preorder numbering internally.
783 // We have to permute postorder into preorder.
784 assigned_vars_.Clear();
785
786 const intptr_t block_count = flow_graph_->preorder().length();
787 for (intptr_t i = 0; i < block_count; i++) {
788 BlockEntryInstr* block = flow_graph_->preorder()[i];
789 // All locals are assigned inside a try{} block.
790 // This is a safe approximation and workaround to force insertion of
791 // phis for stores that appear non-live because of the way catch-blocks
792 // are connected to the graph: They normally are dominated by the
793 // try-entry, but are direct successors of the graph entry in our flow
794 // graph.
795 // TODO(fschneider): Improve this approximation by better modeling the
796 // actual data flow to reduce the number of redundant phis.
797 BitVector* kill = GetKillSet(block);
798 if (block->InsideTryBlock()) {
799 kill->SetAll();
800 } else {
801 kill->Intersect(GetLiveOutSet(block));
802 }
803 assigned_vars_.Add(kill);
804 }
805
806 return assigned_vars_;
807 }
static int block_count(const SkSBlockAllocator< N > &pool)
const GrowableArray< BlockEntryInstr * > & preorder() const
Definition: flow_graph.h:203
BitVector * GetKillSet(BlockEntryInstr *block) const
Definition: flow_graph.h:769
BitVector * GetLiveOutSet(BlockEntryInstr *block) const
Definition: flow_graph.h:773

◆ ComputeInitialSets()

void dart::VariableLivenessAnalysis::ComputeInitialSets ( )
privatevirtual

Implements dart::LivenessAnalysis.

Definition at line 844 of file flow_graph.cc.

844 {
845 const intptr_t block_count = postorder_.length();
846
847 BitVector* last_loads = new (zone()) BitVector(zone(), variable_count_);
848 for (intptr_t i = 0; i < block_count; i++) {
849 BlockEntryInstr* block = postorder_[i];
850
851 BitVector* kill = kill_[i];
852 BitVector* live_in = live_in_[i];
853 last_loads->Clear();
854
855 // There is an implicit use (load-local) of every local variable at each
856 // call inside a try{} block and every call has an implicit control-flow
857 // to the catch entry. As an approximation we mark all locals as live
858 // inside try{}.
859 // TODO(fschneider): Improve this approximation, since not all local
860 // variable stores actually reach a call.
861 if (block->InsideTryBlock()) {
862 live_in->SetAll();
863 continue;
864 }
865
866 // Iterate backwards starting at the last instruction.
867 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) {
868 Instruction* current = it.Current();
869
870 LoadLocalInstr* load = current->AsLoadLocal();
871 if (load != nullptr) {
872 const intptr_t index = flow_graph_->EnvIndex(&load->local());
873 if (index >= live_in->length()) continue; // Skip tmp_locals.
874 live_in->Add(index);
875 if (!last_loads->Contains(index)) {
876 last_loads->Add(index);
877 load->mark_last();
878 }
879 continue;
880 }
881
882 StoreLocalInstr* store = current->AsStoreLocal();
883 if (store != nullptr) {
884 const intptr_t index = flow_graph_->EnvIndex(&store->local());
885 if (index >= live_in->length()) continue; // Skip tmp_locals.
886 if (kill->Contains(index)) {
887 if (!live_in->Contains(index)) {
888 store->mark_dead();
889 }
890 } else {
891 if (!live_in->Contains(index)) {
892 store->mark_last();
893 }
894 kill->Add(index);
895 }
896 live_in->Remove(index);
897 continue;
898 }
899 }
900
901 // For blocks with parameter or special parameter instructions we add them
902 // to the kill set.
903 const bool is_function_entry = block->IsFunctionEntry();
904 const bool is_osr_entry = block->IsOsrEntry();
905 const bool is_catch_block_entry = block->IsCatchBlockEntry();
906 if (is_function_entry || is_osr_entry || is_catch_block_entry) {
907 const intptr_t parameter_count =
908 (is_osr_entry || is_catch_block_entry)
909 ? flow_graph_->variable_count()
910 : flow_graph_->num_direct_parameters();
911 for (intptr_t i = 0; i < parameter_count; ++i) {
912 live_in->Remove(i);
913 kill->Add(i);
914 }
915 }
916 if (is_function_entry) {
917 if (flow_graph_->parsed_function().has_arg_desc_var()) {
918 const auto index = flow_graph_->ArgumentDescriptorEnvIndex();
919 live_in->Remove(index);
920 kill->Add(index);
921 }
922 }
923 }
924}
SI void store(P *ptr, const T &val)
SI T load(const P *ptr)
Definition: Transform_inl.h:98
intptr_t ArgumentDescriptorEnvIndex() const
Definition: flow_graph.h:185
const ParsedFunction & parsed_function() const
Definition: flow_graph.h:129
intptr_t num_direct_parameters() const
Definition: flow_graph.h:137
intptr_t variable_count() const
Definition: flow_graph.h:143
intptr_t EnvIndex(const LocalVariable *variable) const
Definition: flow_graph.h:189
const intptr_t variable_count_
Definition: flow_graph.h:803
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
bool has_arg_desc_var() const
Definition: parser.h:130

◆ IsLastLoad()

bool dart::VariableLivenessAnalysis::IsLastLoad ( BlockEntryInstr block,
LoadLocalInstr load 
)
inline

Definition at line 829 of file flow_graph.cc.

829 {
830 if (load->local().Equals(*flow_graph_->CurrentContextVar())) {
831 return false;
832 }
833 const intptr_t index = flow_graph_->EnvIndex(&load->local());
834 return load->is_last() && !GetLiveOutSet(block)->Contains(index);
835 }
bool Contains(intptr_t i) const
Definition: bit_vector.h:91
LocalVariable * CurrentContextVar() const
Definition: flow_graph.h:173

◆ IsStoreAlive()

bool dart::VariableLivenessAnalysis::IsStoreAlive ( BlockEntryInstr block,
StoreLocalInstr store 
)
inline

Definition at line 811 of file flow_graph.cc.

811 {
812 if (store->local().Equals(*flow_graph_->CurrentContextVar())) {
813 return true;
814 }
815
816 if (store->is_dead()) {
817 return false;
818 }
819 if (store->is_last()) {
820 const intptr_t index = flow_graph_->EnvIndex(&store->local());
821 return GetLiveOutSet(block)->Contains(index);
822 }
823
824 return true;
825 }

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