about summary refs log tree commit diff homepage
path: root/lib/Module
diff options
context:
space:
mode:
authorMartin Nowack <m.nowack@imperial.ac.uk>2018-07-29 15:56:54 +0100
committerCristian Cadar <c.cadar@imperial.ac.uk>2018-10-24 14:15:25 +0300
commitcdff297692a1edbf9159d1c998648c6e609025ef (patch)
treeca4e5abc6408f65f51fb181cdaac33b61d3b27f3 /lib/Module
parent56e4c597a8d7e641604aea1ecfff4600fbf8dea9 (diff)
downloadklee-cdff297692a1edbf9159d1c998648c6e609025ef.tar.gz
Use llvm::Builder for DivCheck instrumentation
Use llvm::Builder instead of raw `*Inst::create()` functions.
Builder automatically manages metadata (e.g. debug, TBAA, ..) such that
we don't have to take care of this automatically.

Updated code to C++11 and clang-formated it.
Diffstat (limited to 'lib/Module')
-rw-r--r--lib/Module/Checks.cpp80
1 files changed, 38 insertions, 42 deletions
diff --git a/lib/Module/Checks.cpp b/lib/Module/Checks.cpp
index aac63e1d..a9ef0dd4 100644
--- a/lib/Module/Checks.cpp
+++ b/lib/Module/Checks.cpp
@@ -12,16 +12,17 @@
 #include "klee/Config/Version.h"
 
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Module.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
-#include "llvm/IR/DataLayout.h"
 #include "llvm/Pass.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -31,50 +32,45 @@ using namespace klee;
 
 char DivCheckPass::ID;
 
-bool DivCheckPass::runOnModule(Module &M) { 
-  Function *divZeroCheckFunction = 0;
-  LLVMContext &ctx = M.getContext();
-
-  bool moduleChanged = false;
-  
-  for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) {
-    for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) {
-      for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) {     
-          if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) {
-          // find all [s|u][div|mod] instructions
-          Instruction::BinaryOps opcode = binOp->getOpcode();
-          if (opcode == Instruction::SDiv || opcode == Instruction::UDiv ||
-              opcode == Instruction::SRem || opcode == Instruction::URem) {
-            
-            CastInst *denominator =
-              CastInst::CreateIntegerCast(i->getOperand(1),
-                                          Type::getInt64Ty(ctx),
-                                          false,  /* sign doesn't matter */
-                                          "int_cast_to_i64",
-                                          &*i);
-            
-            // Lazily bind the function to avoid always importing it.
-            if (!divZeroCheckFunction) {
-              Constant *fc = M.getOrInsertFunction("klee_div_zero_check", 
-                                                   Type::getVoidTy(ctx),
-                                                   Type::getInt64Ty(ctx),
-                                                   NULL);
-              divZeroCheckFunction = cast<Function>(fc);
-            }
-
-            CallInst * ci = CallInst::Create(divZeroCheckFunction, denominator, "", &*i);
-
-            // Set debug location of checking call to that of the div/rem
-            // operation so error locations are reported in the correct
-            // location.
-            ci->setDebugLoc(binOp->getDebugLoc());
-            moduleChanged = true;
-          }
+bool DivCheckPass::runOnModule(Module &M) {
+  std::vector<llvm::BinaryOperator *> divInstruction;
+
+  for (auto &F : M) {
+    for (auto &BB : F) {
+      for (auto &I : BB) {
+        auto binOp = dyn_cast<BinaryOperator>(&I);
+        if (!binOp)
+          continue;
+
+        // find all [s|u][div|rem] instructions
+        auto opcode = binOp->getOpcode();
+        if (opcode != Instruction::SDiv && opcode != Instruction::UDiv &&
+            opcode != Instruction::SRem && opcode != Instruction::URem)
+          continue;
         }
       }
     }
   }
-  return moduleChanged;
+
+  // If nothing to do, return
+  if (divInstruction.empty())
+    return false;
+
+  LLVMContext &ctx = M.getContext();
+  auto divZeroCheckFunction = cast<Function>(
+      M.getOrInsertFunction("klee_div_zero_check", Type::getVoidTy(ctx),
+                            Type::getInt64Ty(ctx), NULL));
+
+  for (auto &divInst : divInstruction) {
+    llvm::IRBuilder<> Builder(divInst /* Inserts before divInst*/);
+    auto denominator =
+        Builder.CreateIntCast(divInst->getOperand(1), Type::getInt64Ty(ctx),
+                              false, /* sign doesn't matter */
+                              "int_cast_to_i64");
+    Builder.CreateCall(divZeroCheckFunction, denominator);
+  }
+
+  return true;
 }
 
 char OvershiftCheckPass::ID;