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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
|
/*========================== begin_copyright_notice ============================
Copyright (C) 2020-2022 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
//
// Definition of backend configuration options and immutable wrapper pass.
//
// This pass should be used to query all options that can affect backend
// behavior. Pass will always be available at least with default options.
// Default values are set using LLVM command line options that can be
// overridden, for example, in plugin mode.
//
// Online mode wrapper will provide its custom values for all options that
// should not be defaulted.
//
// Proposed usage in passes: just use "getAnalysis<GenXBackendConfig>()" and
// query all needed information.
//
//===----------------------------------------------------------------------===//
#ifndef VC_SUPPORT_BACKEND_CONFIG_H
#define VC_SUPPORT_BACKEND_CONFIG_H
#include "vc/Support/ShaderDump.h"
#include "vc/Support/ShaderOverride.h"
#include "llvmWrapper/Support/MemoryBuffer.h"
#include "Probe/Assertion.h"
#include "inc/common/sku_wa.h"
#include <llvm/Pass.h>
#include <llvm/PassRegistry.h>
#include <llvm/ADT/StringSet.h>
#include <limits>
#include <memory>
enum class FunctionControl { Default, StackCall };
namespace vc {
enum class BinaryKind { Default, CM, OpenCL, ZE };
} // namespace vc
namespace llvm {
void initializeGenXBackendConfigPass(PassRegistry &PR);
// Plain structure to be filled by users who want to create backend
// configuration. Some values are default-initialized from cl options.
struct GenXBackendOptions {
// EmitDebuggable Kernels (allocate SIP Surface)
bool DebuggabilityEmitDebuggableKernels = true;
// Legacy path requires kernel to reserve BTI=0
bool DebuggabilityForLegacyPath = false;
// Emit breakpoints at the start of each kernel
bool DebuggabilityEmitBreakpoints = false;
// Enable emission of DWARF debug information
bool DebuggabilityEmitDWARF = true;
// Generate Debug Info in a format compatible with zebin
bool DebuggabilityZeBinCompatibleDWARF = false;
// Enable strict debug info validation
bool DebuggabilityValidateDWARF = false;
// Special mode of operation for emulation BiF precompilation.
// It is expected that this mode is set only by specialized tools and should
// not be touched during standard compilation flow.
bool BiFEmulationCompilation = false;
// Enable/disable regalloc dump.
bool DumpRegAlloc = false;
// Maximum available memory for stack (in bytes).
unsigned StackSurfaceMaxSize = 8 * 1024;
// Non-owning pointer to abstract shader dumper for debug dumps.
vc::ShaderDumper *Dumper = nullptr;
// Non-owning pointer to ShaderOverride interface
vc::ShaderOverrider *ShaderOverrider = nullptr;
// Flag to turn off StructSpliter pass
bool DisableStructSplitting = false;
// Flag to disable EU fusion
bool DisableEUFusion = false;
// Whether to enable finalizer dumps.
bool EnableAsmDumps = false;
// Whether to enable dumps of kernel debug information
bool EnableDebugInfoDumps = false;
std::string DebugInfoDumpsNameOverride;
bool ForceArrayPromotion = false;
// Localize live ranges to reduce accumulator usage
bool LocalizeLRsForAccUsage = false;
// Disable LR coalescing
bool DisableLiveRangesCoalescing = false;
// Disable extra coalescing
bool DisableExtraCoalescing = false;
// Disable non-overlapping region transformation (the case with undef
// value in two-address operand)
bool DisableNonOverlappingRegionOpt = false;
// use new Prolog/Epilog Insertion pass vs old CisaBuilder machinery
bool UseNewStackBuilder = true;
FunctionControl FCtrl = FunctionControl::Default;
// Non-owning pointer to workaround table.
const WA_TABLE *WATable = nullptr;
bool IsLargeGRFMode = false;
// Use bindless mode for buffers.
bool UseBindlessBuffers = false;
// Output binary format
vc::BinaryKind Binary = vc::BinaryKind::OpenCL;
// Add vISA asm as sections in ZeBin
bool EmitZebinVisaSections = false;
// max private stateless memory size per thread
unsigned StatelessPrivateMemSize = 8192;
// Disable critical messages from CisaBuilder
bool DisableFinalizerMsg = false;
// Historically stack calls linkage is changed to internal in CMABI. This
// option allows saving the original linkage type for such functions. This is
// required for linking (e.g. invoke_simd).
bool SaveStackCallLinkage = false;
// Treat "image2d_t" as non-media 2d images.
bool UsePlain2DImages = false;
// Enable/disable flushing L3 cache for globals.
bool L3FlushForGlobal = false;
// Allow the use of `GPU` fence scope on single-tile GPUs.
bool GPUFenceScopeOnSingleTileGPUs = false;
// Enable preemption (to be switched on by default)
bool EnablePreemption = false;
// Temporary solution. When is set, code is generated under the assumption all
// calls are direct. Extern call are still extern in LLVM IR.
bool DirectCallsOnly = false;
// Loop unroll threshold. Value 0 means to keep default threshold.
unsigned LoopUnrollThreshold = 0;
// Ignore unrolling threshold on loops with #pragma unroll.
bool IgnoreLoopUnrollThresholdOnPragma = false;
// Subgroup size used for cross-module calls/returns
unsigned InteropSubgroupSize = 16;
// Calling enforceLLVMOptions queries the state of LLVM options and
// updates BackendOptions accordingly.
// Note: current implementation allows backend options to be configured by
// both driver and LLVM command line. LLVM options take presedence over
// driver-derived values.
void enforceLLVMOptions();
struct InitFromLLVMOpts {};
GenXBackendOptions() = default;
GenXBackendOptions(InitFromLLVMOpts) { enforceLLVMOptions(); }
};
enum BiFKind {
OCLGeneric,
VCPrintf,
VCEmulation,
VCSPIRVBuiltins,
Size
};
class GenXBackendData {
// The owner of OpenCL generic BiF module.
// For now it is only required for llvm-lit/debugging,
// in libigc mode this field always holds nullptr.
std::array<std::unique_ptr<MemoryBuffer>, BiFKind::Size> BiFModuleOwner;
public:
std::array<MemoryBufferRef, BiFKind::Size> BiFModule;
llvm::ArrayRef<const char*> VISALTOStrings;
llvm::StringSet<> DirectCallFunctions;
struct InitFromLLMVOpts {};
GenXBackendData() {}
GenXBackendData(InitFromLLMVOpts);
private:
// ModuleBuffer cannot be nullptr.
void setOwningBiFModule(BiFKind Kind,
std::unique_ptr<MemoryBuffer> ModuleBuffer);
// Weak contract variant. Does nothing for nullptr.
void setOwningBiFModuleIf(BiFKind Kind,
std::unique_ptr<MemoryBuffer> ModuleBuffer);
};
class GenXBackendConfig : public ImmutablePass {
public:
static char ID;
private:
GenXBackendOptions Options;
GenXBackendData Data;
public:
GenXBackendConfig();
explicit GenXBackendConfig(GenXBackendOptions OptionsIn,
GenXBackendData DataIn);
// Return whether regalloc results should be printed.
bool enableRegAllocDump() const { return Options.DumpRegAlloc; }
// Return whether emulation BiF compilation mode is enabled.
bool isBiFEmulationCompilation() const {
return Options.BiFEmulationCompilation;
}
// Return maximum available space in bytes for stack purposes.
unsigned getStackSurfaceMaxSize() const {
return Options.StackSurfaceMaxSize;
}
MemoryBufferRef getBiFModule(BiFKind Kind) const {
return Data.BiFModule[Kind];
}
llvm::ArrayRef<const char*> getVISALTOStrings() const {
return Data.VISALTOStrings;
}
llvm::StringSet<> getDirectCallFunctionsSet() const {
return Data.DirectCallFunctions;
}
bool emitBreakpointAtKernelEntry() const {
return Options.DebuggabilityEmitBreakpoints;
}
bool emitDebuggableKernels() const {
return Options.DebuggabilityEmitDebuggableKernels;
}
bool emitDebuggableKernelsForLegacyPath() const {
return Options.DebuggabilityForLegacyPath && emitDebuggableKernels();
}
bool emitDWARFDebugInfo() const { return Options.DebuggabilityEmitDWARF; }
bool emitDWARFDebugInfoForZeBin() const {
return Options.DebuggabilityZeBinCompatibleDWARF && emitDWARFDebugInfo();
}
bool enableDebugInfoValidation() const {
return Options.DebuggabilityValidateDWARF;
}
// Return whether shader dumper is installed.
bool hasShaderDumper() const { return Options.Dumper; }
// Get reference to currently installed dumper.
// Precondition: hasShaderDumper() == true.
vc::ShaderDumper &getShaderDumper() const {
IGC_ASSERT_MESSAGE(hasShaderDumper(),
"Attempt to query not installed dumper");
return *Options.Dumper;
}
// Return whether shader overrider is installed.
bool hasShaderOverrider() const { return Options.ShaderOverrider; }
// Get reference to currently installed overrider.
// Precondition: hasShaderOverrider() == true.
vc::ShaderOverrider &getShaderOverrider() const {
IGC_ASSERT_MESSAGE(hasShaderOverrider(),
"Attempt to query not installed overrider");
return *Options.ShaderOverrider;
}
bool asmDumpsEnabled() const { return Options.EnableAsmDumps; }
bool dbgInfoDumpsEnabled() const { return Options.EnableDebugInfoDumps; }
const std::string &dbgInfoDumpsNameOverride() const {
return Options.DebugInfoDumpsNameOverride;
}
bool isArrayPromotionForced() const { return Options.ForceArrayPromotion; }
bool localizeLiveRangesForAccUsage() const {
return Options.LocalizeLRsForAccUsage;
}
bool disableLiveRangesCoalescing() const {
return Options.DisableLiveRangesCoalescing;
}
bool disableExtraCoalescing() const {
return Options.DisableExtraCoalescing;
}
bool disableNonOverlappingRegionOpt() const {
return Options.DisableNonOverlappingRegionOpt;
}
bool useNewStackBuilder() const { return Options.UseNewStackBuilder; }
unsigned getStatelessPrivateMemSize() const {
return Options.StatelessPrivateMemSize;
}
bool isDisableFinalizerMsg() const {
return Options.DisableFinalizerMsg;
}
bool isDisableEUFusion() const { return Options.DisableEUFusion; }
FunctionControl getFCtrl() const { return Options.FCtrl; }
bool isLargeGRFMode() const { return Options.IsLargeGRFMode; }
// Return pointer to WA_TABLE. Can be null.
const WA_TABLE *getWATable() const {
return Options.WATable;
}
bool doStructSplitting() const { return !Options.DisableStructSplitting; }
bool useBindlessBuffers() const { return Options.UseBindlessBuffers; }
bool emitZebinVisaSections() const { return Options.EmitZebinVisaSections; }
bool saveStackCallLinkage() const { return Options.SaveStackCallLinkage; }
bool usePlain2DImages() const { return Options.UsePlain2DImages; }
bool enablePreemption() const { return Options.EnablePreemption; }
bool directCallsOnly(llvm::StringRef FunctionName = "") const {
return Options.DirectCallsOnly || Data.DirectCallFunctions.count(FunctionName);
}
unsigned getLoopUnrollThreshold() const {
return Options.LoopUnrollThreshold;
}
bool ignoreLoopUnrollThresholdOnPragma() const {
return Options.IgnoreLoopUnrollThresholdOnPragma;
}
unsigned getInteropSubgroupSize() const {
return Options.InteropSubgroupSize;
}
vc::BinaryKind getBinaryFormat() const { return Options.Binary; }
};
} // namespace llvm
#endif
|