Skip to content

Commit 823e008

Browse files
authored
merge main into amd-staging (#681)
2 parents b5e847e + 1758b4f commit 823e008

File tree

371 files changed

+15641
-15547
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

371 files changed

+15641
-15547
lines changed

clang/include/clang/Sema/SemaARM.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class SemaARM : public SemaBase {
9696
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
9797
SmallVectorImpl<SourceLocation> &Locs,
9898
SmallVectorImpl<SmallString<64>> &NewParams);
99+
bool checkSVETypeSupport(QualType Ty, SourceLocation Loc,
100+
const FunctionDecl *FD,
101+
const llvm::StringMap<bool> &FeatureMap);
99102
};
100103

101104
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);

clang/lib/CIR/CodeGen/CIRGenDeclOpenACC.cpp

Lines changed: 167 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "CIRGenFunction.h"
14+
#include "CIRGenOpenACCHelpers.h"
15+
1416
#include "mlir/Dialect/OpenACC/OpenACC.h"
1517
#include "clang/AST/DeclOpenACC.h"
18+
#include "llvm/Support/SaveAndRestore.h"
1619

1720
using namespace clang;
1821
using namespace clang::CIRGen;
@@ -96,6 +99,13 @@ struct OpenACCDeclareCleanup final : EHScopeStack::Cleanup {
9699
};
97100
} // namespace
98101

