Skip to content

Commit df5b3b7

Browse files
S1eGamisonijnik
authored andcommitted
[feat] Add label-adder from testcomp24 competition. Add pass to wrap llvm.dbg.label.
[feat] Added call to label-adder instrumentation in kleef script. Removed DbgIntrinsicWrapper as all dbg intrinsics are removing in CallRemover pass. [feat] Return DbgIntrinsicWrapper pass. Added DbgIntrinsicUnwrapper pass. [fix] label-adder did not choose correct location for end of if-statement. [fix] Added main for testcov, moved temporary files during instrumentation in /tmp. chore: Enable the all optimizations [feat] Add label-adder from testcomp24 competition. Add pass to wrap llvm.dbg.label. [feat] Added call to label-adder instrumentation in kleef script. Removed DbgIntrinsicWrapper as all dbg intrinsics are removing in CallRemover pass. [feat] Return DbgIntrinsicWrapper pass. Added DbgIntrinsicUnwrapper pass. [fix] label-adder did not choose correct location for end of if-statement. [fix] Added main for testcov, moved temporary files during instrumentation in /tmp. fix: Remove `llvm-14` dependency fix:
1 parent ef73a78 commit df5b3b7

45 files changed

Lines changed: 1873 additions & 53 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,19 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
197197
################################################################################
198198
include(${CMAKE_SOURCE_DIR}/cmake/compiler_warnings.cmake)
199199

200+
################################################################################
201+
# Clang
202+
################################################################################
203+
include(${LLVM_DIR}/AddLLVM.cmake)
204+
include(${LLVM_DIR}/../lib/cmake/clang/AddClang.cmake)
205+
# include(${LLVM_DIR}/../lib/cmake/clang/ClangConfig.cmake)
206+
# include(${LLVM_DIR}/../lib/cmake/clang/ClangTargets-release.cmake)
207+
# include(${LLVM_DIR}/../lib/cmake/clang/ClangTargets.cmake)
208+
209+
message("!!! ${LLVM_DIR}/../lib/cmake/clang/AddClang.cmake")
210+
# find_package(cmake_clang_tools QUIET)
211+
# message("!!! FOUND: ${cmake_clang_tools_FOUND}")
212+
200213
################################################################################
201214
# Solvers
202215
################################################################################

