-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFindStructElements.cc
More file actions
101 lines (81 loc) · 2.92 KB
/
FindStructElements.cc
File metadata and controls
101 lines (81 loc) · 2.92 KB
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
#define DEBUG_TYPE "find-struct-elements"
#include "FindStructElements.hh"
#include "NameCompare.hh"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <llvm/IR/InstVisitor.h>
#pragma GCC diagnostic pop
#include <fstream>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Debug.h>
#include <llvm/Support/raw_os_ostream.h>
#include <sstream>
using namespace llvm;
using namespace std;
namespace {
struct FindStructsGEPVisitor : public InstVisitor<FindStructsGEPVisitor> {
StructElementToValueSet &structCollection;
std::vector<const StructType *> &orderedTypes;
FindStructsGEPVisitor(StructElementToValueSet &s,vector<const StructType *> &o) : structCollection(s), orderedTypes(o) {}
void visitGetElementPtrInst(GetElementPtrInst &);
};
}
void FindStructsGEPVisitor::visitGetElementPtrInst(GetElementPtrInst &gepi)
{
DEBUG(dbgs() << "Top of visitor\n");
DEBUG(dbgs() << gepi << "\n");
const auto element = StructElement::get(gepi);
if (!element) return;
structCollection.emplace(*element, make_shared<ValueSet>()).first->second->insert(&gepi);
if (find(orderedTypes.begin(), orderedTypes.end(), &element->structure) == orderedTypes.end()) {
orderedTypes.push_back(&element->structure);
}
}
static const RegisterPass<FindStructElements> registration("find-struct-elements",
"Organize GEP instructions referring to struct element accesses by struct element.",
true, true);
char FindStructElements::ID;
static llvm::cl::opt<std::string>
testOutputName("test-find-struct-elements",
llvm::cl::Optional,
llvm::cl::value_desc("filename"),
llvm::cl::desc("Filename to write results to for regression tests"));
FindStructElements::FindStructElements()
: ModulePass(ID) {
}
void FindStructElements::getAnalysisUsage(AnalysisUsage &usage) const {
// read-only pass never changes anything
usage.setPreservesAll();
}
bool FindStructElements::runOnModule(Module &module) {
DEBUG(dbgs() << "Top of runOnModule()\n");
for (Function &func : module) {
DEBUG(dbgs() << "Analyzing " << func.getName() << "\n");
FindStructsGEPVisitor visitor(structElementCollections, orderedTypes);
for(BasicBlock &visitee : func) {
DEBUG(dbgs() << "Visiting a new basic block...\n");
visitor.visit(visitee);
}
}
if (!testOutputName.empty()) {
ofstream out(testOutputName);
llvm::raw_os_ostream sink(out);
print(sink, &module);
sink.flush();
out.close();
}
// read-only pass never changes anything
return false;
}
void FindStructElements::print(raw_ostream &sink, const Module* ) const {
for (const StructType *structTy : orderedTypes) {
sink << structTy->getName() << ":\n";
for (unsigned i = 0; i < structTy->getNumElements(); i++) {
const StructElement probe { *structTy, i };
if (structElementCollections.count(probe) > 0)
sink << "\telement " << i << " accessed\n";
}
}
}