Skip to content

Commit d400def

Browse files
author
git apple-llvm automerger
committed
Merge commit '504402111f1b' from apple/stable/20200108 into swift/release/5.3
2 parents bad8a72 + 5044021 commit d400def

File tree

5 files changed

+129
-55
lines changed

5 files changed

+129
-55
lines changed

clang/include/clang/CodeGen/CodeGenABITypes.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "clang/CodeGen/CGFunctionInfo.h"
2929

3030
namespace llvm {
31+
class AttrBuilder;
3132
class Constant;
3233
class DataLayout;
3334
class Module;
@@ -102,6 +103,25 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T);
102103
unsigned getLLVMFieldNumber(CodeGenModule &CGM,
103104
const RecordDecl *RD, const FieldDecl *FD);
104105

106+
/// Given the language and code-generation options that Clang was configured
107+
/// with, set the default LLVM IR attributes for a function definition.
108+
/// The attributes set here are mostly global target-configuration and
109+
/// pipeline-configuration options like the target CPU, variant stack
110+
/// rules, whether to optimize for size, and so on. This is useful for
111+
/// frontends (such as Swift) that generally intend to interoperate with
112+
/// C code and rely on Clang's target configuration logic.
113+
///
114+
/// As a general rule, this function assumes that meaningful attributes
115+
/// haven't already been added to the builder. It won't intentionally
116+
/// displace any existing attributes, but it also won't check to avoid
117+
/// overwriting them. Callers should generally apply customizations after
118+
/// making this call.
119+
///
120+
/// This function assumes that the caller is not defining a function that
121+
/// requires special no-builtin treatment.
122+
void addDefaultFunctionDefinitionAttributes(CodeGenModule &CGM,
123+
llvm::AttrBuilder &attrs);
124+
105125
/// Compute a stable hash of the given string.
106126
///
107127
/// The exact algorithm is the little-endian interpretation of the

clang/lib/CodeGen/CGCall.cpp

Lines changed: 92 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,8 +1702,9 @@ static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
17021702
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
17031703
}
17041704

1705-
void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
1706-
bool AttrOnCallSite,
1705+
void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
1706+
bool HasOptnone,
1707+
bool AttrOnCallSite,
17071708
llvm::AttrBuilder &FuncAttrs) {
17081709
// OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
17091710
if (!HasOptnone) {
@@ -1796,6 +1797,8 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
17961797
FuncAttrs.addAttribute("stackrealign");
17971798
if (CodeGenOpts.Backchain)
17981799
FuncAttrs.addAttribute("backchain");
1800+
if (CodeGenOpts.EnableSegmentedStacks)
1801+
FuncAttrs.addAttribute("split-stack");
17991802
if (CodeGenOpts.PointerAuth.ReturnAddresses)
18001803
FuncAttrs.addAttribute("ptrauth-returns");
18011804
if (CodeGenOpts.PointerAuth.FunctionPointers)
@@ -1834,13 +1837,21 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
18341837
}
18351838
}
18361839

1837-
void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
1840+
void CodeGenModule::addDefaultFunctionDefinitionAttributes(llvm::Function &F) {
18381841
llvm::AttrBuilder FuncAttrs;
1839-
ConstructDefaultFnAttrList(F.getName(), F.hasOptNone(),
1840-
/* AttrOnCallSite = */ false, FuncAttrs);
1842+
getDefaultFunctionAttributes(F.getName(), F.hasOptNone(),
1843+
/* AttrOnCallSite = */ false, FuncAttrs);
1844+
// TODO: call GetCPUAndFeaturesAttributes?
18411845
F.addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs);
18421846
}
18431847

1848+
void CodeGenModule::addDefaultFunctionDefinitionAttributes(
1849+
llvm::AttrBuilder &attrs) {
1850+
getDefaultFunctionAttributes(/*function name*/ "", /*optnone*/ false,
1851+
/*for call*/ false, attrs);
1852+
GetCPUAndFeaturesAttributes(GlobalDecl(), attrs);
1853+
}
1854+
18441855
static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
18451856
const LangOptions &LangOpts,
18461857
const NoBuiltinAttr *NBA = nullptr) {
@@ -1877,26 +1888,47 @@ static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
18771888
llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
18781889
}
18791890

