Skip to content

Commit af2d143

Browse files
committed
[IRBuilder] Lowering Scan Directive
1 parent 2c8e260 commit af2d143

File tree

6 files changed

+841
-91
lines changed

6 files changed

+841
-91
lines changed

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

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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 specified, the region of the parent is
747+
/// expected to have a `scan` directive. 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,
@@ -797,13 +839,16 @@ class OpenMPIRBuilder {
797839
/// at the outermost loop of a loop nest. If not set,
798840
/// defaults to the preheader of the generated loop.
799841
/// \param Name Base name used to derive BB and instruction names.
842+
/// \param InScan Whether loop has a scan reduction specified.
800843
///
801844
/// \returns An object representing the created control flow structure which
802845
/// 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");
846+
Expected<CanonicalLoopInfo *>
847+
createCanonicalLoop(const LocationDescription &Loc,
848+
LoopBodyGenCallbackTy BodyGenCB, Value *Start,
849+
Value *Stop, Value *Step, bool IsSigned,
850+
bool InclusiveStop, InsertPointTy ComputeIP = {},
851+
const Twine &Name = "loop", bool InScan = false);
807852

808853
/// Collapse a loop nest into a single loop.
809854
///
@@ -1530,6 +1575,38 @@ class OpenMPIRBuilder {
15301575
ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
15311576
Function *ReduceFn, AttributeList FuncAttrs);
15321577

1578+
/// Creates the runtime call specified
1579+
/// \param Callee Function Declaration Value
1580+
/// \param Args Arguments passed to the call
1581+
/// \param Name Optional param to specify the name of the call Instruction.
1582+
///
1583+
/// \return The Runtime call instruction created.
1584+
llvm::CallInst *emitNoUnwindRuntimeCall(llvm::FunctionCallee Callee,
1585+
ArrayRef<llvm::Value *> Args,
1586+
const llvm::Twine &Name);
1587+
1588+
/// Helper function for CreateCanonicalScanLoops to create InputLoop
1589+
/// in the firstGen and Scan Loop in the SecondGen
1590+
/// \param InputLoopGen Callback for generating the loop for input phase
1591+
/// \param ScanLoopGen Callback for generating the loop for scan phase
1592+
///
1593+
/// \return error if any produced, else return success.
1594+
Error emitScanBasedDirectiveIR(
1595+
llvm::function_ref<Error()> InputLoopGen,
1596+
llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1597+
1598+
/// Creates the basic blocks required for scan reduction.
1599+
void createScanBBs();
1600+
1601+
/// Creates the buffer needed for scan reduction.
1602+
/// \param ScanVars Scan Variables.
1603+
void emitScanBasedDirectiveDeclsIR(ArrayRef<llvm::Value *> ScanVars);
1604+
1605+
/// Copies the result back to the reduction variable.
1606+
/// \param ReductionInfos Array type containing the ReductionOps.
1607+
void emitScanBasedDirectiveFinalsIR(
1608+
SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1609+
15331610
/// This function emits a helper that gathers Reduce lists from the first
15341611
/// lane of every active warp to lanes in the first warp.
15351612
///
@@ -2177,7 +2254,6 @@ class OpenMPIRBuilder {
21772254
// block, if possible, or else at the end of the function. Also add a branch
21782255
// from current block to BB if current block does not have a terminator.
21792256
void emitBlock(BasicBlock *BB, Function *CurFn, bool IsFinished = false);
2180-
21812257
/// Emits code for OpenMP 'if' clause using specified \a BodyGenCallbackTy
21822258
/// Here is the logic:
21832259
/// if (Cond) {
@@ -2603,6 +2679,42 @@ class OpenMPIRBuilder {
26032679
BodyGenCallbackTy BodyGenCB,
26042680
FinalizeCallbackTy FiniCB, Value *Filter);
26052681

2682+
/// This function performs the scan reduction of the values updated in
2683+
/// the input phase. The reduction logic needs to be emitted between input
2684+
/// and scan loop returned by `CreateCanonicalScanLoops`. The following
2685+
/// is the code that is generated, `buffer` and `span` are expected to be
2686+
/// populated before executing the generated code.
2687+
///
2688+
/// for (int k = 0; k != ceil(log2(span)); ++k) {
2689+
/// i=pow(2,k)
2690+
/// for (size cnt = last_iter; cnt >= i; --cnt)
2691+
/// buffer[cnt] op= buffer[cnt-i];
2692+
/// }
2693+
/// \param Loc The insert and source location description.
2694+
/// \param FinalizeIP The IP where the reduction result needs
2695+
// to be copied back to original variable.
2696+
/// \param ReductionInfos Array type containing the ReductionOps.
2697+
///
2698+
/// \returns The insertion position *after* the masked.
2699+
InsertPointOrErrorTy emitScanReduction(
2700+
const LocationDescription &Loc, InsertPointTy &FinalizeIP,
2701+
SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2702+
2703+
/// This directive split and directs the control flow to input phase
2704+
/// blocks or scan phase blocks based on 1. whether input loop or scan loop
2705+
/// is executed, 2. whether exclusive or inclusive scan is used.
2706+
///
2707+
/// \param Loc The insert and source location description.
2708+
/// \param AllocaIP The IP where the temporary buffer for scan reduction
2709+
// needs to be allocated.
2710+
/// \param ScanVars Scan Variables.
2711+
/// \param IsInclusive Whether it is an inclusive or exclusive scan.
2712+
///
2713+
/// \returns The insertion position *after* the masked.
2714+
InsertPointOrErrorTy createScan(const LocationDescription &Loc,
2715+
InsertPointTy AllocaIP,
2716+
ArrayRef<llvm::Value *> ScanVars,
2717+
bool IsInclusive);
26062718
/// Generator for '#omp critical'
26072719
///
26082720
/// \param Loc The insert and source location description.

0 commit comments

Comments
 (0)