@@ -1702,8 +1702,9 @@ static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
1702
1702
FuncAttrs.addAttribute (llvm::Attribute::NoUnwind);
1703
1703
}
1704
1704
1705
- void CodeGenModule::ConstructDefaultFnAttrList (StringRef Name, bool HasOptnone,
1706
- bool AttrOnCallSite,
1705
+ void CodeGenModule::getDefaultFunctionAttributes (StringRef Name,
1706
+ bool HasOptnone,
1707
+ bool AttrOnCallSite,
1707
1708
llvm::AttrBuilder &FuncAttrs) {
1708
1709
// OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
1709
1710
if (!HasOptnone) {
@@ -1796,6 +1797,8 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
1796
1797
FuncAttrs.addAttribute (" stackrealign" );
1797
1798
if (CodeGenOpts.Backchain )
1798
1799
FuncAttrs.addAttribute (" backchain" );
1800
+ if (CodeGenOpts.EnableSegmentedStacks )
1801
+ FuncAttrs.addAttribute (" split-stack" );
1799
1802
if (CodeGenOpts.PointerAuth .ReturnAddresses )
1800
1803
FuncAttrs.addAttribute (" ptrauth-returns" );
1801
1804
if (CodeGenOpts.PointerAuth .FunctionPointers )
@@ -1834,13 +1837,21 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
1834
1837
}
1835
1838
}
1836
1839
1837
- void CodeGenModule::AddDefaultFnAttrs (llvm::Function &F) {
1840
+ void CodeGenModule::addDefaultFunctionDefinitionAttributes (llvm::Function &F) {
1838
1841
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?
1841
1845
F.addAttributes (llvm::AttributeList::FunctionIndex, FuncAttrs);
1842
1846
}
1843
1847
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
+
1844
1855
static void addNoBuiltinAttributes (llvm::AttrBuilder &FuncAttrs,
1845
1856
const LangOptions &LangOpts,
1846
1857
const NoBuiltinAttr *NBA = nullptr ) {
@@ -1877,26 +1888,47 @@ static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
1877
1888
llvm::for_each (NBA->builtinNames (), AddNoBuiltinAttr);
1878
1889
}
1879
1890
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
+ // /
1880
1908
void CodeGenModule::ConstructAttributeList (
1881
1909
StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
1882
1910
llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) {
1883
1911
llvm::AttrBuilder FuncAttrs;
1884
1912
llvm::AttrBuilder RetAttrs;
1885
1913
1914
+ // Collect function IR attributes from the CC lowering.
1915
+ // We'll collect the paramete and result attributes later.
1886
1916
CallingConv = FI.getEffectiveCallingConvention ();
1887
1917
if (FI.isNoReturn ())
1888
1918
FuncAttrs.addAttribute (llvm::Attribute::NoReturn);
1889
1919
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.
1892
1921
AddAttributesFromFunctionProtoType (getContext (), FuncAttrs,
1893
1922
CalleeInfo.getCalleeFunctionProtoType ());
1894
1923
1895
1924
const Decl *TargetDecl = CalleeInfo.getCalleeDecl ().getDecl ();
1896
1925
1897
1926
bool HasOptnone = false ;
1898
- // The NoBuiltinAttr attached to a TargetDecl (only allowed on FunctionDecls) .
1927
+ // The NoBuiltinAttr attached to the target FunctionDecl .
1899
1928
const NoBuiltinAttr *NBA = nullptr ;
1929
+
1930
+ // Collect function IR attributes based on declaration-specific
1931
+ // information.
1900
1932
// FIXME: handle sseregparm someday...
1901
1933
if (TargetDecl) {
1902
1934
if (TargetDecl->hasAttr <ReturnsTwiceAttr>())
@@ -1955,6 +1987,21 @@ void CodeGenModule::ConstructAttributeList(
1955
1987
FuncAttrs.addAllocSizeAttr (AllocSize->getElemSizeParam ().getLLVMIndex (),
1956
1988
NumElemsParam);
1957
1989
}
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
+ }
1958
2005
}
1959
2006
1960
2007
// Attach "no-builtins" attributes to:
@@ -1965,68 +2012,65 @@ void CodeGenModule::ConstructAttributeList(
1965
2012
// * FunctionDecl attributes: __attribute__((no_builtin(...)))
1966
2013
addNoBuiltinAttributes (FuncAttrs, getLangOpts (), NBA);
1967
2014
1968
- ConstructDefaultFnAttrList (Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2015
+ // Collect function IR attributes based on global settiings.
2016
+ getDefaultFunctionAttributes (Name, HasOptnone, AttrOnCallSite, FuncAttrs);
1969
2017
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.
1973
2020
if (TargetDecl) {
1974
2021
if (TargetDecl->hasAttr <NoSpeculativeLoadHardeningAttr>())
1975
2022
FuncAttrs.removeAttribute (llvm::Attribute::SpeculativeLoadHardening);
1976
2023
if (TargetDecl->hasAttr <SpeculativeLoadHardeningAttr>())
1977
2024
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
+ }
1990
2037
}
1991
2038
}
1992
2039
}
1993
2040
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.
2009
2043
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 ;
2011
2052
2012
- if (CodeGenOpts.DisableTailCalls )
2013
- DisableTailCalls = true ;
2014
- else if (TargetDecl) {
2015
2053
if (TargetDecl->hasAttr <DisableTailCallsAttr>() ||
2016
2054
TargetDecl->hasAttr <AnyX86InterruptAttr>())
2017
- DisableTailCalls = true ;
2018
- else if (CodeGenOpts.NoEscapingBlockTailCalls ) {
2055
+ return true ;
2056
+
2057
+ if (CodeGenOpts.NoEscapingBlockTailCalls ) {
2019
2058
if (const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
2020
2059
if (!BD->doesNotEscape ())
2021
- DisableTailCalls = true ;
2060
+ return true ;
2022
2061
}
2023
- }
2024
2062
2063
+ return false ;
2064
+ };
2025
2065
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.
2027
2070
GetCPUAndFeaturesAttributes (CalleeInfo.getCalleeDecl (), FuncAttrs);
2028
2071
}
2029
2072
2073
+ // Collect attributes from arguments and return values.
2030
2074
ClangToLLVMArgMapping IRFunctionArgs (getContext (), FI);
2031
2075
2032
2076
QualType RetTy = FI.getReturnType ();
0 commit comments