Thanks to visit codestin.com
Credit goes to clang.llvm.org

clang 22.0.0git
CIRGenOpenACC.cpp
Go to the documentation of this file.
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
18using namespace clang;
19using namespace clang::CIRGen;
20
21namespace {
22mlir::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
41mlir::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()),
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
56mlir::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
70 const Expr *curVarExpr = e->IgnoreParenImpCasts();
71 QualType origType =
73 // Array sections are special, and we have to treat them that way.
74 if (const auto *section =
75 dyn_cast<ArraySectionExpr>(curVarExpr->IgnoreParenImpCasts()))
76 origType = ArraySectionExpr::getBaseOriginalType(section);
77
78 mlir::Location exprLoc = cgm.getLoc(curVarExpr->getBeginLoc());
81
82 std::string exprString;
83 llvm::raw_string_ostream os(exprString);
84 e->printPretty(os, nullptr, getContext().getPrintingPolicy());
85
86 auto addBoundType = [&](const Expr *e) {
87 if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr)) {
89 section->getBase()->IgnoreParenImpCasts());
90 boundTypes.push_back(QualType(baseTy->getPointeeOrArrayElementType(), 0));
91 } else {
92 boundTypes.push_back(curVarExpr->getType());
93 }
94 };
95
96 addBoundType(curVarExpr);
97
99 mlir::Location boundLoc = cgm.getLoc(curVarExpr->getBeginLoc());
100 mlir::Value lowerBound;
101 mlir::Value upperBound;
102 mlir::Value extent;
103
104 if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr)) {
105 if (const Expr *lb = section->getLowerBound())
106 lowerBound = emitOpenACCIntExpr(lb);
107 else
108 lowerBound = createOpenACCConstantInt(boundLoc, 64, 0);
109
110 if (const Expr *len = section->getLength()) {
111 extent = emitOpenACCIntExpr(len);
112 } else {
114 section->getBase()->IgnoreParenImpCasts());
115 // We know this is the case as implicit lengths are only allowed for
116 // array types with a constant size, or a dependent size. AND since
117 // we are codegen we know we're not dependent.
118 auto *arrayTy = getContext().getAsConstantArrayType(baseTy);
119 // Rather than trying to calculate the extent based on the
120 // lower-bound, we can just emit this as an upper bound.
121 upperBound = createOpenACCConstantInt(boundLoc, 64,
122 arrayTy->getLimitedSize() - 1);
123 }
124
125 curVarExpr = section->getBase()->IgnoreParenImpCasts();
126 } else {
127 const auto *subscript = cast<ArraySubscriptExpr>(curVarExpr);
128
129 lowerBound = emitOpenACCIntExpr(subscript->getIdx());
130 // Length of an array index is always 1.
131 extent = createOpenACCConstantInt(boundLoc, 64, 1);
132 curVarExpr = subscript->getBase()->IgnoreParenImpCasts();
133 }
134
135 bounds.push_back(createBound(*this, this->builder, boundLoc, lowerBound,
136 upperBound, extent));
137 addBoundType(curVarExpr);
138 }
139
140 if (const auto *memExpr = dyn_cast<MemberExpr>(curVarExpr))
141 return {exprLoc,
142 emitMemberExpr(memExpr).getPointer(),
143 exprString,
144 origType,
146 std::move(bounds),
147 std::move(boundTypes)};
148
149 // Sema has made sure that only 4 types of things can get here, array
150 // subscript, array section, member expr, or DRE to a var decl (or the
151 // former 3 wrapping a var-decl), so we should be able to assume this is
152 // right.
153 const auto *dre = cast<DeclRefExpr>(curVarExpr);
154 return {exprLoc,
156 exprString,
157 origType,
159 std::move(bounds),
160 std::move(boundTypes)};
161}
Defines the clang::Expr interface and subclasses for C++ expressions.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition Expr.cpp:5265
LValue emitMemberExpr(const MemberExpr *e)
OpenACCDataOperandInfo getOpenACCDataOperandInfo(const Expr *e)
mlir::Value emitScalarExpr(const clang::Expr *e)
Emit the computation of the specified expression of scalar type.
mlir::Value emitOpenACCIntExpr(const Expr *intExpr)
mlir::MLIRContext & getMLIRContext()
mlir::Value createOpenACCConstantInt(mlir::Location loc, unsigned width, int64_t value)
LValue emitDeclRefLValue(const clang::DeclRefExpr *e)
clang::ASTContext & getContext() const
mlir::Value getPointer() const
This represents one expression.
Definition Expr.h:112
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3085
QualType getType() const
Definition Expr.h:144
A (possibly-)qualified type.
Definition TypeBase.h:937
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8470
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8379
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:346
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Definition Type.cpp:2225
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
Definition TypeBase.h:9058
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
U cast(CodeGen::Address addr)
Definition Address.h:327