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