Skip to content

Commit 8e0683c

Browse files
committed
IR Builder Changes to Support Scan Operation
1 parent 7450580 commit 8e0683c

File tree

3 files changed

+651
-5
lines changed

3 files changed

+651
-5
lines changed

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

Lines changed: 134 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,30 @@ class OpenMPIRBuilder {
511511
return allocaInst;
512512
}
513513
};
514+
515+
struct ScanInformation {
516+
/// Dominates the body of the loop before scan directive
517+
llvm::BasicBlock *OMPBeforeScanBlock = nullptr;
518+
/// Dominates the body of the loop before scan directive
519+
llvm::BasicBlock *OMPAfterScanBlock = nullptr;
520+
/// Controls the flow to before or after scan blocks
521+
llvm::BasicBlock *OMPScanDispatch = nullptr;
522+
/// Exit block of loop body
523+
llvm::BasicBlock *OMPScanLoopExit = nullptr;
524+
/// Block before loop body where scan initializations are done
525+
llvm::BasicBlock *OMPScanInit = nullptr;
526+
/// Block after loop body where scan finalizations are done
527+
llvm::BasicBlock *OMPScanFinish = nullptr;
528+
/// If true, it indicates Input phase is lowered; else it indicates
529+
/// ScanPhase is lowered
530+
bool OMPFirstScanLoop = false;
531+
// Maps the private reduction variable to the pointer of the temporary
532+
// buffer
533+
llvm::SmallDenseMap<llvm::Value *, llvm::Value *> ScanBuffPtrs;
534+
llvm::Value *IV;
535+
llvm::Value *Span;
536+
} ScanInfo;
537+
514538
/// Initialize the internal state, this will put structures types and
515539
/// potentially other helpers into the underlying module. Must be called
516540
/// before any other method and only once! This internal state includes types
@@ -750,6 +774,35 @@ class OpenMPIRBuilder {
750774
LoopBodyGenCallbackTy BodyGenCB, Value *TripCount,
751775
const Twine &Name = "loop");
752776

