It is illustrative to look at several ways to simplify the right hand side of a Fortran assignment statement with Polaris. This section will discuss a correct, but slow, way of doing it, then an incorrect (but faster) way of doing it, then finally show a way to fix the problems with the incorrect method, to get a fast method which is correct and conforms to Polaris conventions.
First, we show the correct, but slow, method:
Statement s; s.rhs( simplify( s.rhs().clone() );
The steps here are:
This example conforms to Polaris conventions, is simple to write, and gets the job done, but involves making a copy of the original expression. This can get very expensive if the expression is quite long and complicated.
In an attempt to eliminate the copying, a programmer might decide to use the pull()/ assign() functions, which temporarily extract an expression from the List<Expression> in the Statement, simplify it, then re-insert it in the same place in the list. This is a reasonable thing to try, but it is important to be careful about applying this idea. The following attempt is incorrect:
Statement s; Iterator<Expression> iter = s.iterate_expressions(); ++iter; iter.assign() = simplify(iter.pull());
There are three problems with this attempt:
In light of these problems, the incorrect example can be re-written correctly as follows:
Statement s; for (Mutator<Expression> muter = s.iterate_expressions(); muter.valid(); ++muter) { if (&muter.current() == &s.rhs()) { muter.assign() = simplify(muter.pull()); break; } s.build_refs();
This example fixes the incorrect example by: