@@ -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 specifier, the region of the parent is
747+ // / expected to have a `scan` directive specified. 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,
@@ -800,10 +842,12 @@ class OpenMPIRBuilder {
800842 // /
801843 // / \returns An object representing the created control flow structure which
802844 // / 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" );
845+ Expected<CanonicalLoopInfo *>
846+ createCanonicalLoop (const LocationDescription &Loc,
847+ LoopBodyGenCallbackTy BodyGenCB, Value *Start,
848+ Value *Stop, Value *Step, bool IsSigned,
849+ bool InclusiveStop, InsertPointTy ComputeIP = {},
850+ const Twine &Name = " loop" , bool InScan = false );
807851
808852 // / Collapse a loop nest into a single loop.
809853 // /
@@ -1530,6 +1574,38 @@ class OpenMPIRBuilder {
15301574 ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
15311575 Function *ReduceFn, AttributeList FuncAttrs);
15321576
1577+ // / Creates the runtime call specified
1578+ // / \param Callee Function Declaration Value
1579+ // / \param Args Arguments passed to the call
1580+ // / \param Name Optional param to specify the name of the call Instruction.
1581+ // /
1582+ // / \return The Runtime call instruction created.
1583+ llvm::CallInst *emitNoUnwindRuntimeCall (llvm::FunctionCallee Callee,
1584+ ArrayRef<llvm::Value *> Args,
1585+ const llvm::Twine &Name);
1586+
1587+ // / Helper function for CreateCanonicalScanLoops to create InputLoop
1588+ // / in the firstGen and Scan Loop in the SecondGen
1589+ // / \param InputLoopGen Callback for generating the loop for input phase
1590+ // / \param ScanLoopGen Callback for generating the loop for scan phase
1591+ // /
1592+ // / \return error if any produced, else return success.
1593+ Error emitScanBasedDirectiveIR (
1594+ llvm::function_ref<Error()> InputLoopGen,
1595+ llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1596+
1597+ // / Creates the basic blocks required for scan reduction.
1598+ void createScanBBs ();
1599+
1600+ // / Creates the buffer needed for scan reduction.
1601+ // / \param ScanVars Scan Variables.
1602+ void emitScanBasedDirectiveDeclsIR (ArrayRef<llvm::Value *> ScanVars);
1603+
1604+ // / Copies the result back to the reduction variable.
1605+ // / \param ReductionInfos Array type containing the ReductionOps.
1606+ void emitScanBasedDirectiveFinalsIR (
1607+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1608+
15331609 // / This function emits a helper that gathers Reduce lists from the first
15341610 // / lane of every active warp to lanes in the first warp.
15351611 // /
@@ -2177,7 +2253,6 @@ class OpenMPIRBuilder {
21772253 // block, if possible, or else at the end of the function. Also add a branch
21782254 // from current block to BB if current block does not have a terminator.
21792255 void emitBlock (BasicBlock *BB, Function *CurFn, bool IsFinished = false );
2180-
21812256 // / Emits code for OpenMP 'if' clause using specified \a BodyGenCallbackTy
21822257 // / Here is the logic:
21832258 // / if (Cond) {
@@ -2603,6 +2678,42 @@ class OpenMPIRBuilder {
26032678 BodyGenCallbackTy BodyGenCB,
26042679 FinalizeCallbackTy FiniCB, Value *Filter);
26052680
2681+ // / This function performs the scan reduction of the values updated in
2682+ // / the input phase. This reductions needs to be emitted between input and
2683+ // / scan loop returned by `CreateCanonicalScanLoops`. The following is the
2684+ // / code that is generated, `buffer` and `span` are exected to be
2685+ // / populated before calling the function
2686+ // /
2687+ // / for (int k = 0; k != ceil(log2(span)); ++k) {
2688+ // / i=pow(2,k)
2689+ // / for (size cnt = last_iter; cnt >= i; --cnt)
2690+ // / buffer[cnt] op= buffer[cnt-i];
2691+ // / }
2692+ // / \param Loc The insert and source location description.
2693+ // / \param FinalizeIP The IP where the reduction result needs
2694+ // to be copied back to original variable.
2695+ // / \param ReductionInfos Array type containing the ReductionOps.
2696+ // /
2697+ // / \returns The insertion position *after* the masked.
2698+ InsertPointOrErrorTy emitScanReduction (
2699+ const LocationDescription &Loc, InsertPointTy &FinalizeIP,
2700+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2701+
2702+ // / This directive split and directs the control flow to input phase
2703+ // / blocks or scan phase blocks based on 1. whether input loop or scan loop
2704+ // / is executed, 2. whether exclusive or inclusive scan is used.
2705+ // /
2706+ // / \param Loc The insert and source location description.
2707+ // / \param AllocaIP The IP where the temporary buffer for scan reduction
2708+ // needs to be allocated.
2709+ // / \param ScanVars Scan Variables.
2710+ // / \param IsInclusive Indicates if it is an inclusive or exclusive scan.
2711+ // /
2712+ // / \returns The insertion position *after* the masked.
2713+ InsertPointOrErrorTy createScan (const LocationDescription &Loc,
2714+ InsertPointTy AllocaIP,
2715+ ArrayRef<llvm::Value *> ScanVars,
2716+ bool IsInclusive);
26062717 // / Generator for '#omp critical'
26072718 // /
26082719 // / \param Loc The insert and source location description.
0 commit comments