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 //
10 // Definition of backend configuration options and immutable wrapper pass.
11 //
12 // This pass should be used to query all options that can affect backend
13 // behavior. Pass will always be available at least with default options.
14 // Default values are set using LLVM command line options that can be
15 // overridden, for example, in plugin mode.
16 //
17 // Online mode wrapper will provide its custom values for all options that
18 // should not be defaulted.
19 //
20 // Proposed usage in passes: just use "getAnalysis<GenXBackendConfig>()" and
21 // query all needed information.
22 //
23 //===----------------------------------------------------------------------===//
24 
25 #ifndef VC_SUPPORT_BACKEND_CONFIG_H
26 #define VC_SUPPORT_BACKEND_CONFIG_H
27 
28 #include "vc/Support/ShaderDump.h"
29 #include "vc/Support/ShaderOverride.h"
30 
31 #include "llvmWrapper/Support/MemoryBuffer.h"
32 
33 #include "Probe/Assertion.h"
34 
35 #include "inc/common/sku_wa.h"
36 
37 #include <llvm/Pass.h>
38 #include <llvm/PassRegistry.h>
39 
40 #include <limits>
41 #include <memory>
42 
43 enum class FunctionControl { Default, StackCall };
44 
45 namespace llvm {
46 
47 void initializeGenXBackendConfigPass(PassRegistry &PR);
48 
49 // Plain structure to be filled by users who want to create backend
50 // configuration. Some values are default-initialized from cl options.
51 struct GenXBackendOptions {
52   // EmitDebuggable Kernels (allocate SIP Surface and avoid using BTI=0)
53   bool EmitDebuggableKernels = false;
54   // Enable emission of DWARF debug information
55   bool EmitDebugInformation = false;
56   // Generate Debug Info in a format compatible with zebin
57   bool DebugInfoForZeBin = false;
58   // Enable strict debug info validation
59   bool DebugInfoValidationEnable = false;
60 
61   // Enable/disable regalloc dump.
62   bool DumpRegAlloc;
63   // Maximum available memory for stack (in bytes).
64   unsigned StackSurfaceMaxSize;
65 
66   // Non-owning pointer to abstract shader dumper for debug dumps.
67   vc::ShaderDumper *Dumper = nullptr;
68   // Non-owning pointer to ShaderOverride interface
69   vc::ShaderOverrider *ShaderOverrider = nullptr;
70 
71   // Flag to turn off StructSpliter pass
72   bool DisableStructSplitting = false;
73 
74   // Whether to enable finalizer dumps.
75   bool EnableAsmDumps;
76   // Whether to enable dumps of kernel debug information
77   bool EnableDebugInfoDumps;
78   std::string DebugInfoDumpsNameOverride;
79 
80   bool ForceArrayPromotion = false;
81   bool ReserveBTIZero = false;
82 
83   // Localize live ranges to reduce accumulator usage
84   bool LocalizeLRsForAccUsage;
85 
86   // Disable LR coalescing
87   bool DisableLiveRangesCoalescing = false;
88 
89   // Disable non-overlapping region transformation (the case with undef
90   // value in two-address operand)
91   bool DisableNonOverlappingRegionOpt;
92 
93   // Force passing "-debug" option to finalizer
94   bool PassDebugToFinalizer = false;
95 
96   // use new Prolog/Epilog Insertion pass vs old CisaBuilder machinery
97   bool UseNewStackBuilder = true;
98 
99   FunctionControl FCtrl;
100 
101   // Non-owning pointer to workaround table.
102   const WA_TABLE *WATable = nullptr;
103 
104   bool IsLargeGRFMode = false;
105 
106   // Use bindless mode for buffers.
107   bool UseBindlessBuffers;
108 
109   // max private stateless memory size per thread
110   unsigned StatelessPrivateMemSize;
111 
112   // Disable critical messages from CisaBuilder
113   bool DisableFinalizerMsg = false;
114 
115   // Historically stack calls linkage is changed to internal in CMABI. This
116   // option allows saving the original linkage type for such functions. This is
117   // required for linking (e.g. invoke_simd).
118   bool SaveStackCallLinkage = false;
119 
120   // Treat "image2d_t" as non-media 2d images.
121   bool UsePlain2DImages = false;
122 
123 
124   // Enable preemption (to be switched on by default)
125   bool EnablePreemption = false;
126 
127   GenXBackendOptions();
128 };
129 
130 enum BiFKind {
131   OCLGeneric,
132   VCPrintf,
133   VCEmulation,
134   VCSPIRVBuiltins,
135   Size
136 };
137 
138 class GenXBackendData {
139   // The owner of OpenCL generic BiF module.
140   // For now it is only required for llvm-lit/debugging,
141   // in libigc mode this field always holds nullptr.
142   std::array<std::unique_ptr<MemoryBuffer>, BiFKind::Size>  BiFModuleOwner;
143 
144 public:
145   std::array<MemoryBufferRef, BiFKind::Size> BiFModule;
146 
147   struct InitFromLLMVOpts {};
148 
GenXBackendData()149   GenXBackendData() {}
150   GenXBackendData(InitFromLLMVOpts);
151 
152 private:
153   // ModuleBuffer cannot be nullptr.
154   void setOwningBiFModule(BiFKind Kind,
155                           std::unique_ptr<MemoryBuffer> ModuleBuffer);
156   // Weak contract variant. Does nothing for nullptr.
157   void setOwningBiFModuleIf(BiFKind Kind,
158                             std::unique_ptr<MemoryBuffer> ModuleBuffer);
159 };
160 
161 class GenXBackendConfig : public ImmutablePass {
162 public:
163   static char ID;
164 
165 private:
166   GenXBackendOptions Options;
167   GenXBackendData Data;
168 
169 public:
170   GenXBackendConfig();
171   explicit GenXBackendConfig(GenXBackendOptions OptionsIn,
172                              GenXBackendData DataIn);
173 
174   // Return whether regalloc results should be printed.
enableRegAllocDump()175   bool enableRegAllocDump() const { return Options.DumpRegAlloc; }
176 
177   // Return maximum available space in bytes for stack purposes.
getStackSurfaceMaxSize()178   unsigned getStackSurfaceMaxSize() const {
179     return Options.StackSurfaceMaxSize;
180   }
181 
getBiFModule(BiFKind Kind)182   MemoryBufferRef getBiFModule(BiFKind Kind) const {
183     return Data.BiFModule[Kind];
184   }
185 
emitDebugInformation()186   bool emitDebugInformation() const { return Options.EmitDebugInformation; }
emitDebuggableKernels()187   bool emitDebuggableKernels() const { return Options.EmitDebuggableKernels; }
emitDebugInfoForZeBin()188   bool emitDebugInfoForZeBin() const { return Options.DebugInfoForZeBin; }
enableDebugInfoValidation()189   bool enableDebugInfoValidation() const { return Options.DebugInfoValidationEnable; }
190   // Return whether shader dumper is installed.
hasShaderDumper()191   bool hasShaderDumper() const { return Options.Dumper; }
192 
193   // Get reference to currently installed dumper.
194   // Precondition: hasShaderDumper() == true.
getShaderDumper()195   vc::ShaderDumper &getShaderDumper() const {
196     IGC_ASSERT_MESSAGE(hasShaderDumper(),
197                        "Attempt to query not installed dumper");
198     return *Options.Dumper;
199   }
200   // Return whether shader overrider is installed.
hasShaderOverrider()201   bool hasShaderOverrider() const { return Options.ShaderOverrider; }
202   // Get reference to currently installed overrider.
203   // Precondition: hasShaderOverrider() == true.
getShaderOverrider()204   vc::ShaderOverrider &getShaderOverrider() const {
205     IGC_ASSERT_MESSAGE(hasShaderOverrider(),
206                        "Attempt to query not installed overrider");
207     return *Options.ShaderOverrider;
208   }
209 
asmDumpsEnabled()210   bool asmDumpsEnabled() const { return Options.EnableAsmDumps; }
dbgInfoDumpsEnabled()211   bool dbgInfoDumpsEnabled() const { return Options.EnableDebugInfoDumps; }
dbgInfoDumpsNameOverride()212   const std::string &dbgInfoDumpsNameOverride() const {
213     return Options.DebugInfoDumpsNameOverride;
214   }
215 
isArrayPromotionForced()216   bool isArrayPromotionForced() const { return Options.ForceArrayPromotion; }
217 
isBTIZeroReserved()218   bool isBTIZeroReserved() const { return Options.ReserveBTIZero; }
219 
localizeLiveRangesForAccUsage()220   bool localizeLiveRangesForAccUsage() const {
221     return Options.LocalizeLRsForAccUsage;
222   }
223 
disableLiveRangesCoalescing()224   bool disableLiveRangesCoalescing() const {
225     return Options.DisableLiveRangesCoalescing;
226   }
227 
disableNonOverlappingRegionOpt()228   bool disableNonOverlappingRegionOpt() const {
229     return Options.DisableNonOverlappingRegionOpt;
230   }
231 
passDebugToFinalizer()232   bool passDebugToFinalizer() const {
233     return Options.PassDebugToFinalizer;
234   }
235 
useNewStackBuilder()236   bool useNewStackBuilder() const { return Options.UseNewStackBuilder; }
237 
getStatelessPrivateMemSize()238   unsigned getStatelessPrivateMemSize() const {
239     return Options.StatelessPrivateMemSize;
240   }
241 
isDisableFinalizerMsg()242   bool isDisableFinalizerMsg() const {
243     return Options.DisableFinalizerMsg;
244   }
245 
getFCtrl()246   FunctionControl getFCtrl() const { return Options.FCtrl; }
247 
isLargeGRFMode()248   bool isLargeGRFMode() const { return Options.IsLargeGRFMode; }
249 
250   // Return pointer to WA_TABLE. Can be null.
getWATable()251   const WA_TABLE *getWATable() const {
252     return Options.WATable;
253   }
254 
doStructSplitting()255   bool doStructSplitting() const { return !Options.DisableStructSplitting; }
256 
useBindlessBuffers()257   bool useBindlessBuffers() const { return Options.UseBindlessBuffers; }
258 
saveStackCallLinkage()259   bool saveStackCallLinkage() const { return Options.SaveStackCallLinkage; }
260 
usePlain2DImages()261   bool usePlain2DImages() const { return Options.UsePlain2DImages; }
262 
enablePreemption()263   bool enablePreemption() const { return Options.EnablePreemption; }
264 };
265 } // namespace llvm
266 
267 #endif
268