This is an archive of the discontinued LLVM Phabricator instance.

[FuncSpec] Remove definitions of fully specialized functions.
ClosedPublic

Authored by labrinea on Feb 15 2022, 12:03 PM.

Details

Summary

A function is basically dead when:

  • it has no uses
  • it has only self-referencing uses (it's recursive)

Diff Detail

Event Timeline

labrinea created this revision.Feb 15 2022, 12:03 PM
labrinea requested review of this revision.Feb 15 2022, 12:03 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 15 2022, 12:03 PM
ChuanqiXu added inline comments.Feb 15 2022, 7:16 PM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
526–528

It surprised me that the unreachable function wouldn't be removed. Have you tested to run opt -O3 for the tests? I think they might be removed in later passes.

labrinea added inline comments.Feb 16 2022, 2:57 AM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
526–528

Yes, later passes will remove these dead functions. The benefit of removing them now is that the later passes won't have to discover them all over again.

ChuanqiXu accepted this revision.Feb 16 2022, 2:59 AM
ChuanqiXu added inline comments.
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
526–528

OK, I agree it is not bad to delete it now since the cost looks cheap.

This revision is now accepted and ready to land.Feb 16 2022, 2:59 AM
nikic added a subscriber: nikic.Feb 16 2022, 3:11 AM
nikic added inline comments.
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
522

or_null is unnecessary here, user cannot be null.

labrinea added inline comments.Feb 16 2022, 9:45 AM
llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
522

thanks, will update it accordingly

This patch makes clang crash when compiling ClamAV from the llvm-test-suite:

0.	Program arguments: /data/oss-llvm/debug_build/bin/clang -DNDEBUG -O3 -w -Werror=date-time -DHAVE_CONFIG_H -I/data/oss-llvm/llvm-project/test-suite/CTMark/ClamAV -I/data/oss-llvm/llvm-project/test-suite/CTMark/ClamAV/zlib -DDONT_LOCK_DBDIRS -DC_LINUX -DFPU_WORDS_BIGENDIAN=0 -DWORDS_BIGENDIAN=0 -MD -MT CTMark/ClamAV/CMakeFiles/clamscan.dir/libclamav_message.c.o -MF CTMark/ClamAV/CMakeFiles/clamscan.dir/libclamav_message.c.o.d -o CTMark/ClamAV/CMakeFiles/clamscan.dir/libclamav_message.c.o -c /data/oss-llvm/llvm-project/test-suite/CTMark/ClamAV/libclamav_message.c
1.	<eof> parser at end of file
2.	Optimizer
 #0 0x0000000005860211 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /data/oss-llvm/llvm-project/llvm/lib/Support/Unix/Signals.inc:565:22
 #1 0x00000000058602c8 PrintStackTraceSignalHandler(void*) /data/oss-llvm/llvm-project/llvm/lib/Support/Unix/Signals.inc:632:1
 #2 0x000000000585e284 llvm::sys::RunSignalHandlers() /data/oss-llvm/llvm-project/llvm/lib/Support/Signals.cpp:97:20
 #3 0x000000000585fb70 llvm::sys::CleanupOnSignal(unsigned long) /data/oss-llvm/llvm-project/llvm/lib/Support/Unix/Signals.inc:361:31
 #4 0x00000000057894d6 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) /data/oss-llvm/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:79:5
 #5 0x0000000005789982 CrashRecoverySignalHandler(int) /data/oss-llvm/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:393:1
 #6 0x00007f3c4d908390 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11390)
 #7 0x00000000025ba226 llvm::PointerIntPair<llvm::ilist_node_base<true>*, 1u, unsigned int, llvm::PointerLikeTypeTraits<llvm::ilist_node_base<true>*>, llvm::PointerIntPairInfo<llvm::ilist_node_base<true>*, 1u, llvm::PointerLikeTypeTraits<llvm::ilist_node_base<true>*> > >::setPointer(llvm::ilist_node_base<true>*) & /data/oss-llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:65:32
 #8 0x00000000025b8def llvm::ilist_node_base<true>::setPrev(llvm::ilist_node_base<true>*) /data/oss-llvm/llvm-project/llvm/include/llvm/ADT/ilist_node_base.h:40:75
 #9 0x00000000025bf15d llvm::ilist_base<true>::removeImpl(llvm::ilist_node_base<true>&) /data/oss-llvm/llvm-project/llvm/include/llvm/ADT/ilist_base.h:34:5
#10 0x000000000417ceb3 void llvm::ilist_base<true>::remove<llvm::ilist_node_impl<llvm::ilist_detail::node_options<llvm::Function, true, false, void> > >(llvm::ilist_node_impl<llvm::ilist_detail::node_options<llvm::Function, true, false, void> >&) /data/oss-llvm/llvm-project/llvm/include/llvm/ADT/ilist_base.h:80:64
#11 0x000000000417c86c llvm::simple_ilist<llvm::Function>::remove(llvm::Function&) /data/oss-llvm/llvm-project/llvm/include/llvm/ADT/simple_ilist.h:183:77
#12 0x000000000417bc37 llvm::iplist_impl<llvm::simple_ilist<llvm::Function>, llvm::SymbolTableListTraits<llvm::Function> >::remove(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Function, true, false, void>, false, false>&) /data/oss-llvm/llvm-project/llvm/include/llvm/ADT/ilist.h:256:12
#13 0x0000000004c672a1 llvm::iplist_impl<llvm::simple_ilist<llvm::Function>, llvm::SymbolTableListTraits<llvm::Function> >::erase(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Function, true, false, void>, false, false>) /data/oss-llvm/llvm-project/llvm/include/llvm/ADT/ilist.h:269:5
#14 0x0000000004c4c6db llvm::Function::eraseFromParent() /data/oss-llvm/llvm-project/llvm/lib/IR/Function.cpp:366:1
#15 0x0000000004ffcd0b (anonymous namespace)::FunctionSpecializer::removeDeadFunctions() /data/oss-llvm/llvm-project/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp:336:5
#16 0x0000000004fffe5a llvm::runFunctionSpecialization(llvm::Module&, llvm::DataLayout const&, std::function<llvm::TargetLibraryInfo& (llvm::Function&)>, std::function<llvm::TargetTransformInfo& (llvm::Function&)>, std::function<llvm::AssumptionCache& (llvm::Function&)>, llvm::function_ref<llvm::AnalysisResultsForFn (llvm::Function&)>) /data/oss-llvm/llvm-project/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp:941:16
#17 0x0000000004fbf1a8 llvm::FunctionSpecializationPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) /data/oss-llvm/llvm-project/llvm/lib/Transforms/IPO/SCCP.cpp:128:33
labrinea updated this revision to Diff 409392.Feb 16 2022, 1:40 PM
  • Fixed a segfault which would happen if you tried to erase a function twice (replaced SmallVector with SmallPtrSet)
  • Moved the deletion of dead instructions and functions in a destructor to make sure it's the last thing being called (though I am wondering if the Solver could still contain references to dead functions/instructions)
  • Changed the dyn_cast_or_null to dyn_cast as suggested
This revision was landed with ongoing or failed builds.Mar 1 2022, 4:12 AM
This revision was automatically updated to reflect the committed changes.