From de65e74c8f9e433c0f94c30e1b0aff27c22dc6cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Thu, 3 Sep 2020 17:52:12 +0200
Subject: [PATCH] =?UTF-8?q?use=5Fdll:=20add=20the=20=E2=80=9Crestrict?=
 =?UTF-8?q?=E2=80=9D=20C99=20keyword=20to=20all=20pointers=20to=20double?=
 =?UTF-8?q?=20in=20computation=20functions?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This greatly facilitates the job of the compiler during the optimization pass,
since we promise that the various pointers do not overlap each other. It may
now be possible to reenable some of the optimization flags that were disabled
without sacrificing compilation time, but this needs more investigation.

For the gory details, see:
https://en.cppreference.com/w/c/language/restrict
https://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
---
 src/DynamicModel.cc | 14 +++++++-------
 src/StaticModel.cc  | 14 +++++++-------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index 933ae44a..76b6671e 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -632,9 +632,9 @@ DynamicModel::writeDynamicPerBlockCFiles(const string &basename) const
 
       if (simulation_type == BlockSimulationType::evaluateBackward
           || simulation_type == BlockSimulationType::evaluateForward)
-        output << "void dynamic_" << blk+1 << "(double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, double *T, int it_, bool stochastic_mode, double *g1_i, double *g1_j, double *g1_v, double *g1_x_i, double *g1_x_j, double *g1_x_v, double *g1_xd_i, double *g1_xd_j, double *g1_xd_v, double *g1_o_i, double *g1_o_j, double *g1_o_v)" << endl;
+        output << "void dynamic_" << blk+1 << "(double *restrict y, const double *restrict x, int nb_row_x, const double *restrict params, const double *restrict steady_state, double *restrict T, int it_, bool stochastic_mode, double *restrict g1_i, double *restrict g1_j, double *restrict g1_v, double *restrict g1_x_i, double *restrict g1_x_j, double *restrict g1_x_v, double *restrict g1_xd_i, double *restrict g1_xd_j, double *restrict g1_xd_v, double *restrict g1_o_i, double *restrict g1_o_j, double *restrict g1_o_v)" << endl;
       else
-        output << "void dynamic_" << blk+1 << "(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, double *T, int it_, bool stochastic_mode, double *residual, double *g1_i, double *g1_j, double *g1_v, double *g1_x_i, double *g1_x_j, double *g1_x_v, double *g1_xd_i, double *g1_xd_j, double *g1_xd_v, double *g1_o_i, double *g1_o_j, double *g1_o_v)" << endl;
+        output << "void dynamic_" << blk+1 << "(const double *restrict y, const double *restrict x, int nb_row_x, const double *restrict params, const double *restrict steady_state, double *restrict T, int it_, bool stochastic_mode, double *restrict residual, double *restrict g1_i, double *restrict g1_j, double *restrict g1_v, double *restrict g1_x_i, double *restrict g1_x_j, double *restrict g1_x_v, double *restrict g1_xd_i, double *restrict g1_xd_j, double *restrict g1_xd_v, double *restrict g1_o_i, double *restrict g1_o_j, double *restrict g1_o_v)" << endl;
       output << '{' << endl;
 
       writeDynamicPerBlockHelper(blk, output, ExprNodeOutputType::CDynamicModel, temporary_terms,
@@ -2114,18 +2114,18 @@ DynamicModel::writeDynamicModel(const string &basename, ostream &DynamicOutput,
       for (size_t i = 0; i < d_output.size(); i++)
         {
           string funcname = i == 0 ? "resid" : "g" + to_string(i);
-          DynamicOutput << "void dynamic_" << funcname << "_tt(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, double *T)" << endl
+          DynamicOutput << "void dynamic_" << funcname << "_tt(const double *restrict y, const double *restrict x, int nb_row_x, const double *restrict params, const double *restrict steady_state, int it_, double *restrict T)" << endl
                         << "{" << endl
                         << tt_output[i].str()
                         << "}" << endl
                         << endl
-                        << "void dynamic_" << funcname << "(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, ";
+                        << "void dynamic_" << funcname << "(const double *restrict y, const double *restrict x, int nb_row_x, const double *restrict params, const double *restrict steady_state, int it_, const double *restrict T, ";
           if (i == 0)
-            DynamicOutput << "double *residual";
+            DynamicOutput << "double *restrict residual";
           else if (i == 1)
-            DynamicOutput << "double *g1";
+            DynamicOutput << "double *restrict g1";
           else
-            DynamicOutput << "double *" << funcname << "_i, double *" << funcname << "_j, double *" << funcname << "_v";
+            DynamicOutput << "double *restrict " << funcname << "_i, double *restrict " << funcname << "_j, double *restrict " << funcname << "_v";
           DynamicOutput << ")" << endl
                         << "{" << endl;
           if (i == 0)
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index 1cbd21b6..69a93ec9 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -316,9 +316,9 @@ StaticModel::writeStaticPerBlockCFiles(const string &basename) const
 
       if (simulation_type == BlockSimulationType::evaluateBackward
           || simulation_type == BlockSimulationType::evaluateForward)
-        output << "void static_" << blk+1 << "(double *y, const double *x, const double *params, double *T)" << endl;
+        output << "void static_" << blk+1 << "(double *restrict y, const double *restrict x, const double *restrict params, double *restrict T)" << endl;
       else
-        output << "void static_" << blk+1 << "(const double *y, const double *x, const double *params, double *T, double *residual, double *g1_i, double *g1_j, double *g1_v)" << endl;
+        output << "void static_" << blk+1 << "(const double *restrict y, const double *restrict x, const double *restrict params, double *restrict T, double *restrict residual, double *restrict g1_i, double *restrict g1_j, double *restrict g1_v)" << endl;
       output << '{' << endl;
 
       writeStaticPerBlockHelper(blk, output, ExprNodeOutputType::CStaticModel, temporary_terms);
@@ -1446,18 +1446,18 @@ StaticModel::writeStaticModel(const string &basename,
       for (size_t i = 0; i < d_output.size(); i++)
         {
           string funcname = i == 0 ? "resid" : "g" + to_string(i);
-          StaticOutput << "void static_" << funcname << "_tt(const double *y, const double *x, const double *params, double *T)" << endl
+          StaticOutput << "void static_" << funcname << "_tt(const double *restrict y, const double *restrict x, const double *restrict params, double *restrict T)" << endl
                        << "{" << endl
                        << tt_output[i].str()
                        << "}" << endl
                        << endl
-                       << "void static_" << funcname << "(const double *y, const double *x, const double *params, const double *T, ";
+                       << "void static_" << funcname << "(const double *restrict y, const double *restrict x, const double *restrict params, const double *restrict T, ";
           if (i == 0)
-            StaticOutput << "double *residual";
+            StaticOutput << "double *restrict residual";
           else if (i == 1)
-            StaticOutput << "double *g1";
+            StaticOutput << "double *restrict g1";
           else
-            StaticOutput << "double *" << funcname << "_i, double *" << funcname << "_j, double *" << funcname << "_v";
+            StaticOutput << "double *restrict " << funcname << "_i, double *restrict " << funcname << "_j, double *restrict " << funcname << "_v";
           StaticOutput << ")" << endl
                        << "{" << endl;
           if (i == 0)
-- 
GitLab