Optimize code by merging expressions
Now that we are using Eigen expressions in Stan Math it makes sense for compiler to merge multiple expressions into singe one where possible to avoid unnecessary memory accesses. This is possible where we have a variable of matrix, vector or row_vector type (or if using OpenCL any type that is replaced with a matrix_cl) that is used in exactly one place in further code. Such a variable can be removed and its use case replaced with the expression that was assigned to the variable.
For example from stan code:
matrix a, b;
matrix c = a + b;
matrix d = c * 3;
We want to generate (assuming c is not used anywhere else):
Eigen::MatrixXd a, b;
Eigen::MatrixXd d = (a + b) * 3;
instead of:
Eigen::MatrixXd a, b;
Eigen::MatrixXd c = a + b;
Eigen::MatrixXd d = c * 3;
I think this is the current behavior of the optimizations when you turn lazy code motion off (it's implemented by expression propagation + dead code elimination). Lazy code motion assumes that it's free to make a new local variable to hold an intermediate result. So, I think we could implement this by teaching lazy code motion that it's not worth moving an expression if it's only used in one place.