Skip to content

Commit

Permalink
Improve handling of c++ attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
wsmoses committed Feb 28, 2024
1 parent f7a46fd commit 5280808
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 275 deletions.
285 changes: 10 additions & 275 deletions enzyme/Enzyme/Clang/EnzymeClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ struct EnzymeFunctionLikeAttrInfo : public ParsedAttrInfo {

AttrHandling handleDeclAttribute(Sema &S, Decl *D,
const ParsedAttr &Attr) const override {
auto FD = cast<FunctionDecl>(D);
if (Attr.getNumArgs() != 1) {
unsigned ID = S.getDiagnostics().getCustomDiagID(
DiagnosticsEngine::Error,
Expand All @@ -274,92 +273,9 @@ struct EnzymeFunctionLikeAttrInfo : public ParsedAttrInfo {
return AttributeNotApplied;
}

// if (FD->isLateTemplateParsed()) return;
auto &AST = S.getASTContext();
DeclContext *declCtx = FD->getDeclContext();
for (auto tmpCtx = declCtx; tmpCtx; tmpCtx = tmpCtx->getParent()) {
if (tmpCtx->isRecord()) {
declCtx = tmpCtx->getParent();
}
}
auto loc = FD->getLocation();
RecordDecl *RD;
if (S.getLangOpts().CPlusPlus)
RD = CXXRecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
else
RD = RecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
RD->setAnonymousStructOrUnion(true);
RD->setImplicit();
RD->startDefinition();
auto Tinfo = nullptr;
auto Tinfo0 = nullptr;
auto FT = AST.getPointerType(FD->getType());
auto CharTy = AST.getIntTypeForBitwidth(8, false);
auto FD0 = FieldDecl::Create(AST, RD, loc, loc, /*Ud*/ nullptr, FT, Tinfo0,
/*expr*/ nullptr, /*mutable*/ true,
/*inclassinit*/ ICIS_NoInit);
FD0->setAccess(AS_public);
RD->addDecl(FD0);
auto FD1 = FieldDecl::Create(
AST, RD, loc, loc, /*Ud*/ nullptr, AST.getPointerType(CharTy), Tinfo0,
/*expr*/ nullptr, /*mutable*/ true, /*inclassinit*/ ICIS_NoInit);
FD1->setAccess(AS_public);
RD->addDecl(FD1);
RD->completeDefinition();
assert(RD->getDefinition());
auto &Id = AST.Idents.get("__enzyme_function_like_autoreg_" +
FD->getNameAsString());
auto T = AST.getRecordType(RD);
auto V = VarDecl::Create(AST, declCtx, loc, loc, &Id, T, Tinfo, SC_None);
V->setStorageClass(SC_PrivateExtern);
V->addAttr(clang::UsedAttr::CreateImplicit(AST));
TemplateArgumentListInfo *TemplateArgs = nullptr;
auto DR = DeclRefExpr::Create(AST, NestedNameSpecifierLoc(), loc, FD, false,
loc, FD->getType(), ExprValueKind::VK_LValue,
FD, TemplateArgs);
#if LLVM_VERSION_MAJOR >= 13
auto rval = ExprValueKind::VK_PRValue;
#else
auto rval = ExprValueKind::VK_RValue;
#endif
StringRef cstr = Literal->getString();
Expr *exprs[2] = {
#if LLVM_VERSION_MAJOR >= 12
ImplicitCastExpr::Create(AST, FT, CastKind::CK_FunctionToPointerDecay, DR,
nullptr, rval, FPOptionsOverride()),
ImplicitCastExpr::Create(
AST, AST.getPointerType(CharTy), CastKind::CK_ArrayToPointerDecay,
StringLiteral::Create(
AST, cstr, stringkind,
/*Pascal*/ false,
AST.getStringLiteralArrayType(CharTy, cstr.size()), loc),
nullptr, rval, FPOptionsOverride())
#else
ImplicitCastExpr::Create(AST, FT, CastKind::CK_FunctionToPointerDecay, DR,
nullptr, rval),
ImplicitCastExpr::Create(
AST, AST.getPointerType(CharTy), CastKind::CK_ArrayToPointerDecay,
StringLiteral::Create(
AST, cstr, stringkind,
/*Pascal*/ false,
AST.getStringLiteralArrayType(CharTy, cstr.size()), loc),
nullptr, rval)
#endif
};
auto IL = new (AST) InitListExpr(AST, loc, exprs, loc);
V->setInit(IL);
IL->setType(T);
if (IL->isValueDependent()) {
unsigned ID = S.getDiagnostics().getCustomDiagID(
DiagnosticsEngine::Error, "use of attribute 'enzyme_function_like' "
"in a templated context not yet supported");
S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}
S.MarkVariableReferenced(loc, V);
S.getASTConsumer().HandleTopLevelDecl(DeclGroupRef(V));
D->addAttr(AnnotateAttr::Create(
S.Context, ("enzyme_function_like=" + Literal->getString()).str(),
Attr.getRange()));
return AttributeApplied;
}
};
Expand Down Expand Up @@ -409,71 +325,8 @@ struct EnzymeInactiveAttrInfo : public ParsedAttrInfo {
return AttributeNotApplied;
}

auto &AST = S.getASTContext();
DeclContext *declCtx = D->getDeclContext();
for (auto tmpCtx = declCtx; tmpCtx; tmpCtx = tmpCtx->getParent()) {
if (tmpCtx->isRecord()) {
declCtx = tmpCtx->getParent();
}
}
auto loc = D->getLocation();
RecordDecl *RD;
if (S.getLangOpts().CPlusPlus)
RD = CXXRecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
else
RD = RecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
RD->setAnonymousStructOrUnion(true);
RD->setImplicit();
RD->startDefinition();
auto T = isa<FunctionDecl>(D) ? cast<FunctionDecl>(D)->getType()
: cast<VarDecl>(D)->getType();
auto Name = isa<FunctionDecl>(D) ? cast<FunctionDecl>(D)->getNameAsString()
: cast<VarDecl>(D)->getNameAsString();
auto FT = AST.getPointerType(T);
auto subname = isa<FunctionDecl>(D) ? "inactivefn" : "inactive_global";
auto &Id = AST.Idents.get(
(StringRef("__enzyme_") + subname + "_autoreg_" + Name).str());
auto V = VarDecl::Create(AST, declCtx, loc, loc, &Id, FT, nullptr, SC_None);
V->setStorageClass(SC_PrivateExtern);
V->addAttr(clang::UsedAttr::CreateImplicit(AST));
TemplateArgumentListInfo *TemplateArgs = nullptr;
auto DR = DeclRefExpr::Create(
AST, NestedNameSpecifierLoc(), loc, cast<ValueDecl>(D), false, loc, T,
ExprValueKind::VK_LValue, cast<NamedDecl>(D), TemplateArgs);
#if LLVM_VERSION_MAJOR >= 13
auto rval = ExprValueKind::VK_PRValue;
#else
auto rval = ExprValueKind::VK_RValue;
#endif
Expr *expr = nullptr;
if (isa<FunctionDecl>(D)) {
#if LLVM_VERSION_MAJOR >= 12
expr =
ImplicitCastExpr::Create(AST, FT, CastKind::CK_FunctionToPointerDecay,
DR, nullptr, rval, FPOptionsOverride());
#else
expr = ImplicitCastExpr::Create(
AST, FT, CastKind::CK_FunctionToPointerDecay, DR, nullptr, rval);
#endif
} else {
expr =
UnaryOperator::Create(AST, DR, UnaryOperatorKind::UO_AddrOf, FT, rval,
clang::ExprObjectKind ::OK_Ordinary, loc,
/*canoverflow*/ false, FPOptionsOverride());
}

if (expr->isValueDependent()) {
unsigned ID = S.getDiagnostics().getCustomDiagID(
DiagnosticsEngine::Error, "use of attribute 'enzyme_inactive' "
"in a templated context not yet supported");
S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}
V->setInit(expr);
S.MarkVariableReferenced(loc, V);
S.getASTConsumer().HandleTopLevelDecl(DeclGroupRef(V));
D->addAttr(
AnnotateAttr::Create(S.Context, "enzyme_inactive", Attr.getRange()));
return AttributeApplied;
}
};
Expand Down Expand Up @@ -522,71 +375,8 @@ struct EnzymeNoFreeAttrInfo : public ParsedAttrInfo {
S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}

