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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
//===----------------------------------------------------------------------===//
// LLVM 'OPT' UTILITY
//
// Optimizations may be specified an arbitrary number of times on the command
// line, they are run in the order specified.
//
//===----------------------------------------------------------------------===//
#include "llvm/Module.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Bytecode/Writer.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Transforms/ConstantMerge.h"
#include "llvm/Transforms/CleanupGCCOutput.h"
#include "llvm/Transforms/LevelChange.h"
#include "llvm/Transforms/MethodInlining.h"
#include "llvm/Transforms/SymbolStripping.h"
#include "llvm/Transforms/ChangeAllocations.h"
#include "llvm/Transforms/IPO/SimpleStructMutation.h"
#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Transforms/Scalar/DCE.h"
#include "llvm/Transforms/Scalar/ConstantProp.h"
#include "llvm/Transforms/Scalar/InductionVars.h"
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/Transforms/Scalar/InstructionCombining.h"
#include "llvm/Transforms/Instrumentation/TraceValues.h"
#include "Support/CommandLine.h"
#include <fstream>
#include <memory>
enum Opts {
// Basic optimizations
dce, constprop, inlining, constmerge, strip, mstrip,
// Miscellaneous Transformations
trace, tracem, print, raiseallocs, cleangcc,
// More powerful optimizations
indvars, instcombine, sccp, adce, raise,
// Interprocedural optimizations...
globaldce, swapstructs, sortstructs,
};
struct {
enum Opts OptID;
Pass *ThePass;
} OptTable[] = {
{ dce , new DeadCodeElimination() },
{ constprop , new ConstantPropogation() },
{ inlining , new MethodInlining() },
{ constmerge , new ConstantMerge() },
{ strip , new SymbolStripping() },
{ mstrip , new FullSymbolStripping() },
{ indvars , new InductionVariableSimplify() },
{ instcombine, new InstructionCombining() },
{ sccp , new SCCPPass() },
{ adce , new AgressiveDCE() },
{ raise , new RaisePointerReferences() },
{ trace , new InsertTraceCode(true, true) },
{ tracem , new InsertTraceCode(false, true) },
{ print , new PrintMethodPass("Current Method: \n",&cerr) },
{ raiseallocs, new RaiseAllocations() },
{ cleangcc , new CleanupGCCOutput() },
{ globaldce , new GlobalDCE() },
{ swapstructs, new SimpleStructMutation(SimpleStructMutation::SwapElements) },
{ sortstructs, new SimpleStructMutation(SimpleStructMutation::SortElements) },
};
cl::String InputFilename ("", "Load <arg> file to optimize", cl::NoFlags, "-");
cl::String OutputFilename("o", "Override output filename", cl::NoFlags, "");
cl::Flag Force ("f", "Overwrite output files", cl::NoFlags, false);
cl::Flag Quiet ("q", "Don't print modifying pass names", 0, false);
cl::Alias QuietA ("quiet", "Alias for -q", cl::NoFlags, Quiet);
cl::EnumList<enum Opts> OptimizationList(cl::NoFlags,
clEnumVal(dce , "Dead Code Elimination"),
clEnumVal(constprop , "Simple Constant Propogation"),
clEnumValN(inlining , "inline", "Method Integration"),
clEnumVal(constmerge , "Merge identical global constants"),
clEnumVal(strip , "Strip Symbols"),
clEnumVal(mstrip , "Strip Module Symbols"),
clEnumVal(indvars , "Simplify Induction Variables"),
clEnumVal(instcombine, "Simplify Induction Variables"),
clEnumVal(sccp , "Sparse Conditional Constant Propogation"),
clEnumVal(adce , "Agressive DCE"),
clEnumVal(globaldce , "Remove unreachable globals"),
clEnumVal(swapstructs, "Swap structure types around"),
clEnumVal(sortstructs, "Sort structure elements"),
clEnumVal(raiseallocs, "Raise allocations from calls to instructions"),
clEnumVal(cleangcc , "Cleanup GCC Output"),
clEnumVal(raise , "Raise to Higher Level"),
clEnumVal(trace , "Insert BB & Method trace code"),
clEnumVal(tracem , "Insert Method trace code only"),
clEnumVal(print , "Print working method to stderr"),
0);
static void RunOptimization(Module *M, enum Opts Opt) {
for (unsigned j = 0; j < sizeof(OptTable)/sizeof(OptTable[0]); ++j)
if (Opt == OptTable[j].OptID) {
if (OptTable[j].ThePass->run(M) && !Quiet)
cerr << OptimizationList.getArgName(Opt)
<< " pass made modifications!\n";
return;
}
cerr << "Optimization tables inconsistent!!\n";
}
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv,
" llvm .bc -> .bc modular optimizer\n");
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) {
cerr << "bytecode didn't read correctly.\n";
return 1;
}
PassManager Passes;
// Run all of the optimizations specified on the command line
for (unsigned i = 0; i < OptimizationList.size(); ++i)
RunOptimization(M.get(), OptimizationList[i]);
std::ostream *Out = &std::cout; // Default to printing to stdout...
if (OutputFilename != "") {
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
cerr << "Error opening '" << OutputFilename << "': File exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
if (!Out->good()) {
cerr << "Error opening " << OutputFilename << "!\n";
return 1;
}
}
// Okay, we're done now... write out result...
WriteBytecodeToFile(M.get(), *Out);
if (Out != &cout) delete Out;
return 0;
}
|