@@ -502,6 +502,19 @@ class OpenMPIRBuilder {
502502 return allocaInst;
503503 }
504504 };
505+ struct ScanInformation {
506+ public:
507+ llvm::BasicBlock *OMPBeforeScanBlock = nullptr ;
508+ llvm::BasicBlock *OMPAfterScanBlock = nullptr ;
509+ llvm::BasicBlock *OMPScanExitBlock = nullptr ;
510+ llvm::BasicBlock *OMPScanDispatch = nullptr ;
511+ llvm::BasicBlock *OMPScanLoopExit = nullptr ;
512+ bool OMPFirstScanLoop = false ;
513+ llvm::SmallDenseMap<llvm::Value *, llvm::Value *> ReductionVarToScanBuffs;
514+ llvm::Value *IV;
515+ llvm::Value *Span;
516+ } ScanInfo;
517+
505518 // / Initialize the internal state, this will put structures types and
506519 // / potentially other helpers into the underlying module. Must be called
507520 // / before any other method and only once! This internal state includes types
@@ -728,6 +741,35 @@ class OpenMPIRBuilder {
728741 LoopBodyGenCallbackTy BodyGenCB, Value *TripCount,
729742 const Twine &Name = " loop" );
730743
744+ // / Generator for the control flow structure of an OpenMP canonical loops if
745+ // / the parent directive has an `inscan` modifier specified.
746+ // / If the `inscan` modifier is specified, the region of the parent is
747+ // / expected to have a `scan` directive. Based on the clauses in
748+ // / scan directive, the body of the loop is split into two loops: Input loop
749+ // / and Scan Loop. Input loop contains the code generated for input phase of
750+ // / scan and Scan loop contains the code generated for scan phase of scan.
751+ // /
752+ // / \param Loc The insert and source location description.
753+ // / \param BodyGenCB Callback that will generate the loop body code.
754+ // / \param Start Value of the loop counter for the first iterations.
755+ // / \param Stop Loop counter values past this will stop the loop.
756+ // / \param Step Loop counter increment after each iteration; negative
757+ // / means counting down.
758+ // / \param IsSigned Whether Start, Stop and Step are signed integers.
759+ // / \param InclusiveStop Whether \p Stop itself is a valid value for the loop
760+ // / counter.
761+ // / \param ComputeIP Insertion point for instructions computing the trip
762+ // / count. Can be used to ensure the trip count is available
763+ // / at the outermost loop of a loop nest. If not set,
764+ // / defaults to the preheader of the generated loop.
765+ // / \param Name Base name used to derive BB and instruction names.
766+ // /
767+ // / \returns A vector containing Loop Info of Input Loop and Scan Loop.
768+ Expected<SmallVector<llvm::CanonicalLoopInfo *>> createCanonicalScanLoops (
769+ const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
770+ Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
771+ InsertPointTy ComputeIP, const Twine &Name);
772+
731773 // / Calculate the trip count of a canonical loop.
732774 // /
733775 // / This allows specifying user-defined loop counter values using increment,
@@ -797,13 +839,16 @@ class OpenMPIRBuilder {
797839 // / at the outermost loop of a loop nest. If not set,
798840 // / defaults to the preheader of the generated loop.
799841 // / \param Name Base name used to derive BB and instruction names.
842+ // / \param InScan Whether loop has a scan reduction specified.
800843 // /
801844 // / \returns An object representing the created control flow structure which
802845 // / can be used for loop-associated directives.
803- Expected<CanonicalLoopInfo *> createCanonicalLoop (
804- const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
805- Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
806- InsertPointTy ComputeIP = {}, const Twine &Name = " loop" );
846+ Expected<CanonicalLoopInfo *>
847+ createCanonicalLoop (const LocationDescription &Loc,
848+ LoopBodyGenCallbackTy BodyGenCB, Value *Start,
849+ Value *Stop, Value *Step, bool IsSigned,
850+ bool InclusiveStop, InsertPointTy ComputeIP = {},
851+ const Twine &Name = " loop" , bool InScan = false );
807852
808853 // / Collapse a loop nest into a single loop.
809854 // /
@@ -1530,6 +1575,38 @@ class OpenMPIRBuilder {
15301575 ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
15311576 Function *ReduceFn, AttributeList FuncAttrs);
15321577
1578+ // / Creates the runtime call specified
1579+ // / \param Callee Function Declaration Value
1580+ // / \param Args Arguments passed to the call
1581+ // / \param Name Optional param to specify the name of the call Instruction.
1582+ // /
1583+ // / \return The Runtime call instruction created.
1584+ llvm::CallInst *emitNoUnwindRuntimeCall (llvm::FunctionCallee Callee,
1585+ ArrayRef<llvm::Value *> Args,
1586+ const llvm::Twine &Name);
1587+
1588+ // / Helper function for CreateCanonicalScanLoops to create InputLoop
1589+ // / in the firstGen and Scan Loop in the SecondGen
1590+ // / \param InputLoopGen Callback for generating the loop for input phase
1591+ // / \param ScanLoopGen Callback for generating the loop for scan phase
1592+ // /
1593+ // / \return error if any produced, else return success.
1594+ Error emitScanBasedDirectiveIR (
1595+ llvm::function_ref<Error()> InputLoopGen,
1596+ llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1597+
1598+ // / Creates the basic blocks required for scan reduction.
1599+ void createScanBBs ();
1600+
1601+ // / Creates the buffer needed for scan reduction.
1602+ // / \param ScanVars Scan Variables.
1603+ void emitScanBasedDirectiveDeclsIR (ArrayRef<llvm::Value *> ScanVars);
1604+
1605+ // / Copies the result back to the reduction variable.
1606+ // / \param ReductionInfos Array type containing the ReductionOps.
1607+ void emitScanBasedDirectiveFinalsIR (
1608+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1609+
15331610 // / This function emits a helper that gathers Reduce lists from the first
15341611 // / lane of every active warp to lanes in the first warp.
15351612 // /
@@ -2177,7 +2254,6 @@ class OpenMPIRBuilder {
21772254 // block, if possible, or else at the end of the function. Also add a branch
21782255 // from current block to BB if current block does not have a terminator.
21792256 void emitBlock (BasicBlock *BB, Function *CurFn, bool IsFinished = false );
2180-
21812257 // / Emits code for OpenMP 'if' clause using specified \a BodyGenCallbackTy
21822258 // / Here is the logic:
21832259 // / if (Cond) {
@@ -2603,6 +2679,42 @@ class OpenMPIRBuilder {
26032679 BodyGenCallbackTy BodyGenCB,
26042680 FinalizeCallbackTy FiniCB, Value *Filter);
26052681
2682+ // / This function performs the scan reduction of the values updated in
2683+ // / the input phase. The reduction logic needs to be emitted between input
2684+ // / and scan loop returned by `CreateCanonicalScanLoops`. The following
2685+ // / is the code that is generated, `buffer` and `span` are expected to be
2686+ // / populated before executing the generated code.
2687+ // /
2688+ // / for (int k = 0; k != ceil(log2(span)); ++k) {
2689+ // / i=pow(2,k)
2690+ // / for (size cnt = last_iter; cnt >= i; --cnt)
2691+ // / buffer[cnt] op= buffer[cnt-i];
2692+ // / }
2693+ // / \param Loc The insert and source location description.
2694+ // / \param FinalizeIP The IP where the reduction result needs
2695+ // to be copied back to original variable.
2696+ // / \param ReductionInfos Array type containing the ReductionOps.
2697+ // /
2698+ // / \returns The insertion position *after* the masked.
2699+ InsertPointOrErrorTy emitScanReduction (
2700+ const LocationDescription &Loc, InsertPointTy &FinalizeIP,
2701+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2702+
2703+ // / This directive split and directs the control flow to input phase
2704+ // / blocks or scan phase blocks based on 1. whether input loop or scan loop
2705+ // / is executed, 2. whether exclusive or inclusive scan is used.
2706+ // /
2707+ // / \param Loc The insert and source location description.
2708+ // / \param AllocaIP The IP where the temporary buffer for scan reduction
2709+ // needs to be allocated.
2710+ // / \param ScanVars Scan Variables.
2711+ // / \param IsInclusive Whether it is an inclusive or exclusive scan.
2712+ // /
2713+ // / \returns The insertion position *after* the masked.
2714+ InsertPointOrErrorTy createScan (const LocationDescription &Loc,
2715+ InsertPointTy AllocaIP,
2716+ ArrayRef<llvm::Value *> ScanVars,
2717+ bool IsInclusive);
26062718 // / Generator for '#omp critical'
26072719 // /
26082720 // / \param Loc The insert and source location description.
0 commit comments