1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #ifndef __SPILLCLEANUP_H__
10 #define __SPILLCLEANUP_H__
11 
12 #include "G4_IR.hpp"
13 #include "FlowGraph.h"
14 #include "RPE.h"
15 
16 namespace vISA
17 {
18     class CoalesceSpillFills
19     {
20     private:
21         G4_Kernel& kernel;
22         LivenessAnalysis& liveness;
23         GraphColor& graphColor;
24         GlobalRA& gra;
25         SpillManagerGRF& spill;
26         unsigned int iterNo;
27         // Store declares spilled by sends like sampler
28         std::set<G4_Declare*> sendDstDcl;
29         std::set<G4_Declare*> addrTakenSpillFillDcl;
30         RPE& rpe;
31 
32         // Set window size to coalesce
33         const unsigned int cWindowSize = 10;
34         const unsigned int cMaxFillPayloadSize = 4;
35         const unsigned int cMaxSpillPayloadSize = 4;
36         const unsigned int cSpillFillCleanupWindowSize = 10;
37         const unsigned int cFillWindowThreshold128GRF = 180;
38         const unsigned int cSpillWindowThreshold128GRF = 120;
39 
40         unsigned int fillWindowSizeThreshold = 0;
41         unsigned int spillWindowSizeThreshold = 0;
42 
43         // <Old fill declare*, std::pair<Coalesced Decl*, Row Off>>
44         // This data structure is used to replaced old spill/fill operands
45         // with coalesced operands with correct offset.
46         std::map<G4_Declare*, std::pair<G4_Declare*, unsigned int>> replaceMap;
47 
48         bool replaceCoalescedOperands(G4_INST*);
49 
50         void dumpKernel();
51         void dumpKernel(unsigned int v1, unsigned int v2);
52 
53         bool notOOB(unsigned int min, unsigned int max);
54         void sendsInRange(std::list<INST_LIST_ITER>&,
55             std::list<INST_LIST_ITER>&,
56             unsigned int, unsigned int&, unsigned int&);
57         void keepConsecutiveSpills(std::list<INST_LIST_ITER>&,
58             std::list<INST_LIST_ITER>&,
59             unsigned int, unsigned int&, unsigned int&, bool&,
60             G4_InstOption&);
61         void fills();
62         void spills();
63         INST_LIST_ITER analyzeFillCoalescing(std::list<INST_LIST_ITER>&, INST_LIST_ITER, INST_LIST_ITER, G4_BB*);
64         INST_LIST_ITER analyzeSpillCoalescing(std::list<INST_LIST_ITER>&, INST_LIST_ITER, INST_LIST_ITER, G4_BB*);
65         void removeWARFills(std::list<INST_LIST_ITER>&, std::list<INST_LIST_ITER>&);
66         void coalesceFills(std::list<INST_LIST_ITER>&, unsigned int, unsigned int, G4_BB*, int);
67         G4_INST* generateCoalescedFill(G4_SrcRegRegion*, unsigned int, unsigned int, unsigned int, bool);
68         G4_SrcRegRegion* generateCoalescedSpill(G4_SrcRegRegion*, unsigned int, unsigned int, bool,
69             G4_InstOption, G4_Declare*, unsigned int);
70         void copyToOldFills(G4_DstRegRegion*, std::list<std::pair<G4_DstRegRegion*, std::pair<unsigned int, unsigned int>>>,
71             INST_LIST_ITER, G4_BB*, int);
72         bool fillHeuristic(std::list<INST_LIST_ITER>&,
73             std::list<INST_LIST_ITER>&, const std::list<INST_LIST_ITER>&, unsigned int&, unsigned int&);
74         bool overlap(G4_INST*, std::list<INST_LIST_ITER>&);
75         bool overlap(G4_INST*, G4_INST*, bool&);
76         void coalesceSpills(std::list<INST_LIST_ITER>&, unsigned int, unsigned int, bool, G4_InstOption, G4_BB*);
77         bool allSpillsSameVar(std::list<INST_LIST_ITER>&);
78         void fixSendsSrcOverlap();
79         void removeRedundantSplitMovs();
80         G4_Declare* createCoalescedSpillDcl(unsigned int);
81         void populateSendDstDcl();
82         void spillFillCleanup();
83         void removeRedundantWrites();
84         void computeAddressTakenDcls();
85 
86     public:
CoalesceSpillFills(G4_Kernel & k,LivenessAnalysis & l,GraphColor & g,SpillManagerGRF & s,unsigned int iterationNo,RPE & r,GlobalRA & gr)87         CoalesceSpillFills(G4_Kernel& k, LivenessAnalysis& l, GraphColor& g,
88             SpillManagerGRF& s, unsigned int iterationNo, RPE& r, GlobalRA& gr) :
89             kernel(k), liveness(l), graphColor(g), gra(gr), spill(s), iterNo(iterationNo), rpe(r)
90         {
91             unsigned int numGRFs = k.getNumRegTotal();
92             auto scale = [=](unsigned threshold) -> unsigned {
93                 float ratio = 1.0f - (128 - threshold) / 128.0f;
94                 return static_cast<unsigned>(numGRFs * ratio);
95             };
96             fillWindowSizeThreshold = scale(cFillWindowThreshold128GRF);
97             spillWindowSizeThreshold = scale(cSpillWindowThreshold128GRF);
98 
99             computeAddressTakenDcls();
100         }
101 
102         void run();
103 
getScratchMsgInfo(G4_INST * inst,unsigned int & scratchOffset,unsigned int & size)104         static void getScratchMsgInfo(G4_INST* inst, unsigned int& scratchOffset, unsigned int& size)
105         {
106             if (inst->isSpillIntrinsic())
107             {
108                 scratchOffset = inst->asSpillIntrinsic()->getOffset();
109                 size = inst->asSpillIntrinsic()->getNumRows();
110             }
111             else if (inst->isFillIntrinsic())
112             {
113                 scratchOffset = inst->asFillIntrinsic()->getOffset();
114                 size = inst->asFillIntrinsic()->getNumRows();
115             }
116             else
117             {
118                 MUST_BE_TRUE(false, "unknown inst type");
119             }
120         }
121     };
122 }
123 
124 #endif
125