Program Listing for File LoopTransformInterface.h

Program Listing for File LoopTransformInterface.h#

Return to documentation for file (src/midend/programTransformation/loopProcessing/driver/LoopTransformInterface.h)

#ifndef LOOP_TRANSFORMATION_INTERFACE_H
#define LOOP_TRANSFORMATION_INTERFACE_H

#include <list>
#include <string>
#include <iostream>
#include "AstInterface.h"
#include "SymbolicVal.h"
#include "AnalysisInterface.h"

/*************
QY: Interface classes used by loop optimizations
**************/
class ArrayAbstractionInterface {
 public:
  virtual bool IsArrayAccess( AstInterface& fa,
                                 const AstNodePtr& s, AstNodePtr* array = 0,
                                 AstInterface::AstNodeList* index = 0) = 0 ;
  virtual bool GetArrayBound( AstInterface& fa,
                                 const AstNodePtr& array,
                                 int dim, int &lb, int &ub) = 0;
  virtual bool IsUniqueArray( AstInterface& fa, const AstNodePtr& array) = 0;
//{ return false; }
  virtual AstNodePtr CreateArrayAccess( AstInterface& fa, const AstNodePtr& arr,
                                const AstNodeList& index) = 0;
  virtual SymbolicVal CreateArrayAccess(
                                const SymbolicVal& arr,
                                const SymbolicVal& index) = 0;
     //{ /*QY: need to be defined by a derived class*/ assert(0); }
  virtual ~ArrayAbstractionInterface() {}
};

class ArrayUseAccessFunction
  : public ArrayAbstractionInterface, public FunctionSideEffectInterface
{
  std::string funcname;
  ArrayAbstractionInterface* prev;
  FunctionSideEffectInterface* prev1;
 public:
  ArrayUseAccessFunction( const std::string& fn, ArrayAbstractionInterface* n = 0,
                           FunctionSideEffectInterface* n1 = 0)
     : funcname(fn), prev(n), prev1(n1) {}
  virtual ~ArrayUseAccessFunction() {}
  virtual bool IsArrayAccess( AstInterface& fa,
                                 const AstNodePtr& s, AstNodePtr* array = 0,
                                 AstInterface::AstNodeList* index = 0) ;
  virtual bool IsUniqueArray( AstInterface& fa, const AstNodePtr& array);
  virtual bool GetArrayBound( AstInterface& fa,
                                 const AstNodePtr& array,
                                 int dim, int &lb, int &ub);
  virtual AstNodePtr CreateArrayAccess( AstInterface& fa, const AstNodePtr& arr,
                                const AstNodeList& index);
  virtual SymbolicVal CreateArrayAccess(
                                const SymbolicVal& arr,
                                const SymbolicVal& index) ;
 // returns false if unknown function encountered
  virtual bool get_modify(AstInterface& fa, const AstNodePtr& fc,
                               CollectObject<AstNodePtr>* collect = 0);
  virtual bool get_read(AstInterface& fa, const AstNodePtr& fc,
                               CollectObject<AstNodePtr>* collect = 0);

};

class AutoTuningInterface ;
/**********
QY: Singular interface class which remembers configurations for loop
    optimizations
***********/
class LoopTransformInterface
{
  static AstInterface* fa;
  static int configIndex;
  static AliasAnalysisInterface* aliasInfo;
  static FunctionSideEffectInterface* funcInfo;
  static ArrayAbstractionInterface* arrayInfo;
  static AutoTuningInterface* tuning;

 public:

  static void set_aliasInfo(AliasAnalysisInterface* alias)
    { aliasInfo= alias; }
  static void set_sideEffectInfo(FunctionSideEffectInterface* func)
    { funcInfo = func; }
  static void set_arrayInfo( ArrayAbstractionInterface* array)
    { arrayInfo = array; }
  static void set_astInterface( AstInterface& _fa);
  static void set_tuningInterface(AutoTuningInterface* _tuning);
  static void cmdline_configure(std::vector<std::string>& argv);

  static AstInterface& getAstInterface() { assert(fa != 0); return *fa; }
  static AliasAnalysisInterface* getAliasInfo() { return aliasInfo; }
  static FunctionSideEffectInterface* getSideEffectInterface()
            { return funcInfo; }
  static AutoTuningInterface* getAutoTuningInterface() { return tuning; }

  static bool IsAliasedRef( const AstNodePtr& r1, const AstNodePtr& r2)
    { assert(fa != 0 && aliasInfo!=0); return aliasInfo->may_alias(*fa, r1, r2); }
  static bool GetFunctionCallSideEffect( const AstNodePtr& fc,
                     CollectObject<AstNodePtr>& collectmod,
                     CollectObject<AstNodePtr>& collectread);

  static bool IsMemoryAccess( const AstNodePtr& s)
   { assert(fa != 0);
     return (arrayInfo != 0 && arrayInfo->IsArrayAccess(*fa, s)) ||
            fa->IsMemoryAccess(s); }
  static bool IsLoop( const AstNodePtr& s,
                       SymbolicVal* init = 0, SymbolicVal* cond=0,
                       SymbolicVal* incr =0, AstNodePtr* body=0);
  static bool IsUniqueArray(const AstNodePtr& array)
   { assert(fa!=0);
     return arrayInfo!=0 && arrayInfo->IsUniqueArray(*fa, array); }
  static bool IsArrayAccess( const AstNodePtr& s, AstNodePtr* array = 0,
                                   AstInterface::AstNodeList* index = 0)
   { assert(fa != 0);
     return (arrayInfo != 0 && arrayInfo->IsArrayAccess(*fa, s, array, index))
            || fa->IsArrayAccess(s, array, index); }

  static AstNodePtr CreateArrayAccess( const AstNodePtr& arr,
                                AstInterface::AstList& index) ;
  static AstNodePtr CreateArrayAccess(const std::string& arrname,
                            const std::vector<SymbolicVal>& arrindex);
  static bool GetArrayBound( const AstNodePtr& array,int dim, int &lb, int &ub)
  { assert(fa!=0);
    if (arrayInfo != 0 && arrayInfo->IsArrayAccess(*fa, array))
      return arrayInfo->GetArrayBound(*fa, array, dim, lb, ub);
    return fa->GetArrayBound(array, dim, lb, ub);
  }

  static AstNodePtr CreateDynamicFusionConfig( const AstNodePtr& groupNum,
                                        AstInterface::AstNodeList& args, int &id);
  static AstNodePtr CreateDynamicFusionEnd( int id);
  static bool IsDynamicFusionConfig( const AstNodePtr& n, AstNodePtr* configvar = 0,
                                 int* configID = 0, AstInterface::AstNodeList* params = 0);
  static bool IsDynamicFusionEnd(const AstNodePtr& n);

  /*************
   QY: apply transformations to head; return the transformation result
  ************/
  static AstNodePtr
  TransformTraverse( AstInterfaceImpl& scope, const AstNodePtr& head);

  static void PrintTransformUsage( std::ostream& out);
};


/* normalize the forloops in C
  i<x is normalized to i<= (x-1)
  i>x is normalized to i>= (x+1)

  i++ is normalized to i=i+1
  i-- is normalized to i=i-1
*/
void NormalizeForLoop (AstInterface& fa, const AstNodePtr& head) ;


#endif