Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / dataflow.h
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 necessary callback
13 //  functions that  the "flow" object will call as the data flow
14 //  analysis progresses.
15 //
16 #pragma once
17
18 #include "compiler.h"
19 #include "jitstd.h"
20
21 class DataFlow
22 {
23 private:
24     DataFlow();
25
26 public:
27     // The callback interface that needs to be implemented by anyone
28     // needing updates by the dataflow object.
29     class Callback
30     {
31     public:
32         Callback(Compiler* pCompiler);
33
34         void StartMerge(BasicBlock* block);
35         void Merge(BasicBlock* block, BasicBlock* pred, flowList* preds);
36         bool EndMerge(BasicBlock* block);
37
38     private:
39         Compiler* m_pCompiler;
40     };
41
42     DataFlow(Compiler* pCompiler);
43
44     template <typename TCallback>
45     void ForwardAnalysis(TCallback& callback);
46
47 private:
48     Compiler* m_pCompiler;
49 };
50
51 template <typename TCallback>
52 void DataFlow::ForwardAnalysis(TCallback& callback)
53 {
54     jitstd::list<BasicBlock*> worklist(jitstd::allocator<void>(m_pCompiler->getAllocator()));
55
56     worklist.insert(worklist.begin(), m_pCompiler->fgFirstBB);
57     while (!worklist.empty())
58     {
59         BasicBlock* block = *(worklist.begin());
60         worklist.erase(worklist.begin());
61
62         callback.StartMerge(block);
63         {
64             flowList* preds = m_pCompiler->BlockPredsWithEH(block);
65             for (flowList* pred = preds; pred; pred = pred->flNext)
66             {
67                 callback.Merge(block, pred->flBlock, preds);
68             }
69         }
70
71         if (callback.EndMerge(block))
72         {
73             for (BasicBlock* succ : block->GetAllSuccs(m_pCompiler))
74             {
75                 worklist.insert(worklist.end(), succ);
76             }
77         }
78     }
79 }