[llvm-dev] LTO early plugin is too late - or how to disable dead code optimization?

Marc via llvm-dev llvm-dev at lists.llvm.org
Wed Feb 24 08:46:12 PST 2021


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


More information about the llvm-dev mailing list