ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OmpAttribute.h
Go to the documentation of this file.
1 
9 //
10 // Liao 9/17, 2008
11 //
12 
13 #include <iostream>
14 #include <string>
15 #include <map>
16 #include <cassert>
17 #include <vector>
18 class SgNode;
19 namespace OmpSupport
20 {
21  // OpenMP construct name list
22  //-------------------------------------------------------------------
23  // We put all directive and clause types into one enumerate type
24  // since some internal data structure(map) have to access
25  // both directives and clauses uniformly
27  {
28  e_unknown = 0,
29 
30  // 16 directives as OpenMP 3.0
38 
44 
45  // Liao, 1/15/2013, experimental implementation for the draft OpenMP Accelerator Model technical report
50  e_map, // map clauses
52 
60  // we have both ordered directive and ordered clause,
61  //so make the name explicit
63 
64  // Fortran only end directives
77 
78  // 15 clauses for OpenMP 3.0
79  // 7 data-sharing attributes clauses
80  e_default, // the clause
87 
88  //8 misc clauses
89  e_if, // used with omp parallel or omp task
90  e_num_threads, // for omp parallel only
97 
98  // Simple values for some clauses
99 
100  //4 values for default clause
101  //C/C++ default values
104  //Fortran default values
107 
108  // reduction operations
109  //8 operand for C/C++
110  // shared 3 common operators for both C and Fortran
114  // C/C++ only
120 
121  // fortran operator
122  e_reduction_and, // .and.
123  e_reduction_or, // .or.
124  e_reduction_eqv, // fortran .eqv.
125  e_reduction_neqv, // fortran .neqv.
126  // reduction intrinsic procedure name for Fortran
132 
133  //5 schedule policies for
134  //---------------------
141 
142  // 4 device map variants
143  //----------------------
148 
149  // experimental SIMD directive, phlin 8/5/2013
155 
156  // not an OpenMP construct
158 
159  }; //end omp_construct_enum
160 
161  //-------------------------------------------------------------------
162  // some utility functions
163 
165  // Better using OmpSupport::toString() to avoid ambiguous
166  std::string toString(omp_construct_enum omp_type);
167 
170 
173 
175  bool isDirective(omp_construct_enum omp_type);
176 
179 
181  bool isClause(omp_construct_enum omp_type);
182 
185 
186  class OmpAttribute;
188  //
190  ROSE_DLL_API OmpAttribute* buildOmpAttribute(enum omp_construct_enum directive_type, SgNode* context_node, bool useDefined);
191 
193  ROSE_DLL_API void addOmpAttribute(OmpAttribute* ompattribute, SgNode* node);
194 
196  ROSE_DLL_API void removeOmpAttribute(OmpAttribute* ompattribute, SgNode* node);
197 
199  ROSE_DLL_API bool isEquivalentOmpAttribute (OmpAttribute* a1, OmpAttribute* a2);
200 
201  class OmpAttributeList;
203  ROSE_DLL_API OmpAttributeList* getOmpAttributeList(SgNode* node);
204 
206  OmpAttribute* getOmpAttribute(SgNode* node);
207 
210 
213 
216 
219  //TODO this is duplicated from autoParallization project's generatedOpenMPPragmas()
220  // We should remove this duplicate once autopar is moved into rose/src
221 
224 
225  //------------------------------------------------------------------
226  // By default, the persistent attribute attached to an OpenMP pragma node in SAGE III AST
227  // Attaching to pragma is easier since a few directives have no obvious
228  // associated code blocks, like threadprivate.
229  //
230  // The attribute can also be attached by a scope affected by OpenMP. This is used during
231  // automatic parallelization when the corresponding pragma is not yet generated.
232  //
233  // A cure-all approach is used to simplify the handling.
234  // OmpAttribute is implemented using a 'flat' data structure encompass all
235  // possible directives, clauses
236  // and their various contents, if any.
237  //
238  // different types of pragmas need different information in some cases
239  // e.g.
240  // 'omp for' needs scheduling type
241  //------------------------------------------------------------------
242 
244  {
245  public:
246  std::vector<OmpAttribute*> ompAttriList;
247  // Restore to legal OpenMP directive strings
248  std::string toOpenMPString();
249  // Pretty print for debugging purpose
250  void print();
251  ~OmpAttributeList();
252  };
253 
254  // One attribute object stores all information within an OpenMP pragma (directive and clauses)
256  {
257  public:
260  SgPragmaDeclaration* getPragmaDeclaration();
261 
264  void setPreprocessingInfo(PreprocessingInfo* info) { pinfo=info;};
265 
267  SgNode* getNode(){return mNode;};
268  void setNode(SgNode* n) { mNode= n;};
270  void setOmpDirectiveType(omp_construct_enum omptype){ assert (isDirective(omptype)); omp_type = omptype;}
272 
275  void addClause(omp_construct_enum clause_type);
277  bool hasClause(omp_construct_enum clause_type);
278 
280  std::vector<omp_construct_enum> getClauses();
281 
284  SgVariableSymbol* addVariable(omp_construct_enum targetConstruct, const std::string& varString, SgInitializedName* sgvar=NULL);
286  bool hasVariableList(omp_construct_enum);
288  std::vector<std::pair<std::string,SgNode* > >
289  getVariableList(omp_construct_enum);
290 
292  // We store a list (vector) of dimension bounds for each array variable
293  std::map<SgSymbol*, std::vector < std::pair <SgExpression*, SgExpression*> > > array_dimensions;
294 
296  std::vector<enum omp_construct_enum> get_clauses(const std::string& variable);
297 
300  void addExpression(omp_construct_enum targetConstruct, const std::string& expString, SgExpression* sgexp=NULL);
301 
303  std::pair<std::string, SgExpression*>
304  getExpression(omp_construct_enum targetConstruct);
305 
307  //
308  // Reduction needs special handling
309  // since multiple ones with different operator types can co-exist within one pragma
310  // We categories reduction clauses by their operator type and store variable lists for each of the reduction operator type, not with the reduction clause
311  // Add a new reduction clauses with the specified operator
312  void setReductionOperator(omp_construct_enum operatorx);
314  std::vector<omp_construct_enum> getReductionOperators();
316  bool hasReductionOperator(omp_construct_enum operatorx);
317 
318  // map clause is similar to reduction clause,
319  //
320  // Add a new map clauses with the specified variant type
321  void setMapVariant(omp_construct_enum operatorx);
323  std::vector<omp_construct_enum> getMapVariants();
325  bool hasMapVariant(omp_construct_enum operatorx);
326 
328  bool isMapVariant(omp_construct_enum omp_type);
329 
330  // default () value
331  void setDefaultValue(omp_construct_enum valuex);
332  omp_construct_enum getDefaultValue();
333 
334  // Schedule kind
335  omp_construct_enum getScheduleKind();
336  void setScheduleKind(omp_construct_enum kindx);
337 
339  bool isInConstruct(const std::string & variable, enum omp_construct_enum);
340 
342  void setCriticalName(const std::string & name);
343  std::string getCriticalName() {return name;};
344  bool isNamedCritical(){return hasName;};
345 
347  void print();
348 
350  bool get_isUserDefined() {return isUserDefined; }
351 
353  //not named toString() to void ambiguous with OmpAttribute::toString()
354  std::string toOpenMPString();
355  friend OmpAttribute* buildOmpAttribute(omp_construct_enum directive_type, SgNode* node, bool userDefined);
356  //------------------hide the implementation details, could be changed anytime!!
357  //----------------------------------------------------------------------------
358  private:
359  //It is recommended to use OmpSupport::buildOmpAttribute() instead of
360  //using the constructors here
363  {
364  mNode = NULL;
365  omp_type = e_unknown;
366  init();
367  isUserDefined = true;
368  }
371  mNode(mynode),omp_type(omptype){
372  /*The initialization order has to match the declaration order,
373  * otherwise get a compilation warning*/
374  init();
375  isUserDefined = true;
376  if (mNode != NULL )
377  {
378  SgLocatedNode * lnode = isSgLocatedNode (mNode);
379  ROSE_ASSERT (lnode != NULL);
380  //ROSE_ASSERT (lnode->get_file_info()->get_filename()!=std::string("transformation"));
381  }
382  // Liao 2/12/2010, we allow build empty attribute as a replacement of a default constructor.
383  // This is used by autoParallization to tentatively create an instance and later fill data fields.
384  // assert(isDirective(omptype));
385  }
386 
391 
394 
396  enum omp_construct_enum omp_type;
397 
399  // vector is used to preserve the order of clauses in the directive
400  // map is used to fast query if a clause exists or not
401  // Some clauses are allowed to appear more than once, merge the content into the first occurrence in our implementation.
402  std::vector<omp_construct_enum> clauses;
403  std::map<omp_construct_enum,bool> clause_map;
404 
405  // Multiple reduction clauses, each has a different operator
406  //value for reduction operation: + -, * & | etc
407  std::vector<omp_construct_enum> reduction_operators;
408  //omp_construct_enum reduction_operator;
409 
410  // Liao, 1/15/2013, map variant:
411  // there could be multiple map clause with the same variant type: alloc, in, out , and inout.
412  std::vector<omp_construct_enum> map_variants;
413  //enum omp_construct_enum map_variant;
414 
415  //variable lists-------------------
416  //appeared within some directives and clauses
417  //The clauses/directive are: flush, threadprivate, private, firstprivate,
418  // shared, copyin, reduction, lastprivate, copyprivate
419  // We use a pair of (name, SgNode) for each variable
420  // It is highly possible that a variable having more than one OpenMP properties.
421  // For example, a variable can be both firstprivate and lastprivate.
422  std::map<omp_construct_enum, std::vector<std::pair<std::string,SgNode* > > > variable_lists;
423  // A reverse map from a variable to the clauses the variable appears
424  std::map<std::string, std::vector<omp_construct_enum> > var_clauses;
425 
426  // expressions ----------------------
427  // e.g.: if (exp), num_threads(exp), schedule(,exp), collapse(exp)
428  std::map<omp_construct_enum, std::pair<std::string, SgExpression*> > expressions;
429 
430  // values for some clauses -------------------------
431  // values for default() clause: data scoping information
432  // choices are: none,shared, private, firstprivate
434 
435  // value for omp for's schedule policies
437 
438  // Only used for omp critical to indicate if it is named or not
439  // name for the directive, only used for omp critical
440  bool hasName;
441  std::string name;
442 
443  // Misc fields --------------------------------
444  // help translation and analysis
445  bool isOrphaned; //true if parent omp parallel is not in the static lexical scope
446 
447  // Additional information to help translation
448  int wrapperCount; // the shared variables from the same scope which needs wrapper
449 
450  //optional information
451  OmpAttribute * parent; //upper-level OMP pragma's attribute
452 
455  void init() ;
456 
458  // invoke OmpSupport::toString() to stringify the enumerate type internally
459  std::string toOpenMPString(omp_construct_enum omp_type);
460 
462  std::string toOpenMPString(std::vector<std::pair<std::string,SgNode* > >);
463  }; // end class OmpAttribute
464 
465 
466  // save encountered Fortran OpenMP directives here.
467  // We reuse the list later on to build OpenMP AST for Fortran
468  extern std::list<OmpAttribute* > omp_comment_list;
469 
470 
471 } //end namespace OmpSupport