@@ -1700,8 +1700,9 @@ static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
1700
1700
FuncAttrs.addAttribute (llvm::Attribute::NoUnwind);
1701
1701
}
1702
1702
1703
- void CodeGenModule::ConstructDefaultFnAttrList (StringRef Name, bool HasOptnone,
1704
- bool AttrOnCallSite,
1703
+ void CodeGenModule::getDefaultFunctionAttributes (StringRef Name,
1704
+ bool HasOptnone,
1705
+ bool AttrOnCallSite,
1705
1706
llvm::AttrBuilder &FuncAttrs) {
1706
1707
// OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
1707
1708
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
1800
1803
if (CodeGenOpts.SpeculativeLoadHardening )
1801
1804
FuncAttrs.addAttribute (llvm::Attribute::SpeculativeLoadHardening);
@@ -1822,13 +1825,21 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
1822
1825
}
1823
1826
}
1824
1827
1825
- void CodeGenModule::AddDefaultFnAttrs (llvm::Function &F) {
1828
+ void CodeGenModule::addDefaultFunctionDefinitionAttributes (llvm::Function &F) {
1826
1829
llvm::AttrBuilder FuncAttrs;
1827
- ConstructDefaultFnAttrList (F.getName (), F.hasOptNone (),
1828
- /* AttrOnCallSite = */ false , FuncAttrs);
1830
+ getDefaultFunctionAttributes (F.getName (), F.hasOptNone (),
1831
+ /* AttrOnCallSite = */ false , FuncAttrs);
1832
+ // TODO: call GetCPUAndFeaturesAttributes?
1829
1833
F.addAttributes (llvm::AttributeList::FunctionIndex, FuncAttrs);
1830
1834
}
1831
1835
1836
+ void CodeGenModule::addDefaultFunctionDefinitionAttributes (
1837
+ llvm::AttrBuilder &attrs) {
1838
+ getDefaultFunctionAttributes (/* function name*/ " " , /* optnone*/ false ,
1839
+ /* for call*/ false , attrs);
1840
+ GetCPUAndFeaturesAttributes (GlobalDecl (), attrs);
1841
+ }
1842
+
1832
1843
static void addNoBuiltinAttributes (llvm::AttrBuilder &FuncAttrs,
1833
1844
const LangOptions &LangOpts,
1834
1845
const NoBuiltinAttr *NBA = nullptr ) {
@@ -1865,29 +1876,49 @@ static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
1865
1876
llvm::for_each (NBA->builtinNames (), AddNoBuiltinAttr);
1866
1877
}
1867
1878
1879
+ // / Construct the IR attribute list of a function or call.
1880
+ // /
1881
+ // / When adding an attribute, please consider where it should be handled:
1882
+ // /
1883
+ // / - getDefaultFunctionAttributes is for attributes that are essentially
1884
+ // / part of the global target configuration (but perhaps can be
1885
+ // / overridden on a per-function basis). Adding attributes there
1886
+ // / will cause them to also be set in frontends that build on Clang's
1887
+ // / target-configuration logic, as well as for code defined in library
1888
+ // / modules such as CUDA's libdevice.
1889
+ // /
1890
+ // / - ConstructAttributeList builds on top of getDefaultFunctionAttributes
1891
+ // / and adds declaration-specific, convention-specific, and
1892
+ // / frontend-specific logic. The last is of particular importance:
1893
+ // / attributes that restrict how the frontend generates code must be
1894
+ // / added here rather than getDefaultFunctionAttributes.
1895
+ // /
1868
1896
void CodeGenModule::ConstructAttributeList (
1869
1897
StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
1870
1898
llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) {
1871
1899
llvm::AttrBuilder FuncAttrs;
1872
1900
llvm::AttrBuilder RetAttrs;
1873
1901
1902
+ // Collect function IR attributes from the CC lowering.
1903
+ // We'll collect the paramete and result attributes later.
1874
1904
CallingConv = FI.getEffectiveCallingConvention ();
1875
1905
if (FI.isNoReturn ())
1876
1906
FuncAttrs.addAttribute (llvm::Attribute::NoReturn);
1877
-
1878
1907
if (FI.isCmseNSCall ())
1879
1908
FuncAttrs.addAttribute (" cmse_nonsecure_call" );
1880
1909
1881
- // If we have information about the function prototype, we can learn
1882
- // attributes from there.
1910
+ // Collect function IR attributes from the callee prototype if we have one.
1883
1911
AddAttributesFromFunctionProtoType (getContext (), FuncAttrs,
1884
1912
CalleeInfo.getCalleeFunctionProtoType ());
1885
1913
1886
1914
const Decl *TargetDecl = CalleeInfo.getCalleeDecl ().getDecl ();
1887
1915
1888
1916
bool HasOptnone = false ;
1889
- // The NoBuiltinAttr attached to a TargetDecl (only allowed on FunctionDecls) .
1917
+ // The NoBuiltinAttr attached to the target FunctionDecl .
1890
1918
const NoBuiltinAttr *NBA = nullptr ;
1919
+
1920
+ // Collect function IR attributes based on declaration-specific
1921
+ // information.
1891
1922
// FIXME: handle sseregparm someday...
1892
1923
if (TargetDecl) {
1893
1924
if (TargetDecl->hasAttr <ReturnsTwiceAttr>())
@@ -1953,6 +1984,21 @@ void CodeGenModule::ConstructAttributeList(
1953
1984
FuncAttrs.addAllocSizeAttr (AllocSize->getElemSizeParam ().getLLVMIndex (),
1954
1985
NumElemsParam);
1955
1986
}
1987
+
1988
+ if (TargetDecl->hasAttr <OpenCLKernelAttr>()) {
1989
+ if (getLangOpts ().OpenCLVersion <= 120 ) {
1990
+ // OpenCL v1.2 Work groups are always uniform
1991
+ FuncAttrs.addAttribute (" uniform-work-group-size" , " true" );
1992
+ } else {
1993
+ // OpenCL v2.0 Work groups may be whether uniform or not.
1994
+ // '-cl-uniform-work-group-size' compile option gets a hint
1995
+ // to the compiler that the global work-size be a multiple of
1996
+ // the work-group size specified to clEnqueueNDRangeKernel
1997
+ // (i.e. work groups are uniform).
1998
+ FuncAttrs.addAttribute (" uniform-work-group-size" ,
1999
+ llvm::toStringRef (CodeGenOpts.UniformWGSize ));
2000
+ }
2001
+ }
1956
2002
}
1957
2003
1958
2004
// Attach "no-builtins" attributes to:
@@ -1963,71 +2009,68 @@ void CodeGenModule::ConstructAttributeList(
1963
2009
// * FunctionDecl attributes: __attribute__((no_builtin(...)))
1964
2010
addNoBuiltinAttributes (FuncAttrs, getLangOpts (), NBA);
1965
2011
1966
- ConstructDefaultFnAttrList (Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2012
+ // Collect function IR attributes based on global settiings.
2013
+ getDefaultFunctionAttributes (Name, HasOptnone, AttrOnCallSite, FuncAttrs);
1967
2014
1968
- // This must run after constructing the default function attribute list
1969
- // to ensure that the speculative load hardening attribute is removed
1970
- // in the case where the -mspeculative-load-hardening flag was passed.
2015
+ // Override some default IR attributes based on declaration-specific
2016
+ // information.
1971
2017
if (TargetDecl) {
1972
2018
if (TargetDecl->hasAttr <NoSpeculativeLoadHardeningAttr>())
1973
2019
FuncAttrs.removeAttribute (llvm::Attribute::SpeculativeLoadHardening);
1974
2020
if (TargetDecl->hasAttr <SpeculativeLoadHardeningAttr>())
1975
2021
FuncAttrs.addAttribute (llvm::Attribute::SpeculativeLoadHardening);
1976
- }
1977
-
1978
- if (CodeGenOpts. EnableSegmentedStacks &&
1979
- !(TargetDecl && TargetDecl-> hasAttr <NoSplitStackAttr>()))
1980
- FuncAttrs. addAttribute ( " split-stack " );
1981
-
1982
- // Add NonLazyBind attribute to function declarations when -fno-plt
1983
- // is used.
1984
- if (TargetDecl && CodeGenOpts. NoPLT ) {
1985
- if ( auto *Fn = dyn_cast<FunctionDecl>(TargetDecl) ) {
1986
- if (!Fn-> isDefined () && !AttrOnCallSite) {
1987
- FuncAttrs. addAttribute (llvm::Attribute::NonLazyBind);
2022
+ if (TargetDecl-> hasAttr <NoSplitStackAttr>())
2023
+ FuncAttrs. removeAttribute ( " split-stack " );
2024
+
2025
+ // Add NonLazyBind attribute to function declarations when -fno-plt
2026
+ // is used.
2027
+ // FIXME: what if we just haven't processed the function definition
2028
+ // yet, or if it's an external definition like C99 inline?
2029
+ if (CodeGenOpts. NoPLT ) {
2030
+ if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl) ) {
2031
+ if (!Fn-> isDefined () && !AttrOnCallSite ) {
2032
+ FuncAttrs. addAttribute (llvm::Attribute::NonLazyBind);
2033
+ }
1988
2034
}
1989
2035
}
1990
2036
}
1991
2037
1992
- if (TargetDecl && TargetDecl->hasAttr <OpenCLKernelAttr>()) {
1993
- if (getLangOpts ().OpenCLVersion <= 120 ) {
1994
- // OpenCL v1.2 Work groups are always uniform
1995
- FuncAttrs.addAttribute (" uniform-work-group-size" , " true" );
1996
- } else {
1997
- // OpenCL v2.0 Work groups may be whether uniform or not.
1998
- // '-cl-uniform-work-group-size' compile option gets a hint
1999
- // to the compiler that the global work-size be a multiple of
2000
- // the work-group size specified to clEnqueueNDRangeKernel
2001
- // (i.e. work groups are uniform).
2002
- FuncAttrs.addAttribute (" uniform-work-group-size" ,
2003
- llvm::toStringRef (CodeGenOpts.UniformWGSize ));
2004
- }
2005
- }
2006
-
2038
+ // Collect non-call-site function IR attributes from declaration-specific
2039
+ // information.
2007
2040
if (!AttrOnCallSite) {
2008
2041
if (TargetDecl && TargetDecl->hasAttr <CmseNSEntryAttr>())
2009
2042
FuncAttrs.addAttribute (" cmse_nonsecure_entry" );
2010
2043
2011
- 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 ;
2012
2052
2013
- if (CodeGenOpts.DisableTailCalls )
2014
- DisableTailCalls = true ;
2015
- else if (TargetDecl) {
2016
2053
if (TargetDecl->hasAttr <DisableTailCallsAttr>() ||
2017
2054
TargetDecl->hasAttr <AnyX86InterruptAttr>())
2018
- DisableTailCalls = true ;
2019
- else if (CodeGenOpts.NoEscapingBlockTailCalls ) {
2055
+ return true ;
2056
+
2057
+ if (CodeGenOpts.NoEscapingBlockTailCalls ) {
2020
2058
if (const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
2021
2059
if (!BD->doesNotEscape ())
2022
- DisableTailCalls = true ;
2060
+ return true ;
2023
2061
}
2024
- }
2025
2062
2063
+ return false ;
2064
+ };
2026
2065
FuncAttrs.addAttribute (" disable-tail-calls" ,
2027
- 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.
2028
2070
GetCPUAndFeaturesAttributes (CalleeInfo.getCalleeDecl (), FuncAttrs);
2029
2071
}
2030
2072
2073
+ // Collect attributes from arguments and return values.
2031
2074
ClangToLLVMArgMapping IRFunctionArgs (getContext (), FI);
2032
2075
2033
2076
QualType RetTy = FI.getReturnType ();
0 commit comments