auto &AST = S.getASTContext();
DeclContext *declCtx = D->getDeclContext();
for (auto tmpCtx = declCtx; tmpCtx; tmpCtx = tmpCtx->getParent()) {
if (tmpCtx->isRecord()) {
declCtx = tmpCtx->getParent();
}
}
auto loc = D->getLocation();
RecordDecl *RD;
if (S.getLangOpts().CPlusPlus)
RD = CXXRecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
else
RD = RecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
RD->setAnonymousStructOrUnion(true);
RD->setImplicit();
RD->startDefinition();
auto T = isa<FunctionDecl>(D) ? cast<FunctionDecl>(D)->getType()
: cast<VarDecl>(D)->getType();
auto Name = isa<FunctionDecl>(D) ? cast<FunctionDecl>(D)->getNameAsString()
: cast<VarDecl>(D)->getNameAsString();
auto FT = AST.getPointerType(T);
auto &Id = AST.Idents.get(
(StringRef("__enzyme_nofree") + "_autoreg_" + Name).str());
auto V = VarDecl::Create(AST, declCtx, loc, loc, &Id, FT, nullptr, SC_None);
V->setStorageClass(SC_PrivateExtern);
V->addAttr(clang::UsedAttr::CreateImplicit(AST));
TemplateArgumentListInfo *TemplateArgs = nullptr;
auto DR = DeclRefExpr::Create(
AST, NestedNameSpecifierLoc(), loc, cast<ValueDecl>(D), false, loc, T,
ExprValueKind::VK_LValue, cast<NamedDecl>(D), TemplateArgs);
#if LLVM_VERSION_MAJOR >= 13
auto rval = ExprValueKind::VK_PRValue;
#else
auto rval = ExprValueKind::VK_RValue;
#endif
Expr *expr = nullptr;
if (isa<FunctionDecl>(D)) {
#if LLVM_VERSION_MAJOR >= 12
expr =
ImplicitCastExpr::Create(AST, FT, CastKind::CK_FunctionToPointerDecay,
DR, nullptr, rval, FPOptionsOverride());
#else
expr = ImplicitCastExpr::Create(
AST, FT, CastKind::CK_FunctionToPointerDecay, DR, nullptr, rval);
#endif
} else {
expr =
UnaryOperator::Create(AST, DR, UnaryOperatorKind::UO_AddrOf, FT, rval,
clang::ExprObjectKind ::OK_Ordinary, loc,
/*canoverflow*/ false, FPOptionsOverride());
}

