Program Listing for File Outliner.hh

Program Listing for File Outliner.hh#

Return to documentation for file (src/midend/programTransformation/astOutlining/Outliner.hh)

#if !defined(INC_LIAOUTLINER_HH)
#define INC_LIAOUTLINER_HH

#include <cstdlib>
#include <vector>
#include <set>
#include <string>
#include <ASTtools.hh>
#include <VarSym.hh>

class SgProject;
class SgFunctionDeclaration;
class SgStatement;
class SgPragmaDeclaration;

namespace Outliner
{
  //
  // Default behavior
  // ----------------------------------
  // if none of the flags are set to true, the default behavior is:
  // * all variables are passed by references whenever possible by default (pointer types, and pointer dereferencing)
  // * function parameter packing is needed to transfer the value of parameter to a local declaration

  // default behavior + variable cloning
   // Using variable cloning(temp variable) to reduce the uses of pointer dereferencing in computation kernels.
  // Details are in the paper: Chunhua Liao, Daniel J. Quinlan, Richard Vuduc, and Thomas Panas. 2009. Effective source-to-source outlining to support whole program empirical optimization. In Proceedings of the 22nd international conference on Languages and Compilers for Parallel Computing (LCPC'09).
  ROSE_DLL_API extern bool temp_variable; // Use temporary variables to reduce the uses of pointer dereferencing. Activated by -rose:outline:temp_variable

  // -----------------------------------
  // Method 1: classic outlining behavior:
  // Each parameter represents a single variable being passed in/out the outlined function. No parameter wrapping
  // Use parameters of the outlined function directly in the function,  no local declaration/copying of parameter is needed .
  // Side effect analysis is used for deciding on pass-by-value (readOnly) and pass-by-ref,
  ROSE_DLL_API extern bool enable_classic;
  // -----------------------------------
  // Method 2: using a wrapper (array of pointers vs. structure of flexible typed members)
  // use a wrapper for all variables or one parameter for a variable or a wrapper for all variables
  ROSE_DLL_API extern bool useParameterWrapper;  // use an array of pointers wrapper for parameters of the outlined function. all things are passed by pointers (addressOf) by default
  ROSE_DLL_API extern bool useStructureWrapper;  // use a structure-type wrapper for parameters of the outlined function, this is a sub option for useParameterWrapper. false means using array, true means using structure (the same as useParameterWrapper).
  // turned on by command line option:   -rose:outline:parameter_wrapper


  //---------------------------------others ---------------------
  ROSE_DLL_API extern bool preproc_only_;  // preprocessing only, -rose:outline:preproc-only
  ROSE_DLL_API extern bool useNewFile; // Generate the outlined function into a separated new source file
                          // -rose:outline:new_file
  ROSE_DLL_API extern bool copy_origFile; // when generating the new file to store outlined function, copy entire original file to it.
  ROSE_DLL_API extern std::vector<int> lines;  // line positions of outlining targets, given by command line option -rose:outline:line for each
  ROSE_DLL_API extern bool enable_debug; // output debug information for outliner
  ROSE_DLL_API extern bool exclude_headers; // exclude headers from the new file containing outlined functions
  ROSE_DLL_API extern bool enable_liveness; // enable liveness analysis to reduce restoring statements when temp variables are used
  ROSE_DLL_API extern bool use_dlopen; // Outlining the target to a separated file and calling it using a dlopen() scheme. It turns on useNewFile.
  //Note that use_dlopen_simple is treated as a suboption under use_dlopen.
  //So we must turn on use_dlopen if use_dlopen_simple is turned on!
  ROSE_DLL_API extern bool use_dlopen_simple; // Outlining the target to a separated file and calling it using a dlopen() scheme. It turns on useNewFile. Additionally using a simple call convention through findAndCallFunctionUsingDlopen

  ROSE_DLL_API extern bool enable_template;  // Enabling outlining code blocks inside template functions
  ROSE_DLL_API extern bool select_omp_loop;  // Find OpenMP for loops and outline them. This is used for testing purposes.

  ROSE_DLL_API extern std::string output_path; // where to save the new file containing the outlined function

// DQ (3/19/2019): Suppress the output of the #include "autotuning_lib.h" since some tools will want to define there own supporting libraries and header files.
  ROSE_DLL_API extern bool suppress_autotuning_header; // when generating the new file to store outlined function, suppress output of #include "autotuning_lib.h".

