diff --git a/Src/ILGPU/Backends/ArgumentMapper.cs b/Src/ILGPU/Backends/ArgumentMapper.cs
index b19ec8b79..d5bccb64b 100644
--- a/Src/ILGPU/Backends/ArgumentMapper.cs
+++ b/Src/ILGPU/Backends/ArgumentMapper.cs
@@ -27,7 +27,7 @@ namespace ILGPU.Backends
/// can be accessed by the native kernel.
///
/// Members of this class are not thread safe.
- public abstract class ArgumentMapper
+ public abstract class ArgumentMapper : ICache
{
#region Nested Types
@@ -526,6 +526,15 @@ protected Type MapType(Type type)
}
}
+ ///
+ /// Clears internal caches.
+ ///
+ /// The clear mode.
+ public void ClearCache(ClearCacheMode mode)
+ {
+ typeMapping.Clear();
+ }
+
#endregion
}
}
diff --git a/Src/ILGPU/Backends/Backend.cs b/Src/ILGPU/Backends/Backend.cs
index 59054b199..8752f1184 100644
--- a/Src/ILGPU/Backends/Backend.cs
+++ b/Src/ILGPU/Backends/Backend.cs
@@ -43,7 +43,7 @@ public enum TargetPlatform
///
/// Represents a general ILGPU backend.
///
- public abstract class Backend : DisposeBase
+ public abstract class Backend : DisposeBase, ICache
{
#region Nested Types
@@ -460,6 +460,16 @@ protected static TargetPlatform GetPlatform(TargetPlatform? platform)
in BackendContext backendContext,
in KernelSpecialization specialization);
+ ///
+ /// Clears all internal caches.
+ ///
+ /// The clear mode.
+ /// This method is not thread-safe.
+ public void ClearCache(ClearCacheMode mode)
+ {
+ ArgumentMapper?.ClearCache(mode);
+ }
+
#endregion
#region IDisposable
diff --git a/Src/ILGPU/Context.Constants.cs b/Src/ILGPU/Context.Constants.cs
index 303595ebd..4a3d56e38 100644
--- a/Src/ILGPU/Context.Constants.cs
+++ b/Src/ILGPU/Context.Constants.cs
@@ -18,10 +18,15 @@ partial class Context
///
public const string RuntimeAssemblyName = "ILGPURuntime";
+ ///
+ /// Represents the general ILGPU assembly name.
+ ///
+ public const string AssemblyName = "ILGPU";
+
///
/// Represents the general ILGPU assembly module name.
///
- public const string AssemblyModuleName = "ILGPU.dll";
+ public const string FullAssemblyModuleName = AssemblyName + ".dll";
///
/// The ILGPU assembly file extension.
diff --git a/Src/ILGPU/Context.cs b/Src/ILGPU/Context.cs
index b21833fa2..cb9ddccef 100644
--- a/Src/ILGPU/Context.cs
+++ b/Src/ILGPU/Context.cs
@@ -32,7 +32,7 @@ namespace ILGPU
/// Represents the main ILGPU context.
///
/// Members of this class are thread safe.
- public sealed partial class Context : DisposeBase
+ public sealed partial class Context : DisposeBase, ICache
{
#region Static
@@ -129,8 +129,9 @@ static Context()
private PTXContextData ptxContextData;
private readonly object assemblyLock = new object();
- private readonly AssemblyBuilder assemblyBuilder;
- private readonly ModuleBuilder moduleBuilder;
+ private int assemblyVersion = 0;
+ private AssemblyBuilder assemblyBuilder;
+ private ModuleBuilder moduleBuilder;
private volatile int typeBuilderIdx = 0;
///
@@ -195,13 +196,9 @@ public Context(ContextFlags flags, OptimizationLevel optimizationLevel)
TransformerConfiguration.Transformed,
Flags);
- // Initialize assembly and module builder
- var assemblyName = new AssemblyName(RuntimeAssemblyName);
- assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
- moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);
-
- // Initialize context-dependent information
- ptxContextData = new PTXContextData(this);
+ // Initialize assembly builder and context data
+ ReloadAssemblyBuilder();
+ ReloadContextData();
}
#endregion
@@ -257,6 +254,31 @@ public Context(ContextFlags flags, OptimizationLevel optimizationLevel)
#region Methods
+ ///
+ /// Reloads the assembly builder.
+ ///
+ private void ReloadAssemblyBuilder()
+ {
+ var assemblyName = new AssemblyName(RuntimeAssemblyName)
+ {
+ Version = new Version(1, assemblyVersion++),
+ };
+ assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(
+ assemblyName,
+ AssemblyBuilderAccess.RunAndCollect);
+ moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);
+ }
+
+ ///
+ /// Reloads context-dependent information.
+ ///
+ private void ReloadContextData()
+ {
+ Dispose(ref ptxContextData);
+
+ ptxContextData = new PTXContextData(this);
+ }
+
///
/// Returns true if the current context has the given flags.
///
@@ -346,6 +368,24 @@ public Task BeginCodeGenerationAsync(IRContext irCon
return Task.Run(() => BeginCodeGeneration(irContext));
}
+ ///
+ /// Clears internal caches. However, this does not affect individual accelerator caches.
+ ///
+ /// The clear mode.
+ ///
+ /// This method is not thread-safe.
+ ///
+ public void ClearCache(ClearCacheMode mode)
+ {
+ mainContext.ClearCache(mode);
+ typeContext.ClearCache(mode);
+ debugInformationManager.ClearCache(mode);
+ defaultILBackend.ClearCache(mode);
+
+ ReloadAssemblyBuilder();
+ ReloadContextData();
+ }
+
#endregion
#region Runtime Assembly
diff --git a/Src/ILGPU/ContextFlags.cs b/Src/ILGPU/ContextFlags.cs
index a6d055373..962790552 100644
--- a/Src/ILGPU/ContextFlags.cs
+++ b/Src/ILGPU/ContextFlags.cs
@@ -128,6 +128,8 @@ public enum ContextFlags : int
///
/// However, IR nodes, type information and debug information will still
/// be cached, since they are used for different kernel compilation operations.
+ /// If you want to clear those caches as well, you will have to clear them
+ /// manually using .
///
DisableKernelCaching = 1 << 24,
diff --git a/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs b/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs
index ce9a30e62..a9ab5476c 100644
--- a/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs
+++ b/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs
@@ -24,7 +24,7 @@ namespace ILGPU.Frontend.DebugInformation
///
/// Represents a debug-information manager.
///
- public sealed class DebugInformationManager : DisposeBase
+ public sealed class DebugInformationManager : DisposeBase, ICache
{
#region Constants
@@ -203,7 +203,7 @@ public bool Load(Assembly assembly, out AssemblyDebugInformation assemblyDebugIn
#region Instance
- private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(
+ private readonly ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim(
LockRecursionPolicy.SupportsRecursion);
private readonly Dictionary pdbFiles = new Dictionary();
private readonly HashSet lookupDirectories = new HashSet();
@@ -432,6 +432,44 @@ public MethodScopeEnumerator LoadScopes(MethodBase methodBase)
return MethodScopeEnumerator.Empty;
}
+ ///
+ /// Clears cached debug information.
+ ///
+ /// The clear mode.
+ public void ClearCache(ClearCacheMode mode)
+ {
+ cacheLock.EnterWriteLock();
+ try
+ {
+ if (mode == ClearCacheMode.Everything)
+ {
+ foreach (var debugInformation in assemblies.Values)
+ debugInformation.Dispose();
+ assemblies.Clear();
+ }
+ else
+ {
+ // Do not dispose system assemblies
+ var assembliesToRemove = new List(assemblies.Count);
+ foreach (var assembly in assemblies.Keys)
+ {
+ if (assembly.FullName.StartsWith(Context.AssemblyName, StringComparison.OrdinalIgnoreCase))
+ continue;
+ assembliesToRemove.Add(assembly);
+ }
+ foreach (var assemblyToRemove in assembliesToRemove)
+ {
+ assemblies[assemblyToRemove].Dispose();
+ assemblies.Remove(assemblyToRemove);
+ }
+ }
+ }
+ finally
+ {
+ cacheLock.ExitWriteLock();
+ }
+ }
+
#endregion
#region IDisposable
@@ -441,10 +479,8 @@ public MethodScopeEnumerator LoadScopes(MethodBase methodBase)
Justification = "Dispose method will be invoked by a helper method")]
protected override void Dispose(bool disposing)
{
- foreach (var assembly in assemblies.Values)
- assembly.Dispose();
- assemblies.Clear();
- Dispose(ref cacheLock);
+ ClearCache(ClearCacheMode.Everything);
+ cacheLock.Dispose();
}
#endregion
diff --git a/Src/ILGPU/ICache.cs b/Src/ILGPU/ICache.cs
new file mode 100644
index 000000000..c0181a8ba
--- /dev/null
+++ b/Src/ILGPU/ICache.cs
@@ -0,0 +1,44 @@
+// -----------------------------------------------------------------------------
+// ILGPU
+// Copyright (c) 2016-2019 Marcel Koester
+// www.ilgpu.net
+//
+// File: ICache.cs
+//
+// This file is part of ILGPU and is distributed under the University of
+// Illinois Open Source License. See LICENSE.txt for details
+// -----------------------------------------------------------------------------
+
+namespace ILGPU
+{
+ ///
+ /// Specifies which resources should be removed from the cache.
+ ///
+ public enum ClearCacheMode : int
+ {
+ ///
+ /// Removes all non-ILGPU objects form the caches.
+ ///
+ Default = 0,
+
+ ///
+ /// Removes everything from the caches.
+ ///
+ Everything = 1,
+ }
+
+ ///
+ /// Represents an object that contains internal caches.
+ ///
+ public interface ICache
+ {
+ ///
+ /// Clears all internal caches.
+ ///
+ /// The clear mode.
+ ///
+ /// Implementations of this method are not guaranteed to be thread-safe.
+ ///
+ void ClearCache(ClearCacheMode mode);
+ }
+}
diff --git a/Src/ILGPU/IR/IRContext.cs b/Src/ILGPU/IR/IRContext.cs
index 543c283da..9b98d2f95 100644
--- a/Src/ILGPU/IR/IRContext.cs
+++ b/Src/ILGPU/IR/IRContext.cs
@@ -30,7 +30,7 @@ namespace ILGPU.IR
///
/// Represents an IR context.
///
- public sealed partial class IRContext : DisposeBase
+ public sealed partial class IRContext : DisposeBase, ICache
{
#region Nested Types
@@ -554,9 +554,16 @@ public void GC()
}
///
- /// Clears this context and removes all nodes
+ /// Clears cached IR nodes.
///
- public void Clear()
+ [Obsolete("Use ClearCache(ClearCacheMode.Everything) instead")]
+ public void Clear() => ClearCache(ClearCacheMode.Everything);
+
+ ///
+ /// Clears cached IR nodes.
+ ///
+ /// The clear mode.
+ public void ClearCache(ClearCacheMode mode)
{
irLock.EnterWriteLock();
try
diff --git a/Src/ILGPU/IR/Transformations/Inliner.cs b/Src/ILGPU/IR/Transformations/Inliner.cs
index f9b34d61f..169948449 100644
--- a/Src/ILGPU/IR/Transformations/Inliner.cs
+++ b/Src/ILGPU/IR/Transformations/Inliner.cs
@@ -53,7 +53,7 @@ public sealed class Inliner : OrderedTransformation
if ((source.MethodImplementationFlags & MethodImplAttributes.AggressiveInlining)
== MethodImplAttributes.AggressiveInlining ||
- source.Module.Name == Context.AssemblyModuleName)
+ source.Module.Name == Context.FullAssemblyModuleName)
method.AddFlags(MethodFlags.Inline);
}
diff --git a/Src/ILGPU/IR/Types/IRTypeContext.cs b/Src/ILGPU/IR/Types/IRTypeContext.cs
index 029b51900..b4b56d074 100644
--- a/Src/ILGPU/IR/Types/IRTypeContext.cs
+++ b/Src/ILGPU/IR/Types/IRTypeContext.cs
@@ -253,7 +253,7 @@ public TypeNode CreateType(Type type, MemoryAddressSpace addressSpace)
}
///
- /// Specializes the address space of the given .
+ /// Specializes the address space of the given .
///
/// The source type.
/// The new address space.
@@ -334,6 +334,47 @@ private T CreateType(T type)
}
}
+ ///
+ /// Clears all internal caches.
+ ///
+ /// The clear mode.
+ public override void ClearCache(ClearCacheMode mode)
+ {
+ base.ClearCache(mode);
+
+ typeLock.EnterWriteLock();
+ try
+ {
+ unifiedTypes.Clear();
+
+ unifiedTypes.Add(VoidType, VoidType);
+ unifiedTypes.Add(StringType, StringType);
+
+ foreach (var basicType in BasicValueTypes)
+ {
+ var type = GetPrimitiveType(basicType);
+ unifiedTypes.Add(type, type);
+ }
+
+ unifiedTypes.Add(IndexType, IndexType);
+ }
+ finally
+ {
+ typeLock.ExitWriteLock();
+ }
+ }
+
+ #endregion
+
+ #region IDisposable
+
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ typeLock.Dispose();
+ }
+
#endregion
}
}
diff --git a/Src/ILGPU/IR/Types/TypeInformationManager.cs b/Src/ILGPU/IR/Types/TypeInformationManager.cs
index 2ba5d3995..ac0583f67 100644
--- a/Src/ILGPU/IR/Types/TypeInformationManager.cs
+++ b/Src/ILGPU/IR/Types/TypeInformationManager.cs
@@ -23,7 +23,7 @@ namespace ILGPU.IR.Types
///
/// Represents a context that manages type information.
///
- public class TypeInformationManager : DisposeBase
+ public class TypeInformationManager : DisposeBase, ICache
{
#region Nested Types
@@ -157,6 +157,18 @@ public override string ToString()
/// Constructs a new type context.
///
public TypeInformationManager()
+ {
+ InitIntrinsicTypeInformation();
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Initializes intrinsic type information.
+ ///
+ private void InitIntrinsicTypeInformation()
{
AddTypeInfo(typeof(bool), false);
@@ -177,10 +189,6 @@ public TypeInformationManager()
AddTypeInfo(typeof(string), false);
}
- #endregion
-
- #region Methods
-
///
/// Resolves type information for the given type.
///
@@ -314,14 +322,16 @@ private TypeInformation CreateCompoundTypeInfo(Type type)
}
///
- /// Clears the cached type information.
+ /// Clears all internal caches.
///
- public void Clear()
+ /// The clear mode.
+ public virtual void ClearCache(ClearCacheMode mode)
{
cachingLock.EnterWriteLock();
try
{
typeInfoMapping.Clear();
+ InitIntrinsicTypeInformation();
}
finally
{
diff --git a/Src/ILGPU/Runtime/Accelerator.cs b/Src/ILGPU/Runtime/Accelerator.cs
index 37e4fc97e..ffe68a06e 100644
--- a/Src/ILGPU/Runtime/Accelerator.cs
+++ b/Src/ILGPU/Runtime/Accelerator.cs
@@ -39,7 +39,7 @@ public enum AcceleratorType
/// Represents a general abstract accelerator.
///
/// Members of this class are not thread safe.
- public abstract partial class Accelerator : DisposeBase
+ public abstract partial class Accelerator : DisposeBase, ICache
{
#region Static
@@ -368,6 +368,19 @@ public void Synchronize()
///
protected abstract void SynchronizeInternal();
+ ///
+ /// Clears all internal caches.
+ ///
+ /// The clear mode.
+ public void ClearCache(ClearCacheMode mode)
+ {
+ lock (syncRoot)
+ {
+ Backend.ClearCache(mode);
+ ClearKernelCache_SyncRoot();
+ }
+ }
+
#endregion
#region Occupancy
diff --git a/Src/ILGPU/Runtime/KernelCache.cs b/Src/ILGPU/Runtime/KernelCache.cs
index 42baf3ce9..3455cfe14 100644
--- a/Src/ILGPU/Runtime/KernelCache.cs
+++ b/Src/ILGPU/Runtime/KernelCache.cs
@@ -317,8 +317,9 @@ private void InitKernelCache()
///
/// This method is invoked in the scope of the locked object.
private bool RequestKernelCacheGC_SyncRoot =>
- (compiledKernelCache.Count % NumberNewKernelsUntilGC) == 0 ||
- (kernelCache.Count % NumberNewKernelsUntilGC) == 0;
+ KernelCacheEnabled &&
+ ((compiledKernelCache.Count % NumberNewKernelsUntilGC) == 0 ||
+ (kernelCache.Count % NumberNewKernelsUntilGC) == 0);
#endregion
@@ -435,6 +436,17 @@ public CompiledKernel CompileKernel(MethodInfo method, KernelSpecialization spec
return Backend.Compile(method, specialization);
}
+ ///
+ /// Clears the internal cache cache.
+ ///
+ private void ClearKernelCache_SyncRoot()
+ {
+ if (!KernelCacheEnabled)
+ return;
+ compiledKernelCache.Clear();
+ kernelCache.Clear();
+ }
+
///
/// GC method to clean disposed kernels.
///
diff --git a/Src/ILGPU/Runtime/MemoryBufferCache.cs b/Src/ILGPU/Runtime/MemoryBufferCache.cs
index d0182fcc2..c2afe35ae 100644
--- a/Src/ILGPU/Runtime/MemoryBufferCache.cs
+++ b/Src/ILGPU/Runtime/MemoryBufferCache.cs
@@ -24,7 +24,7 @@ namespace ILGPU.Runtime
/// buffer will be freed and a new buffer will be allocated.
///
/// Members of this class are not thread safe.
- public sealed class MemoryBufferCache : AcceleratorObject
+ public sealed class MemoryBufferCache : AcceleratorObject, ICache
{
#region Instance
@@ -139,6 +139,15 @@ public unsafe void CopyFrom(AcceleratorStream stream, T source, Index sourceI
}
}
+ ///
+ /// Clears all internal caches.
+ ///
+ /// The clear mode.
+ public void ClearCache(ClearCacheMode mode)
+ {
+ Dispose(ref cache);
+ }
+
#endregion
#region IDisposable
@@ -146,7 +155,7 @@ public unsafe void CopyFrom(AcceleratorStream stream, T source, Index sourceI
///
protected override void Dispose(bool disposing)
{
- Dispose(ref cache);
+ ClearCache(ClearCacheMode.Everything);
}
#endregion