@@ -503,6 +503,31 @@ class OpenMPIRBuilder {
503503 return allocaInst;
504504 }
505505 };
506+
507+ struct ScanInformation {
508+ public:
509+ // / Dominates the body of the loop before scan directive
510+ llvm::BasicBlock *OMPBeforeScanBlock = nullptr ;
511+ // / Dominates the body of the loop before scan directive
512+ llvm::BasicBlock *OMPAfterScanBlock = nullptr ;
513+ // / Controls the flow to before or after scan blocks
514+ llvm::BasicBlock *OMPScanDispatch = nullptr ;
515+ // / Exit block of loop body
516+ llvm::BasicBlock *OMPScanLoopExit = nullptr ;
517+ // / Block before loop body where scan initializations are done
518+ llvm::BasicBlock *OMPScanInit = nullptr ;
519+ // / Block after loop body where scan finalizations are done
520+ llvm::BasicBlock *OMPScanFinish = nullptr ;
521+ // / If true, it indicates Input phase is lowered; else it indicates
522+ // / ScanPhase is lowered
523+ bool OMPFirstScanLoop = false ;
524+ // Maps the private reduction variable to the pointer of the temporary
525+ // buffer
526+ llvm::SmallDenseMap<llvm::Value *, llvm::Value *> ScanBuffPtrs;
527+ llvm::Value *IV;
528+ llvm::Value *Span;
529+ } ScanInfo;
530+
506531 // / Initialize the internal state, this will put structures types and
507532 // / potentially other helpers into the underlying module. Must be called
508533 // / before any other method and only once! This internal state includes types
@@ -729,6 +754,35 @@ class OpenMPIRBuilder {
729754 LoopBodyGenCallbackTy BodyGenCB, Value *TripCount,
730755 const Twine &Name = " loop" );
731756
757+ // / Generator for the control flow structure of an OpenMP canonical loops if
758+ // / the parent directive has an `inscan` modifier specified.
759+ // / If the `inscan` modifier is specified, the region of the parent is
760+ // / expected to have a `scan` directive. Based on the clauses in
761+ // / scan directive, the body of the loop is split into two loops: Input loop
762+ // / and Scan Loop. Input loop contains the code generated for input phase of
763+ // / scan and Scan loop contains the code generated for scan phase of scan.
764+ // /
765+ // / \param Loc The insert and source location description.
766+ // / \param BodyGenCB Callback that will generate the loop body code.
767+ // / \param Start Value of the loop counter for the first iterations.
768+ // / \param Stop Loop counter values past this will stop the loop.
769+ // / \param Step Loop counter increment after each iteration; negative
770+ // / means counting down.
771+ // / \param IsSigned Whether Start, Stop and Step are signed integers.
772+ // / \param InclusiveStop Whether \p Stop itself is a valid value for the loop
773+ // / counter.
774+ // / \param ComputeIP Insertion point for instructions computing the trip
775+ // / count. Can be used to ensure the trip count is available
776+ // / at the outermost loop of a loop nest. If not set,
777+ // / defaults to the preheader of the generated loop.
778+ // / \param Name Base name used to derive BB and instruction names.
779+ // /
780+ // / \returns A vector containing Loop Info of Input Loop and Scan Loop.
781+ Expected<SmallVector<llvm::CanonicalLoopInfo *>> createCanonicalScanLoops (
782+ const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
783+ Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
784+ InsertPointTy ComputeIP, const Twine &Name);
785+
732786 // / Calculate the trip count of a canonical loop.
733787 // /
734788 // / This allows specifying user-defined loop counter values using increment,
@@ -798,13 +852,16 @@ class OpenMPIRBuilder {
798852 // / at the outermost loop of a loop nest. If not set,
799853 // / defaults to the preheader of the generated loop.
800854 // / \param Name Base name used to derive BB and instruction names.
855+ // / \param InScan Whether loop has a scan reduction specified.
801856 // /
802857 // / \returns An object representing the created control flow structure which
803858 // / 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" );
859+ Expected<CanonicalLoopInfo *>
860+ createCanonicalLoop (const LocationDescription &Loc,
861+ LoopBodyGenCallbackTy BodyGenCB, Value *Start,
862+ Value *Stop, Value *Step, bool IsSigned,
863+ bool InclusiveStop, InsertPointTy ComputeIP = {},
864+ const Twine &Name = " loop" , bool InScan = false );
808865
809866 // / Collapse a loop nest into a single loop.
810867 // /
@@ -1532,6 +1589,45 @@ class OpenMPIRBuilder {
15321589 ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
15331590 Function *ReduceFn, AttributeList FuncAttrs);
15341591
1592+ // / Creates the runtime call specified
1593+ // / \param Callee Function Declaration Value
1594+ // / \param Args Arguments passed to the call
1595+ // / \param Name Optional param to specify the name of the call Instruction.
1596+ // /
1597+ // / \return The Runtime call instruction created.
1598+ llvm::CallInst *emitNoUnwindRuntimeCall (llvm::FunctionCallee Callee,
1599+ ArrayRef<llvm::Value *> Args,
1600+ const llvm::Twine &Name);
1601+
1602+ // / Helper function for CreateCanonicalScanLoops to create InputLoop
1603+ // / in the firstGen and Scan Loop in the SecondGen
1604+ // / \param InputLoopGen Callback for generating the loop for input phase
1605+ // / \param ScanLoopGen Callback for generating the loop for scan phase
1606+ // /
1607+ // / \return error if any produced, else return success.
1608+ Error emitScanBasedDirectiveIR (
1609+ llvm::function_ref<Error()> InputLoopGen,
1610+ llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1611+
1612+ // / Creates the basic blocks required for scan reduction.
1613+ void createScanBBs ();
1614+
1615+ // / Dynamically allocates the buffer needed for scan reduction.
1616+ // / \param AllocaIP The IP where possibly-shared pointer of buffer needs to be
1617+ // / declared. \param ScanVars Scan Variables.
1618+ // /
1619+ // / \return error if any produced, else return success.
1620+ Error emitScanBasedDirectiveDeclsIR (InsertPointTy AllocaIP,
1621+ ArrayRef<llvm::Value *> ScanVars,
1622+ ArrayRef<llvm::Type *> ScanVarsType);
1623+
1624+ // / Copies the result back to the reduction variable.
1625+ // / \param ReductionInfos Array type containing the ReductionOps.
1626+ // /
1627+ // / \return error if any produced, else return success.
1628+ Error emitScanBasedDirectiveFinalsIR (
1629+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1630+
15351631 // / This function emits a helper that gathers Reduce lists from the first
15361632 // / lane of every active warp to lanes in the first warp.
15371633 // /
@@ -2607,6 +2703,41 @@ class OpenMPIRBuilder {
26072703 BodyGenCallbackTy BodyGenCB,
26082704 FinalizeCallbackTy FiniCB, Value *Filter);
26092705
2706+ // / This function performs the scan reduction of the values updated in
2707+ // / the input phase. The reduction logic needs to be emitted between input
2708+ // / and scan loop returned by `CreateCanonicalScanLoops`. The following
2709+ // / is the code that is generated, `buffer` and `span` are expected to be
2710+ // / populated before executing the generated code.
2711+ // /
2712+ // / for (int k = 0; k != ceil(log2(span)); ++k) {
2713+ // / i=pow(2,k)
2714+ // / for (size cnt = last_iter; cnt >= i; --cnt)
2715+ // / buffer[cnt] op= buffer[cnt-i];
2716+ // / }
2717+ // / \param Loc The insert and source location description.
2718+ // / \param ReductionInfos Array type containing the ReductionOps.
2719+ // /
2720+ // / \returns The insertion position *after* the masked.
2721+ InsertPointOrErrorTy emitScanReduction (
2722+ const LocationDescription &Loc,
2723+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2724+
2725+ // / This directive split and directs the control flow to input phase
2726+ // / blocks or scan phase blocks based on 1. whether input loop or scan loop
2727+ // / is executed, 2. whether exclusive or inclusive scan is used.
2728+ // /
2729+ // / \param Loc The insert and source location description.
2730+ // / \param AllocaIP The IP where the temporary buffer for scan reduction
2731+ // needs to be allocated.
2732+ // / \param ScanVars Scan Variables.
2733+ // / \param IsInclusive Whether it is an inclusive or exclusive scan.
2734+ // /
2735+ // / \returns The insertion position *after* the scan.
2736+ InsertPointOrErrorTy createScan (const LocationDescription &Loc,
2737+ InsertPointTy AllocaIP,
2738+ ArrayRef<llvm::Value *> ScanVars,
2739+ ArrayRef<llvm::Type *> ScanVarsType,
2740+ bool IsInclusive);
26102741 // / Generator for '#omp critical'
26112742 // /
26122743 // / \param Loc The insert and source location description.
0 commit comments