OmpAttribute.h

Go to the documentation of this file.
00001 
00009 //
00010 // Liao 9/17, 2008
00011 //
00012 
00013 #include <iostream>
00014 #include <string>
00015 #include <map>
00016 #include <cassert>
00017 #include <vector>
00018 class SgNode;
00019 namespace OmpSupport
00020 {
00021   // OpenMP construct name list
00022   //-------------------------------------------------------------------
00023   // We put all directive and clause types into one enumerate type
00024   // since some internal data structure(map) have to access 
00025   // both directives and clauses uniformly
00026   enum  omp_construct_enum 
00027   {
00028     e_unknown = 0, 
00029 
00030     // 16 directives as OpenMP 3.0
00031     e_parallel,
00032     e_for,
00033     e_do,
00034     e_workshare,
00035     e_sections,
00036     e_section,
00037     e_single,
00038 
00039     e_master, 
00040     e_critical,
00041     e_barrier,
00042     e_atomic,
00043     e_flush,
00044 
00045     e_threadprivate,
00046     e_parallel_for,
00047     e_parallel_do,
00048     e_parallel_sections,
00049     e_parallel_workshare,
00050     e_task,
00051     e_taskwait, 
00052     // we have both ordered directive and ordered clause, 
00053     //so make the name explicit
00054     e_ordered_directive,
00055 
00056     // Fortran only end directives
00057     e_end_critical,
00058     e_end_do,
00059     e_end_master,
00060     e_end_ordered,
00061     e_end_parallel_do,
00062     e_end_parallel_sections,
00063     e_end_parallel_workshare,
00064     e_end_parallel,
00065     e_end_sections,
00066     e_end_single,
00067     e_end_task,
00068     e_end_workshare,
00069 
00070     // 15 clauses for OpenMP 3.0
00071     // 7 data-sharing attributes clauses
00072     e_default, // the clause
00073     e_shared,
00074     e_private,
00075     e_firstprivate,
00076     e_lastprivate,
00077     e_copyin,
00078     e_copyprivate,
00079 
00080     //8 misc clauses
00081     e_if, // used with omp parallel or omp task
00082     e_num_threads, // for omp parallel only
00083     e_nowait,
00084     e_ordered_clause,
00085     e_reduction,
00086     e_schedule,
00087     e_collapse,
00088     e_untied, 
00089 
00090     // Simple values for some clauses
00091 
00092     //4 values for default clause 
00093     //C/C++ default values
00094     e_default_none,
00095     e_default_shared,
00096     //Fortran default values
00097     e_default_private,
00098     e_default_firstprivate,
00099 
00100     // reduction operations
00101     //8 operand for C/C++
00102      //  shared 3 common operators for both C and Fortran
00103     e_reduction_plus, //+
00104     e_reduction_mul,  //* 
00105     e_reduction_minus, // -
00106       // C/C++ only
00107     e_reduction_bitand, // &  
00108     e_reduction_bitor,  // | 
00109     e_reduction_bitxor,  // ^  
00110     e_reduction_logand,  // &&  
00111     e_reduction_logor,   // || 
00112 
00113     // fortran operator
00114     e_reduction_and, // .and.
00115     e_reduction_or, // .or.
00116     e_reduction_eqv,   // fortran .eqv. 
00117     e_reduction_neqv,   // fortran .neqv.
00118     // reduction intrinsic procedure name for Fortran  
00119     e_reduction_max,
00120     e_reduction_min, 
00121     e_reduction_iand,
00122     e_reduction_ior,
00123     e_reduction_ieor,
00124 
00125     //5 schedule policies for
00126     //---------------------
00127     e_schedule_none,
00128     e_schedule_static,
00129     e_schedule_dynamic,
00130     e_schedule_guided,
00131     e_schedule_auto,
00132     e_schedule_runtime,
00133 
00134     // not an OpenMP construct
00135     e_not_omp
00136   }; //end omp_construct_enum
00137 
00138   //-------------------------------------------------------------------
00139   // some utility functions
00140 
00142   // Better using OmpSupport::toString() to avoid ambiguous 
00143   std::string toString(omp_construct_enum omp_type);
00144 
00146   bool isFortranEndDirective(omp_construct_enum omp_type);
00147 
00149   bool isFortranBeginDirective(omp_construct_enum omp_type);
00150 
00152   bool isDirective(omp_construct_enum omp_type);
00153 
00155   bool isDirectiveWithBody(omp_construct_enum omp_type);
00156 
00158   bool isClause(omp_construct_enum omp_type);
00159 
00161   bool isReductionOperator(omp_construct_enum omp_type);
00162 
00163   class OmpAttribute;
00165   //
00167   OmpAttribute* buildOmpAttribute(enum omp_construct_enum directive_type, SgNode* context_node, bool useDefined);
00168 
00170   void addOmpAttribute(OmpAttribute* ompattribute, SgNode* node);
00171 
00173   void removeOmpAttribute(OmpAttribute* ompattribute, SgNode* node);
00174 
00176   bool isEquivalentOmpAttribute (OmpAttribute* a1, OmpAttribute* a2);
00177   
00178   class OmpAttributeList;
00180   OmpAttributeList* getOmpAttributeList(SgNode* node);
00181 
00183   OmpAttribute* getOmpAttribute(SgNode* node);
00184 
00186   omp_construct_enum getOmpConstructEnum(SgPragmaDeclaration* decl);
00187 
00189   omp_construct_enum getBeginOmpConstructEnum (omp_construct_enum end_enum);
00190 
00192   omp_construct_enum getEndOmpConstructEnum (omp_construct_enum begin_enum);
00193 
00195   void generatePragmaFromOmpAttribute(SgNode* sg_node); 
00196   //TODO this is duplicated from autoParallization project's generatedOpenMPPragmas() 
00197   // We should remove this duplicate once autopar is moved into rose/src 
00198   
00200   std::string generateDiffTextFromOmpAttribute(SgNode* sg_node);
00201 
00202   //------------------------------------------------------------------
00203   // By default, the persistent attribute attached to an OpenMP pragma node in SAGE III AST
00204   // Attaching to pragma is easier since a few directives have no obvious 
00205   // associated code blocks, like threadprivate.
00206   //
00207   // The attribute can also be attached by a scope affected by OpenMP. This is used during
00208   // automatic parallelization when the corresponding pragma is not yet generated.
00209   //
00210   // A cure-all approach is used to simplify the handling. 
00211   // OmpAttribute is implemented using a 'flat' data structure encompass all 
00212   // possible directives, clauses
00213   // and their various contents, if any.
00214   //
00215   // different types of pragmas need different information in some cases
00216   // e.g.
00217   //    'omp for' needs scheduling type 
00218   //------------------------------------------------------------------
00219 
00220   class OmpAttributeList :public AstAttribute
00221   {
00222     public:
00223       std::vector<OmpAttribute*> ompAttriList;
00224       // Restore to legal OpenMP directive strings
00225       std::string toOpenMPString();
00226       // Pretty print for debugging purpose
00227       void print();
00228       ~OmpAttributeList();
00229   };                      
00230 
00231   class OmpAttribute
00232   {
00233     public:
00236       SgPragmaDeclaration* getPragmaDeclaration();
00237 
00239       PreprocessingInfo* getPreprocessingInfo() {return pinfo;};
00240       void setPreprocessingInfo(PreprocessingInfo* info) { pinfo=info;};
00241 
00243       SgNode* getNode(){return mNode;};
00244       void setNode(SgNode* n) { mNode= n;};
00246       void setOmpDirectiveType(omp_construct_enum omptype){ assert (isDirective(omptype)); omp_type = omptype;}
00247       omp_construct_enum getOmpDirectiveType() {return omp_type;}
00248 
00251       void addClause(omp_construct_enum clause_type);
00253       bool hasClause(omp_construct_enum clause_type);
00254 
00256       std::vector<omp_construct_enum> getClauses();
00257 
00260       void addVariable(omp_construct_enum targetConstruct, const std::string& varString,SgInitializedName* sgvar=NULL);
00262       bool hasVariableList(omp_construct_enum);
00264       std::vector<std::pair<std::string,SgNode* > > 
00265         getVariableList(omp_construct_enum);
00266 
00268       std::vector<enum omp_construct_enum> get_clauses(const std::string& variable);
00269 
00272       void addExpression(omp_construct_enum targetConstruct, const std::string& expString, SgExpression*    sgexp=NULL); 
00273 
00275       std::pair<std::string, SgExpression*>  
00276         getExpression(omp_construct_enum targetConstruct);
00277 
00279       //
00280       // Reduction needs special handling 
00281       // since multiple ones with different operator types can co-exist within one pragma
00282       // We categories reduction clauses by their operator type and store variable lists for each of the reduction operator type, not with the reduction clause
00283       // Add a new reduction clauses with the specified operator
00284       void setReductionOperator(omp_construct_enum operatorx);
00286       std::vector<omp_construct_enum> getReductionOperators();
00288       bool hasReductionOperator(omp_construct_enum operatorx);
00289 
00290       // default () value
00291       void setDefaultValue(omp_construct_enum valuex);
00292       omp_construct_enum getDefaultValue();
00293 
00294       // Schedule kind
00295       omp_construct_enum getScheduleKind(); 
00296       void setScheduleKind(omp_construct_enum kindx);
00297 
00299       bool isInConstruct(const std::string & variable, enum omp_construct_enum);
00300 
00302       void setCriticalName(const std::string & name);
00303       std::string  getCriticalName() {return name;};
00304       bool isNamedCritical(){return hasName;};
00305 
00307       void print(); 
00308       
00310       bool get_isUserDefined() {return isUserDefined; }
00311 
00313       //not named toString() to void ambiguous with OmpAttribute::toString()
00314       std::string toOpenMPString();
00315     friend  OmpAttribute* buildOmpAttribute(omp_construct_enum directive_type, SgNode* node, bool userDefined);
00316       //------------------hide the implementation details, could be changed anytime!!
00317       //----------------------------------------------------------------------------
00318     private:  
00319       //It is recommended to use OmpSupport::buildOmpAttribute() instead of 
00320       //using the constructors here
00322       OmpAttribute()
00323       {
00324         mNode = NULL;
00325         omp_type = e_unknown;
00326         init();
00327         isUserDefined = true;
00328       }
00330       OmpAttribute(omp_construct_enum omptype, SgNode* mynode):
00331         mNode(mynode),omp_type(omptype){ 
00332           /*The initialization order has to match the declaration order, 
00333            * otherwise get a compilation warning*/
00334           init();
00335           isUserDefined = true;
00336           if (mNode != NULL )
00337           {
00338             SgLocatedNode * lnode = isSgLocatedNode (mNode);
00339             ROSE_ASSERT (lnode != NULL);
00340             //ROSE_ASSERT (lnode->get_file_info()->get_filename()!=std::string("transformation"));
00341           }
00342           // Liao 2/12/2010, we allow build empty attribute as a replacement of a default constructor.
00343           // This is used by autoParallization to tentatively create an instance and later fill data fields.
00344           // assert(isDirective(omptype));
00345         }
00346 
00348       SgNode*  mNode; 
00350       PreprocessingInfo* pinfo;
00351 
00353       bool isUserDefined; 
00354 
00356       enum omp_construct_enum  omp_type; 
00357 
00359       // vector is used to preserve the order of clauses in the directive
00360       // map is used to fast query if a clause exists or not
00361       // Some clauses are allowed to appear more than once, merge the content into the first occurrence in our implementation.
00362       std::vector<omp_construct_enum> clauses;
00363       std::map<omp_construct_enum,bool> clause_map;
00364 
00365       // Multiple reduction clauses, each has a different operator
00366       //value for reduction operation: + -, * & | etc
00367       std::vector<omp_construct_enum> reduction_operators;
00368       //omp_construct_enum reduction_operator;
00369 
00370       //variable lists------------------- 
00371       //appeared within some directives and clauses
00372       //The clauses/directive are: flush, threadprivate, private, firstprivate, 
00373       //  shared, copyin, reduction, lastprivate, copyprivate
00374       // We use a pair of (name, SgNode) for each variable 
00375       // It is highly possible that a variable having more than one OpenMP properties.
00376       // For example, a variable can be both firstprivate and lastprivate.
00377       std::map<omp_construct_enum, std::vector<std::pair<std::string,SgNode* > > > variable_lists; 
00378       // A reverse map from a variable to the clauses the variable appears
00379       std::map<std::string, std::vector<omp_construct_enum> > var_clauses;
00380 
00381       // expressions ----------------------
00382       // e.g.: if (exp), num_threads(exp), schedule(,exp), collapse(exp)
00383       std::map<omp_construct_enum, std::pair<std::string, SgExpression*> > expressions;
00384 
00385       // values for some clauses -------------------------
00386       // values for default() clause: data scoping information
00387       // choices are: none,shared, private, firstprivate
00388       omp_construct_enum default_scope; 
00389 
00390       // value for omp for's schedule policies
00391       omp_construct_enum schedule_kind;
00392 
00393       // Only used for omp critical to indicate if it is named or not
00394       // name for the directive, only used for omp critical
00395       bool hasName; 
00396       std::string name; 
00397 
00398       // Misc fields  --------------------------------
00399       // help translation and analysis   
00400       bool isOrphaned; //true if parent omp parallel is not in the static lexical scope
00401 
00402       // Additional information to help translation
00403       int wrapperCount; // the shared variables from the same scope which needs wrapper
00404 
00405       //optional information
00406       OmpAttribute * parent; //upper-level OMP pragma's attribute
00407 
00410       void init() ;
00411 
00413       // invoke OmpSupport::toString() to stringify the enumerate type internally
00414       std::string toOpenMPString(omp_construct_enum omp_type);
00415 
00417       std::string toOpenMPString(std::vector<std::pair<std::string,SgNode* > >);
00418   }; // end class OmpAttribute
00419 
00420 
00421  // save encountered Fortran OpenMP directives here.
00422  // We reuse the list later on to build OpenMP AST for Fortran
00423   extern std::list<OmpAttribute* > omp_comment_list;
00424 
00425 
00426 } //end namespace OmpSupport

Generated on Wed May 16 06:18:11 2012 for ROSE by  doxygen 1.4.7