lib/Core/Executor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ llvm::Module *Executor::setModule(
672672
preservedFunctions.push_back("memcpy");
673673
preservedFunctions.push_back("memcmp");
674674
preservedFunctions.push_back("memmove");
675+
preservedFunctions.push_back("llvm.dbg.label");
675676

676677
if (FunctionCallReproduce != "") {
677678
preservedFunctions.push_back(FunctionCallReproduce.c_str());

lib/Module/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ set(KLEE_MODULE_COMPONENT_SRCS
1212
CallRemover.cpp
1313
Checks.cpp
1414
CodeGraphInfo.cpp
15+
DbgIntrinsicWrapperPass.cpp
16+
DbgIntrinsicUnwrapperPass.cpp
1517
FunctionAlias.cpp
1618
LocationInfo.cpp
1719
InstructionOperandTypeCheckPass.cpp

lib/Module/CallRemover.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ using namespace llvm;
1616
char CallRemover::ID;
1717

1818
bool CallRemover::runOnModule(llvm::Module &M) {
19-
std::vector<std::string> badFuncs = {"llvm.dbg.declare", "llvm.dbg.label",
20-
"llvm.dbg.value"};
19+
std::vector<std::string> badFuncs = {"llvm.dbg.declare", "llvm.dbg.value"};
2120

2221
for (const auto &f : badFuncs) {
2322
auto Declare = M.getFunction(f);
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
//===-- LocalVarDeclarationFinderPass.cpp -----------------------*- C++ -*-===//
2+
//
3+
// The KLEEF Symbolic Virtual Machine
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
#include "Passes.h"
10+
11+
#include "llvm/ADT/SmallVector.h"
12+
#include "llvm/Analysis/CallGraph.h"
13+
#include "llvm/IR/Attributes.h"
14+
#include "llvm/IR/BasicBlock.h"
15+
#include "llvm/IR/Constants.h"
16+
#include "llvm/IR/DerivedTypes.h"
17+
#include "llvm/IR/Function.h"
18+
#include "llvm/IR/IRBuilder.h"
19+
#include "llvm/IR/Instruction.h"
20+
#include "llvm/IR/IntrinsicInst.h"
21+
#include "llvm/IR/Value.h"
22+
#include "llvm/IR/Verifier.h"
23+
#include "llvm/Support/Casting.h"
24+
#include "llvm/Support/raw_ostream.h"
25+
26+
#include <optional>
27+
#include <unordered_map>
28+
29+
using namespace klee;
30+
31+
char DbgIntrinsicUnwrapperPass::ID = 0;
32+
33+
std::optional<std::pair<llvm::Instruction *, llvm::Instruction *>>
34+
DbgIntrinsicUnwrapperPass::unwrapCall(llvm::CallInst &callInst) {
35+
auto &ctx = callInst.getContext();
36+
auto &module = *callInst.getModule();
37+
38+
auto calledFunction = callInst.getCalledFunction();
39+
auto dbgLabelOptional = findDbgLabel(*calledFunction);
40+
if (!dbgLabelOptional) {
41+
return std::nullopt;
42+
}
43+
44+
auto &intrinsic = **dbgLabelOptional;
45+
46+
auto operands = intrinsic.getOperandList();
47+
auto functionCallee = module.getOrInsertFunction(
48+
intrinsic.getCalledFunction()->getName(),
49+
intrinsic.getCalledFunction()->getFunctionType());
50+
51+
llvm::IRBuilder<> builder(ctx);
52+
auto callToDbgInst = builder.CreateCall(functionCallee, operands->get());
53+
callToDbgInst->setDebugLoc(intrinsic.getDebugLoc());
54+
55+
return {{&callInst, callToDbgInst}};
56+
}
57+
58+
void DbgIntrinsicUnwrapperPass::runOnBasicBlock(llvm::BasicBlock &block) {
59+
std::unordered_map<llvm::Instruction *, llvm::Instruction *> replaces;
60+
for (auto &instruction : block) {
61+
if (auto *callInst = llvm::dyn_cast<llvm::CallInst>(&instruction)) {
62+
if (wrappers.count(callInst->getCalledFunction()) == 0) {
63+
continue;
64+
}
65+
66+
if (auto replace = unwrapCall(*callInst)) {
67+
replaces.insert(*replace);
68+
}
69+
}
70+
}
71+
72+
for (auto [callInst, intrinsic] : replaces) {
73+
auto nextInstruction = callInst->eraseFromParent();
74+
intrinsic->insertBefore(&*nextInstruction);
75+
}
76+
}
77+
78+
std::optional<llvm::DbgLabelInst *>
79+
DbgIntrinsicUnwrapperPass::findDbgLabel(llvm::Function &function) {
80+
for (auto &block : function) {
81+
for (auto &instruction : block) {
82+
if (auto *dbgLabelInstr =
83+
llvm::dyn_cast<llvm::DbgLabelInst>(&instruction)) {
84+
return dbgLabelInstr;
85+
}
86+
}
87+
}
88+
return std::nullopt;
89+
}
90+
91+
bool DbgIntrinsicUnwrapperPass::runOnModule(llvm::Module &module) {
92+
if (wrappers.empty()) {
93+
return false;
94+
}
95+
96+
for (auto &function : module) {
97+
for (auto &block : function) {
98+
runOnBasicBlock(block);
99+
}
100+
}
101+
102+
// llvm::CallGraph callGraph(module);
103+
// for (auto wrapper : wrappers) {
104+
// // wrapper->deleteBody();
105+
// callGraph.removeFunctionFromModule(callGraph.getOrInsertFunction(wrapper));
106+
// //
107+
// wrapper->replaceAllUsesWith(llvm::UndefValue::get(wrapper->getType()));
108+
// wrapper->removeFromParent();
109+
// }
110+
111+
return true;
112+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//===-- LocalVarDeclarationFinderPass.cpp -----------------------*- C++ -*-===//
2+
//
3+
// The KLEEF Symbolic Virtual Machine
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
#include "Passes.h"
10+
11+
#include "llvm/ADT/SmallVector.h"
12+
#include "llvm/IR/Attributes.h"
13+
#include "llvm/IR/BasicBlock.h"
14+
#include "llvm/IR/DerivedTypes.h"
15+
#include "llvm/IR/Function.h"
16+
#include "llvm/IR/IRBuilder.h"
17+
#include "llvm/IR/Instruction.h"
18+
#include "llvm/IR/IntrinsicInst.h"
19+
#include "llvm/IR/Value.h"
20+
#include "llvm/IR/Verifier.h"
21+
#include "llvm/Support/Casting.h"
22+
#include "llvm/Support/raw_ostream.h"
23+
#include <cassert>
24+
25+
#include <string>
26+
#include <unordered_map>
27+
28+
using namespace klee;
29+
30+
char DbgIntrinsicWrapperPass::ID = 0;
31+
32+
std::string DbgIntrinsicWrapperPass::generateNewWrapperName() {
33+
return "_dbg_intrinsic_wrapper_#" + std::to_string(wrappedCounter++);
34+
}
35+
36+
llvm::Function &
37+
DbgIntrinsicWrapperPass::wrapInFunction(llvm::DbgInfoIntrinsic &intrinsic) {
38+
std::string wrapperName = generateNewWrapperName();
39+
40+
auto &ctx = intrinsic.getContext();
41+
auto &module = *intrinsic.getModule();
42+
43+
/* Generate function */
44+
auto wrapperFunctionReturnType =
45+
llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), {}, false);
46+
auto wrapperFunction = llvm::Function::Create(wrapperFunctionReturnType,
47+
llvm::Function::InternalLinkage,
48+
wrapperName, &module);
49+
50+
wrapperFunction->addFnAttr(llvm::Attribute::OptimizeNone);
51+
wrapperFunction->addFnAttr(llvm::Attribute::NoInline);
52+
53+
/* Generate function body */
54+
auto wrapperBlock = llvm::BasicBlock::Create(ctx, "", wrapperFunction);
55+
56+
llvm::IRBuilder<> builder(ctx);
57+
builder.SetInsertPoint(wrapperBlock);
58+
59+
auto operands = intrinsic.getOperandList();
60+
auto functionCallee = module.getOrInsertFunction(
61+
intrinsic.getCalledFunction()->getName(),
62+
intrinsic.getCalledFunction()->getFunctionType());
63+
64+
auto callToDbgInst = builder.CreateCall(functionCallee, operands->get());
65+
callToDbgInst->setDebugLoc(intrinsic.getDebugLoc());
66+
67+
builder.CreateRetVoid();
68+
69+
assert(!llvm::verifyFunction(*wrapperFunction));
70+
return *wrapperFunction;
71+
}
72+
73+
bool DbgIntrinsicWrapperPass::runOnBasicBlock(llvm::BasicBlock &block) {
74+
bool isModified = false;
75+
76+
auto &module = *block.getModule();
77+
auto &ctx = block.getContext();
78+
79+
std::unordered_map<llvm::DbgLabelInst *, llvm::Function *> wrappers;
80+
81+
for (auto &instruction : block) {
82+
if (auto intrinsic =
83+
llvm::dyn_cast_or_null<llvm::DbgLabelInst>(&instruction)) {
84+
85+
isModified = true;
86+
auto &function = wrapInFunction(*intrinsic);
87+
wrappers.emplace(intrinsic, &function);
88+
addedWrappers.emplace(&function);
89+
}
90+
}
91+
92+
llvm::IRBuilder<> builder(ctx);
93+
for (auto &[intrinsic, function] : wrappers) {
94+
auto iteratorAfterIntrinsic = intrinsic->eraseFromParent();
95+
96+
auto functionCallee = module.getOrInsertFunction(function->getName(),
97+
function->getReturnType());
98+
99+
auto wrapperCall = builder.CreateCall(functionCallee);
100+
wrapperCall->insertBefore(&*iteratorAfterIntrinsic);
101+
}
102+
103+
return isModified;
104+
}
105+
106+
bool DbgIntrinsicWrapperPass::runOnModule(llvm::Module &module) {
107+
bool isModified = false;
108+
109+
for (auto &function : module) {
110+
if (addedWrappers.count(&function) != 0) {
111+
continue;
112+
}
113+
114+
for (auto &block : function) {
115+
isModified |= runOnBasicBlock(block);
116+
}
117+
}
118+
119+
return isModified;
120+
}

lib/Module/InstrumentLegacy.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "klee/Support/CompilerWarning.h"
1313
#include "klee/Support/ErrorHandling.h"
1414
#include "klee/Support/ModuleUtil.h"
15+
#include "klee/System/Time.h"
1516

1617
DISABLE_WARNING_PUSH
1718
DISABLE_WARNING_DEPRECATED_DECLARATIONS
@@ -97,6 +98,20 @@ void klee::optimiseAndPrepare(bool OptimiseKLEECall, bool Optimize,
9798
llvm::Module *module) {
9899
// Preserve all functions containing klee-related function calls from being
99100
// optimised around
101+
102+
auto start = klee::time::getWallTime();
103+
std::unordered_set<llvm::Function *> addedWrappers;
104+
/* TODO: */ {
105+
legacy::PassManager pm;
106+
auto dbgIntrinsincWrapperPass = new DbgIntrinsicWrapperPass();
107+
pm.add(dbgIntrinsincWrapperPass);
108+
pm.run(*module);
109+
addedWrappers = std::move(dbgIntrinsincWrapperPass->addedWrappers);
110+
}
111+
112+
auto end = klee::time::getWallTime();
113+
klee_message("Instrumentation elapsed: %lu", (end - start).toMicroseconds());
114+
100115
if (!OptimiseKLEECall) {
101116
legacy::PassManager pm;
102117
pm.add(new OptNonePass());
@@ -158,4 +173,10 @@ void klee::optimiseAndPrepare(bool OptimiseKLEECall, bool Optimize,
158173

159174
pm3.add(new FreezeLower());
160175
pm3.run(*module);
176+
177+
{
178+
llvm::legacy::PassManager pm;
179+
pm.add(new DbgIntrinsicUnwrapperPass(std::move(addedWrappers)));
180+
pm.run(*module);
181+
}
161182
}

lib/Module/KModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
//
88
//===----------------------------------------------------------------------===//
99

10+
#include "llvm/IR/Attributes.h"
11+
#include "llvm/Transforms/IPO.h"
12+
#include <klee/System/Time.h>
1013
#define DEBUG_TYPE "KModule"
1114

1215
#include "klee/Module/KModule.h"

lib/Module/OptimizeLegacy.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,6 @@ static cl::opt<bool>
7474
static cl::alias A1("S", cl::desc("Alias for --strip-debug"),
7575
cl::aliasopt(StripDebug));
7676

77-
static cl::opt<bool> DeleteDeadLoops("delete-dead-loops",
78-
cl::desc("Use LoopDeletionPass"),
79-
cl::init(true), cl::cat(klee::ModuleCat));
80-
81-
static cl::opt<bool>
82-
OptimizeAggressive("optimize-aggressive",
83-
cl::desc("Use aggressive optimization passes"),
84-
cl::init(true), cl::cat(klee::ModuleCat));
85-
8677
// A utility function that adds a pass to the pass manager but will also add
8778
// a verifier pass after if we're supposed to verify.
8879
static inline void addPass(legacy::PassManager &PM, Pass *P) {
@@ -140,9 +131,8 @@ static void AddStandardCompilePasses(legacy::PassManager &PM) {
140131
#endif
141132
// FIXME : Removing instcombine causes nestedloop regression.
142133
addPass(PM, createInstructionCombiningPass());
143-
addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars
144-
if (DeleteDeadLoops)
145-
addPass(PM, createLoopDeletionPass()); // Delete dead loops
134+
addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars
135+
addPass(PM, createLoopDeletionPass()); // Delete dead loops
146136
addPass(PM, createLoopUnrollPass()); // Unroll small loops
147137
addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller
148138
addPass(PM, createGVNPass()); // Remove redundancies
@@ -269,9 +259,7 @@ void klee::optimizeModule(llvm::Module *M,
269259
addPass(Passes, pass);
270260
}
271261

272-
if (OptimizeAggressive) {
273-
AddNonStandardCompilePasses(Passes);
274-
}
262+
AddNonStandardCompilePasses(Passes);
275263

276264
// Run our queue of passes all at once now, efficiently.
277265
Passes.run(*M);

0 commit comments

Comments
 (0)