forked from Blue9/llvm-pass-skeleton
-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.py
114 lines (80 loc) · 2.83 KB
/
run.py
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
import os
import subprocess
program = lambda num_runs, threshold: f'''
#include <vector>
#include "llvm/Analysis/InlineCost.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Cloning.h"
// using namespace llvm;
namespace llvm{{
const int INLINE_THRESHOLD = {threshold};
const int NUM_RUNS = {num_runs};
class FunctionInliningPass : public PassInfoMixin<FunctionInliningPass> {{
public:
// static char ID;
PreservedAnalyses run(Function& F, FunctionAnalysisManager& AM) {{
bool modified = false;
for (int i = 0; i < NUM_RUNS; ++i) {{
std::vector<Instruction *> worklist;
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {{
worklist.push_back(&*I);
}}
for (Instruction *I : worklist) {{
CallInst *call = dyn_cast<CallInst>(I);
if (call != nullptr) {{
Function *fun = call->getCalledFunction();
if (fun != nullptr && isInlineViable(*fun).isSuccess() &&
fun->getInstructionCount() <= INLINE_THRESHOLD) {{
InlineFunctionInfo info;
auto call_base = dyn_cast<CallBase>(call);
InlineFunction(*call_base, info);
modified = true;
}}
}}
}}
}}
return PreservedAnalyses::all();
}}
}};
}} // namespace
// char FunctionInliningPass::ID = 0;
// Register the pass so `opt -function-inlining` runs it.
// static RegisterPass<FunctionInliningPass> X("function-inlining",
// "a useful pass");
// Register the pass
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {{
return {{
LLVM_PLUGIN_API_VERSION, "function-inlining", "v0.1",
[](llvm::PassBuilder &PB) {{
PB.registerPipelineParsingCallback(
[](llvm::StringRef Name, llvm::FunctionPassManager &FPM,
llvm::ArrayRef<llvm::PassBuilder::PipelineElement>) {{
if(Name == "function-inlining"){{
FPM.addPass(llvm::FunctionInliningPass());
return true;
}}
return false;
}}
);
}}
}};
}}
'''
if __name__ == '__main__':
for threshold in (10, 100, 1000):
for num_runs in (1, 2, 3):
prog = program(num_runs, threshold)
with open('function-inlining/FunctionInlining.cpp', 'w') as f:
f.write(prog)
result = subprocess.run(['./build.sh'])
assert result.returncode == 0, "benis"
result = subprocess.run(['python3', 'benchmark.py', f'out-{num_runs}-{threshold}.csv'])
assert result.returncode == 0, "big ol begnis"