From d5222cf99108c2f017caf1f324c180d8916044a1 Mon Sep 17 00:00:00 2001
From: Matt Wala <wala1@illinois.edu>
Date: Sat, 15 Jul 2017 19:07:45 -0500
Subject: [PATCH] Change tuple assignment to be implemented directly by the
 code generator, so that we can avoid generating a dummy C function.

---
 loopy/library/tuple.py     | 32 +-------------------------------
 loopy/target/c/__init__.py | 33 +++++++++++++++++++++++++++++++++
 loopy/target/opencl.py     |  2 --
 3 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/loopy/library/tuple.py b/loopy/library/tuple.py
index dd6b553eb..ce2865ff5 100644
--- a/loopy/library/tuple.py
+++ b/loopy/library/tuple.py
@@ -29,40 +29,10 @@ def tuple_function_mangler(kernel, name, arg_dtypes):
     if name == "make_tuple":
         from loopy.kernel.data import CallMangleInfo
         return CallMangleInfo(
-                target_name=tuple_function_name(*arg_dtypes),
+                target_name="loopy_make_tuple",
                 result_dtypes=arg_dtypes,
                 arg_dtypes=arg_dtypes)
 
     return None
 
-
-def tuple_function_name(dtype0, dtype1):
-    return "loopy_tuple_%s_%s" % (
-            dtype0.numpy_dtype.type.__name__, dtype1.numpy_dtype.type.__name__)
-
-
-def get_tuple_preamble(kernel, func_id, arg_dtypes):
-    name = tuple_function_name(*arg_dtypes)
-    return (name, """
-    inline %(t0)s %(name)s(%(t0)s i0, %(t1)s i1, %(t1)s *o1)
-    {
-      *o1 = i1;
-      return i0;
-    }
-    """ % dict(name=name,
-            t0=kernel.target.dtype_to_typename(arg_dtypes[0]),
-            t1=kernel.target.dtype_to_typename(arg_dtypes[1])))
-
-
-def tuple_preamble_generator(preamble_info):
-    from loopy.target.opencl import OpenCLTarget
-
-    for func in preamble_info.seen_functions:
-        if func.name == "make_tuple":
-            if not isinstance(preamble_info.kernel.target, OpenCLTarget):
-                raise LoopyError("only OpenCL supported for now")
-
-            yield get_tuple_preamble(preamble_info.kernel, func.name,
-                    func.arg_dtypes)
-
 # vim: fdm=marker
diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py
index e4835a363..ed1ba1ce9 100644
--- a/loopy/target/c/__init__.py
+++ b/loopy/target/c/__init__.py
@@ -648,6 +648,36 @@ class CASTBuilder(ASTBuilderBase):
             lhs_expr, rhs_expr, lhs_dtype):
         raise NotImplementedError("atomic updates in %s" % type(self).__name__)
 
+    def emit_tuple_assignment(self, codegen_state, insn):
+        ecm = codegen_state.expression_to_code_mapper
+
+        parameters = insn.expression.parameters
+        parameter_dtypes = tuple(ecm.infer_type(par) for par in parameters)
+
+        from cgen import Assign, block_if_necessary
+        assignments = []
+
+        for i, (assignee, tgt_dtype) in enumerate(
+                zip(insn.assignees, parameter_dtypes)):
+            if tgt_dtype != ecm.infer_type(assignee):
+                raise LoopyError("type mismatch in %d'th (0-based) left-hand "
+                        "side of instruction '%s'" % (i, insn.id))
+
+            lhs_code = ecm(assignee, prec=PREC_NONE, type_context=None)
+            assignee_var_name = insn.assignee_var_names()[i]
+            lhs_var = codegen_state.kernel.get_var_descriptor(assignee_var_name)
+            lhs_dtype = lhs_var.dtype
+
+            from loopy.expression import dtype_to_type_context
+            rhs_type_context = dtype_to_type_context(
+                    codegen_state.kernel.target, lhs_dtype)
+            rhs_code = ecm(parameters[i], prec=PREC_NONE,
+                           type_context=rhs_type_context, needed_dtype=lhs_dtype)
+
+            assignments.append(Assign(lhs_code, rhs_code))
+
+        return block_if_necessary(assignments)
+
     def emit_multiple_assignment(self, codegen_state, insn):
         ecm = codegen_state.expression_to_code_mapper
 
@@ -674,6 +704,9 @@ class CASTBuilder(ASTBuilderBase):
 
         assert mangle_result.arg_dtypes is not None
 
+        if mangle_result.target_name == "loopy_make_tuple":
+            return self.emit_tuple_assignment(codegen_state, insn)
+
         from loopy.expression import dtype_to_type_context
         c_parameters = [
                 ecm(par, PREC_NONE,
diff --git a/loopy/target/opencl.py b/loopy/target/opencl.py
index e70acfeab..a5f7562c4 100644
--- a/loopy/target/opencl.py
+++ b/loopy/target/opencl.py
@@ -390,13 +390,11 @@ class OpenCLCASTBuilder(CASTBuilder):
 
     def preamble_generators(self):
         from loopy.library.reduction import reduction_preamble_generator
-        from loopy.library.tuple import tuple_preamble_generator
 
         return (
                 super(OpenCLCASTBuilder, self).preamble_generators() + [
                     opencl_preamble_generator,
                     reduction_preamble_generator,
-                    tuple_preamble_generator
                     ])
 
     # }}}
-- 
GitLab