-//===------------------------------------------------------------------------===
+//===----------------------------------------------------------------------===//
// LLVM 'GCCAS' UTILITY
//
// This utility is designed to be used by the GCC frontend for creating
// bytecode files from it's intermediate llvm assembly. The requirements for
// this utility are thus slightly different than that of the standard as util.
//
-//===------------------------------------------------------------------------===
+//===----------------------------------------------------------------------===//
#include "llvm/Module.h"
+#include "llvm/PassManager.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Transforms/CleanupGCCOutput.h"
#include "llvm/Transforms/LevelChange.h"
-#include "llvm/Optimizations/ConstantProp.h"
-#include "llvm/Optimizations/DCE.h"
#include "llvm/Transforms/ConstantMerge.h"
-#include "llvm/Bytecode/Writer.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/ChangeAllocations.h"
+#include "llvm/Transforms/Scalar/DCE.h"
+#include "llvm/Transforms/Scalar/IndVarSimplify.h"
+#include "llvm/Transforms/Scalar/InstructionCombining.h"
+#include "llvm/Transforms/Scalar/PromoteMemoryToRegister.h"
+#include "llvm/Bytecode/WriteBytecodePass.h"
+#include "Support/CommandLine.h"
+#include "Support/Signals.h"
#include <memory>
#include <fstream>
#include <string>
cl::String InputFilename ("", "Parse <arg> file, compile to bytecode",
cl::Required, "");
cl::String OutputFilename("o", "Override output filename", cl::NoFlags, "");
+cl::Flag StopAtLevelRaise("stopraise", "Stop optimization before level raise",
+ cl::Hidden);
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");
- ostream *Out = 0;
std::auto_ptr<Module> M;
try {
// Parse the file now...
}
if (OutputFilename == "") { // Didn't specify an output filename?
- string IFN = InputFilename;
+ std::string IFN = InputFilename;
int Len = IFN.length();
if (IFN[Len-2] == '.' && IFN[Len-1] == 's') { // Source ends in .s?
- OutputFilename = string(IFN.begin(), IFN.end()-2);
+ OutputFilename = std::string(IFN.begin(), IFN.end()-2);
} else {
OutputFilename = IFN; // Append a .o to it
}
OutputFilename += ".o";
}
- Out = new ofstream(OutputFilename.c_str(), ios::out);
- if (!Out->good()) {
+ std::ofstream Out(OutputFilename.c_str(), ios::out);
+ if (!Out.good()) {
cerr << "Error opening " << OutputFilename << "!\n";
return 1;
}
+ // Make sure that the Out file gets unlink'd from the disk if we get a SIGINT
+ RemoveFileOnSignal(OutputFilename);
+
// In addition to just parsing the input from GCC, we also want to spiff it up
// a little bit. Do this now.
//
- vector<Pass*> Passes;
- Passes.push_back(new CleanupGCCOutput()); // Fix gccisms
- Passes.push_back(new opt::ConstantPropogation());// Trivial const prop
- Passes.push_back(new RaisePointerReferences()); // Fix general low level code
- Passes.push_back(new opt::ConstantPropogation());// Trivial const prop
- Passes.push_back(new opt::DeadCodeElimination());// Trivial DCE
- Passes.push_back(new ConstantMerge()); // Merge dup global constants
-
- // 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);
+ PassManager Passes;
+ Passes.add(createFunctionResolvingPass()); // Resolve (...) functions
+ Passes.add(createDeadInstEliminationPass()); // Remove Dead code/vars
+ Passes.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
+ Passes.add(createCleanupGCCOutputPass()); // Fix gccisms
+ Passes.add(createIndVarSimplifyPass()); // Simplify indvars
+ if (!StopAtLevelRaise) {
+ Passes.add(createRaisePointerReferencesPass()); // Eliminate casts
+ Passes.add(createPromoteMemoryToRegister()); // Promote alloca's to regs
+ Passes.add(createConstantMergePass()); // Merge dup global consts
+ Passes.add(createInstructionCombiningPass()); // Combine silly seq's
+ Passes.add(createDeadCodeEliminationPass()); // Remove Dead code/vars
+ }
+ Passes.add(new WriteBytecodePass(&Out)); // Write bytecode to file...
- WriteBytecodeToFile(M.get(), *Out);
+ // Run our queue of passes all at once now, efficiently.
+ Passes.run(M.get());
return 0;
}