Index: runtime/vm/redundancy_elimination.cc |
diff --git a/runtime/vm/redundancy_elimination.cc b/runtime/vm/redundancy_elimination.cc |
index 06df06ab4b404d088efff525ccdeed9f594dd401..707eedc9b38d2b8e6a6caea35c6cf060968c55c4 100644 |
--- a/runtime/vm/redundancy_elimination.cc |
+++ b/runtime/vm/redundancy_elimination.cc |
@@ -13,7 +13,6 @@ |
namespace dart { |
- |
DEFINE_FLAG(bool, dead_store_elimination, true, "Eliminate dead stores"); |
DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination."); |
DEFINE_FLAG(bool, |
@@ -24,7 +23,6 @@ DEFINE_FLAG(bool, |
// Quick access to the current zone. |
#define Z (zone()) |
- |
class CSEInstructionMap : public ValueObject { |
public: |
// Right now CSE and LICM track a single effect: possible externalization of |
@@ -71,7 +69,6 @@ class CSEInstructionMap : public ValueObject { |
Map dependent_; |
}; |
- |
// Place describes an abstract location (e.g. field) that IR can load |
// from or store to. |
// |
@@ -331,7 +328,6 @@ class Place : public ValueObject { |
RoundByteOffset(to, index_constant_)); |
} |
- |
intptr_t id() const { return id_; } |
Kind kind() const { return KindBits::decode(flags_); } |
@@ -583,7 +579,6 @@ class Place : public ValueObject { |
intptr_t id_; |
}; |
- |
class ZonePlace : public ZoneAllocated { |
public: |
explicit ZonePlace(const Place& place) : place_(place) {} |
@@ -594,14 +589,12 @@ class ZonePlace : public ZoneAllocated { |
Place place_; |
}; |
- |
Place* Place::Wrap(Zone* zone, const Place& place, intptr_t id) { |
Place* wrapped = (new (zone) ZonePlace(place))->place(); |
wrapped->id_ = id; |
return wrapped; |
} |
- |
// Correspondence between places connected through outgoing phi moves on the |
// edge that targets join. |
class PhiPlaceMoves : public ZoneAllocated { |
@@ -647,7 +640,6 @@ class PhiPlaceMoves : public ZoneAllocated { |
GrowableArray<ZoneGrowableArray<Move>*> moves_; |
}; |
- |
// A map from aliases to a set of places sharing the alias. Additionally |
// carries a set of places that can be aliased by side-effects, essentially |
// those that are affected by calls. |
@@ -1136,7 +1128,6 @@ class AliasedSet : public ZoneAllocated { |
GrowableArray<Definition*> identity_rollback_; |
}; |
- |
static Definition* GetStoredValue(Instruction* instr) { |
if (instr->IsStoreIndexed()) { |
return instr->AsStoreIndexed()->value()->definition(); |
@@ -1156,14 +1147,12 @@ static Definition* GetStoredValue(Instruction* instr) { |
return NULL; |
} |
- |
static bool IsPhiDependentPlace(Place* place) { |
return ((place->kind() == Place::kField) || |
(place->kind() == Place::kVMField)) && |
(place->instance() != NULL) && place->instance()->IsPhi(); |
} |
- |
// For each place that depends on a phi ensure that equivalent places |
// corresponding to phi input are numbered and record outgoing phi moves |
// for each block which establish correspondence between phi dependent place |
@@ -1209,10 +1198,8 @@ static PhiPlaceMoves* ComputePhiMoves( |
return phi_moves; |
} |
- |
enum CSEMode { kOptimizeLoads, kOptimizeStores }; |
- |
static AliasedSet* NumberPlaces( |
FlowGraph* graph, |
DirectChainedHashMap<PointerKeyValueTrait<Place> >* map, |
@@ -1265,14 +1252,12 @@ static AliasedSet* NumberPlaces( |
return new (zone) AliasedSet(zone, map, places, phi_moves); |
} |
- |
// Load instructions handled by load elimination. |
static bool IsLoadEliminationCandidate(Instruction* instr) { |
return instr->IsLoadField() || instr->IsLoadIndexed() || |
instr->IsLoadStaticField(); |
} |
- |
static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets, |
intptr_t loop_header_index, |
Instruction* instr) { |
@@ -1281,12 +1266,10 @@ static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets, |
(*sets)[loop_header_index]->Contains(instr->place_id()); |
} |
- |
LICM::LICM(FlowGraph* flow_graph) : flow_graph_(flow_graph) { |
ASSERT(flow_graph->is_licm_allowed()); |
} |
- |
void LICM::Hoist(ForwardInstructionIterator* it, |
BlockEntryInstr* pre_header, |
Instruction* current) { |
@@ -1319,7 +1302,6 @@ void LICM::Hoist(ForwardInstructionIterator* it, |
current->CopyDeoptIdFrom(*last); |
} |
- |
void LICM::TrySpecializeSmiPhi(PhiInstr* phi, |
BlockEntryInstr* header, |
BlockEntryInstr* pre_header) { |
@@ -1369,7 +1351,6 @@ void LICM::TrySpecializeSmiPhi(PhiInstr* phi, |
phi->UpdateType(CompileType::FromCid(kSmiCid)); |
} |
- |
void LICM::OptimisticallySpecializeSmiPhis() { |
if (!flow_graph()->function().allows_hoisting_check_class() || |
FLAG_precompiled_mode) { |
@@ -1394,7 +1375,6 @@ void LICM::OptimisticallySpecializeSmiPhis() { |
} |
} |
- |
void LICM::Optimize() { |
if (!flow_graph()->function().allows_hoisting_check_class()) { |
// Do not hoist any. |
@@ -1443,7 +1423,6 @@ void LICM::Optimize() { |
} |
} |
- |
class LoadOptimizer : public ValueObject { |
public: |
LoadOptimizer(FlowGraph* graph, AliasedSet* aliased_set) |
@@ -1839,7 +1818,6 @@ class LoadOptimizer : public ValueObject { |
ZoneGrowableArray<Definition*>* block_out_values = |
out_values_[preorder_number]; |
- |
// If OUT set has changed then we have new values available out of |
// the block. Compute these values creating phi where necessary. |
for (BitVector::Iterator it(out_[preorder_number]); !it.Done(); |
@@ -2352,14 +2330,12 @@ class LoadOptimizer : public ValueObject { |
GrowableArray<Definition*> congruency_worklist_; |
BitVector* in_worklist_; |
- |
// True if any load was eliminated. |
bool forwarded_; |
DISALLOW_COPY_AND_ASSIGN(LoadOptimizer); |
}; |
- |
bool DominatorBasedCSE::Optimize(FlowGraph* graph) { |
bool changed = false; |
if (FLAG_load_cse) { |
@@ -2372,7 +2348,6 @@ bool DominatorBasedCSE::Optimize(FlowGraph* graph) { |
return changed; |
} |
- |
bool DominatorBasedCSE::OptimizeRecursive(FlowGraph* graph, |
BlockEntryInstr* block, |
CSEInstructionMap* map) { |
@@ -2419,7 +2394,6 @@ bool DominatorBasedCSE::OptimizeRecursive(FlowGraph* graph, |
return changed; |
} |
- |
class StoreOptimizer : public LivenessAnalysis { |
public: |
StoreOptimizer(FlowGraph* graph, |
@@ -2626,14 +2600,12 @@ class StoreOptimizer : public LivenessAnalysis { |
DISALLOW_COPY_AND_ASSIGN(StoreOptimizer); |
}; |
- |
void DeadStoreElimination::Optimize(FlowGraph* graph) { |
if (FLAG_dead_store_elimination) { |
StoreOptimizer::OptimizeGraph(graph); |
} |
} |
- |
enum SafeUseCheck { kOptimisticCheck, kStrictCheck }; |
// Check if the use is safe for allocation sinking. Allocation sinking |
@@ -2675,7 +2647,6 @@ static bool IsSafeUse(Value* use, SafeUseCheck check_type) { |
return false; |
} |
- |
// Right now we are attempting to sink allocation only into |
// deoptimization exit. So candidate should only be used in StoreInstanceField |
// instructions that write into fields of the allocated object. |
@@ -2696,7 +2667,6 @@ static bool IsAllocationSinkingCandidate(Definition* alloc, |
return true; |
} |
- |
// If the given use is a store into an object then return an object we are |
// storing into. |
static Definition* StoreInto(Value* use) { |
@@ -2708,7 +2678,6 @@ static Definition* StoreInto(Value* use) { |
return NULL; |
} |
- |
// Remove the given allocation from the graph. It is not observable. |
// If deoptimization occurs the object will be materialized. |
void AllocationSinking::EliminateAllocation(Definition* alloc) { |
@@ -2743,7 +2712,6 @@ void AllocationSinking::EliminateAllocation(Definition* alloc) { |
} |
} |
- |
// Find allocation instructions that can be potentially eliminated and |
// rematerialized at deoptimization exits if needed. See IsSafeUse |
// for the description of algorithm used below. |
@@ -2807,7 +2775,6 @@ void AllocationSinking::CollectCandidates() { |
candidates_.TruncateTo(j); |
} |
- |
// If materialization references an allocation sinking candidate then replace |
// this reference with a materialization which should have been computed for |
// this side-exit. CollectAllExits should have collected this exit. |
@@ -2825,7 +2792,6 @@ void AllocationSinking::NormalizeMaterializations() { |
} |
} |
- |
// We transitively insert materializations at each deoptimization exit that |
// might see the given allocation (see ExitsCollector). Some of this |
// materializations are not actually used and some fail to compute because |
@@ -2859,7 +2825,6 @@ void AllocationSinking::RemoveUnusedMaterializations() { |
materializations_.TruncateTo(j); |
} |
- |
// Some candidates might stop being eligible for allocation sinking after |
// the load forwarding because they flow into phis that load forwarding |
// inserts. Discover such allocations and remove them from the list |
@@ -2945,7 +2910,6 @@ void AllocationSinking::DiscoverFailedCandidates() { |
candidates_.TruncateTo(j); |
} |
- |
void AllocationSinking::Optimize() { |
CollectCandidates(); |
@@ -2998,7 +2962,6 @@ void AllocationSinking::Optimize() { |
} |
} |
- |
// Remove materializations from the graph. Register allocator will treat them |
// as part of the environment not as a real instruction. |
void AllocationSinking::DetachMaterializations() { |
@@ -3007,7 +2970,6 @@ void AllocationSinking::DetachMaterializations() { |
} |
} |
- |
// Add a field/offset to the list of fields if it is not yet present there. |
static bool AddSlot(ZoneGrowableArray<const Object*>* slots, |
const Object& slot) { |
@@ -3022,7 +2984,6 @@ static bool AddSlot(ZoneGrowableArray<const Object*>* slots, |
return true; |
} |
- |
// Find deoptimization exit for the given materialization assuming that all |
// materializations are emitted right before the instruction which is a |
// deoptimization exit. |
@@ -3033,7 +2994,6 @@ static Instruction* ExitForMaterialization(MaterializeObjectInstr* mat) { |
return mat->next(); |
} |
- |
// Given the deoptimization exit find first materialization that was inserted |
// before it. |
static Instruction* FirstMaterializationAt(Instruction* exit) { |
@@ -3043,7 +3003,6 @@ static Instruction* FirstMaterializationAt(Instruction* exit) { |
return exit; |
} |
- |
// Given the allocation and deoptimization exit try to find MaterializeObject |
// instruction corresponding to this allocation at this exit. |
MaterializeObjectInstr* AllocationSinking::MaterializationFor( |
@@ -3063,7 +3022,6 @@ MaterializeObjectInstr* AllocationSinking::MaterializationFor( |
return NULL; |
} |
- |
// Insert MaterializeObject instruction for the given allocation before |
// the given instruction that can deoptimize. |
void AllocationSinking::CreateMaterializationAt( |
@@ -3129,7 +3087,6 @@ void AllocationSinking::CreateMaterializationAt( |
materializations_.Add(mat); |
} |
- |
// Add given instruction to the list of the instructions if it is not yet |
// present there. |
template <typename T> |
@@ -3143,7 +3100,6 @@ void AddInstruction(GrowableArray<T*>* list, T* value) { |
list->Add(value); |
} |
- |
// Transitively collect all deoptimization exits that might need this allocation |
// rematerialized. It is not enough to collect only environment uses of this |
// allocation because it can flow into other objects that will be |
@@ -3172,7 +3128,6 @@ void AllocationSinking::ExitsCollector::Collect(Definition* alloc) { |
} |
} |
- |
void AllocationSinking::ExitsCollector::CollectTransitively(Definition* alloc) { |
exits_.TruncateTo(0); |
worklist_.TruncateTo(0); |
@@ -3189,7 +3144,6 @@ void AllocationSinking::ExitsCollector::CollectTransitively(Definition* alloc) { |
} |
} |
- |
void AllocationSinking::InsertMaterializations(Definition* alloc) { |
// Collect all fields that are written for this instance. |
ZoneGrowableArray<const Object*>* slots = |
@@ -3224,7 +3178,6 @@ void AllocationSinking::InsertMaterializations(Definition* alloc) { |
} |
} |
- |
void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) { |
// For every catch-block: Iterate over all call instructions inside the |
// corresponding try-block and figure out for each environment value if it |
@@ -3297,7 +3250,6 @@ void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) { |
} |
} |
- |
// Returns true iff this definition is used in a non-phi instruction. |
static bool HasRealUse(Definition* def) { |
// Environment uses are real (non-phi) uses. |
@@ -3309,7 +3261,6 @@ static bool HasRealUse(Definition* def) { |
return false; |
} |
- |
void DeadCodeElimination::EliminateDeadPhis(FlowGraph* flow_graph) { |
GrowableArray<PhiInstr*> live_phis; |
for (BlockIterator b = flow_graph->postorder_iterator(); !b.Done(); |
@@ -3382,5 +3333,4 @@ void DeadCodeElimination::EliminateDeadPhis(FlowGraph* flow_graph) { |
} |
} |
- |
} // namespace dart |