about summary refs log tree commit diff homepage
path: root/lib/Module/OptNone.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Module/OptNone.cpp')
-rw-r--r--lib/Module/OptNone.cpp59
1 files changed, 59 insertions, 0 deletions
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<llvm::Function *,16> 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<llvm::CallInst>(U) && !llvm::isa<llvm::InvokeInst>(U))
+        continue;
+      auto *Inst = llvm::cast<llvm::Instruction>(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<llvm::Instruction>(*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