diff --git a/control/descriptor.h b/control/descriptor.h
index e0ebcc936077256f42902dd8a49dcf05ca3c54ab..49e038d98f969fcf9427a2907770c35273dcb750 100644
--- a/control/descriptor.h
+++ b/control/descriptor.h
@@ -4,7 +4,7 @@
  *                          of Tennessee Research Foundation.
  *                          All rights reserved.
  * @copyright (c) 2012-2014 Inria. All rights reserved.
- * @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
+ * @copyright (c) 2012-2014, 2017 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved.
  *
  **/
 
@@ -196,6 +196,32 @@ inline static int morse_desc_islocal( const MORSE_desc_t *A, int m, int n )
 #endif /* defined(CHAMELEON_USE_MPI) */
 }
 
+/*******************************************************************************
+ * Declare data accesses of codelets using these macros, for instance:
+ * MORSE_BEGIN_ACCESS_DECLARATION
+ * MORSE_ACCESS_R(A, Am, An)
+ * MORSE_ACCESS_R(B, Bm, Bn)
+ * MORSE_ACCESS_RW(C, Cm, Cn)
+ * MORSE_END_ACCESS_DECLARATION
+ */
+#define MORSE_BEGIN_ACCESS_DECLARATION { \
+    unsigned __morse_need_submit = 0;
+
+#define MORSE_ACCESS_R(A, Am, An) \
+    if (morse_desc_islocal(A, Am, An)) __morse_need_submit = 1;
+
+#define MORSE_ACCESS_W(A, Am, An) \
+    if (morse_desc_islocal(A, Am, An)) __morse_need_submit = 1;
+
+#define MORSE_ACCESS_RW(A, Am, An) \
+    if (morse_desc_islocal(A, Am, An)) __morse_need_submit = 1;
+
+#define MORSE_RANK_CHANGED __morse_need_submit = 1;
+
+#define MORSE_END_ACCESS_DECLARATION \
+    if (!__morse_need_submit) return; \
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/runtime/starpu/codelets/codelet_zgemm.c b/runtime/starpu/codelets/codelet_zgemm.c
index d9ba98ff68d151edc28c8dfa5ef023200fd2e508..ed5ff9d571be4c9ccf6f657e286c1338f5c41fa0 100644
--- a/runtime/starpu/codelets/codelet_zgemm.c
+++ b/runtime/starpu/codelets/codelet_zgemm.c
@@ -70,37 +70,38 @@ void MORSE_TASK_zgemm(const MORSE_option_t *options,
         rank_changed = 1;
     }
 
-    if ( morse_desc_islocal( A, Am, An ) ||
-         morse_desc_islocal( B, Bm, Bn ) ||
-         morse_desc_islocal( C, Cm, Cn ) ||
-         rank_changed
-       )
-    {
-        starpu_insert_task(
-            starpu_mpi_codelet(codelet),
-            STARPU_VALUE,    &transA,            sizeof(MORSE_enum),
-            STARPU_VALUE,    &transB,            sizeof(MORSE_enum),
-            STARPU_VALUE,    &m,                 sizeof(int),
-            STARPU_VALUE,    &n,                 sizeof(int),
-            STARPU_VALUE,    &k,                 sizeof(int),
-            STARPU_VALUE,    &alpha,             sizeof(MORSE_Complex64_t),
-            STARPU_R,         RTBLKADDR(A, MORSE_Complex64_t, Am, An),
-            STARPU_VALUE,    &lda,               sizeof(int),
-            STARPU_R,         RTBLKADDR(B, MORSE_Complex64_t, Bm, Bn),
-            STARPU_VALUE,    &ldb,               sizeof(int),
-            STARPU_VALUE,    &beta,              sizeof(MORSE_Complex64_t),
-            STARPU_RW,        RTBLKADDR(C, MORSE_Complex64_t, Cm, Cn),
-            STARPU_VALUE,    &ldc,               sizeof(int),
-            STARPU_PRIORITY,  options->priority,
-            STARPU_CALLBACK,  callback,
+    MORSE_BEGIN_ACCESS_DECLARATION;
+    MORSE_ACCESS_R(A, Am, An);
+    MORSE_ACCESS_R(B, Bm, Bn);
+    MORSE_ACCESS_RW(C, Cm, Cn);
+    if (rank_changed)
+        MORSE_RANK_CHANGED;
+    MORSE_END_ACCESS_DECLARATION;
+
+    starpu_insert_task(
+        starpu_mpi_codelet(codelet),
+        STARPU_VALUE,    &transA,            sizeof(MORSE_enum),
+        STARPU_VALUE,    &transB,            sizeof(MORSE_enum),
+        STARPU_VALUE,    &m,                 sizeof(int),
+        STARPU_VALUE,    &n,                 sizeof(int),
+        STARPU_VALUE,    &k,                 sizeof(int),
+        STARPU_VALUE,    &alpha,             sizeof(MORSE_Complex64_t),
+        STARPU_R,         RTBLKADDR(A, MORSE_Complex64_t, Am, An),
+        STARPU_VALUE,    &lda,               sizeof(int),
+        STARPU_R,         RTBLKADDR(B, MORSE_Complex64_t, Bm, Bn),
+        STARPU_VALUE,    &ldb,               sizeof(int),
+        STARPU_VALUE,    &beta,              sizeof(MORSE_Complex64_t),
+        STARPU_RW,        RTBLKADDR(C, MORSE_Complex64_t, Cm, Cn),
+        STARPU_VALUE,    &ldc,               sizeof(int),
+        STARPU_PRIORITY,  options->priority,
+        STARPU_CALLBACK,  callback,
 #if defined(CHAMELEON_USE_MPI)
-            STARPU_EXECUTE_ON_NODE, execution_rank,
+        STARPU_EXECUTE_ON_NODE, execution_rank,
 #endif
 #if defined(CHAMELEON_CODELETS_HAVE_NAME)
-            STARPU_NAME, "zgemm",
+        STARPU_NAME, "zgemm",
 #endif
-            0);
-    }
+        0);
 }
 
 #if !defined(CHAMELEON_SIMULATION)