mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-16 11:30:51 +00:00
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
This commit is contained in:
parent
5c368899b3
commit
39bab0e11a
@ -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<AttributeSet, 8> 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;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
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));
|
||||
}
|
||||
} 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<Argument*>::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<Argument *>::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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user