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
6 changes: 4 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ using namespace clang;
using namespace clang::CIRGen;

CIRGenFunction::AutoVarEmission
CIRGenFunction::emitAutoVarAlloca(const VarDecl &d) {
CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
mlir::OpBuilder::InsertPoint ip) {
QualType ty = d.getType();
if (ty.getAddressSpace() != LangAS::Default)
cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: address space");
Expand All @@ -50,7 +51,8 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d) {
// A normal fixed sized variable becomes an alloca in the entry block,
mlir::Type allocaTy = convertTypeForMem(ty);
// Create the temp alloca and declare variable using it.
address = createTempAlloca(allocaTy, alignment, loc, d.getName());
address = createTempAlloca(allocaTy, alignment, loc, d.getName(),
/*arraySize=*/nullptr, /*alloca=*/nullptr, ip);
declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), alignment);

emission.Addr = address;
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,8 @@ class CIRGenFunction : public CIRGenTypeCache {

Address emitArrayToPointerDecay(const Expr *array);

AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d);
AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d,
mlir::OpBuilder::InsertPoint ip = {});

/// Emit code and set up symbol table for a variable declaration with auto,
/// register, or no storage class specifier. These turn into simple stack
Expand Down Expand Up @@ -1375,6 +1376,7 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::Location beginLoc;
mlir::Value varValue;
std::string name;
QualType baseType;
llvm::SmallVector<mlir::Value> bounds;
};
// Gets the collection of info required to lower and OpenACC clause or cache
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,13 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) {

if (const auto *memExpr = dyn_cast<MemberExpr>(curVarExpr))
return {exprLoc, emitMemberExpr(memExpr).getPointer(), exprString,
std::move(bounds)};
curVarExpr->getType(), std::move(bounds)};

// Sema has made sure that only 4 types of things can get here, array
// subscript, array section, member expr, or DRE to a var decl (or the
// former 3 wrapping a var-decl), so we should be able to assume this is
// right.
const auto *dre = cast<DeclRefExpr>(curVarExpr);
return {exprLoc, emitDeclRefLValue(dre).getPointer(), exprString,
std::move(bounds)};
curVarExpr->getType(), std::move(bounds)};
}
136 changes: 136 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <type_traits>

#include "CIRGenCXXABI.h"
#include "CIRGenFunction.h"

#include "clang/AST/ExprCXX.h"
Expand Down Expand Up @@ -355,6 +356,110 @@ class OpenACCClauseCIREmitter final
}
}

template <typename RecipeTy>
RecipeTy getOrCreateRecipe(ASTContext &astCtx, const Expr *varRef,
DeclContext *dc, QualType baseType,
mlir::Value mainOp) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
builder.getBlock()->getParentOfType<mlir::ModuleOp>();

getParentOfType walks the hierarchy until it finds the requested type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

mlir::Block doesn't seem to have getParentOfType? I think that must be why this uses getParent. OR am I missing something further?


std::string recipeName;
{
llvm::raw_string_ostream stream(recipeName);
if constexpr (std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
stream << "privatization_";
} else if constexpr (std::is_same_v<RecipeTy,
mlir::acc::FirstprivateRecipeOp>) {
stream << "firstprivatization_";

} else if constexpr (std::is_same_v<RecipeTy,
mlir::acc::ReductionRecipeOp>) {
stream << "reduction_";
// We don't have the reduction operation here well enough to know how to
// spell this correctly (+ == 'add', etc), so when we implement
// 'reduction' we have to do that here.
cgf.cgm.errorNYI(varRef->getSourceRange(),
"OpeNACC reduction recipe creation");
} else {
static_assert(!sizeof(RecipeTy), "Unknown Recipe op kind");
}

MangleContext &mc = cgf.cgm.getCXXABI().getMangleContext();
mc.mangleCanonicalTypeName(baseType, stream);
}

if (auto recipe = mod.lookupSymbol<RecipeTy>(recipeName))
return recipe;

mlir::Location loc = cgf.cgm.getLoc(varRef->getBeginLoc());
mlir::Location locEnd = cgf.cgm.getLoc(varRef->getEndLoc());

mlir::OpBuilder modBuilder(mod.getBodyRegion());
auto recipe =
modBuilder.create<RecipeTy>(loc, recipeName, mainOp.getType());