102+
void CIRGenModule::emitGlobalOpenACCDecl(const OpenACCConstructDecl *d) {
103+
if (const auto *rd = dyn_cast<OpenACCRoutineDecl>(d))
104+
emitGlobalOpenACCRoutineDecl(rd);
105+
else
106+
emitGlobalOpenACCDeclareDecl(cast<OpenACCDeclareDecl>(d));
107+
}
108+
99109
void CIRGenFunction::emitOpenACCDeclare(const OpenACCDeclareDecl &d) {
100110
mlir::Location exprLoc = cgm.getLoc(d.getBeginLoc());
101111
auto enterOp = mlir::acc::DeclareEnterOp::create(
@@ -109,15 +119,165 @@ void CIRGenFunction::emitOpenACCDeclare(const OpenACCDeclareDecl &d) {
109119
enterOp);
110120
}
111121

122+
// Helper function that gets the declaration referenced by the declare clause.
123+
// This is a simplified verison of the work that `getOpenACCDataOperandInfo`
124+
// does, as it only has to get forms that 'declare' does.
125+
static const Decl *getDeclareReferencedDecl(const Expr *e) {
126+
const Expr *curVarExpr = e->IgnoreParenImpCasts();
127+
128+
// Since we allow array sections, we have to unpack the array sections here.
129+
// We don't have to worry about other bounds, since only variable or array
130+
// name (plus array sections as an extension) are permitted.
131+
while (const auto *ase = dyn_cast<ArraySectionExpr>(curVarExpr))
132+
curVarExpr = ase->getBase()->IgnoreParenImpCasts();
133+
134+
if (const auto *dre = dyn_cast<DeclRefExpr>(curVarExpr))
135+
return dre->getFoundDecl()->getCanonicalDecl();
136+
137+
// MemberExpr is allowed when it is implicit 'this'.
138+
return cast<MemberExpr>(curVarExpr)->getMemberDecl()->getCanonicalDecl();
139+
}
140+
141+
template <typename BeforeOpTy, typename DataClauseTy>
142+
void CIRGenModule::emitGlobalOpenACCDeclareDataOperands(
143+
const Expr *varOperand, DataClauseTy dataClause,
144+
OpenACCModifierKind modifiers, bool structured, bool implicit,
145+
bool requiresDtor) {
146+
// This is a template argument so that we don't have to include all of
147+
// mlir::acc into CIRGenModule.
148+
static_assert(std::is_same_v<DataClauseTy, mlir::acc::DataClause>);
149+
mlir::Location exprLoc = getLoc(varOperand->getBeginLoc());
150+
const Decl *refedDecl = getDeclareReferencedDecl(varOperand);
151+
StringRef varName = getMangledName(GlobalDecl{cast<VarDecl>(refedDecl)});
152+
153+
// We have to emit two separate functions in this case, an acc_ctor and an
154+
// acc_dtor. These two sections are/should remain reasonably equal, however
155+
// the order of the clauses/vs-enter&exit in them makes combining these two
156+
// sections not particularly attractive, so we have a bit of repetition.
157+
{
158+
mlir::OpBuilder::InsertionGuard guardCase(builder);
159+
auto ctorOp = mlir::acc::GlobalConstructorOp::create(
160+
builder, exprLoc, (varName + "_acc_ctor").str());
161+
getModule().push_back(ctorOp);
162+
mlir::Block *block = builder.createBlock(&ctorOp.getRegion(),
163+
ctorOp.getRegion().end(), {}, {});
164+
builder.setInsertionPointToEnd(block);
165+
// These things are close enough to a function handling-wise we can just
166+
// create this here.
167+
CIRGenFunction cgf{*this, builder, true};
168+
llvm::SaveAndRestore<CIRGenFunction *> savedCGF(curCGF, &cgf);
169+
cgf.curFn = ctorOp;
170+
CIRGenFunction::SourceLocRAIIObject fnLoc{cgf, exprLoc};
171+
172+
// This gets the information we need, PLUS emits the bounds correctly, so we
173+
// have to do this in both enter and exit.
174+
CIRGenFunction::OpenACCDataOperandInfo inf =
175+
cgf.getOpenACCDataOperandInfo(varOperand);
176+
auto beforeOp =
177+
BeforeOpTy::create(builder, exprLoc, inf.varValue, structured, implicit,
178+
inf.name, inf.bounds);
179+
beforeOp.setDataClause(dataClause);
180+
beforeOp.setModifiers(convertOpenACCModifiers(modifiers));
181+
182+
mlir::acc::DeclareEnterOp::create(
183+
builder, exprLoc, mlir::acc::DeclareTokenType::get(&getMLIRContext()),
184+
beforeOp.getResult());
185+
186+
mlir::acc::TerminatorOp::create(builder, exprLoc);
187+
}
188+
189+
// copyin, create, and device_resident require a destructor, link does not. In
190+
// the case of the first three, they are all a 'getdeviceptr', followed by the
191+
// declare_exit, followed by a delete op in the destructor region.
192+
if (requiresDtor) {
193+
mlir::OpBuilder::InsertionGuard guardCase(builder);
194+
auto ctorOp = mlir::acc::GlobalDestructorOp::create(
195+
builder, exprLoc, (varName + "_acc_dtor").str());
196+
getModule().push_back(ctorOp);
197+
mlir::Block *block = builder.createBlock(&ctorOp.getRegion(),
198+
ctorOp.getRegion().end(), {}, {});
199+
builder.setInsertionPointToEnd(block);
200+
201+
// These things are close enough to a function handling-wise we can just
202+
// create this here.
203+
CIRGenFunction cgf{*this, builder, true};
204+
llvm::SaveAndRestore<CIRGenFunction *> savedCGF(curCGF, &cgf);
205+
cgf.curFn = ctorOp;
206+
CIRGenFunction::SourceLocRAIIObject fnLoc{cgf, exprLoc};
207+
208+
CIRGenFunction::OpenACCDataOperandInfo inf =
209+
cgf.getOpenACCDataOperandInfo(varOperand);
210+
auto getDevPtr = mlir::acc::GetDevicePtrOp::create(
211+
builder, exprLoc, inf.varValue, structured, implicit, inf.name,
212+
inf.bounds);
213+
getDevPtr.setDataClause(dataClause);
214+
getDevPtr.setModifiers(convertOpenACCModifiers(modifiers));
215+
216+
mlir::acc::DeclareExitOp::create(builder, exprLoc, /*token=*/mlir::Value{},
217+
getDevPtr.getResult());
218+
auto deleteOp = mlir::acc::DeleteOp::create(
219+
builder, exprLoc, getDevPtr, structured, implicit, inf.name, {});
220+
deleteOp.setDataClause(dataClause);
221+
deleteOp.setModifiers(convertOpenACCModifiers(modifiers));
222+
mlir::acc::TerminatorOp::create(builder, exprLoc);
223+
}
224+
}
225+
namespace {
226+
// This class emits all of the information for a 'declare' at a global/ns/class
227+
// scope. Each clause results in its own acc_ctor and acc_dtor for the variable.
228+
// This class creates those and emits them properly.
229+
// This behavior is unique/special enough from the emission of statement-level
230+
// clauses that it doesn't really make sense to use that clause visitor.
231+
class OpenACCGlobalDeclareClauseEmitter final
232+
: public OpenACCClauseVisitor<OpenACCGlobalDeclareClauseEmitter> {
233+
CIRGenModule &cgm;
234+
void clauseNotImplemented(const OpenACCClause &c) {
235+
cgm.errorNYI(c.getSourceRange(), "OpenACC Global Declare Clause",
236+
c.getClauseKind());
237+
}
238+
239+
public:
240+
OpenACCGlobalDeclareClauseEmitter(CIRGenModule &cgm) : cgm(cgm) {}
241+
242+
void VisitClause(const OpenACCClause &clause) {
243+
clauseNotImplemented(clause);
244+
}
245+
246+
void emitClauses(ArrayRef<const OpenACCClause *> clauses) {
247+
this->VisitClauseList(clauses);
248+
}
249+
250+
void VisitCopyInClause(const OpenACCCopyInClause &clause) {
251+
for (const Expr *var : clause.getVarList())
252+
cgm.emitGlobalOpenACCDeclareDataOperands<mlir::acc::CopyinOp>(
253+
var, mlir::acc::DataClause::acc_copyin, clause.getModifierList(),
254+
/*structured=*/true,
255+
/*implicit=*/false, /*requiresDtor=*/true);
256+
}
257+
258+
void VisitCreateClause(const OpenACCCreateClause &clause) {
259+
for (const Expr *var : clause.getVarList())
260+
cgm.emitGlobalOpenACCDeclareDataOperands<mlir::acc::CreateOp>(
261+
var, mlir::acc::DataClause::acc_create, clause.getModifierList(),
262+
/*structured=*/true,
263+
/*implicit=*/false, /*requiresDtor=*/true);
264+
}
265+
};
266+
} // namespace
267+
268+
void CIRGenModule::emitGlobalOpenACCDeclareDecl(const OpenACCDeclareDecl *d) {
269+
// Declare creates 1 'acc_ctor' and 0-1 'acc_dtor' per clause, since it needs
270+
// a unique one on a per-variable basis. We can just use a clause emitter to
271+
// do all the work.
272+
mlir::OpBuilder::InsertionGuard guardCase(builder);
273+
OpenACCGlobalDeclareClauseEmitter em{*this};
274+
em.emitClauses(d->clauses());
275+
}
276+
112277
void CIRGenFunction::emitOpenACCRoutine(const OpenACCRoutineDecl &d) {
113278
getCIRGenModule().errorNYI(d.getSourceRange(), "OpenACC Routine Construct");
114279
}
115280

116-
void CIRGenModule::emitGlobalOpenACCDecl(const OpenACCConstructDecl *d) {
117-
if (isa<OpenACCRoutineDecl>(d))
118-
errorNYI(d->getSourceRange(), "OpenACC Routine Construct");
119-
else if (isa<OpenACCDeclareDecl>(d))
120-
errorNYI(d->getSourceRange(), "OpenACC Declare Construct");
121-
else
122-
llvm_unreachable("unknown OpenACC declaration kind?");
281+
void CIRGenModule::emitGlobalOpenACCRoutineDecl(const OpenACCRoutineDecl *d) {
282+
errorNYI(d->getSourceRange(), "OpenACC Global Routine Construct");
123283
}

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,10 +1513,10 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
15131513
break;
15141514
}
15151515
case Decl::OpenACCRoutine:
1516-
emitGlobalOpenACCDecl(cast<OpenACCRoutineDecl>(decl));
1516+
emitGlobalOpenACCRoutineDecl(cast<OpenACCRoutineDecl>(decl));
15171517
break;
15181518
case Decl::OpenACCDeclare:
1519-
emitGlobalOpenACCDecl(cast<OpenACCDeclareDecl>(decl));
1519+
emitGlobalOpenACCDeclareDecl(cast<OpenACCDeclareDecl>(decl));
15201520
break;
15211521
case Decl::Enum:
15221522
case Decl::Using: // using X; [C++]
@@ -1560,7 +1560,7 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
15601560
CXXRecordDecl *crd = cast<CXXRecordDecl>(decl);
15611561
assert(!cir::MissingFeatures::generateDebugInfo());
15621562
for (auto *childDecl : crd->decls())
1563-
if (isa<VarDecl, CXXRecordDecl, EnumDecl>(childDecl))
1563+
if (isa<VarDecl, CXXRecordDecl, EnumDecl, OpenACCDeclareDecl>(childDecl))
15641564
emitTopLevelDecl(childDecl);
15651565
break;
15661566
}

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,14 @@ class CIRGenModule : public CIRGenTypeCache {
453453
bool performInit);
454454

