================ @@ -184,37 +189,94 @@ class OpenACCClauseCIREmitter final mlir::Location beginLoc; mlir::Value varValue; llvm::StringRef name; + llvm::SmallVector<mlir::Value> bounds; }; + mlir::Value createBound(mlir::Location boundLoc, mlir::Value lowerBound, + mlir::Value upperBound, mlir::Value extent) { + // Arrays always have a start-idx of 0. + mlir::Value startIdx = createConstantInt(boundLoc, 64, 0); + // TODO: OpenACC: It isn't clear that stride would ever be anything other + // than '1'? We emit the type of the reference 'correctly' as far as I + // know, so it should just be 1 element each time. We could perhaps use + // the 'inBytes' variant here, but it isn't clear what value that gets us. + // We might need to revisit this once we try to opt this and see what is + // going to happen. + mlir::Value stride = createConstantInt(boundLoc, 64, 1); + + auto bound = builder.create<mlir::acc::DataBoundsOp>(boundLoc, lowerBound, + upperBound); + bound.getStartIdxMutable().assign(startIdx); + if (extent) + bound.getExtentMutable().assign(extent); + bound.getStrideMutable().assign(stride); + + return bound; + } + // A helper function that gets the information from an operand to a data // clause, so that it can be used to emit the data operations. - inline DataOperandInfo getDataOperandInfo(OpenACCDirectiveKind dk, - const Expr *e) { + DataOperandInfo getDataOperandInfo(OpenACCDirectiveKind dk, const Expr *e) { // TODO: OpenACC: Cache was different enough as to need a separate // `ActOnCacheVar`, so we are going to need to do some investigations here // when it comes to implement this for cache. if (dk == OpenACCDirectiveKind::Cache) { cgf.cgm.errorNYI(e->getSourceRange(), "OpenACC data operand for 'cache' directive"); - return {cgf.cgm.getLoc(e->getBeginLoc()), {}, {}}; + return {cgf.cgm.getLoc(e->getBeginLoc()), {}, {}, {}}; } const Expr *curVarExpr = e->IgnoreParenImpCasts(); mlir::Location exprLoc = cgf.cgm.getLoc(curVarExpr->getBeginLoc()); + llvm::SmallVector<mlir::Value> bounds; + + // Assemble the list of bounds. + while (isa<ArraySectionExpr, ArraySubscriptExpr>(curVarExpr)) { + mlir::Location boundLoc = cgf.cgm.getLoc(curVarExpr->getBeginLoc()); + mlir::Value lowerBound; + mlir::Value upperBound; + mlir::Value extent; + + if (const auto *section = dyn_cast<ArraySectionExpr>(curVarExpr)) { + if (const Expr *lb = section->getLowerBound()) + lowerBound = emitIntExpr(lb); + else + lowerBound = createConstantInt(boundLoc, 64, 0); + + if (const Expr *len = section->getLength()) { + extent = emitIntExpr(len); + } else { + QualType baseTy = ArraySectionExpr::getBaseOriginalType( + section->getBase()->IgnoreParenImpCasts()); + // We know this is the case as implicit lengths are only allowed for + // array types with a constant size, or a dependent size. AND since + // we are codegen we know we're not dependent. + auto *arrayTy = cgf.getContext().getAsConstantArrayType(baseTy); + // Rather than trying to calculate the extent based on the + // lower-bound, we can just emit this as an upper bound. + upperBound = + createConstantInt(boundLoc, 64, arrayTy->getLimitedSize() - 1); + } - // TODO: OpenACC: Assemble the list of bounds. - if (isa<ArraySectionExpr, ArraySubscriptExpr>(curVarExpr)) { - cgf.cgm.errorNYI(curVarExpr->getSourceRange(), - "OpenACC data clause array subscript/section"); - return {exprLoc, {}, {}}; + curVarExpr = section->getBase()->IgnoreParenImpCasts(); + } else { + const auto *subscript = dyn_cast<ArraySubscriptExpr>(curVarExpr); ---------------- andykaylor wrote:
```suggestion const auto *subscript = cast<ArraySubscriptExpr>(curVarExpr); ``` https://github.com/llvm/llvm-project/pull/140971 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits