From 39bab0e11abc1a310c537052872415b29b6a4241 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 22 Jun 2013 15:51:19 +0000 Subject: FunctionAttrs: Merge attributes once instead of doing it for every argument. It has become an expensive operation. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184638 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/FunctionAttrs.cpp | 78 +++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 32 deletions(-) (limited to 'lib/Transforms/IPO') diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp index bc5109b..9e55e61 100644 --- a/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/lib/Transforms/IPO/FunctionAttrs.cpp @@ -410,9 +410,6 @@ bool FunctionAttrs::AddNoCaptureAttrs(const CallGraphSCC &SCC) { ArgumentGraph AG; - AttrBuilder B; - B.addAttribute(Attribute::NoCapture); - // Check each function in turn, determining which pointer arguments are not // captured. for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { @@ -427,43 +424,59 @@ bool FunctionAttrs::AddNoCaptureAttrs(const CallGraphSCC &SCC) { if (F->isDeclaration() || F->mayBeOverridden()) continue; + SmallVector AttrSets; + // Functions that are readonly (or readnone) and nounwind and don't return // a value can't capture arguments. Don't analyze them. if (F->onlyReadsMemory() && F->doesNotThrow() && F->getReturnType()->isVoidTy()) { - for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); - A != E; ++A) { - if (A->getType()->isPointerTy() && !A->hasNoCaptureAttr()) { - A->addAttr(AttributeSet::get(F->getContext(), A->getArgNo() + 1, B)); - ++NumNoCapture; - Changed = true; - } + for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E; + ++A) { + if (!A->getType()->isPointerTy() || A->hasNoCaptureAttr()) + continue; + + AttributeSet In = + F->getAttributes().getParamAttributes(A->getArgNo() + 1); + AttrSets.push_back(In.addAttribute(F->getContext(), A->getArgNo() + 1, + Attribute::NoCapture)); } - continue; - } + } else { + for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E; + ++A) { + if (!A->getType()->isPointerTy() || A->hasNoCaptureAttr()) + continue; - for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A!=E; ++A) - if (A->getType()->isPointerTy() && !A->hasNoCaptureAttr()) { ArgumentUsesTracker Tracker(SCCNodes); PointerMayBeCaptured(A, &Tracker); - if (!Tracker.Captured) { - if (Tracker.Uses.empty()) { - // If it's trivially not captured, mark it nocapture now. - A->addAttr(AttributeSet::get(F->getContext(), A->getArgNo()+1, B)); - ++NumNoCapture; - Changed = true; - } else { - // If it's not trivially captured and not trivially not captured, - // then it must be calling into another function in our SCC. Save - // its particulars for Argument-SCC analysis later. - ArgumentGraphNode *Node = AG[A]; - for (SmallVectorImpl::iterator UI = Tracker.Uses.begin(), - UE = Tracker.Uses.end(); UI != UE; ++UI) - Node->Uses.push_back(AG[*UI]); - } + if (Tracker.Captured) + continue; // It's captured. Don't bother doing SCC analysis on it. + + if (Tracker.Uses.empty()) { + // If it's trivially not captured, mark it nocapture now. + AttributeSet In = + F->getAttributes().getParamAttributes(A->getArgNo() + 1); + AttrSets.push_back(In.addAttribute(F->getContext(), A->getArgNo() + 1, + Attribute::NoCapture)); + } else { + // If it's not trivially captured and not trivially not captured, + // then it must be calling into another function in our SCC. Save + // its particulars for Argument-SCC analysis later. + ArgumentGraphNode *Node = AG[A]; + for (SmallVectorImpl::iterator UI = Tracker.Uses.begin(), + UE = Tracker.Uses.end(); + UI != UE; ++UI) + Node->Uses.push_back(AG[*UI]); } - // Otherwise, it's captured. Don't bother doing SCC analysis on it. } + } + + // Merge all attribute sets into one in a single step. + if (!AttrSets.empty()) { + NumNoCapture += AttrSets.size(); + AttrSets.push_back(F->getAttributes()); + F->setAttributes(AttributeSet::get(F->getContext(), AttrSets)); + Changed = true; + } } // The graph we've collected is partial because we stopped scanning for @@ -486,7 +499,7 @@ bool FunctionAttrs::AddNoCaptureAttrs(const CallGraphSCC &SCC) { Definition-> addAttr(AttributeSet::get(ArgumentSCC[0]->Definition->getContext(), ArgumentSCC[0]->Definition->getArgNo() + 1, - B)); + Attribute::NoCapture)); ++NumNoCapture; Changed = true; } @@ -528,7 +541,8 @@ bool FunctionAttrs::AddNoCaptureAttrs(const CallGraphSCC &SCC) { for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) { Argument *A = ArgumentSCC[i]->Definition; - A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B)); + A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, + Attribute::NoCapture)); ++NumNoCapture; Changed = true; } -- cgit v1.1