Skip to content

Commit 3ab7e52

Browse files
NimishMishraTIFitis
authored andcommitted
[llvm][mlir][OpenMP] Support translation for linear clause in omp.wsloop and omp.simd (llvm#139386)
This patch adds support for LLVM translation of linear clause on omp.wsloop (except for linear modifiers).
1 parent cf6797a commit 3ab7e52

File tree

11 files changed

+283
-109
lines changed

11 files changed

+283
-109
lines changed

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,49 @@ bool ClauseProcessor::processIsDevicePtr(
12351235
});
12361236
}
12371237

1238+
bool ClauseProcessor::processLinear(mlir::omp::LinearClauseOps &result) const {
1239+
lower::StatementContext stmtCtx;
1240+
return findRepeatableClause<
1241+
omp::clause::Linear>([&](const omp::clause::Linear &clause,
1242+
const parser::CharBlock &) {
1243+
auto &objects = std::get<omp::ObjectList>(clause.t);
1244+
static std::vector<mlir::Attribute> typeAttrs;
1245+
1246+
if (!result.linearVars.size())
1247+
typeAttrs.clear();
1248+
1249+
for (const omp::Object &object : objects) {
1250+
semantics::Symbol *sym = object.sym();
1251+
const mlir::Value variable = converter.getSymbolAddress(*sym);
1252+
result.linearVars.push_back(variable);
1253+
mlir::Type ty = converter.genType(*sym);
1254+
typeAttrs.push_back(mlir::TypeAttr::get(ty));
1255+
}
1256+
result.linearVarTypes =
1257+
mlir::ArrayAttr::get(&converter.getMLIRContext(), typeAttrs);
1258+
if (objects.size()) {
1259+
if (auto &mod =
1260+
std::get<std::optional<omp::clause::Linear::StepComplexModifier>>(
1261+
clause.t)) {
1262+
mlir::Value operand =
1263+
fir::getBase(converter.genExprValue(toEvExpr(*mod), stmtCtx));
1264+
result.linearStepVars.append(objects.size(), operand);
1265+
} else if (std::get<std::optional<omp::clause::Linear::LinearModifier>>(
1266+
clause.t)) {
1267+
mlir::Location currentLocation = converter.getCurrentLocation();
1268+
TODO(currentLocation, "Linear modifiers not yet implemented");
1269+
} else {
1270+
// If nothing is present, add the default step of 1.
1271+
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
1272+
mlir::Location currentLocation = converter.getCurrentLocation();
1273+
mlir::Value operand = firOpBuilder.createIntegerConstant(
1274+
currentLocation, firOpBuilder.getI32Type(), 1);
1275+
result.linearStepVars.append(objects.size(), operand);
1276+
}
1277+
}
1278+
});
1279+
}
1280+
12381281
bool ClauseProcessor::processLink(
12391282
llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &result) const {
12401283
return findRepeatableClause<omp::clause::Link>(

flang/lib/Lower/OpenMP/ClauseProcessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class ClauseProcessor {
130130
processEnter(llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &result) const;
131131
bool processIf(omp::clause::If::DirectiveNameModifier directiveName,
132132
mlir::omp::IfClauseOps &result) const;
133+
bool processLinear(mlir::omp::LinearClauseOps &result) const;
133134
bool processInReduction(
134135
mlir::Location currentLocation, mlir::omp::InReductionClauseOps &result,
135136
llvm::SmallVectorImpl<const semantics::Symbol *> &outReductionSyms) const;

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,8 +1642,7 @@ static void genSimdClauses(
16421642
cp.processReduction(loc, clauseOps, reductionSyms);
16431643
cp.processSafelen(clauseOps);
16441644
cp.processSimdlen(clauseOps);
1645-
1646-
cp.processTODO<clause::Linear>(loc, llvm::omp::Directive::OMPD_simd);
1645+
cp.processLinear(clauseOps);
16471646
}
16481647

16491648
static void genSingleClauses(lower::AbstractConverter &converter,
@@ -1839,9 +1838,9 @@ static void genWsloopClauses(
18391838
cp.processOrdered(clauseOps);
18401839
cp.processReduction(loc, clauseOps, reductionSyms);
18411840
cp.processSchedule(stmtCtx, clauseOps);
1841+
cp.processLinear(clauseOps);
18421842

1843-
cp.processTODO<clause::Allocate, clause::Linear>(
1844-
loc, llvm::omp::Directive::OMPD_do);
1843+
cp.processTODO<clause::Allocate>(loc, llvm::omp::Directive::OMPD_do);
18451844
}
18461845

18471846
//===----------------------------------------------------------------------===//

flang/test/Lower/OpenMP/Todo/omp-do-simd-linear.f90

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
! This test checks lowering of OpenMP SIMD Directive
2+
! with linear clause
3+
4+
! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - 2>&1 | FileCheck %s
5+
6+
!CHECK: %[[X_alloca:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFsimple_linearEx"}
7+
!CHECK: %[[X:.*]]:2 = hlfir.declare %[[X_alloca]] {uniq_name = "_QFsimple_linearEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
8+
!CHECK: %[[const:.*]] = arith.constant 1 : i32
9+
subroutine simple_linear
10+
implicit none
11+
integer :: x, y, i
12+
!CHECK: omp.simd linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>) {{.*}}
13+
!$omp simd linear(x)
14+
!CHECK: %[[LOAD:.*]] = fir.load %[[X]]#0 : !fir.ref<i32>
15+
!CHECK: %[[const:.*]] = arith.constant 2 : i32
16+
!CHECK: %[[RESULT:.*]] = arith.addi %[[LOAD]], %[[const]] : i32
17+
do i = 1, 10
18+
y = x + 2
19+
end do
20+
!CHECK: } {linear_var_types = [i32]}
21+
end subroutine
22+
23+
24+
!CHECK: %[[X_alloca:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFlinear_stepEx"}
25+
!CHECK: %[[X:.*]]:2 = hlfir.declare %[[X_alloca]] {uniq_name = "_QFlinear_stepEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
26+
subroutine linear_step
27+
implicit none
28+
integer :: x, y, i
29+
!CHECK: %[[const:.*]] = arith.constant 4 : i32
30+
!CHECK: omp.simd linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>) {{.*}}
31+
!$omp simd linear(x:4)
32+
!CHECK: %[[LOAD:.*]] = fir.load %[[X]]#0 : !fir.ref<i32>
33+
!CHECK: %[[const:.*]] = arith.constant 2 : i32
34+
!CHECK: %[[RESULT:.*]] = arith.addi %[[LOAD]], %[[const]] : i32
35+
do i = 1, 10
36+
y = x + 2
37+
end do
38+
!CHECK: } {linear_var_types = [i32]}
39+
end subroutine
40+
41+
!CHECK: %[[A_alloca:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFlinear_exprEa"}
42+
!CHECK: %[[A:.*]]:2 = hlfir.declare %[[A_alloca]] {uniq_name = "_QFlinear_exprEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
43+
!CHECK: %[[X_alloca:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFlinear_exprEx"}
44+
!CHECK: %[[X:.*]]:2 = hlfir.declare %[[X_alloca]] {uniq_name = "_QFlinear_exprEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
45+
subroutine linear_expr
46+
implicit none
47+
integer :: x, y, i, a
48+
!CHECK: %[[LOAD_A:.*]] = fir.load %[[A]]#0 : !fir.ref<i32>
49+
!CHECK: %[[const:.*]] = arith.constant 4 : i32
50+
!CHECK: %[[LINEAR_EXPR:.*]] = arith.addi %[[LOAD_A]], %[[const]] : i32
51+
!CHECK: omp.simd linear(%[[X]]#0 = %[[LINEAR_EXPR]] : !fir.ref<i32>) {{.*}}
52+
!$omp simd linear(x:a+4)
53+
do i = 1, 10
54+
y = x + 2
55+
end do
56+
!CHECK: } {linear_var_types = [i32]}
57+
end subroutine

flang/test/Lower/OpenMP/wsloop-linear.f90

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
! This test checks lowering of OpenMP DO Directive (Worksharing)
22
! with linear clause
3-
! XFAIL: *
3+
44
! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - 2>&1 | FileCheck %s
55

66
!CHECK: %[[X_alloca:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFsimple_linearEx"}
@@ -18,6 +18,7 @@ subroutine simple_linear
1818
y = x + 2
1919
end do
2020
!$omp end do
21+
!CHECK: } {linear_var_types = [i32]}
2122
end subroutine
2223

2324

@@ -31,11 +32,12 @@ subroutine linear_step
3132
!$omp do linear(x:4)
3233
!CHECK: %[[LOAD:.*]] = fir.load %[[X]]#0 : !fir.ref<i32>
3334
!CHECK: %[[const:.*]] = arith.constant 2 : i32
34-
!CHECK: %[[RESULT:.*]] = arith.addi %[[LOAD]], %[[const]] : i32
35+
!CHECK: %[[RESULT:.*]] = arith.addi %[[LOAD]], %[[const]] : i32
3536
do i = 1, 10
3637
y = x + 2
3738
end do
3839
!$omp end do
40+
!CHECK: } {linear_var_types = [i32]}
3941
end subroutine
4042

4143
!CHECK: %[[A_alloca:.*]] = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFlinear_exprEa"}
@@ -54,4 +56,5 @@ subroutine linear_expr
5456
y = x + 2
5557
end do
5658
!$omp end do
59+
!CHECK: } {linear_var_types = [i32]}
5760
end subroutine

mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
include "mlir/Dialect/OpenMP/OpenMPOpBase.td"
2323
include "mlir/Interfaces/SideEffectInterfaces.td"
2424
include "mlir/IR/SymbolInterfaces.td"
25+
include "mlir/IR/BuiltinAttributes.td"
2526

2627
//===----------------------------------------------------------------------===//
2728
// V5.2: [6.3] `align` clause
@@ -776,10 +777,9 @@ class OpenMP_LinearClauseSkip<
776777
bit description = false, bit extraClassDeclaration = false
777778
> : OpenMP_Clause<traits, arguments, assemblyFormat, description,
778779
extraClassDeclaration> {
779-
let arguments = (ins
780-
Variadic<AnyType>:$linear_vars,
781-
Variadic<I32>:$linear_step_vars
782-
);
780+
let arguments = (ins Variadic<AnyType>:$linear_vars,
781+
Variadic<I32>:$linear_step_vars,
782+
OptionalAttr<ArrayAttr>:$linear_var_types);
783783

784784
let optAssemblyFormat = [{
785785
`linear` `(`

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,6 +2862,7 @@ void WsloopOp::build(OpBuilder &builder, OperationState &state,
28622862
ArrayRef<NamedAttribute> attributes) {
28632863
build(builder, state, /*allocate_vars=*/{}, /*allocator_vars=*/{},
28642864
/*linear_vars=*/ValueRange(), /*linear_step_vars=*/ValueRange(),
2865+
/*linear_var_types*/ nullptr,
28652866
/*nowait=*/false, /*order=*/nullptr, /*order_mod=*/nullptr,
28662867
/*ordered=*/nullptr, /*private_vars=*/{}, /*private_syms=*/nullptr,
28672868
/*private_needs_barrier=*/false,
@@ -2880,8 +2881,8 @@ void WsloopOp::build(OpBuilder &builder, OperationState &state,
28802881
WsloopOp::build(
28812882
builder, state,
28822883
/*allocate_vars=*/{}, /*allocator_vars=*/{}, clauses.linearVars,
2883-
clauses.linearStepVars, clauses.nowait, clauses.order, clauses.orderMod,
2884-
clauses.ordered, clauses.privateVars,
2884+
clauses.linearStepVars, clauses.linearVarTypes, clauses.nowait,
2885+
clauses.order, clauses.orderMod, clauses.ordered, clauses.privateVars,
28852886
makeArrayAttr(ctx, clauses.privateSyms), clauses.privateNeedsBarrier,
28862887
clauses.reductionMod, clauses.reductionVars,
28872888
makeDenseBoolArrayAttr(ctx, clauses.reductionByref),
@@ -2926,17 +2927,16 @@ LogicalResult WsloopOp::verifyRegions() {
29262927
void SimdOp::build(OpBuilder &builder, OperationState &state,
29272928
const SimdOperands &clauses) {
29282929
MLIRContext *ctx = builder.getContext();
2929-
// TODO Store clauses in op: linearVars, linearStepVars
2930-
SimdOp::build(builder, state, clauses.alignedVars,
2931-
makeArrayAttr(ctx, clauses.alignments), clauses.ifExpr,
2932-
/*linear_vars=*/{}, /*linear_step_vars=*/{},
2933-
clauses.nontemporalVars, clauses.order, clauses.orderMod,
2934-
clauses.privateVars, makeArrayAttr(ctx, clauses.privateSyms),
2935-
clauses.privateNeedsBarrier, clauses.reductionMod,
2936-
clauses.reductionVars,
2937-
makeDenseBoolArrayAttr(ctx, clauses.reductionByref),
2938-
makeArrayAttr(ctx, clauses.reductionSyms), clauses.safelen,
2939-
clauses.simdlen);
2930+
SimdOp::build(
2931+
builder, state, clauses.alignedVars,
2932+
makeArrayAttr(ctx, clauses.alignments), clauses.ifExpr,
2933+
clauses.linearVars, clauses.linearStepVars, clauses.linearVarTypes,
2934+
clauses.nontemporalVars, clauses.order, clauses.orderMod,
2935+
clauses.privateVars, makeArrayAttr(ctx, clauses.privateSyms),
2936+
clauses.privateNeedsBarrier, clauses.reductionMod, clauses.reductionVars,
2937+
makeDenseBoolArrayAttr(ctx, clauses.reductionByref),
2938+
makeArrayAttr(ctx, clauses.reductionSyms), clauses.safelen,
2939+
clauses.simdlen);
29402940
}
29412941

29422942
LogicalResult SimdOp::verify() {

0 commit comments

Comments
 (0)