455455
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd);
456+
void emitGlobalOpenACCRoutineDecl(const clang::OpenACCRoutineDecl *cd);
457+
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd);
458+
template <typename BeforeOpTy, typename DataClauseTy>
459+
void emitGlobalOpenACCDeclareDataOperands(const Expr *varOperand,
460+
DataClauseTy dataClause,
461+
OpenACCModifierKind modifiers,
462+
bool structured, bool implicit,
463+
bool requiresDtor);
456464

457465
// C++ related functions.
458466
void emitDeclContext(const DeclContext *dc);

clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "CIRGenCXXABI.h"
1616
#include "CIRGenFunction.h"
17+
#include "CIRGenOpenACCHelpers.h"
1718
#include "CIRGenOpenACCRecipe.h"
1819

1920
#include "clang/AST/ExprCXX.h"
@@ -182,33 +183,6 @@ class OpenACCClauseCIREmitter final
182183
dataOperands.append(computeEmitter.dataOperands);
183184
}
184185

185-
mlir::acc::DataClauseModifier
186-
convertModifiers(OpenACCModifierKind modifiers) {
187-
using namespace mlir::acc;
188-
static_assert(static_cast<int>(OpenACCModifierKind::Zero) ==
189-
static_cast<int>(DataClauseModifier::zero) &&
190-
static_cast<int>(OpenACCModifierKind::Readonly) ==
191-
static_cast<int>(DataClauseModifier::readonly) &&
192-
static_cast<int>(OpenACCModifierKind::AlwaysIn) ==
193-
static_cast<int>(DataClauseModifier::alwaysin) &&
194-
static_cast<int>(OpenACCModifierKind::AlwaysOut) ==
195-
static_cast<int>(DataClauseModifier::alwaysout) &&
196-
static_cast<int>(OpenACCModifierKind::Capture) ==
197-
static_cast<int>(DataClauseModifier::capture));
198-
199-
DataClauseModifier mlirModifiers{};
200-
201-
// The MLIR representation of this represents `always` as `alwaysin` +
202-
// `alwaysout`. So do a small fixup here.
203-
if (isOpenACCModifierBitSet(modifiers, OpenACCModifierKind::Always)) {
204-
mlirModifiers = mlirModifiers | DataClauseModifier::always;
205-
modifiers &= ~OpenACCModifierKind::Always;
206-
}
207-
208-
mlirModifiers = mlirModifiers | static_cast<DataClauseModifier>(modifiers);
209-
return mlirModifiers;
210-
}
211-
212186
template <typename BeforeOpTy, typename AfterOpTy>
213187
void addDataOperand(const Expr *varOperand, mlir::acc::DataClause dataClause,
214188
OpenACCModifierKind modifiers, bool structured,
@@ -243,8 +217,8 @@ class OpenACCClauseCIREmitter final
243217
// Set the 'rest' of the info for both operations.
244218
beforeOp.setDataClause(dataClause);
245219
afterOp.setDataClause(dataClause);
246-
beforeOp.setModifiers(convertModifiers(modifiers));
247-
afterOp.setModifiers(convertModifiers(modifiers));
220+
beforeOp.setModifiers(convertOpenACCModifiers(modifiers));
221+
afterOp.setModifiers(convertOpenACCModifiers(modifiers));
248222

249223
// Make sure we record these, so 'async' values can be updated later.
250224
dataOperands.push_back(beforeOp.getOperation());
@@ -264,7 +238,7 @@ class OpenACCClauseCIREmitter final
264238

265239
// Set the 'rest' of the info for the operation.
266240
beforeOp.setDataClause(dataClause);
267-
beforeOp.setModifiers(convertModifiers(modifiers));
241+
beforeOp.setModifiers(convertOpenACCModifiers(modifiers));
268242

269243
// Make sure we record these, so 'async' values can be updated later.
270244
dataOperands.push_back(beforeOp.getOperation());
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This contains helpers for OpenACC emission that don't need to be in
10+
// CIRGenModule, but can't live in a single .cpp file.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
#include "mlir/Dialect/OpenACC/OpenACC.h"
14+
#include "clang/AST/DeclOpenACC.h"
15+
16+
namespace clang::CIRGen {
17+
inline mlir::acc::DataClauseModifier
18+
convertOpenACCModifiers(OpenACCModifierKind modifiers) {
19+
using namespace mlir::acc;
20+
static_assert(static_cast<int>(OpenACCModifierKind::Zero) ==
21+
static_cast<int>(DataClauseModifier::zero) &&
22+
static_cast<int>(OpenACCModifierKind::Readonly) ==
23+
static_cast<int>(DataClauseModifier::readonly) &&
24+
static_cast<int>(OpenACCModifierKind::AlwaysIn) ==
25+
static_cast<int>(DataClauseModifier::alwaysin) &&
26+
static_cast<int>(OpenACCModifierKind::AlwaysOut) ==
27+
static_cast<int>(DataClauseModifier::alwaysout) &&
28+
static_cast<int>(OpenACCModifierKind::Capture) ==
29+
static_cast<int>(DataClauseModifier::capture));
30+
31+
DataClauseModifier mlirModifiers{};
32+
33+
// The MLIR representation of this represents `always` as `alwaysin` +
34+
// `alwaysout`. So do a small fixup here.
35+
if (isOpenACCModifierBitSet(modifiers, OpenACCModifierKind::Always)) {
36+
mlirModifiers = mlirModifiers | DataClauseModifier::always;
37+
modifiers &= ~OpenACCModifierKind::Always;
38+
}
39+
40+
mlirModifiers = mlirModifiers | static_cast<DataClauseModifier>(modifiers);
41+
return mlirModifiers;
42+
}
43+
} // namespace clang::CIRGen

clang/lib/Sema/Sema.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,16 +2259,10 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
22592259
}
22602260

