A game about forced loneliness, made by TACStudios
at master 931 lines 36 kB view raw
1using System; 2using System.ComponentModel; 3using System.IO; 4using System.Reflection; 5using System.Text; 6using System.Collections.Generic; 7using System.Diagnostics; 8using System.Linq; 9using System.Runtime.InteropServices; 10#if BURST_COMPILER_SHARED 11using Burst.Compiler.IL.Helpers; 12#else 13using Unity.Jobs.LowLevel.Unsafe; 14using Unity.Burst; 15#endif 16 17// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 18// NOTE: This file is shared via a csproj cs link in Burst.Compiler.IL 19// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 20 21namespace Unity.Burst 22{ 23 internal enum GlobalSafetyChecksSettingKind 24 { 25 Off = 0, 26 On = 1, 27 ForceOn = 2, 28 } 29 30 /// <summary> 31 /// Options available at Editor time and partially at runtime to control the behavior of the compilation and to enable/disable burst jobs. 32 /// </summary> 33#if BURST_COMPILER_SHARED 34 internal sealed partial class BurstCompilerOptionsInternal 35#else 36 public sealed partial class BurstCompilerOptions 37#endif 38 { 39 private const string DisableCompilationArg = "--burst-disable-compilation"; 40 41 private const string ForceSynchronousCompilationArg = "--burst-force-sync-compilation"; 42 43 internal const string DefaultLibraryName = "lib_burst_generated"; 44 45 internal const string BurstInitializeName = "burst.initialize"; 46 internal const string BurstInitializeExternalsName = "burst.initialize.externals"; 47 internal const string BurstInitializeStaticsName = "burst.initialize.statics"; 48 49#if BURST_COMPILER_SHARED || UNITY_EDITOR 50 internal static readonly string DefaultCacheFolder = Path.Combine(Environment.CurrentDirectory, "Library", "BurstCache", "JIT"); 51 internal const string DeleteCacheMarkerFileName = "DeleteCache.txt"; 52#endif 53 54#if UNITY_EDITOR 55 private static readonly string BackendNameOverride = Environment.GetEnvironmentVariable("UNITY_BURST_BACKEND_NAME_OVERRIDE"); 56#endif 57 58 // ------------------------------------------------------- 59 // Common options used by the compiler 60 // ------------------------------------------------------- 61 internal const string OptionBurstcSwitch = "+burstc"; 62 internal const string OptionGroup = "group"; 63 internal const string OptionPlatform = "platform="; 64 internal const string OptionBackend = "backend="; 65 internal const string OptionGlobalSafetyChecksSetting = "global-safety-checks-setting="; 66 internal const string OptionDisableSafetyChecks = "disable-safety-checks"; 67 internal const string OptionDisableOpt = "disable-opt"; 68 internal const string OptionFastMath = "fastmath"; 69 internal const string OptionTarget = "target="; 70 internal const string OptionOptLevel = "opt-level="; 71 internal const string OptionLogTimings = "log-timings"; 72 internal const string OptionOptForSize = "opt-for-size"; 73 internal const string OptionFloatPrecision = "float-precision="; 74 internal const string OptionFloatMode = "float-mode="; 75 internal const string OptionBranchProtection = "branch-protection="; 76 internal const string OptionDisableWarnings = "disable-warnings="; 77 internal const string OptionAssemblyDefines = "assembly-defines="; 78 internal const string OptionDump = "dump="; 79 internal const string OptionFormat = "format="; 80 internal const string OptionDebugTrap = "debugtrap"; 81 internal const string OptionDisableVectors = "disable-vectors"; 82 internal const string OptionDebug = "debug="; 83 internal const string OptionDebugMode = "debugMode"; 84 internal const string OptionStaticLinkage = "generate-static-linkage-methods"; 85 internal const string OptionJobMarshalling = "generate-job-marshalling-methods"; 86 internal const string OptionTempDirectory = "temp-folder="; 87 internal const string OptionEnableDirectExternalLinking = "enable-direct-external-linking"; 88 internal const string OptionLinkerOptions = "linker-options="; 89 internal const string OptionEnableAutoLayoutFallbackCheck = "enable-autolayout-fallback-check"; 90 internal const string OptionGenerateLinkXml = "generate-link-xml="; 91 internal const string OptionMetaDataGeneration = "meta-data-generation="; 92 internal const string OptionDisableStringInterpolationInExceptionMessages = "disable-string-interpolation-in-exception-messages"; 93 internal const string OptionPlatformConfiguration = "platform-configuration="; 94 95 // ------------------------------------------------------- 96 // Options used by the Jit and Bcl compilers 97 // ------------------------------------------------------- 98 internal const string OptionCacheDirectory = "cache-directory="; 99 100 // ------------------------------------------------------- 101 // Options used by the Jit compiler 102 // ------------------------------------------------------- 103 internal const string OptionJitDisableFunctionCaching = "disable-function-caching"; 104 internal const string OptionJitDisableAssemblyCaching = "disable-assembly-caching"; 105 internal const string OptionJitEnableAssemblyCachingLogs = "enable-assembly-caching-logs"; 106 internal const string OptionJitEnableSynchronousCompilation = "enable-synchronous-compilation"; 107 internal const string OptionJitCompilationPriority = "compilation-priority="; 108 109 internal const string OptionJitIsForFunctionPointer = "is-for-function-pointer"; 110 111 internal const string OptionJitManagedFunctionPointer = "managed-function-pointer="; 112 internal const string OptionJitManagedDelegateHandle = "managed-delegate-handle="; 113 114 internal const string OptionEnableInterpreter = "enable-interpreter"; 115 116 // ------------------------------------------------------- 117 // Options used by the Aot compiler 118 // ------------------------------------------------------- 119 internal const string OptionAotAssemblyFolder = "assembly-folder="; 120 internal const string OptionRootAssembly = "root-assembly="; 121 internal const string OptionIncludeRootAssemblyReferences = "include-root-assembly-references="; 122 internal const string OptionAotMethod = "method="; 123 internal const string OptionAotType = "type="; 124 internal const string OptionAotAssembly = "assembly="; 125 internal const string OptionAotOutputPath = "output="; 126 internal const string OptionAotKeepIntermediateFiles = "keep-intermediate-files"; 127 internal const string OptionAotNoLink = "nolink"; 128 129 internal const string OptionAotOnlyStaticMethods = "only-static-methods"; 130 internal const string OptionMethodPrefix = "method-prefix="; 131 internal const string OptionAotNoNativeToolchain = "no-native-toolchain"; 132 internal const string OptionAotEmitLlvmObjects = "emit-llvm-objects"; 133 internal const string OptionAotKeyFolder = "key-folder="; 134 internal const string OptionAotDecodeFolder = "decode-folder="; 135 internal const string OptionVerbose = "verbose"; 136 internal const string OptionValidateExternalToolChain = "validate-external-tool-chain"; 137 internal const string OptionCompilerThreads = "threads="; 138 internal const string OptionChunkSize = "chunk-size="; 139 internal const string OptionPrintLogOnMissingPInvokeCallbackAttribute = "print-monopinvokecallbackmissing-message"; 140 internal const string OptionOutputMode = "output-mode="; 141 internal const string OptionAlwaysCreateOutput = "always-create-output="; 142 internal const string OptionAotPdbSearchPaths = "pdb-search-paths="; 143 internal const string OptionSafetyChecks = "safety-checks"; 144 internal const string OptionLibraryOutputMode = "library-output-mode="; 145 internal const string OptionCompilationId = "compilation-id="; 146 internal const string OptionTargetFramework = "target-framework="; 147 internal const string OptionDiscardAssemblies = "discard-assemblies="; 148 internal const string OptionSaveExtraContext = "save-extra-context"; 149 150 internal const string CompilerCommandShutdown = "$shutdown"; 151 internal const string CompilerCommandCancel = "$cancel"; 152 internal const string CompilerCommandEnableCompiler = "$enable_compiler"; 153 internal const string CompilerCommandDisableCompiler = "$disable_compiler"; 154 internal const string CompilerCommandSetDefaultOptions = "$set_default_options"; 155 internal const string CompilerCommandTriggerSetupRecompilation = "$trigger_setup_recompilation"; 156 internal const string CompilerCommandIsCurrentCompilationDone = "$is_current_compilation_done"; 157 158 // This one is annoying special - the Unity editor has a detection for this string being in the command and does some 159 // job specific logic - meaning that we **cannot** have this string be present in any other command or bugs will occur. 160 internal const string CompilerCommandTriggerRecompilation = "$trigger_recompilation"; 161 internal const string CompilerCommandInitialize = "$initialize"; 162 internal const string CompilerCommandDomainReload = "$domain_reload"; 163 internal const string CompilerCommandVersionNotification = "$version"; 164 internal const string CompilerCommandGetTargetCpuFromHost = "$get_target_cpu_from_host"; 165 internal const string CompilerCommandSetProfileCallbacks = "$set_profile_callbacks"; 166 internal const string CompilerCommandUnloadBurstNatives = "$unload_burst_natives"; 167 internal const string CompilerCommandIsNativeApiAvailable = "$is_native_api_available"; 168 internal const string CompilerCommandILPPCompilation = "$ilpp_compilation"; 169 internal const string CompilerCommandIsArmTestEnv = "$is_arm_test_env"; 170 internal const string CompilerCommandNotifyAssemblyCompilationNotRequired = "$notify_assembly_compilation_not_required"; 171 internal const string CompilerCommandNotifyAssemblyCompilationFinished = "$notify_assembly_compilation_finished"; 172 internal const string CompilerCommandNotifyCompilationStarted = "$notify_compilation_started"; 173 internal const string CompilerCommandNotifyCompilationFinished = "$notify_compilation_finished"; 174 internal const string CompilerCommandAotCompilation = "$aot_compilation"; 175 internal const string CompilerCommandRequestInitialiseDebuggerCommmand = "$request_debug_command"; 176 internal const string CompilerCommandInitialiseDebuggerCommmand = "$load_debugger_interface"; 177 internal const string CompilerCommandRequestSetProtocolVersionEditor = "$request_set_protocol_version_editor"; 178 internal const string CompilerCommandSetProtocolVersionBurst = "$set_protocol_version_burst"; 179 180 internal static string SerialiseCompilationOptionsSafe(string[] roots, string[] folders, string options) 181 { 182 var finalSerialise = new string[3]; 183 finalSerialise[0] = SafeStringArrayHelper.SerialiseStringArraySafe(roots); 184 finalSerialise[1] = SafeStringArrayHelper.SerialiseStringArraySafe(folders); 185 finalSerialise[2] = options; 186 return SafeStringArrayHelper.SerialiseStringArraySafe(finalSerialise); 187 } 188 189 internal static (string[] roots, string[] folders, string options) DeserialiseCompilationOptionsSafe(string from) 190 { 191 var set = SafeStringArrayHelper.DeserialiseStringArraySafe(from); 192 193 return (SafeStringArrayHelper.DeserialiseStringArraySafe(set[0]), SafeStringArrayHelper.DeserialiseStringArraySafe(set[1]), set[2]); 194 } 195 196 // All the following content is exposed to the public interface 197 198#if !BURST_COMPILER_SHARED 199 // These fields are only setup at startup 200 internal static readonly bool ForceDisableBurstCompilation; 201 private static readonly bool ForceBurstCompilationSynchronously; 202 internal static readonly bool IsSecondaryUnityProcess; 203 204#if UNITY_EDITOR 205 internal bool IsInitializing; 206#endif 207 208 private bool _enableBurstCompilation; 209 private bool _enableBurstCompileSynchronously; 210 private bool _enableBurstSafetyChecks; 211 private bool _enableBurstTimings; 212 private bool _enableBurstDebug; 213 private bool _forceEnableBurstSafetyChecks; 214 215 private BurstCompilerOptions() : this(false) 216 { 217 } 218 219 internal BurstCompilerOptions(bool isGlobal) 220 { 221#if UNITY_EDITOR 222 IsInitializing = true; 223#endif 224 225 try 226 { 227 IsGlobal = isGlobal; 228 // By default, burst is enabled as well as safety checks 229 EnableBurstCompilation = true; 230 EnableBurstSafetyChecks = true; 231 } 232 finally 233 { 234#if UNITY_EDITOR 235 IsInitializing = false; 236#endif 237 } 238 } 239 240 /// <summary> 241 /// <c>true</c> if this option is the global options that affects menus 242 /// </summary> 243 private bool IsGlobal { get; } 244 245 /// <summary> 246 /// Gets a boolean indicating whether burst is enabled. 247 /// </summary> 248 public bool IsEnabled 249 { 250 get => EnableBurstCompilation && !ForceDisableBurstCompilation; 251 } 252 253 /// <summary> 254 /// Gets or sets a boolean to enable or disable compilation of burst jobs. 255 /// </summary> 256 public bool EnableBurstCompilation 257 { 258 get => _enableBurstCompilation; 259 set 260 { 261 // If we are in the global settings, and we are forcing to no burst compilation 262 if (IsGlobal && ForceDisableBurstCompilation) value = false; 263 264 bool changed = _enableBurstCompilation != value; 265 266 _enableBurstCompilation = value; 267 268 // Modify only JobsUtility.JobCompilerEnabled when modifying global settings 269 if (IsGlobal) 270 { 271#if !BURST_INTERNAL 272 // We need also to disable jobs as functions are being cached by the job system 273 // and when we ask for disabling burst, we are also asking the job system 274 // to no longer use the cached functions 275 JobsUtility.JobCompilerEnabled = value; 276#if UNITY_EDITOR 277 if (changed) 278 { 279 // Send the command to the compiler service 280 if (value) 281 { 282 BurstCompiler.Enable(); 283 MaybeTriggerRecompilation(); 284 } 285 else 286 { 287 BurstCompiler.Disable(); 288 } 289 } 290#endif 291#endif 292 293 // Store the option directly into BurstCompiler.IsEnabled 294 BurstCompiler._IsEnabled = value; 295 } 296 297 if (changed) 298 { 299 OnOptionsChanged(); 300 } 301 } 302 } 303 304 /// <summary> 305 /// Gets or sets a boolean to force the compilation of all burst jobs synchronously. 306 /// </summary> 307 /// <remarks> 308 /// This is only available at Editor time. Does not have an impact on player mode. 309 /// </remarks> 310 public bool EnableBurstCompileSynchronously 311 { 312 get => _enableBurstCompileSynchronously; 313 set 314 { 315 bool changed = _enableBurstCompileSynchronously != value; 316 _enableBurstCompileSynchronously = value; 317 if (changed) OnOptionsChanged(); 318 } 319 } 320 321 /// <summary> 322 /// Gets or sets a boolean to enable or disable safety checks. 323 /// </summary> 324 /// <remarks> 325 /// This is only available at Editor time. Does not have an impact on player mode. 326 /// </remarks> 327 public bool EnableBurstSafetyChecks 328 { 329 get => _enableBurstSafetyChecks; 330 set 331 { 332 bool changed = _enableBurstSafetyChecks != value; 333 334 _enableBurstSafetyChecks = value; 335 if (changed) 336 { 337 OnOptionsChanged(); 338 MaybeTriggerRecompilation(); 339 } 340 } 341 } 342 343 /// <summary> 344 /// Gets or sets a boolean to force enable safety checks, irrespective of what 345 /// <c>EnableBurstSafetyChecks</c> is set to, or whether the job or function 346 /// has <c>DisableSafetyChecks</c> set. 347 /// </summary> 348 /// <remarks> 349 /// This is only available at Editor time. Does not have an impact on player mode. 350 /// </remarks> 351 public bool ForceEnableBurstSafetyChecks 352 { 353 get => _forceEnableBurstSafetyChecks; 354 set 355 { 356 bool changed = _forceEnableBurstSafetyChecks != value; 357 358 _forceEnableBurstSafetyChecks = value; 359 if (changed) 360 { 361 OnOptionsChanged(); 362 MaybeTriggerRecompilation(); 363 } 364 } 365 } 366 /// <summary> 367 /// Enable debugging mode 368 /// </summary> 369 public bool EnableBurstDebug 370 { 371 get => _enableBurstDebug; 372 set 373 { 374 bool changed = _enableBurstDebug != value; 375 376 _enableBurstDebug = value; 377 if (changed) 378 { 379 OnOptionsChanged(); 380 MaybeTriggerRecompilation(); 381 } 382 } 383 } 384 385 /// <summary> 386 /// This property is no longer used and will be removed in a future major release. 387 /// </summary> 388 [Obsolete("This property is no longer used and will be removed in a future major release")] 389 public bool DisableOptimizations 390 { 391 get => false; 392 set 393 { 394 } 395 } 396 397 /// <summary> 398 /// This property is no longer used and will be removed in a future major release. Use the [BurstCompile(FloatMode = FloatMode.Fast)] on the method directly to enable this feature 399 /// </summary> 400 [Obsolete("This property is no longer used and will be removed in a future major release. Use the [BurstCompile(FloatMode = FloatMode.Fast)] on the method directly to enable this feature")] 401 public bool EnableFastMath 402 { 403 get => true; 404 405 set 406 { 407 // ignored 408 } 409 } 410 411 internal bool EnableBurstTimings 412 { 413 get => _enableBurstTimings; 414 set 415 { 416 bool changed = _enableBurstTimings != value; 417 _enableBurstTimings = value; 418 if (changed) OnOptionsChanged(); 419 } 420 } 421 422 internal bool RequiresSynchronousCompilation => EnableBurstCompileSynchronously || ForceBurstCompilationSynchronously; 423 424 internal Action OptionsChanged { get; set; } 425 426 internal BurstCompilerOptions Clone() 427 { 428 // WARNING: for some reason MemberwiseClone() is NOT WORKING on Mono/Unity 429 // so we are creating a manual clone 430 var clone = new BurstCompilerOptions 431 { 432 EnableBurstCompilation = EnableBurstCompilation, 433 EnableBurstCompileSynchronously = EnableBurstCompileSynchronously, 434 EnableBurstSafetyChecks = EnableBurstSafetyChecks, 435 EnableBurstTimings = EnableBurstTimings, 436 EnableBurstDebug = EnableBurstDebug, 437 ForceEnableBurstSafetyChecks = ForceEnableBurstSafetyChecks, 438 }; 439 return clone; 440 } 441 442 private static bool TryGetAttribute(MemberInfo member, out BurstCompileAttribute attribute) 443 { 444 attribute = null; 445 // We don't fail if member == null as this method is being called by native code and doesn't expect to crash 446 if (member == null) 447 { 448 return false; 449 } 450 451 // Fetch options from attribute 452 attribute = GetBurstCompileAttribute(member); 453 if (attribute == null) 454 { 455 return false; 456 } 457 458 return true; 459 } 460 461 private static bool TryGetAttribute(Assembly assembly, out BurstCompileAttribute attribute) 462 { 463 // We don't fail if assembly == null as this method is being called by native code and doesn't expect to crash 464 if (assembly == null) 465 { 466 attribute = null; 467 return false; 468 } 469 470 // Fetch options from attribute 471 attribute = assembly.GetCustomAttribute<BurstCompileAttribute>(); 472 473 return attribute != null; 474 } 475 476 private static BurstCompileAttribute GetBurstCompileAttribute(MemberInfo memberInfo) 477 { 478 var result = memberInfo.GetCustomAttribute<BurstCompileAttribute>(); 479 if (result != null) 480 { 481 return result; 482 } 483 484 foreach (var a in memberInfo.GetCustomAttributes()) 485 { 486 var attributeType = a.GetType(); 487 if (attributeType.FullName == "Burst.Compiler.IL.Tests.TestCompilerAttribute") 488 { 489 var options = new List<string>(); 490 491 return new BurstCompileAttribute(FloatPrecision.Standard, FloatMode.Default) 492 { 493 CompileSynchronously = true, 494 Options = options.ToArray(), 495 }; 496 } 497 } 498 499 return null; 500 } 501 502 internal static bool HasBurstCompileAttribute(MemberInfo member) 503 { 504 if (member == null) throw new ArgumentNullException(nameof(member)); 505 BurstCompileAttribute attr; 506 return TryGetAttribute(member, out attr); 507 } 508 509 /// <summary> 510 /// Merges the attributes from the assembly into the member attribute, such that if any field of the member attribute 511 /// was not specifically set by the user (or is a default), the assembly level setting is used for the Burst compilation. 512 /// </summary> 513 internal static void MergeAttributes(ref BurstCompileAttribute memberAttribute, in BurstCompileAttribute assemblyAttribute) 514 { 515 if (memberAttribute.FloatMode == FloatMode.Default) 516 { 517 memberAttribute.FloatMode = assemblyAttribute.FloatMode; 518 } 519 520 if (memberAttribute.FloatPrecision == FloatPrecision.Standard) 521 { 522 memberAttribute.FloatPrecision = assemblyAttribute.FloatPrecision; 523 } 524 525 if (memberAttribute.OptimizeFor == OptimizeFor.Default) 526 { 527 memberAttribute.OptimizeFor = assemblyAttribute.OptimizeFor; 528 } 529 530 if (!memberAttribute._compileSynchronously.HasValue && assemblyAttribute._compileSynchronously.HasValue) 531 { 532 memberAttribute._compileSynchronously = assemblyAttribute._compileSynchronously; 533 } 534 535 if (!memberAttribute._debug.HasValue && assemblyAttribute._debug.HasValue) 536 { 537 memberAttribute._debug = assemblyAttribute._debug; 538 } 539 540 if (!memberAttribute._disableDirectCall.HasValue && assemblyAttribute._disableDirectCall.HasValue) 541 { 542 memberAttribute._disableDirectCall = assemblyAttribute._disableDirectCall; 543 } 544 545 if (!memberAttribute._disableSafetyChecks.HasValue && assemblyAttribute._disableSafetyChecks.HasValue) 546 { 547 memberAttribute._disableSafetyChecks = assemblyAttribute._disableSafetyChecks; 548 } 549 } 550 551 /// <summary> 552 /// Gets the options for the specified member. Returns <c>false</c> if the `[BurstCompile]` attribute was not found. 553 /// </summary> 554 /// <returns><c>false</c> if the `[BurstCompile]` attribute was not found; otherwise <c>true</c></returns> 555 internal bool TryGetOptions(MemberInfo member, out string flagsOut, bool isForILPostProcessing = false, bool isForCompilerClient = false) 556 { 557 flagsOut = null; 558 if (!TryGetAttribute(member, out var memberAttribute)) 559 { 560 return false; 561 } 562 563 if (TryGetAttribute(member.Module.Assembly, out var assemblyAttribute)) 564 { 565 MergeAttributes(ref memberAttribute, in assemblyAttribute); 566 } 567 568 flagsOut = GetOptions(memberAttribute, isForILPostProcessing, isForCompilerClient); 569 return true; 570 } 571 572 internal string GetOptions(BurstCompileAttribute attr = null, bool isForILPostProcessing = false, bool isForCompilerClient = false) 573 { 574 // Add debug to Jit options instead of passing it here 575 // attr.Debug 576 577 var flagsBuilderOut = new StringBuilder(); 578 579 if (!isForCompilerClient && ((attr?.CompileSynchronously ?? false) || RequiresSynchronousCompilation)) 580 { 581 AddOption(flagsBuilderOut, GetOption(OptionJitEnableSynchronousCompilation)); 582 } 583 584 AddOption(flagsBuilderOut, GetOption(OptionDebug, 585#if UNITY_EDITOR 586 BurstCompiler.IsScriptDebugInfoEnabled && EnableBurstDebug ? "Full" : "LineOnly" 587#else 588 "LineOnly" 589#endif 590 )); 591 592 if (isForILPostProcessing) 593 { 594 // IL Post Processing compiles are the only thing set to low priority. 595 AddOption(flagsBuilderOut, GetOption(OptionJitCompilationPriority, CompilationPriority.ILPP)); 596 } 597 598 if (attr != null) 599 { 600 if (attr.FloatMode != FloatMode.Default) 601 { 602 AddOption(flagsBuilderOut, GetOption(OptionFloatMode, attr.FloatMode)); 603 } 604 605 if (attr.FloatPrecision != FloatPrecision.Standard) 606 { 607 AddOption(flagsBuilderOut, GetOption(OptionFloatPrecision, attr.FloatPrecision)); 608 } 609 610 // We disable safety checks for jobs with `[BurstCompile(DisableSafetyChecks = true)]`. 611 if (attr.DisableSafetyChecks) 612 { 613 AddOption(flagsBuilderOut, GetOption(OptionDisableSafetyChecks)); 614 } 615 616 if (attr.Options != null) 617 { 618 foreach (var option in attr.Options) 619 { 620 if (!string.IsNullOrEmpty(option)) 621 { 622 AddOption(flagsBuilderOut, option); 623 } 624 } 625 } 626 627 switch (attr.OptimizeFor) 628 { 629 case OptimizeFor.Default: 630 case OptimizeFor.Balanced: 631 AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 2)); 632 break; 633 case OptimizeFor.Performance: 634 AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 3)); 635 break; 636 case OptimizeFor.Size: 637 AddOption(flagsBuilderOut, GetOption(OptionOptForSize)); 638 AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 3)); 639 break; 640 case OptimizeFor.FastCompilation: 641 AddOption(flagsBuilderOut, GetOption(OptionOptLevel, 1)); 642 break; 643 } 644 } 645 646 if (ForceEnableBurstSafetyChecks) 647 { 648 AddOption(flagsBuilderOut, GetOption(OptionGlobalSafetyChecksSetting, GlobalSafetyChecksSettingKind.ForceOn)); 649 } 650 else if (EnableBurstSafetyChecks) 651 { 652 AddOption(flagsBuilderOut, GetOption(OptionGlobalSafetyChecksSetting, GlobalSafetyChecksSettingKind.On)); 653 } 654 else 655 { 656 AddOption(flagsBuilderOut, GetOption(OptionGlobalSafetyChecksSetting, GlobalSafetyChecksSettingKind.Off)); 657 } 658 659 if (EnableBurstTimings) 660 { 661 AddOption(flagsBuilderOut, GetOption(OptionLogTimings)); 662 } 663 664 if (EnableBurstDebug || (attr?.Debug ?? false)) 665 { 666 AddOption(flagsBuilderOut, GetOption(OptionDebugMode)); 667 } 668 669#if UNITY_EDITOR 670 if (BackendNameOverride != null) 671 { 672 AddOption(flagsBuilderOut, GetOption(OptionBackend, BackendNameOverride)); 673 } 674#endif 675 676 AddOption(flagsBuilderOut, GetOption(OptionTempDirectory, Path.Combine(Environment.CurrentDirectory, "Temp", "Burst"))); 677 678 return flagsBuilderOut.ToString(); 679 } 680 681 private static void AddOption(StringBuilder builder, string option) 682 { 683 if (builder.Length != 0) 684 builder.Append('\n'); // Use \n to separate options 685 686 builder.Append(option); 687 } 688 internal static string GetOption(string optionName, object value = null) 689 { 690 if (optionName == null) throw new ArgumentNullException(nameof(optionName)); 691 return "--" + optionName + (value ?? String.Empty); 692 } 693 694 private void OnOptionsChanged() 695 { 696 OptionsChanged?.Invoke(); 697 } 698 699 private void MaybeTriggerRecompilation() 700 { 701#if UNITY_EDITOR 702 if (IsGlobal && IsEnabled && !IsInitializing) 703 { 704 UnityEditor.EditorUtility.DisplayProgressBar("Burst", "Waiting for compilation to finish", -1); 705 try 706 { 707 BurstCompiler.TriggerRecompilation(); 708 } 709 finally 710 { 711 UnityEditor.EditorUtility.ClearProgressBar(); 712 } 713 } 714#endif 715 } 716 717#if !UNITY_DOTSPLAYER 718 /// <summary> 719 /// Static initializer based on command line arguments 720 /// </summary> 721 static BurstCompilerOptions() 722 { 723 foreach (var arg in Environment.GetCommandLineArgs()) 724 { 725 switch (arg) 726 { 727 case DisableCompilationArg: 728 ForceDisableBurstCompilation = true; 729 break; 730 case ForceSynchronousCompilationArg: 731 ForceBurstCompilationSynchronously = true; 732 break; 733 } 734 } 735 736 if (CheckIsSecondaryUnityProcess()) 737 { 738 ForceDisableBurstCompilation = true; 739 IsSecondaryUnityProcess = true; 740 } 741 742 var disableCompilation = Environment.GetEnvironmentVariable("UNITY_BURST_DISABLE_COMPILATION"); 743 if (!string.IsNullOrEmpty(disableCompilation) && disableCompilation != "0") 744 { 745 ForceDisableBurstCompilation = true; 746 } 747 748#if UNITY_EDITOR && ENABLE_CORECLR 749 ForceDisableBurstCompilation = true; 750#endif 751 } 752 753 private static bool CheckIsSecondaryUnityProcess() 754 { 755#if UNITY_EDITOR 756#if UNITY_2021_1_OR_NEWER 757 if (UnityEditor.MPE.ProcessService.level == UnityEditor.MPE.ProcessLevel.Secondary 758 || UnityEditor.AssetDatabase.IsAssetImportWorkerProcess()) 759 { 760 return true; 761 } 762#else 763 if (UnityEditor.MPE.ProcessService.level == UnityEditor.MPE.ProcessLevel.Slave 764 || UnityEditor.AssetDatabase.IsAssetImportWorkerProcess()) 765 { 766 return true; 767 } 768#endif 769#endif 770 771 return false; 772 } 773#endif 774#endif // !BURST_COMPILER_SHARED 775 } 776 777#if UNITY_EDITOR 778 // NOTE: This must be synchronized with Backend.TargetPlatform 779 internal enum TargetPlatform 780 { 781 Windows = 0, 782 macOS = 1, 783 Linux = 2, 784 Android = 3, 785 iOS = 4, 786 PS4 = 5, 787 XboxOne_Deprecated = 6, 788 WASM = 7, 789 UWP = 8, 790 Lumin = 9, 791 Switch = 10, 792 Stadia_Deprecated = 11, 793 tvOS = 12, 794 EmbeddedLinux = 13, 795 GameCoreXboxOne = 14, 796 GameCoreXboxSeries = 15, 797 PS5 = 16, 798 QNX = 17, 799 visionOS = 18, 800 visionSimulator = 19, 801 } 802#endif 803 804 // Don't expose the enum in Burst.Compiler.IL, need only in Unity.Burst.dll which is referenced by Burst.Compiler.IL.Tests 805#if !BURST_COMPILER_SHARED 806// Make the enum public for btests via Unity.Burst.dll; leave it internal in the package 807#if BURST_INTERNAL 808 public 809#else 810 internal 811#endif 812 // NOTE: This must be synchronized with Backend.TargetCpu 813 enum BurstTargetCpu 814 { 815 Auto = 0, 816 X86_SSE2 = 1, 817 X86_SSE4 = 2, 818 X64_SSE2 = 3, 819 X64_SSE4 = 4, 820 AVX = 5, 821 AVX2 = 6, 822 WASM32 = 7, 823 ARMV7A_NEON32 = 8, 824 ARMV8A_AARCH64 = 9, 825 THUMB2_NEON32 = 10, 826 ARMV8A_AARCH64_HALFFP = 11, 827 ARMV9A = 12, 828 } 829#endif 830 831 832 /// <summary> 833 /// Flags used by <see cref="NativeCompiler.CompileMethod"/> to dump intermediate compiler results. 834 /// Note please ensure MonoDebuggerHandling/Constants.h is updated if you change this enum 835 /// </summary> 836 [Flags] 837#if BURST_COMPILER_SHARED 838 public enum NativeDumpFlags 839#else 840 internal enum NativeDumpFlags 841#endif 842 { 843 /// <summary> 844 /// Nothing is selected. 845 /// </summary> 846 None = 0, 847 848 /// <summary> 849 /// Dumps the IL of the method being compiled 850 /// </summary> 851 IL = 1 << 0, 852 853 /// <summary> 854 /// Unused dump state. 855 /// </summary> 856 Unused = 1 << 1, 857 858 /// <summary> 859 /// Dumps the generated module without optimizations 860 /// </summary> 861 IR = 1 << 2, 862 863 /// <summary> 864 /// Dumps the generated backend code after optimizations (if enabled) 865 /// </summary> 866 IROptimized = 1 << 3, 867 868 /// <summary> 869 /// Dumps the generated ASM code 870 /// </summary> 871 Asm = 1 << 4, 872 873 /// <summary> 874 /// Generate the native code 875 /// </summary> 876 Function = 1 << 5, 877 878 /// <summary> 879 /// Dumps the result of analysis 880 /// </summary> 881 Analysis = 1 << 6, 882 883 /// <summary> 884 /// Dumps the diagnostics from optimisation 885 /// </summary> 886 IRPassAnalysis = 1 << 7, 887 888 /// <summary> 889 /// Dumps the IL before all transformation of the method being compiled 890 /// </summary> 891 ILPre = 1 << 8, 892 893 /// <summary> 894 /// Dumps the per-entry-point module 895 /// </summary> 896 IRPerEntryPoint = 1 << 9, 897 898 /// <summary> 899 /// Dumps all normal output. 900 /// </summary> 901 All = IL | ILPre | IR | IROptimized | IRPerEntryPoint | Asm | Function | Analysis | IRPassAnalysis 902 } 903 904#if BURST_COMPILER_SHARED 905 public enum CompilationPriority 906#else 907 internal enum CompilationPriority 908#endif 909 { 910 EagerCompilationSynchronous = 0, 911 Asynchronous = 1, 912 ILPP = 2, 913 EagerCompilationAsynchronous = 3, 914 } 915 916#if UNITY_EDITOR 917 /// <summary> 918 /// Some options cannot be applied until after an Editor restart, in Editor versions prior to 2019.3. 919 /// This class assists with allowing the relevant settings to be changed via the menu, 920 /// followed by displaying a message to the user to say a restart is necessary. 921 /// </summary> 922 internal static class RequiresRestartUtility 923 { 924 [ThreadStatic] 925 public static bool CalledFromUI; 926 927 [ThreadStatic] 928 public static bool RequiresRestart; 929 } 930#endif 931}