@@ -508,6 +508,30 @@ class OpenMPIRBuilder {
508
508
return allocaInst;
509
509
}
510
510
};
511
+
512
+ struct ScanInformation {
513
+ // / Dominates the body of the loop before scan directive
514
+ llvm::BasicBlock *OMPBeforeScanBlock = nullptr ;
515
+ // / Dominates the body of the loop before scan directive
516
+ llvm::BasicBlock *OMPAfterScanBlock = nullptr ;
517
+ // / Controls the flow to before or after scan blocks
518
+ llvm::BasicBlock *OMPScanDispatch = nullptr ;
519
+ // / Exit block of loop body
520
+ llvm::BasicBlock *OMPScanLoopExit = nullptr ;
521
+ // / Block before loop body where scan initializations are done
522
+ llvm::BasicBlock *OMPScanInit = nullptr ;
523
+ // / Block after loop body where scan finalizations are done
524
+ llvm::BasicBlock *OMPScanFinish = nullptr ;
525
+ // / If true, it indicates Input phase is lowered; else it indicates
526
+ // / ScanPhase is lowered
527
+ bool OMPFirstScanLoop = false ;
528
+ // Maps the private reduction variable to the pointer of the temporary
529
+ // buffer
530
+ llvm::SmallDenseMap<llvm::Value *, llvm::Value *> ScanBuffPtrs;
531
+ llvm::Value *IV;
532
+ llvm::Value *Span;
533
+ } ScanInfo;
534
+
511
535
// / Initialize the internal state, this will put structures types and
512
536
// / potentially other helpers into the underlying module. Must be called
513
537
// / before any other method and only once! This internal state includes types
@@ -743,6 +767,35 @@ class OpenMPIRBuilder {
743
767
LoopBodyGenCallbackTy BodyGenCB, Value *TripCount,
744
768
const Twine &Name = " loop" );
745
769
770
+ // / Generator for the control flow structure of an OpenMP canonical loops if
771
+ // / the parent directive has an `inscan` modifier specified.
772
+ // / If the `inscan` modifier is specified, the region of the parent is
773
+ // / expected to have a `scan` directive. Based on the clauses in
774
+ // / scan directive, the body of the loop is split into two loops: Input loop
775
+ // / and Scan Loop. Input loop contains the code generated for input phase of
776
+ // / scan and Scan loop contains the code generated for scan phase of scan.
777
+ // /
778
+ // / \param Loc The insert and source location description.
779
+ // / \param BodyGenCB Callback that will generate the loop body code.
780
+ // / \param Start Value of the loop counter for the first iterations.
781
+ // / \param Stop Loop counter values past this will stop the loop.
782
+ // / \param Step Loop counter increment after each iteration; negative
783
+ // / means counting down.
784
+ // / \param IsSigned Whether Start, Stop and Step are signed integers.
785
+ // / \param InclusiveStop Whether \p Stop itself is a valid value for the loop
786
+ // / counter.
787
+ // / \param ComputeIP Insertion point for instructions computing the trip
788
+ // / count. Can be used to ensure the trip count is available
789
+ // / at the outermost loop of a loop nest. If not set,
790
+ // / defaults to the preheader of the generated loop.
791
+ // / \param Name Base name used to derive BB and instruction names.
792
+ // /
793
+ // / \returns A vector containing Loop Info of Input Loop and Scan Loop.
794
+ Expected<SmallVector<llvm::CanonicalLoopInfo *>> createCanonicalScanLoops (
795
+ const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
796
+ Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
797
+ InsertPointTy ComputeIP, const Twine &Name);
798
+
746
799
// / Calculate the trip count of a canonical loop.
747
800
// /
748
801
// / This allows specifying user-defined loop counter values using increment,
@@ -811,13 +864,15 @@ class OpenMPIRBuilder {
811
864
// / at the outermost loop of a loop nest. If not set,
812
865
// / defaults to the preheader of the generated loop.
813
866
// / \param Name Base name used to derive BB and instruction names.
867
+ // / \param InScan Whether loop has a scan reduction specified.
814
868
// /
815
869
// / \returns An object representing the created control flow structure which
816
870
// / can be used for loop-associated directives.
817
871
LLVM_ABI Expected<CanonicalLoopInfo *> createCanonicalLoop (
818
872
const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
819
873
Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
820
- InsertPointTy ComputeIP = {}, const Twine &Name = " loop" );
874
+ InsertPointTy ComputeIP = {}, const Twine &Name = " loop" ,
875
+ bool InScan = false );
821
876
822
877
// / Collapse a loop nest into a single loop.
823
878
// /
@@ -1548,6 +1603,45 @@ class OpenMPIRBuilder {
1548
1603
ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
1549
1604
Function *ReduceFn, AttributeList FuncAttrs);
1550
1605
1606
+ // / Creates the runtime call specified
1607
+ // / \param Callee Function Declaration Value
1608
+ // / \param Args Arguments passed to the call
1609
+ // / \param Name Optional param to specify the name of the call Instruction.
1610
+ // /
1611
+ // / \return The Runtime call instruction created.
1612
+ llvm::CallInst *emitNoUnwindRuntimeCall (llvm::FunctionCallee Callee,
1613
+ ArrayRef<llvm::Value *> Args,
1614
+ const llvm::Twine &Name);
1615
+
1616
+ // / Helper function for CreateCanonicalScanLoops to create InputLoop
1617
+ // / in the firstGen and Scan Loop in the SecondGen
1618
+ // / \param InputLoopGen Callback for generating the loop for input phase
1619
+ // / \param ScanLoopGen Callback for generating the loop for scan phase
1620
+ // /
1621
+ // / \return error if any produced, else return success.
1622
+ Error emitScanBasedDirectiveIR (
1623
+ llvm::function_ref<Error()> InputLoopGen,
1624
+ llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1625
+
1626
+ // / Creates the basic blocks required for scan reduction.
1627
+ void createScanBBs ();
1628
+
1629
+ // / Dynamically allocates the buffer needed for scan reduction.
1630
+ // / \param AllocaIP The IP where possibly-shared pointer of buffer needs to be
1631
+ // / declared. \param ScanVars Scan Variables.
1632
+ // /
1633
+ // / \return error if any produced, else return success.
1634
+ Error emitScanBasedDirectiveDeclsIR (InsertPointTy AllocaIP,
1635
+ ArrayRef<llvm::Value *> ScanVars,
1636
+ ArrayRef<llvm::Type *> ScanVarsType);
1637
+
1638
+ // / Copies the result back to the reduction variable.
1639
+ // / \param ReductionInfos Array type containing the ReductionOps.
1640
+ // /
1641
+ // / \return error if any produced, else return success.
1642
+ Error emitScanBasedDirectiveFinalsIR (
1643
+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1644
+
1551
1645
// / This function emits a helper that gathers Reduce lists from the first
1552
1646
// / lane of every active warp to lanes in the first warp.
1553
1647
// /
@@ -2631,6 +2725,41 @@ class OpenMPIRBuilder {
2631
2725
FinalizeCallbackTy FiniCB,
2632
2726
Value *Filter);
2633
2727
2728
+ // / This function performs the scan reduction of the values updated in
2729
+ // / the input phase. The reduction logic needs to be emitted between input
2730
+ // / and scan loop returned by `CreateCanonicalScanLoops`. The following
2731
+ // / is the code that is generated, `buffer` and `span` are expected to be
2732
+ // / populated before executing the generated code.
2733
+ // /
2734
+ // / for (int k = 0; k != ceil(log2(span)); ++k) {
2735
+ // / i=pow(2,k)
2736
+ // / for (size cnt = last_iter; cnt >= i; --cnt)
2737
+ // / buffer[cnt] op= buffer[cnt-i];
2738
+ // / }
2739
+ // / \param Loc The insert and source location description.
2740
+ // / \param ReductionInfos Array type containing the ReductionOps.
2741
+ // /
2742
+ // / \returns The insertion position *after* the masked.
2743
+ InsertPointOrErrorTy emitScanReduction (
2744
+ const LocationDescription &Loc,
2745
+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2746
+
2747
+ // / This directive split and directs the control flow to input phase
2748
+ // / blocks or scan phase blocks based on 1. whether input loop or scan loop
2749
+ // / is executed, 2. whether exclusive or inclusive scan is used.
2750
+ // /
2751
+ // / \param Loc The insert and source location description.
2752
+ // / \param AllocaIP The IP where the temporary buffer for scan reduction
2753
+ // needs to be allocated.
2754
+ // / \param ScanVars Scan Variables.
2755
+ // / \param IsInclusive Whether it is an inclusive or exclusive scan.
2756
+ // /
2757
+ // / \returns The insertion position *after* the scan.
2758
+ InsertPointOrErrorTy createScan (const LocationDescription &Loc,
2759
+ InsertPointTy AllocaIP,
2760
+ ArrayRef<llvm::Value *> ScanVars,
2761
+ ArrayRef<llvm::Type *> ScanVarsType,
2762
+ bool IsInclusive);
2634
2763
// / Generator for '#omp critical'
2635
2764
// /
2636
2765
// / \param Loc The insert and source location description.
0 commit comments