22612261
// Don't allow SVE types in functions without a SVE target.
2262-
if (Ty->isSVESizelessBuiltinType() && FD && !FD->getType().isNull()) {
2262+
if (Ty->isSVESizelessBuiltinType() && FD) {
22632263
llvm::StringMap<bool> CallerFeatureMap;
22642264
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
2265-
if (!Builtin::evaluateRequiredTargetFeatures("sve", CallerFeatureMap)) {
2266-
if (!Builtin::evaluateRequiredTargetFeatures("sme", CallerFeatureMap))
2267-
Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
2268-
else if (!IsArmStreamingFunction(FD,
2269-
/*IncludeLocallyStreaming=*/true))
2270-
Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
2271-
}
2265+
ARM().checkSVETypeSupport(Ty, Loc, FD, CallerFeatureMap);
22722266
}
22732267

22742268
if (auto *VT = Ty->getAs<VectorType>();

clang/lib/Sema/SemaARM.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,4 +1684,24 @@ bool SemaARM::checkTargetClonesAttr(
16841684
return false;
16851685
}
16861686

1687+
bool SemaARM::checkSVETypeSupport(QualType Ty, SourceLocation Loc,
1688+
const FunctionDecl *FD,
1689+
const llvm::StringMap<bool> &FeatureMap) {
1690+
if (!Ty->isSVESizelessBuiltinType())
1691+
return false;
1692+
1693+
if (FeatureMap.lookup("sve"))
1694+
return false;
1695+
1696+
// No SVE environment available.
1697+
if (!FeatureMap.lookup("sme"))
1698+
return Diag(Loc, diag::err_sve_vector_in_non_sve_target) << Ty;
1699+
1700+
// SVE environment only available to streaming functions.
1701+
if (FD && !FD->getType().isNull() &&
1702+
!IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true))
1703+
return Diag(Loc, diag::err_sve_vector_in_non_streaming_function) << Ty;
1704+
1705+
return false;
1706+
}
16871707
} // namespace clang

0 commit comments

Comments
 (0)