mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
For PR872:
Shrinkify LLVM's footprint by removing the analyze tool and moving its functionality into the opt tool. THis eliminates one of the largest tools from LLVM and doesn't make opt much bigger because it already included most of the analysis passes. To get the old analyze functionality pass the -analyze option to opt. Note that the integeration here is dead simple. The "main" of analyze was just copied to opt and invoked if the -analyze option was given. There may be opportunities for further integration such as removing the distinction between transform passes and analysis passes. To use the analysis functionality, if you previously did this: analyze $FNAME -domset -disable-verify you would now do this: opt -analyze $FNAME -domset -disable-verify Pretty simple. llvm-svn: 29762
This commit is contained in:
parent
9c89e09297
commit
8245e5bde1
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-dspass=td -dsgc-check-flags=Ptr:HR
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-dspass=td -dsgc-check-flags=Ptr:HR
|
||||
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
; This is the same testcase as 2003-06-29-NodeCollapsing2.ll, but it uses the
|
||||
; graph checker.
|
||||
;
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
;
|
||||
%T = type { int}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-dspass=td -dsgc-check-flags=X:GM
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-dspass=td -dsgc-check-flags=X:GM
|
||||
|
||||
%G = internal global int 5
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
|
||||
%X = internal global { int, short, short } { int 1, short 2, short 3 }
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; This should cause the global node to collapse!!
|
||||
; XFAIL: *
|
||||
; RUN: analyze %s -datastructure-gc --dsgc-check-flags=test:GAU
|
||||
; RUN: opt -analyze %s -datastructure-gc --dsgc-check-flags=test:GAU
|
||||
|
||||
%Tree = type { int, %Tree*, %Tree* }
|
||||
%T5 = external global %Tree
|
||||
|
@ -1,7 +1,7 @@
|
||||
; This is the same testcase as 2003-06-29-NodeCollapsing2.ll, but it uses the
|
||||
; graph checker.
|
||||
;
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
;
|
||||
|
||||
%S = type { double, int }
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-check-flags=Xn:SMR
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-check-flags=X:SMR
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-check-flags=Xn:SMR
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-check-flags=X:SMR
|
||||
|
||||
declare void %llvm.memcpy.i32(sbyte*, sbyte*, uint, uint)
|
||||
declare void %llvm.memmove.i32(sbyte*, sbyte*, uint, uint)
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=bu &&\
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=td
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=bu &&\
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-check-flags=G:GIM -dsgc-dspass=td
|
||||
|
||||
%S = type { double, int }
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llvm-as < %s | analyze -datastructure
|
||||
; RUN: llvm-as < %s | opt -analyze -datastructure
|
||||
|
||||
target endian = little
|
||||
target pointersize = 32
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llvm-as < %s | analyze -datastructure
|
||||
; RUN: llvm-as < %s | opt -analyze -datastructure
|
||||
|
||||
; ModuleID = 'bug3.bc'
|
||||
target endian = little
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-check-flags=x:IA
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-check-flags=x:IA
|
||||
|
||||
; ModuleID = 'bug3.bc'
|
||||
target endian = little
|
||||
|
@ -1,7 +1,7 @@
|
||||
; FIXME: this should be SHM for bu, but change it for now since besides incompleteness
|
||||
; this is working
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-dspass=bu -dsgc-check-flags=Y:SHIM && \
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-dspass=td -dsgc-check-flags=P1:SHM,P2:SHM
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-dspass=bu -dsgc-check-flags=Y:SHIM && \
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-dspass=td -dsgc-check-flags=P1:SHM,P2:SHM
|
||||
|
||||
%G = internal constant [2 x int*(int*)*] [
|
||||
int*(int*)* %callee1, int*(int*)* %callee2
|
||||
|
@ -5,7 +5,7 @@
|
||||
; -- globals in GG pointed to by latter should be marked I, but not other nodes
|
||||
;
|
||||
; FIXME: KnownPtr should be just S.
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-check-flags=KnownPtr:SI,UnknownPtr:SI -dsgc-dspass=bu
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-check-flags=KnownPtr:SI,UnknownPtr:SI -dsgc-dspass=bu
|
||||
|
||||
%Z = internal global int 0
|
||||
%X = internal global int 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -budatastructure -dont-print-ds
|
||||
; RUN: opt -analyze %s -budatastructure -dont-print-ds
|
||||
|
||||
%MidFnTy = type void (\2*)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Test to check for support for "physical subtyping"
|
||||
;
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-abort-if-any-collapsed
|
||||
;
|
||||
%S = type { int }
|
||||
%T = type { int, float, double }
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
; RUN: analyze %s -datastructure-gc --dsgc-abort-if-merged=Y,BVal
|
||||
; RUN: opt -analyze %s -datastructure-gc --dsgc-abort-if-merged=Y,BVal
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
; FIXME: A should just be SM
|
||||
; RUN: analyze %s -datastructure-gc -dsgc-dspass=bu -dsgc-check-flags=A:SIM
|
||||
; RUN: opt -analyze %s -datastructure-gc -dsgc-dspass=bu -dsgc-check-flags=A:SIM
|
||||
; Constant globals should not mark stuff incomplete. This should allow the
|
||||
; bu pass to resolve the indirect call immediately in "test", allowing %A to
|
||||
; be marked complete and the store to happen.
|
||||
|
@ -3,7 +3,7 @@
|
||||
; has no defined way to check for this, so DSA can know that strcpy doesn't
|
||||
; require merging the input arguments.
|
||||
|
||||
; RUN: analyze %s -datastructure-gc --dsgc-abort-if-merged=A,B --dsgc-check-flags=A:ASM,B:ASR --dsgc-dspass=bu
|
||||
; RUN: opt -analyze %s -datastructure-gc --dsgc-abort-if-merged=A,B --dsgc-check-flags=A:ASM,B:ASR --dsgc-dspass=bu
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -domset -disable-verify
|
||||
; RUN: opt -analyze %s -domset -disable-verify
|
||||
;
|
||||
int %re_match_2() {
|
||||
ENTRY:
|
||||
|
@ -1,7 +1,7 @@
|
||||
; This testcase was incorrectly computing that the loopentry.7 loop was
|
||||
; not a child of the loopentry.6 loop.
|
||||
;
|
||||
; RUN: analyze %s -loops | grep "^ Loop Containing: %loopentry.7"
|
||||
; RUN: opt -analyze %s -loops | grep "^ Loop Containing: %loopentry.7"
|
||||
|
||||
void %getAndMoveToFrontDecode() { ; No predecessors!
|
||||
br label %endif.2
|
||||
|
@ -2,7 +2,7 @@
|
||||
; folded completely away if possible. This is a very common case, so it should
|
||||
; be efficient.
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
;
|
||||
implementation
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
%crazy = type [2 x { [2 x sbyte], short } ]
|
||||
|
||||
implementation
|
||||
|
@ -1,6 +1,6 @@
|
||||
; This file contains a list of situations where node folding should happen...
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; very simple test
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
%str = type { int*, int* }
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; This file contains a list of cases where node folding should NOT happen
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
;
|
||||
|
||||
implementation
|
||||
|
@ -1,5 +1,5 @@
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
%G = global int 2 ; <int*> [#uses=1]
|
||||
%H = global int* null
|
||||
|
@ -1,5 +1,5 @@
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
int* %test1(int *%A) {
|
||||
%R = getelementptr int* %A, long 1
|
||||
|
@ -1,6 +1,6 @@
|
||||
; A test for "physical subtyping" used in some C programs...
|
||||
;
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
;
|
||||
%ST = type { int, int* } ; "Subtype"
|
||||
%DT = type { int, int*, int } ; "derived type"
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
implementation ; Functions:
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
void %foo(int* %X) {
|
||||
store int 4, int* %X
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: analyze %s -tddatastructure
|
||||
; RUN: opt -analyze %s -tddatastructure
|
||||
|
||||
%str = type { int, int* }
|
||||
|
||||
|
@ -9,8 +9,7 @@
|
||||
|
||||
LEVEL := ..
|
||||
PARALLEL_DIRS := llvm-config llvm-as llvm-dis opt gccas llc llvm-link lli gccld\
|
||||
llvm-stub analyze llvm-extract llvm-nm llvm-prof llvm-ar \
|
||||
llvm-ranlib llvm-bcanalyzer llvmc llvm-ld llvm-db bugpoint \
|
||||
llvm2cpp
|
||||
llvm-stub llvm-extract llvm-nm llvm-prof llvm-ar llvm-ranlib \
|
||||
llvm-bcanalyzer llvmc llvm-ld llvm-db bugpoint llvm2cpp
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -1,17 +0,0 @@
|
||||
##===- tools/analyze/Makefile ------------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file was developed by the LLVM research group and is distributed under
|
||||
# the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
LEVEL = ../..
|
||||
TOOLNAME = analyze
|
||||
USEDLIBS = LLVMAsmParser.a LLVMBCReader.a LLVMAnalysis.a LLVMipa.a \
|
||||
LLVMDataStructure \
|
||||
LLVMScalarOpts.a LLVMTransforms.a LLVMTarget.a LLVMScalarOpts.a \
|
||||
LLVMTransformUtils.a LLVMCore.a LLVMSupport.a LLVMbzip2.a LLVMSystem.a
|
||||
REQUIRES_EH := 1
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
@ -1,188 +0,0 @@
|
||||
//===- analyze.cpp - The LLVM analyze utility -----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This utility is designed to print out the results of running various analysis
|
||||
// passes on a program. This is useful for understanding a program, or for
|
||||
// debugging an analysis pass.
|
||||
//
|
||||
// analyze --help - Output information about command line switches
|
||||
// analyze --quiet - Do not print analysis name before output
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Bytecode/Reader.h"
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#include "llvm/Analysis/Verifier.h"
|
||||
#include "llvm/Analysis/LinkAllAnalyses.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Support/PassNameParser.h"
|
||||
#include "llvm/System/Signals.h"
|
||||
#include "llvm/Support/PluginLoader.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/LinkAllVMCore.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
cl::opt<std::string>
|
||||
InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"),
|
||||
cl::value_desc("filename"));
|
||||
|
||||
cl::opt<bool> Quiet("q", cl::desc("Don't print analysis pass names"));
|
||||
cl::alias QuietA("quiet", cl::desc("Alias for -q"),
|
||||
cl::aliasopt(Quiet));
|
||||
|
||||
cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
|
||||
cl::desc("Do not verify input module"));
|
||||
|
||||
// The AnalysesList is automatically populated with registered Passes by the
|
||||
// PassNameParser.
|
||||
//
|
||||
cl::list<const PassInfo*, bool, FilteredPassNameParser<PassInfo::Analysis> >
|
||||
AnalysesList(cl::desc("Analyses available:"));
|
||||
|
||||
Timer BytecodeLoadTimer("Bytecode Loader");
|
||||
}
|
||||
|
||||
struct ModulePassPrinter : public ModulePass {
|
||||
const PassInfo *PassToPrint;
|
||||
ModulePassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
|
||||
|
||||
virtual bool runOnModule(Module &M) {
|
||||
if (!Quiet) {
|
||||
std::cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
|
||||
getAnalysisID<Pass>(PassToPrint).print(std::cout, &M);
|
||||
}
|
||||
|
||||
// Get and print pass...
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const char *getPassName() const { return "'Pass' Printer"; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredID(PassToPrint);
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
|
||||
struct FunctionPassPrinter : public FunctionPass {
|
||||
const PassInfo *PassToPrint;
|
||||
FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
if (!Quiet) {
|
||||
std::cout << "Printing analysis '" << PassToPrint->getPassName()
|
||||
<< "' for function '" << F.getName() << "':\n";
|
||||
}
|
||||
// Get and print pass...
|
||||
getAnalysisID<Pass>(PassToPrint).print(std::cout, F.getParent());
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const char *getPassName() const { return "FunctionPass Printer"; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredID(PassToPrint);
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
|
||||
struct BasicBlockPassPrinter : public BasicBlockPass {
|
||||
const PassInfo *PassToPrint;
|
||||
BasicBlockPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
|
||||
|
||||
virtual bool runOnBasicBlock(BasicBlock &BB) {
|
||||
if (!Quiet) {
|
||||
std::cout << "Printing Analysis info for BasicBlock '" << BB.getName()
|
||||
<< "': Pass " << PassToPrint->getPassName() << ":\n";
|
||||
}
|
||||
|
||||
// Get and print pass...
|
||||
getAnalysisID<Pass>(PassToPrint).print(std::cout, BB.getParent()->getParent());
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const char *getPassName() const { return "BasicBlockPass Printer"; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredID(PassToPrint);
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
try {
|
||||
cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
|
||||
Module *CurMod = 0;
|
||||
try {
|
||||
#if 0
|
||||
TimeRegion RegionTimer(BytecodeLoadTimer);
|
||||
#endif
|
||||
CurMod = ParseBytecodeFile(InputFilename);
|
||||
if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
|
||||
std::cerr << argv[0] << ": input file didn't read correctly.\n";
|
||||
return 1;
|
||||
}
|
||||
} catch (const ParseException &E) {
|
||||
std::cerr << argv[0] << ": " << E.getMessage() << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a PassManager to hold and optimize the collection of passes we are
|
||||
// about to build...
|
||||
//
|
||||
PassManager Passes;
|
||||
|
||||
// Add an appropriate TargetData instance for this module...
|
||||
Passes.add(new TargetData(CurMod));
|
||||
|
||||
// Make sure the input LLVM is well formed.
|
||||
if (!NoVerify)
|
||||
Passes.add(createVerifierPass());
|
||||
|
||||
// Create a new optimization pass for each one specified on the command line
|
||||
for (unsigned i = 0; i < AnalysesList.size(); ++i) {
|
||||
const PassInfo *Analysis = AnalysesList[i];
|
||||
|
||||
if (Analysis->getNormalCtor()) {
|
||||
Pass *P = Analysis->getNormalCtor()();
|
||||
Passes.add(P);
|
||||
|
||||
if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P))
|
||||
Passes.add(new BasicBlockPassPrinter(Analysis));
|
||||
else if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P))
|
||||
Passes.add(new FunctionPassPrinter(Analysis));
|
||||
else
|
||||
Passes.add(new ModulePassPrinter(Analysis));
|
||||
|
||||
} else
|
||||
std::cerr << argv[0] << ": cannot create pass: "
|
||||
<< Analysis->getPassName() << "\n";
|
||||
}
|
||||
|
||||
Passes.run(*CurMod);
|
||||
|
||||
delete CurMod;
|
||||
return 0;
|
||||
|
||||
} catch (const std::string& msg) {
|
||||
std::cerr << argv[0] << ": " << msg << "\n";
|
||||
} catch (...) {
|
||||
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
@ -10,9 +10,9 @@ LEVEL = ../..
|
||||
TOOLNAME = opt
|
||||
REQUIRES_EH := 1
|
||||
|
||||
USEDLIBS = LLVMBCReader.a LLVMBCWriter.a LLVMInstrumentation.a \
|
||||
LLVMScalarOpts.a LLVMipo.a LLVMipa.a LLVMDataStructure LLVMTransforms.a \
|
||||
LLVMTarget.a LLVMTransformUtils.a LLVMAnalysis.a LLVMCore.a LLVMSupport.a \
|
||||
LLVMbzip2.a LLVMSystem.a
|
||||
USEDLIBS = LLVMAsmParser.a LLVMBCReader.a LLVMBCWriter.a LLVMInstrumentation.a \
|
||||
LLVMScalarOpts.a LLVMipo.a LLVMipa.a LLVMDataStructure \
|
||||
LLVMTransforms.a LLVMTarget.a LLVMTransformUtils.a LLVMAnalysis.a \
|
||||
LLVMCore.a LLVMSupport.a LLVMbzip2.a LLVMSystem.a
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -8,11 +8,12 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Optimizations may be specified an arbitrary number of times on the command
|
||||
// line, they are run in the order specified.
|
||||
// line, They are run in the order specified.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Bytecode/Reader.h"
|
||||
#include "llvm/Bytecode/WriteBytecodePass.h"
|
||||
@ -24,6 +25,8 @@
|
||||
#include "llvm/System/Signals.h"
|
||||
#include "llvm/Support/PluginLoader.h"
|
||||
#include "llvm/Support/SystemUtils.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/Analysis/LinkAllAnalyses.h"
|
||||
#include "llvm/Transforms/LinkAllPasses.h"
|
||||
#include "llvm/LinkAllVMCore.h"
|
||||
#include <fstream>
|
||||
@ -43,7 +46,8 @@ OptimizationList(cl::desc("Optimizations available:"));
|
||||
// Other command line options...
|
||||
//
|
||||
static cl::opt<std::string>
|
||||
InputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-"));
|
||||
InputFilename(cl::Positional, cl::desc("<input bytecode file>"),
|
||||
cl::init("-"), cl::value_desc("filename"));
|
||||
|
||||
static cl::opt<std::string>
|
||||
OutputFilename("o", cl::desc("Override output filename"),
|
||||
@ -68,6 +72,91 @@ Quiet("q", cl::desc("Obsolete option"), cl::Hidden);
|
||||
static cl::alias
|
||||
QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
|
||||
|
||||
static cl::opt<bool>
|
||||
AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization"));
|
||||
|
||||
// The AnalysesList is automatically populated with registered Passes by the
|
||||
// PassNameParser.
|
||||
static
|
||||
cl::list<const PassInfo*, bool, FilteredPassNameParser<PassInfo::Analysis> >
|
||||
AnalysesList(cl::desc("Analyses available:"));
|
||||
|
||||
static Timer BytecodeLoadTimer("Bytecode Loader");
|
||||
|
||||
// ---------- Define Printers for module and function passes ------------
|
||||
namespace {
|
||||
|
||||
struct ModulePassPrinter : public ModulePass {
|
||||
const PassInfo *PassToPrint;
|
||||
ModulePassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
|
||||
|
||||
virtual bool runOnModule(Module &M) {
|
||||
if (!Quiet) {
|
||||
std::cout << "Printing analysis '" << PassToPrint->getPassName()
|
||||
<< "':\n";
|
||||
getAnalysisID<Pass>(PassToPrint).print(std::cout, &M);
|
||||
}
|
||||
|
||||
// Get and print pass...
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const char *getPassName() const { return "'Pass' Printer"; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredID(PassToPrint);
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
|
||||
struct FunctionPassPrinter : public FunctionPass {
|
||||
const PassInfo *PassToPrint;
|
||||
FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
if (!Quiet) {
|
||||
std::cout << "Printing analysis '" << PassToPrint->getPassName()
|
||||
<< "' for function '" << F.getName() << "':\n";
|
||||
}
|
||||
// Get and print pass...
|
||||
getAnalysisID<Pass>(PassToPrint).print(std::cout, F.getParent());
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const char *getPassName() const { return "FunctionPass Printer"; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredID(PassToPrint);
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
|
||||
struct BasicBlockPassPrinter : public BasicBlockPass {
|
||||
const PassInfo *PassToPrint;
|
||||
BasicBlockPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
|
||||
|
||||
virtual bool runOnBasicBlock(BasicBlock &BB) {
|
||||
if (!Quiet) {
|
||||
std::cout << "Printing Analysis info for BasicBlock '" << BB.getName()
|
||||
<< "': Pass " << PassToPrint->getPassName() << ":\n";
|
||||
}
|
||||
|
||||
// Get and print pass...
|
||||
getAnalysisID<Pass>(PassToPrint).print(
|
||||
std::cout, BB.getParent()->getParent());
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const char *getPassName() const { return "BasicBlockPass Printer"; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequiredID(PassToPrint);
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// main for opt
|
||||
@ -75,9 +164,63 @@ QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
|
||||
int main(int argc, char **argv) {
|
||||
try {
|
||||
cl::ParseCommandLineOptions(argc, argv,
|
||||
" llvm .bc -> .bc modular optimizer\n");
|
||||
" llvm .bc -> .bc modular optimizer and analysis printer \n");
|
||||
sys::PrintStackTraceOnErrorSignal();
|
||||
|
||||
if (AnalyzeOnly) {
|
||||
Module *CurMod = 0;
|
||||
try {
|
||||
#if 0
|
||||
TimeRegion RegionTimer(BytecodeLoadTimer);
|
||||
#endif
|
||||
CurMod = ParseBytecodeFile(InputFilename);
|
||||
if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
|
||||
std::cerr << argv[0] << ": input file didn't read correctly.\n";
|
||||
return 1;
|
||||
}
|
||||
} catch (const ParseException &E) {
|
||||
std::cerr << argv[0] << ": " << E.getMessage() << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create a PassManager to hold and optimize the collection of passes we
|
||||
// are about to build...
|
||||
PassManager Passes;
|
||||
|
||||
// Add an appropriate TargetData instance for this module...
|
||||
Passes.add(new TargetData(CurMod));
|
||||
|
||||
// Make sure the input LLVM is well formed.
|
||||
if (!NoVerify)
|
||||
Passes.add(createVerifierPass());
|
||||
|
||||
// Create a new optimization pass for each one specified on the
|
||||
// command line
|
||||
for (unsigned i = 0; i < AnalysesList.size(); ++i) {
|
||||
const PassInfo *Analysis = AnalysesList[i];
|
||||
|
||||
if (Analysis->getNormalCtor()) {
|
||||
Pass *P = Analysis->getNormalCtor()();
|
||||
Passes.add(P);
|
||||
|
||||
if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P))
|
||||
Passes.add(new BasicBlockPassPrinter(Analysis));
|
||||
else if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P))
|
||||
Passes.add(new FunctionPassPrinter(Analysis));
|
||||
else
|
||||
Passes.add(new ModulePassPrinter(Analysis));
|
||||
|
||||
} else
|
||||
std::cerr << argv[0] << ": cannot create pass: "
|
||||
<< Analysis->getPassName() << "\n";
|
||||
}
|
||||
|
||||
Passes.run(*CurMod);
|
||||
|
||||
delete CurMod;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate a full target machine description only if necessary...
|
||||
// FIXME: The choice of target should be controllable on the command line.
|
||||
std::auto_ptr<TargetMachine> target;
|
||||
@ -169,6 +312,7 @@ int main(int argc, char **argv) {
|
||||
Passes.run(*M.get());
|
||||
|
||||
return 0;
|
||||
|
||||
} catch (const std::string& msg) {
|
||||
std::cerr << argv[0] << ": " << msg << "\n";
|
||||
} catch (...) {
|
||||
|
Loading…
Reference in New Issue
Block a user