Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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