File: GenXRegionUtils.h

package info (click to toggle)
intel-graphics-compiler 1.0.12504.6-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 83,912 kB
  • sloc: cpp: 910,147; lisp: 202,655; ansic: 15,197; python: 4,025; yacc: 2,241; lex: 1,570; pascal: 244; sh: 104; makefile: 25
file content (179 lines) | stat: -rw-r--r-- 6,838 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*========================== begin_copyright_notice ============================

Copyright (C) 2017-2022 Intel Corporation

SPDX-License-Identifier: MIT

============================= end_copyright_notice ===========================*/

/// GenXRegion : region information
/// -------------------------------
///
/// Refer to the comments in the base class CMRegion defined in
/// llvm/Transform/Scalar.
///
/// Function added for the GenXRegion
///
/// * Construct from a rdregion/wrregion intrinsic, setting the GenXRegion
///   to the region described by the intrinsic. This constructor also takes the
///   BaleInfo as an argument, allowing a variable index that is a baled in
///   constant add to be considered as a separate variable index and constant
///   offset.
///
/// GenXLegalization uses GenXRegion to determine whether a region is legal,
/// and split it up if necessary. First it constructs a GenXRegion, then it
/// has a loop to split it into legal regions. Each loop iteration calls:
///
/// * the getLegalSize method (see below) to determine the split size; then
/// * getSubregion to modify the GenXRegion for the split size; then
/// * one of the methods to create a new rdregion or wrregion intrinsic.
///
/// GenXRegion::getLegalSize
/// ^^^^^^^^^^^^^^^^^^^^^^^^
///
/// The ``getLegalSize`` method is used by GenXLegalization and some other
/// passes to determine whether a region is legal, and if not how small
/// a split is required to make it legal.
///
/// It takes the GenXSubtarget as an argument, because it needs to know
/// architecture-specific details, currently just whether a single GRF
/// crossing is allowed in an indirect region.
///
/// It also takes either an AlignmentInfo object, or the actual alignment
/// of the indirect index (if any). Knowing the alignment of the indirect
/// index can help allow a larger legal region, and avoid needing to split
/// into simd1.
///
//===----------------------------------------------------------------------===//

#ifndef LIB_GENXCODEGEN_GENXREGIONUTILS_H
#define LIB_GENXCODEGEN_GENXREGIONUTILS_H

#include "GenXAlignmentInfo.h"
#include "vc/Utils/GenX/Region.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallBitVector.h"

namespace llvm {
    class Constant;
    class DataLayout;
    class Value;
    class Function;
    class GenXBaling;
    class GenXSubtarget;
    class Module;
    class Type;
    class Instruction;
    class raw_ostream;
    class Twine;
    class DebugLoc;
    class TargetLibraryInfo;

namespace genx {

struct BaleInfo;

using Region = vc::Region;

Region makeRegionWithOffset(const Instruction *Inst,
                            bool WantParentWidth = false);

Region makeRegionFromBaleInfo(const Instruction *Inst, const BaleInfo &BI,
                              bool WantParentWidth = false);

// getLegalSize : get the max legal size of a region
unsigned getLegalRegionSizeForTarget(const GenXSubtarget &ST, const Region &R,
                                     unsigned Idx, bool Allow2D,
                                     unsigned InputNumElements,
                                     AlignmentInfo *AI = nullptr);
unsigned getLegalRegionSizeForTarget(const GenXSubtarget &ST, const Region &R,
                                     unsigned Idx, bool Allow2D,
                                     unsigned InputNumElements,
                                     Alignment Align);

// RdWrRegionSequence : a sequence of rdregion-wrregion pairs probably
// created by legalization or coalescing, conforming to the following
// rules:
//
// 1. It is a sequence of wrregions, each one (other than the last)
//    having the next one's "old value" input as its only use.
//
// 2. Each wrregion's "new value" input is a single-use rdregion.
//
// 3. All the rdregions have the same "old value" input.
//
// 4. If the rdregions have a variable index, the index is the same for each
//    one, other than the constant offset from a baled in genx.add.addr.
//
// 5. The rdregion regions are such that they can be combined to give the
//    region parameters of the original unsplit rdregion. Those rdregion
//    parameters are stored in the RdR field.
//
// 6. If the wrregions have a variable index, the index is the same for each
//    one, other than the constant offset from a baled in genx.add.addr.
//
// 7. The wrregion regions are such that they can be combined to give the
//    region parameters of the original unsplit wrregion. Those wrregion
//    parameters are stored in the WrR field.
//
// Alternatively, a RdWrRegionSequence can represent a sequence of wrregion
// instructions with undef "old value" input to the first one and constant
// "new value" input to each one, forming a legalized constant load.
//
class RdWrRegionSequence {
  Instruction *WaitingFor = nullptr;
public:
  Value *Input = nullptr;
  Value *OldVal = nullptr;
  Instruction *StartWr = nullptr;
  Instruction *EndWr = nullptr;
  Region RdR;
  Region WrR;
  // Default constructor
  RdWrRegionSequence() : Input(nullptr), EndWr(nullptr) {}
  // isNull : true if the RdWrRegionSequence has not been initialized
  bool isNull() const { return !EndWr && !Input; }
  // Scan for sequence from the start wrregion instruction.
  // Returns false if not even a single rdregion-wrregion pair found.
  bool buildFromStartWr(Instruction *Wr, GenXBaling *Baling);
  // Scan for sequence from any wrregion instruction in the sequence.
  // Returns false if not even a single rdregion-wrregion pair found.
  bool buildFromWr(Instruction *Wr, GenXBaling *Baling);
  // Scan for sequence from any rdregion instruction in the sequence.
  // Returns false if not even a single rdregion-wrregion pair found.
  bool buildFromRd(Instruction *Rd, GenXBaling *Baling);
  // Get number of rdregion-wrregion pairs in the sequence
  unsigned size() const;
  // Check whether the sequence is the only use of its input
  bool isOnlyUseOfInput() const;
  // Get the index of the legalized rdregion
  Value *getRdIndex() const;
  // Get the index of the legalized wrregion
  Value *getWrIndex() const;
  // Get some use of Input in the sequence
  Use *getInputUse() const;
  // Debug dump/print
  void dump() const;
  void print(raw_ostream &OS) const;
};

inline raw_ostream &operator<<(raw_ostream &OS, const RdWrRegionSequence &RWS) {
  RWS.print(OS);
  return OS;
}

Value *simplifyRegionInst(Instruction *Inst, const DataLayout *DL = nullptr,
                          const GenXSubtarget *ST = nullptr);
bool simplifyRegionInsts(Function *F, const DataLayout *DL = nullptr,
                         const GenXSubtarget *ST = nullptr);

bool cleanupLoads(Function *F);

bool IsLinearVectorConstantInts(Value* v, int64_t& start, int64_t& stride);

} // end namespace genx

} // end namespace llvm

#endif // LIB_GENXCODEGEN_GENXREGIONUTILS_H