15 if (!FLAG_reorder_basic_blocks) {
26 const Array& edge_counters,
27 intptr_t entry_count) {
29 if (
auto target = successor->AsTargetEntry()) {
36 static_cast<double>(
count) /
static_cast<double>(entry_count);
37 target->set_edge_weight(weight);
43 static_cast<double>(
count) /
static_cast<double>(entry_count);
44 jump->set_edge_weight(weight);
50 if (!FLAG_reorder_basic_blocks) {
58 const Array& ic_data_array =
60 if (ic_data_array.
IsNull()) {
68 if (edge_counters.
IsNull()) {
74 if (entry ==
nullptr) {
75 entry = graph_entry->osr_entry();
78 const intptr_t entry_count =
80 graph_entry->set_entry_count(entry_count);
81 if (entry_count == 0) {
128 if (
a->weight <
b->weight) {
131 return (
a->weight >
b->weight) ? 1 : 0;
138 Chain* target_chain) {
141 (*chains)[
link->block->postorder_number()] = target_chain;
150 (*chains)[
link->block->postorder_number()] = source_chain;
153 source_chain->
last = target_chain->
last;
164 ReorderBlocksAOT(flow_graph);
166 ReorderBlocksJIT(flow_graph);
170void BlockScheduler::ReorderBlocksJIT(
FlowGraph* flow_graph) {
185 chains.Add(
new Chain(block));
191 if (succ->IsTargetEntry()) {
192 weight = succ->AsTargetEntry()->edge_weight();
193 }
else if (last->IsGoto()) {
194 weight = last->AsGoto()->edge_weight();
196 edges.Add(
Edge(block, succ, weight));
202 while (!edges.is_empty()) {
203 Edge edge = edges.RemoveLast();
204 Chain* source_chain = chains[edge.source->postorder_number()];
205 Chain* target_chain = chains[edge.target->postorder_number()];
210 if ((source_chain == target_chain) ||
211 (edge.source != source_chain->last->block) ||
212 (edge.target != target_chain->first->block)) {
216 Union(&chains, source_chain, target_chain);
221 GraphEntryInstr* graph_entry = flow_graph->
graph_entry();
223 FunctionEntryInstr* checked_entry = graph_entry->normal_entry();
224 if (checked_entry !=
nullptr) {
233 if (chains[
i]->first->block == flow_graph->
postorder()[
i]) {
235 if ((
link->block != checked_entry) && (
link->block != graph_entry)) {
251class AOTBlockScheduler {
253 explicit AOTBlockScheduler(FlowGraph* flow_graph)
254 : flow_graph_(flow_graph),
255 block_count_(flow_graph->reverse_postorder().
length()),
256 marks_(block_count_),
257 postorder_(block_count_),
258 cold_postorder_(10) {
259 marks_.FillWith(0, 0, block_count_);
262 void ComputeOrder() {
265 const auto codegen_order = flow_graph_->CodegenBlockOrder();
266 for (intptr_t
i = postorder_.length() - 1;
i >= 0; --
i) {
267 codegen_order->Add(postorder_[
i]);
269 for (intptr_t
i = cold_postorder_.length() - 1;
i >= 0; --
i) {
270 codegen_order->Add(cold_postorder_[
i]);
278 void ComputeOrderImpl() {
279 PushBlock(flow_graph_->graph_entry());
280 while (!block_stack_.is_empty()) {
281 BlockEntryInstr* block = block_stack_.Last();
282 auto& marks = MarksOf(block);
283 auto last = block->last_instruction();
286 if ((marks & kVisitedMark) == 0) {
287 marks |= kVisitedMark;
289 if (last->IsThrow() || last->IsReThrow()) {
299 if (successor_count == 2 && block->loop_info() !=
nullptr) {
303 if (succ0->NestingDepth() < succ1->NestingDepth()) {
311 for (intptr_t
i = 0;
i < successor_count;
i++) {
317 if (block_stack_.Last() != block) {
327 block_stack_.RemoveLast();
331 if (successor_count > 0) {
332 uint8_t cold_mark = kColdMark;
333 for (intptr_t
i = 0;
i < successor_count;
i++) {
339 if ((marks & (kColdMark | kPinnedMark)) == kColdMark) {
342 cold_postorder_.Add(block);
344 postorder_.Add(block);
350 static constexpr uint8_t kSeenMark = 1 << 0;
352 static constexpr uint8_t kVisitedMark = 1 << 1;
354 static constexpr uint8_t kColdMark = 1 << 2;
356 static constexpr uint8_t kPinnedMark = 1 << 3;
358 uint8_t& MarksOf(BlockEntryInstr* block) {
359 return marks_[block->preorder_number()];
362 void PushBlock(BlockEntryInstr* block) {
363 auto& marks = MarksOf(block);
364 if ((marks & kSeenMark) == 0) {
366 block_stack_.Add(block);
368 if (block->IsFunctionEntry() || block->IsGraphEntry()) {
369 marks |= kPinnedMark;
374 FlowGraph*
const flow_graph_;
375 const intptr_t block_count_;
378 GrowableArray<uint8_t> marks_;
381 GrowableArray<BlockEntryInstr*> block_stack_;
383 GrowableArray<BlockEntryInstr*> postorder_;
384 GrowableArray<BlockEntryInstr*> cold_postorder_;
388void BlockScheduler::ReorderBlocksAOT(FlowGraph* flow_graph) {
389 AOTBlockScheduler(flow_graph).ComputeOrder();
GrTriangulator::Edge Edge
static int block_count(const SkSBlockAllocator< N > &pool)
#define DEBUG_ASSERT(cond)
ObjectPtr At(intptr_t index) const
intptr_t preorder_number() const
Instruction * last_instruction() const
static void AssignEdgeWeights(FlowGraph *flow_graph)
static void ReorderBlocks(FlowGraph *flow_graph)
static CompilerState & Current()
GraphEntryInstr * graph_entry() const
const GrowableArray< BlockEntryInstr * > & preorder() const
BlockIterator postorder_iterator() const
const GrowableArray< BlockEntryInstr * > & postorder() const
const ParsedFunction & parsed_function() const
BlockIterator reverse_postorder_iterator() const
GrowableArray< BlockEntryInstr * > * CodegenBlockOrder()
bool should_reorder_blocks() const
virtual BlockEntryInstr * SuccessorAt(intptr_t index) const
virtual intptr_t SuccessorCount() const
static IsolateGroup * Current()
static ObjectPtr RawCast(ObjectPtr obj)
const Function & function() const
Dart_NativeFunction function
def link(from_root, to_root)
static void SetEdgeWeight(BlockEntryInstr *block, BlockEntryInstr *successor, const Array &edge_counters, intptr_t entry_count)
static void Union(GrowableArray< Chain * > *chains, Chain *source_chain, Chain *target_chain)
static intptr_t GetEdgeCount(const Array &edge_counters, intptr_t edge_id)
Chain(BlockEntryInstr *block)
Edge(BlockEntryInstr *source, BlockEntryInstr *target, double weight)
static int LowestWeightFirst(const Edge *a, const Edge *b)
static constexpr intptr_t kEdgeCounters
Link(BlockEntryInstr *block, Link *next)