Marc via llvm-dev
2021-Feb-24 16:46 UTC
[llvm-dev] LTO early plugin is too late - or how to disable dead code optimization?
I am writing an LTO plugin path that should be run before optimization, however before my pass is running functions have already been removed. Simple example below. b.c contains foo(), bar() and foobar(). a.c contains the main and runs either foo() or bar() but not foobar(). The bitcode file that ld.lld receives still contains the empty foobar() function. I try to prevent any kind of optimization - but still the foobar() function is already eliminated before the plugin is running. How can I prevent the elimination of dead code? I already use -O0 -fno-inline -fno-inline-functions -Wl,--discard-none -Wl,--lto-O0 -femit-all-decls -fno-virtual-function-elimination -Wl,--no-gc-sections Thank you! # cat a.c #include <stdio.h> int main(int argc, char **argv) { if (argc == 2) foo(); else bar(); return 0; } # cat b.c void foo() {} void bar() {} void foobar() {} # cat f.cpp #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Pass.h" using namespace llvm; namespace { class Unreachable : public ModulePass { public: static char ID; Unreachable() : ModulePass(ID) {} bool runOnModule(Module &M) override; }; } char Unreachable::ID = 0; bool Unreachable::runOnModule(Module &M) { errs() << "Running plugin ...\n"; for (auto &F : M) errs() << F.getName() << "\n"; return true; } static void registerUnreachablePass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { auto p = new Unreachable(); PM.add(p); } static RegisterStandardPasses RegisterUnreachablePassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationEarly, registerUnreachablePass); # export CFLAGS="-O0 -g -flto=full" # clang $CFLAGS -c a.c # clang $CFLAGS -c b.c # clang++ `llvm-config --cxxflags` -fno-rtti -fPIC -std=c++14 -o f.so -shared f.cpp # clang -fno-inline -fno-inline-functions -Wl,--discard-none -Wl,--lto-O0 -femit-all-decls -fno-virtual-function-elimination -Wl,--no-gc-sections -fuse-ld=/usr/bin/ld.lld $CFLAGS -fno-experimental-new-pass-manager -Wl,-mllvm=-load=./f.so -o ab a.o b.o Running plugin ... main llvm.dbg.declare foo bar #^^^the foobar function is gone :-( Regards, Marc -- Marc Heuse www.mh-sec.de PGP: AF3D 1D4C D810 F0BB 977D 3807 C7EE D0A0 6BE9 F573
Teresa Johnson via llvm-dev
2021-Feb-24 17:29 UTC
[llvm-dev] LTO early plugin is too late - or how to disable dead code optimization?
LTO itself has global dead code elimination. Try disabling with an internal option: -Wl,-mllvm,-compute-dead=false. Teresa On Wed, Feb 24, 2021 at 8:46 AM Marc via llvm-dev <llvm-dev at lists.llvm.org> wrote:> I am writing an LTO plugin path that should be run before optimization, > however before my pass is running functions have already been removed. > > Simple example below. > b.c contains foo(), bar() and foobar(). a.c contains the main and runs > either foo() or bar() but not foobar(). > > The bitcode file that ld.lld receives still contains the empty foobar() > function. I try to prevent any kind of optimization - but still the > foobar() function is already eliminated before the plugin is running. > > How can I prevent the elimination of dead code? > I already use -O0 -fno-inline -fno-inline-functions -Wl,--discard-none > -Wl,--lto-O0 -femit-all-decls -fno-virtual-function-elimination > -Wl,--no-gc-sections > Thank you! > > # cat a.c > #include <stdio.h> > int main(int argc, char **argv) { > if (argc == 2) > foo(); > else > bar(); > return 0; > } > > # cat b.c > void foo() {} > void bar() {} > void foobar() {} > > # cat f.cpp > #include "llvm/Support/Debug.h" > #include "llvm/Support/raw_ostream.h" > #include "llvm/IR/LegacyPassManager.h" > #include "llvm/IR/Module.h" > #include "llvm/Transforms/IPO/PassManagerBuilder.h" > #include "llvm/Pass.h" > using namespace llvm; > namespace { > class Unreachable : public ModulePass { > public: > static char ID; > Unreachable() : ModulePass(ID) {} > bool runOnModule(Module &M) override; > }; > } > char Unreachable::ID = 0; > bool Unreachable::runOnModule(Module &M) { > errs() << "Running plugin ...\n"; > for (auto &F : M) > errs() << F.getName() << "\n"; > return true; > } > static void registerUnreachablePass(const PassManagerBuilder &, > legacy::PassManagerBase &PM) { > auto p = new Unreachable(); > PM.add(p); > } > static RegisterStandardPasses RegisterUnreachablePassLTO( > PassManagerBuilder::EP_FullLinkTimeOptimizationEarly, > registerUnreachablePass); > > # export CFLAGS="-O0 -g -flto=full" > # clang $CFLAGS -c a.c > # clang $CFLAGS -c b.c > # clang++ `llvm-config --cxxflags` -fno-rtti -fPIC -std=c++14 -o f.so > -shared f.cpp > > # clang -fno-inline -fno-inline-functions -Wl,--discard-none > -Wl,--lto-O0 -femit-all-decls -fno-virtual-function-elimination > -Wl,--no-gc-sections -fuse-ld=/usr/bin/ld.lld $CFLAGS > -fno-experimental-new-pass-manager -Wl,-mllvm=-load=./f.so -o ab a.o b.o > > Running plugin ... > main > llvm.dbg.declare > foo > bar > > #^^^the foobar function is gone :-( > > Regards, > Marc > > -- > Marc Heuse > www.mh-sec.de > > PGP: AF3D 1D4C D810 F0BB 977D 3807 C7EE D0A0 6BE9 F573 > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-- Teresa Johnson | Software Engineer | tejohnson at google.com | -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210224/bb7a394b/attachment.html>