diff --git a/doc/source/array.rst b/doc/source/array.rst
index 01235d5b37f55cee3ffd0fd4c9c053065a716ece..460eeba9f0d4f4e980e7412a030a58b9cc1a3423 100644
--- a/doc/source/array.rst
+++ b/doc/source/array.rst
@@ -38,11 +38,17 @@ about them using this function:
 
 .. currentmodule:: pyopencl.tools
 
-.. function:: register_dtype(dtype, name)
+.. autofunction:: get_or_register_dtype
+
+.. exception:: TypeNameNotKnown
 
-    *dtype* is a :class:`numpy.dtype`.
+    .. versionadded:: 2012.2
 
-    .. versionadded: 2011.2
+.. function:: register_dtype(dtype, name)
+
+    .. versionchanged:: 2012.2
+        This function has been deprecated. It is recommended that you develop
+        against the new interface, :func:`get_or_register_dtype`.
 
 .. function:: dtype_to_ctype(dtype)
 
diff --git a/doc/source/misc.rst b/doc/source/misc.rst
index b3c907d57feeb04169bdc24b083d47a1e5a8f542..f6f456a8355a6b9a988493b9a4b95c5607460b88 100644
--- a/doc/source/misc.rst
+++ b/doc/source/misc.rst
@@ -87,6 +87,8 @@ Version 2012.2
 * Add :envvar:`PYOPENCL_NO_CACHE` environment variable to aid debugging
   (e.g. with AMD's CPU implementation, see
   `their programming guide <http://developer.amd.com/sdks/AMDAPPSDK/assets/AMD_Accelerated_Parallel_Processing_OpenCL_Programming_Guide.pdf>`_.
+* Deprecated :func:`pyopencl.tools.register_dtype` in favor of
+  :func:`pyopencl.tools.get_or_register_dtype`.
 
 Version 2012.1
 --------------
diff --git a/examples/demo-struct-reduce.py b/examples/demo-struct-reduce.py
index 536b8e8dc96cf1c4f22e42e34bd2ddd934dce12c..c0c26e34743687a281c534c05d9c8cb74c6587ec 100644
--- a/examples/demo-struct-reduce.py
+++ b/examples/demo-struct-reduce.py
@@ -9,10 +9,10 @@ def make_collector_dtype(device):
         ])
 
     name = "minmax_collector"
-    from pyopencl.tools import register_dtype, match_dtype_to_c_struct
+    from pyopencl.tools import get_or_register_dtype, match_dtype_to_c_struct
 
     dtype, c_decl = match_dtype_to_c_struct(device, name, dtype)
-    register_dtype(dtype, name)
+    dtype = get_or_register_dtype(name, dtype)
 
     return dtype, c_decl
 
diff --git a/pyopencl/algorithm.py b/pyopencl/algorithm.py
index ac8770d1f835db1238239d59f093bdf197811df5..d8925eb9779b3bbe2f1b2ac74d1074cffbc60e27 100644
--- a/pyopencl/algorithm.py
+++ b/pyopencl/algorithm.py
@@ -221,18 +221,19 @@ def _padded_bin(i, l):
 
 @memoize
 def _make_sort_scan_type(device, bits, index_dtype):
+    name = "pyopencl_sort_scan_%s_%dbits_t" % (
+            index_dtype.type.__name__, bits)
+
     fields = []
     for mnr in range(2**bits):
         fields.append(('c%s' % _padded_bin(mnr, bits), index_dtype))
 
     dtype = np.dtype(fields)
 
-    name = "pyopencl_sort_scan_%s_%dbits_t" % (
-            index_dtype.type.__name__, bits)
-    from pyopencl.tools import register_dtype, match_dtype_to_c_struct
+    from pyopencl.tools import get_or_register_dtype, match_dtype_to_c_struct
     dtype, c_decl = match_dtype_to_c_struct(device, name, dtype)
 
-    register_dtype(dtype, name)
+    dtype = get_or_register_dtype(name, dtype)
     return name, dtype, c_decl
 
 # {{{ types, helpers preamble
@@ -344,7 +345,7 @@ class RadixSort(object):
         :arg arguments: A string of comma-separated C argument declarations.
             If *arguments* is specified, then *input_expr* must also be
             specified. All types used here must be known to PyOpenCL.
-            (see :func:`pyopencl.tools.register_dtype`).
+            (see :func:`pyopencl.tools.get_or_register_dtype`).
         :arg key_expr: An integer-valued C expression returning the
             key based on which the sort is performed. The array index
             for which the key is to be computed is available as `i`.
