-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstrcmp.cpp
118 lines (106 loc) · 3.44 KB
/
strcmp.cpp
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
// SPDX-License-Identifier: MIT License
// Copyright (c) 2024 Yingwei Zheng
// This file is licensed under the MIT License.
// See the LICENSE file for more information.
#include <llvm/ADT/DenseMap.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/InstVisitor.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/Intrinsics.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Operator.h>
#include <llvm/IR/Type.h>
#include <llvm/IR/Value.h>
#include <llvm/IR/Verifier.h>
#include <llvm/IRPrinter/IRPrintingPasses.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Error.h>
#include <llvm/Support/ErrorHandling.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/FormattedStream.h>
#include <llvm/Support/InitLLVM.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/ToolOutputFile.h>
#include <llvm/Support/raw_ostream.h>
#include <cstdint>
#include <cstdlib>
#include <filesystem>
#include <map>
#include <memory>
#include <unordered_map>
using namespace llvm;
namespace fs = std::filesystem;
static cl::opt<std::string>
InputDir(cl::Positional, cl::desc("<directory for input LLVM IR files>"),
cl::Required, cl::value_desc("inputdir"));
int main(int argc, char **argv) {
InitLLVM Init{argc, argv};
cl::ParseCommandLineOptions(argc, argv, "scanner\n");
std::vector<fs::path> InputFiles;
for (auto &Entry : fs::recursive_directory_iterator(std::string(InputDir))) {
if (Entry.is_regular_file()) {
auto &Path = Entry.path();
if (Path.extension() == ".ll" &&
Path.string().find("optimized") != std::string::npos)
InputFiles.push_back(Path);
}
}
errs() << "Input files: " << InputFiles.size() << '\n';
LLVMContext Context;
std::map<uint32_t, uint32_t> LenDist;
uint32_t Count = 0;
for (auto &Path : InputFiles) {
SMDiagnostic Err;
auto M = parseIRFile(Path.string(), Err, Context);
if (!M)
continue;
for (auto &F : *M) {
if (F.empty())
continue;
auto Handle = [&](Value *V) {
if (auto *Global = dyn_cast<GlobalVariable>(V)) {
if (!Global->hasInitializer())
return;
if (!Global->isConstant())
return;
auto *Initializer = Global->getInitializer();
if (auto *Arr = dyn_cast<ConstantDataArray>(Initializer)) {
if (Arr->getType()->getArrayElementType()->isIntegerTy(8))
LenDist[Arr->getType()->getArrayNumElements()]++;
}
}
};
for (auto &BB : F) {
for (auto &I : BB) {
if (auto *Call = dyn_cast<CallInst>(&I)) {
auto *Callee = Call->getCalledFunction();
if (!Callee)
continue;
auto FuncName = Callee->getName();
if (FuncName == "strcmp" || FuncName == "strncmp") {
auto *Op1 = Call->getArgOperand(0);
auto *Op2 = Call->getArgOperand(1);
Handle(Op1);
Handle(Op2);
}
}
}
}
}
errs() << "\rProgress: " << ++Count;
}
errs() << '\n';
for (auto [K, V] : LenDist)
errs() << K << ' ' << V << '\n';
return EXIT_SUCCESS;
}