31
31
32
32
namespace llvm {
33
33
class CanonicalLoopInfo ;
34
+ class ScanInfo ;
34
35
struct TargetRegionEntryInfo ;
35
36
class OffloadEntriesInfoManager ;
36
37
class OpenMPIRBuilder ;
@@ -512,29 +513,6 @@ class OpenMPIRBuilder {
512
513
}
513
514
};
514
515
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
-
538
516
// / Initialize the internal state, this will put structures types and
539
517
// / potentially other helpers into the underlying module. Must be called
540
518
// / before any other method and only once! This internal state includes types
@@ -731,6 +709,9 @@ class OpenMPIRBuilder {
731
709
LLVM_ABI InsertPointOrErrorTy createCancellationPoint (
732
710
const LocationDescription &Loc, omp::Directive CanceledDirective);
733
711
712
+ // / Creates a ScanInfo object, allocates and returns the pointer.
713
+ Expected<ScanInfo *> scanInfoInitialize ();
714
+
734
715
// / Generator for '#omp parallel'
735
716
// /
736
717
// / \param Loc The insert and source location description.
@@ -781,6 +762,11 @@ class OpenMPIRBuilder {
781
762
// / scan directive, the body of the loop is split into two loops: Input loop
782
763
// / and Scan Loop. Input loop contains the code generated for input phase of
783
764
// / 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.
784
770
// /
785
771
// / \param Loc The insert and source location description.
786
772
// / \param BodyGenCB Callback that will generate the loop body code.
@@ -796,12 +782,14 @@ class OpenMPIRBuilder {
796
782
// / at the outermost loop of a loop nest. If not set,
797
783
// / defaults to the preheader of the generated loop.
798
784
// / \param Name Base name used to derive BB and instruction names.
785
+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
786
+ // / `ScanInfoInitialize`.
799
787
// /
800
788
// / \returns A vector containing Loop Info of Input Loop and Scan Loop.
801
789
Expected<SmallVector<llvm::CanonicalLoopInfo *>> createCanonicalScanLoops (
802
790
const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
803
791
Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
804
- InsertPointTy ComputeIP, const Twine &Name);
792
+ InsertPointTy ComputeIP, const Twine &Name, ScanInfo *ScanRedInfo );
805
793
806
794
// / Calculate the trip count of a canonical loop.
807
795
// /
@@ -872,15 +860,16 @@ class OpenMPIRBuilder {
872
860
// / defaults to the preheader of the generated loop.
873
861
// / \param Name Base name used to derive BB and instruction names.
874
862
// / \param InScan Whether loop has a scan reduction specified.
863
+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
864
+ // / `ScanInfoInitialize`.
875
865
// /
876
866
// / \returns An object representing the created control flow structure which
877
867
// / 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 );
884
873
885
874
// / Collapse a loop nest into a single loop.
886
875
// /
@@ -1612,44 +1601,45 @@ class OpenMPIRBuilder {
1612
1601
ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
1613
1602
Function *ReduceFn, AttributeList FuncAttrs);
1614
1603
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
-
1625
1604
// / Helper function for CreateCanonicalScanLoops to create InputLoop
1626
1605
// / in the firstGen and Scan Loop in the SecondGen
1627
1606
// / \param InputLoopGen Callback for generating the loop for input phase
1628
1607
// / \param ScanLoopGen Callback for generating the loop for scan phase
1608
+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
1609
+ // / `ScanInfoInitialize`.
1629
1610
// /
1630
1611
// / \return error if any produced, else return success.
1631
1612
Error emitScanBasedDirectiveIR (
1632
1613
llvm::function_ref<Error()> InputLoopGen,
1633
- llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1614
+ llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen,
1615
+ ScanInfo *ScanRedInfo);
1634
1616
1635
1617
// / 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);
1637
1621
1638
1622
// / Dynamically allocates the buffer needed for scan reduction.
1639
1623
// / \param AllocaIP The IP where possibly-shared pointer of buffer needs to be
1640
1624
// / declared. \param ScanVars Scan Variables.
1625
+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
1626
+ // / `ScanInfoInitialize`.
1641
1627
// /
1642
1628
// / \return error if any produced, else return success.
1643
1629
Error emitScanBasedDirectiveDeclsIR (InsertPointTy AllocaIP,
1644
1630
ArrayRef<llvm::Value *> ScanVars,
1645
- ArrayRef<llvm::Type *> ScanVarsType);
1631
+ ArrayRef<llvm::Type *> ScanVarsType,
1632
+ ScanInfo *ScanRedInfo);
1646
1633
1647
1634
// / Copies the result back to the reduction variable.
1648
1635
// / \param ReductionInfos Array type containing the ReductionOps.
1636
+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
1637
+ // / `ScanInfoInitialize`.
1649
1638
// /
1650
1639
// / \return error if any produced, else return success.
1651
1640
Error emitScanBasedDirectiveFinalsIR (
1652
- SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1641
+ ArrayRef<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos,
1642
+ ScanInfo *ScanInfo);
1653
1643
1654
1644
// / This function emits a helper that gathers Reduce lists from the first
1655
1645
// / lane of every active warp to lanes in the first warp.
@@ -2278,6 +2268,7 @@ class OpenMPIRBuilder {
2278
2268
// / Collection of owned canonical loop objects that eventually need to be
2279
2269
// / free'd.
2280
2270
std::forward_list<CanonicalLoopInfo> LoopInfos;
2271
+ std::forward_list<ScanInfo> ScanInfos;
2281
2272
2282
2273
// / Add a new region that will be outlined later.
2283
2274
void addOutlineInfo (OutlineInfo &&OI) { OutlineInfos.emplace_back (OI); }
@@ -2747,11 +2738,14 @@ class OpenMPIRBuilder {
2747
2738
// / }
2748
2739
// / \param Loc The insert and source location description.
2749
2740
// / \param ReductionInfos Array type containing the ReductionOps.
2741
+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
2742
+ // / `ScanInfoInitialize`.
2750
2743
// /
2751
2744
// / \returns The insertion position *after* the masked.
2752
2745
InsertPointOrErrorTy emitScanReduction (
2753
2746
const LocationDescription &Loc,
2754
- SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2747
+ ArrayRef<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos,
2748
+ ScanInfo *ScanRedInfo);
2755
2749
2756
2750
// / This directive split and directs the control flow to input phase
2757
2751
// / blocks or scan phase blocks based on 1. whether input loop or scan loop
@@ -2762,13 +2756,15 @@ class OpenMPIRBuilder {
2762
2756
// needs to be allocated.
2763
2757
// / \param ScanVars Scan Variables.
2764
2758
// / \param IsInclusive Whether it is an inclusive or exclusive scan.
2759
+ // / \param ScanRedInfo Pointer to the ScanInfo objected created using
2760
+ // / `ScanInfoInitialize`.
2765
2761
// /
2766
2762
// / \returns The insertion position *after* the scan.
2767
2763
InsertPointOrErrorTy createScan (const LocationDescription &Loc,
2768
2764
InsertPointTy AllocaIP,
2769
2765
ArrayRef<llvm::Value *> ScanVars,
2770
2766
ArrayRef<llvm::Type *> ScanVarsType,
2771
- bool IsInclusive);
2767
+ bool IsInclusive, ScanInfo *ScanRedInfo );
2772
2768
// / Generator for '#omp critical'
2773
2769
// /
2774
2770
// / \param Loc The insert and source location description.
@@ -3904,6 +3900,84 @@ class CanonicalLoopInfo {
3904
3900
LLVM_ABI void invalidate ();
3905
3901
};
3906
3902
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
+
3907
3981
} // end namespace llvm
3908
3982
3909
3983
#endif // LLVM_FRONTEND_OPENMP_OMPIRBUILDER_H
0 commit comments