Implement a more powerful, simpler, pass system. This pass system can figure
out how to run a collection of passes optimially given their behaviors and
charactaristics.
Convert code to use it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1507 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/gccas/gccas.cpp b/tools/gccas/gccas.cpp
index 073b248..7e2b6f3 100644
--- a/tools/gccas/gccas.cpp
+++ b/tools/gccas/gccas.cpp
@@ -63,19 +63,19 @@
// In addition to just parsing the input from GCC, we also want to spiff it up
// a little bit. Do this now.
//
- std::vector<Pass*> Passes;
- Passes.push_back(new opt::DeadCodeElimination()); // Remove Dead code/vars
- Passes.push_back(new CleanupGCCOutput()); // Fix gccisms
- Passes.push_back(new InductionVariableSimplify()); // Simplify indvars
- Passes.push_back(new RaisePointerReferences()); // Eliminate casts
- Passes.push_back(new ConstantMerge()); // Merge dup global consts
- Passes.push_back(new InstructionCombining()); // Combine silly seq's
- Passes.push_back(new opt::DeadCodeElimination()); // Remove Dead code/vars
+ PassManager Passes;
+ Passes.add(new opt::DeadCodeElimination()); // Remove Dead code/vars
+ Passes.add(new CleanupGCCOutput()); // Fix gccisms
+ Passes.add(new InductionVariableSimplify()); // Simplify indvars
+ Passes.add(new RaisePointerReferences()); // Eliminate casts
+ Passes.add(new ConstantMerge()); // Merge dup global consts
+ Passes.add(new InstructionCombining()); // Combine silly seq's
+ Passes.add(new opt::DeadCodeElimination()); // Remove Dead code/vars
// Run our queue of passes all at once now, efficiently. This form of
// runAllPasses frees the Pass objects after runAllPasses completes.
//
- Pass::runAllPassesAndFree(M.get(), Passes);
+ Passes.run(M.get());
WriteBytecodeToFile(M.get(), *Out);
return 0;
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 6b51f79..3cc8a72 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -52,21 +52,20 @@
// Native code generation for a specified target.
//===---------------------------------------------------------------------===//
-class GenerateCodeForTarget : public Pass {
+class GenerateCodeForTarget : public MethodPass {
TargetMachine &Target;
public:
inline GenerateCodeForTarget(TargetMachine &T) : Target(T) {}
- // doPerMethodWork - This method does the actual work of generating code for
+ // runOnMethod - This method does the actual work of generating code for
// the specified method.
//
- bool doPerMethodWork(Method *M) {
+ bool runOnMethod(Method *M) {
if (!M->isExternal() && Target.compileMethod(M)) {
cerr << "Error compiling " << InputFilename << "!\n";
- return true;
}
- return false;
+ return true;
}
};
@@ -85,8 +84,7 @@
inline EmitAssembly(const TargetMachine &T, std::ostream *O, bool D)
: Target(T), Out(O), DeleteStream(D) {}
-
- virtual bool doPassFinalization(Module *M) {
+ virtual bool run(Module *M) {
Target.emitAssembly(M, *Out);
if (DeleteStream) delete Out;
@@ -95,6 +93,7 @@
};
+
//===---------------------------------------------------------------------===//
// Function main()
//
@@ -119,18 +118,18 @@
}
// Build up all of the passes that we want to do to the module...
- std::vector<Pass*> Passes;
+ PassManager Passes;
// Hoist constants out of PHI nodes into predecessor BB's
- Passes.push_back(new HoistPHIConstants());
+ Passes.add(new HoistPHIConstants());
if (TraceBBValues || TraceMethodValues) { // If tracing enabled...
// Insert trace code in all methods in the module
- Passes.push_back(new InsertTraceCode(TraceBBValues,
- TraceBBValues ||TraceMethodValues));
+ Passes.add(new InsertTraceCode(TraceBBValues,
+ TraceBBValues ||TraceMethodValues));
// Eliminate duplication in constant pool
- Passes.push_back(new DynamicConstantMerge());
+ Passes.add(new DynamicConstantMerge());
// Then write out the module with tracing code before code generation
assert(InputFilename != "-" &&
@@ -152,20 +151,20 @@
return 1;
}
- Passes.push_back(new WriteBytecodePass(os, true));
+ Passes.add(new WriteBytecodePass(os, true));
}
// Replace malloc and free instructions with library calls.
// Do this after tracing until lli implements these lib calls.
// For now, it will emulate malloc and free internally.
- Passes.push_back(new LowerAllocations(Target.DataLayout));
+ Passes.add(new LowerAllocations(Target.DataLayout));
// If LLVM dumping after transformations is requested, add it to the pipeline
if (DumpAsm)
- Passes.push_back(new PrintModulePass("Code after xformations: \n",&cerr));
+ Passes.add(new PrintMethodPass("Code after xformations: \n",&cerr));
// Generate Target code...
- Passes.push_back(new GenerateCodeForTarget(Target));
+ Passes.add(new GenerateCodeForTarget(Target));
if (!DoNotEmitAssembly) { // If asm output is enabled...
// Figure out where we are going to send the output...
@@ -203,12 +202,11 @@
}
// Output assembly language to the .s file
- Passes.push_back(new EmitAssembly(Target, Out, Out != &std::cout));
+ Passes.add(new EmitAssembly(Target, Out, Out != &std::cout));
}
- // Run our queue of passes all at once now, efficiently. This form of
- // runAllPasses frees the Pass objects after runAllPasses completes.
- Pass::runAllPassesAndFree(M.get(), Passes);
+ // Run our queue of passes all at once now, efficiently.
+ Passes.run(M.get());
return 0;
}
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 8a2208d..7f9acf0 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -34,14 +34,13 @@
indvars, instcombine, sccp, adce, raise,
// Interprocedural optimizations...
- globaldce, swapstructs,
+ globaldce, swapstructs, sortstructs,
};
struct {
enum Opts OptID;
Pass *ThePass;
} OptTable[] = {
- { swapstructs, 0 },
{ dce , new opt::DeadCodeElimination() },
{ constprop , new opt::ConstantPropogation() },
{ inlining , new opt::MethodInlining() },
@@ -55,8 +54,11 @@
{ raise , new RaisePointerReferences() },
{ trace , new InsertTraceCode(true, true) },
{ tracem , new InsertTraceCode(false, true) },
- { print , new PrintModulePass("Current Method: \n",&cerr) },
+ { print , new PrintMethodPass("Current Method: \n",&cerr) },
{ 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, "-");
@@ -78,6 +80,7 @@
clEnumVal(globaldce , "Remove unreachable globals"),
clEnumVal(swapstructs, "Swap structure types around"),
+ clEnumVal(sortstructs, "Sort structure elements"),
clEnumVal(cleangcc , "Cleanup GCC Output"),
clEnumVal(raise , "Raise to Higher Level"),
@@ -95,18 +98,7 @@
return;
}
- // Special cases that haven't been fit into a consistent framework yet...
- switch (Opt) {
- case globaldce: {
- GlobalDCE GDCE; GDCE.run(M); return;
- }
- case swapstructs: {
- PrebuiltStructMutation SM(M, PrebuiltStructMutation::SortElements);
- SM.run(M); return;
- }
- default:
- cerr << "Optimization tables inconsistent!!\n";
- }
+ cerr << "Optimization tables inconsistent!!\n";
}
int main(int argc, char **argv) {
@@ -118,6 +110,8 @@
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]);