1891+
/// Construct the IR attribute list of a function or call.
1892+
///
1893+
/// When adding an attribute, please consider where it should be handled:
1894+
///
1895+
/// - getDefaultFunctionAttributes is for attributes that are essentially
1896+
/// part of the global target configuration (but perhaps can be
1897+
/// overridden on a per-function basis). Adding attributes there
1898+
/// will cause them to also be set in frontends that build on Clang's
1899+
/// target-configuration logic, as well as for code defined in library
1900+
/// modules such as CUDA's libdevice.
1901+
///
1902+
/// - ConstructAttributeList builds on top of getDefaultFunctionAttributes
1903+
/// and adds declaration-specific, convention-specific, and
1904+
/// frontend-specific logic. The last is of particular importance:
1905+
/// attributes that restrict how the frontend generates code must be
1906+
/// added here rather than getDefaultFunctionAttributes.
1907+
///
18801908
void CodeGenModule::ConstructAttributeList(
18811909
StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
18821910
llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) {
18831911
llvm::AttrBuilder FuncAttrs;
18841912
llvm::AttrBuilder RetAttrs;
18851913

1914+
// Collect function IR attributes from the CC lowering.
1915+
// We'll collect the paramete and result attributes later.
18861916
CallingConv = FI.getEffectiveCallingConvention();
18871917
if (FI.isNoReturn())
18881918
FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
18891919

1890-
// If we have information about the function prototype, we can learn
1891-
// attributes from there.
1920+
// Collect function IR attributes from the callee prototype if we have one.
18921921
AddAttributesFromFunctionProtoType(getContext(), FuncAttrs,
18931922
CalleeInfo.getCalleeFunctionProtoType());
18941923

18951924
const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl();
18961925

18971926
bool HasOptnone = false;
1898-
// The NoBuiltinAttr attached to a TargetDecl (only allowed on FunctionDecls).
1927+
// The NoBuiltinAttr attached to the target FunctionDecl.
18991928
const NoBuiltinAttr *NBA = nullptr;
1929+
1930+
// Collect function IR attributes based on declaration-specific
1931+
// information.
19001932
// FIXME: handle sseregparm someday...
19011933
if (TargetDecl) {
19021934
if (TargetDecl->hasAttr<ReturnsTwiceAttr>())
@@ -1955,6 +1987,21 @@ void CodeGenModule::ConstructAttributeList(
19551987
FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
19561988
NumElemsParam);
19571989
}
1990+
1991+
if (TargetDecl->hasAttr<OpenCLKernelAttr>()) {
1992+
if (getLangOpts().OpenCLVersion <= 120) {
1993+
// OpenCL v1.2 Work groups are always uniform
1994+
FuncAttrs.addAttribute("uniform-work-group-size", "true");
1995+
} else {
1996+
// OpenCL v2.0 Work groups may be whether uniform or not.
1997+
// '-cl-uniform-work-group-size' compile option gets a hint
1998+
// to the compiler that the global work-size be a multiple of
1999+
// the work-group size specified to clEnqueueNDRangeKernel
2000+
// (i.e. work groups are uniform).
2001+
FuncAttrs.addAttribute("uniform-work-group-size",
2002+
llvm::toStringRef(CodeGenOpts.UniformWGSize));
2003+
}
2004+
}
19582005
}
19592006

19602007
// Attach "no-builtins" attributes to:
@@ -1965,68 +2012,65 @@ void CodeGenModule::ConstructAttributeList(
19652012
// * FunctionDecl attributes: __attribute__((no_builtin(...)))
19662013
addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA);
19672014

1968-
ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2015+
// Collect function IR attributes based on global settiings.
2016+
getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
19692017

1970-
// This must run after constructing the default function attribute list
1971-
// to ensure that the speculative load hardening attribute is removed
1972-
// in the case where the -mspeculative-load-hardening flag was passed.
2018+
// Override some default IR attributes based on declaration-specific
2019+
// information.
19732020
if (TargetDecl) {
19742021
if (TargetDecl->hasAttr<NoSpeculativeLoadHardeningAttr>())
19752022
FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
19762023
if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>())
19772024
FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
1978-
}
1979-
1980-
if (CodeGenOpts.EnableSegmentedStacks &&
1981-
!(TargetDecl && TargetDecl->hasAttr<NoSplitStackAttr>()))
1982-
FuncAttrs.addAttribute("split-stack");
1983-
1984-
// Add NonLazyBind attribute to function declarations when -fno-plt
1985-
// is used.
1986-
if (TargetDecl && CodeGenOpts.NoPLT) {
1987-
if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
1988-
if (!Fn->isDefined() && !AttrOnCallSite) {
1989-
FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2025+
if (TargetDecl->hasAttr<NoSplitStackAttr>())
2026+
FuncAttrs.removeAttribute("split-stack");
2027+
2028+
// Add NonLazyBind attribute to function declarations when -fno-plt
2029+
// is used.
2030+
// FIXME: what if we just haven't processed the function definition
2031+
// yet, or if it's an external definition like C99 inline?
2032+
if (CodeGenOpts.NoPLT) {
2033+
if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2034+
if (!Fn->isDefined() && !AttrOnCallSite) {
2035+
FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2036+
}
19902037
}
19912038
}
19922039
}
19932040