if (expr->isValueDependent()) {
unsigned ID = S.getDiagnostics().getCustomDiagID(
DiagnosticsEngine::Error, "use of attribute 'enzyme_nofree' "
"in a templated context not yet supported");
S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}
V->setInit(expr);
S.MarkVariableReferenced(loc, V);
S.getASTConsumer().HandleTopLevelDecl(DeclGroupRef(V));
D->addAttr(
AnnotateAttr::Create(S.Context, "enzyme_nofree", Attr.getRange()));
return AttributeApplied;
}
};
Expand Down Expand Up @@ -631,65 +421,10 @@ struct EnzymeSparseAccumulateAttrInfo : public ParsedAttrInfo {
S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}

auto &AST = S.getASTContext();
DeclContext *declCtx = D->getDeclContext();
for (auto tmpCtx = declCtx; tmpCtx; tmpCtx = tmpCtx->getParent()) {
if (tmpCtx->isRecord()) {
declCtx = tmpCtx->getParent();
}
}
auto loc = D->getLocation();
RecordDecl *RD;
if (S.getLangOpts().CPlusPlus)
RD = CXXRecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
else
RD = RecordDecl::Create(AST, StructKind, declCtx, loc, loc,
nullptr); // rId);
RD->setAnonymousStructOrUnion(true);
RD->setImplicit();
RD->startDefinition();
auto T = cast<FunctionDecl>(D)->getType();
auto Name = cast<FunctionDecl>(D)->getNameAsString();
auto FT = AST.getPointerType(T);
auto &Id = AST.Idents.get(
(StringRef("__enzyme_sparse_accumulate") + "_autoreg_" + Name).str());
auto V = VarDecl::Create(AST, declCtx, loc, loc, &Id, FT, nullptr, SC_None);
V->setStorageClass(SC_PrivateExtern);
V->addAttr(clang::UsedAttr::CreateImplicit(AST));
TemplateArgumentListInfo *TemplateArgs = nullptr;
auto DR = DeclRefExpr::Create(
AST, NestedNameSpecifierLoc(), loc, cast<ValueDecl>(D), false, loc, T,
ExprValueKind::VK_LValue, cast<NamedDecl>(D), TemplateArgs);
#if LLVM_VERSION_MAJOR >= 13
auto rval = ExprValueKind::VK_PRValue;
#else
auto rval = ExprValueKind::VK_RValue;
#endif
Expr *expr = nullptr;
#if LLVM_VERSION_MAJOR >= 12
expr =
ImplicitCastExpr::Create(AST, FT, CastKind::CK_FunctionToPointerDecay,
DR, nullptr, rval, FPOptionsOverride());
#else
expr = ImplicitCastExpr::Create(
AST, FT, CastKind::CK_FunctionToPointerDecay, DR, nullptr, rval);
#endif

if (expr->isValueDependent()) {
unsigned ID = S.getDiagnostics().getCustomDiagID(
DiagnosticsEngine::Error,
"use of attribute 'enzyme_sparse_accumulate' "
"in a templated context not yet supported");
S.Diag(Attr.getLoc(), ID);
return AttributeNotApplied;
}
V->setInit(expr);
S.MarkVariableReferenced(loc, V);
S.getASTConsumer().HandleTopLevelDecl(DeclGroupRef(V));
D->addAttr(AnnotateAttr::Create(S.Context, "enzyme_sparse_accumulate",
Attr.getRange()));
return AttributeApplied;
}
};
};

static ParsedAttrInfoRegistry::Add<EnzymeSparseAccumulateAttrInfo>
Expand Down
Loading

0 comments on commit 5280808

Please sign in to comment.