aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetJITInfo.h5
-rw-r--r--include/llvm/Target/TargetMachine.h102
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp10
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp56
-rw-r--r--lib/Target/ARM/ARMTargetMachine.h9
-rw-r--r--lib/Target/Alpha/AlphaJITInfo.h6
-rw-r--r--lib/Target/Alpha/AlphaTargetMachine.cpp93
-rw-r--r--lib/Target/Alpha/AlphaTargetMachine.h18
-rw-r--r--lib/Target/CBackend/CBackend.cpp6
-rw-r--r--lib/Target/CBackend/CTargetMachine.h8
-rw-r--r--lib/Target/CBackend/Writer.cpp6
-rw-r--r--lib/Target/IA64/IA64TargetMachine.cpp84
-rw-r--r--lib/Target/IA64/IA64TargetMachine.h15
-rw-r--r--lib/Target/PowerPC/PPC.h10
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.h6
-rw-r--r--lib/Target/PowerPC/PPCMachOWriter.cpp2
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp119
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.h16
-rw-r--r--lib/Target/Sparc/SparcTargetMachine.cpp61
-rw-r--r--lib/Target/Sparc/SparcTargetMachine.h11
-rw-r--r--lib/Target/X86/X86.h4
-rw-r--r--lib/Target/X86/X86ELFWriter.cpp2
-rw-r--r--lib/Target/X86/X86JITInfo.h6
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp132
-rw-r--r--lib/Target/X86/X86TargetMachine.h20
-rw-r--r--tools/llc/llc.cpp189
26 files changed, 380 insertions, 616 deletions
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
index b7fd2d4c39..b80b0558f1 100644
--- a/include/llvm/Target/TargetJITInfo.h
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -33,11 +33,6 @@ namespace llvm {
public:
virtual ~TargetJITInfo() {}
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast code generator for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM) = 0;
-
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
/// overwriting OLD with a branch to NEW. This is used for self-modifying
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 855938646e..2a41d5ec3d 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file describes the general parts of a Target machine.
+// This file defines the TargetMachine and LLVMTargetMachine classes.
//
//===----------------------------------------------------------------------===//
@@ -62,8 +62,8 @@ namespace CodeModel {
/// through this interface.
///
class TargetMachine {
- TargetMachine(const TargetMachine&); // DO NOT IMPLEMENT
- void operator=(const TargetMachine&); // DO NOT IMPLEMENT
+ TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT
+ void operator=(const TargetMachine &); // DO NOT IMPLEMENT
protected: // Can only create subclasses.
TargetMachine() { }
@@ -151,19 +151,109 @@ public:
/// code as fast as possible, without regard for compile time. This method
/// should return true if emission of this file type is not supported.
///
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
+ virtual bool addPassesToEmitFile(FunctionPassManager &PM, std::ostream &Out,
CodeGenFileType FileType, bool Fast) {
return true;
}
+
+ /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+ /// get machine code emitted. This uses a MachineCodeEmitter object to handle
+ /// actually outputting the machine code and resolving things like the address
+ /// of functions. This method returns true if machine code emission is
+ /// not supported.
+ ///
+ virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
+ MachineCodeEmitter &MCE, bool Fast) {
+ return true;
+ }
+
+ /// addPassesToEmitWholeFile - This method can be implemented by targets that
+ /// require having the entire module at once. This is not recommended, do not
+ /// use this.
+ virtual bool WantsWholeFile() const { return false; }
+ virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
+ CodeGenFileType FileType, bool Fast) {
+ return true;
+ }
+};
+
+/// LLVMTargetMachine - This class describes a target machine that is
+/// implemented with the LLVM target-independent code generator.
+///
+class LLVMTargetMachine : public TargetMachine {
+protected: // Can only create subclasses.
+ LLVMTargetMachine() { }
+public:
+
+ /// addPassesToEmitFile - Add passes to the specified pass manager to get
+ /// the specified file emitted. Typically this will involve several steps of
+ /// code generation. If Fast is set to true, the code generator should emit
+ /// code as fast as possible, without regard for compile time. This method
+ /// should return true if emission of this file type is not supported.
+ ///
+ /// The default implementation of this method adds components from the
+ /// LLVM retargetable code generator, invoking the methods below to get
+ /// target-specific passes in standard locations.
+ ///
+ virtual bool addPassesToEmitFile(FunctionPassManager &PM, std::ostream &Out,
+ CodeGenFileType FileType, bool Fast);
+
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted. This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
- /// of functions. This method should returns true if machine code emission is
+ /// of functions. This method returns true if machine code emission is
/// not supported.
///
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
+ MachineCodeEmitter &MCE, bool Fast);
+
+ /// Target-Independent Code Generator Pass Configuration Options.
+
+ /// addInstSelector - This method should add any "last minute" LLVM->LLVM
+ /// passes, then install an instruction selector pass, which converts from
+ /// LLVM code to machine instructions.
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast) {
+ return true;
+ }
+
+ /// addPostRegAllocPasses - This method may be implemented by targets that
+ /// want to run passes after register allocation but before prolog-epilog
+ /// insertion. This should return true if -print-machineinstrs should print
+ /// after these passes.
+ virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
+ return false;
+ }
+
+ /// addPreEmitPass - This pass may be implemented by targets that want to run
+ /// passes immediately before machine code is emitted. This should return
+ /// true if -print-machineinstrs should print out the code after the passes.
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast) {
+ return false;
+ }
+
+
+ /// addAssemblyEmitter - This pass should be overridden by the target to add
+ /// the asmprinter, if asm emission is supported. If this is not supported,
+ /// 'true' should be returned.
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ return true;
+ }
+
+ /// addObjectWriter - This pass should be overridden by the target to add
+ /// the object-file writer, if supported. If this is not supported,
+ /// 'true' should be returned.
+ virtual bool addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ return true;
+ }
+
+ /// addCodeEmitter - This pass should be overridden by the target to add a
+ /// code emitter, if supported. If this is not supported, 'true' should be
+ /// returned.
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
return true;
}
};
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index fe5309558c..0a5423ef9d 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -58,18 +58,18 @@ JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji)
// Add target data
MutexGuard locked(lock);
- FunctionPassManager& PM = state.getPM(locked);
+ FunctionPassManager &PM = state.getPM(locked);
PM.add(new TargetData(*TM.getTargetData()));
- // Compile LLVM Code down to machine code in the intermediate representation
- TJI.addPassesToJITCompile(PM);
-
// Turn the machine code intermediate representation into bytes in memory that
// may be executed.
- if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
+ if (TM.addPassesToEmitMachineCode(PM, *MCE, false /*fast*/)) {
std::cerr << "Target does not support machine code emission!\n";
abort();
}
+
+ // Initialize passes.
+ PM.doInitialization();
}
JIT::~JIT() {
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index fe053c5605..175335f5c1 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -14,15 +14,9 @@
#include "ARMTargetMachine.h"
#include "ARMFrameInfo.h"
#include "ARM.h"
-#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include <iostream>
using namespace llvm;
namespace {
@@ -47,54 +41,16 @@ unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
return 0;
}
-/// addPassesToEmitFile - Add passes to the specified pass manager
-/// to implement a static compiler for this target.
-///
-bool ARMTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile)
- return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast)
- PM.add(createLoopStrengthReducePass());
-
- if (!Fast)
- PM.add(createCFGSimplificationPass());
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Print LLVM code input to instruction selector:
- if (PrintMachineCode)
- PM.add(new PrintFunctionPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+// Pass Pipeline Configuration
+bool ARMTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createARMISelDag(*this));
-
- // Print machine instructions as they were initially generated.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Print machine instructions after register allocation and prolog/epilog
- // insertion.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+ return false;
+}
+bool ARMTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
// Output assembly language.
PM.add(createARMCodePrinterPass(Out, *this));
-
- // Delete the MachineInstrs we generated, since they're no longer needed.
- PM.add(createMachineCodeDeleter());
return false;
}
diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h
index 400ea0c7be..f09b92b8f3 100644
--- a/lib/Target/ARM/ARMTargetMachine.h
+++ b/lib/Target/ARM/ARMTargetMachine.h
@@ -18,7 +18,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "ARMInstrInfo.h"
#include "ARMFrameInfo.h"
@@ -26,7 +25,7 @@ namespace llvm {
class Module;
-class ARMTargetMachine : public TargetMachine {
+class ARMTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
ARMInstrInfo InstrInfo;
ARMFrameInfo FrameInfo;
@@ -41,8 +40,10 @@ public:
virtual const TargetData *getTargetData() const { return &DataLayout; }
static unsigned getModuleMatchQuality(const Module &M);
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
};
} // end namespace llvm
diff --git a/lib/Target/Alpha/AlphaJITInfo.h b/lib/Target/Alpha/AlphaJITInfo.h
index 7d1416ecf6..26c45b1256 100644
--- a/lib/Target/Alpha/AlphaJITInfo.h
+++ b/lib/Target/Alpha/AlphaJITInfo.h
@@ -29,12 +29,6 @@ namespace llvm {
AlphaJITInfo(TargetMachine &tm) : TM(tm)
{ useGOT = true; }
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast dynamic compiler for this target. Return true if this
- /// is not supported for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM);
-
virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
virtual void relocate(void *Function, MachineRelocation *MR,
diff --git a/lib/Target/Alpha/AlphaTargetMachine.cpp b/lib/Target/Alpha/AlphaTargetMachine.cpp
index 2d7e467815..9c9f52dcf1 100644
--- a/lib/Target/Alpha/AlphaTargetMachine.cpp
+++ b/lib/Target/Alpha/AlphaTargetMachine.cpp
@@ -14,12 +14,8 @@
#include "AlphaJITInfo.h"
#include "AlphaTargetMachine.h"
#include "llvm/Module.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
+#include "llvm/PassManager.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/Debug.h"
-#include <iostream>
using namespace llvm;
@@ -57,89 +53,30 @@ AlphaTargetMachine::AlphaTargetMachine(const Module &M, const std::string &FS)
: DataLayout("e"),
FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
JITInfo(*this),
- Subtarget(M, FS)
-{
- DEBUG(std::cerr << "FS is " << FS << "\n");
+ Subtarget(M, FS) {
}
-/// addPassesToEmitFile - Add passes to the specified pass manager to implement
-/// a static compiler for this target.
-///
-bool AlphaTargetMachine::addPassesToEmitFile(PassManager &PM,
- std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile) return true;
- PM.add(createLoopStrengthReducePass());
- PM.add(createCFGSimplificationPass());
-
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
+bool AlphaTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createAlphaISelDag(*this));
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createPrologEpilogCodeInserter());
-
- // Must run branch selection immediately preceding the asm printer
- //PM.add(createAlphaBranchSelectionPass());
-
- PM.add(createAlphaCodePrinterPass(Out, *this));
-
- PM.add(createMachineCodeDeleter());
return false;
}
-
-void AlphaJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
-
- PM.add(createLoopStrengthReducePass());
- PM.add(createCFGSimplificationPass());
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- PM.add(createAlphaISelDag(TM));
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createPrologEpilogCodeInserter());
-
+bool AlphaTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
// Must run branch selection immediately preceding the asm printer
//PM.add(createAlphaBranchSelectionPass());
-
+ return false;
}
-
-bool AlphaTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
+bool AlphaTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createAlphaCodePrinterPass(Out, *this));
+ return false;
+}
+bool AlphaTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
PM.add(createAlphaCodeEmitterPass(*this, MCE));
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
return false;
}
diff --git a/lib/Target/Alpha/AlphaTargetMachine.h b/lib/Target/Alpha/AlphaTargetMachine.h
index 413a99464a..d71c7cec72 100644
--- a/lib/Target/Alpha/AlphaTargetMachine.h
+++ b/lib/Target/Alpha/AlphaTargetMachine.h
@@ -17,7 +17,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "AlphaInstrInfo.h"
#include "AlphaJITInfo.h"
#include "AlphaSubtarget.h"
@@ -26,7 +25,7 @@ namespace llvm {
class GlobalValue;
-class AlphaTargetMachine : public TargetMachine {
+class AlphaTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
AlphaInstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
@@ -48,14 +47,15 @@ public:
}
static unsigned getJITMatchQuality();
-
- virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE);
-
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
-
static unsigned getModuleMatchQuality(const Module &M);
+
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE);
};
} // end namespace llvm
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index cbd13601a3..c50b5a40e9 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -2027,8 +2027,10 @@ void CWriter::visitVAArgInst(VAArgInst &I) {
// External Interface declaration
//===----------------------------------------------------------------------===//
-bool CTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o,
- CodeGenFileType FileType, bool Fast) {
+bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
+ std::ostream &o,
+ CodeGenFileType FileType,
+ bool Fast) {
if (FileType != TargetMachine::AssemblyFile) return true;
PM.add(createLowerGCPass());
diff --git a/lib/Target/CBackend/CTargetMachine.h b/lib/Target/CBackend/CTargetMachine.h
index 1dde6fe236..38c738ebc3 100644
--- a/lib/Target/CBackend/CTargetMachine.h
+++ b/lib/Target/CBackend/CTargetMachine.h
@@ -25,14 +25,14 @@ struct CTargetMachine : public TargetMachine {
CTargetMachine(const Module &M, const std::string &FS)
: DataLayout(&M) {}
- // This is the only thing that actually does anything here.
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
+ virtual bool WantsWholeFile() const { return true; }
+ virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
+ CodeGenFileType FileType, bool Fast);
// This class always works, but shouldn't be the default in most cases.
static unsigned getModuleMatchQuality(const Module &M) { return 1; }
- virtual const TargetData *getTargetData() const { return &DataLayout; }
+ virtual const TargetData *getTargetData() const { return &DataLayout; }
};
} // End llvm namespace
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index cbd13601a3..c50b5a40e9 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -2027,8 +2027,10 @@ void CWriter::visitVAArgInst(VAArgInst &I) {
// External Interface declaration
//===----------------------------------------------------------------------===//
-bool CTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o,
- CodeGenFileType FileType, bool Fast) {
+bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
+ std::ostream &o,
+ CodeGenFileType FileType,
+ bool Fast) {
if (FileType != TargetMachine::AssemblyFile) return true;
PM.add(createLowerGCPass());
diff --git a/lib/Target/IA64/IA64TargetMachine.cpp b/lib/Target/IA64/IA64TargetMachine.cpp
index c512ce6781..0f7821f5af 100644
--- a/lib/Target/IA64/IA64TargetMachine.cpp
+++ b/lib/Target/IA64/IA64TargetMachine.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the IA64 specific subclass of TargetMachine.
+// This file implements the IA64 specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
@@ -15,14 +15,7 @@
#include "IA64.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/Statistic.h"
-#include <iostream>
using namespace llvm;
/// IA64TargetMachineModule - Note that this is used on hosts that cannot link
@@ -33,14 +26,6 @@ extern "C" int IA64TargetMachineModule;
int IA64TargetMachineModule = 0;
namespace {
- cl::opt<bool> DisableOutput("disable-ia64-llc-output", cl::Hidden,
- cl::desc("Disable the IA64 asm printer, for use "
- "when profiling the code generator."));
-
- cl::opt<bool> EnableDAGIsel("enable-ia64-dag-isel", cl::Hidden,
- cl::desc("Enable the IA64 DAG->DAG isel"));
-
- // Register the target.
RegisterTarget<IA64TargetMachine> X("ia64", " IA-64 (Itanium)");
}
@@ -76,65 +61,24 @@ IA64TargetMachine::IA64TargetMachine(const Module &M, const std::string &FS)
TLInfo(*this) { // FIXME? check this stuff
}
-// addPassesToEmitFile - We currently use all of the same passes as the JIT
-// does to emit statically compiled machine code.
-bool IA64TargetMachine::addPassesToEmitFile(PassManager &PM,
- std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile) return true;
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass(704, 16)); // on ia64 linux, jmpbufs are 704
- // bytes and must be 16byte aligned
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
- // Add an instruction selector
-// FIXME: reap this option one day: if(EnableDAGIsel)
+bool IA64TargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createIA64DAGToDAGInstructionSelector(*this));
-
-/* XXX not yet. ;)
- // Run optional SSA-based machine code optimizations next...
- if (!NoSSAPeephole)
- PM.add(createIA64SSAPeepholeOptimizerPass());
-*/
-
- // Print the instruction selected machine code...
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Perform register allocation to convert to a concrete IA64 representation
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- PM.add(createPrologEpilogCodeInserter());
-
-/* XXX no, not just yet */
-// PM.add(createIA64PeepholeOptimizerPass());
+ return false;
+}
+bool IA64TargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
// Make sure everything is bundled happily
PM.add(createIA64BundlingPass(*this));
-
- if (PrintMachineCode) // Print the register-allocated code
- PM.add(createIA64CodePrinterPass(std::cerr, *this));
-
- if (!DisableOutput)
- PM.add(createIA64CodePrinterPass(Out, *this));
-
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
-
- return false; // success!
+ return true;
+}
+bool IA64TargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createIA64CodePrinterPass(Out, *this));
+ return false;
}
diff --git a/lib/Target/IA64/IA64TargetMachine.h b/lib/Target/IA64/IA64TargetMachine.h
index 267d354117..5a4b6b6995 100644
--- a/lib/Target/IA64/IA64TargetMachine.h
+++ b/lib/Target/IA64/IA64TargetMachine.h
@@ -11,19 +11,18 @@
//
//===----------------------------------------------------------------------===//
-#ifndef IA64TARGETMACHINE_H
-#define IA64TARGETMACHINE_H
+#ifndef LLVM_TARGET_IA64TARGETMACHINE_H
+#define LLVM_TARGET_IA64TARGETMACHINE_H
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "IA64InstrInfo.h"
#include "IA64ISelLowering.h"
namespace llvm {
-class IA64TargetMachine : public TargetMachine {
+class IA64TargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
IA64InstrInfo InstrInfo;
TargetFrameInfo FrameInfo;
@@ -42,11 +41,13 @@ public:
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
-
static unsigned getModuleMatchQuality(const Module &M);
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
};
} // End llvm namespace
diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h
index f34b9b08a0..26439bd094 100644
--- a/lib/Target/PowerPC/PPC.h
+++ b/lib/Target/PowerPC/PPC.h
@@ -1,4 +1,4 @@
-//===-- PowerPC.h - Top-level interface for PowerPC representation -*- C++ -*-//
+//===-- PPC.h - Top-level interface for PowerPC Target ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,15 +12,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef TARGET_POWERPC_H
-#define TARGET_POWERPC_H
+#ifndef LLVM_TARGET_POWERPC_H
+#define LLVM_TARGET_POWERPC_H
#include <iosfwd>
namespace llvm {
class PPCTargetMachine;
-class PassManager;
+class FunctionPassManager;
class FunctionPass;
class MachineCodeEmitter;
@@ -29,7 +29,7 @@ FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, PPCTargetMachine &TM);
FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM,
MachineCodeEmitter &MCE);
-void addPPCMachOObjectWriterPass(PassManager &FPM, std::ostream &o,
+void addPPCMachOObjectWriterPass(FunctionPassManager &FPM, std::ostream &o,
PPCTargetMachine &tm);
} // end namespace llvm;
diff --git a/lib/Target/PowerPC/PPCJITInfo.h b/lib/Target/PowerPC/PPCJITInfo.h
index 61ec4691cb..66ee0eef30 100644
--- a/lib/Target/PowerPC/PPCJITInfo.h
+++ b/lib/Target/PowerPC/PPCJITInfo.h
@@ -29,12 +29,6 @@ namespace llvm {
is64Bit = tmIs64Bit;
}
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast dynamic compiler for this target. Return true if this
- /// is not supported for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM);
-
virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
virtual void relocate(void *Function, MachineRelocation *MR,
diff --git a/lib/Target/PowerPC/PPCMachOWriter.cpp b/lib/Target/PowerPC/PPCMachOWriter.cpp
index 308e8b7775..a7da37127d 100644
--- a/lib/Target/PowerPC/PPCMachOWriter.cpp
+++ b/lib/Target/PowerPC/PPCMachOWriter.cpp
@@ -33,7 +33,7 @@ namespace {
/// addPPCMachOObjectWriterPass - Returns a pass that outputs the generated code
/// as a Mach-O object file.
///
-void llvm::addPPCMachOObjectWriterPass(PassManager &FPM,
+void llvm::addPPCMachOObjectWriterPass(FunctionPassManager &FPM,
std::ostream &O, PPCTargetMachine &TM) {
PPCMachOWriter *EW = new PPCMachOWriter(O, TM);
FPM.add(EW);
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index 811e18992d..2e2fd28587 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -12,19 +12,10 @@
//===----------------------------------------------------------------------===//
#include "PPC.h"
-#include "PPCFrameInfo.h"
#include "PPCTargetMachine.h"
-#include "PPCJITInfo.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/CommandLine.h"
-#include <iostream>
using namespace llvm;
namespace {
@@ -106,99 +97,47 @@ PPC64TargetMachine::PPC64TargetMachine(const Module &M, const std::string &FS)
: PPCTargetMachine(M, FS, true) {
}
-/// addPassesToEmitFile - Add passes to the specified pass manager to implement
-/// a static compiler for this target.
-///
-bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile &&
- FileType != TargetMachine::ObjectFile) return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast) PM.add(createLoopStrengthReducePass(&TLInfo));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Clean up after other passes, e.g. merging critical edges.
- if (!Fast) PM.add(createCFGSimplificationPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
+bool PPCTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
// Install an instruction selector.
PM.add(createPPCISelDag(*this));
+ return false;
+}
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createPrologEpilogCodeInserter());
-
- // Must run branch selection immediately preceding the asm printer
+bool PPCTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
+
+ // Must run branch selection immediately preceding the asm printer.
PM.add(createPPCBranchSelectionPass());
-
- if (FileType == TargetMachine::AssemblyFile)
- PM.add(createDarwinAsmPrinter(Out, *this));
- else
- // FIXME: support PPC ELF files at some point
- addPPCMachOObjectWriterPass(PM, Out, *this);
-
- PM.add(createMachineCodeDeleter());
return false;
}
-void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
- // The JIT should use the static relocation model.
- TM.setRelocationModel(Reloc::Static);
-
- // Run loop strength reduction before anything else.
- PM.add(createLoopStrengthReducePass(TM.getTargetLowering()));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Clean up after other passes, e.g. merging critical edges.
- PM.add(createCFGSimplificationPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- // Install an instruction selector.
- PM.add(createPPCISelDag(TM));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Must run branch selection immediately preceding the asm printer
- PM.add(createPPCBranchSelectionPass());
+bool PPCTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createDarwinAsmPrinter(Out, *this));
+ return false;
+}
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
+bool PPCTargetMachine::addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ // FIXME: support PPC ELF files at some point
+ addPPCMachOObjectWriterPass(PM, Out, *this);
+ return true;
}
-/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
-/// machine code emitted. This uses a MachineCodeEmitter object to handle
-/// actually outputting the machine code and resolving things like the address
-/// of functions. This method should returns true if machine code emission is
-/// not supported.
-///
-bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
- // Machine code emitter pass for PowerPC
+bool PPCTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
+ // The JIT should use the static relocation model.
+ // FIXME: This should be moved to TargetJITInfo!!
+ setRelocationModel(Reloc::Static);
+
+
+
+ // Machine code emitter pass for PowerPC.
PM.add(createPPCCodeEmitterPass(*this, MCE));
- // Delete machine code for this function after emitting it
- PM.add(createMachineCodeDeleter());
return false;
}
+
diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h
index 266ef18044..9a77a4fcb8 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -28,7 +28,7 @@ class GlobalValue;
/// PPCTargetMachine - Common code between 32-bit and 64-bit PowerPC targets.
///
-class PPCTargetMachine : public TargetMachine {
+class PPCTargetMachine : public LLVMTargetMachine {
PPCSubtarget Subtarget;
const TargetData DataLayout; // Calculates type size & alignment
PPCInstrInfo InstrInfo;
@@ -55,12 +55,16 @@ public:
return InstrItins;
}
-
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
- bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE);
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE);
};
/// PPC32TargetMachine - PowerPC 32-bit target machine.
diff --git a/lib/Target/Sparc/SparcTargetMachine.cpp b/lib/Target/Sparc/SparcTargetMachine.cpp
index 324fcc3dc9..477e954414 100644
--- a/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -12,14 +12,9 @@
#include "SparcTargetMachine.h"
#include "Sparc.h"
-#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
-#include "llvm/Transforms/Scalar.h"
#include <iostream>
using namespace llvm;
@@ -55,57 +50,23 @@ unsigned SparcTargetMachine::getModuleMatchQuality(const Module &M) {
return 0;
}
-/// addPassesToEmitFile - Add passes to the specified pass manager
-/// to implement a static compiler for this target.
-///
-bool SparcTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile) return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast) PM.add(createLoopStrengthReducePass());
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Print LLVM code input to instruction selector:
- if (PrintMachineCode)
- PM.add(new PrintFunctionPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
+bool SparcTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
PM.add(createSparcISelDag(*this));
+ return false;
+}
- // Print machine instructions as they were initially generated.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createRegisterAllocator());
- PM.add(createPrologEpilogCodeInserter());
-
- // Print machine instructions after register allocation and prolog/epilog
- // insertion.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+/// addPreEmitPass - This pass may be implemented by targets that want to run
+/// passes immediately before machine code is emitted. This should return
+/// true if -print-machineinstrs should print out the code after the passes.
+bool SparcTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
PM.add(createSparcFPMoverPass(*this));
-
PM.add(createSparcDelaySlotFillerPass(*this));
+ return true;
+}
- // Print machine instructions after filling delay slots.
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+bool SparcTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
// Output assembly language.
PM.add(createSparcCodePrinterPass(Out, *this));
-
- // Delete the MachineInstrs we generated, since they're no longer needed.
- PM.add(createMachineCodeDeleter());
return false;
}
-
diff --git a/lib/Target/Sparc/SparcTargetMachine.h b/lib/Target/Sparc/SparcTargetMachine.h
index c2988fbf4b..e377afa085 100644
--- a/lib/Target/Sparc/SparcTargetMachine.h
+++ b/lib/Target/Sparc/SparcTargetMachine.h
@@ -17,7 +17,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "SparcInstrInfo.h"
#include "SparcSubtarget.h"
@@ -25,7 +24,7 @@ namespace llvm {
class Module;
-class SparcTargetMachine : public TargetMachine {
+class SparcTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
SparcSubtarget Subtarget;
SparcInstrInfo InstrInfo;
@@ -42,8 +41,12 @@ public:
virtual const TargetData *getTargetData() const { return &DataLayout; }
static unsigned getModuleMatchQuality(const Module &M);
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
+
+ // Pass Pipeline Configuration
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
};
} // end namespace llvm
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index 11a63868d9..5a16cd92e8 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -20,7 +20,7 @@
namespace llvm {
class X86TargetMachine;
-class PassManager;
+class FunctionPassManager;
class FunctionPass;
class IntrinsicLowering;
class MachineCodeEmitter;
@@ -50,7 +50,7 @@ FunctionPass *createX86CodeEmitterPass(X86TargetMachine &TM,
/// addX86ELFObjectWriterPass - Add passes to the FPM that output the generated
/// code as an ELF object file.
///
-void addX86ELFObjectWriterPass(PassManager &FPM,
+void addX86ELFObjectWriterPass(FunctionPassManager &FPM,
std::ostream &o, X86TargetMachine &tm);
/// createX86EmitCodeToMemory - Returns a pass that converts a register
diff --git a/lib/Target/X86/X86ELFWriter.cpp b/lib/Target/X86/X86ELFWriter.cpp
index 5bd22a0aa9..eb7392ab79 100644
--- a/lib/Target/X86/X86ELFWriter.cpp
+++ b/lib/Target/X86/X86ELFWriter.cpp
@@ -31,7 +31,7 @@ namespace {
/// addX86ELFObjectWriterPass - Returns a pass that outputs the generated code
/// as an ELF object file.
///
-void llvm::addX86ELFObjectWriterPass(PassManager &FPM,
+void llvm::addX86ELFObjectWriterPass(FunctionPassManager &FPM,
std::ostream &O, X86TargetMachine &TM) {
X86ELFWriter *EW = new X86ELFWriter(O, TM);
FPM.add(EW);
diff --git a/lib/Target/X86/X86JITInfo.h b/lib/Target/X86/X86JITInfo.h
index 02e54af11a..481b2328b0 100644
--- a/lib/Target/X86/X86JITInfo.h
+++ b/lib/Target/X86/X86JITInfo.h
@@ -25,12 +25,6 @@ namespace llvm {
public:
X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;}
- /// addPassesToJITCompile - Add passes to the specified pass manager to
- /// implement a fast dynamic compiler for this target. Return true if this
- /// is not supported for this target.
- ///
- virtual void addPassesToJITCompile(FunctionPassManager &PM);
-
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
/// overwriting OLD with a branch to NEW. This is used for self-modifying
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index d12e9642ff..83af172c7f 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -20,8 +20,6 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Transforms/Scalar.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/Statistic.h"
#include <iostream>
using namespace llvm;
@@ -33,9 +31,6 @@ extern "C" int X86TargetMachineModule;
int X86TargetMachineModule = 0;
namespace {
- cl::opt<bool> DisableOutput("disable-x86-llc-output", cl::Hidden,
- cl::desc("Disable the X86 asm printer, for use "
- "when profiling the code generator."));
// Register the target.
RegisterTarget<X86TargetMachine> X("x86", " IA-32 (Pentium and above)");
}
@@ -79,121 +74,38 @@ X86TargetMachine::X86TargetMachine(const Module &M, const std::string &FS)
setRelocationModel(Reloc::PIC_);
}
+//===----------------------------------------------------------------------===//
+// Pass Pipeline Configuration
+//===----------------------------------------------------------------------===//
-// addPassesToEmitFile - We currently use all of the same passes as the JIT
-// does to emit statically compiled machine code.
-bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType,
- bool Fast) {
- if (FileType != TargetMachine::AssemblyFile &&
- FileType != TargetMachine::ObjectFile) return true;
-
- // Run loop strength reduction before anything else.
- if (!Fast) PM.add(createLoopStrengthReducePass(&TLInfo));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
+bool X86TargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
// Install an instruction selector.
PM.add(createX86ISelDag(*this, Fast));
-
- // Print the instruction selected machine code...
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Perform register allocation to convert to a concrete x86 representation
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- PM.add(createX86FloatingPointStackifierPass());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- PM.add(createPrologEpilogCodeInserter());
-
- if (PrintMachineCode) // Print the register-allocated code
- PM.add(createX86CodePrinterPass(std::cerr, *this));
-
- if (!DisableOutput)
- switch (FileType) {
- default:
- assert(0 && "Unexpected filetype here!");
- case TargetMachine::AssemblyFile:
- PM.add(createX86CodePrinterPass(Out, *this));
- break;
- case TargetMachine::ObjectFile:
- // FIXME: We only support emission of ELF files for now, this should check
- // the target triple and decide on the format to write (e.g. COFF on
- // win32 or Mach-O on darwin).
- addX86ELFObjectWriterPass(PM, Out, *this);
- break;
- }
-
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
-
- return false; // success!
+ return false;
}
-/// addPassesToJITCompile - Add passes to the specified pass manager to
-/// implement a fast dynamic compiler for this target. Return true if this is
-/// not supported for this target.
-///
-void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
- // The JIT should use static relocation model.
- TM.setRelocationModel(Reloc::Static);
-
- // Run loop strength reduction before anything else.
- PM.add(createLoopStrengthReducePass(TM.getTargetLowering()));
-
- // FIXME: Implement efficient support for garbage collection intrinsics.
- PM.add(createLowerGCPass());
-
- // FIXME: Implement the invoke/unwind instructions!
- PM.add(createLowerInvokePass());
-
- // Make sure that no unreachable blocks are instruction selected.
- PM.add(createUnreachableBlockEliminationPass());
-
- // Install an instruction selector.
- PM.add(createX86ISelDag(TM, false));
-
- // Print the instruction selected machine code...
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Perform register allocation to convert to a concrete x86 representation
- PM.add(createRegisterAllocator());
-
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
+bool X86TargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
PM.add(createX86FloatingPointStackifierPass());
+ return true; // -print-machineinstr should print after this.
+}
- if (PrintMachineCode)
- PM.add(createMachineFunctionPrinterPass(&std::cerr));
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- PM.add(createPrologEpilogCodeInserter());
+bool X86TargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ PM.add(createX86CodePrinterPass(Out, *this));
+ return false;
+}
- if (PrintMachineCode) // Print the register-allocated code
- PM.add(createX86CodePrinterPass(std::cerr, TM));
+bool X86TargetMachine::addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ if (Subtarget.isTargetELF()) {
+ addX86ELFObjectWriterPass(PM, Out, *this);
+ return false;
+ }
+ return true;
}
-bool X86TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE) {
+bool X86TargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
PM.add(createX86CodeEmitterPass(*this, MCE));
- // Delete machine code for this function
- PM.add(createMachineCodeDeleter());
return false;
}
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
index 8a76b0e89c..9b50c7e408 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -17,7 +17,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/PassManager.h"
#include "X86.h"
#include "X86InstrInfo.h"
#include "X86JITInfo.h"
@@ -26,7 +25,7 @@
namespace llvm {
-class X86TargetMachine : public TargetMachine {
+class X86TargetMachine : public LLVMTargetMachine {
X86Subtarget Subtarget;
const TargetData DataLayout; // Calculates type size & alignment
TargetFrameInfo FrameInfo;
@@ -48,14 +47,19 @@ public:
}
virtual const TargetData *getTargetData() const { return &DataLayout; }
- virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
- MachineCodeEmitter &MCE);
-
- virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
- CodeGenFileType FileType, bool Fast);
-
static unsigned getModuleMatchQuality(const Module &M);
static unsigned getJITMatchQuality();
+
+
+ // Set up the pass pipeline.
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+ virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast);
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addObjectWriter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out);
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE);
};
} // End llvm namespace
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 917c826ef8..cd047924e1 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -101,6 +101,69 @@ GetFileNameRoot(const std::string &InputFilename) {
return outputFilename;
}
+static std::ostream *GetOutputStream(const char *ProgName) {
+ if (OutputFilename != "") {
+ if (OutputFilename == "-")
+ return &std::cout;
+
+ // Specified an output filename?
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << ProgName << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 0;
+ }
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ return new std::ofstream(OutputFilename.c_str());
+ }
+
+ if (InputFilename == "-") {
+ OutputFilename = "-";
+ return &std::cout;
+ }
+
+ OutputFilename = GetFileNameRoot(InputFilename);
+
+ switch (FileType) {
+ case TargetMachine::AssemblyFile:
+ if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
+ OutputFilename += ".s";
+ else
+ OutputFilename += ".cbe.c";
+ break;
+ case TargetMachine::ObjectFile:
+ OutputFilename += ".o";
+ break;
+ case TargetMachine::DynamicLibrary:
+ OutputFilename += LTDL_SHLIB_EXT;
+ break;
+ }
+
+ if (!Force && std::ifstream(OutputFilename.c_str())) {
+ // If force is not specified, make sure not to overwrite a file!
+ std::cerr << ProgName << ": error opening '" << OutputFilename
+ << "': file exists!\n"
+ << "Use -f command line argument to force output\n";
+ return 0;
+ }
+
+ // Make sure that the Out file gets unlinked from the disk if we get a
+ // SIGINT
+ sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+
+ std::ostream *Out = new std::ofstream(OutputFilename.c_str());
+ if (!Out->good()) {
+ std::cerr << ProgName << ": error opening " << OutputFilename << "!\n";
+ delete Out;
+ return 0;
+ }
+
+ return Out;
+}
// main - Entry point for the llc compiler.
//
@@ -148,91 +211,59 @@ int main(int argc, char **argv) {
assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get();
- // Build up all of the passes that we want to do to the module...
- PassManager Passes;
- Passes.add(new TargetData(*Target.getTargetData()));
-
-#ifndef NDEBUG
- if(!NoVerify)
- Passes.add(createVerifierPass());
-#endif
-
// Figure out where we are going to send the output...
- std::ostream *Out = 0;
- if (OutputFilename != "") {
- if (OutputFilename != "-") {
- // Specified an output filename?
- if (!Force && std::ifstream(OutputFilename.c_str())) {
- // If force is not specified, make sure not to overwrite a file!
- std::cerr << argv[0] << ": error opening '" << OutputFilename
- << "': file exists!\n"
- << "Use -f command line argument to force output\n";
- return 1;
- }
- Out = new std::ofstream(OutputFilename.c_str());
-
- // Make sure that the Out file gets unlinked from the disk if we get a
- // SIGINT
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
- } else {
- Out = &std::cout;
+ std::ostream *Out = GetOutputStream(argv[0]);
+ if (Out == 0) return 1;
+
+ // If this target requires addPassesToEmitWholeFile, do it now. This is
+ // used by strange things like the C backend.
+ if (Target.WantsWholeFile()) {
+ PassManager PM;
+ PM.add(new TargetData(*Target.getTargetData()));
+ if (!NoVerify)
+ PM.add(createVerifierPass());
+
+ // Ask the target to add backend passes as necessary.
+ if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) {
+ std::cerr << argv[0] << ": target does not support generation of this"
+ << " file type!\n";
+ if (Out != &std::cout) delete Out;
+ // And the Out file is empty and useless, so remove it now.
+ sys::Path(OutputFilename).eraseFromDisk();
+ return 1;
}
+ PM.run(mod);
} else {
- if (InputFilename == "-") {
- OutputFilename = "-";
- Out = &std::cout;
- } else {
- OutputFilename = GetFileNameRoot(InputFilename);
-
- switch (FileType) {
- case TargetMachine::AssemblyFile:
- if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
- OutputFilename += ".s";
- else
- OutputFilename += ".cbe.c";
- break;
- case TargetMachine::ObjectFile:
- OutputFilename += ".o";
- break;
- case TargetMachine::DynamicLibrary:
- OutputFilename += LTDL_SHLIB_EXT;
- break;
- }
-
- if (!Force && std::ifstream(OutputFilename.c_str())) {
- // If force is not specified, make sure not to overwrite a file!
- std::cerr << argv[0] << ": 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()) {
- std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
- delete Out;
- return 1;
- }
-
- // Make sure that the Out file gets unlinked from the disk if we get a
- // SIGINT
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
+ // Build up all of the passes that we want to do to the module.
+ FunctionPassManager Passes(new ExistingModuleProvider(M.get()));
+ Passes.add(new TargetData(*Target.getTargetData()));
+
+#ifndef NDEBUG
+ if (!NoVerify)
+ Passes.add(createVerifierPass());
+#endif
+
+ // Ask the target to add backend passes as necessary.
+ if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
+ std::cerr << argv[0] << ": target does not support generation of this"
+ << " file type!\n";
+ if (Out != &std::cout) delete Out;
+ // And the Out file is empty and useless, so remove it now.
+ sys::Path(OutputFilename).eraseFromDisk();
+ return 1;
}
- }
-
- // Ask the target to add backend passes as necessary.
- if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
- std::cerr << argv[0] << ": target does not support generation of this"
- << " file type!\n";
- if (Out != &std::cout) delete Out;
- // And the Out file is empty and useless, so remove it now.
- sys::Path(OutputFilename).eraseFromDisk();
- return 1;
- } else {
+
+ Passes.doInitialization();
+
// Run our queue of passes all at once now, efficiently.
- Passes.run(*M.get());
+ // TODO: this could lazily stream functions out of the module.
+ for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
+ if (!I->isExternal())
+ Passes.run(*I);
+
+ Passes.doFinalization();
}
-
+
// Delete the ostream if it's not a stdout stream
if (Out != &std::cout) delete Out;