summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorLuke Cheeseman <luke.cheeseman@arm.com>2018-02-22 14:42:08 +0000
committerLuke Cheeseman <luke.cheeseman@arm.com>2018-02-22 14:42:08 +0000
commit6c1e6bbe0c609489ef49f9d64f1370a43e05c19c (patch)
tree42f8f4b2437344e153ec13ac4fcf82182d1f75ed /llvm/lib/Transforms
parent92b73711138b3d37855fb527a538c85b293f37a7 (diff)
downloadbcm5719-llvm-6c1e6bbe0c609489ef49f9d64f1370a43e05c19c.tar.gz
bcm5719-llvm-6c1e6bbe0c609489ef49f9d64f1370a43e05c19c.zip
[FunctionAttrs][ArgumentPromotion][GlobalOpt] Disable some optimisations passes for naked functions
- Fix for bug 36078. - Prevent the functionattrs, function-attrs, globalopt and argpromotion passes from changing naked functions. - These passes can perform some alterations to the functions that should not be applied. An example is removing parameters that are seemingly not used because they are only referenced in the inline assembly. Another example is marking the function as fastcc. llvm-svn: 325788
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/ArgumentPromotion.cpp6
-rw-r--r--llvm/lib/Transforms/IPO/FunctionAttrs.cpp6
-rw-r--r--llvm/lib/Transforms/IPO/GlobalOpt.cpp5
3 files changed, 15 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index d3a7b0e76fe..461c4e12cbd 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -817,6 +817,12 @@ promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter,
unsigned MaxElements,
Optional<function_ref<void(CallSite OldCS, CallSite NewCS)>>
ReplaceCallSite) {
+ // Don't perform argument promotion for naked functions; otherwise we can end
+ // up removing parameters that are seemingly 'not used' as they are referred
+ // to in the assembly.
+ if(F->hasFnAttribute(Attribute::Naked))
+ return nullptr;
+
// Make sure that it is local to this module.
if (!F->hasLocalLinkage())
return nullptr;
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 5352e32479b..353daece48e 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -1136,7 +1136,8 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
bool HasUnknownCall = false;
for (LazyCallGraph::Node &N : C) {
Function &F = N.getFunction();
- if (F.hasFnAttribute(Attribute::OptimizeNone)) {
+ if (F.hasFnAttribute(Attribute::OptimizeNone) ||
+ F.hasFnAttribute(Attribute::Naked)) {
// Treat any function we're trying not to optimize as if it were an
// indirect call and omit it from the node set used below.
HasUnknownCall = true;
@@ -1221,7 +1222,8 @@ static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) {
bool ExternalNode = false;
for (CallGraphNode *I : SCC) {
Function *F = I->getFunction();
- if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) {
+ if (!F || F->hasFnAttribute(Attribute::OptimizeNone) ||
+ F->hasFnAttribute(Attribute::Naked)) {
// External node or function we're trying not to optimize - we both avoid
// transform them and avoid leveraging information they provide.
ExternalNode = true;
diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
index 9dfb61d3d73..274ecf0a099 100644
--- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp
@@ -2221,6 +2221,11 @@ OptimizeFunctions(Module &M, TargetLibraryInfo *TLI,
for (Module::iterator FI = M.begin(), E = M.end(); FI != E; ) {
Function *F = &*FI++;
+ // Don't perform global opt pass on naked functions; we don't want fast
+ // calling conventions for naked functions.
+ if (F->hasFnAttribute(Attribute::Naked))
+ continue;
+
// Functions without names cannot be referenced outside this module.
if (!F->hasName() && !F->isDeclaration() && !F->hasLocalLinkage())
F->setLinkage(GlobalValue::InternalLinkage);
OpenPOWER on IntegriCloud