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 __SPILLMANAGERGMRF_H__
10 #define __SPILLMANAGERGMRF_H__
11
12 #include "Mem_Manager.h"
13 #include "G4_Opcode.h"
14 #include "BuildIR.h"
15
16 #include <list>
17 #include <utility>
18
19 // Forward declarations
20 namespace vISA
21 {
22 class G4_Kernel;
23 class G4_Declare;
24 class G4_Operand;
25 class G4_RegVar;
26 class G4_RegVarTransient;
27 class G4_DstRegRegion;
28 class G4_SrcRegRegion;
29 class G4_Imm;
30 class G4_Predicate;
31 class G4_INST;
32 class IR_Builder;
33 class LivenessAnalysis;
34 class Interference;
35 class LiveRange;
36 class LSLiveRange;
37 class PointsToAnalysis;
38 class GlobalRA;
39 class GraphColor;
40 }
41 struct RegionDesc;
42 // Class definitions
43 namespace vISA
44 {
45
46 class SpillManagerGRF
47 {
48 public:
49
50 using DECLARE_LIST = std::list<G4_Declare *> ;
51 using LR_LIST = std::list<LiveRange *>;
52 using LSLR_LIST = std::list<LSLiveRange *>;
53 using INST_LIST = std::list<G4_INST *,INST_LIST_NODE_ALLOCATOR>;
54 typedef struct Edge
55 {
56 unsigned first;
57 unsigned second;
58 } EDGE;
59 using INTF_LIST = std::list<EDGE>;
60
61 // Methods
62
63 SpillManagerGRF(
64 GlobalRA& g,
65 unsigned spillAreaOffset,
66 unsigned varIdCount,
67 const LivenessAnalysis * lvInfo,
68 LiveRange ** lrInfo,
69 const Interference * intf,
70 const LR_LIST * spilledLRs,
71 unsigned iterationNo,
72 bool useSpillReg,
73 unsigned spillRegSize,
74 unsigned indrSpillRegSize,
75 bool enableSpillSpaceCompression,
76 bool useScratchMsg,
77 bool avoidDstSrcOverlap
78 );
79
80 SpillManagerGRF(
81 GlobalRA& g,
82 unsigned spillAreaOffset,
83 unsigned varIdCount,
84 const LivenessAnalysis* lvInfo,
85 LSLR_LIST* spilledLSLRs,
86 bool enableSpillSpaceCompression,
87 bool useScratchMsg,
88 bool avoidDstSrcOverlap
89 );
90
~SpillManagerGRF()91 ~SpillManagerGRF() {}
92
93
94 bool insertSpillFillCode(
95 G4_Kernel* kernel,
96 PointsToAnalysis& pointsToAnalysis
97 );
98
99 void expireRanges(unsigned int idx, std::list<LSLiveRange*>* liveList);
100
101 void updateActiveList(LSLiveRange* lr, std::list<LSLiveRange*>* liveList);
102
103 bool spillLiveRanges(G4_Kernel* kernel);
104
getNumGRFSpill()105 unsigned getNumGRFSpill() const { return numGRFSpill; }
getNumGRFFill()106 unsigned getNumGRFFill() const { return numGRFFill; }
getNumGRFMove()107 unsigned getNumGRFMove() const { return numGRFMove; }
108 // return the next cumulative logical offset. This does not non-spilled stuff like
109 // private variables placed by IGC (marked by spill_mem_offset)
110 // this should only be called after insertSpillFillCode()
getNextOffset()111 uint32_t getNextOffset() const { return nextSpillOffset_; }
112 // return the cumulative scratch space offset for the next spilled variable.
113 // This adjusts for scratch space reserved for file scope vars and IGC/GT-pin
getNextScratchOffset()114 uint32_t getNextScratchOffset() const
115 {
116 int offset = nextSpillOffset_;
117 getSpillOffset(offset);
118 return offset;
119 }
120
121 // convert zero-based logical offset into the scratch space offset.
getSpillOffset(int & logicalOffset)122 void getSpillOffset(int& logicalOffset) const
123 {
124 logicalOffset += globalScratchOffset;
125 }
126
127 static std::tuple<uint32_t, G4_ExecSize> createSpillSendMsgDescOWord(
128 unsigned int height);
129
130 private:
131 G4_Declare* getOrCreateAddrSpillFillDcl(G4_Declare* spilledAddrTakenDcl, G4_Kernel* kernel);
132 bool handleAddrTakenSpills(G4_Kernel * kernel, PointsToAnalysis& pointsToAnalysis);
133 unsigned int handleAddrTakenLSSpills(G4_Kernel* kernel, PointsToAnalysis& pointsToAnalysis);
134 void insertAddrTakenSpillFill(G4_Kernel * kernel, PointsToAnalysis& pointsToAnalysis);
135 void insertAddrTakenLSSpillFill(G4_Kernel* kernel, PointsToAnalysis& pointsToAnalysis);
136 void insertAddrTakenSpillAndFillCode(
137 G4_Kernel* kernel, G4_BB* bb, INST_LIST::iterator inst_it,
138 G4_Operand* opnd, PointsToAnalysis& pointsToAnalysis,
139 bool spill, unsigned int bbid);
140 void insertAddrTakenLSSpillAndFillCode(G4_Kernel* kernel, G4_BB* bb,
141 INST_LIST::iterator inst_it, G4_Operand* opnd,
142 PointsToAnalysis& pointsToAnalysis, bool spill, unsigned int bbid);
143 void prunePointsTo(G4_Kernel* kernel, PointsToAnalysis& pointsToAnalysis);
144
145 void prunePointsToLS(G4_Kernel* kernel, PointsToAnalysis& pointsToAnalysis);
146
147 bool isComprInst (G4_INST * inst) const;
148
149 bool isMultiRegComprSource (
150 G4_SrcRegRegion* src,
151 G4_INST * inst) const;
152
153 unsigned getSendRspLengthBitOffset() const;
154
155 unsigned getSendMaxResponseLength() const;
156
157 static unsigned getSendMsgLengthBitOffset();
158
159 unsigned getSendMaxMessageLength() const;
160
161 static unsigned getSendDescDataSizeBitOffset();
162
163 unsigned getSendReadTypeBitOffset() const;
164
165 static unsigned getSendWriteTypeBitOffset();
166
167 unsigned getSendScReadType() const;
168
169 unsigned getSendScWriteType() const;
170
171 unsigned getSendOwordReadType() const;
172 static unsigned getSendOwordWriteType();
173 unsigned getSendExDesc(bool isWrite, bool isScatter) const;
174
175 unsigned getSpillIndex(G4_RegVar * spilledRegVar);
176
177 unsigned getFillIndex(G4_RegVar * spilledRegVar);
178
179 unsigned getTmpIndex(G4_RegVar * spilledRegVar);
180
181 unsigned getMsgSpillIndex(G4_RegVar * spilledRegVar);
182
183 unsigned getMsgFillIndex(G4_RegVar * spilledRegVar);
184
185 unsigned getAddrSpillFillIndex(G4_RegVar * spilledRegVar);
186
187 const char *
188 createImplicitRangeName (
189 const char * baseName,
190 G4_RegVar * spilledRegVar,
191 unsigned index
192 );
193
194 G4_RegVar *
195 getReprRegVar (
196 G4_RegVar * regVar
197 ) const;
198
199 template <class REGION_TYPE>
200 G4_RegVar *
201 getRegVar (
202 REGION_TYPE * region
203 ) const;
204
205 G4_RegFileKind
206 getRFType (
207 G4_RegVar * regvar
208 ) const;
209
210 template <class REGION_TYPE>
211 G4_RegFileKind getRFType(REGION_TYPE * region) const;
212
213 template <class REGION_TYPE>
214 unsigned getRegionOriginOffset(REGION_TYPE * region) const;
215
216 unsigned grfMask() const;
217
218 unsigned hwordMask() const;
219
220 unsigned owordMask() const;
221
222 unsigned dwordMask() const;
223
224 bool owordAligned(unsigned offset) const;
225
226 bool dwordAligned(unsigned offset) const;
227
228 static unsigned cdiv(unsigned dvd, unsigned dvr);
229
230 G4_RegVar *getRegVar(unsigned id) const;
231
232 bool shouldSpillRegister(G4_RegVar * regVar) const;
233
234 unsigned getByteSize(G4_RegVar * regVar) const;
235
236 template <class REGION_TYPE>
237 unsigned getSegmentDisp(REGION_TYPE * region, G4_ExecSize execSize);
238
239 unsigned getDisp(G4_RegVar * lRange);
240
241 template <class REGION_TYPE>
242 unsigned getRegionDisp(REGION_TYPE * region);
243
244 bool spillMemLifetimeInterfere(unsigned i, unsigned j) const;
245
246 unsigned calculateSpillDisp(G4_RegVar * lRange) const;
247
248 unsigned calculateSpillDispForLS(G4_RegVar* regVar) const;
249
250 template <class REGION_TYPE>
251 unsigned getMsgType(REGION_TYPE * region, G4_ExecSize execSize);
252
253 template <class REGION_TYPE>
254 bool isUnalignedRegion(REGION_TYPE * region, G4_ExecSize execSize);
255
256 template <class REGION_TYPE>
257 void calculateEncAlignedSegment(
258 REGION_TYPE * region,
259 G4_ExecSize execSize,
260 unsigned & start,
261 unsigned & end,
262 unsigned & type);
263
264 template <class REGION_TYPE>
265 unsigned getEncAlignedSegmentByteSize(REGION_TYPE * region, G4_ExecSize execSize);
266
267 template <class REGION_TYPE>
268 unsigned getEncAlignedSegmentDisp(REGION_TYPE * region, G4_ExecSize execSize);
269
270 template <class REGION_TYPE>
271 unsigned getEncAlignedSegmentMsgType(REGION_TYPE * region, G4_ExecSize execSize);
272
273 template <class REGION_TYPE>
274 unsigned getSegmentByteSize(REGION_TYPE * region, G4_ExecSize execSize);
275
276 unsigned getRegionByteSize (G4_DstRegRegion * region, G4_ExecSize execSize) const;
277
278 unsigned getRegionByteSize(G4_SrcRegRegion * region, G4_ExecSize execSize) const;
279
280 bool isScalarReplication(G4_SrcRegRegion * region) const;
281
282 bool repeatSIMD16or32Source(G4_SrcRegRegion * region) const;
283
284 G4_Declare *
285 createRangeDeclare(
286 const char* name,
287 G4_RegFileKind regFile,
288 unsigned short nElems,
289 unsigned short nRows,
290 G4_Type type,
291 DeclareType kind,
292 G4_RegVar * base,
293 G4_Operand * repRegion,
294 G4_ExecSize execSize);
295
296 template <class REGION_TYPE>
297 G4_Declare *
298 createTransientGRFRangeDeclare(
299 REGION_TYPE * region,
300 const char * name,
301 unsigned index,
302 G4_ExecSize execSize,
303 G4_INST * inst
304 );
305
306 G4_Declare *
307 createPostDstSpillRangeDeclare(G4_INST * sendOut);
308
309 G4_Declare *
310 createSpillRangeDeclare(
311 G4_DstRegRegion * spillRegion,
312 G4_ExecSize execSize,
313 G4_INST * inst);
314
315 G4_Declare *
316 createGRFFillRangeDeclare (
317 G4_SrcRegRegion * fillRegion,
318 G4_ExecSize execSize,
319 G4_INST * inst
320 );
321
322 G4_Declare *
323 createSendFillRangeDeclare (
324 G4_SrcRegRegion * filledRegion,
325 G4_INST * sendInst
326 );
327
328 G4_Declare *
329 createTemporaryRangeDeclare(
330 G4_DstRegRegion * fillRegion,
331 G4_ExecSize execSize,
332 bool forceSegmentAlignment = false);
333
334 G4_DstRegRegion *
335 createSpillRangeDstRegion(
336 G4_RegVar * spillRangeRegVar,
337 G4_DstRegRegion * spilledRegion,
338 G4_ExecSize execSize,
339 unsigned regOff = 0);
340
341 G4_SrcRegRegion *
342 createFillRangeSrcRegion(
343 G4_RegVar * fillRangeRegVar,
344 G4_SrcRegRegion * filledRegion,
345 G4_ExecSize execSize);
346
347 G4_SrcRegRegion *
348 createTemporaryRangeSrcRegion(
349 G4_RegVar * tmpRangeRegVar,
350 G4_DstRegRegion * spilledRegion,
351 G4_ExecSize execSize,
352 unsigned regOff = 0);
353
354 G4_SrcRegRegion *
355 createBlockSpillRangeSrcRegion(
356 G4_RegVar * spillRangeRegVar,
357 unsigned regOff = 0,
358 unsigned subregOff = 0);
359
360 G4_Declare *
361 createMRangeDeclare(G4_RegVar * regVar);
362
363 G4_Declare *
364 createMRangeDeclare(G4_DstRegRegion * region, G4_ExecSize execSize);
365
366 G4_Declare *
367 createMRangeDeclare(G4_SrcRegRegion * region, G4_ExecSize execSize);
368
369 G4_DstRegRegion *
370 createMPayloadBlockWriteDstRegion(
371 G4_RegVar * grfRange,
372 unsigned regOff = 0,
373 unsigned subregOff = 0);
374
375 G4_DstRegRegion * createMHeaderInputDstRegion(
376 G4_RegVar * grfRange,
377 unsigned subregOff = 0);
378
379 G4_DstRegRegion *
380 createMHeaderBlockOffsetDstRegion(G4_RegVar * grfRange);
381
382
383 G4_SrcRegRegion * createInputPayloadSrcRegion();
384
385 G4_Declare * initMHeader(G4_Declare * mRangeDcl);
386
387 G4_Declare * createAndInitMHeader(G4_RegVar * regVar);
388
389 template <class REGION_TYPE>
390 G4_Declare * initMHeader(
391 G4_Declare * mRangeDcl,
392 REGION_TYPE * region,
393 G4_ExecSize execSize);
394
395 template <class REGION_TYPE>
396 G4_Declare * createAndInitMHeader(
397 REGION_TYPE * region,
398 G4_ExecSize execSize);
399
400 void sendInSpilledRegVarPortions(
401 G4_Declare * fillRangeDcl,
402 G4_Declare * mRangeDcl,
403 unsigned regOff,
404 unsigned height,
405 unsigned srcRegOff = 0);
406
407 void sendOutSpilledRegVarPortions(
408 G4_Declare * spillRangeDcl,
409 G4_Declare * mRangeDcl,
410 unsigned regOff,
411 unsigned height,
412 unsigned srcRegOff = 0);
413
414 void initMWritePayload(
415 G4_Declare * spillRangeDcl,
416 G4_Declare * mRangeDcl,
417 unsigned regOff,
418 unsigned height
419 );
420
421 void
422 initMWritePayload (
423 G4_Declare * spillRangeDcl,
424 G4_Declare * mRangeDcl,
425 G4_DstRegRegion * spilledRangeRegion,
426 G4_ExecSize execSize,
427 unsigned regOff = 0);
428
429 static unsigned blockSendBlockSizeCode(unsigned regOff);
430
431 unsigned scatterSendBlockSizeCode(unsigned regOff) const;
432
433 G4_Imm * createSpillSendMsgDesc(
434 unsigned regOff,
435 unsigned height,
436 G4_ExecSize & execSize,
437 G4_RegVar* base = NULL);
438
439 std::tuple<G4_Imm*, G4_ExecSize> createSpillSendMsgDesc(
440 G4_DstRegRegion * spilledRangeRegion,
441 G4_ExecSize execSize);
442
443 G4_INST * createAddFPInst(
444 G4_ExecSize execSize,
445 G4_DstRegRegion * dst,
446 G4_Operand * src
447 );
448
449 G4_INST * createMovInst(
450 G4_ExecSize execSize,
451 G4_DstRegRegion * dst,
452 G4_Operand * src,
453 G4_Predicate * predicate = NULL,
454 G4_InstOpts options = InstOpt_WriteEnable
455 );
456
457 G4_INST * createSendInst(
458 G4_ExecSize execSize,
459 G4_DstRegRegion * postDst,
460 G4_SrcRegRegion * payload,
461 G4_Imm * desc,
462 SFID funcID,
463 bool isWrite,
464 G4_InstOpts option);
465
466 bool shouldPreloadSpillRange(
467 G4_INST* instContext,
468 G4_BB* parentBB);
469
470 void preloadSpillRange(
471 G4_Declare * spillRangeDcl,
472 G4_Declare * mRangeDcl,
473 G4_DstRegRegion * spilledRangeRegion,
474 G4_ExecSize execSize);
475
476 G4_INST * createSpillSendInstr(
477 G4_Declare * spillRangeDcl,
478 G4_Declare * mRangeDcl,
479 unsigned regOff,
480 unsigned height,
481 unsigned spillOff);
482
483 G4_INST *createSpillSendInstr (
484 G4_Declare * spillRangeDcl,
485 G4_Declare * mRangeDcl,
486 G4_DstRegRegion * spilledRangeRegion,
487 G4_ExecSize execSize,
488 unsigned option);
489
490 G4_Imm *createFillSendMsgDesc (
491 unsigned regOff,
492 unsigned height,
493 G4_ExecSize & execSize,
494 G4_RegVar* base = NULL);
495
496 template <class REGION_TYPE>
497 G4_Imm* createFillSendMsgDesc(
498 REGION_TYPE* filledRangeRegion,
499 G4_ExecSize execSize
500 );
501
502 G4_INST * createFillSendInstr (
503 G4_Declare * fillRangeDcl,
504 G4_Declare * mRangeDcl,
505 unsigned regOff,
506 unsigned height,
507 unsigned spillOff);
508
509 G4_INST * createFillSendInstr(
510 G4_Declare * fillRangeDcl,
511 G4_Declare * mRangeDcl,
512 G4_SrcRegRegion * filledRangeRegion,
513 G4_ExecSize execSize);
514
515 G4_SrcRegRegion* getLSCSpillFillHeader(
516 G4_Declare* mRangeDcl,
517 const G4_Declare *fp,
518 int offset);
519
520 G4_INST* createLSCSpill(
521 G4_Declare* spillRangeDcl,
522 G4_Declare* mRangeDcl,
523 unsigned regOff,
524 unsigned height,
525 unsigned spillOff);
526
527 G4_INST* createLSCSpill(
528 G4_Declare* spillRangeDcl,
529 G4_Declare* mRangeDcl,
530 G4_DstRegRegion* spilledRangeRegion,
531 G4_ExecSize execSize,
532 unsigned option);
533
534 G4_INST* createLSCFill(
535 G4_Declare* fillRangeDcl,
536 G4_Declare* mRangeDcl,
537 unsigned regOff,
538 unsigned height,
539 unsigned spillOff);
540
541 G4_INST* createLSCFill(
542 G4_Declare* fillRangeDcl,
543 G4_Declare* mRangeDcl,
544 G4_SrcRegRegion* filledRangeRegion,
545 G4_ExecSize execSize);
546
547 void replaceSpilledRange(
548 G4_Declare * spillRangeDcl,
549 G4_DstRegRegion * spilledRegion,
550 G4_INST * spilledInst,
551 uint32_t subregOff);
552
553 void replaceFilledRange(
554 G4_Declare * fillRangeDcl,
555 G4_SrcRegRegion * filledRegion,
556 G4_INST * filledInst);
557
558 void insertSpillRangeCode(
559 INST_LIST::iterator spilledInstIter,
560 G4_BB* bb
561 );
562
563 INST_LIST::iterator insertSendFillRangeCode(
564 G4_SrcRegRegion * filledRegion,
565 INST_LIST::iterator filledInstIter,
566 G4_BB* bb);
567
568 void insertFillGRFRangeCode(
569 G4_SrcRegRegion * filledRegion,
570 INST_LIST::iterator filledInstIter,
571 G4_BB* bb);
572
573 void *allocMem (unsigned size) const;
574
575 SpillManagerGRF(const SpillManagerGRF & other);
576
577 bool useSplitSend() const;
578
getHWordEncoding(int numHWord)579 int getHWordEncoding(int numHWord)
580 {
581 switch (numHWord)
582 {
583 case 1:
584 return 0;
585 case 2:
586 return 1;
587 case 4:
588 return 2;
589 case 8:
590 return 3;
591 default:
592 MUST_BE_TRUE(false, "only 1/2/4/8 HWords are supported");
593 return 0;
594 }
595 }
596
getChMaskForSpill(int numHWord)597 ChannelMask getChMaskForSpill(int numHWord) const
598 {
599 switch (numHWord)
600 {
601 case 1:
602 case 2:
603 return ChannelMask::createFromAPI(CHANNEL_MASK_R);
604 case 4:
605 return ChannelMask::createFromAPI(CHANNEL_MASK_RG);
606 case 8:
607 return ChannelMask::createFromAPI(CHANNEL_MASK_RGBA);
608 default:
609 assert(false && "illegal spill size");
610 return ChannelMask::createFromAPI(CHANNEL_MASK_R);
611 }
612 }
613
614 // Data
615 GlobalRA& gra;
616 IR_Builder * builder_;
617 unsigned varIdCount_;
618 unsigned latestImplicitVarIdCount_;
619 const LivenessAnalysis * lvInfo_;
620 LiveRange ** lrInfo_;
621 const LR_LIST * spilledLRs_;
622 LSLR_LIST* spilledLSLRs_;
623 unsigned * spillRangeCount_;
624 unsigned * fillRangeCount_;
625 unsigned * tmpRangeCount_;
626 unsigned * msgSpillRangeCount_;
627 unsigned * msgFillRangeCount_;
628 unsigned * addrSpillFillRangeCount_;
629 unsigned nextSpillOffset_;
630 unsigned iterationNo_;
631 unsigned bbId_ = UINT_MAX;
632 unsigned spillAreaOffset_;
633 bool doSpillSpaceCompression;
634
635 bool failSafeSpill_;
636 unsigned spillRegStart_;
637 unsigned indrSpillRegStart_;
638 unsigned spillRegOffset_;
639 LSLR_LIST activeLR_;
640 std::unordered_set<G4_DstRegRegion*> noRMWNeeded;
641
642 const Interference * spillIntf_;
643 vISA::Mem_Manager mem_;
644
645 // The number of GRF spill.
646 unsigned numGRFSpill = 0;
647
648 // The number of GRF fill.
649 unsigned numGRFFill = 0;
650
651 // The number of mov.
652 unsigned numGRFMove = 0;
653
654 // CISA instruction id of current instruction
655 G4_INST* curInst;
656
657 int globalScratchOffset;
658
659 bool useScratchMsg_;
660 bool avoidDstSrcOverlap_;
661 // spilled declares that represent a scalar immediate (created due to encoding restrictions)
662 // We rematerialize the immediate value instead of spill/fill them
663 std::unordered_map<G4_Declare*, G4_Imm*> scalarImmSpill;
664
665 VarReferences refs;
666
667 // analysis pass to assist in spill/fill code gen
668 // currently it identifies scalar imm variables that should be re-mat
669 // later on we can add detection to avoid unncessary read-modify-write for spills
670 void runSpillAnalysis();
671
672 bool checkUniqueDefAligned(G4_DstRegRegion* dst, G4_BB* defBB);
673 bool checkDefUseDomRel(G4_DstRegRegion* dst, G4_BB* bb);
674 void updateRMWNeeded();
675
676 bool useLSCMsg = false;
677 bool useLscNonstackCall = false;
678
headerNeeded()679 bool headerNeeded() const
680 {
681 bool needed = true;
682
683 if (useScratchMsg_ && builder_->getPlatform() >= GENX_SKL)
684 needed = false;
685
686 if (builder_->kernel.fg.getHasStackCalls() ||
687 builder_->kernel.fg.getIsStackCallFunc())
688 needed = false;
689
690 if (useLSCMsg)
691 needed = false;
692
693 return needed;
694 }
695
696 // return true if offset for spill/fill message needs to be GRF-aligned
needGRFAlignedOffset()697 bool needGRFAlignedOffset() const
698 {
699 return useScratchMsg_ || useSplitSend();
700 }
701 }; // class SpillManagerGRF
702
703 // Check if the destination region is discontiguous or not.
704 // A destination region is discontiguous if there are portions of the
705 // region that are not written and unaffected.
isDisContRegion(G4_DstRegRegion * region,unsigned execSize)706 static inline bool isDisContRegion(G4_DstRegRegion * region, unsigned execSize)
707 {
708 // If the horizontal stride is greater than 1, then it has gaps.
709 // NOTE: Horizontal stride of 0 is not allowed for destination regions.
710 return region->getHorzStride() != 1;
711 }
712
713 // Check if the source region is discontiguous or not.
714 // A source region is discontiguous in there are portions of the region
715 // that are not read.
isDisContRegion(G4_SrcRegRegion * region,unsigned execSize)716 static inline bool isDisContRegion(G4_SrcRegRegion * region, unsigned execSize)
717 {
718 return region->getRegion()->isContiguous(execSize);
719 }
720
721
722 // Check if the region is partial or not, i.e does it read/write the
723 // whole segment.
724 template <class REGION_TYPE>
isPartialRegion(REGION_TYPE * region,unsigned execSize)725 static inline bool isPartialRegion(REGION_TYPE * region, unsigned execSize)
726 {
727 // If the region is discontiguous then it is partial.
728 if (isDisContRegion(region, execSize)) {
729 return true;
730 }
731 else
732 {
733 return false;
734 }
735 }
736
737 G4_SrcRegRegion* getSpillFillHeader(IR_Builder& builder, G4_Declare* decl);
738
739 // Class used to analyze spill/fill decisions
740 class SpillAnalysis
741 {
742 public:
743 SpillAnalysis() = default;
744 ~SpillAnalysis();
745
746 void Dump(std::ostream& OS = std::cerr);
747 void DumpHistogram(std::ostream& OS = std::cerr);
748
749 unsigned int GetDistance(G4_Declare* Dcl);
750 void LoadAugIntervals(DECLARE_LIST&, GlobalRA&);
751 void LoadDegree(G4_Declare* Dcl, unsigned int degree);
752
SetLivenessAnalysis(LivenessAnalysis * L)753 void SetLivenessAnalysis(LivenessAnalysis* L) { LA = L; }
SetGraphColor(GraphColor * C)754 void SetGraphColor(GraphColor* C) { GC = C; }
SetSpillManager(SpillManagerGRF * S)755 void SetSpillManager(SpillManagerGRF* S) { SM = S; }
756
757 void Clear();
758
759 void Do(LivenessAnalysis* L, GraphColor* C, SpillManagerGRF* S);
760
761 private:
762 VarReferences* Refs = nullptr;
763
764 LivenessAnalysis* LA = nullptr;
765 GraphColor* GC = nullptr;
766 SpillManagerGRF* SM = nullptr;
767
768 std::unordered_map<G4_Declare*, std::pair<G4_INST*, G4_INST*>> AugIntervals;
769 std::unordered_map<G4_Declare*, unsigned int> DclDegree;
770
771 std::vector<G4_BB*> GetLiveBBs(G4_Declare*, std::unordered_map<G4_INST*, G4_BB*>&);
772 std::vector<G4_BB*> GetIntervalBBs(G4_INST* Start, G4_INST* End, std::unordered_map<G4_INST*, G4_BB*>& InstBBMap);
773 };
774
775 } // vISA::
776
777 #endif // __SPILLMANAGERGMRF_H__
778