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 | |
28 | class DataFlow |
29 | { |
30 | private: |
31 | DataFlow(); |
32 | |
33 | public: |
34 | DataFlow(Compiler* pCompiler); |
35 | |
36 | template <typename TCallback> |
37 | void ForwardAnalysis(TCallback& callback); |
38 | |
39 | private: |
40 | Compiler* m_pCompiler; |
41 | }; |
42 | |
43 | template <typename TCallback> |
44 | void 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 |