@@ -508,6 +508,30 @@ class OpenMPIRBuilder {
508508 return allocaInst;
509509 }
510510 };
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+
511535 // / Initialize the internal state, this will put structures types and
512536 // / potentially other helpers into the underlying module. Must be called
513537 // / before any other method and only once! This internal state includes types
@@ -743,6 +767,35 @@ class OpenMPIRBuilder {
743767 LoopBodyGenCallbackTy BodyGenCB, Value *TripCount,
744768 const Twine &Name = " loop" );
745769
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+
746799 // / Calculate the trip count of a canonical loop.
747800 // /
748801 // / This allows specifying user-defined loop counter values using increment,
@@ -811,13 +864,16 @@ class OpenMPIRBuilder {
811864 // / at the outermost loop of a loop nest. If not set,
812865 // / defaults to the preheader of the generated loop.
813866 // / \param Name Base name used to derive BB and instruction names.
867+ // / \param InScan Whether loop has a scan reduction specified.
814868 // /
815869 // / \returns An object representing the created control flow structure which
816870 // / can be used for loop-associated directives.
817- LLVM_ABI Expected<CanonicalLoopInfo *> createCanonicalLoop (
818- const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
819- Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
820- InsertPointTy ComputeIP = {}, const Twine &Name = " loop" );
871+ LLVM_ABI Expected<CanonicalLoopInfo *>
872+ createCanonicalLoop (const LocationDescription &Loc,
873+ LoopBodyGenCallbackTy BodyGenCB, Value *Start,
874+ Value *Stop, Value *Step, bool IsSigned,
875+ bool InclusiveStop, InsertPointTy ComputeIP = {},
876+ const Twine &Name = " loop" , bool InScan = false );
821877
822878 // / Collapse a loop nest into a single loop.
823879 // /
@@ -1548,6 +1604,45 @@ class OpenMPIRBuilder {
15481604 ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
15491605 Function *ReduceFn, AttributeList FuncAttrs);
15501606
1607+ // / Creates the runtime call specified
1608+ // / \param Callee Function Declaration Value
1609+ // / \param Args Arguments passed to the call
1610+ // / \param Name Optional param to specify the name of the call Instruction.
1611+ // /
1612+ // / \return The Runtime call instruction created.
1613+ llvm::CallInst *emitNoUnwindRuntimeCall (llvm::FunctionCallee Callee,
1614+ ArrayRef<llvm::Value *> Args,
1615+ const llvm::Twine &Name);
1616+
1617+ // / Helper function for CreateCanonicalScanLoops to create InputLoop
1618+ // / in the firstGen and Scan Loop in the SecondGen
1619+ // / \param InputLoopGen Callback for generating the loop for input phase
1620+ // / \param ScanLoopGen Callback for generating the loop for scan phase
1621+ // /
1622+ // / \return error if any produced, else return success.
1623+ Error emitScanBasedDirectiveIR (
1624+ llvm::function_ref<Error()> InputLoopGen,
1625+ llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1626+
1627+ // / Creates the basic blocks required for scan reduction.
1628+ void createScanBBs ();
1629+
1630+ // / Dynamically allocates the buffer needed for scan reduction.
1631+ // / \param AllocaIP The IP where possibly-shared pointer of buffer needs to be
1632+ // / declared. \param ScanVars Scan Variables.
1633+ // /
1634+ // / \return error if any produced, else return success.
1635+ Error emitScanBasedDirectiveDeclsIR (InsertPointTy AllocaIP,
1636+ ArrayRef<llvm::Value *> ScanVars,
1637+ ArrayRef<llvm::Type *> ScanVarsType);
1638+
1639+ // / Copies the result back to the reduction variable.
1640+ // / \param ReductionInfos Array type containing the ReductionOps.
1641+ // /
1642+ // / \return error if any produced, else return success.
1643+ Error emitScanBasedDirectiveFinalsIR (
1644+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1645+
15511646 // / This function emits a helper that gathers Reduce lists from the first
15521647 // / lane of every active warp to lanes in the first warp.
15531648 // /
@@ -2631,6 +2726,41 @@ class OpenMPIRBuilder {
26312726 FinalizeCallbackTy FiniCB,
26322727 Value *Filter);
26332728
2729+ // / This function performs the scan reduction of the values updated in
2730+ // / the input phase. The reduction logic needs to be emitted between input
2731+ // / and scan loop returned by `CreateCanonicalScanLoops`. The following
2732+ // / is the code that is generated, `buffer` and `span` are expected to be
2733+ // / populated before executing the generated code.
2734+ // /
2735+ // / for (int k = 0; k != ceil(log2(span)); ++k) {
2736+ // / i=pow(2,k)
2737+ // / for (size cnt = last_iter; cnt >= i; --cnt)
2738+ // / buffer[cnt] op= buffer[cnt-i];
2739+ // / }
2740+ // / \param Loc The insert and source location description.
2741+ // / \param ReductionInfos Array type containing the ReductionOps.
2742+ // /
2743+ // / \returns The insertion position *after* the masked.
2744+ InsertPointOrErrorTy emitScanReduction (
2745+ const LocationDescription &Loc,
2746+ SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2747+
2748+ // / This directive split and directs the control flow to input phase
2749+ // / blocks or scan phase blocks based on 1. whether input loop or scan loop
2750+ // / is executed, 2. whether exclusive or inclusive scan is used.
2751+ // /
2752+ // / \param Loc The insert and source location description.
2753+ // / \param AllocaIP The IP where the temporary buffer for scan reduction
2754+ // needs to be allocated.
2755+ // / \param ScanVars Scan Variables.
2756+ // / \param IsInclusive Whether it is an inclusive or exclusive scan.
2757+ // /
2758+ // / \returns The insertion position *after* the scan.
2759+ InsertPointOrErrorTy createScan (const LocationDescription &Loc,
2760+ InsertPointTy AllocaIP,
2761+ ArrayRef<llvm::Value *> ScanVars,
2762+ ArrayRef<llvm::Type *> ScanVarsType,
2763+ bool IsInclusive);
26342764 // / Generator for '#omp critical'
26352765 // /
26362766 // / \param Loc The insert and source location description.
0 commit comments