Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
213799 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Generic OpenACC lowering functions not Stmt, Decl, or clause specific.9//10//===----------------------------------------------------------------------===//1112#include "CIRGenFunction.h"13#include "mlir/Dialect/Arith/IR/Arith.h"14#include "mlir/Dialect/OpenACC/OpenACC.h"15#include "clang/AST/ExprCXX.h"1617using namespace clang;18using namespace clang::CIRGen;1920namespace {21mlir::Value createBound(CIRGenFunction &cgf, CIRGen::CIRGenBuilderTy &builder,22mlir::Location boundLoc, mlir::Value lowerBound,23mlir::Value upperBound, mlir::Value extent) {24// Arrays always have a start-idx of 0.25mlir::Value startIdx = cgf.createOpenACCConstantInt(boundLoc, 64, 0);26// Stride is always 1 in C/C++.27mlir::Value stride = cgf.createOpenACCConstantInt(boundLoc, 64, 1);2829auto bound =30builder.create<mlir::acc::DataBoundsOp>(boundLoc, lowerBound, upperBound);31bound.getStartIdxMutable().assign(startIdx);32if (extent)33bound.getExtentMutable().assign(extent);34bound.getStrideMutable().assign(stride);3536return bound;37}38} // namespace3940mlir::Value CIRGenFunction::emitOpenACCIntExpr(const Expr *intExpr) {41mlir::Value expr = emitScalarExpr(intExpr);42mlir::Location exprLoc = cgm.getLoc(intExpr->getBeginLoc());4344mlir::IntegerType targetType = mlir::IntegerType::get(45&getMLIRContext(), getContext().getIntWidth(intExpr->getType()),46intExpr->getType()->isSignedIntegerOrEnumerationType()47? mlir::IntegerType::SignednessSemantics::Signed48: mlir::IntegerType::SignednessSemantics::Unsigned);4950auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(51exprLoc, targetType, expr);52return conversionOp.getResult(0);53}5455mlir::Value CIRGenFunction::createOpenACCConstantInt(mlir::Location loc,56unsigned width,57int64_t value) {58mlir::IntegerType ty =59mlir::IntegerType::get(&getMLIRContext(), width,60mlir::IntegerType::SignednessSemantics::Signless);61auto constOp = builder.create<mlir::arith::ConstantOp>(62loc, builder.getIntegerAttr(ty, value));6364return constOp.getResult();65}6667CIRGenFunction::OpenACCDataOperandInfo68CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {69const Expr *curVarExpr = e->IgnoreParenImpCasts();7071mlir::Location exprLoc = cgm.getLoc(curVarExpr->getBeginLoc());72llvm::SmallVector<mlir::Value> bounds;7374std::string exprString;75llvm::raw_string_ostream os(exprString);76e->printPretty(os, nullptr, getContext().getPrintingPolicy());7778while (isa<ArraySectionExpr, ArraySubscriptExpr>(curVarExpr)) {79mlir::Location boundLoc = cgm.getLoc(curVarExpr->getBeginLoc());80mlir::Value lowerBound;81mlir::Value upperBound;82mlir::Value extent;8384if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr)) {85if (const Expr *lb = section->getLowerBound())86lowerBound = emitOpenACCIntExpr(lb);87else88lowerBound = createOpenACCConstantInt(boundLoc, 64, 0);8990if (const Expr *len = section->getLength()) {91extent = emitOpenACCIntExpr(len);92} else {93QualType baseTy = ArraySectionExpr::getBaseOriginalType(94section->getBase()->IgnoreParenImpCasts());95// We know this is the case as implicit lengths are only allowed for96// array types with a constant size, or a dependent size. AND since97// we are codegen we know we're not dependent.98auto *arrayTy = getContext().getAsConstantArrayType(baseTy);99// Rather than trying to calculate the extent based on the100// lower-bound, we can just emit this as an upper bound.101upperBound = createOpenACCConstantInt(boundLoc, 64,102arrayTy->getLimitedSize() - 1);103}104105curVarExpr = section->getBase()->IgnoreParenImpCasts();106} else {107const auto *subscript = cast<ArraySubscriptExpr>(curVarExpr);108109lowerBound = emitOpenACCIntExpr(subscript->getIdx());110// Length of an array index is always 1.111extent = createOpenACCConstantInt(boundLoc, 64, 1);112curVarExpr = subscript->getBase()->IgnoreParenImpCasts();113}114115bounds.push_back(createBound(*this, this->builder, boundLoc, lowerBound,116upperBound, extent));117}118119if (const auto *memExpr = dyn_cast<MemberExpr>(curVarExpr))120return {exprLoc, emitMemberExpr(memExpr).getPointer(), exprString,121std::move(bounds)};122123// Sema has made sure that only 4 types of things can get here, array124// subscript, array section, member expr, or DRE to a var decl (or the125// former 3 wrapping a var-decl), so we should be able to assume this is126// right.127const auto *dre = cast<DeclRefExpr>(curVarExpr);128return {exprLoc, emitDeclRefLValue(dre).getPointer(), exprString,129std::move(bounds)};130}131132133