1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2020-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #ifndef _LOCAL_DATAFLOW_H
10 #define _LOCAL_DATAFLOW_H
11 
12 #include "FlowGraph.h"
13 #include "BuildIR.h"
14 
15 #include <unordered_map>
16 
17 using namespace vISA;
18 
19 // ToDo: move Local dataflow here and make it a class
20 
21 namespace vISA {
22 
23     // A simple local (within one BB) analysis that checks if a def escapes (i.e., reaches the end of BB without other defines killing it).
24     // This information may be helpful for a number of optimizations by determining if a define has only local effect.
25     // Destination may be GRF or Address (i.e., direct DstRegRegion).
26     // Acc and other special ARFs are not considered as their defintions should always be local.
27     // Flag dst (i.e., conditional modifier) is currently not handled; while adding it is possible it may lead to confusion for instructions with both dst and condMod.
28     // To reduce compilation overhead and implementation complexity only a single killing defintion is considered for now;
29     // this is conservative but should cover most pratical cases as our input is almost SSA.
30     class DefEscapeBBAnalysis
31     {
32 
33         const FlowGraph& fg;
34 
35         // all escaped inst for this BB
36         // If BB is not in the map, it means we need to run analysis for this BB
37         // ToDo: assumption is that there should not be many escaped inst. Can change to vector to set later if desired.
38         std::unordered_map<G4_BB*, std::vector<G4_INST*> > escapedInsts;
39 
40 #ifdef _DEBUG
41         // for debugging only, record instructions that were killed in the BB
42         std::unordered_map<G4_BB*, std::vector<G4_INST*> > killedDefs;
43 #endif
44 
45     public:
46 
DefEscapeBBAnalysis(const FlowGraph & cfg)47         DefEscapeBBAnalysis(const FlowGraph& cfg) : fg(cfg) {}
48 
49         DefEscapeBBAnalysis(const DefEscapeBBAnalysis& analysis) = delete;
50 
51         virtual ~DefEscapeBBAnalysis() = default;
52 
run()53         void run()
54         {
55             for (auto&& bb : const_cast<FlowGraph&>(fg))
56             {
57                 analyzeBB(bb);
58             }
59         }
60 
61         void analyzeBB(G4_BB* bb);
62 
isBBValid(G4_BB * bb)63         bool isBBValid(G4_BB* bb) const { return escapedInsts.count(bb); }
invalidate()64         void invalidate() { escapedInsts.clear(); }
invalidateBB(G4_BB * bb)65         void invalidateBB(G4_BB* bb) { escapedInsts.erase(bb); }
isEscaped(G4_BB * bb,G4_INST * inst)66         bool isEscaped(G4_BB* bb, G4_INST* inst)
67         {
68             if (!isBBValid(bb))
69             {
70                 analyzeBB(bb);
71             }
72             auto&& vec = escapedInsts.find(bb)->second;
73             return std::find(vec.begin(), vec.end(), inst) != vec.end();
74         }
75         void print(std::ostream& OS) const;
dump()76         void dump() const
77         {
78             print(std::cerr);
79         }
80     };
81 }
82 #endif // _LOCAL_DATAFLOW_H
83