Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 75 additions & 13 deletions clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ class OpenACCClauseCIREmitter final
return constOp.getResult();
}

mlir::Value createConstantInt(SourceLocation loc, unsigned width,
int64_t value) {
return createConstantInt(cgf.cgm.getLoc(loc), width, value);
}

mlir::acc::DeviceType decodeDeviceType(const IdentifierInfo *ii) {
// '*' case leaves no identifier-info, just a nullptr.
if (!ii)
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is OK to remove the TODO here. I agree both with the choice to have stride as '1' and not specified in bytes.

The acc dialect permits non-1 stride because not all languages have contiguous arrays. And in particular, I imagine if CIR allowed native representation of non-contiguous array views - taking advantage of this functionality would be necessary.

// 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);

lowerBound = emitIntExpr(subscript->getIdx());
// Length of an array index is always 1.
extent = createConstantInt(boundLoc, 64, 1);
curVarExpr = subscript->getBase()->IgnoreParenImpCasts();
}

bounds.push_back(createBound(boundLoc, lowerBound, upperBound, extent));
}

// TODO: OpenACC: if this is a member expr, emit the VarPtrPtr correctly.
if (isa<MemberExpr>(curVarExpr)) {
cgf.cgm.errorNYI(curVarExpr->getSourceRange(),
"OpenACC Data clause member expr");
return {exprLoc, {}, {}};
return {exprLoc, {}, {}, std::move(bounds)};
}

// Sema has made sure that only 4 types of things can get here, array
Expand All @@ -223,14 +285,14 @@ class OpenACCClauseCIREmitter final
// right.
const auto *dre = cast<DeclRefExpr>(curVarExpr);
const auto *vd = cast<VarDecl>(dre->getFoundDecl()->getCanonicalDecl());
return {exprLoc, cgf.emitDeclRefLValue(dre).getPointer(), vd->getName()};
return {exprLoc, cgf.emitDeclRefLValue(dre).getPointer(), vd->getName(),
std::move(bounds)};
}

template <typename BeforeOpTy, typename AfterOpTy>
void addDataOperand(const Expr *varOperand, mlir::acc::DataClause dataClause,
bool structured, bool implicit) {
DataOperandInfo opInfo = getDataOperandInfo(dirKind, varOperand);
mlir::ValueRange bounds;

// TODO: OpenACC: we should comprehend the 'modifier-list' here for the data
// operand. At the moment, we don't have a uniform way to assign these
Expand All @@ -239,7 +301,7 @@ class OpenACCClauseCIREmitter final

auto beforeOp =
builder.create<BeforeOpTy>(opInfo.beginLoc, opInfo.varValue, structured,
implicit, opInfo.name, bounds);
implicit, opInfo.name, opInfo.bounds);
operation.getDataClauseOperandsMutable().append(beforeOp.getResult());

AfterOpTy afterOp;
Expand All @@ -248,7 +310,7 @@ class OpenACCClauseCIREmitter final
builder.setInsertionPointAfter(operation);
afterOp = builder.create<AfterOpTy>(opInfo.beginLoc, beforeOp.getResult(),
opInfo.varValue, structured, implicit,
opInfo.name, bounds);
opInfo.name, opInfo.bounds);
}

// Set the 'rest' of the info for both operations.
Expand Down
Loading
Loading