3131
3232namespace llvm {
3333class CanonicalLoopInfo ;
34+ class ScanInfo ;
3435struct TargetRegionEntryInfo ;
3536class OffloadEntriesInfoManager ;
3637class OpenMPIRBuilder ;
@@ -512,29 +513,6 @@ class OpenMPIRBuilder {
512513 }
513514 };
514515
515- struct ScanInformation {
516- // / Dominates the body of the loop before scan directive
517- llvm::BasicBlock *OMPBeforeScanBlock = nullptr ;
518- // / Dominates the body of the loop before scan directive
519- llvm::BasicBlock *OMPAfterScanBlock = nullptr ;
520- // / Controls the flow to before or after scan blocks
521- llvm::BasicBlock *OMPScanDispatch = nullptr ;
522- // / Exit block of loop body
523- llvm::BasicBlock *OMPScanLoopExit = nullptr ;
524- // / Block before loop body where scan initializations are done
525- llvm::BasicBlock *OMPScanInit = nullptr ;
526- // / Block after loop body where scan finalizations are done
527- llvm::BasicBlock *OMPScanFinish = nullptr ;
528- // / If true, it indicates Input phase is lowered; else it indicates
529- // / ScanPhase is lowered
530- bool OMPFirstScanLoop = false ;
531- // Maps the private reduction variable to the pointer of the temporary
532- // buffer
533- llvm::SmallDenseMap<llvm::Value *, llvm::Value *> ScanBuffPtrs;
534- llvm::Value *IV;
535- llvm::Value *Span;
536- } ScanInfo;
537-
538516 // / Initialize the internal state, this will put structures types and
539517 // / potentially other helpers into the underlying module. Must be called
540518 // / before any other method and only once! This internal state includes types
@@ -731,6 +709,9 @@ class OpenMPIRBuilder {
731709 LLVM_ABI InsertPointOrErrorTy createCancellationPoint (
732710 const LocationDescription &Loc, omp::Directive CanceledDirective);
733711
712+ // / Creates a ScanInfo object, allocates and returns the pointer.
713+ Expected<ScanInfo *> scanInfoInitialize ();
714+
734715 // / Generator for '#omp parallel'
735716 // /
736717 // / \param Loc The insert and source location description.
@@ -781,6 +762,11 @@ class OpenMPIRBuilder {
781762 // / scan directive, the body of the loop is split into two loops: Input loop
782763 // / and Scan Loop. Input loop contains the code generated for input phase of
783764 // / scan and Scan loop contains the code generated for scan phase of scan.
765+ // / From the bodyGen callback of these loops, `createScan` would be called
766+ // / when a scan directive is encountered from the loop body. `createScan`
767+ // / based on whether 1. inclusive or exclusive scan is specified and, 2. input
768+ // / loop or scan loop is generated, lowers the body of the for loop
769+ // / accordingly.
784770 // /
785771 // / \param Loc The insert and source location description.
786772 // / \param BodyGenCB Callback that will generate the loop body code.
@@ -796,12 +782,14 @@ class OpenMPIRBuilder {
796782 // / at the outermost loop of a loop nest. If not set,
797783 // / defaults to the preheader of the generated loop.
798784 // / \param Name Base name used to derive BB and instruction names.
785+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
786+ // / `ScanInfoInitialize`.
799787 // /
800788 // / \returns A vector containing Loop Info of Input Loop and Scan Loop.
801789 Expected<SmallVector<llvm::CanonicalLoopInfo *>> createCanonicalScanLoops (
802790 const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
803791 Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
804- InsertPointTy ComputeIP, const Twine &Name);
792+ InsertPointTy ComputeIP, const Twine &Name, ScanInfo *ScanRedInfo );
805793
806794 // / Calculate the trip count of a canonical loop.
807795 // /
@@ -872,15 +860,16 @@ class OpenMPIRBuilder {
872860 // / defaults to the preheader of the generated loop.
873861 // / \param Name Base name used to derive BB and instruction names.
874862 // / \param InScan Whether loop has a scan reduction specified.
863+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
864+ // / `ScanInfoInitialize`.
875865 // /
876866 // / \returns An object representing the created control flow structure which
877867 // / can be used for loop-associated directives.
878- LLVM_ABI Expected<CanonicalLoopInfo *>
879- createCanonicalLoop (const LocationDescription &Loc,
880- LoopBodyGenCallbackTy BodyGenCB, Value *Start,
881- Value *Stop, Value *Step, bool IsSigned,
882- bool InclusiveStop, InsertPointTy ComputeIP = {},
883- const Twine &Name = " loop" , bool InScan = false );
868+ LLVM_ABI Expected<CanonicalLoopInfo *> createCanonicalLoop (
869+ const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
870+ Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
871+ InsertPointTy ComputeIP = {}, const Twine &Name = " loop" ,
872+ bool InScan = false , ScanInfo *ScanRedInfo = nullptr );
884873
885874 // / Collapse a loop nest into a single loop.
886875 // /
@@ -1612,44 +1601,45 @@ class OpenMPIRBuilder {
16121601 ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
16131602 Function *ReduceFn, AttributeList FuncAttrs);
16141603
1615- // / Creates the runtime call specified
1616- // / \param Callee Function Declaration Value
1617- // / \param Args Arguments passed to the call
1618- // / \param Name Optional param to specify the name of the call Instruction.
1619- // /
1620- // / \return The Runtime call instruction created.
1621- llvm::CallInst *emitNoUnwindRuntimeCall (llvm::FunctionCallee Callee,
1622- ArrayRef<llvm::Value *> Args,
1623- const llvm::Twine &Name);
1624-
16251604 // / Helper function for CreateCanonicalScanLoops to create InputLoop
16261605 // / in the firstGen and Scan Loop in the SecondGen
16271606 // / \param InputLoopGen Callback for generating the loop for input phase
16281607 // / \param ScanLoopGen Callback for generating the loop for scan phase
1608+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
1609+ // / `ScanInfoInitialize`.
16291610 // /
16301611 // / \return error if any produced, else return success.
16311612 Error emitScanBasedDirectiveIR (
16321613 llvm::function_ref<Error()> InputLoopGen,
1633- llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1614+ llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen,
1615+ ScanInfo *ScanRedInfo);
16341616
16351617 // / Creates the basic blocks required for scan reduction.
1636- void createScanBBs ();
1618+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
1619+ // / `ScanInfoInitialize`.
1620+ void createScanBBs (ScanInfo *ScanRedInfo);
16371621
16381622 // / Dynamically allocates the buffer needed for scan reduction.
16391623 // / \param AllocaIP The IP where possibly-shared pointer of buffer needs to be
16401624 // / declared. \param ScanVars Scan Variables.
1625+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
1626+ // / `ScanInfoInitialize`.
16411627 // /
16421628 // / \return error if any produced, else return success.
16431629 Error emitScanBasedDirectiveDeclsIR (InsertPointTy AllocaIP,
16441630 ArrayRef<llvm::Value *> ScanVars,
1645- ArrayRef<llvm::Type *> ScanVarsType);
1631+ ArrayRef<llvm::Type *> ScanVarsType,
1632+ ScanInfo *ScanRedInfo);
16461633
16471634 // / Copies the result back to the reduction variable.
16481635 // / \param ReductionInfos Array type containing the ReductionOps.
1636+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
1637+ // / `ScanInfoInitialize`.
16491638 // /
16501639 // / \return error if any produced, else return success.
16511640 Error emitScanBasedDirectiveFinalsIR (
1652- SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1641+ ArrayRef<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos,
1642+ ScanInfo *ScanInfo);
16531643
16541644 // / This function emits a helper that gathers Reduce lists from the first
16551645 // / lane of every active warp to lanes in the first warp.
@@ -2278,6 +2268,7 @@ class OpenMPIRBuilder {
22782268 // / Collection of owned canonical loop objects that eventually need to be
22792269 // / free'd.
22802270 std::forward_list<CanonicalLoopInfo> LoopInfos;
2271+ std::forward_list<ScanInfo> ScanInfos;
22812272
22822273 // / Add a new region that will be outlined later.
22832274 void addOutlineInfo (OutlineInfo &&OI) { OutlineInfos.emplace_back (OI); }
@@ -2747,11 +2738,14 @@ class OpenMPIRBuilder {
27472738 // / }
27482739 // / \param Loc The insert and source location description.
27492740 // / \param ReductionInfos Array type containing the ReductionOps.
2741+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
2742+ // / `ScanInfoInitialize`.
27502743 // /
27512744 // / \returns The insertion position *after* the masked.
27522745 InsertPointOrErrorTy emitScanReduction (
27532746 const LocationDescription &Loc,
2754- SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2747+ ArrayRef<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos,
2748+ ScanInfo *ScanRedInfo);
27552749
27562750 // / This directive split and directs the control flow to input phase
27572751 // / blocks or scan phase blocks based on 1. whether input loop or scan loop
@@ -2762,13 +2756,15 @@ class OpenMPIRBuilder {
27622756 // needs to be allocated.
27632757 // / \param ScanVars Scan Variables.
27642758 // / \param IsInclusive Whether it is an inclusive or exclusive scan.
2759+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
2760+ // / `ScanInfoInitialize`.
27652761 // /
27662762 // / \returns The insertion position *after* the scan.
27672763 InsertPointOrErrorTy createScan (const LocationDescription &Loc,
27682764 InsertPointTy AllocaIP,
27692765 ArrayRef<llvm::Value *> ScanVars,
27702766 ArrayRef<llvm::Type *> ScanVarsType,
2771- bool IsInclusive);
2767+ bool IsInclusive, ScanInfo *ScanRedInfo );
27722768 // / Generator for '#omp critical'
27732769 // /
27742770 // / \param Loc The insert and source location description.
@@ -3904,6 +3900,84 @@ class CanonicalLoopInfo {
39043900 LLVM_ABI void invalidate ();
39053901};
39063902
3903+ // / ScanInfo holds the information to assist in lowering of Scan reduction.
3904+ // / Before lowering, body of the for loop specifying scan reduction is expected
3905+ // / to have the following structure
3906+ // / Loop Body Entry
3907+ // / |
3908+ // / Code before the scan directive
3909+ // / |
3910+ // / Scan Directive
3911+ // / |
3912+ // / Code after the scan directive
3913+ // / |
3914+ // / Loop Body Exit
3915+ // / When `createCanonicalScanLoops` is executed, the bodyGen callback of it
3916+ // / transforms the body to:
3917+ // /
3918+ // / Loop Body Entry
3919+ // / |
3920+ // / OMPScanDispatch
3921+ // /
3922+ // / OMPBeforeScanBlock
3923+ // / |
3924+ // / OMPScanLoopExit
3925+ // / |
3926+ // / Loop Body Exit
3927+ // /
3928+ // / The insert point is updated to the first insert point of OMPBeforeScanBlock.
3929+ // / It dominates the control flow of code generated until
3930+ // / scan directive is encountered and OMPAfterScanBlock dominates the
3931+ // / control flow of code generated after scan is encountered. The successor
3932+ // / of OMPScanDispatch can be OMPBeforeScanBlock or OMPAfterScanBlock based
3933+ // / on 1.whether it is in Input phase or Scan Phase , 2. whether it is an
3934+ // / exclusive or inclusive scan. This jump is added when `createScan` is
3935+ // / executed. If input loop is being generated, if it is inclusive scan,
3936+ // / `OMPAfterScanBlock` succeeds `OMPScanDispatch` , if exclusive,
3937+ // / `OMPBeforeScanBlock` succeeds `OMPDispatch` and vice versa for scan loop. At
3938+ // / the end of the input loop, temporary buffer is populated and at the
3939+ // / beginning of the scan loop, temporary buffer is read. After scan directive
3940+ // / is encountered, insertion point is updated to `OMPAfterScanBlock` as it is
3941+ // / expected to dominate the code after the scan directive. Both Before and
3942+ // / After scan blocks are succeeded by `OMPScanLoopExit`.
3943+ // / Temporary buffer allocations are done in `ScanLoopInit` block before the
3944+ // / lowering of for-loop. The results are copied back to reduction variable in
3945+ // / `ScanLoopFinish` block.
3946+
3947+ class ScanInfo {
3948+ public:
3949+ // / Dominates the body of the loop before scan directive
3950+ llvm::BasicBlock *OMPBeforeScanBlock = nullptr ;
3951+ // / Dominates the body of the loop before scan directive
3952+ llvm::BasicBlock *OMPAfterScanBlock = nullptr ;
3953+ // / Controls the flow to before or after scan blocks
3954+ llvm::BasicBlock *OMPScanDispatch = nullptr ;
3955+ // / Exit block of loop body
3956+ llvm::BasicBlock *OMPScanLoopExit = nullptr ;
3957+ // / Block before loop body where scan initializations are done
3958+ llvm::BasicBlock *OMPScanInit = nullptr ;
3959+ // / Block after loop body where scan finalizations are done
3960+ llvm::BasicBlock *OMPScanFinish = nullptr ;
3961+ // / If true, it indicates Input phase is lowered; else it indicates
3962+ // / ScanPhase is lowered
3963+ bool OMPFirstScanLoop = false ;
3964+ // / Maps the private reduction variable to the pointer of the temporary
3965+ // / buffer
3966+ llvm::SmallDenseMap<llvm::Value *, llvm::Value *> *ScanBuffPtrs;
3967+ // / Keeps track of value of iteration variable for input/scan loop to be
3968+ // / used for Scan directive lowering
3969+ llvm::Value *IV;
3970+ // / Stores the span of canonical loop being lowered to be used for temporary
3971+ // / buffer allocation or Finalization.
3972+ llvm::Value *Span;
3973+
3974+ ScanInfo () {
3975+ ScanBuffPtrs = new llvm::SmallDenseMap<llvm::Value *, llvm::Value *>();
3976+ }
3977+
3978+ ~ScanInfo () { delete (ScanBuffPtrs); }
3979+ };
3980+
39073981} // end namespace llvm
39083982
39093983#endif // LLVM_FRONTEND_OPENMP_OMPIRBUILDER_H
0 commit comments