23 -1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, 10.0, 20.0, 30.0, 64.0,
26 2.718281828459045, 2.302585092994046, 0.6931471805599453,
27 1.4426950408889634, 0.4342944819032518, 3.1415926535897932,
28 0.7071067811865476, 1.4142135623730951};
32 for (intptr_t
i = 0;
i <
len;
i++) {
56 auto zone = callee_graph->
zone();
59 const intptr_t outer_deopt_id = call_->
deopt_id();
61 double scale_factor = 1.0;
68 !block_it.
Done(); block_it.Advance()) {
70 if (block->IsTargetEntry()) {
71 block->AsTargetEntry()->adjust_edge_weight(scale_factor);
74 if (block->
env() !=
nullptr) {
75 env->DeepCopyToOuter(zone, block, outer_deopt_id);
82 if (instr->
env() !=
nullptr) {
83 env->DeepCopyToOuter(zone, instr, outer_deopt_id);
86 if (instr->IsGoto()) {
87 instr->AsGoto()->adjust_edge_weight(scale_factor);
91 RemoveUnreachableExits(callee_graph);
102 ASSERT(caller_graph_ == other->caller_graph_);
103 ASSERT(call_ == other->call_);
107int InlineExitCollector::LowestBlockIdFirst(
const Data*
a,
const Data*
b) {
108 return (
a->exit_block->block_id() -
b->exit_block->block_id());
111void InlineExitCollector::RemoveUnreachableExits(FlowGraph* callee_graph) {
112 const GrowableArray<BlockEntryInstr*>& postorder = callee_graph->postorder();
114 for (
int i = 0;
i < exits_.
length(); ++
i) {
115 BlockEntryInstr* block = exits_[
i].exit_return->GetBlock();
116 if ((block !=
nullptr) && (0 <= block->postorder_number()) &&
117 (block->postorder_number() < postorder.length()) &&
118 (postorder[block->postorder_number()] == block)) {
120 exits_[j] = exits_[
i];
128void InlineExitCollector::SortExits() {
131 for (
int i = 0;
i < exits_.
length(); ++
i) {
132 exits_[
i].exit_block = exits_[
i].exit_return->GetBlock();
134 exits_.
Sort(LowestBlockIdFirst);
137Definition* InlineExitCollector::JoinReturns(BlockEntryInstr** exit_block,
138 Instruction** last_instruction,
139 intptr_t try_index) {
143 intptr_t num_exits = exits_.
length();
144 if (num_exits == 1) {
146 *exit_block = ExitBlockAt(0);
147 *last_instruction = LastInstructionAt(0);
154 JoinEntryInstr*
join =
new (
Z) JoinEntryInstr(
169 GrowableArray<BlockEntryInstr*> block_dominators;
170 GrowableArray<BlockEntryInstr*> join_dominators;
171 for (intptr_t
i = 0;
i < num_exits; ++
i) {
173 GotoInstr* goto_instr =
175 goto_instr->InheritDeoptTarget(zone(), ReturnAt(
i));
176 LastInstructionAt(
i)->
LinkTo(goto_instr);
178 join->predecessors_.Add(ExitBlockAt(
i));
181 block_dominators.Clear();
182 BlockEntryInstr* dominator = ExitBlockAt(
i)->
dominator();
183 while (dominator !=
nullptr) {
184 block_dominators.Add(dominator);
191 for (intptr_t j = block_dominators.length() - 1; j >= 0; --j) {
192 join_dominators.Add(block_dominators[j]);
196 intptr_t last = block_dominators.length() - 1;
197 for (intptr_t j = 0; j < join_dominators.length(); ++j) {
198 intptr_t k = last - j;
199 if ((k < 0) || (join_dominators[j] != block_dominators[k])) {
205 join_dominators.TruncateTo(j);
213 join_dominators.Last()->AddDominatedBlock(
join);
215 *last_instruction =
join;
220 PhiInstr* phi =
new (
Z) PhiInstr(
join, num_exits);
223 for (intptr_t
i = 0;
i < num_exits; ++
i) {
225 phi->SetInputAt(
i, ValueAt(
i));
227 join->InsertPhi(phi);
228 join->InheritDeoptTargetAfter(caller_graph_, call_, phi);
233 for (intptr_t
i = 0;
i < num_exits; ++
i) {
236 join->InheritDeoptTargetAfter(caller_graph_, call_,
nullptr);
251 if (exits_.
length() == 0) {
268 new (
Z)
Value(true_const),
269 new (
Z)
Value(true_const),
false,
291 true_target->AddDominatedBlock(block);
304 &callee_exit, &callee_last_instruction, call_block->
try_index());
305 if (callee_result !=
nullptr) {
308 if (callee_last_instruction == callee_entry) {
315 callee_last_instruction->
LinkTo(call_->
next());
317 if (callee_exit != callee_entry) {
374 if (!
type.IsInstantiated())
return false;
377 if (
type.IsFunctionType() ||
type.IsRecordType() ||
378 type.IsDartFunctionType()) {
static float next(float f)
void TruncateTo(intptr_t length)
void AddArray(const BaseGrowableArray< T, B, Allocator > &src)
void Sort(int compare(const T *, const T *))
BlockEntryInstr * dominator() const
void ClearDominatedBlocks()
intptr_t try_index() const
void AddDominatedBlock(BlockEntryInstr *block)
virtual intptr_t PredecessorCount() const =0
const GrowableArray< BlockEntryInstr * > & dominated_blocks()
void ReplaceAsPredecessorWith(BlockEntryInstr *new_block)
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const =0
void set_last_instruction(Instruction *instr)
static const Bool & True()
TargetEntryInstr ** false_successor_address()
TargetEntryInstr ** true_successor_address()
static TargetEntryInstr * ToTargetEntry(Zone *zone, BlockEntryInstr *target)
intptr_t GetNextDeoptId()
static CompilerState & Current()
virtual intptr_t CallCount() const
void ReplaceUsesWith(Definition *other)
static constexpr intptr_t kNone
GraphEntryInstr * graph_entry() const
ConstantInstr * GetConstant(const Object &object, Representation representation=kTagged)
intptr_t current_ssa_temp_index() const
void set_current_ssa_temp_index(intptr_t index)
BlockIterator postorder_iterator() const
intptr_t max_block_id() const
void set_max_block_id(intptr_t id)
void AllocateSSAIndex(Definition *def)
intptr_t allocate_block_id()
intptr_t entry_count() const
virtual intptr_t SuccessorCount() const
void Union(const InlineExitCollector *other)
void PrepareGraphs(FlowGraph *callee_graph)
void AddExit(DartReturnInstr *exit)
void ReplaceCall(BlockEntryInstr *callee_entry)
Instruction * next() const
void InheritDeoptTargetAfter(FlowGraph *flow_graph, Definition *call, Definition *result)
void LinkTo(Instruction *next)
void InheritDeoptTarget(Zone *zone, Instruction *other)
virtual BlockEntryInstr * GetBlock()
Environment * env() const
Instruction * AppendInstruction(Instruction *tail)
intptr_t deopt_id() const
Instruction * previous() const
static Thread * Current()
static bool DoublesBitEqual(const double a, const double b)
Definition * definition() const
#define COMPILER_TIMINGS_TIMER_SCOPE(thread, timer_id)
uword FindDoubleConstant(double value)
bool SimpleInstanceOfType(const AbstractType &type)
const double kCommonDoubleConstants[]
static int8_t data[kExtLength]
struct PathData * Data(SkPath *path)
static SkString join(const CommandLineFlags::StringArray &)