next up previous contents
Next: The Basic Data Structures Up: Writing a Pass Previous: Command line parsing   Contents


Passes and Pipelinable Passes

Most of the modules are compiler passes, which performs some analysis on the program representation, rooted at the file_set_block in the textttsuif_env. This common schema is captured in the definition of a Pass, which is a subclass of a Module.

       class Pass : public Module {
       protected:
         Pass( SuifEnv* suif_env, const LString &name );
         virtual ~Pass();

       public:
         // the default implementation invokes the method do_file_set_block
         virtual void execute();
         virtual Module* clone() const = 0;
     
         // your stuff goes here
         virtual void do_file_set_block( FileSetBlock* file_set_block ) = 0;
       };

A Pass simply adds a new method, do_file_set_block, which is invoked in the execute routine on the file_set_block of the suif_env. To write a pass, you must derive from this class and define the clone and do_file_set_block methods.

Another useful schema of a pass is captured by the PipelinablePass, which is a subclass of Pass itself. Its declaration is shown below. A pass is pipelinable if its computation can be applied to each procedure independently. The system execute a sequence of PipelinablePasses by applying all the functions from the different passes to the same procedure in the program, before moving onto another procedure. This execution order should have a better data locality. The syntax to call a group of pipelined passes in a suifdriver is ``pipeline {pass1;pass2; }''.

  class PipelinablePass : public Pass {
  public:
     PipelinablePass( SuifEnv* suif_env, const LString &name );
     virtual ~PipelinablePass() = 0;

     // will execute the Pass as if it is not pipelined
     virtual void execute();

     // May return this if the pass has no state.
     virtual Module* clone() const = 0;

     // override one or more of the following methods
     // the default implementation is empty
     virtual void do_file_set_block( FileSetBlock* file_set_block );
     virtual void do_file_block( FileBlock* file_block );
     virtual void do_variable_definition( VariableDefinition* var_def );
     virtual void do_procedure_definition( ProcedureDefinition* proc_def );
     virtual void finalize(){};         
  };

The pipelined execution starts by calling the do_file_set_block methods in all the pipelined modules. Next, for each file block in the program, it calls the do_file_block methods in all the modules. Next, for each variable definition in the file block, it calls the do_variable_definition methods in all the modules. Next, for each procedure in the program, it calls the do_procedure_definition methods in all the modules. Finally, it calls the finalize methods in all the modules.


next up previous contents
Next: The Basic Data Structures Up: Writing a Pass Previous: Command line parsing   Contents
SUIF Nightly Build
2000-08-14