Skip to content

Commit da06b45

Browse files
authored
[NFC][Clang][FMV] Refactor sema checking of target_version/clones attributes. (#149067)
Sema currently has checkTargetVersionAttr and checkTargetClonesAttrString to diagnose the said attributes. However the code tries to handle all of AArch64, RISC-V and X86 targets at once which is hard to maintain, therefore I am splitting these functions. Unfortunately I could not use polymorphism because all of Sema, SemaARM, SemaRISCV and SemaX86 inherit from SemaBase. The Sema instance itself contains instances of every other target specific Sema.
1 parent 54b5068 commit da06b45

File tree

9 files changed

+322
-261
lines changed

9 files changed

+322
-261
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,13 @@ enum class CCEKind {
834834
///< message.
835835
};
836836

837+
/// Enums for the diagnostics of target, target_version and target_clones.
838+
namespace DiagAttrParams {
839+
enum DiagType { Unsupported, Duplicate, Unknown };
840+
enum Specifier { None, CPU, Tune };
841+
enum AttrName { Target, TargetClones, TargetVersion };
842+
} // end namespace DiagAttrParams
843+
837844
void inferNoReturnAttr(Sema &S, const Decl *D);
838845

839846
/// Sema - This implements semantic analysis and AST building for C.
@@ -4922,13 +4929,6 @@ class Sema final : public SemaBase {
49224929
// handled later in the process, once we know how many exist.
49234930
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
49244931

4925-
/// Check Target Version attrs
4926-
bool checkTargetVersionAttr(SourceLocation Loc, Decl *D, StringRef Str);
4927-
bool checkTargetClonesAttrString(
4928-
SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal,
4929-
Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault,
4930-
SmallVectorImpl<SmallString<64>> &StringsBuffer);
4931-
49324932
ErrorAttr *mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
49334933
StringRef NewUserDiagnostic);
49344934
FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,

clang/include/clang/Sema/SemaARM.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ class SemaARM : public SemaBase {
9191
/// Return true if the given vector types are lax-compatible SVE vector types,
9292
/// false otherwise.
9393
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType);
94+
95+
bool checkTargetVersionAttr(const StringRef Str, const SourceLocation Loc);
96+
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
97+
SmallVectorImpl<SourceLocation> &Locs,
98+
SmallVectorImpl<SmallString<64>> &NewParams);
9499
};
95100

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

clang/include/clang/Sema/SemaRISCV.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ class SemaRISCV : public SemaBase {
5555
bool DeclareAndesVectorBuiltins = false;
5656

5757
std::unique_ptr<sema::RISCVIntrinsicManager> IntrinsicManager;
58+
59+
bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc);
60+
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
61+
SmallVectorImpl<SourceLocation> &Locs,
62+
SmallVectorImpl<SmallString<64>> &NewParams);
5863
};
5964

6065
std::unique_ptr<sema::RISCVIntrinsicManager>

clang/include/clang/Sema/SemaX86.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class SemaX86 : public SemaBase {
3737

3838
void handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL);
3939
void handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL);
40+
41+
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
42+
SmallVectorImpl<SourceLocation> &Locs,
43+
SmallVectorImpl<SmallString<64>> &NewParams);
4044
};
4145
} // namespace clang
4246

clang/lib/Sema/SemaARM.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,4 +1535,95 @@ bool SemaARM::areLaxCompatibleSveTypes(QualType FirstType,
15351535
IsLaxCompatible(SecondType, FirstType);
15361536
}
15371537

1538+
bool SemaARM::checkTargetVersionAttr(const StringRef Param,
1539+
const SourceLocation Loc) {
1540+
using namespace DiagAttrParams;
1541+
1542+
llvm::SmallVector<StringRef, 8> Features;
1543+
Param.split(Features, '+');
1544+
for (StringRef Feat : Features) {
1545+
Feat = Feat.trim();
1546+
if (Feat == "default")
1547+
continue;
1548+
if (!getASTContext().getTargetInfo().validateCpuSupports(Feat))
1549+
return Diag(Loc, diag::warn_unsupported_target_attribute)
1550+
<< Unsupported << None << Feat << TargetVersion;
1551+
}
1552+
return false;
1553+
}
1554+
1555+
bool SemaARM::checkTargetClonesAttr(
1556+
SmallVectorImpl<StringRef> &Params, SmallVectorImpl<SourceLocation> &Locs,
1557+
SmallVectorImpl<SmallString<64>> &NewParams) {
1558+
using namespace DiagAttrParams;
1559+
1560+
if (!getASTContext().getTargetInfo().hasFeature("fmv"))
1561+
return true;
1562+
1563+
assert(Params.size() == Locs.size() &&
1564+
"Mismatch between number of string parameters and locations");
1565+
1566+
bool HasDefault = false;
1567+
bool HasNonDefault = false;
1568+
for (unsigned I = 0, E = Params.size(); I < E; ++I) {
1569+
const StringRef Param = Params[I].trim();
1570+
const SourceLocation &Loc = Locs[I];
1571+
1572+
if (Param.empty())
1573+
return Diag(Loc, diag::warn_unsupported_target_attribute)
1574+
<< Unsupported << None << "" << TargetClones;
1575+
1576+
if (Param == "default") {
1577+
if (HasDefault)
1578+
Diag(Loc, diag::warn_target_clone_duplicate_options);
1579+
else {
1580+
NewParams.push_back(Param);
1581+
HasDefault = true;
1582+
}
1583+
continue;
1584+
}
1585+
1586+
bool HasCodeGenImpact = false;
1587+
llvm::SmallVector<StringRef, 8> Features;
1588+
llvm::SmallVector<StringRef, 8> ValidFeatures;
1589+
Param.split(Features, '+');
1590+
for (StringRef Feat : Features) {
1591+
Feat = Feat.trim();
1592+
if (!getASTContext().getTargetInfo().validateCpuSupports(Feat)) {
1593+
Diag(Loc, diag::warn_unsupported_target_attribute)
1594+
<< Unsupported << None << Feat << TargetClones;
1595+
continue;
1596+
}
1597+
if (getASTContext().getTargetInfo().doesFeatureAffectCodeGen(Feat))
1598+
HasCodeGenImpact = true;
1599+
ValidFeatures.push_back(Feat);
1600+
}
1601+
1602+
// Ignore features that don't impact code generation.
1603+
if (!HasCodeGenImpact) {
1604+
Diag(Loc, diag::warn_target_clone_no_impact_options);
1605+
continue;
1606+
}
1607+
1608+
if (ValidFeatures.empty())
1609+
continue;
1610+
1611+
// Canonicalize attribute parameter.
1612+
llvm::sort(ValidFeatures);
1613+
SmallString<64> NewParam(llvm::join(ValidFeatures, "+"));
1614+
if (llvm::is_contained(NewParams, NewParam)) {
1615+
Diag(Loc, diag::warn_target_clone_duplicate_options);
1616+
continue;
1617+
}
1618+
1619+
// Valid non-default argument.
1620+
NewParams.push_back(NewParam);
1621+
HasNonDefault = true;
1622+
}
1623+
if (!HasNonDefault)
1624+
return true;
1625+
1626+
return false;
1627+
}
1628+
15381629
} // namespace clang

0 commit comments

Comments
 (0)