1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5//
6// This class is used to perform data flow optimizations.
7// An example usage would be:
8//
9// DataFlow flow(m_pCompiler);
10// flow.ForwardAnalysis(callback);
11//
12// The "callback" object needs to implement the following member
13// functions that the "flow" object will call as the data flow
14// analysis progresses:
15//
16// class Callback
17// {
18// public:
19// void StartMerge(BasicBlock* block);
20// void Merge(BasicBlock* block, BasicBlock* pred, flowList* preds);
21// bool EndMerge(BasicBlock* block);
22// };
23#pragma once
24
25#include "compiler.h"
26#include "jitstd.h"
27
28class DataFlow
29{
30private:
31 DataFlow();
32
33public:
34 DataFlow(Compiler* pCompiler);
35
36 template <typename TCallback>
37 void ForwardAnalysis(TCallback& callback);
38
39private:
40 Compiler* m_pCompiler;
41};
42
43template <typename TCallback>
44void DataFlow::ForwardAnalysis(TCallback& callback)
45{
46 jitstd::list<BasicBlock*> worklist(jitstd::allocator<void>(m_pCompiler->getAllocator()));
47
48 worklist.insert(worklist.begin(), m_pCompiler->fgFirstBB);
49 while (!worklist.empty())
50 {
51 BasicBlock* block = *(worklist.begin());
52 worklist.erase(worklist.begin());
53
54 callback.StartMerge(block);
55 {
56 flowList* preds = m_pCompiler->BlockPredsWithEH(block);
57 for (flowList* pred = preds; pred; pred = pred->flNext)
58 {
59 callback.Merge(block, pred->flBlock, preds);
60 }
61 }
62
63 if (callback.EndMerge(block))
64 {
65 for (BasicBlock* succ : block->GetAllSuccs(m_pCompiler))
66 {
67 worklist.insert(worklist.end(), succ);
68 }
69 }
70 }
71}
72