clang 24.0.0git
FunctionUtils.cpp
Go to the documentation of this file.
1//===--- FunctionUtils.cpp - Shared function emission queries -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "clang/AST/Attr.h"
12#include "clang/AST/Expr.h"
17#include "llvm/ADT/StringMap.h"
18
19namespace clang::CodeGenUtils {
20
22 const LangOptions &LangOpts) {
23 if (CGOpts.DisableLifetimeMarkers)
24 return false;
25
26 // Sanitizers may use markers.
27 if (CGOpts.SanitizeAddressUseAfterScope ||
28 LangOpts.Sanitize.has(SanitizerKind::HWAddress) ||
29 LangOpts.Sanitize.has(SanitizerKind::Memory) ||
30 LangOpts.Sanitize.has(SanitizerKind::MemtagStack))
31 return true;
32
33 // For now, only in optimized builds.
34 return CGOpts.OptimizationLevel != 0;
35}
36
37// Emits an error if we don't have a valid set of target features for the
38// called function.
40 const LangOptions &LangOpts, const CallExpr *E,
41 const FunctionDecl *Caller,
42 const FunctionDecl *TargetDecl) {
43 // SemaChecking cannot handle these x86 builtins because they have different
44 // parameter ranges depending on the caller's TargetAttribute.
45 if (Ctx.getTargetInfo().getTriple().isX86()) {
46 unsigned BuiltinID = TargetDecl->getBuiltinID();
47 if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
48 BuiltinID == X86::BI__builtin_ia32_cmpss ||
49 BuiltinID == X86::BI__builtin_ia32_cmppd ||
50 BuiltinID == X86::BI__builtin_ia32_cmpsd) {
51 llvm::StringMap<bool> TargetFeatureMap;
52 Ctx.getFunctionFeatureMap(TargetFeatureMap, Caller);
53 llvm::APSInt Result = *(E->getArg(2)->getIntegerConstantExpr(Ctx));
54 if (Result.getSExtValue() > 7 && !TargetFeatureMap.lookup("avx"))
55 Diags.Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
56 << TargetDecl->getDeclName() << "avx";
57 }
58 }
59 checkTargetFeatures(Ctx, Diags, LangOpts, E->getBeginLoc(), Caller,
60 TargetDecl);
61}
62
63// Emits an error if we don't have a valid set of target features for the
64// called function.
66 const LangOptions &LangOpts, SourceLocation Loc,
67 const FunctionDecl *Caller,
68 const FunctionDecl *TargetDecl) {
69 if (!TargetDecl || !Caller)
70 return;
71
72 bool IsAlwaysInline = TargetDecl->hasAttr<AlwaysInlineAttr>();
73 bool IsFlatten = Caller->hasAttr<FlattenAttr>();
74
75 unsigned BuiltinID = TargetDecl->getBuiltinID();
76 std::string MissingFeature;
77 llvm::StringMap<bool> CallerFeatureMap;
78 Ctx.getFunctionFeatureMap(CallerFeatureMap, Caller);
79 // When compiling in HipStdPar mode we have to be conservative in rejecting
80 // target specific features in the FE, and defer the possible error to the
81 // AcceleratorCodeSelection pass, wherein iff an unsupported target builtin is
82 // referenced by an accelerator executable function, we emit an error.
83 bool IsHipStdPar = LangOpts.HIPStdPar && LangOpts.CUDAIsDevice;
84 if (BuiltinID) {
85 StringRef FeatureList(Ctx.BuiltinInfo.getRequiredFeatures(BuiltinID));
87 CallerFeatureMap) &&
88 !IsHipStdPar)
89 Diags.Report(Loc, diag::err_builtin_needs_feature)
90 << TargetDecl->getDeclName() << FeatureList;
91 } else if (!TargetDecl->isMultiVersion() &&
92 TargetDecl->hasAttr<TargetAttr>()) {
93 // Get the required features for the callee.
94 const TargetAttr *TD = TargetDecl->getAttr<TargetAttr>();
96
97 SmallVector<StringRef, 1> ReqFeatures;
98 llvm::StringMap<bool> CalleeFeatureMap;
99 Ctx.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
100
101 for (const auto &F : ParsedAttr.Features) {
102 if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))
103 ReqFeatures.push_back(StringRef(F).substr(1));
104 }
105 for (const auto &F : CalleeFeatureMap) {
106 if (F.getValue())
107 ReqFeatures.push_back(F.getKey());
108 }
109 if (!llvm::all_of(ReqFeatures,
110 [&](StringRef Feature) {
111 if (!CallerFeatureMap.lookup(Feature)) {
112 MissingFeature = Feature.str();
113 return false;
114 }
115 return true;
116 }) &&
117 !IsHipStdPar) {
118 if (IsAlwaysInline)
119 Diags.Report(Loc, diag::err_function_needs_feature)
120 << Caller->getDeclName() << TargetDecl->getDeclName()
121 << MissingFeature;
122 else if (IsFlatten)
123 Diags.Report(Loc, diag::err_flatten_function_needs_feature)
124 << Caller->getDeclName() << TargetDecl->getDeclName()
125 << MissingFeature;
126 }
127 } else if (!Caller->isMultiVersion() && Caller->hasAttr<TargetAttr>()) {
128 llvm::StringMap<bool> CalleeFeatureMap;
129 Ctx.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
130
131 for (const auto &F : CalleeFeatureMap) {
132 if (F.getValue() &&
133 (!CallerFeatureMap.lookup(F.getKey()) ||
134 !CallerFeatureMap.find(F.getKey())->getValue()) &&
135 !IsHipStdPar) {
136 if (IsAlwaysInline)
137 Diags.Report(Loc, diag::err_function_needs_feature)
138 << Caller->getDeclName() << TargetDecl->getDeclName()
139 << F.getKey();
140 else if (IsFlatten)
141 Diags.Report(Loc, diag::err_flatten_function_needs_feature)
142 << Caller->getDeclName() << TargetDecl->getDeclName()
143 << F.getKey();
144 }
145 }
146 }
147}
148
149} // namespace clang::CodeGenUtils
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const
Parses the target attributes passed in, and returns only the ones that are valid feature names.
Builtin::Context & BuiltinInfo
Definition ASTContext.h:858
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:975
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
const char * getRequiredFeatures(unsigned ID) const
Definition Builtins.cpp:118
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2991
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3195
SourceLocation getBeginLoc() const
Definition Expr.h:3325
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
T * getAttr() const
Definition DeclBase.h:581
bool hasAttr() const
Definition DeclBase.h:585
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:241
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents a function declaration or definition.
Definition Decl.h:2059
bool isMultiVersion() const
True if this function is considered a multiversioned function.
Definition Decl.h:2820
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3809
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
SanitizerSet Sanitize
Set of enabled sanitizers.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
ParsedAttr - Represents a syntactic attribute.
Definition ParsedAttr.h:119
Encodes a location in the source.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, const LangOptions &LangOpts)
Decide whether we need to emit the lifetime markers.
void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const CallExpr *E, const FunctionDecl *Caller, const FunctionDecl *TargetDecl)
Check that a call to a target-specific builtin has the required target features enabled in the caller...
@ Result
The result type of a method or function.
Definition TypeBase.h:906
Contains information gathered from parsing the contents of TargetAttr.
Definition TargetInfo.h:59
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition Sanitizers.h:174