next up previous
Next: adding a switch Up: Code Examples Previous: instrumenter

simplify()ing the rhs of a statement (two ways)

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:

  1. The example does not rebuild the in_, out_, and act_refs of the Statement s. The Polaris base cannot do it automatically, since the replacement of the expression is happening directly on the List<Expression> and the Statement which contains those expressions never gets involved, and never has a chance to rebuild those RefSets.
  2. The example assumes that the right hand side expression will be in a specific position of the iterate_exprs() List<Expression> (position 1 - the second element). This may happen to be the case now, but Polaris does not guarantee that. The order of the expressions in the list may change.
  3. Since the List<Expression> returned by Statement::iterate_expressions() gets modified, the Iterator should be a Mutator.

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:

  1. Rebuilding the in_, out_, and act_ ref sets through the s.build_refs() call.
  2. Searching through the entire List<Expression> returned by s.iterate_expressions() until it finds the element whose address matches the address of the right hand side (implemented by the if (&muter.current() == &s.rhs()) statement).
  3. Using the modifiable version of the Iterator, the Mutator, in the for loop.


next up previous
Next: adding a switch Up: Code Examples Previous: instrumenter



Jay Hoeflinger
Mon Apr 21 11:52:18 CDT 1997