Skip to content

Commit 0987b64

Browse files
committed
[IRBuilder] Lowering Scan Directive
1 parent a557550 commit 0987b64

File tree

6 files changed

+839
-92
lines changed

6 files changed

+839
-92
lines changed

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)