Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions flang/include/flang/Optimizer/OpenMP/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ def LowerWorkshare : Pass<"lower-workshare", "::mlir::ModuleOp"> {
let summary = "Lower workshare construct";
}

def LowerWorkdistribute : Pass<"lower-workdistribute", "::mlir::ModuleOp"> {
let summary = "Lower workdistribute construct";
}

def GenericLoopConversionPass
: Pass<"omp-generic-loop-conversion", "mlir::func::FuncOp"> {
let summary = "Converts OpenMP generic `omp.loop` to semantically "
Expand Down
33 changes: 33 additions & 0 deletions flang/include/flang/Optimizer/Support/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"

#include "flang/Optimizer/CodeGen/TypeConverter.h"

namespace fir {
/// Return the integer value of a arith::ConstantOp.
inline std::int64_t toInt(mlir::arith::ConstantOp cop) {
Expand Down Expand Up @@ -198,6 +200,37 @@ std::optional<llvm::ArrayRef<int64_t>> getComponentLowerBoundsIfNonDefault(
fir::RecordType recordType, llvm::StringRef component,
mlir::ModuleOp module, const mlir::SymbolTable *symbolTable = nullptr);

/// Generate a LLVM constant value of type `ity`, using the provided offset.
mlir::LLVM::ConstantOp
genConstantIndex(mlir::Location loc, mlir::Type ity,
mlir::ConversionPatternRewriter &rewriter,
std::int64_t offset);

/// Helper function for generating the LLVM IR that computes the distance
/// in bytes between adjacent elements pointed to by a pointer
/// of type \p ptrTy. The result is returned as a value of \p idxTy integer
/// type.
mlir::Value computeElementDistance(mlir::Location loc,
mlir::Type llvmObjectType, mlir::Type idxTy,
mlir::ConversionPatternRewriter &rewriter,
const mlir::DataLayout &dataLayout);

// Compute the alloc scale size (constant factors encoded in the array type).
// We do this for arrays without a constant interior or arrays of character with
// dynamic length arrays, since those are the only ones that get decayed to a
// pointer to the element type.
mlir::Value genAllocationScaleSize(mlir::Location loc, mlir::Type dataTy,
mlir::Type ity,
mlir::ConversionPatternRewriter &rewriter);

/// Perform an extension or truncation as needed on an integer value. Lowering
/// to the specific target may involve some sign-extending or truncation of
/// values, particularly to fit them from abstract box types to the
/// appropriate reified structures.
mlir::Value integerCast(const fir::LLVMTypeConverter &converter,
mlir::Location loc,
mlir::ConversionPatternRewriter &rewriter,
mlir::Type ty, mlir::Value val, bool fold = false);
} // namespace fir

#endif // FORTRAN_OPTIMIZER_SUPPORT_UTILS_H
7 changes: 7 additions & 0 deletions flang/include/flang/Semantics/openmp-directive-sets.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ static const OmpDirectiveSet topTargetSet{
Directive::OMPD_target_teams_distribute_parallel_do_simd,
Directive::OMPD_target_teams_distribute_simd,
Directive::OMPD_target_teams_loop,
Directive::OMPD_target_teams_workdistribute,
};

static const OmpDirectiveSet allTargetSet{topTargetSet};
Expand Down Expand Up @@ -172,6 +173,7 @@ static const OmpDirectiveSet topTeamsSet{
Directive::OMPD_teams_distribute_parallel_do_simd,
Directive::OMPD_teams_distribute_simd,
Directive::OMPD_teams_loop,
Directive::OMPD_teams_workdistribute,
};

static const OmpDirectiveSet bottomTeamsSet{
Expand All @@ -187,6 +189,7 @@ static const OmpDirectiveSet allTeamsSet{
Directive::OMPD_target_teams_distribute_parallel_do_simd,
Directive::OMPD_target_teams_distribute_simd,
Directive::OMPD_target_teams_loop,
Directive::OMPD_target_teams_workdistribute,
} | topTeamsSet,
};

Expand Down Expand Up @@ -230,6 +233,9 @@ static const OmpDirectiveSet blockConstructSet{
Directive::OMPD_taskgroup,
Directive::OMPD_teams,
Directive::OMPD_workshare,
Directive::OMPD_target_teams_workdistribute,
Directive::OMPD_teams_workdistribute,
Directive::OMPD_workdistribute,
};

static const OmpDirectiveSet loopConstructSet{
Expand Down Expand Up @@ -376,6 +382,7 @@ static const OmpDirectiveSet nestedReduceWorkshareAllowedSet{
};

static const OmpDirectiveSet nestedTeamsAllowedSet{
Directive::OMPD_workdistribute,
Directive::OMPD_distribute,
Directive::OMPD_distribute_parallel_do,
Directive::OMPD_distribute_parallel_do_simd,
Expand Down
23 changes: 22 additions & 1 deletion flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,13 @@ static void processHostEvalClauses(lower::AbstractConverter &converter,
cp.processCollapse(loc, eval, hostInfo->ops, hostInfo->iv);
break;

case OMPD_teams_workdistribute:
cp.processThreadLimit(stmtCtx, hostInfo->ops);
[[fallthrough]];
case OMPD_target_teams_workdistribute:
cp.processNumTeams(stmtCtx, hostInfo->ops);
break;

// Standalone 'target' case.
case OMPD_target: {
processSingleNestedIf(
Expand Down Expand Up @@ -2631,6 +2638,17 @@ genTeamsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
queue, item, clauseOps);
}

static mlir::omp::WorkdistributeOp genWorkdistributeOp(
lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
mlir::Location loc, const ConstructQueue &queue,
ConstructQueue::const_iterator item) {
return genOpWithBody<mlir::omp::WorkdistributeOp>(
OpWithBodyGenInfo(converter, symTable, semaCtx, loc, eval,
llvm::omp::Directive::OMPD_workdistribute),
queue, item);
}

//===----------------------------------------------------------------------===//
// Code generation functions for the standalone version of constructs that can
// also be a leaf of a composite construct
Expand Down Expand Up @@ -3262,7 +3280,10 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
TODO(loc, "Unhandled loop directive (" +
llvm::omp::getOpenMPDirectiveName(dir, version) + ")");
}
// case llvm::omp::Directive::OMPD_workdistribute:
case llvm::omp::Directive::OMPD_workdistribute:
newOp = genWorkdistributeOp(converter, symTable, semaCtx, eval, loc, queue,
item);
break;
case llvm::omp::Directive::OMPD_workshare:
newOp = genWorkshareOp(converter, symTable, stmtCtx, semaCtx, eval, loc,
queue, item);
Expand Down
Loading