// Magic-up a var-decl so we can use normal init/destruction operations for
// a variable declaration.
VarDecl &tempDecl = *VarDecl::Create(
astCtx, dc, varRef->getBeginLoc(), varRef->getBeginLoc(),
&astCtx.Idents.get("openacc.private.init"), baseType,
astCtx.getTrivialTypeSourceInfo(baseType), SC_Auto);
CIRGenFunction::AutoVarEmission tempDeclEmission{
CIRGenFunction::AutoVarEmission::invalid()};

// Init section.
{
llvm::SmallVector<mlir::Type> argsTys{mainOp.getType()};
llvm::SmallVector<mlir::Location> argsLocs{loc};
builder.createBlock(&recipe.getInitRegion(), recipe.getInitRegion().end(),
argsTys, argsLocs);
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());

if constexpr (!std::is_same_v<RecipeTy, mlir::acc::PrivateRecipeOp>) {
// We have only implemented 'init' for private, so make this NYI until
// we have explicitly implemented everything.
cgf.cgm.errorNYI(varRef->getSourceRange(),
"OpenACC non-private recipe init");
}

tempDeclEmission =
cgf.emitAutoVarAlloca(tempDecl, builder.saveInsertionPoint());
cgf.emitAutoVarInit(tempDeclEmission);

builder.create<mlir::acc::YieldOp>(locEnd);
}

// Copy section.
if constexpr (std::is_same_v<RecipeTy, mlir::acc::FirstprivateRecipeOp> ||
std::is_same_v<RecipeTy, mlir::acc::ReductionRecipeOp>) {
// TODO: OpenACC: 'private' doesn't emit this, but for the other two we
// have to figure out what 'copy' means here.
cgf.cgm.errorNYI(varRef->getSourceRange(),
"OpenACC record type privatization copy section");
}

// Destroy section (doesn't currently exist).
if (tempDecl.needsDestruction(cgf.getContext())) {
llvm::SmallVector<mlir::Type> argsTys{mainOp.getType()};
llvm::SmallVector<mlir::Location> argsLocs{loc};
mlir::Block *block = builder.createBlock(&recipe.getDestroyRegion(),
recipe.getDestroyRegion().end(),
argsTys, argsLocs);
builder.setInsertionPointToEnd(&recipe.getDestroyRegion().back());

mlir::Type elementTy =
mlir::cast<cir::PointerType>(mainOp.getType()).getPointee();
Address addr{block->getArgument(0), elementTy,
cgf.getContext().getDeclAlign(&tempDecl)};
cgf.emitDestroy(addr, baseType,
cgf.getDestroyer(QualType::DK_cxx_destructor));

builder.create<mlir::acc::YieldOp>(locEnd);
}

return recipe;
}

public:
OpenACCClauseCIREmitter(OpTy &operation, CIRGen::CIRGenFunction &cgf,
CIRGen::CIRGenBuilderTy &builder,
Expand Down Expand Up @@ -971,6 +1076,37 @@ class OpenACCClauseCIREmitter final
llvm_unreachable("Unknown construct kind in VisitAttachClause");
}
}

void VisitPrivateClause(const OpenACCPrivateClause &clause) {
if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp,
mlir::acc::LoopOp>) {
for (const Expr *var : clause.getVarList()) {
CIRGenFunction::OpenACCDataOperandInfo opInfo =
cgf.getOpenACCDataOperandInfo(var);
auto privateOp = builder.create<mlir::acc::PrivateOp>(
opInfo.beginLoc, opInfo.varValue, /*structured=*/true,
/*implicit=*/false, opInfo.name, opInfo.bounds);
privateOp.setDataClause(mlir::acc::DataClause::acc_private);

{
mlir::OpBuilder::InsertionGuard guardCase(builder);
auto recipe = getOrCreateRecipe<mlir::acc::PrivateRecipeOp>(
cgf.getContext(), var, Decl::castToDeclContext(cgf.curFuncDecl),
opInfo.baseType, privateOp.getResult());
// TODO: OpenACC: The dialect is going to change in the near future to
// have these be on a different operation, so when that changes, we
// probably need to change these here.
operation.addPrivatization(builder.getContext(), privateOp, recipe);
}
}
} else if constexpr (isCombinedType<OpTy>) {
// Despite this being valid on ParallelOp or SerialOp, combined type
// applies to the 'loop'.
applyToLoopOp(clause);
} else {
llvm_unreachable("Unknown construct kind in VisitPrivateClause");
}
}
};

template <typename OpTy>
Expand Down
Loading
Loading