Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
213799 views
1
//===----------------------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Generic OpenACC lowering functions not Stmt, Decl, or clause specific.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "CIRGenFunction.h"
14
#include "mlir/Dialect/Arith/IR/Arith.h"
15
#include "mlir/Dialect/OpenACC/OpenACC.h"
16
#include "clang/AST/ExprCXX.h"
17
18
using namespace clang;
19
using namespace clang::CIRGen;
20
21
namespace {
22
mlir::Value createBound(CIRGenFunction &cgf, CIRGen::CIRGenBuilderTy &builder,
23
mlir::Location boundLoc, mlir::Value lowerBound,
24
mlir::Value upperBound, mlir::Value extent) {
25
// Arrays always have a start-idx of 0.
26
mlir::Value startIdx = cgf.createOpenACCConstantInt(boundLoc, 64, 0);
27
// Stride is always 1 in C/C++.
28
mlir::Value stride = cgf.createOpenACCConstantInt(boundLoc, 64, 1);
29
30
auto bound =
31
builder.create<mlir::acc::DataBoundsOp>(boundLoc, lowerBound, upperBound);
32
bound.getStartIdxMutable().assign(startIdx);
33
if (extent)
34
bound.getExtentMutable().assign(extent);
35
bound.getStrideMutable().assign(stride);
36
37
return bound;
38
}
39
} // namespace
40
41
mlir::Value CIRGenFunction::emitOpenACCIntExpr(const Expr *intExpr) {
42
mlir::Value expr = emitScalarExpr(intExpr);
43
mlir::Location exprLoc = cgm.getLoc(intExpr->getBeginLoc());
44
45
mlir::IntegerType targetType = mlir::IntegerType::get(
46
&getMLIRContext(), getContext().getIntWidth(intExpr->getType()),
47
intExpr->getType()->isSignedIntegerOrEnumerationType()
48
? mlir::IntegerType::SignednessSemantics::Signed
49
: mlir::IntegerType::SignednessSemantics::Unsigned);
50
51
auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
52
exprLoc, targetType, expr);
53
return conversionOp.getResult(0);
54
}
55
56
mlir::Value CIRGenFunction::createOpenACCConstantInt(mlir::Location loc,
57
unsigned width,
58
int64_t value) {
59
mlir::IntegerType ty =
60
mlir::IntegerType::get(&getMLIRContext(), width,
61
mlir::IntegerType::SignednessSemantics::Signless);
62
auto constOp = builder.create<mlir::arith::ConstantOp>(
63
loc, builder.getIntegerAttr(ty, value));
64
65
return constOp.getResult();
66
}
67
68
CIRGenFunction::OpenACCDataOperandInfo
69
CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {
70
const Expr *curVarExpr = e->IgnoreParenImpCasts();
71
72
mlir::Location exprLoc = cgm.getLoc(curVarExpr->getBeginLoc());
73
llvm::SmallVector<mlir::Value> bounds;
74
75
std::string exprString;
76
llvm::raw_string_ostream os(exprString);
77
e->printPretty(os, nullptr, getContext().getPrintingPolicy());
78
79
while (isa<ArraySectionExpr, ArraySubscriptExpr>(curVarExpr)) {
80
mlir::Location boundLoc = cgm.getLoc(curVarExpr->getBeginLoc());
81
mlir::Value lowerBound;
82
mlir::Value upperBound;
83
mlir::Value extent;
84
85
if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr)) {
86
if (const Expr *lb = section->getLowerBound())
87
lowerBound = emitOpenACCIntExpr(lb);
88
else
89
lowerBound = createOpenACCConstantInt(boundLoc, 64, 0);
90
91
if (const Expr *len = section->getLength()) {
92
extent = emitOpenACCIntExpr(len);
93
} else {
94
QualType baseTy = ArraySectionExpr::getBaseOriginalType(
95
section->getBase()->IgnoreParenImpCasts());
96
// We know this is the case as implicit lengths are only allowed for
97
// array types with a constant size, or a dependent size. AND since
98
// we are codegen we know we're not dependent.
99
auto *arrayTy = getContext().getAsConstantArrayType(baseTy);
100
// Rather than trying to calculate the extent based on the
101
// lower-bound, we can just emit this as an upper bound.
102
upperBound = createOpenACCConstantInt(boundLoc, 64,
103
arrayTy->getLimitedSize() - 1);
104
}
105
106
curVarExpr = section->getBase()->IgnoreParenImpCasts();
107
} else {
108
const auto *subscript = cast<ArraySubscriptExpr>(curVarExpr);
109
110
lowerBound = emitOpenACCIntExpr(subscript->getIdx());
111
// Length of an array index is always 1.
112
extent = createOpenACCConstantInt(boundLoc, 64, 1);
113
curVarExpr = subscript->getBase()->IgnoreParenImpCasts();
114
}
115
116
bounds.push_back(createBound(*this, this->builder, boundLoc, lowerBound,
117
upperBound, extent));
118
}
119
120
if (const auto *memExpr = dyn_cast<MemberExpr>(curVarExpr))
121
return {exprLoc, emitMemberExpr(memExpr).getPointer(), exprString,
122
std::move(bounds)};
123
124
// Sema has made sure that only 4 types of things can get here, array
125
// subscript, array section, member expr, or DRE to a var decl (or the
126
// former 3 wrapping a var-decl), so we should be able to assume this is
127
// right.
128
const auto *dre = cast<DeclRefExpr>(curVarExpr);
129
return {exprLoc, emitDeclRefLValue(dre).getPointer(), exprString,
130
std::move(bounds)};
131
}
132
133