From 842966d5f2921e807ddc348505ee710eba3ad86d Mon Sep 17 00:00:00 2001 From: Martin Nowack Date: Sat, 16 Mar 2019 23:27:20 +0000 Subject: Disable optimisation for functions that contain KLEE calls Compilers are allowed to hoist function calls and do GVE. This is currently done even without `--optimization` enabled. This is unfortunate in the context of KLEE function calls that might depend on specific code position without direct control flow dependencies. In such cases, function calls can be hoisted. To circumvent this, disallow to optimise functions that contain such calls by default. This might reduce optimisation for some functions containing such function calls but still allows it for all others. This patch adds an additional pass, that detects all functions starting with a prefix `klee_` and disable optimisations for functions containing such calls. This is enabled by default but can be disabled by `--klee-call-optimisation=false`. --- lib/Module/OptNone.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 lib/Module/OptNone.cpp (limited to 'lib/Module/OptNone.cpp') diff --git a/lib/Module/OptNone.cpp b/lib/Module/OptNone.cpp new file mode 100644 index 00000000..08837488 --- /dev/null +++ b/lib/Module/OptNone.cpp @@ -0,0 +1,59 @@ +//===-- OptNone.cpp -------------------------------------------------------===// +// +// The KLEE Symbolic Virtual Machine +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Passes.h" + +#include "klee/Config/Version.h" + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Module.h" + +namespace klee { + +char OptNonePass::ID; + +bool OptNonePass::runOnModule(llvm::Module &M) { + // Find list of functions that start with `klee_` + // and mark all functions that contain such call or invoke as optnone + llvm::SmallPtrSet CallingFunctions; + for (auto &F : M) { + if (!F.hasName() || !F.getName().startswith("klee_")) + continue; +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) + for (auto *U : F.users()) { + // skip non-calls and non-invokes + if (!llvm::isa(U) && !llvm::isa(U)) + continue; + auto *Inst = llvm::cast(U); + CallingFunctions.insert(Inst->getParent()->getParent()); + } +#else + for (auto i = F.use_begin(), e = F.use_end(); i != e; ++i) { + if (auto Inst = llvm::dyn_cast(*i)) { + CallingFunctions.insert(Inst->getParent()->getParent()); + } + } +#endif + } + + bool changed = false; + for (auto F : CallingFunctions) { + // Skip if already annotated + if (F->hasFnAttribute(llvm::Attribute::OptimizeNone)) + continue; + F->addFnAttr(llvm::Attribute::OptimizeNone); + F->addFnAttr(llvm::Attribute::NoInline); + changed = true; + } + + return changed; +} +} // namespace klee -- cgit 1.4.1