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