|
16 | 16 | #include "flang/Lower/PFTBuilder.h" |
17 | 17 | #include "flang/Parser/tools.h" |
18 | 18 | #include "flang/Semantics/tools.h" |
| 19 | +#include "llvm/Frontend/OpenMP/OMPIRBuilder.h" |
19 | 20 |
|
20 | 21 | namespace Fortran { |
21 | 22 | namespace lower { |
@@ -514,6 +515,65 @@ bool ClauseProcessor::processUntied(mlir::omp::UntiedClauseOps &result) const { |
514 | 515 | //===----------------------------------------------------------------------===// |
515 | 516 | // ClauseProcessor repeatable clauses |
516 | 517 | //===----------------------------------------------------------------------===// |
| 518 | +static llvm::StringMap<bool> getTargetFeatures(mlir::ModuleOp module) { |
| 519 | + llvm::StringMap<bool> featuresMap; |
| 520 | + llvm::SmallVector<llvm::StringRef> targetFeaturesVec; |
| 521 | + if (mlir::LLVM::TargetFeaturesAttr features = |
| 522 | + fir::getTargetFeatures(module)) { |
| 523 | + llvm::ArrayRef<mlir::StringAttr> featureAttrs = features.getFeatures(); |
| 524 | + for (auto &featureAttr : featureAttrs) { |
| 525 | + llvm::StringRef featureKeyString = featureAttr.strref(); |
| 526 | + featuresMap[featureKeyString.substr(1)] = (featureKeyString[0] == '+'); |
| 527 | + } |
| 528 | + } |
| 529 | + return featuresMap; |
| 530 | +} |
| 531 | + |
| 532 | +static void |
| 533 | +addAlignedClause(lower::AbstractConverter &converter, |
| 534 | + const omp::clause::Aligned &clause, |
| 535 | + llvm::SmallVectorImpl<mlir::Value> &alignedVars, |
| 536 | + llvm::SmallVectorImpl<mlir::Attribute> &alignmentAttrs) { |
| 537 | + using Aligned = omp::clause::Aligned; |
| 538 | + lower::StatementContext stmtCtx; |
| 539 | + mlir::IntegerAttr alignmentValueAttr; |
| 540 | + int64_t alignment = 0; |
| 541 | + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); |
| 542 | + |
| 543 | + if (auto &alignmentValueParserExpr = |
| 544 | + std::get<std::optional<Aligned::Alignment>>(clause.t)) { |
| 545 | + mlir::Value operand = fir::getBase( |
| 546 | + converter.genExprValue(*alignmentValueParserExpr, stmtCtx)); |
| 547 | + alignment = *fir::getIntIfConstant(operand); |
| 548 | + } else { |
| 549 | + llvm::StringMap<bool> featuresMap = getTargetFeatures(builder.getModule()); |
| 550 | + llvm::Triple triple = fir::getTargetTriple(builder.getModule()); |
| 551 | + alignment = |
| 552 | + llvm::OpenMPIRBuilder::getOpenMPDefaultSimdAlign(triple, featuresMap); |
| 553 | + } |
| 554 | + |
| 555 | + // The default alignment for some targets is equal to 0. |
| 556 | + // Do not generate alignment assumption if alignment is less than or equal to |
| 557 | + // 0. |
| 558 | + if (alignment > 0) { |
| 559 | + auto &objects = std::get<omp::ObjectList>(clause.t); |
| 560 | + if (!objects.empty()) |
| 561 | + genObjectList(objects, converter, alignedVars); |
| 562 | + alignmentValueAttr = builder.getI64IntegerAttr(alignment); |
| 563 | + // All the list items in a aligned clause will have same alignment |
| 564 | + for (std::size_t i = 0; i < objects.size(); i++) |
| 565 | + alignmentAttrs.push_back(alignmentValueAttr); |
| 566 | + } |
| 567 | +} |
| 568 | + |
| 569 | +bool ClauseProcessor::processAligned( |
| 570 | + mlir::omp::AlignedClauseOps &result) const { |
| 571 | + return findRepeatableClause<omp::clause::Aligned>( |
| 572 | + [&](const omp::clause::Aligned &clause, const parser::CharBlock &) { |
| 573 | + addAlignedClause(converter, clause, result.alignedVars, |
| 574 | + result.alignmentAttrs); |
| 575 | + }); |
| 576 | +} |
517 | 577 |
|
518 | 578 | bool ClauseProcessor::processAllocate( |
519 | 579 | mlir::omp::AllocateClauseOps &result) const { |
|
0 commit comments