1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 20:23:11 +01:00
llvm-mirror/test/Transforms/MergeFunc/external-before-local.ll
whitequark 11cd8b2ab1 [MergeFuncs] Improve ordering of equal functions
Summary:
MergeFunctions currently tries to process strong functions before
weak functions, because weak functions can simply call strong
functions, while a strong/weak function cannot call a weak function
(a backing strong function is needed).

This patch additionally tries to process external functions before
local functions, because we definitely have to keep the external
function, but may be able to drop the local one (and definitely
can if it is also unnamed_addr).

Unfortunately, this exposes an existing bug in the implementation:
The FnTree and FNodesInTree structures can currently go out of
sync in the case where two weak functions are merged, because the
function in FnTree/FNodesInTree is RAUWed. This leaves it behind in
FnTree (this is intended, as it is the strong backing function which
should be used for further merges), while it is replaced in
FNodesInTree (this is not intended).

This is fixed by switching FNodesInTree from using a ValueMap to
using a DenseMap of AssertingVH.

This exposes another minor issue: Currently FNodesInTree is not
cleared after MergeFunctions finishes running. Currently, this is
potentially dangerous (e.g. if something else wants to RAUW a function
with a non-function), but at the very least it is unnecessary/inefficient.
After the change to use AssertingVH it becomes more problematic,
because there are certainly passes that remove functions.

This issue is fixed by clearing FNodesInTree at the end of the pass.

Reviewers: jfb, whitequark

Reviewed By: whitequark

Subscribers: rkruppe, llvm-commits

Differential Revision: https://reviews.llvm.org/D53271

llvm-svn: 346386
2018-11-08 03:58:01 +00:00

56 lines
1.2 KiB
LLVM

; RUN: opt -S -mergefunc < %s | FileCheck %s
; We should normalize to test2 rather than test1,
; because it allows us to drop test1 entirely
; CHECK-NOT: define internal void @test1() unnamed_addr
; CHECK: define void @test3() unnamed_addr
; CHECK-NEXT: call void @test2()
; CHECK-NEXT: call void @test2()
declare void @dummy()
define internal void @test1() unnamed_addr {
call void @dummy()
call void @dummy()
ret void
}
define void @test2() unnamed_addr {
call void @dummy()
call void @dummy()
ret void
}
define void @test3() unnamed_addr {
call void @test1()
call void @test2()
ret void
}
; We should normalize to the existing test6 rather than
; to a new anonymous strong backing function
; CHECK: define weak void @test5()
; CHECK-NEXT: tail call void @test6()
; CHECK: define weak void @test4()
; CHECK-NEXT: tail call void @test6()
declare void @dummy2()
define weak void @test4() {
call void @dummy2()
call void @dummy2()
ret void
}
define weak void @test5() {
call void @dummy2()
call void @dummy2()
ret void
}
define void @test6() {
call void @dummy2()
call void @dummy2()
ret void
}