#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/PassNameParser.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/LinkAllVMCore.h"
#include <memory>
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"),
- cl::value_desc("filename"), cl::init("-"));
+ cl::value_desc("filename"));
static cl::opt<bool>
Force("f", cl::desc("Enable binary output on terminals"));
struct CallGraphSCCPassPrinter : public CallGraphSCCPass {
static char ID;
const PassInfo *PassToPrint;
- CallGraphSCCPassPrinter(const PassInfo *PI) :
- CallGraphSCCPass(&ID), PassToPrint(PI) {}
+ raw_ostream &Out;
+ std::string PassName;
+
+ CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out) :
+ CallGraphSCCPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "CallGraphSCCPass Printer: " + PassToPrintName;
+ }
virtual bool runOnSCC(CallGraphSCC &SCC) {
- if (!Quiet) {
- outs() << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ if (!Quiet)
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
- for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
- Function *F = (*I)->getFunction();
- if (F)
- getAnalysisID<Pass>(PassToPrint).print(outs(), F->getParent());
- }
- }
// Get and print pass...
+ for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
+ Function *F = (*I)->getFunction();
+ if (F)
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ F->getParent());
+ }
return false;
}
- virtual const char *getPassName() const { return "'Pass' Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredID(PassToPrint);
+ AU.addRequiredID(PassToPrint->getTypeInfo());
AU.setPreservesAll();
}
};
struct ModulePassPrinter : public ModulePass {
static char ID;
const PassInfo *PassToPrint;
- ModulePassPrinter(const PassInfo *PI) : ModulePass(&ID),
- PassToPrint(PI) {}
+ raw_ostream &Out;
+ std::string PassName;
- virtual bool runOnModule(Module &M) {
- if (!Quiet) {
- outs() << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
- getAnalysisID<Pass>(PassToPrint).print(outs(), &M);
+ ModulePassPrinter(const PassInfo *PI, raw_ostream &out)
+ : ModulePass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "ModulePass Printer: " + PassToPrintName;
}
+ virtual bool runOnModule(Module &M) {
+ if (!Quiet)
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+
// Get and print pass...
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M);
return false;
}
- virtual const char *getPassName() const { return "'Pass' Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredID(PassToPrint);
+ AU.addRequiredID(PassToPrint->getTypeInfo());
AU.setPreservesAll();
}
};
char ModulePassPrinter::ID = 0;
struct FunctionPassPrinter : public FunctionPass {
const PassInfo *PassToPrint;
+ raw_ostream &Out;
static char ID;
- FunctionPassPrinter(const PassInfo *PI) : FunctionPass(&ID),
- PassToPrint(PI) {}
+ std::string PassName;
- virtual bool runOnFunction(Function &F) {
- if (!Quiet) {
- outs() << "Printing analysis '" << PassToPrint->getPassName()
- << "' for function '" << F.getName() << "':\n";
+ FunctionPassPrinter(const PassInfo *PI, raw_ostream &out)
+ : FunctionPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "FunctionPass Printer: " + PassToPrintName;
}
+
+ virtual bool runOnFunction(Function &F) {
+ if (!Quiet)
+ Out << "Printing analysis '" << PassToPrint->getPassName()
+ << "' for function '" << F.getName() << "':\n";
+
// Get and print pass...
- getAnalysisID<Pass>(PassToPrint).print(outs(), F.getParent());
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ F.getParent());
return false;
}
- virtual const char *getPassName() const { return "FunctionPass Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredID(PassToPrint);
+ AU.addRequiredID(PassToPrint->getTypeInfo());
AU.setPreservesAll();
}
};
struct LoopPassPrinter : public LoopPass {
static char ID;
const PassInfo *PassToPrint;
- LoopPassPrinter(const PassInfo *PI) :
- LoopPass(&ID), PassToPrint(PI) {}
+ raw_ostream &Out;
+ std::string PassName;
+
+ LoopPassPrinter(const PassInfo *PI, raw_ostream &out) :
+ LoopPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "LoopPass Printer: " + PassToPrintName;
+ }
+
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
+ if (!Quiet)
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+
+ // Get and print pass...
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ L->getHeader()->getParent()->getParent());
+ return false;
+ }
+
+ virtual const char *getPassName() const { return PassName.c_str(); }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(PassToPrint->getTypeInfo());
+ AU.setPreservesAll();
+ }
+};
+
+char LoopPassPrinter::ID = 0;
+
+struct RegionPassPrinter : public RegionPass {
+ static char ID;
+ const PassInfo *PassToPrint;
+ raw_ostream &Out;
+ std::string PassName;
+
+ RegionPassPrinter(const PassInfo *PI, raw_ostream &out) : RegionPass(ID),
+ PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "LoopPass Printer: " + PassToPrintName;
+ }
+
+ virtual bool runOnRegion(Region *R, RGPassManager &RGM) {
if (!Quiet) {
- outs() << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
- getAnalysisID<Pass>(PassToPrint).print(outs(),
- L->getHeader()->getParent()->getParent());
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "' for "
+ << "region: '" << R->getNameStr() << "' in function '"
+ << R->getEntry()->getParent()->getNameStr() << "':\n";
}
// Get and print pass...
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ R->getEntry()->getParent()->getParent());
return false;
}
virtual const char *getPassName() const { return "'Pass' Printer"; }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredID(PassToPrint);
+ AU.addRequiredID(PassToPrint->getTypeInfo());
AU.setPreservesAll();
}
};
-char LoopPassPrinter::ID = 0;
+char RegionPassPrinter::ID = 0;
struct BasicBlockPassPrinter : public BasicBlockPass {
const PassInfo *PassToPrint;
+ raw_ostream &Out;
static char ID;
- BasicBlockPassPrinter(const PassInfo *PI)
- : BasicBlockPass(&ID), PassToPrint(PI) {}
+ std::string PassName;
- virtual bool runOnBasicBlock(BasicBlock &BB) {
- if (!Quiet) {
- outs() << "Printing Analysis info for BasicBlock '" << BB.getName()
- << "': Pass " << PassToPrint->getPassName() << ":\n";
+ BasicBlockPassPrinter(const PassInfo *PI, raw_ostream &out)
+ : BasicBlockPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = PassToPrint->getPassName();
+ PassName = "BasicBlockPass Printer: " + PassToPrintName;
}
+ virtual bool runOnBasicBlock(BasicBlock &BB) {
+ if (!Quiet)
+ Out << "Printing Analysis info for BasicBlock '" << BB.getName()
+ << "': Pass " << PassToPrint->getPassName() << ":\n";
+
// Get and print pass...
- getAnalysisID<Pass>(PassToPrint).print(outs(), BB.getParent()->getParent());
+ getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out,
+ BB.getParent()->getParent());
return false;
}
- virtual const char *getPassName() const { return "BasicBlockPass Printer"; }
+ virtual const char *getPassName() const { return PassName.c_str(); }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequiredID(PassToPrint);
+ AU.addRequiredID(PassToPrint->getTypeInfo());
AU.setPreservesAll();
}
};
if (DisableInline) {
// No inlining pass
} else if (OptLevel) {
- unsigned Threshold = 200;
+ unsigned Threshold = 225;
if (OptLevel > 2)
- Threshold = 250;
+ Threshold = 275;
InliningPass = createFunctionInliningPass(Threshold);
} else {
InliningPass = createAlwaysInlinerPass();
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc, argv);
+
+ if (AnalyzeOnly && NoOutput) {
+ errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n";
+ return 1;
+ }
// Enable debug stream buffering.
EnableDebugBuffering = true;
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
LLVMContext &Context = getGlobalContext();
+ // Initialize passes
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeCore(Registry);
+ initializeScalarOpts(Registry);
+ initializeIPO(Registry);
+ initializeAnalysis(Registry);
+ initializeIPA(Registry);
+ initializeTransformUtils(Registry);
+ initializeInstCombine(Registry);
+ initializeInstrumentation(Registry);
+ initializeTarget(Registry);
+
cl::ParseCommandLineOptions(argc, argv,
"llvm .bc -> .bc modular optimizer and analysis printer\n");
}
// Figure out what stream we are supposed to write to...
- raw_ostream *Out = 0;
- bool DeleteStream = false;
- if (!NoOutput && !AnalyzeOnly) {
- if (OutputFilename == "-") {
- // Print to stdout.
- Out = &outs();
- // If we're printing a bitcode file, switch stdout to binary mode.
- // FIXME: This switches outs() globally, not just for the bitcode output.
- if (!OutputAssembly)
- sys::Program::ChangeStdoutToBinary();
- } else {
- if (NoOutput || AnalyzeOnly) {
- errs() << "WARNING: The -o (output filename) option is ignored when\n"
- "the --disable-output or --analyze options are used.\n";
- } else {
- // Make sure that the Output file gets unlinked from the disk if we get
- // a SIGINT.
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
-
- std::string ErrorInfo;
- Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo,
- raw_fd_ostream::F_Binary);
- if (!ErrorInfo.empty()) {
- errs() << ErrorInfo << '\n';
- delete Out;
- return 1;
- }
- DeleteStream = true;
- }
+ OwningPtr<tool_output_file> Out;
+ if (NoOutput) {
+ if (!OutputFilename.empty())
+ errs() << "WARNING: The -o (output filename) option is ignored when\n"
+ "the --disable-output option is used.\n";
+ } else {
+ // Default to standard output.
+ if (OutputFilename.empty())
+ OutputFilename = "-";
+
+ std::string ErrorInfo;
+ Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo,
+ raw_fd_ostream::F_Binary));
+ if (!ErrorInfo.empty()) {
+ errs() << ErrorInfo << '\n';
+ return 1;
}
}
// console, print out a warning message and refuse to do it. We don't
// impress anyone by spewing tons of binary goo to a terminal.
if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly)
- if (CheckBitcodeOutputToConsole(*Out, !Quiet))
+ if (CheckBitcodeOutputToConsole(Out->os(), !Quiet))
NoOutput = true;
// Create a PassManager to hold and optimize the collection of passes we are
if (AnalyzeOnly) {
switch (Kind) {
case PT_BasicBlock:
- Passes.add(new BasicBlockPassPrinter(PassInf));
+ Passes.add(new BasicBlockPassPrinter(PassInf, Out->os()));
+ break;
+ case PT_Region:
+ Passes.add(new RegionPassPrinter(PassInf, Out->os()));
break;
case PT_Loop:
- Passes.add(new LoopPassPrinter(PassInf));
+ Passes.add(new LoopPassPrinter(PassInf, Out->os()));
break;
case PT_Function:
- Passes.add(new FunctionPassPrinter(PassInf));
+ Passes.add(new FunctionPassPrinter(PassInf, Out->os()));
break;
case PT_CallGraphSCC:
- Passes.add(new CallGraphSCCPassPrinter(PassInf));
+ Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os()));
break;
default:
- Passes.add(new ModulePassPrinter(PassInf));
+ Passes.add(new ModulePassPrinter(PassInf, Out->os()));
break;
}
}
if (!NoVerify && !VerifyEach)
Passes.add(createVerifierPass());
- // Write bitcode or assembly out to disk or outs() as the last step...
+ // Write bitcode or assembly to the output as the last step...
if (!NoOutput && !AnalyzeOnly) {
if (OutputAssembly)
- Passes.add(createPrintModulePass(Out));
+ Passes.add(createPrintModulePass(&Out->os()));
else
- Passes.add(createBitcodeWriterPass(*Out));
+ Passes.add(createBitcodeWriterPass(Out->os()));
}
// Now that we have all of the passes ready, run them.
Passes.run(*M.get());
- // Delete the raw_fd_ostream.
- if (DeleteStream)
- delete Out;
+ // Declare success.
+ if (!NoOutput)
+ Out->keep();
+
return 0;
}