5#ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_H_
6#define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_H_
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
25class VariableLivenessAnalysis;
28class GraphIntrinsifier;
34 : block_order_(block_order), current_(0) {}
38 block_order_(other.block_order_),
39 current_(other.current_) {}
46 bool Done()
const {
return current_ >= block_order_.length(); }
72 if (
key.constant.IsSmi()) {
73 return Smi::Cast(
key.constant).Value();
75 if (
key.constant.IsDouble()) {
76 return static_cast<intptr_t
>(bit_cast<int32_t, float>(
77 static_cast<float>(Double::Cast(
key.constant).value())));
79 if (
key.constant.IsMint()) {
80 return static_cast<intptr_t
>(Mint::Cast(
key.constant).value());
82 if (
key.constant.IsString()) {
83 return String::Cast(
key.constant).Hash();
85 return key.constant.GetClassId();
132 void Print(
const char* phase =
"unknown");
191 return num_direct_parameters_ - variable->
index().
value();
208 return reverse_postorder_;
211 return optimized_block_order_;
245 current_ssa_temp_index_ = index;
252 enum class ToCheck { kNoCheck, kCheckNull, kCheckCid };
276 current_ssa_temp_index_++;
308 bool tagged_value_must_be_smi);
412 return unmatched_representations_allowed_;
418 unmatched_representations_allowed_ =
false;
431 if (loop_hierarchy_ ==
nullptr) {
432 loop_hierarchy_ = ComputeLoops();
445 loop_hierarchy_ =
nullptr;
446 loop_invariant_loads_ =
nullptr;
453 return loop_invariant_loads_;
505 return compiler_pass_filters_;
511 return should_remove_all_bounds_checks_;
564 return max_argument_slot_count_;
568 max_argument_slot_count_ =
count;
573 return direct_parameter_locations_[
i];
579 bool should_assign_stack_locations =
false,
583 intptr_t arguments_count);
611 void CompressPath(intptr_t start_index,
612 intptr_t current_index,
631 void PopulateEnvironmentFromFunctionEntry(
638 void PopulateEnvironmentFromOsrEntry(
OsrEntryInstr* osr_entry,
671 bool is_environment_use);
677 void ComputeIsReceiver(
PhiInstr* phi)
const;
678 void ComputeIsReceiverRecursive(
PhiInstr* phi,
681 void OptimizeLeftShiftBitAndSmiOp(
689 void AppendExtractNthOutputForMerged(
Definition* instr,
699 void ExtractNonInternalTypedDataPayload(
Instruction* instr,
709 intptr_t current_ssa_temp_index_;
710 intptr_t max_block_id_;
714 intptr_t num_direct_parameters_;
725 bool unmatched_representations_allowed_ =
true;
726 bool huge_method_ =
false;
727 const bool should_reorder_blocks_;
738 intptr_t inlining_id_;
740 const bool should_remove_all_bounds_checks_;
741 uint8_t* compiler_pass_filters_ =
nullptr;
743 intptr_t max_argument_slot_count_ = -1;
745 const Array* coverage_array_ = &Array::empty_array();
825 : defs_(initial_capacity),
826 contains_vector_(new
BitVector(flow_graph->zone(),
827 flow_graph->current_ssa_temp_index())) {}
841 bool IsEmpty()
const {
return defs_.is_empty(); }
854 contains_vector_->
Clear();
static float next(float f)
static float prev(float f)
#define RELEASE_ASSERT(cond)
bool Contains(intptr_t i) const
intptr_t postorder_number() const
intptr_t stack_depth() const
BlockIterator(const GrowableArray< BlockEntryInstr * > &block_order)
BlockEntryInstr * Current() const
BlockIterator(const BlockIterator &other)
const Object & value() const
BitVector * contains_vector() const
bool Contains(Definition *defn) const
void Add(Definition *defn)
Definition * RemoveLast()
const GrowableArray< Definition * > & definitions() const
DefinitionWorklist(FlowGraph *flow_graph, intptr_t initial_capacity)
void set_ssa_temp_index(intptr_t index)
intptr_t ssa_temp_index() const
const GrowableArray< BlockEntryInstr * > & reverse_postorder() const
GraphEntryInstr * graph_entry() const
ConstantInstr * GetConstant(const Object &object, Representation representation=kTagged)
IsolateGroup * isolate_group() const
bool should_print() const
PrologueInfo prologue_info() const
bool VerifyRedefinitions()
void EnsureSSATempIndex(Definition *defn, Definition *replacement)
Instruction * AppendTo(Instruction *prev, Instruction *instr, Environment *env, UseKind use_kind)
static constexpr CompilationMode CompilationModeFrom(bool is_optimizing)
void set_coverage_array(const Array &array)
void CompactSSA(ZoneGrowableArray< Definition * > *detached_defs=nullptr)
intptr_t max_argument_slot_count() const
bool IsCompiledForOsr() const
ConstantInstr * constant_dead() const
ConstantInstr * GetExistingConstant(const Object &object, Representation representation=kTagged) const
intptr_t current_ssa_temp_index() const
bool IsReceiver(Definition *def) const
intptr_t ArgumentDescriptorEnvIndex() const
static Representation ReturnRepresentationOf(const Function &function)
intptr_t inlining_id() const
const uint8_t * compiler_pass_filters() const
void ReplaceCurrentInstruction(ForwardInstructionIterator *iterator, Instruction *current, Instruction *replacement)
bool should_remove_all_bounds_checks() const
JoinEntryInstr * NewDiamond(Instruction *instruction, Instruction *inherit, ComparisonInstr *compare, TargetEntryInstr **block_true, TargetEntryInstr **block_false)
Instruction * AppendSpeculativeTo(Instruction *prev, Instruction *instr, Environment *env, UseKind use_kind)
intptr_t InstructionCount() const
ToCheck CheckForInstanceCall(InstanceCallInstr *call, UntaggedFunction::Kind kind) const
void RemoveRedefinitions(bool keep_checks=false)
bool IsIrregexpFunction() const
intptr_t SuspendStateEnvIndex() const
const GrowableArray< BlockEntryInstr * > & preorder() const
void set_current_ssa_temp_index(intptr_t index)
void CreateCommonConstants()
void AddExactnessGuard(InstanceCallInstr *call, intptr_t receiver_cid)
const std::pair< Location, Representation > & GetDirectParameterInfoAt(intptr_t i)
void InsertSpeculativeAfter(Instruction *prev, Instruction *instr, Environment *env, UseKind use_kind)
void set_max_argument_slot_count(intptr_t count)
void set_loop_invariant_loads(ZoneGrowableArray< BitVector * > *loop_invariant_loads)
BlockIterator postorder_iterator() const
Definition * CreateCheckBound(Definition *length, Definition *index, intptr_t deopt_id)
intptr_t max_block_id() const
const GrowableArray< BlockEntryInstr * > & optimized_block_order() const
static intptr_t ComputeArgumentsSizeInWords(const Function &function, intptr_t arguments_count)
void InsertMoveArguments()
void Print(const char *phase="unknown")
const GrowableArray< BlockEntryInstr * > & postorder() const
intptr_t num_stack_locals() const
void ComputeDominators(GrowableArray< BitVector * > *dominance_frontier)
static Representation ParameterRepresentationAt(const Function &function, intptr_t index)
intptr_t max_vreg() const
void set_inlining_id(intptr_t value)
void EliminateEnvironments()
void disallow_unmatched_representations()
const Array & coverage_array() const
intptr_t CurrentContextEnvIndex() const
static intptr_t ComputeLocationsOfFixedParameters(Zone *zone, const Function &function, bool should_assign_stack_locations=false, compiler::ParameterInfoArray *parameter_info=nullptr)
BitVector * captured_parameters() const
void set_max_block_id(intptr_t id)
ConstantInstr * constant_null() const
Instruction * CreateCheckClass(Definition *to_check, const Cids &cids, intptr_t deopt_id, const InstructionSource &source)
const LoopHierarchy & GetLoopHierarchy()
const Function & function() const
const ParsedFunction & parsed_function() const
bool is_huge_method() const
bool is_licm_allowed() const
void ResetLoopHierarchy()
intptr_t num_direct_parameters() const
ZoneGrowableArray< BitVector * > * loop_invariant_loads() const
const LoopHierarchy & loop_hierarchy() const
void RenameUsesDominatedByRedefinitions()
FlowGraph(const ParsedFunction &parsed_function, GraphEntryInstr *graph_entry, intptr_t max_block_id, PrologueInfo prologue_info, CompilationMode compilation_mode)
bool unmatched_representations_allowed() const
Definition * TryCreateConstantReplacementFor(Definition *op, const Object &value)
intptr_t osr_variable_count() const
void PopulateWithICData(const Function &function)
RedefinitionInstr * EnsureRedefinition(Instruction *prev, Definition *original, CompileType compile_type)
void TryOptimizePatterns()
PhiInstr * AddPhi(JoinEntryInstr *join, Definition *d1, Definition *d2)
void AddToGraphInitialDefinitions(Definition *defn)
bool ExtractExternalUntaggedPayload(Instruction *instr, Value *array, classid_t cid)
void CopyDeoptTarget(Instruction *to, Instruction *from)
void AllocateSSAIndex(Definition *def)
static bool IsConstantRepresentable(const Object &value, Representation target_rep, bool tagged_value_must_be_smi)
BlockIterator reverse_postorder_iterator() const
void ComputeSSA(ZoneGrowableArray< Definition * > *inlining_parameters)
LocalVariable * CurrentContextVar() const
intptr_t RawTypeArgumentEnvIndex() const
void InsertBefore(Instruction *next, Instruction *instr, Environment *env, UseKind use_kind)
static void RenameDominatedUses(Definition *def, Instruction *dom, Definition *other)
LocalVariable * SuspendStateVar() const
friend class FlowGraphChecker
void SelectRepresentations()
intptr_t variable_count() const
void AddToInitialDefinitions(BlockEntryWithInitialDefs *entry, Definition *defn)
void ExtractNonInternalTypedDataPayloads()
GrowableArray< BlockEntryInstr * > * CodegenBlockOrder()
intptr_t allocate_block_id()
void InsertAfter(Instruction *prev, Instruction *instr, Environment *env, UseKind use_kind)
void InsertSpeculativeBefore(Instruction *next, Instruction *instr, Environment *env, UseKind use_kind)
bool should_reorder_blocks() const
bool IsImmortalVariable(intptr_t env_index) const
intptr_t EnvIndex(const LocalVariable *variable) const
bool IsIrregexpFunction() const
bool IsCompiledForOsr() const
OsrEntryInstr * osr_entry() const
void InheritDeoptTarget(Zone *zone, Instruction *other)
virtual Representation representation() const
const intptr_t variable_count_
virtual ~LivenessAnalysis()
virtual void ComputeInitialSets()=0
GrowableArray< BitVector * > kill_
void ComputeLiveInAndLiveOutSets()
bool UpdateLiveOut(const BlockEntryInstr &instr)
BitVector * GetKillSet(BlockEntryInstr *block) const
LivenessAnalysis(intptr_t variable_count, const GrowableArray< BlockEntryInstr * > &postorder)
BitVector * GetLiveOutSetAt(intptr_t postorder_number) const
GrowableArray< BitVector * > live_out_
BitVector * GetLiveOutSet(BlockEntryInstr *block) const
GrowableArray< BitVector * > live_in_
BitVector * GetLiveInSet(BlockEntryInstr *block) const
BitVector * GetLiveInSetAt(intptr_t postorder_number) const
const GrowableArray< BlockEntryInstr * > & postorder_
bool UpdateLiveIn(const BlockEntryInstr &instr)
VariableIndex index() const
const Function & function() const
int num_stack_locals() const
LocalVariable * current_context_var() const
LocalVariable * suspend_state_var() const
IsolateGroup * isolate_group() const
static float max(float r, float g, float b)
static float min(float r, float g, float b)
static constexpr intptr_t kMaxLocationCount
int compare(const void *untyped_lhs, const void *untyped_rhs)
static SkString join(const CommandLineFlags::StringArray &)
Representation representation
static Key KeyOf(Pair kv)
static uword Hash(Key key)
static bool IsKeyEqual(Pair kv, Key key)
ConstantAndRepresentation Key
static Value ValueOf(Pair kv)
LogicalAnd(ComparisonInstr *x, ComparisonInstr *y)
bool Contains(intptr_t block_id) const
PrologueInfo(intptr_t min, intptr_t max)