aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/MergeFunctions.cpp
diff options
context:
space:
mode:
authorErik Eckstein <eeckstein@apple.com>2016-05-31 17:20:23 +0000
committerErik Eckstein <eeckstein@apple.com>2016-05-31 17:20:23 +0000
commit0c48dd8ca53f3a962ffa408908b03f4cf45bddcb (patch)
tree6a6b56378415477e0b0350f98d3601728db1fe8c /llvm/lib/Transforms/IPO/MergeFunctions.cpp
parent1762eef57240d261e0fc0ec7ad64aafc3e1b3fc6 (diff)
downloadllvm-0c48dd8ca53f3a962ffa408908b03f4cf45bddcb.zip
llvm-0c48dd8ca53f3a962ffa408908b03f4cf45bddcb.tar.gz
llvm-0c48dd8ca53f3a962ffa408908b03f4cf45bddcb.tar.bz2
Fix a crash in MergeFunctions related to ordering of weak/strong functions
The assumption, made in insert() that weak functions are always inserted after strong functions, is only true in the first round of adding functions. In subsequent rounds this is no longer guaranteed , because we might remove a strong function from the tree (because it's modified) and add it later, where an equivalent weak function already exists in the tree. This change removes the assert in insert() and explicitly enforces a weak->strong order. This also removes the need of two separate loops in runOnModule(). llvm-svn: 271299
Diffstat (limited to 'llvm/lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/MergeFunctions.cpp44
1 files changed, 12 insertions, 32 deletions
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index bb0ab84..27caa07 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -1577,28 +1577,12 @@ bool MergeFunctions::runOnModule(Module &M) {
DEBUG(dbgs() << "size of module: " << M.size() << '\n');
DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n');
- // Insert only strong functions and merge them. Strong function merging
- // always deletes one of them.
+ // Insert functions and merge them.
for (std::vector<WeakVH>::iterator I = Worklist.begin(),
E = Worklist.end(); I != E; ++I) {
if (!*I) continue;
Function *F = cast<Function>(*I);
- if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
- !F->isInterposable()) {
- Changed |= insert(F);
- }
- }
-
- // Insert only weak functions and merge them. By doing these second we
- // create thunks to the strong function when possible. When two weak
- // functions are identical, we create a new strong function with two weak
- // weak thunks to it which are identical but not mergable.
- for (std::vector<WeakVH>::iterator I = Worklist.begin(),
- E = Worklist.end(); I != E; ++I) {
- if (!*I) continue;
- Function *F = cast<Function>(*I);
- if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
- F->isInterposable()) {
+ if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) {
Changed |= insert(F);
}
}
@@ -1838,20 +1822,16 @@ bool MergeFunctions::insert(Function *NewFunction) {
// important when operating on more than one module independently to prevent
// cycles of thunks calling each other when the modules are linked together.
//
- // When one function is weak and the other is strong there is an order imposed
- // already. We process strong functions before weak functions.
- if ((OldF.getFunc()->isInterposable() && NewFunction->isInterposable()) ||
- (!OldF.getFunc()->isInterposable() && !NewFunction->isInterposable()))
- if (OldF.getFunc()->getName() > NewFunction->getName()) {
- // Swap the two functions.
- Function *F = OldF.getFunc();
- replaceFunctionInTree(*Result.first, NewFunction);
- NewFunction = F;
- assert(OldF.getFunc() != F && "Must have swapped the functions.");
- }
-
- // Never thunk a strong function to a weak function.
- assert(!OldF.getFunc()->isInterposable() || NewFunction->isInterposable());
+ // First of all, we process strong functions before weak functions.
+ if ((OldF.getFunc()->isInterposable() && !NewFunction->isInterposable()) ||
+ (OldF.getFunc()->isInterposable() == NewFunction->isInterposable() &&
+ OldF.getFunc()->getName() > NewFunction->getName())) {
+ // Swap the two functions.
+ Function *F = OldF.getFunc();
+ replaceFunctionInTree(*Result.first, NewFunction);
+ NewFunction = F;
+ assert(OldF.getFunc() != F && "Must have swapped the functions.");
+ }
DEBUG(dbgs() << " " << OldF.getFunc()->getName()
<< " == " << NewFunction->getName() << '\n');