diff --git a/pyopencl/array.py b/pyopencl/array.py
index d73214d5e38fc286ada7762edece3f81814fd25b..7652a0877ad63a9d029d109b8a8260dc1277aa52 100644
--- a/pyopencl/array.py
+++ b/pyopencl/array.py
@@ -59,7 +59,7 @@ class vec:
 def _create_vector_types():
     field_names = ["x", "y", "z", "w"]
 
-    from pyopencl.tools import register_dtype
+    from pyopencl.tools import get_or_register_dtype
 
     vec.types = {}
     counts = [2, 3, 4, 8, 16]
@@ -87,7 +87,7 @@ def _create_vector_types():
                 formats=[base_type]*count,
                 titles=titles))
 
-            register_dtype(dtype, name)
+            get_or_register_dtype(name, dtype)
 
             setattr(vec, name, dtype)
 
diff --git a/pyopencl/compyte b/pyopencl/compyte
index 1e4f772ef58883bdd4da06cb07de82feb77ea1bd..6d04cbf3df4fd55fd59aad5885171af9ed484b4f 160000
--- a/pyopencl/compyte
+++ b/pyopencl/compyte
@@ -1 +1 @@
-Subproject commit 1e4f772ef58883bdd4da06cb07de82feb77ea1bd
+Subproject commit 6d04cbf3df4fd55fd59aad5885171af9ed484b4f
diff --git a/pyopencl/scan.py b/pyopencl/scan.py
index 0ee565f2c7a4fd10f0278183066a11e35b380417..3a82172af5311658ea4f5b1c0c5dd75236e630cb 100644
--- a/pyopencl/scan.py
+++ b/pyopencl/scan.py
@@ -814,11 +814,11 @@ class _GenericScanKernelBase(object):
             for this scan kernel will be generated.
         :arg dtype: the :class:`numpy.dtype` with which the scan will
             be performed. May be a structured type if that type was registered
-            through :func:`pyopencl.tools.register_dtype`.
+            through :func:`pyopencl.tools.get_or_register_dtype`.
         :arg arguments: A string of comma-separated C argument declarations.
             If *arguments* is specified, then *input_expr* must also be
             specified. All types used here must be known to PyOpenCL.
-            (see :func:`pyopencl.tools.register_dtype`).
+            (see :func:`pyopencl.tools.get_or_register_dtype`).
         :arg scan_expr: The associative, binary operation carrying out the scan,
             represented as a C string. Its two arguments are available as `a`
             and `b` when it is evaluated. `b` is guaranteed to be the
diff --git a/pyopencl/tools.py b/pyopencl/tools.py
index ab70927cc8d6f532e18fe7ef8a6ecf3f2bc7086c..ee8560af65313d8ea6815e9864ce8f6017d27afd 100644
--- a/pyopencl/tools.py
+++ b/pyopencl/tools.py
@@ -37,12 +37,13 @@ from pytools import memoize, memoize_method
 import re
 
 from pyopencl.compyte.dtypes import (
+        get_or_register_dtype, TypeNameNotKnown,
         register_dtype, _fill_dtype_registry,
         dtype_to_ctype)
 
 _fill_dtype_registry(respect_windows=False)
-register_dtype(np.complex64, "cfloat_t")
-register_dtype(np.complex128, "cdouble_t")
+get_or_register_dtype("cfloat_t", np.complex64)
+get_or_register_dtype("cdouble_t", np.complex128)
 
 
 
@@ -378,9 +379,9 @@ def match_dtype_to_c_struct(device, name, dtype, context=None):
         } id_val;
         >>> print dtype
         [('id', '<u4'), ('value', '<f4')]
-        >>> cl.tools.register_dtype(dtype, 'id_val')
+        >>> dtype_cl.tools.get_or_register_dtype('id_val', dtype)
 
-    As this example shows, it is important to call :func:`register_dtype` on
+    As this example shows, it is important to call :func:`get_or_register_dtype` on
     the modified `dtype` returned by this function, not the original one.
     """
 
diff --git a/test/test_array.py b/test/test_array.py
index fdf99917f20d098e9b3b3d4b4afe04e4305c9fd6..47b2f76b94f7f5fbfabadaaab37f3914f40f9acb 100644
--- a/test/test_array.py
+++ b/test/test_array.py
@@ -723,10 +723,10 @@ def make_mmc_dtype(device):
         ])
 
     name = "minmax_collector"
-    from pyopencl.tools import register_dtype, match_dtype_to_c_struct
+    from pyopencl.tools import get_or_register_dtype, match_dtype_to_c_struct
 
     dtype, c_decl = match_dtype_to_c_struct(device, name, dtype)
-    register_dtype(dtype, name)
+    dtype = get_or_register_dtype(name, dtype)
 
     return dtype, c_decl