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