Skip to content

[NFC][Clang][FMV] Refactor sema checking of target_version/clones attributes. #149067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
14 changes: 7 additions & 7 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,13 @@ enum class CCEKind {
///< message.
};

/// Enums for the diagnostics of target, target_version and target_clones.
namespace DiagAttrParams {
enum DiagType { Unsupported, Duplicate, Unknown };
enum Specifier { None, CPU, Tune };
enum AttrName { Target, TargetClones, TargetVersion };
} // end namespace DiagAttrParams

void inferNoReturnAttr(Sema &S, const Decl *D);

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

/// Check Target Version attrs
bool checkTargetVersionAttr(SourceLocation Loc, Decl *D, StringRef Str);
bool checkTargetClonesAttrString(
SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal,
Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault,
SmallVectorImpl<SmallString<64>> &StringsBuffer);

ErrorAttr *mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
StringRef NewUserDiagnostic);
FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Sema/SemaARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ class SemaARM : public SemaBase {
/// Return true if the given vector types are lax-compatible SVE vector types,
/// false otherwise.
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType);

bool checkTargetVersionAttr(const StringRef Str, const SourceLocation Loc);
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &NewParams);
};

SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Sema/SemaRISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class SemaRISCV : public SemaBase {
bool DeclareAndesVectorBuiltins = false;

std::unique_ptr<sema::RISCVIntrinsicManager> IntrinsicManager;

bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc);
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &NewParams);
};

std::unique_ptr<sema::RISCVIntrinsicManager>
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/SemaX86.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class SemaX86 : public SemaBase {

void handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL);
void handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL);

bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &NewParams);
};
} // namespace clang

Expand Down
91 changes: 91 additions & 0 deletions clang/lib/Sema/SemaARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1535,4 +1535,95 @@ bool SemaARM::areLaxCompatibleSveTypes(QualType FirstType,
IsLaxCompatible(SecondType, FirstType);
}

bool SemaARM::checkTargetVersionAttr(const StringRef Param,
const SourceLocation Loc) {
using namespace DiagAttrParams;

llvm::SmallVector<StringRef, 8> Features;
Param.split(Features, '+');
for (StringRef Feat : Features) {
Feat = Feat.trim();
if (Feat == "default")
continue;
if (!getASTContext().getTargetInfo().validateCpuSupports(Feat))
return Diag(Loc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << Feat << TargetVersion;
}
return false;
}

bool SemaARM::checkTargetClonesAttr(
SmallVectorImpl<StringRef> &Params, SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &NewParams) {
using namespace DiagAttrParams;

if (!getASTContext().getTargetInfo().hasFeature("fmv"))
return true;

assert(Params.size() == Locs.size() &&
"Mismatch between number of string parameters and locations");

bool HasDefault = false;
bool HasNonDefault = false;
for (unsigned I = 0, E = Params.size(); I < E; ++I) {
const StringRef Param = Params[I].trim();
const SourceLocation &Loc = Locs[I];

if (Param.empty())
return Diag(Loc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << "" << TargetClones;

if (Param == "default") {
if (HasDefault)
Diag(Loc, diag::warn_target_clone_duplicate_options);
else {
NewParams.push_back(Param);
HasDefault = true;
}
continue;
}

bool HasCodeGenImpact = false;
llvm::SmallVector<StringRef, 8> Features;
llvm::SmallVector<StringRef, 8> ValidFeatures;
Param.split(Features, '+');
for (StringRef Feat : Features) {
Feat = Feat.trim();
if (!getASTContext().getTargetInfo().validateCpuSupports(Feat)) {
Diag(Loc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << Feat << TargetClones;
continue;
}
if (getASTContext().getTargetInfo().doesFeatureAffectCodeGen(Feat))
HasCodeGenImpact = true;
ValidFeatures.push_back(Feat);
}

// Ignore features that don't impact code generation.
if (!HasCodeGenImpact) {
Diag(Loc, diag::warn_target_clone_no_impact_options);
continue;
}

if (ValidFeatures.empty())
continue;

// Canonicalize attribute parameter.
llvm::sort(ValidFeatures);
SmallString<64> NewParam(llvm::join(ValidFeatures, "+"));
if (llvm::is_contained(NewParams, NewParam)) {
Diag(Loc, diag::warn_target_clone_duplicate_options);
continue;
}

// Valid non-default argument.
NewParams.push_back(NewParam);
HasNonDefault = true;
}
if (!HasNonDefault)
return true;

return false;
}

} // namespace clang
Loading
Loading