@@ -149,24 +149,7 @@ template <typename T> class DirectiveAttributeVisitor {
149149    dataSharingAttributeObjects_.clear ();
150150  }
151151  bool  HasDataSharingAttributeObject (const  Symbol &);
152- 
153-   // / Extract the iv and bounds of a DO loop:
154-   // / 1. The loop index/induction variable
155-   // / 2. The lower bound
156-   // / 3. The upper bound
157-   // / 4. The step/increment (or nullptr if not present)
158-   // /
159-   // / Each returned tuple value can be nullptr if not present. Diagnoses an
160-   // / error if the the DO loop is a DO WHILE or DO CONCURRENT loop.
161-   std::tuple<const  parser::Name *, const  parser::ScalarExpr *,
162-       const  parser::ScalarExpr *, const  parser::ScalarExpr *>
163-   GetLoopBounds (const  parser::DoConstruct &);
164- 
165-   // / Extract the loop index/induction variable from a DO loop. Diagnoses an
166-   // / error if the the DO loop is a DO WHILE or DO CONCURRENT loop and returns
167-   // / nullptr.
168152  const  parser::Name *GetLoopIndex (const  parser::DoConstruct &);
169- 
170153  const  parser::DoConstruct *GetDoConstructIf (
171154      const  parser::ExecutionPartConstruct &);
172155  Symbol *DeclareNewAccessEntity (const  Symbol &, Symbol::Flag, Scope &);
@@ -970,13 +953,6 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
970953    privateDataSharingAttributeObjects_.clear ();
971954  }
972955
973-   // / Check that loops in the loop nest are perfectly nested, as well that lower
974-   // / bound, upper bound, and step expressions do not use the iv
975-   // / of a surrounding loop of the associated loops nest.
976-   // / We do not support non-perfectly nested loops not non-rectangular loops yet
977-   // / (both introduced in OpenMP 5.0)
978-   void  CheckPerfectNestAndRectangularLoop (const  parser::OpenMPLoopConstruct &x);
979- 
980956  //  Predetermined DSA rules
981957  void  PrivatizeAssociatedLoopIndexAndCheckLoopLevel (
982958      const  parser::OpenMPLoopConstruct &);
@@ -1052,30 +1028,23 @@ bool DirectiveAttributeVisitor<T>::HasDataSharingAttributeObject(
10521028}
10531029
10541030template  <typename  T>
1055- std::tuple<const  parser::Name *, const  parser::ScalarExpr *,
1056-     const  parser::ScalarExpr *, const  parser::ScalarExpr *>
1057- DirectiveAttributeVisitor<T>::GetLoopBounds(const  parser::DoConstruct &x) {
1031+ const  parser::Name *DirectiveAttributeVisitor<T>::GetLoopIndex(
1032+     const  parser::DoConstruct &x) {
10581033  using  Bounds = parser::LoopControl::Bounds;
10591034  if  (x.GetLoopControl ()) {
10601035    if  (const  Bounds * b{std::get_if<Bounds>(&x.GetLoopControl ()->u )}) {
1061-       auto  &step =  b->step ;
1062-        return  {&b-> name . thing , &b-> lower , &b-> upper , 
1063-           step. has_value () ? &step. value () :  nullptr } ;
1036+       return  & b->name . thing ;
1037+     }  else  { 
1038+       return   nullptr ;
10641039    }
10651040  } else  {
10661041    context_
10671042        .Say (std::get<parser::Statement<parser::NonLabelDoStmt>>(x.t ).source ,
10681043            " Loop control is not present in the DO LOOP" 
10691044        .Attach (GetContext ().directiveSource ,
10701045            " associated with the enclosing LOOP construct" 
1046+     return  nullptr ;
10711047  }
1072-   return  {nullptr , nullptr , nullptr , nullptr };
1073- }
1074- 
1075- template  <typename  T>
1076- const  parser::Name *DirectiveAttributeVisitor<T>::GetLoopIndex(
1077-     const  parser::DoConstruct &x) {
1078-   return  std::get<const  parser::Name *>(GetLoopBounds (x));
10791048}
10801049
10811050template  <typename  T>
@@ -2021,10 +1990,6 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
20211990      }
20221991    }
20231992  }
2024- 
2025-   //  Must be done before iv privatization
2026-   CheckPerfectNestAndRectangularLoop (x);
2027- 
20281993  PrivatizeAssociatedLoopIndexAndCheckLoopLevel (x);
20291994  ordCollapseLevel = GetNumAffectedLoopsFromLoopConstruct (x) + 1 ;
20301995  return  true ;
@@ -2220,116 +2185,6 @@ void OmpAttributeVisitor::CollectNumAffectedLoopsFromClauses(
22202185  }
22212186}
22222187
2223- void  OmpAttributeVisitor::CheckPerfectNestAndRectangularLoop (
2224-     const  parser::OpenMPLoopConstruct &x) {
2225-   auto  &dirContext{GetContext ()};
2226-   std::int64_t  dirDepth{dirContext.associatedLoopLevel };
2227-   if  (dirDepth <= 0 )
2228-     return ;
2229- 
2230-   auto  checkExprHasSymbols = [&](llvm::SmallVector<Symbol *> &ivs,
2231-                                  const  parser::ScalarExpr *bound) {
2232-     if  (ivs.empty ())
2233-       return ;
2234-     auto  boundExpr{semantics::AnalyzeExpr (context_, *bound)};
2235-     if  (!boundExpr)
2236-       return ;
2237-     semantics::UnorderedSymbolSet boundSyms{
2238-         evaluate::CollectSymbols (*boundExpr)};
2239-     if  (boundSyms.empty ())
2240-       return ;
2241-     for  (Symbol *iv : ivs) {
2242-       if  (boundSyms.count (*iv) != 0 ) {
2243-         //  TODO: Point to occurence of iv in boundExpr, directiveSource as a
2244-         //        note
2245-         context_.Say (dirContext.directiveSource ,
2246-             " Trip count must be computable and invariant" 
2247-       }
2248-     }
2249-   };
2250- 
2251-   //  Find the associated region by skipping nested loop-associated constructs
2252-   //  such as loop transformations
2253-   const  parser::NestedConstruct *innermostAssocRegion{nullptr };
2254-   const  parser::OpenMPLoopConstruct *innermostConstruct{&x};
2255-   while  (const  auto  &innerAssocStmt{
2256-       std::get<std::optional<parser::NestedConstruct>>(
2257-           innermostConstruct->t )}) {
2258-     innermostAssocRegion = &(innerAssocStmt.value ());
2259-     if  (const  auto  *innerConstruct{
2260-             std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
2261-                 innermostAssocRegion)}) {
2262-       innermostConstruct = &innerConstruct->value ();
2263-     } else  {
2264-       break ;
2265-     }
2266-   }
2267- 
2268-   if  (!innermostAssocRegion)
2269-     return ;
2270-   const  auto  &outer{std::get_if<parser::DoConstruct>(innermostAssocRegion)};
2271-   if  (!outer)
2272-     return ;
2273- 
2274-   llvm::SmallVector<Symbol *> ivs;
2275-   int  curLevel{0 };
2276-   const  parser::DoConstruct *loop{outer};
2277-   while  (true ) {
2278-     auto  [iv, lb, ub, step] = GetLoopBounds (*loop);
2279- 
2280-     if  (lb)
2281-       checkExprHasSymbols (ivs, lb);
2282-     if  (ub)
2283-       checkExprHasSymbols (ivs, ub);
2284-     if  (step)
2285-       checkExprHasSymbols (ivs, step);
2286-     if  (iv) {
2287-       if  (auto  *symbol{currScope ().FindSymbol (iv->source )})
2288-         ivs.push_back (symbol);
2289-     }
2290- 
2291-     //  Stop after processing all affected loops
2292-     if  (curLevel + 1  >= dirDepth)
2293-       break ;
2294- 
2295-     //  Recurse into nested loop
2296-     const  auto  &block{std::get<parser::Block>(loop->t )};
2297-     if  (block.empty ()) {
2298-       //  Insufficient number of nested loops already reported by
2299-       //  CheckAssocLoopLevel()
2300-       break ;
2301-     }
2302- 
2303-     loop = GetDoConstructIf (block.front ());
2304-     if  (!loop) {
2305-       //  Insufficient number of nested loops already reported by
2306-       //  CheckAssocLoopLevel()
2307-       break ;
2308-     }
2309- 
2310-     auto  checkPerfectNest = [&, this ]() {
2311-       auto  blockSize = block.size ();
2312-       if  (blockSize <= 1 )
2313-         return ;
2314- 
2315-       if  (parser::Unwrap<parser::ContinueStmt>(x))
2316-         blockSize -= 1 ;
2317- 
2318-       if  (blockSize <= 1 )
2319-         return ;
2320- 
2321-       //  Non-perfectly nested loop
2322-       //  TODO: Point to non-DO statement, directiveSource as a note
2323-       context_.Say (dirContext.directiveSource ,
2324-           " Canonical loop nest must be perfectly nested." 
2325-     };
2326- 
2327-     checkPerfectNest ();
2328- 
2329-     ++curLevel;
2330-   }
2331- }
2332- 
23332188//  2.15.1.1 Data-sharing Attribute Rules - Predetermined
23342189//    - The loop iteration variable(s) in the associated do-loop(s) of a do,
23352190//      parallel do, taskloop, or distribute construct is (are) private.
0 commit comments