Skip to content
Merged
16 changes: 8 additions & 8 deletions llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@
using namespace llvm;

static bool finalizeLinkage(Module &M) {
SmallPtrSet<Function *, 8> EntriesAndExports;
SmallPtrSet<Function *, 8> Funcs;

// Find all entry points and export functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment may be better updated to something like:
Collect all non-entry point and non-exported functions to possibly set to internal linkage later.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

for (Function &EF : M.functions()) {
if (!EF.hasFnAttribute("hlsl.shader") && !EF.hasFnAttribute("hlsl.export"))
if (EF.hasFnAttribute("hlsl.shader") || EF.hasFnAttribute("hlsl.export"))
continue;
EntriesAndExports.insert(&EF);
Funcs.insert(&EF);
}

for (Function &F : M.functions()) {
if (F.getLinkage() == GlobalValue::ExternalLinkage &&
!EntriesAndExports.contains(&F)) {
F.setLinkage(GlobalValue::InternalLinkage);
}
for (Function *F : Funcs) {
if (F->getLinkage() == GlobalValue::ExternalLinkage)
F->setLinkage(GlobalValue::InternalLinkage);
if (F->hasFnAttribute(Attribute::AlwaysInline) && F->isDefTriviallyDead())
M.getFunctionList().erase(F);
}

return false;
Expand Down
80 changes: 80 additions & 0 deletions llvm/test/CodeGen/DirectX/finalize-linkage-remove-dead.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
; RUN: opt -S -dxil-finalize-linkage -mtriple=dxil-unknown-shadermodel6.5-compute %s | FileCheck %s
; RUN: llc %s --filetype=asm -o - | FileCheck %s

target triple = "dxilv1.5-pc-shadermodel6.5-compute"

; Confirm that DXILFinalizeLinkage will remove functions that have compatible
; linkage and are not called from anywhere. This should be any function that
; is not explicitly marked noinline or export and is not an entry point.

; Not called nor marked with any linking or inlining attributes.
; CHECK-NOT: define {{.*}}doNothingNothing
define void @"?doNothingNothing@@YAXXZ"() #0 {
entry:
ret void
}

; Marked internal, this should be removed.
; CHECK-NOT: define {{.*}}doNothingInternally
define internal void @"?doNothingInternally@@YAXXZ"() #0 {
entry:
ret void
}

; Marked external, which should become internal and be removed.
; CHECK-NOT: define {{.*}}doNothingExternally
define external void @"?doNothingExternally@@YAXXZ"() #0 {
entry:
ret void
}

; Not called nor marked with any linking or inlining attributes.
; CHECK: define internal void @"?doSomethingSomething@@YAXXZ"() #0
define void @"?doSomethingSomething@@YAXXZ"() #0 {
entry:
ret void
}

; Marked internal, this should be removed.
; CHECK: define internal void @"?doSomethingInternally@@YAXXZ"() #0
define internal void @"?doSomethingInternally@@YAXXZ"() #0 {
entry:
ret void
}

; Marked external, which should become internal and be removed.
; CHECK: define internal void @"?doSomethingExternally@@YAXXZ"() #0
define external void @"?doSomethingExternally@@YAXXZ"() #0 {
entry:
ret void
}

; Lacks alwaysinline attribute. Should remain.
; CHECK: define internal void @"?doNothingDefault@@YAXXZ"() #1
define void @"?doNothingDefault@@YAXXZ"() #1 {
entry:
ret void
}

; Has noinline attribute. Should remain.
; CHECK: define {{.*}}doNothingNoinline
define void @"?doNothingNoinline@@YAXXZ"() #2 {
entry:
ret void
}

; Entry point function should stay.
; CHECK: define void @main() #3
define void @main() #3 {
entry:
call void @"?doSomethingSomething@@YAXXZ"() #4
call void @"?doSomethingInternally@@YAXXZ"() #4
call void @"?doSomethingExternally@@YAXXZ"() #4
ret void
}

attributes #0 = { alwaysinline convergent norecurse nounwind }
attributes #1 = { convergent norecurse nounwind }
attributes #2 = { convergent noinline norecurse nounwind }
attributes #3 = { convergent noinline norecurse "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
attributes #4 = { convergent }