  // A support lib's header name
  //const std::string AUTOTUNING_LIB_HEADER="autotuning_lib.h";
  const std::string AUTOTUNING_LIB_HEADER="outlining_lib.h"; // we moved the lib to be inside of rose/src and renamed it.
  // the lib function call to find a specified function pointer
  const std::string FIND_FUNCP_DLOPEN="findFunctionUsingDlopen";
  //Find and call a function through dlopen, using a single function call to implement all logic of parameter packing, lib existence checking etc.
  const std::string FIND_AND_CALL_FUNCP_DLOPEN="findAndCallFunctionUsingDlopen";

  const std::string DEFAULT_OUTPUT_PATH="/tmp";

#if 0
  // DQ (11/19/2020): We need to expand the use of this to cover deffered transformations of common SageInterface transformations (e.g. replaceStatement).
  // So I need to move this out of being specific to the outliner and make it more generally data structure in the SageInterface.
  struct DeferredTransformation
     {
    // DQ (11/15/2020): Need to add the concept of deffered transformation to cover replaceStatement operations.

    // DQ (8/7/2019): Store data required to support defering the transformation to insert the outlined function prototypes
    // into class declaration (when this is required to support the outlined function's access to protected or private data members).
    // This is part of an optimization to support the optimization of header file unparsing (limiting the overhead of supporting any
    // header file to just focus on the few (typically one) header file that would have to be unparsed.

       SgClassDefinition* class_definition;
       SgDeclarationStatement* target_class_member;
       SgDeclarationStatement* new_function_prototype;

       typedef std::set<SgClassDefinition *> ClassDefSet_t;
       ClassDefSet_t targetClasses;

       typedef std::vector<SgFunctionDeclaration *> FuncDeclList_t;
       FuncDeclList_t targetFriends;

    // DQ (12/5/2019): Added ROSE_DLL_API prefix for Windows support (too all of these functions).
       ROSE_DLL_API DeferredTransformation();
       ROSE_DLL_API DeferredTransformation(SgClassDefinition* class_definition, SgDeclarationStatement* target_class_member, SgDeclarationStatement* new_function_prototype);
       ROSE_DLL_API DeferredTransformation (const DeferredTransformation& X);
       ROSE_DLL_API ~DeferredTransformation (void);

       ROSE_DLL_API DeferredTransformation & operator= (const DeferredTransformation& X);
     };
#endif

  struct Result
  {
    SgFunctionDeclaration* decl_;

    SgStatement* call_;

    // outlined function if -rose:outline:new_file is specified (useNewFile==true)
    SgFile* file_;

 // DQ (8/7/2019): Store data required to support defering the transformation to insert the outlined function prototypes
 // into class declaration (when this is required to support the outlined function's access to protected or private data members).
    SgDeclarationStatement* target_class_member;
    SgDeclarationStatement* new_function_prototype;

 // DQ (11/19/2020): DeferredTransformation support was moved to the SageInterface namespace to support more general usage.
 // DQ (8/15/2019): Adding support to defere the transformations in header files (a performance improvement).
 // DeferredTransformation deferredTransformation;
    SageInterface::DeferredTransformation deferredTransformation;

 // DQ (12/5/2019): Added ROSE_DLL_API prefix for Windows support (too all of these functions).
    ROSE_DLL_API Result (void);

 // DQ (11/19/2020): DeferredTransformation support was moved to the SageInterface namespace to support more general usage.
 // DQ (8/15/2019): Adding support to defere the transformations in header files (a performance improvement).
 // Result (SgFunctionDeclaration *, SgStatement *, SgFile* file=NULL);
 // ROSE_DLL_API Result (SgFunctionDeclaration *, SgStatement *, SgFile* file, DeferredTransformation deferredTransformation);
    ROSE_DLL_API Result (SgFunctionDeclaration *, SgStatement *, SgFile* file, SageInterface::DeferredTransformation deferredTransformation);

    ROSE_DLL_API Result (const Result&);
    ROSE_DLL_API ~Result (void) {};
    ROSE_DLL_API bool isValid (void) const;
  };

  ROSE_DLL_API void validateSettings();

  // Please use this function before calling the frontend() to set the internal flags
  ROSE_DLL_API void commandLineProcessing(std::vector<std::string> &argvList);
  //
  ROSE_DLL_API bool isOutlineable (const SgStatement* s, bool verbose = false);


  std::string generateFuncName (const SgStatement* stmt);

  std::string generateFuncArgName (const SgStatement* stmt);


  ROSE_DLL_API Result outline (SgStatement* s);

  Result outline (SgStatement* s, const std::string& func_name);


  Result outline (SgPragmaDeclaration* s);


  ROSE_DLL_API size_t outlineAll (SgProject *);

