blob: daae80431dfa27ecfbac35a37f1a21f5988ef8b5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
//===-- InstrumentLegacy.cpp ------------------------------------*- C++ -*-===//
//
// The KLEE Symbolic Virtual Machine
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "ModuleHelper.h"
#include "Passes.h"
#include "klee/Support/CompilerWarning.h"
#include "klee/Support/ErrorHandling.h"
DISABLE_WARNING_PUSH
DISABLE_WARNING_DEPRECATED_DECLARATIONS
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/Scalarizer.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/Cloning.h"
DISABLE_WARNING_POP
using namespace llvm;
using namespace klee;
void klee::instrument(bool CheckDivZero, bool CheckOvershift,
llvm::Module *module) {
// Inject checks prior to optimization... we also perform the
// invariant transformations that we will end up doing later so that
// optimize is seeing what is as close as possible to the final
// module.
legacy::PassManager pm;
pm.add(new RaiseAsmPass());
// This pass will scalarize as much code as possible so that the Executor
// does not need to handle operands of vector type for most instructions
// other than InsertElementInst and ExtractElementInst.
//
// NOTE: Must come before division/overshift checks because those passes
// don't know how to handle vector instructions.
pm.add(createScalarizerPass());
// This pass will replace atomic instructions with non-atomic operations
pm.add(createLowerAtomicPass());
if (CheckDivZero)
pm.add(new DivCheckPass());
if (CheckOvershift)
pm.add(new OvershiftCheckPass());
llvm::DataLayout targetData(module);
pm.add(new IntrinsicCleanerPass(targetData));
pm.run(*module);
}
void klee::checkModule(bool DontVerify, llvm::Module *module) {
InstructionOperandTypeCheckPass *operandTypeCheckPass =
new InstructionOperandTypeCheckPass();
legacy::PassManager pm;
if (!DontVerify)
pm.add(createVerifierPass());
pm.add(operandTypeCheckPass);
pm.run(*module);
// Enforce the operand type invariants that the Executor expects. This
// implicitly depends on the "Scalarizer" pass to be run in order to succeed
// in the presence of vector instructions.
if (!operandTypeCheckPass->checkPassed()) {
klee_error("Unexpected instruction operand types detected");
}
}
void klee::optimiseAndPrepare(bool OptimiseKLEECall, bool Optimize,
SwitchImplType SwitchType, std::string EntryPoint,
llvm::ArrayRef<const char *> preservedFunctions,
llvm::Module *module) {
// Preserve all functions containing klee-related function calls from being
// optimised around
if (!OptimiseKLEECall) {
legacy::PassManager pm;
pm.add(new OptNonePass());
pm.run(*module);
}
if (Optimize)
optimizeModule(module, preservedFunctions);
// Needs to happen after linking (since ctors/dtors can be modified)
// and optimization (since global optimization can rewrite lists).
injectStaticConstructorsAndDestructors(module, EntryPoint);
// Finally, run the passes that maintain invariants we expect during
// interpretation. We run the intrinsic cleaner just in case we
// linked in something with intrinsics but any external calls are
// going to be unresolved. We really need to handle the intrinsics
// directly I think?
legacy::PassManager pm3;
pm3.add(createCFGSimplificationPass());
switch (SwitchType) {
case SwitchImplType::eSwitchTypeInternal:
break;
case SwitchImplType::eSwitchTypeSimple:
pm3.add(new LowerSwitchPass());
break;
case SwitchImplType::eSwitchTypeLLVM:
pm3.add(createLowerSwitchPass());
break;
}
llvm::DataLayout targetData(module);
pm3.add(new IntrinsicCleanerPass(targetData));
pm3.add(createScalarizerPass());
pm3.add(new PhiCleanerPass());
pm3.add(new FunctionAliasPass());
pm3.run(*module);
}
|