777+
/// Generator for the control flow structure of an OpenMP canonical loops if
778+
/// the parent directive has an `inscan` modifier specified.
779+
/// If the `inscan` modifier is specified, the region of the parent is
780+
/// expected to have a `scan` directive. Based on the clauses in
781+
/// scan directive, the body of the loop is split into two loops: Input loop
782+
/// and Scan Loop. Input loop contains the code generated for input phase of
783+
/// scan and Scan loop contains the code generated for scan phase of scan.
784+
///
785+
/// \param Loc The insert and source location description.
786+
/// \param BodyGenCB Callback that will generate the loop body code.
787+
/// \param Start Value of the loop counter for the first iterations.
788+
/// \param Stop Loop counter values past this will stop the loop.
789+
/// \param Step Loop counter increment after each iteration; negative
790+
/// means counting down.
791+
/// \param IsSigned Whether Start, Stop and Step are signed integers.
792+
/// \param InclusiveStop Whether \p Stop itself is a valid value for the loop
793+
/// counter.
794+
/// \param ComputeIP Insertion point for instructions computing the trip
795+
/// count. Can be used to ensure the trip count is available
796+
/// at the outermost loop of a loop nest. If not set,
797+
/// defaults to the preheader of the generated loop.
798+
/// \param Name Base name used to derive BB and instruction names.
799+
///
800+
/// \returns A vector containing Loop Info of Input Loop and Scan Loop.
801+
Expected<SmallVector<llvm::CanonicalLoopInfo *>> createCanonicalScanLoops(
802+
const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
803+
Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
804+
InsertPointTy ComputeIP, const Twine &Name);
805+
753806
/// Calculate the trip count of a canonical loop.
754807
///
755808
/// This allows specifying user-defined loop counter values using increment,
@@ -818,13 +871,16 @@ class OpenMPIRBuilder {
818871
/// at the outermost loop of a loop nest. If not set,
819872
/// defaults to the preheader of the generated loop.
820873
/// \param Name Base name used to derive BB and instruction names.
874+
/// \param InScan Whether loop has a scan reduction specified.
821875
///
822876
/// \returns An object representing the created control flow structure which
823877
/// can be used for loop-associated directives.
824-
LLVM_ABI Expected<CanonicalLoopInfo *> createCanonicalLoop(
825-
const LocationDescription &Loc, LoopBodyGenCallbackTy BodyGenCB,
826-
Value *Start, Value *Stop, Value *Step, bool IsSigned, bool InclusiveStop,
827-
InsertPointTy ComputeIP = {}, const Twine &Name = "loop");
878+
LLVM_ABI Expected<CanonicalLoopInfo *>
879+
createCanonicalLoop(const LocationDescription &Loc,
880+
LoopBodyGenCallbackTy BodyGenCB, Value *Start,
881+
Value *Stop, Value *Step, bool IsSigned,
882+
bool InclusiveStop, InsertPointTy ComputeIP = {},
883+
const Twine &Name = "loop", bool InScan = false);
828884

829885
/// Collapse a loop nest into a single loop.
830886
///
@@ -1556,6 +1612,45 @@ class OpenMPIRBuilder {
15561612
ArrayRef<OpenMPIRBuilder::ReductionInfo> ReductionInfos,
15571613
Function *ReduceFn, AttributeList FuncAttrs);
15581614

1615+
/// Creates the runtime call specified
1616+
/// \param Callee Function Declaration Value
1617+
/// \param Args Arguments passed to the call
1618+
/// \param Name Optional param to specify the name of the call Instruction.
1619+
///
1620+
/// \return The Runtime call instruction created.
1621+
llvm::CallInst *emitNoUnwindRuntimeCall(llvm::FunctionCallee Callee,
1622+
ArrayRef<llvm::Value *> Args,
1623+
const llvm::Twine &Name);
1624+
1625+
/// Helper function for CreateCanonicalScanLoops to create InputLoop
1626+
/// in the firstGen and Scan Loop in the SecondGen
1627+
/// \param InputLoopGen Callback for generating the loop for input phase
1628+
/// \param ScanLoopGen Callback for generating the loop for scan phase
1629+
///
1630+
/// \return error if any produced, else return success.
1631+
Error emitScanBasedDirectiveIR(
1632+
llvm::function_ref<Error()> InputLoopGen,
1633+
llvm::function_ref<Error(LocationDescription Loc)> ScanLoopGen);
1634+
1635+
/// Creates the basic blocks required for scan reduction.
1636+
void createScanBBs();
1637+
1638+
/// Dynamically allocates the buffer needed for scan reduction.
1639+
/// \param AllocaIP The IP where possibly-shared pointer of buffer needs to be
1640+
/// declared. \param ScanVars Scan Variables.
1641+
///
1642+
/// \return error if any produced, else return success.
1643+
Error emitScanBasedDirectiveDeclsIR(InsertPointTy AllocaIP,
1644+
ArrayRef<llvm::Value *> ScanVars,
1645+
ArrayRef<llvm::Type *> ScanVarsType);
1646+
1647+
/// Copies the result back to the reduction variable.
1648+
/// \param ReductionInfos Array type containing the ReductionOps.
1649+
///
1650+
/// \return error if any produced, else return success.
1651+
Error emitScanBasedDirectiveFinalsIR(
1652+
SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
1653+
15591654
/// This function emits a helper that gathers Reduce lists from the first
15601655
/// lane of every active warp to lanes in the first warp.
15611656
///
@@ -2639,6 +2734,41 @@ class OpenMPIRBuilder {
26392734
FinalizeCallbackTy FiniCB,
26402735
Value *Filter);
26412736

2737+
/// This function performs the scan reduction of the values updated in
2738+
/// the input phase. The reduction logic needs to be emitted between input
2739+
/// and scan loop returned by `CreateCanonicalScanLoops`. The following
2740+
/// is the code that is generated, `buffer` and `span` are expected to be
2741+
/// populated before executing the generated code.
2742+
///
2743+
/// for (int k = 0; k != ceil(log2(span)); ++k) {
2744+
/// i=pow(2,k)
2745+
/// for (size cnt = last_iter; cnt >= i; --cnt)
2746+
/// buffer[cnt] op= buffer[cnt-i];
2747+
/// }
2748+
/// \param Loc The insert and source location description.
2749+
/// \param ReductionInfos Array type containing the ReductionOps.
2750+
///
2751+
/// \returns The insertion position *after* the masked.
2752+
InsertPointOrErrorTy emitScanReduction(
2753+
const LocationDescription &Loc,
2754+
SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos);
2755+
2756+
/// This directive split and directs the control flow to input phase
2757+
/// blocks or scan phase blocks based on 1. whether input loop or scan loop
2758+
/// is executed, 2. whether exclusive or inclusive scan is used.
2759+
///
2760+
/// \param Loc The insert and source location description.
2761+
/// \param AllocaIP The IP where the temporary buffer for scan reduction
2762+
// needs to be allocated.
2763+
/// \param ScanVars Scan Variables.
2764+
/// \param IsInclusive Whether it is an inclusive or exclusive scan.
2765+
///
2766+
/// \returns The insertion position *after* the scan.
2767+
InsertPointOrErrorTy createScan(const LocationDescription &Loc,
2768+
InsertPointTy AllocaIP,
2769+
ArrayRef<llvm::Value *> ScanVars,
2770+
ArrayRef<llvm::Type *> ScanVarsType,
2771+
bool IsInclusive);
26422772
/// Generator for '#omp critical'
26432773
///
26442774
/// \param Loc The insert and source location description.

0 commit comments

Comments
 (0)