  ROSE_DLL_API SgBasicBlock* preprocess (SgStatement* s);
  ROSE_DLL_API SgBasicBlock* preprocess (SgPragmaDeclaration* s);
  ROSE_DLL_API size_t preprocessAll (SgProject *);

    Result outlineBlock (SgBasicBlock* b, const std::string& name);

    void collectVars (const SgStatement* s, ASTtools::VarSymSet_t& syms);
    //void collectVars (const SgStatement* s, ASTtools::VarSymSet_t& syms, ASTtools::VarSymSet_t& private_syms);

    ROSE_DLL_API SgSourceFile* generateNewSourceFile(SgBasicBlock* target, const std::string& file_name);

    ROSE_DLL_API SgSourceFile* getLibSourceFile(SgBasicBlock* target);

    // DQ (3/20/2019): This function operates on the new file used to support outlined function definitions.
    /* \brief XXX
     * This function operates on the new file used to support outlined function definitions.
     * We use a copy of the file where the code will be outlined FROM, so that if there are references to
     * declarations in the outlined code we can support the outpiled code with those references.  This
     * approach has the added advantage of also supporting the same include file tree as the original
     * file where the outlined code is being taken from.
     */
    // ROSE_DLL_API void convertFunctionDefinitionsToFunctionPrototypes(SgNode* node);

    ROSE_DLL_API std::string generateLibSourceFileName (SgBasicBlock* target);

    ROSE_DLL_API
    SgClassDeclaration* generateParameterStructureDeclaration(
        SgBasicBlock* s, // the outlining target
        const std::string& func_name_str, // the name for the outlined function, we generate the name of struct based on this.
        const ASTtools::VarSymSet_t& syms, // variables to be passed as parameters
        ASTtools::VarSymSet_t& pdSyms, // variables must use pointer types (pointer dereferencing: pdf). The rest variables use pass-by-value
        SgScopeStatement* func_scope ); // the scope of the outlined function, could be in another file


 // DQ (2/25/2009): Modified function interface to pass "SgBasicBlock*" as not const parameter.
 // SgFunctionDeclaration* generateFunction (const SgBasicBlock* s,const std::string& func_name_str,const ASTtools::VarSymSet_t& syms,SgScopeStatement* scope);
    ROSE_DLL_API
    SgFunctionDeclaration*
    generateFunction (SgBasicBlock* s,
                      const std::string& func_name_str,
                      const ASTtools::VarSymSet_t& syms,
                      const ASTtools::VarSymSet_t& pdSyms, // variables using their addresses as parameters of the outlined functions, compared to use their values (pass-by-value)
                      //const std::set<SgInitializedName*>& readOnlyVars, // optional readOnlyVariables to optimize type of parameter when no wrapper is used.
                      //const std::set< SgInitializedName *>& liveOuts, // optional live out variables to optimize away the copy-back statements in variable cloning
                      const std::set< SgInitializedName *>& restoreVars, // variables need to be restored after their clones finish computation
                      SgClassDeclaration* struct_decl, /*optional struct type to wrap parameters*/
                      SgScopeStatement* scope);

     //return the unique wrapper parameter for the outlined function
     //target is the outlining target
    ROSE_DLL_API std::string generatePackingStatements(SgStatement* target, ASTtools::VarSymSet_t & syms,  ASTtools::VarSymSet_t & pdsyms, SgClassDeclaration* struct_decl = NULL);

 // DQ (11/19/2020): DeferredTransformation support was moved to the SageInterface namespace to support more general usage.
 // DQ (8/15/2019): Adding support to defer the transformations to header files.
 // ROSE_DLL_API void insert (SgFunctionDeclaration* func, SgGlobal* scope, SgBasicBlock* target_outlined_code )
 // ROSE_DLL_API DeferredTransformation insert (SgFunctionDeclaration* func, SgGlobal* scope, SgBasicBlock* outlining_target );
    ROSE_DLL_API SageInterface::DeferredTransformation insert (SgFunctionDeclaration* func, SgGlobal* scope, SgBasicBlock* outlining_target );

    void appendIndividualFunctionCallArgs (const ASTtools::VarSymSet_t& syms, // all symbols for parameters
                                           const std::set<SgInitializedName*> varUsingOriginalType, // symbols which should be passed using their original types
                                           SgExprListExp* e_list); // the result expression list
    SgStatement* generateCall (SgFunctionDeclaration* out_func,
                              const ASTtools::VarSymSet_t& syms,
                              const std::set<SgInitializedName*> readOnlyVars,
                              std::string wrapper_arg_name,
                              SgScopeStatement* scope);

};

#endif // !defined(INC_LIAOUTLINER_HH)

// eof