diff options
author | Liu, Chen3 <chen3.liu@intel.com> | 2020-10-10 18:42:05 +0800 |
---|---|---|
committer | Liu, Chen3 <chen3.liu@intel.com> | 2020-10-30 10:32:53 +0800 |
commit | 00090a2b826a9b357acec51df57b9b47d4decb0d (patch) | |
tree | e1b662cd154db457a706efeb8d598c253c7015c3 /clang/lib/CodeGen/CodeGenFunction.h | |
parent | 30e7df0d58542ad35d517eace70a4cea40e6fa7a (diff) | |
download | llvm-00090a2b826a9b357acec51df57b9b47d4decb0d.zip llvm-00090a2b826a9b357acec51df57b9b47d4decb0d.tar.gz llvm-00090a2b826a9b357acec51df57b9b47d4decb0d.tar.bz2 |
Support complex target features combinations
This patch is mainly doing two things:
1. Adding support for parentheses, making the combination of target features
more diverse;
2. Making the priority of ’,‘ is higher than that of '|' by default. So I need
to make some change with PTX Builtin function.
Differential Revision: https://reviews.llvm.org/D89184
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 4710130..2616226 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4688,6 +4688,77 @@ private: llvm::Value *FormResolverCondition(const MultiVersionResolverOption &RO); }; +/// TargetFeatures - This class is used to check whether the builtin function +/// has the required tagert specific features. It is able to support the +/// combination of ','(and), '|'(or), and '()'. By default, the priority of +/// ',' is higher than that of '|' . +/// E.g: +/// A,B|C means the builtin function requires both A and B, or C. +/// If we want the builtin function requires both A and B, or both A and C, +/// there are two ways: A,B|A,C or A,(B|C). +/// The FeaturesList should not contain spaces, and brackets must appear in +/// pairs. +class TargetFeatures { + struct FeatureListStatus { + bool HasFeatures; + StringRef CurFeaturesList; + }; + + const llvm::StringMap<bool> &CallerFeatureMap; + + FeatureListStatus getAndFeatures(StringRef FeatureList) { + int InParentheses = 0; + bool HasFeatures = true; + size_t SubexpressionStart = 0; + for (size_t i = 0, e = FeatureList.size(); i < e; ++i) { + char CurrentToken = FeatureList[i]; + switch (CurrentToken) { + default: + break; + case '(': + if (InParentheses == 0) + SubexpressionStart = i + 1; + ++InParentheses; + break; + case ')': + --InParentheses; + assert(InParentheses >= 0 && "Parentheses are not in pair"); + LLVM_FALLTHROUGH; + case '|': + case ',': + if (InParentheses == 0) { + if (HasFeatures && i != SubexpressionStart) { + StringRef F = FeatureList.slice(SubexpressionStart, i); + HasFeatures = CurrentToken == ')' ? hasRequiredFeatures(F) + : CallerFeatureMap.lookup(F); + } + SubexpressionStart = i + 1; + if (CurrentToken == '|') { + return {HasFeatures, FeatureList.substr(SubexpressionStart)}; + } + } + break; + } + } + assert(InParentheses == 0 && "Parentheses are not in pair"); + if (HasFeatures && SubexpressionStart != FeatureList.size()) + HasFeatures = + CallerFeatureMap.lookup(FeatureList.substr(SubexpressionStart)); + return {HasFeatures, StringRef()}; + } + +public: + bool hasRequiredFeatures(StringRef FeatureList) { + FeatureListStatus FS = {false, FeatureList}; + while (!FS.HasFeatures && !FS.CurFeaturesList.empty()) + FS = getAndFeatures(FS.CurFeaturesList); + return FS.HasFeatures; + } + + TargetFeatures(const llvm::StringMap<bool> &CallerFeatureMap) + : CallerFeatureMap(CallerFeatureMap) {} +}; + inline DominatingLLVMValue::saved_type DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) { if (!needsSaving(value)) return saved_type(value, false); |