Index: runtime/vm/constant_propagator.h |
=================================================================== |
--- runtime/vm/constant_propagator.h (revision 42566) |
+++ runtime/vm/constant_propagator.h (working copy) |
@@ -2,8 +2,8 @@ |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
-#ifndef VM_FLOW_GRAPH_OPTIMIZER_H_ |
-#define VM_FLOW_GRAPH_OPTIMIZER_H_ |
+#ifndef VM_CONSTANT_PROPAGATOR_H_ |
+#define VM_CONSTANT_PROPAGATOR_H_ |
#include "vm/intermediate_language.h" |
#include "vm/flow_graph.h" |
@@ -10,312 +10,6 @@ |
namespace dart { |
-class CSEInstructionMap; |
-template <typename T> class GrowableArray; |
-class ParsedFunction; |
- |
-class FlowGraphOptimizer : public FlowGraphVisitor { |
- public: |
- explicit FlowGraphOptimizer(FlowGraph* flow_graph) |
- : FlowGraphVisitor(flow_graph->reverse_postorder()), |
- flow_graph_(flow_graph) { } |
- virtual ~FlowGraphOptimizer() {} |
- |
- FlowGraph* flow_graph() const { return flow_graph_; } |
- |
- // Use ICData to optimize, replace or eliminate instructions. |
- void ApplyICData(); |
- |
- // Use propagated class ids to optimize, replace or eliminate instructions. |
- void ApplyClassIds(); |
- |
- // Optimize (a << b) & c pattern: if c is a positive Smi or zero, then the |
- // shift can be a truncating Smi shift-left and result is always Smi. |
- // Merge instructions (only per basic-block). |
- void TryOptimizePatterns(); |
- |
- // Returns true if any instructions were canonicalized away. |
- bool Canonicalize(); |
- |
- void EliminateDeadPhis(); |
- |
- void SelectRepresentations(); |
- |
- void WidenSmiToInt32(); |
- |
- void InferIntRanges(); |
- |
- void SelectIntegerInstructions(); |
- |
- void AnalyzeTryCatch(); |
- |
- bool TryInlineRecognizedMethod(intptr_t receiver_cid, |
- const Function& target, |
- Instruction* call, |
- Definition* receiver, |
- intptr_t token_pos, |
- const ICData& ic_data, |
- TargetEntryInstr** entry, |
- Definition** last); |
- |
- // Remove environments from the instructions which do not deoptimize. |
- void EliminateEnvironments(); |
- |
- virtual void VisitStaticCall(StaticCallInstr* instr); |
- virtual void VisitInstanceCall(InstanceCallInstr* instr); |
- virtual void VisitStoreInstanceField(StoreInstanceFieldInstr* instr); |
- virtual void VisitAllocateContext(AllocateContextInstr* instr); |
- virtual void VisitLoadCodeUnits(LoadCodeUnitsInstr* instr); |
- |
- void InsertBefore(Instruction* next, |
- Instruction* instr, |
- Environment* env, |
- FlowGraph::UseKind use_kind) { |
- flow_graph_->InsertBefore(next, instr, env, use_kind); |
- } |
- |
- private: |
- // Attempt to build ICData for call using propagated class-ids. |
- bool TryCreateICData(InstanceCallInstr* call); |
- const ICData& TrySpecializeICData(const ICData& ic_data, intptr_t cid); |
- |
- void SpecializePolymorphicInstanceCall(PolymorphicInstanceCallInstr* call); |
- |
- bool TryReplaceWithStoreIndexed(InstanceCallInstr* call); |
- bool InlineSetIndexed(MethodRecognizer::Kind kind, |
- const Function& target, |
- Instruction* call, |
- Definition* receiver, |
- intptr_t token_pos, |
- const ICData* ic_data, |
- const ICData& value_check, |
- TargetEntryInstr** entry, |
- Definition** last); |
- bool TryReplaceWithLoadIndexed(InstanceCallInstr* call); |
- bool InlineGetIndexed(MethodRecognizer::Kind kind, |
- Instruction* call, |
- Definition* receiver, |
- const ICData& ic_data, |
- TargetEntryInstr** entry, |
- Definition** last); |
- intptr_t PrepareInlineIndexedOp(Instruction* call, |
- intptr_t array_cid, |
- Definition** array, |
- Definition* index, |
- Instruction** cursor); |
- |
- |
- bool TryReplaceWithBinaryOp(InstanceCallInstr* call, Token::Kind op_kind); |
- bool TryReplaceWithUnaryOp(InstanceCallInstr* call, Token::Kind op_kind); |
- |
- bool TryReplaceWithEqualityOp(InstanceCallInstr* call, Token::Kind op_kind); |
- bool TryReplaceWithRelationalOp(InstanceCallInstr* call, Token::Kind op_kind); |
- |
- bool TryInlineInstanceGetter(InstanceCallInstr* call); |
- bool TryInlineInstanceSetter(InstanceCallInstr* call, |
- const ICData& unary_ic_data); |
- |
- bool TryInlineInstanceMethod(InstanceCallInstr* call); |
- bool TryInlineFloat32x4Constructor(StaticCallInstr* call, |
- MethodRecognizer::Kind recognized_kind); |
- bool TryInlineFloat64x2Constructor(StaticCallInstr* call, |
- MethodRecognizer::Kind recognized_kind); |
- bool TryInlineInt32x4Constructor(StaticCallInstr* call, |
- MethodRecognizer::Kind recognized_kind); |
- bool TryInlineFloat32x4Method(InstanceCallInstr* call, |
- MethodRecognizer::Kind recognized_kind); |
- bool TryInlineFloat64x2Method(InstanceCallInstr* call, |
- MethodRecognizer::Kind recognized_kind); |
- bool TryInlineInt32x4Method(InstanceCallInstr* call, |
- MethodRecognizer::Kind recognized_kind); |
- void ReplaceWithInstanceOf(InstanceCallInstr* instr); |
- bool TypeCheckAsClassEquality(const AbstractType& type); |
- void ReplaceWithTypeCast(InstanceCallInstr* instr); |
- |
- bool TryReplaceInstanceCallWithInline(InstanceCallInstr* call); |
- |
- Definition* PrepareInlineStringIndexOp(Instruction* call, |
- intptr_t cid, |
- Definition* str, |
- Definition* index, |
- Instruction* cursor); |
- |
- bool InlineStringCodeUnitAt(Instruction* call, |
- intptr_t cid, |
- TargetEntryInstr** entry, |
- Definition** last); |
- |
- bool InlineStringBaseCharAt(Instruction* call, |
- intptr_t cid, |
- TargetEntryInstr** entry, |
- Definition** last); |
- |
- bool InlineDoubleOp(Token::Kind op_kind, |
- Instruction* call, |
- TargetEntryInstr** entry, |
- Definition** last); |
- |
- bool InlineByteArrayViewLoad(Instruction* call, |
- Definition* receiver, |
- intptr_t array_cid, |
- intptr_t view_cid, |
- const ICData& ic_data, |
- TargetEntryInstr** entry, |
- Definition** last); |
- |
- bool InlineByteArrayViewStore(const Function& target, |
- Instruction* call, |
- Definition* receiver, |
- intptr_t array_cid, |
- intptr_t view_cid, |
- const ICData& ic_data, |
- TargetEntryInstr** entry, |
- Definition** last); |
- |
- intptr_t PrepareInlineByteArrayViewOp(Instruction* call, |
- intptr_t array_cid, |
- intptr_t view_cid, |
- Definition** array, |
- Definition* index, |
- Instruction** cursor); |
- |
- bool BuildByteArrayViewLoad(InstanceCallInstr* call, |
- intptr_t view_cid); |
- bool BuildByteArrayViewStore(InstanceCallInstr* call, |
- intptr_t view_cid); |
- |
- // Insert a check of 'to_check' determined by 'unary_checks'. If the |
- // check fails it will deoptimize to 'deopt_id' using the deoptimization |
- // environment 'deopt_environment'. The check is inserted immediately |
- // before 'insert_before'. |
- void AddCheckClass(Definition* to_check, |
- const ICData& unary_checks, |
- intptr_t deopt_id, |
- Environment* deopt_environment, |
- Instruction* insert_before); |
- Instruction* GetCheckClass(Definition* to_check, |
- const ICData& unary_checks, |
- intptr_t deopt_id, |
- intptr_t token_pos); |
- |
- // Insert a Smi check if needed. |
- void AddCheckSmi(Definition* to_check, |
- intptr_t deopt_id, |
- Environment* deopt_environment, |
- Instruction* insert_before); |
- |
- // Add a class check for a call's first argument immediately before the |
- // call, using the call's IC data to determine the check, and the call's |
- // deopt ID and deoptimization environment if the check fails. |
- void AddReceiverCheck(InstanceCallInstr* call); |
- |
- void ReplaceCall(Definition* call, Definition* replacement); |
- |
- void InsertConversionsFor(Definition* def); |
- |
- void ConvertUse(Value* use, Representation from); |
- void ConvertEnvironmentUse(Value* use, Representation from); |
- |
- void InsertConversion(Representation from, |
- Representation to, |
- Value* use, |
- bool is_environment_use); |
- |
- bool InstanceCallNeedsClassCheck(InstanceCallInstr* call, |
- RawFunction::Kind kind) const; |
- |
- bool InlineFloat32x4Getter(InstanceCallInstr* call, |
- MethodRecognizer::Kind getter); |
- bool InlineFloat64x2Getter(InstanceCallInstr* call, |
- MethodRecognizer::Kind getter); |
- bool InlineInt32x4Getter(InstanceCallInstr* call, |
- MethodRecognizer::Kind getter); |
- bool InlineFloat32x4BinaryOp(InstanceCallInstr* call, |
- Token::Kind op_kind); |
- bool InlineInt32x4BinaryOp(InstanceCallInstr* call, |
- Token::Kind op_kind); |
- bool InlineFloat64x2BinaryOp(InstanceCallInstr* call, |
- Token::Kind op_kind); |
- void InlineImplicitInstanceGetter(InstanceCallInstr* call); |
- |
- RawBool* InstanceOfAsBool(const ICData& ic_data, |
- const AbstractType& type, |
- ZoneGrowableArray<intptr_t>* results) const; |
- |
- void ReplaceWithMathCFunction(InstanceCallInstr* call, |
- MethodRecognizer::Kind recognized_kind); |
- |
- void OptimizeLeftShiftBitAndSmiOp(Definition* bit_and_instr, |
- Definition* left_instr, |
- Definition* right_instr); |
- void TryMergeTruncDivMod(GrowableArray<BinarySmiOpInstr*>* merge_candidates); |
- void TryMergeMathUnary(GrowableArray<MathUnaryInstr*>* merge_candidates); |
- |
- void AppendLoadIndexedForMerged(Definition* instr, intptr_t ix, intptr_t cid); |
- void AppendExtractNthOutputForMerged(Definition* instr, intptr_t ix, |
- Representation rep, intptr_t cid); |
- bool TryStringLengthOneEquality(InstanceCallInstr* call, Token::Kind op_kind); |
- |
- Isolate* isolate() const { return flow_graph_->isolate(); } |
- |
- FlowGraph* flow_graph_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer); |
-}; |
- |
- |
-// Loop invariant code motion. |
-class LICM : public ValueObject { |
- public: |
- explicit LICM(FlowGraph* flow_graph); |
- |
- void Optimize(); |
- |
- void OptimisticallySpecializeSmiPhis(); |
- |
- private: |
- FlowGraph* flow_graph() const { return flow_graph_; } |
- |
- void Hoist(ForwardInstructionIterator* it, |
- BlockEntryInstr* pre_header, |
- Instruction* current); |
- |
- void TrySpecializeSmiPhi(PhiInstr* phi, |
- BlockEntryInstr* header, |
- BlockEntryInstr* pre_header); |
- |
- FlowGraph* const flow_graph_; |
-}; |
- |
- |
-// A simple common subexpression elimination based |
-// on the dominator tree. |
-class DominatorBasedCSE : public AllStatic { |
- public: |
- // Return true, if the optimization changed the flow graph. |
- // False, if nothing changed. |
- static bool Optimize(FlowGraph* graph); |
- |
- private: |
- static bool OptimizeRecursive( |
- FlowGraph* graph, |
- BlockEntryInstr* entry, |
- CSEInstructionMap* map); |
-}; |
- |
- |
-class DeadStoreElimination : public AllStatic { |
- public: |
- static void Optimize(FlowGraph* graph); |
-}; |
- |
- |
-class DeadCodeElimination : public AllStatic { |
- public: |
- static void EliminateDeadPhis(FlowGraph* graph); |
-}; |
- |
- |
// Sparse conditional constant propagation and unreachable code elimination. |
// Assumes that use lists are computed and preserves them. |
class ConstantPropagator : public FlowGraphVisitor { |
@@ -393,121 +87,6 @@ |
}; |
-// Rewrite branches to eliminate materialization of boolean values after |
-// inlining, and to expose other optimizations (e.g., constant folding of |
-// branches, unreachable code elimination). |
-class BranchSimplifier : public AllStatic { |
- public: |
- static void Simplify(FlowGraph* flow_graph); |
- |
- // Replace a target entry instruction with a join entry instruction. Does |
- // not update the original target's predecessors to point to the new block |
- // and does not replace the target in already computed block order lists. |
- static JoinEntryInstr* ToJoinEntry(Isolate* isolate, |
- TargetEntryInstr* target); |
- |
- private: |
- // Match an instance of the pattern to rewrite. See the implementation |
- // for the patterns that are handled by this pass. |
- static bool Match(JoinEntryInstr* block); |
- |
- // Duplicate a branch while replacing its comparison's left and right |
- // inputs. |
- static BranchInstr* CloneBranch(Isolate* isolate, |
- BranchInstr* branch, |
- Value* new_left, |
- Value* new_right); |
-}; |
- |
- |
-// Rewrite diamond control flow patterns that materialize values to use more |
-// efficient branchless code patterns if such are supported on the current |
-// platform. |
-class IfConverter : public AllStatic { |
- public: |
- static void Simplify(FlowGraph* flow_graph); |
-}; |
- |
- |
-class AllocationSinking : public ZoneAllocated { |
- public: |
- explicit AllocationSinking(FlowGraph* flow_graph) |
- : flow_graph_(flow_graph), |
- candidates_(5), |
- materializations_(5) { } |
- |
- const GrowableArray<Definition*>& candidates() const { |
- return candidates_; |
- } |
- |
- // Find the materialization insterted for the given allocation |
- // at the given exit. |
- MaterializeObjectInstr* MaterializationFor(Definition* alloc, |
- Instruction* exit); |
- |
- void Optimize(); |
- |
- void DetachMaterializations(); |
- |
- private: |
- // Helper class to collect deoptimization exits that might need to |
- // rematerialize an object: that is either instructions that reference |
- // this object explicitly in their deoptimization environment or |
- // reference some other allocation sinking candidate that points to |
- // this object. |
- class ExitsCollector : public ValueObject { |
- public: |
- ExitsCollector() : exits_(10), worklist_(3) { } |
- |
- const GrowableArray<Instruction*>& exits() const { return exits_; } |
- |
- void CollectTransitively(Definition* alloc); |
- |
- private: |
- // Collect immediate uses of this object in the environments. |
- // If this object is stored into other allocation sinking candidates |
- // put them onto worklist so that CollectTransitively will process them. |
- void Collect(Definition* alloc); |
- |
- GrowableArray<Instruction*> exits_; |
- GrowableArray<Definition*> worklist_; |
- }; |
- |
- void CollectCandidates(); |
- |
- void NormalizeMaterializations(); |
- |
- void RemoveUnusedMaterializations(); |
- |
- void DiscoverFailedCandidates(); |
- |
- void InsertMaterializations(Definition* alloc); |
- |
- void CreateMaterializationAt( |
- Instruction* exit, |
- Definition* alloc, |
- const ZoneGrowableArray<const Object*>& fields); |
- |
- void EliminateAllocation(Definition* alloc); |
- |
- Isolate* isolate() const { return flow_graph_->isolate(); } |
- |
- FlowGraph* flow_graph_; |
- |
- GrowableArray<Definition*> candidates_; |
- GrowableArray<MaterializeObjectInstr*> materializations_; |
- |
- ExitsCollector exits_collector_; |
-}; |
- |
- |
-// Optimize spill stores inside try-blocks by identifying values that always |
-// contain a single known constant at catch block entry. |
-class TryCatchAnalyzer : public AllStatic { |
- public: |
- static void Optimize(FlowGraph* flow_graph); |
-}; |
- |
} // namespace dart |
-#endif // VM_FLOW_GRAPH_OPTIMIZER_H_ |
+#endif // VM_CONSTANT_PROPAGATOR_H_ |