@@ -1657,50 +1657,51 @@ OpenMPDirectiveKind
1657
1657
CodeGenFunction::EmitSections (const OMPExecutableDirective &S) {
1658
1658
auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt ())->getCapturedStmt ();
1659
1659
auto *CS = dyn_cast<CompoundStmt>(Stmt);
1660
- if (CS && CS->size () > 1 ) {
1661
- bool HasLastprivates = false ;
1662
- auto &&CodeGen = [&S, CS, &HasLastprivates](CodeGenFunction &CGF) {
1663
- auto &C = CGF.CGM .getContext ();
1664
- auto KmpInt32Ty = C.getIntTypeForBitwidth (/* DestWidth=*/ 32 , /* Signed=*/ 1 );
1665
- // Emit helper vars inits.
1666
- LValue LB = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.lb." ,
1667
- CGF.Builder .getInt32 (0 ));
1668
- auto *GlobalUBVal = CGF.Builder .getInt32 (CS->size () - 1 );
1669
- LValue UB =
1670
- createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.ub." , GlobalUBVal);
1671
- LValue ST = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.st." ,
1672
- CGF.Builder .getInt32 (1 ));
1673
- LValue IL = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.il." ,
1674
- CGF.Builder .getInt32 (0 ));
1675
- // Loop counter.
1676
- LValue IV = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.iv." );
1677
- OpaqueValueExpr IVRefExpr (S.getLocStart (), KmpInt32Ty, VK_LValue);
1678
- CodeGenFunction::OpaqueValueMapping OpaqueIV (CGF, &IVRefExpr, IV);
1679
- OpaqueValueExpr UBRefExpr (S.getLocStart (), KmpInt32Ty, VK_LValue);
1680
- CodeGenFunction::OpaqueValueMapping OpaqueUB (CGF, &UBRefExpr, UB);
1681
- // Generate condition for loop.
1682
- BinaryOperator Cond (&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy , VK_RValue,
1683
- OK_Ordinary, S.getLocStart (),
1684
- /* fpContractable=*/ false );
1685
- // Increment for loop counter.
1686
- UnaryOperator Inc (&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue,
1687
- OK_Ordinary, S.getLocStart ());
1688
- auto BodyGen = [CS, &S, &IV](CodeGenFunction &CGF) {
1689
- // Iterate through all sections and emit a switch construct:
1690
- // switch (IV) {
1691
- // case 0:
1692
- // <SectionStmt[0]>;
1693
- // break;
1694
- // ...
1695
- // case <NumSection> - 1:
1696
- // <SectionStmt[<NumSection> - 1]>;
1697
- // break;
1698
- // }
1699
- // .omp.sections.exit:
1700
- auto *ExitBB = CGF.createBasicBlock (" .omp.sections.exit" );
1701
- auto *SwitchStmt = CGF.Builder .CreateSwitch (
1702
- CGF.EmitLoadOfLValue (IV, S.getLocStart ()).getScalarVal (), ExitBB,
1703
- CS->size ());
1660
+ bool HasLastprivates = false ;
1661
+ auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF) {
1662
+ auto &C = CGF.CGM .getContext ();
1663
+ auto KmpInt32Ty = C.getIntTypeForBitwidth (/* DestWidth=*/ 32 , /* Signed=*/ 1 );
1664
+ // Emit helper vars inits.
1665
+ LValue LB = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.lb." ,
1666
+ CGF.Builder .getInt32 (0 ));
1667
+ auto *GlobalUBVal = CS != nullptr ? CGF.Builder .getInt32 (CS->size () - 1 )
1668
+ : CGF.Builder .getInt32 (0 );
1669
+ LValue UB =
1670
+ createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.ub." , GlobalUBVal);
1671
+ LValue ST = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.st." ,
1672
+ CGF.Builder .getInt32 (1 ));
1673
+ LValue IL = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.il." ,
1674
+ CGF.Builder .getInt32 (0 ));
1675
+ // Loop counter.
1676
+ LValue IV = createSectionLVal (CGF, KmpInt32Ty, " .omp.sections.iv." );
1677
+ OpaqueValueExpr IVRefExpr (S.getLocStart (), KmpInt32Ty, VK_LValue);
1678
+ CodeGenFunction::OpaqueValueMapping OpaqueIV (CGF, &IVRefExpr, IV);
1679
+ OpaqueValueExpr UBRefExpr (S.getLocStart (), KmpInt32Ty, VK_LValue);
1680
+ CodeGenFunction::OpaqueValueMapping OpaqueUB (CGF, &UBRefExpr, UB);
1681
+ // Generate condition for loop.
1682
+ BinaryOperator Cond (&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy , VK_RValue,
1683
+ OK_Ordinary, S.getLocStart (),
1684
+ /* fpContractable=*/ false );
1685
+ // Increment for loop counter.
1686
+ UnaryOperator Inc (&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
1687
+ S.getLocStart ());
1688
+ auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) {
1689
+ // Iterate through all sections and emit a switch construct:
1690
+ // switch (IV) {
1691
+ // case 0:
1692
+ // <SectionStmt[0]>;
1693
+ // break;
1694
+ // ...
1695
+ // case <NumSection> - 1:
1696
+ // <SectionStmt[<NumSection> - 1]>;
1697
+ // break;
1698
+ // }
1699
+ // .omp.sections.exit:
1700
+ auto *ExitBB = CGF.createBasicBlock (" .omp.sections.exit" );
1701
+ auto *SwitchStmt = CGF.Builder .CreateSwitch (
1702
+ CGF.EmitLoadOfLValue (IV, S.getLocStart ()).getScalarVal (), ExitBB,
1703
+ CS == nullptr ? 1 : CS->size ());
1704
+ if (CS) {
1704
1705
unsigned CaseNumber = 0 ;
1705
1706
for (auto *SubStmt : CS->children ()) {
1706
1707
auto CaseBB = CGF.createBasicBlock (" .omp.sections.case" );
@@ -1710,103 +1711,72 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
1710
1711
CGF.EmitBranch (ExitBB);
1711
1712
++CaseNumber;
1712
1713
}
1713
- CGF.EmitBlock (ExitBB, /* IsFinished=*/ true );
1714
- };
1715
-
1716
- CodeGenFunction::OMPPrivateScope LoopScope (CGF);
1717
- if (CGF.EmitOMPFirstprivateClause (S, LoopScope)) {
1718
- // Emit implicit barrier to synchronize threads and avoid data races on
1719
- // initialization of firstprivate variables.
1720
- CGF.CGM .getOpenMPRuntime ().emitBarrierCall (
1721
- CGF, S.getLocStart (), OMPD_unknown, /* EmitChecks=*/ false ,
1722
- /* ForceSimpleCall=*/ true );
1714
+ } else {
1715
+ auto CaseBB = CGF.createBasicBlock (" .omp.sections.case" );
1716
+ CGF.EmitBlock (CaseBB);
1717
+ SwitchStmt->addCase (CGF.Builder .getInt32 (0 ), CaseBB);
1718
+ CGF.EmitStmt (Stmt);
1719
+ CGF.EmitBranch (ExitBB);
1723
1720
}
1724
- CGF.EmitOMPPrivateClause (S, LoopScope);
1725
- HasLastprivates = CGF.EmitOMPLastprivateClauseInit (S, LoopScope);
1726
- CGF.EmitOMPReductionClauseInit (S, LoopScope);
1727
- (void )LoopScope.Privatize ();
1728
-
1729
- // Emit static non-chunked loop.
1730
- CGF.CGM .getOpenMPRuntime ().emitForStaticInit (
1731
- CGF, S.getLocStart (), OMPC_SCHEDULE_static, /* IVSize=*/ 32 ,
1732
- /* IVSigned=*/ true , /* Ordered=*/ false , IL.getAddress (),
1733
- LB.getAddress (), UB.getAddress (), ST.getAddress ());
1734
- // UB = min(UB, GlobalUB);
1735
- auto *UBVal = CGF.EmitLoadOfScalar (UB, S.getLocStart ());
1736
- auto *MinUBGlobalUB = CGF.Builder .CreateSelect (
1737
- CGF.Builder .CreateICmpSLT (UBVal, GlobalUBVal), UBVal, GlobalUBVal);
1738
- CGF.EmitStoreOfScalar (MinUBGlobalUB, UB);
1739
- // IV = LB;
1740
- CGF.EmitStoreOfScalar (CGF.EmitLoadOfScalar (LB, S.getLocStart ()), IV);
1741
- // while (idx <= UB) { BODY; ++idx; }
1742
- CGF.EmitOMPInnerLoop (S, /* RequiresCleanup=*/ false , &Cond, &Inc, BodyGen,
1743
- [](CodeGenFunction &) {});
1744
- // Tell the runtime we are done.
1745
- CGF.CGM .getOpenMPRuntime ().emitForStaticFinish (CGF, S.getLocStart ());
1746
- CGF.EmitOMPReductionClauseFinal (S);
1747
-
1748
- // Emit final copy of the lastprivate variables if IsLastIter != 0.
1749
- if (HasLastprivates)
1750
- CGF.EmitOMPLastprivateClauseFinal (
1751
- S, CGF.Builder .CreateIsNotNull (
1752
- CGF.EmitLoadOfScalar (IL, S.getLocStart ())));
1721
+ CGF.EmitBlock (ExitBB, /* IsFinished=*/ true );
1753
1722
};
1754
1723
1755
- bool HasCancel = false ;
1756
- if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
1757
- HasCancel = OSD->hasCancel ();
1758
- else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
1759
- HasCancel = OPSD->hasCancel ();
1760
- CGM.getOpenMPRuntime ().emitInlinedDirective (*this , OMPD_sections, CodeGen,
1761
- HasCancel);
1762
- // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
1763
- // clause. Otherwise the barrier will be generated by the codegen for the
1764
- // directive.
1765
- if (HasLastprivates && S.getSingleClause <OMPNowaitClause>()) {
1724
+ CodeGenFunction::OMPPrivateScope LoopScope (CGF);
1725
+ if (CGF.EmitOMPFirstprivateClause (S, LoopScope)) {
1766
1726
// Emit implicit barrier to synchronize threads and avoid data races on
1767
1727
// initialization of firstprivate variables.
1768
- CGM.getOpenMPRuntime ().emitBarrierCall (*this , S.getLocStart (),
1769
- OMPD_unknown);
1728
+ CGF.CGM .getOpenMPRuntime ().emitBarrierCall (
1729
+ CGF, S.getLocStart (), OMPD_unknown, /* EmitChecks=*/ false ,
1730
+ /* ForceSimpleCall=*/ true );
1770
1731
}
1771
- return OMPD_sections;
1772
- }
1773
- // If only one section is found - no need to generate loop, emit as a single
1774
- // region.
1775
- bool HasFirstprivates;
1776
- // No need to generate reductions for sections with single section region, we
1777
- // can use original shared variables for all operations.
1778
- bool HasReductions = S.hasClausesOfKind <OMPReductionClause>();
1779
- // No need to generate lastprivates for sections with single section region,
1780
- // we can use original shared variable for all calculations with barrier at
1781
- // the end of the sections.
1782
- bool HasLastprivates = S.hasClausesOfKind <OMPLastprivateClause>();
1783
- auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) {
1784
- CodeGenFunction::OMPPrivateScope SingleScope (CGF);
1785
- HasFirstprivates = CGF.EmitOMPFirstprivateClause (S, SingleScope);
1786
- CGF.EmitOMPPrivateClause (S, SingleScope);
1787
- (void )SingleScope.Privatize ();
1732
+ CGF.EmitOMPPrivateClause (S, LoopScope);
1733
+ HasLastprivates = CGF.EmitOMPLastprivateClauseInit (S, LoopScope);
1734
+ CGF.EmitOMPReductionClauseInit (S, LoopScope);
1735
+ (void )LoopScope.Privatize ();
1736
+
1737
+ // Emit static non-chunked loop.
1738
+ CGF.CGM .getOpenMPRuntime ().emitForStaticInit (
1739
+ CGF, S.getLocStart (), OMPC_SCHEDULE_static, /* IVSize=*/ 32 ,
1740
+ /* IVSigned=*/ true , /* Ordered=*/ false , IL.getAddress (), LB.getAddress (),
1741
+ UB.getAddress (), ST.getAddress ());
1742
+ // UB = min(UB, GlobalUB);
1743
+ auto *UBVal = CGF.EmitLoadOfScalar (UB, S.getLocStart ());
1744
+ auto *MinUBGlobalUB = CGF.Builder .CreateSelect (
1745
+ CGF.Builder .CreateICmpSLT (UBVal, GlobalUBVal), UBVal, GlobalUBVal);
1746
+ CGF.EmitStoreOfScalar (MinUBGlobalUB, UB);
1747
+ // IV = LB;
1748
+ CGF.EmitStoreOfScalar (CGF.EmitLoadOfScalar (LB, S.getLocStart ()), IV);
1749
+ // while (idx <= UB) { BODY; ++idx; }
1750
+ CGF.EmitOMPInnerLoop (S, /* RequiresCleanup=*/ false , &Cond, &Inc, BodyGen,
1751
+ [](CodeGenFunction &) {});
1752
+ // Tell the runtime we are done.
1753
+ CGF.CGM .getOpenMPRuntime ().emitForStaticFinish (CGF, S.getLocStart ());
1754
+ CGF.EmitOMPReductionClauseFinal (S);
1788
1755
1789
- auto Exit = CGF. getJumpDestInCurrentScope ( " omp.sections.exit " );
1790
- CGF. BreakContinueStack . push_back ( BreakContinue (Exit, Exit));
1791
- CGF.EmitStmt (Stmt);
1792
- CGF.EmitBlock (Exit. getBlock ());
1793
- CGF.BreakContinueStack . pop_back ( );
1756
+ // Emit final copy of the lastprivate variables if IsLastIter != 0.
1757
+ if (HasLastprivates)
1758
+ CGF.EmitOMPLastprivateClauseFinal (
1759
+ S, CGF.Builder . CreateIsNotNull (
1760
+ CGF.EmitLoadOfScalar (IL, S. getLocStart ())) );
1794
1761
};
1795
- CGM.getOpenMPRuntime ().emitSingleRegion (*this , CodeGen, S.getLocStart (),
1796
- llvm::None, llvm::None, llvm::None,
1797
- llvm::None);
1798
- // Emit barrier for firstprivates, lastprivates or reductions only if
1799
- // 'sections' directive has 'nowait' clause. Otherwise the barrier will be
1800
- // generated by the codegen for the directive.
1801
- if ((HasFirstprivates || HasLastprivates || HasReductions) &&
1802
- S.getSingleClause <OMPNowaitClause>()) {
1762
+
1763
+ bool HasCancel = false ;
1764
+ if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
1765
+ HasCancel = OSD->hasCancel ();
1766
+ else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
1767
+ HasCancel = OPSD->hasCancel ();
1768
+ CGM.getOpenMPRuntime ().emitInlinedDirective (*this , OMPD_sections, CodeGen,
1769
+ HasCancel);
1770
+ // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
1771
+ // clause. Otherwise the barrier will be generated by the codegen for the
1772
+ // directive.
1773
+ if (HasLastprivates && S.getSingleClause <OMPNowaitClause>()) {
1803
1774
// Emit implicit barrier to synchronize threads and avoid data races on
1804
1775
// initialization of firstprivate variables.
1805
- CGM.getOpenMPRuntime ().emitBarrierCall (*this , S.getLocStart (), OMPD_unknown,
1806
- /* EmitChecks=*/ false ,
1807
- /* ForceSimpleCall=*/ true );
1776
+ CGM.getOpenMPRuntime ().emitBarrierCall (*this , S.getLocStart (),
1777
+ OMPD_unknown);
1808
1778
}
1809
- return OMPD_single ;
1779
+ return OMPD_sections ;
1810
1780
}
1811
1781
1812
1782
void CodeGenFunction::EmitOMPSectionsDirective (const OMPSectionsDirective &S) {
@@ -2651,8 +2621,7 @@ CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
2651
2621
if (Kind == OMPD_parallel || Kind == OMPD_task)
2652
2622
return ReturnBlock;
2653
2623
assert (Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
2654
- Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
2655
- Kind == OMPD_single);
2624
+ Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for);
2656
2625
return BreakContinueStack.back ().BreakBlock ;
2657
2626
}
2658
2627
0 commit comments