1994-
if (TargetDecl && TargetDecl->hasAttr<OpenCLKernelAttr>()) {
1995-
if (getLangOpts().OpenCLVersion <= 120) {
1996-
// OpenCL v1.2 Work groups are always uniform
1997-
FuncAttrs.addAttribute("uniform-work-group-size", "true");
1998-
} else {
1999-
// OpenCL v2.0 Work groups may be whether uniform or not.
2000-
// '-cl-uniform-work-group-size' compile option gets a hint
2001-
// to the compiler that the global work-size be a multiple of
2002-
// the work-group size specified to clEnqueueNDRangeKernel
2003-
// (i.e. work groups are uniform).
2004-
FuncAttrs.addAttribute("uniform-work-group-size",
2005-
llvm::toStringRef(CodeGenOpts.UniformWGSize));
2006-
}
2007-
}
2008-
2041+
// Collect non-call-site function IR attributes from declaration-specific
2042+
// information.
20092043
if (!AttrOnCallSite) {
2010-
bool DisableTailCalls = false;
2044+
// Whether tail calls are enabled.
2045+
auto shouldDisableTailCalls = [&] {
2046+
// Should this be honored in getDefaultFunctionAttributes?
2047+
if (CodeGenOpts.DisableTailCalls)
2048+
return true;
2049+
2050+
if (!TargetDecl)
2051+
return false;
20112052

2012-
if (CodeGenOpts.DisableTailCalls)
2013-
DisableTailCalls = true;
2014-
else if (TargetDecl) {
20152053
if (TargetDecl->hasAttr<DisableTailCallsAttr>() ||
20162054
TargetDecl->hasAttr<AnyX86InterruptAttr>())
2017-
DisableTailCalls = true;
2018-
else if (CodeGenOpts.NoEscapingBlockTailCalls) {
2055+
return true;
2056+
2057+
if (CodeGenOpts.NoEscapingBlockTailCalls) {
20192058
if (const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
20202059
if (!BD->doesNotEscape())
2021-
DisableTailCalls = true;
2060+
return true;
20222061
}
2023-
}
20242062

2063+
return false;
2064+
};
20252065
FuncAttrs.addAttribute("disable-tail-calls",
2026-
llvm::toStringRef(DisableTailCalls));
2066+
llvm::toStringRef(shouldDisableTailCalls()));
2067+
2068+
// CPU/feature overrides. addDefaultFunctionDefinitionAttributes
2069+
// handles these separately to set them based on the global defaults.
20272070
GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
20282071
}
20292072

2073+
// Collect attributes from arguments and return values.
20302074
ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI);
20312075

20322076
QualType RetTy = FI.getReturnType();

clang/lib/CodeGen/CodeGenABITypes.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
using namespace clang;
2828
using namespace CodeGen;
2929

30+
void CodeGen::addDefaultFunctionDefinitionAttributes(CodeGenModule &CGM,
31+
llvm::AttrBuilder &attrs) {
32+
CGM.addDefaultFunctionDefinitionAttributes(attrs);
33+
}
34+
3035
const CGFunctionInfo &
3136
CodeGen::arrangeObjCMessageSendSignature(CodeGenModule &CGM,
3237
const ObjCMethodDecl *MD,

clang/lib/CodeGen/CodeGenAction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ namespace clang {
223223
for (auto &LM : LinkModules) {
224224
if (LM.PropagateAttrs)
225225
for (Function &F : *LM.Module)
226-
Gen->CGM().AddDefaultFnAttrs(F);
226+
Gen->CGM().addDefaultFunctionDefinitionAttributes(F);
227227

228228
CurLinkModule = LM.Module.get();
229229

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,11 @@ class CodeGenModule : public CodeGenTypeCache {
12191219
/// on the function more conservative. But it's unsafe to call this on a
12201220
/// function which relies on particular fast-math attributes for correctness.
12211221
/// It's up to you to ensure that this is safe.
1222-
void AddDefaultFnAttrs(llvm::Function &F);
1222+
void addDefaultFunctionDefinitionAttributes(llvm::Function &F);
1223+
1224+
/// Like the overload taking a `Function &`, but intended specifically
1225+
/// for frontends that want to build on Clang's target-configuration logic.
1226+
void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs);
12231227

12241228
StringRef getMangledName(GlobalDecl GD);
12251229
StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
@@ -1574,11 +1578,12 @@ class CodeGenModule : public CodeGenTypeCache {
15741578

15751579
void destroyConstantSignedPointerCaches();
15761580

1577-
/// Helper function for ConstructAttributeList and AddDefaultFnAttrs.
1578-
/// Constructs an AttrList for a function with the given properties.
1579-
void ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
1580-
bool AttrOnCallSite,
1581-
llvm::AttrBuilder &FuncAttrs);
1581+
/// Helper function for ConstructAttributeList and
1582+
/// addDefaultFunctionDefinitionAttributes. Builds a set of function
1583+
/// attributes to add to a function with the given properties.
1584+
void getDefaultFunctionAttributes(StringRef Name, bool HasOptnone,
1585+
bool AttrOnCallSite,
1586+
llvm::AttrBuilder &FuncAttrs);
15821587

15831588
llvm::Metadata *CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map,
15841589
StringRef Suffix);

0 commit comments

Comments
 (0)