Skip to content

Commit c147f0c

Browse files
committed
Changes from last revision:
* Parse riscv fmv attributes before passing to resolver options * Simplify resolver options struct
1 parent 094f053 commit c147f0c

File tree

5 files changed

+137
-133
lines changed

5 files changed

+137
-133
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,19 +3260,16 @@ def Target : InheritableAttr {
32603260
let Subjects = SubjectList<[Function], ErrorDiag>;
32613261
let Documentation = [TargetDocs];
32623262
let AdditionalMembers = [{
3263-
StringRef getArchitecture() const {
3263+
std::optional<StringRef> getArchitecture() const {
32643264
StringRef Features = getFeaturesStr();
3265-
if (Features == "default") return {};
3266-
3267-
SmallVector<StringRef, 1> AttrFeatures;
3265+
SmallVector<StringRef, 4> AttrFeatures;
32683266
Features.split(AttrFeatures, ",");
3269-
3270-
for (auto &Feature : AttrFeatures) {
3267+
for (StringRef Feature : AttrFeatures) {
32713268
Feature = Feature.trim();
32723269
if (Feature.starts_with("arch="))
32733270
return Feature.drop_front(sizeof("arch=") - 1);
32743271
}
3275-
return "";
3272+
return std::nullopt;
32763273
}
32773274

32783275
// Gets the list of features as simple string-refs with no +/- or 'no-'.
@@ -3304,17 +3301,17 @@ def TargetVersion : InheritableAttr {
33043301
let Documentation = [TargetVersionDocs];
33053302
let AdditionalMembers = [{
33063303
StringRef getName() const { return getNamesStr().trim(); }
3307-
bool isDefaultVersion() const {
3308-
return getName() == "default";
3309-
}
3310-
void getFeatures(llvm::SmallVectorImpl<StringRef> &Out) const {
3311-
if (isDefaultVersion()) return;
3312-
StringRef Features = getName();
33133304

3314-
SmallVector<StringRef, 8> AttrFeatures;
3315-
Features.split(AttrFeatures, "+");
3305+
bool isDefaultVersion() const { return getName() == "default"; }
33163306

3317-
for (auto &Feature : AttrFeatures) {
3307+
void getFeatures(llvm::SmallVectorImpl<StringRef> &Out,
3308+
char Delim = '+') const {
3309+
if (isDefaultVersion())
3310+
return;
3311+
StringRef Features = getName();
3312+
SmallVector<StringRef, 4> AttrFeatures;
3313+
Features.split(AttrFeatures, Delim);
3314+
for (StringRef Feature : AttrFeatures) {
33183315
Feature = Feature.trim();
33193316
Out.push_back(Feature);
33203317
}
@@ -3331,20 +3328,52 @@ def TargetClones : InheritableAttr {
33313328
StringRef getFeatureStr(unsigned Index) const {
33323329
return *(featuresStrs_begin() + Index);
33333330
}
3331+
33343332
bool isDefaultVersion(unsigned Index) const {
33353333
return getFeatureStr(Index) == "default";
33363334
}
3335+
33373336
void getFeatures(llvm::SmallVectorImpl<StringRef> &Out,
3338-
unsigned Index) const {
3339-
if (isDefaultVersion(Index)) return;
3337+
unsigned Index, char Delim = '+') const {
3338+
if (isDefaultVersion(Index))
3339+
return;
33403340
StringRef Features = getFeatureStr(Index);
3341-
SmallVector<StringRef, 8> AttrFeatures;
3342-
Features.split(AttrFeatures, "+");
3343-
for (auto &Feature : AttrFeatures) {
3341+
SmallVector<StringRef, 4> AttrFeatures;
3342+
Features.split(AttrFeatures, Delim);
3343+
for (StringRef Feature : AttrFeatures) {
33443344
Feature = Feature.trim();
33453345
Out.push_back(Feature);
33463346
}
33473347
}
3348+
3349+
// x86 only.
3350+
std::optional<StringRef> getArchitecture(unsigned Index) const {
3351+
StringRef Features = getFeatureStr(Index);
3352+
SmallVector<StringRef, 4> AttrFeatures;
3353+
Features.split(AttrFeatures, ',');
3354+
for (StringRef Feature : AttrFeatures) {
3355+
Feature = Feature.trim();
3356+
if (Feature.starts_with("arch="))
3357+
return Feature.drop_front(sizeof("arch=") - 1);
3358+
}
3359+
return std::nullopt;
3360+
}
3361+
3362+
// x86 only.
3363+
void getAddedFeatures(llvm::SmallVectorImpl<StringRef> &Out,
3364+
unsigned Index) const {
3365+
if (isDefaultVersion(Index))
3366+
return;
3367+
StringRef Features = getFeatureStr(Index);
3368+
SmallVector<StringRef, 4> AttrFeatures;
3369+
Features.split(AttrFeatures, ",");
3370+
for (StringRef Feature : AttrFeatures) {
3371+
Feature = Feature.trim();
3372+
if (!Feature.starts_with("arch="))
3373+
Out.push_back(Feature);
3374+
}
3375+
}
3376+
33483377
// Given an index into the 'featuresStrs' sequence, compute a unique
33493378
// ID to be used with function name mangling for the associated variant.
33503379
// This mapping is necessary due to a requirement that the mangling ID

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -477,18 +477,23 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
477477
}
478478

479479
unsigned RISCVTargetInfo::getFMVPriority(ArrayRef<StringRef> Features) const {
480-
SmallVector<StringRef, 8> Attrs;
481-
Features[0].split(Attrs, ';');
482-
// Default Priority is zero.
483-
unsigned Priority = 0;
484-
for (auto Attr : Attrs) {
485-
if (Attr.consume_front("priority=")) {
486-
unsigned Result;
487-
if (!Attr.getAsInteger(0, Result))
488-
Priority = Result;
489-
}
480+
// Priority is explicitly specified on RISC-V unlike on other targets, where
481+
// it is derived by all the features of a specific version. Therefore if a
482+
// feature contains the priority string, then return it immediately.
483+
for (StringRef Feature : Features) {
484+
auto [LHS, RHS] = Feature.rsplit(';');
485+
if (LHS.consume_front("priority="))
486+
Feature = LHS;
487+
else if (RHS.consume_front("priority="))
488+
Feature = RHS;
489+
else
490+
continue;
491+
unsigned Priority;
492+
if (!Feature.getAsInteger(0, Priority))
493+
return Priority;
490494
}
491-
return Priority;
495+
// Default Priority is zero.
496+
return 0;
492497
}
493498

494499
TargetInfo::CallingConvCheckResult

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,23 +2824,17 @@ void CodeGenFunction::EmitKCFIOperandBundle(
28242824
Bundles.emplace_back("kcfi", CGM.CreateKCFITypeId(FP->desugar()));
28252825
}
28262826

2827-
llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
2828-
const MultiVersionResolverOption &RO) {
2829-
llvm::SmallVector<StringRef, 8> CondFeatures;
2830-
for (const StringRef &Feature : RO.Conditions.Features)
2831-
CondFeatures.push_back(Feature);
2832-
if (!CondFeatures.empty()) {
2833-
return EmitAArch64CpuSupports(CondFeatures);
2834-
}
2835-
return nullptr;
2827+
llvm::Value *
2828+
CodeGenFunction::FormAArch64ResolverCondition(const FMVResolverOption &RO) {
2829+
return RO.Features.empty() ? nullptr : EmitAArch64CpuSupports(RO.Features);
28362830
}
28372831

2838-
llvm::Value *CodeGenFunction::FormX86ResolverCondition(
2839-
const MultiVersionResolverOption &RO) {
2832+
llvm::Value *
2833+
CodeGenFunction::FormX86ResolverCondition(const FMVResolverOption &RO) {
28402834
llvm::Value *Condition = nullptr;
28412835

2842-
if (!RO.Conditions.Architecture.empty()) {
2843-
StringRef Arch = RO.Conditions.Architecture;
2836+
if (RO.Architecture) {
2837+
StringRef Arch = *RO.Architecture;
28442838
// If arch= specifies an x86-64 micro-architecture level, test the feature
28452839
// with __builtin_cpu_supports, otherwise use __builtin_cpu_is.
28462840
if (Arch.starts_with("x86-64"))
@@ -2849,8 +2843,8 @@ llvm::Value *CodeGenFunction::FormX86ResolverCondition(
28492843
Condition = EmitX86CpuIs(Arch);
28502844
}
28512845

2852-
if (!RO.Conditions.Features.empty()) {
2853-
llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
2846+
if (!RO.Features.empty()) {
2847+
llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Features);
28542848
Condition =
28552849
Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond;
28562850
}
@@ -2880,7 +2874,7 @@ static void CreateMultiVersionResolverReturn(CodeGenModule &CGM,
28802874
}
28812875

28822876
void CodeGenFunction::EmitMultiVersionResolver(
2883-
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
2877+
llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
28842878

28852879
llvm::Triple::ArchType ArchType =
28862880
getContext().getTargetInfo().getTriple().getArch();
@@ -2904,7 +2898,7 @@ void CodeGenFunction::EmitMultiVersionResolver(
29042898
}
29052899

29062900
void CodeGenFunction::EmitRISCVMultiVersionResolver(
2907-
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
2901+
llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
29082902

29092903
if (getContext().getTargetInfo().getTriple().getOS() !=
29102904
llvm::Triple::OSType::Linux) {
@@ -2923,23 +2917,14 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver(
29232917
// Check the each candidate function.
29242918
for (unsigned Index = 0; Index < Options.size(); Index++) {
29252919

2926-
if (Options[Index].Conditions.Features[0].starts_with("default")) {
2920+
if (Options[Index].Features.empty()) {
29272921
HasDefault = true;
29282922
DefaultIndex = Index;
29292923
continue;
29302924
}
29312925

29322926
Builder.SetInsertPoint(CurBlock);
29332927

2934-
std::vector<std::string> TargetAttrFeats =
2935-
getContext()
2936-
.getTargetInfo()
2937-
.parseTargetAttr(Options[Index].Conditions.Features[0])
2938-
.Features;
2939-
2940-
if (TargetAttrFeats.empty())
2941-
continue;
2942-
29432928
// FeaturesCondition: The bitmask of the required extension has been
29442929
// enabled by the runtime object.
29452930
// (__riscv_feature_bits.features[i] & REQUIRED_BITMASK) ==
@@ -2963,12 +2948,19 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver(
29632948
// address when using different versions.
29642949
llvm::SmallVector<StringRef, 8> CurrTargetAttrFeats;
29652950

2966-
for (auto &Feat : TargetAttrFeats) {
2967-
StringRef CurrFeat = Feat;
2968-
if (CurrFeat.starts_with('+'))
2969-
CurrTargetAttrFeats.push_back(CurrFeat.substr(1));
2951+
for (StringRef Feat : Options[Index].Features) {
2952+
auto [LHS, RHS] = Feat.rsplit(';');
2953+
Feat = LHS.starts_with("priority=") ? RHS : LHS;
2954+
if (Feat.starts_with("arch="))
2955+
Feat = Feat.drop_front(sizeof("arch=") - 1);
2956+
if (Feat.starts_with('+'))
2957+
Feat = Feat.drop_front(1);
2958+
CurrTargetAttrFeats.push_back(Feat);
29702959
}
29712960

2961+
if (CurrTargetAttrFeats.empty())
2962+
continue;
2963+
29722964
Builder.SetInsertPoint(CurBlock);
29732965
llvm::Value *FeatsCondition = EmitRISCVCpuSupports(CurrTargetAttrFeats);
29742966

@@ -3002,17 +2994,16 @@ void CodeGenFunction::EmitRISCVMultiVersionResolver(
30022994
}
30032995

30042996
void CodeGenFunction::EmitAArch64MultiVersionResolver(
3005-
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
2997+
llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
30062998
assert(!Options.empty() && "No multiversion resolver options found");
3007-
assert(Options.back().Conditions.Features.size() == 0 &&
3008-
"Default case must be last");
2999+
assert(Options.back().Features.size() == 0 && "Default case must be last");
30093000
bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
30103001
assert(SupportsIFunc &&
30113002
"Multiversion resolver requires target IFUNC support");
30123003
bool AArch64CpuInitialized = false;
30133004
llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
30143005

3015-
for (const MultiVersionResolverOption &RO : Options) {
3006+
for (const FMVResolverOption &RO : Options) {
30163007
Builder.SetInsertPoint(CurBlock);
30173008
llvm::Value *Condition = FormAArch64ResolverCondition(RO);
30183009

@@ -3048,7 +3039,7 @@ void CodeGenFunction::EmitAArch64MultiVersionResolver(
30483039
}
30493040

30503041
void CodeGenFunction::EmitX86MultiVersionResolver(
3051-
llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
3042+
llvm::Function *Resolver, ArrayRef<FMVResolverOption> Options) {
30523043

30533044
bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc();
30543045

@@ -3057,7 +3048,7 @@ void CodeGenFunction::EmitX86MultiVersionResolver(
30573048
Builder.SetInsertPoint(CurBlock);
30583049
EmitX86CpuInit();
30593050

3060-
for (const MultiVersionResolverOption &RO : Options) {
3051+
for (const FMVResolverOption &RO : Options) {
30613052
Builder.SetInsertPoint(CurBlock);
30623053
llvm::Value *Condition = FormX86ResolverCondition(RO);
30633054

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5332,35 +5332,27 @@ class CodeGenFunction : public CodeGenTypeCache {
53325332

53335333
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);
53345334

5335-
struct MultiVersionResolverOption {
5335+
struct FMVResolverOption {
53365336
llvm::Function *Function;
5337-
struct Conds {
5338-
StringRef Architecture;
5339-
llvm::SmallVector<StringRef, 8> Features;
5337+
llvm::SmallVector<StringRef, 8> Features;
5338+
std::optional<StringRef> Architecture;
53405339

5341-
Conds(StringRef Arch, ArrayRef<StringRef> Feats)
5342-
: Architecture(Arch), Features(Feats) {}
5343-
} Conditions;
5344-
5345-
MultiVersionResolverOption(llvm::Function *F, StringRef Arch,
5346-
ArrayRef<StringRef> Feats)
5347-
: Function(F), Conditions(Arch, Feats) {}
5340+
FMVResolverOption(llvm::Function *F, ArrayRef<StringRef> Feats,
5341+
std::optional<StringRef> Arch = std::nullopt)
5342+
: Function(F), Features(Feats), Architecture(Arch) {}
53485343
};
53495344

53505345
// Emits the body of a multiversion function's resolver. Assumes that the
53515346
// options are already sorted in the proper order, with the 'default' option
53525347
// last (if it exists).
53535348
void EmitMultiVersionResolver(llvm::Function *Resolver,
5354-
ArrayRef<MultiVersionResolverOption> Options);
5355-
void
5356-
EmitX86MultiVersionResolver(llvm::Function *Resolver,
5357-
ArrayRef<MultiVersionResolverOption> Options);
5358-
void
5359-
EmitAArch64MultiVersionResolver(llvm::Function *Resolver,
5360-
ArrayRef<MultiVersionResolverOption> Options);
5361-
void
5362-
EmitRISCVMultiVersionResolver(llvm::Function *Resolver,
5363-
ArrayRef<MultiVersionResolverOption> Options);
5349+
ArrayRef<FMVResolverOption> Options);
5350+
void EmitX86MultiVersionResolver(llvm::Function *Resolver,
5351+
ArrayRef<FMVResolverOption> Options);
5352+
void EmitAArch64MultiVersionResolver(llvm::Function *Resolver,
5353+
ArrayRef<FMVResolverOption> Options);
5354+
void EmitRISCVMultiVersionResolver(llvm::Function *Resolver,
5355+
ArrayRef<FMVResolverOption> Options);
53645356

53655357
private:
53665358
QualType getVarArgType(const Expr *Arg);
@@ -5379,10 +5371,9 @@ class CodeGenFunction : public CodeGenTypeCache {
53795371
llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs);
53805372
llvm::Value *EmitX86CpuSupports(std::array<uint32_t, 4> FeatureMask);
53815373
llvm::Value *EmitX86CpuInit();
5382-
llvm::Value *FormX86ResolverCondition(const MultiVersionResolverOption &RO);
5374+
llvm::Value *FormX86ResolverCondition(const FMVResolverOption &RO);
53835375
llvm::Value *EmitAArch64CpuInit();
5384-
llvm::Value *
5385-
FormAArch64ResolverCondition(const MultiVersionResolverOption &RO);
5376+
llvm::Value *FormAArch64ResolverCondition(const FMVResolverOption &RO);
53865377
llvm::Value *EmitAArch64CpuSupports(const CallExpr *E);
53875378
llvm::Value *EmitAArch64CpuSupports(ArrayRef<StringRef> FeatureStrs);
53885379
};

0 commit comments

Comments
 (0)