brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · e7bf3bc Raw
158 lines · cpp
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-exception6//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 = mlir::acc::DataBoundsOp::create(builder, boundLoc, lowerBound,31                                               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} // namespace40 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()),47      intExpr->getType()->isSignedIntegerOrEnumerationType()48          ? mlir::IntegerType::SignednessSemantics::Signed49          : mlir::IntegerType::SignednessSemantics::Unsigned);50 51  auto conversionOp = mlir::UnrealizedConversionCastOp::create(52      builder, 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 = mlir::arith::ConstantOp::create(63      builder, loc, builder.getIntegerAttr(ty, value));64 65  return constOp;66}67 68CIRGenFunction::OpenACCDataOperandInfo69CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {70  const Expr *curVarExpr = e->IgnoreParenImpCasts();71  QualType origType =72      curVarExpr->getType().getNonReferenceType().getUnqualifiedType();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 = section->getElementType();77 78  mlir::Location exprLoc = cgm.getLoc(curVarExpr->getBeginLoc());79  llvm::SmallVector<mlir::Value> bounds;80  llvm::SmallVector<QualType> boundTypes;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))88      boundTypes.push_back(section->getElementType());89    else90      boundTypes.push_back(curVarExpr->getType());91  };92 93  addBoundType(curVarExpr);94 95  while (isa<ArraySectionExpr, ArraySubscriptExpr>(curVarExpr)) {96    mlir::Location boundLoc = cgm.getLoc(curVarExpr->getBeginLoc());97    mlir::Value lowerBound;98    mlir::Value upperBound;99    mlir::Value extent;100 101    if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr)) {102      if (const Expr *lb = section->getLowerBound())103        lowerBound = emitOpenACCIntExpr(lb);104      else105        lowerBound = createOpenACCConstantInt(boundLoc, 64, 0);106 107      if (const Expr *len = section->getLength()) {108        extent = emitOpenACCIntExpr(len);109      } else {110        QualType baseTy = section->getBaseType();111        // We know this is the case as implicit lengths are only allowed for112        // array types with a constant size, or a dependent size.  AND since113        // we are codegen we know we're not dependent.114        auto *arrayTy = getContext().getAsConstantArrayType(baseTy);115        // Rather than trying to calculate the extent based on the116        // lower-bound, we can just emit this as an upper bound.117        upperBound = createOpenACCConstantInt(boundLoc, 64,118                                              arrayTy->getLimitedSize() - 1);119      }120 121      curVarExpr = section->getBase()->IgnoreParenImpCasts();122    } else {123      const auto *subscript = cast<ArraySubscriptExpr>(curVarExpr);124 125      lowerBound = emitOpenACCIntExpr(subscript->getIdx());126      // Length of an array index is always 1.127      extent = createOpenACCConstantInt(boundLoc, 64, 1);128      curVarExpr = subscript->getBase()->IgnoreParenImpCasts();129    }130 131    bounds.push_back(createBound(*this, this->builder, boundLoc, lowerBound,132                                 upperBound, extent));133    addBoundType(curVarExpr);134  }135 136  if (const auto *memExpr = dyn_cast<MemberExpr>(curVarExpr))137    return {exprLoc,138            emitMemberExpr(memExpr).getPointer(),139            exprString,140            origType,141            curVarExpr->getType().getNonReferenceType().getUnqualifiedType(),142            std::move(bounds),143            std::move(boundTypes)};144 145  // Sema has made sure that only 4 types of things can get here, array146  // subscript, array section, member expr, or DRE to a var decl (or the147  // former 3 wrapping a var-decl), so we should be able to assume this is148  // right.149  const auto *dre = cast<DeclRefExpr>(curVarExpr);150  return {exprLoc,151          emitDeclRefLValue(dre).getPointer(),152          exprString,153          origType,154          curVarExpr->getType().getNonReferenceType().getUnqualifiedType(),155          std::move(bounds),156          std::move(boundTypes)};157}158