summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp80
1 files changed, 21 insertions, 59 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 3c582688e91..166d588dd55 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2359,91 +2359,53 @@ void CodeGenFunction::EmitSanitizerStatReport(llvm::SanitizerStatKind SSK) {
CGM.getSanStats().create(IRB, SSK);
}
-llvm::Value *CodeGenFunction::FormResolverCondition(
- const TargetMultiVersionResolverOption &RO) {
- llvm::Value *TrueCondition = nullptr;
- if (!RO.ParsedAttribute.Architecture.empty())
- TrueCondition = EmitX86CpuIs(RO.ParsedAttribute.Architecture);
-
- if (!RO.ParsedAttribute.Features.empty()) {
- SmallVector<StringRef, 8> FeatureList;
- llvm::for_each(RO.ParsedAttribute.Features,
- [&FeatureList](const std::string &Feature) {
- FeatureList.push_back(StringRef{Feature}.substr(1));
- });
- llvm::Value *FeatureCmp = EmitX86CpuSupports(FeatureList);
- TrueCondition = TrueCondition ? Builder.CreateAnd(TrueCondition, FeatureCmp)
- : FeatureCmp;
- }
- return TrueCondition;
-}
-
-void CodeGenFunction::EmitTargetMultiVersionResolver(
- llvm::Function *Resolver,
- ArrayRef<TargetMultiVersionResolverOption> Options) {
- assert((getContext().getTargetInfo().getTriple().getArch() ==
- llvm::Triple::x86 ||
- getContext().getTargetInfo().getTriple().getArch() ==
- llvm::Triple::x86_64) &&
- "Only implemented for x86 targets");
-
- // Main function's basic block.
- llvm::BasicBlock *CurBlock = createBasicBlock("entry", Resolver);
- Builder.SetInsertPoint(CurBlock);
- EmitX86CpuInit();
+llvm::Value *
+CodeGenFunction::FormResolverCondition(const MultiVersionResolverOption &RO) {
+ llvm::Value *Condition = nullptr;
- llvm::Function *DefaultFunc = nullptr;
- for (const TargetMultiVersionResolverOption &RO : Options) {
- Builder.SetInsertPoint(CurBlock);
- llvm::Value *TrueCondition = FormResolverCondition(RO);
+ if (!RO.Conditions.Architecture.empty())
+ Condition = EmitX86CpuIs(RO.Conditions.Architecture);
- if (!TrueCondition) {
- DefaultFunc = RO.Function;
- } else {
- llvm::BasicBlock *RetBlock = createBasicBlock("ro_ret", Resolver);
- llvm::IRBuilder<> RetBuilder(RetBlock);
- RetBuilder.CreateRet(RO.Function);
- CurBlock = createBasicBlock("ro_else", Resolver);
- Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock);
- }
+ if (!RO.Conditions.Features.empty()) {
+ llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
+ Condition =
+ Condition ? Builder.CreateAnd(Condition, FeatureCond) : FeatureCond;
}
-
- assert(DefaultFunc && "No default version?");
- // Emit return from the 'else-ist' block.
- Builder.SetInsertPoint(CurBlock);
- Builder.CreateRet(DefaultFunc);
+ return Condition;
}
-void CodeGenFunction::EmitCPUDispatchMultiVersionResolver(
- llvm::Function *Resolver,
- ArrayRef<CPUDispatchMultiVersionResolverOption> Options) {
+void CodeGenFunction::EmitMultiVersionResolver(
+ llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) {
assert((getContext().getTargetInfo().getTriple().getArch() ==
llvm::Triple::x86 ||
getContext().getTargetInfo().getTriple().getArch() ==
llvm::Triple::x86_64) &&
"Only implemented for x86 targets");
-
// Main function's basic block.
llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
Builder.SetInsertPoint(CurBlock);
EmitX86CpuInit();
- for (const CPUDispatchMultiVersionResolverOption &RO : Options) {
+ for (const MultiVersionResolverOption &RO : Options) {
Builder.SetInsertPoint(CurBlock);
+ llvm::Value *Condition = FormResolverCondition(RO);
- // "generic" case should catch-all.
- if (RO.FeatureMask == 0) {
+ // The 'default' or 'generic' case.
+ if (!Condition) {
+ assert(&RO == Options.end() - 1 &&
+ "Default or Generic case must be last");
Builder.CreateRet(RO.Function);
return;
}
+
llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
llvm::IRBuilder<> RetBuilder(RetBlock);
RetBuilder.CreateRet(RO.Function);
CurBlock = createBasicBlock("resolver_else", Resolver);
- llvm::Value *TrueCondition = EmitX86CpuSupports(RO.FeatureMask);
- Builder.CreateCondBr(TrueCondition, RetBlock, CurBlock);
+ Builder.CreateCondBr(Condition, RetBlock, CurBlock);
}
+ // If no generic/default, emit an unreachable.
Builder.SetInsertPoint(CurBlock);
llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
TrapCall->setDoesNotReturn();
OpenPOWER on IntegriCloud