forked from OSchip/llvm-project
Completely rearchitect the interface between targets and the pass manager.
This pass: 1. Splits TargetMachine into TargetMachine (generic targets, can be implemented any way, like the CBE) and LLVMTargetMachine (subclass of TM that is used by things using libcodegen and other support). 2. Instead of having each target fully populate the passmgr for file or JIT output, move all this to common code, and give targets hooks they can implement. 3. Commonalize the target population stuff between file emission and JIT emission. 4. All (native code) codegen stuff now happens in a FunctionPassManager, which paves the way for "fast -O0" stuff in the CFE later, and now LLC could lazily stream .bc files from disk to use less memory. 5. There are now many fewer #includes and the targets don't depend on the scalar xforms or libanalysis anymore (but codegen does). 6. Changing common code generator pass ordering stuff no longer requires touching all targets. 7. The JIT now has the option of "-fast" codegen or normal optimized codegen, which is now orthogonal to the fact that JIT'ing is being done. llvm-svn: 30081
This commit is contained in:
parent
e8ce162969
commit
12e97307a1
|
@ -33,11 +33,6 @@ namespace llvm {
|
||||||
public:
|
public:
|
||||||
virtual ~TargetJITInfo() {}
|
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
|
/// replaceMachineCodeForFunction - Make it so that calling the function
|
||||||
/// whose machine code is at OLD turns into a call to NEW, perhaps by
|
/// 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
|
/// overwriting OLD with a branch to NEW. This is used for self-modifying
|
||||||
|
|
|
@ -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.
|
/// through this interface.
|
||||||
///
|
///
|
||||||
class TargetMachine {
|
class TargetMachine {
|
||||||
TargetMachine(const TargetMachine&); // DO NOT IMPLEMENT
|
TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT
|
||||||
void operator=(const TargetMachine&); // DO NOT IMPLEMENT
|
void operator=(const TargetMachine &); // DO NOT IMPLEMENT
|
||||||
protected: // Can only create subclasses.
|
protected: // Can only create subclasses.
|
||||||
TargetMachine() { }
|
TargetMachine() { }
|
||||||
|
|
||||||
|
@ -151,19 +151,109 @@ public:
|
||||||
/// code as fast as possible, without regard for compile time. This method
|
/// code as fast as possible, without regard for compile time. This method
|
||||||
/// should return true if emission of this file type is not supported.
|
/// 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) {
|
CodeGenFileType FileType, bool Fast) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
|
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
|
||||||
/// get machine code emitted. This uses a MachineCodeEmitter object to handle
|
/// get machine code emitted. This uses a MachineCodeEmitter object to handle
|
||||||
/// actually outputting the machine code and resolving things like the address
|
/// 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.
|
/// not supported.
|
||||||
///
|
///
|
||||||
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
|
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
|
||||||
MachineCodeEmitter &MCE) {
|
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 returns true if machine code emission is
|
||||||
|
/// not supported.
|
||||||
|
///
|
||||||
|
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,18 +58,18 @@ JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji)
|
||||||
|
|
||||||
// Add target data
|
// Add target data
|
||||||
MutexGuard locked(lock);
|
MutexGuard locked(lock);
|
||||||
FunctionPassManager& PM = state.getPM(locked);
|
FunctionPassManager &PM = state.getPM(locked);
|
||||||
PM.add(new TargetData(*TM.getTargetData()));
|
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
|
// Turn the machine code intermediate representation into bytes in memory that
|
||||||
// may be executed.
|
// 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";
|
std::cerr << "Target does not support machine code emission!\n";
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize passes.
|
||||||
|
PM.doInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
JIT::~JIT() {
|
JIT::~JIT() {
|
||||||
|
|
|
@ -14,15 +14,9 @@
|
||||||
#include "ARMTargetMachine.h"
|
#include "ARMTargetMachine.h"
|
||||||
#include "ARMFrameInfo.h"
|
#include "ARMFrameInfo.h"
|
||||||
#include "ARM.h"
|
#include "ARM.h"
|
||||||
#include "llvm/Assembly/PrintModulePass.h"
|
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/PassManager.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/Target/TargetMachineRegistry.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
|
||||||
#include <iostream>
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -47,54 +41,16 @@ unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
|
||||||
return 0;
|
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));
|
PM.add(createARMISelDag(*this));
|
||||||
|
return false;
|
||||||
// Print machine instructions as they were initially generated.
|
}
|
||||||
if (PrintMachineCode)
|
bool ARMTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
std::ostream &Out) {
|
||||||
|
|
||||||
PM.add(createRegisterAllocator());
|
|
||||||
PM.add(createPrologEpilogCodeInserter());
|
|
||||||
|
|
||||||
// Print machine instructions after register allocation and prolog/epilog
|
|
||||||
// insertion.
|
|
||||||
if (PrintMachineCode)
|
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
|
||||||
|
|
||||||
// Output assembly language.
|
// Output assembly language.
|
||||||
PM.add(createARMCodePrinterPass(Out, *this));
|
PM.add(createARMCodePrinterPass(Out, *this));
|
||||||
|
|
||||||
// Delete the MachineInstrs we generated, since they're no longer needed.
|
|
||||||
PM.add(createMachineCodeDeleter());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Target/TargetFrameInfo.h"
|
#include "llvm/Target/TargetFrameInfo.h"
|
||||||
#include "llvm/PassManager.h"
|
|
||||||
#include "ARMInstrInfo.h"
|
#include "ARMInstrInfo.h"
|
||||||
#include "ARMFrameInfo.h"
|
#include "ARMFrameInfo.h"
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ namespace llvm {
|
||||||
|
|
||||||
class Module;
|
class Module;
|
||||||
|
|
||||||
class ARMTargetMachine : public TargetMachine {
|
class ARMTargetMachine : public LLVMTargetMachine {
|
||||||
const TargetData DataLayout; // Calculates type size & alignment
|
const TargetData DataLayout; // Calculates type size & alignment
|
||||||
ARMInstrInfo InstrInfo;
|
ARMInstrInfo InstrInfo;
|
||||||
ARMFrameInfo FrameInfo;
|
ARMFrameInfo FrameInfo;
|
||||||
|
@ -41,8 +40,10 @@ public:
|
||||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||||
static unsigned getModuleMatchQuality(const Module &M);
|
static unsigned getModuleMatchQuality(const Module &M);
|
||||||
|
|
||||||
virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
|
// Pass Pipeline Configuration
|
||||||
CodeGenFileType FileType, bool Fast);
|
virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
|
||||||
|
virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
|
std::ostream &Out);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
|
@ -29,12 +29,6 @@ namespace llvm {
|
||||||
AlphaJITInfo(TargetMachine &tm) : TM(tm)
|
AlphaJITInfo(TargetMachine &tm) : TM(tm)
|
||||||
{ useGOT = true; }
|
{ 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 void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
|
||||||
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
|
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
|
||||||
virtual void relocate(void *Function, MachineRelocation *MR,
|
virtual void relocate(void *Function, MachineRelocation *MR,
|
||||||
|
|
|
@ -14,12 +14,8 @@
|
||||||
#include "AlphaJITInfo.h"
|
#include "AlphaJITInfo.h"
|
||||||
#include "AlphaTargetMachine.h"
|
#include "AlphaTargetMachine.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/PassManager.h"
|
||||||
#include "llvm/Target/TargetOptions.h"
|
|
||||||
#include "llvm/Target/TargetMachineRegistry.h"
|
#include "llvm/Target/TargetMachineRegistry.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
|
||||||
#include "llvm/Support/Debug.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -57,89 +53,30 @@ AlphaTargetMachine::AlphaTargetMachine(const Module &M, const std::string &FS)
|
||||||
: DataLayout("e"),
|
: DataLayout("e"),
|
||||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
|
FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
|
||||||
JITInfo(*this),
|
JITInfo(*this),
|
||||||
Subtarget(M, FS)
|
Subtarget(M, FS) {
|
||||||
{
|
|
||||||
DEBUG(std::cerr << "FS is " << FS << "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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());
|
// Pass Pipeline Configuration
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// 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 AlphaTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
|
||||||
PM.add(createAlphaISelDag(*this));
|
PM.add(createAlphaISelDag(*this));
|
||||||
|
return false;
|
||||||
if (PrintMachineCode)
|
}
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
bool AlphaTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
|
||||||
|
|
||||||
PM.add(createRegisterAllocator());
|
|
||||||
|
|
||||||
if (PrintMachineCode)
|
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
|
||||||
|
|
||||||
PM.add(createPrologEpilogCodeInserter());
|
|
||||||
|
|
||||||
// Must run branch selection immediately preceding the asm printer
|
// Must run branch selection immediately preceding the asm printer
|
||||||
//PM.add(createAlphaBranchSelectionPass());
|
//PM.add(createAlphaBranchSelectionPass());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool AlphaTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
|
std::ostream &Out) {
|
||||||
PM.add(createAlphaCodePrinterPass(Out, *this));
|
PM.add(createAlphaCodePrinterPass(Out, *this));
|
||||||
|
|
||||||
PM.add(createMachineCodeDeleter());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool AlphaTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
void AlphaJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
|
MachineCodeEmitter &MCE) {
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
// Must run branch selection immediately preceding the asm printer
|
|
||||||
//PM.add(createAlphaBranchSelectionPass());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AlphaTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
|
|
||||||
MachineCodeEmitter &MCE) {
|
|
||||||
PM.add(createAlphaCodeEmitterPass(*this, MCE));
|
PM.add(createAlphaCodeEmitterPass(*this, MCE));
|
||||||
// Delete machine code for this function
|
|
||||||
PM.add(createMachineCodeDeleter());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Target/TargetFrameInfo.h"
|
#include "llvm/Target/TargetFrameInfo.h"
|
||||||
#include "llvm/PassManager.h"
|
|
||||||
#include "AlphaInstrInfo.h"
|
#include "AlphaInstrInfo.h"
|
||||||
#include "AlphaJITInfo.h"
|
#include "AlphaJITInfo.h"
|
||||||
#include "AlphaSubtarget.h"
|
#include "AlphaSubtarget.h"
|
||||||
|
@ -26,7 +25,7 @@ namespace llvm {
|
||||||
|
|
||||||
class GlobalValue;
|
class GlobalValue;
|
||||||
|
|
||||||
class AlphaTargetMachine : public TargetMachine {
|
class AlphaTargetMachine : public LLVMTargetMachine {
|
||||||
const TargetData DataLayout; // Calculates type size & alignment
|
const TargetData DataLayout; // Calculates type size & alignment
|
||||||
AlphaInstrInfo InstrInfo;
|
AlphaInstrInfo InstrInfo;
|
||||||
TargetFrameInfo FrameInfo;
|
TargetFrameInfo FrameInfo;
|
||||||
|
@ -48,14 +47,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned getJITMatchQuality();
|
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);
|
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
|
} // end namespace llvm
|
||||||
|
|
|
@ -25,14 +25,14 @@ struct CTargetMachine : public TargetMachine {
|
||||||
CTargetMachine(const Module &M, const std::string &FS)
|
CTargetMachine(const Module &M, const std::string &FS)
|
||||||
: DataLayout(&M) {}
|
: DataLayout(&M) {}
|
||||||
|
|
||||||
// This is the only thing that actually does anything here.
|
virtual bool WantsWholeFile() const { return true; }
|
||||||
virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
|
virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
|
||||||
CodeGenFileType FileType, bool Fast);
|
CodeGenFileType FileType, bool Fast);
|
||||||
|
|
||||||
// This class always works, but shouldn't be the default in most cases.
|
// This class always works, but shouldn't be the default in most cases.
|
||||||
static unsigned getModuleMatchQuality(const Module &M) { return 1; }
|
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
|
} // End llvm namespace
|
||||||
|
|
|
@ -2027,8 +2027,10 @@ void CWriter::visitVAArgInst(VAArgInst &I) {
|
||||||
// External Interface declaration
|
// External Interface declaration
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
bool CTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o,
|
bool CTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
|
||||||
CodeGenFileType FileType, bool Fast) {
|
std::ostream &o,
|
||||||
|
CodeGenFileType FileType,
|
||||||
|
bool Fast) {
|
||||||
if (FileType != TargetMachine::AssemblyFile) return true;
|
if (FileType != TargetMachine::AssemblyFile) return true;
|
||||||
|
|
||||||
PM.add(createLowerGCPass());
|
PM.add(createLowerGCPass());
|
||||||
|
|
|
@ -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 "IA64.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/PassManager.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/Target/TargetMachineRegistry.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include "llvm/ADT/Statistic.h"
|
|
||||||
#include <iostream>
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
/// IA64TargetMachineModule - Note that this is used on hosts that cannot link
|
/// IA64TargetMachineModule - Note that this is used on hosts that cannot link
|
||||||
|
@ -33,14 +26,6 @@ extern "C" int IA64TargetMachineModule;
|
||||||
int IA64TargetMachineModule = 0;
|
int IA64TargetMachineModule = 0;
|
||||||
|
|
||||||
namespace {
|
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)");
|
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
|
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());
|
// Pass Pipeline Configuration
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// FIXME: Implement the invoke/unwind instructions!
|
bool IA64TargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
|
||||||
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());
|
|
||||||
|
|
||||||
// Add an instruction selector
|
|
||||||
// FIXME: reap this option one day: if(EnableDAGIsel)
|
|
||||||
PM.add(createIA64DAGToDAGInstructionSelector(*this));
|
PM.add(createIA64DAGToDAGInstructionSelector(*this));
|
||||||
|
return false;
|
||||||
/* XXX not yet. ;)
|
}
|
||||||
// Run optional SSA-based machine code optimizations next...
|
|
||||||
if (!NoSSAPeephole)
|
bool IA64TargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
|
||||||
PM.add(createIA64SSAPeepholeOptimizerPass());
|
// Make sure everything is bundled happily
|
||||||
*/
|
PM.add(createIA64BundlingPass(*this));
|
||||||
|
return true;
|
||||||
// Print the instruction selected machine code...
|
}
|
||||||
if (PrintMachineCode)
|
bool IA64TargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
std::ostream &Out) {
|
||||||
|
PM.add(createIA64CodePrinterPass(Out, *this));
|
||||||
// Perform register allocation to convert to a concrete IA64 representation
|
return false;
|
||||||
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());
|
|
||||||
|
|
||||||
// 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!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,19 +11,18 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef IA64TARGETMACHINE_H
|
#ifndef LLVM_TARGET_IA64TARGETMACHINE_H
|
||||||
#define IA64TARGETMACHINE_H
|
#define LLVM_TARGET_IA64TARGETMACHINE_H
|
||||||
|
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Target/TargetFrameInfo.h"
|
#include "llvm/Target/TargetFrameInfo.h"
|
||||||
#include "llvm/PassManager.h"
|
|
||||||
#include "IA64InstrInfo.h"
|
#include "IA64InstrInfo.h"
|
||||||
#include "IA64ISelLowering.h"
|
#include "IA64ISelLowering.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class IA64TargetMachine : public TargetMachine {
|
class IA64TargetMachine : public LLVMTargetMachine {
|
||||||
const TargetData DataLayout; // Calculates type size & alignment
|
const TargetData DataLayout; // Calculates type size & alignment
|
||||||
IA64InstrInfo InstrInfo;
|
IA64InstrInfo InstrInfo;
|
||||||
TargetFrameInfo FrameInfo;
|
TargetFrameInfo FrameInfo;
|
||||||
|
@ -42,11 +41,13 @@ public:
|
||||||
}
|
}
|
||||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
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);
|
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
|
} // End llvm namespace
|
||||||
|
|
||||||
|
|
|
@ -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
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
|
@ -12,15 +12,15 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef TARGET_POWERPC_H
|
#ifndef LLVM_TARGET_POWERPC_H
|
||||||
#define TARGET_POWERPC_H
|
#define LLVM_TARGET_POWERPC_H
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class PPCTargetMachine;
|
class PPCTargetMachine;
|
||||||
class PassManager;
|
class FunctionPassManager;
|
||||||
class FunctionPass;
|
class FunctionPass;
|
||||||
class MachineCodeEmitter;
|
class MachineCodeEmitter;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
|
||||||
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, PPCTargetMachine &TM);
|
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, PPCTargetMachine &TM);
|
||||||
FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM,
|
FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM,
|
||||||
MachineCodeEmitter &MCE);
|
MachineCodeEmitter &MCE);
|
||||||
void addPPCMachOObjectWriterPass(PassManager &FPM, std::ostream &o,
|
void addPPCMachOObjectWriterPass(FunctionPassManager &FPM, std::ostream &o,
|
||||||
PPCTargetMachine &tm);
|
PPCTargetMachine &tm);
|
||||||
} // end namespace llvm;
|
} // end namespace llvm;
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,6 @@ namespace llvm {
|
||||||
is64Bit = tmIs64Bit;
|
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 void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
|
||||||
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
|
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
|
||||||
virtual void relocate(void *Function, MachineRelocation *MR,
|
virtual void relocate(void *Function, MachineRelocation *MR,
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace {
|
||||||
/// addPPCMachOObjectWriterPass - Returns a pass that outputs the generated code
|
/// addPPCMachOObjectWriterPass - Returns a pass that outputs the generated code
|
||||||
/// as a Mach-O object file.
|
/// as a Mach-O object file.
|
||||||
///
|
///
|
||||||
void llvm::addPPCMachOObjectWriterPass(PassManager &FPM,
|
void llvm::addPPCMachOObjectWriterPass(FunctionPassManager &FPM,
|
||||||
std::ostream &O, PPCTargetMachine &TM) {
|
std::ostream &O, PPCTargetMachine &TM) {
|
||||||
PPCMachOWriter *EW = new PPCMachOWriter(O, TM);
|
PPCMachOWriter *EW = new PPCMachOWriter(O, TM);
|
||||||
FPM.add(EW);
|
FPM.add(EW);
|
||||||
|
|
|
@ -12,19 +12,10 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "PPC.h"
|
#include "PPC.h"
|
||||||
#include "PPCFrameInfo.h"
|
|
||||||
#include "PPCTargetMachine.h"
|
#include "PPCTargetMachine.h"
|
||||||
#include "PPCJITInfo.h"
|
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/PassManager.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/Target/TargetMachineRegistry.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include <iostream>
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -106,99 +97,47 @@ PPC64TargetMachine::PPC64TargetMachine(const Module &M, const std::string &FS)
|
||||||
: PPCTargetMachine(M, FS, true) {
|
: 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());
|
// Pass Pipeline Configuration
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
// 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());
|
|
||||||
|
|
||||||
|
bool PPCTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
|
||||||
// Install an instruction selector.
|
// Install an instruction selector.
|
||||||
PM.add(createPPCISelDag(*this));
|
PM.add(createPPCISelDag(*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(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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
|
bool PPCTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
|
||||||
|
|
||||||
|
// Must run branch selection immediately preceding the asm printer.
|
||||||
|
PM.add(createPPCBranchSelectionPass());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PPCTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
|
std::ostream &Out) {
|
||||||
|
PM.add(createDarwinAsmPrinter(Out, *this));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PPCTargetMachine::addObjectWriter(FunctionPassManager &PM, bool Fast,
|
||||||
|
std::ostream &Out) {
|
||||||
|
// FIXME: support PPC ELF files at some point
|
||||||
|
addPPCMachOObjectWriterPass(PM, Out, *this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PPCTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
|
MachineCodeEmitter &MCE) {
|
||||||
// The JIT should use the static relocation model.
|
// The JIT should use the static relocation model.
|
||||||
TM.setRelocationModel(Reloc::Static);
|
// FIXME: This should be moved to TargetJITInfo!!
|
||||||
|
setRelocationModel(Reloc::Static);
|
||||||
|
|
||||||
// Run loop strength reduction before anything else.
|
|
||||||
PM.add(createLoopStrengthReducePass(TM.getTargetLowering()));
|
|
||||||
|
// Machine code emitter pass for PowerPC.
|
||||||
// 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());
|
|
||||||
|
|
||||||
if (PrintMachineCode)
|
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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
|
|
||||||
PM.add(createPPCCodeEmitterPass(*this, MCE));
|
PM.add(createPPCCodeEmitterPass(*this, MCE));
|
||||||
// Delete machine code for this function after emitting it
|
|
||||||
PM.add(createMachineCodeDeleter());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class GlobalValue;
|
||||||
|
|
||||||
/// PPCTargetMachine - Common code between 32-bit and 64-bit PowerPC targets.
|
/// PPCTargetMachine - Common code between 32-bit and 64-bit PowerPC targets.
|
||||||
///
|
///
|
||||||
class PPCTargetMachine : public TargetMachine {
|
class PPCTargetMachine : public LLVMTargetMachine {
|
||||||
PPCSubtarget Subtarget;
|
PPCSubtarget Subtarget;
|
||||||
const TargetData DataLayout; // Calculates type size & alignment
|
const TargetData DataLayout; // Calculates type size & alignment
|
||||||
PPCInstrInfo InstrInfo;
|
PPCInstrInfo InstrInfo;
|
||||||
|
@ -55,12 +55,16 @@ public:
|
||||||
return InstrItins;
|
return InstrItins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
|
|
||||||
CodeGenFileType FileType, bool Fast);
|
|
||||||
|
|
||||||
bool addPassesToEmitMachineCode(FunctionPassManager &PM,
|
// Pass Pipeline Configuration
|
||||||
MachineCodeEmitter &MCE);
|
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.
|
/// PPC32TargetMachine - PowerPC 32-bit target machine.
|
||||||
|
|
|
@ -12,14 +12,9 @@
|
||||||
|
|
||||||
#include "SparcTargetMachine.h"
|
#include "SparcTargetMachine.h"
|
||||||
#include "Sparc.h"
|
#include "Sparc.h"
|
||||||
#include "llvm/Assembly/PrintModulePass.h"
|
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/PassManager.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/Target/TargetMachineRegistry.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -55,57 +50,23 @@ unsigned SparcTargetMachine::getModuleMatchQuality(const Module &M) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// addPassesToEmitFile - Add passes to the specified pass manager
|
bool SparcTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
|
||||||
/// 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());
|
|
||||||
|
|
||||||
PM.add(createSparcISelDag(*this));
|
PM.add(createSparcISelDag(*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));
|
|
||||||
|
|
||||||
PM.add(createSparcFPMoverPass(*this));
|
|
||||||
|
|
||||||
PM.add(createSparcDelaySlotFillerPass(*this));
|
|
||||||
|
|
||||||
// Print machine instructions after filling delay slots.
|
|
||||||
if (PrintMachineCode)
|
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
|
||||||
|
|
||||||
// Output assembly language.
|
|
||||||
PM.add(createSparcCodePrinterPass(Out, *this));
|
|
||||||
|
|
||||||
// Delete the MachineInstrs we generated, since they're no longer needed.
|
|
||||||
PM.add(createMachineCodeDeleter());
|
|
||||||
return false;
|
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.
|
||||||
|
bool SparcTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
|
||||||
|
PM.add(createSparcFPMoverPass(*this));
|
||||||
|
PM.add(createSparcDelaySlotFillerPass(*this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SparcTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
|
std::ostream &Out) {
|
||||||
|
// Output assembly language.
|
||||||
|
PM.add(createSparcCodePrinterPass(Out, *this));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Target/TargetFrameInfo.h"
|
#include "llvm/Target/TargetFrameInfo.h"
|
||||||
#include "llvm/PassManager.h"
|
|
||||||
#include "SparcInstrInfo.h"
|
#include "SparcInstrInfo.h"
|
||||||
#include "SparcSubtarget.h"
|
#include "SparcSubtarget.h"
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ namespace llvm {
|
||||||
|
|
||||||
class Module;
|
class Module;
|
||||||
|
|
||||||
class SparcTargetMachine : public TargetMachine {
|
class SparcTargetMachine : public LLVMTargetMachine {
|
||||||
const TargetData DataLayout; // Calculates type size & alignment
|
const TargetData DataLayout; // Calculates type size & alignment
|
||||||
SparcSubtarget Subtarget;
|
SparcSubtarget Subtarget;
|
||||||
SparcInstrInfo InstrInfo;
|
SparcInstrInfo InstrInfo;
|
||||||
|
@ -42,8 +41,12 @@ public:
|
||||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||||
static unsigned getModuleMatchQuality(const Module &M);
|
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
|
} // end namespace llvm
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class X86TargetMachine;
|
class X86TargetMachine;
|
||||||
class PassManager;
|
class FunctionPassManager;
|
||||||
class FunctionPass;
|
class FunctionPass;
|
||||||
class IntrinsicLowering;
|
class IntrinsicLowering;
|
||||||
class MachineCodeEmitter;
|
class MachineCodeEmitter;
|
||||||
|
@ -50,7 +50,7 @@ FunctionPass *createX86CodeEmitterPass(X86TargetMachine &TM,
|
||||||
/// addX86ELFObjectWriterPass - Add passes to the FPM that output the generated
|
/// addX86ELFObjectWriterPass - Add passes to the FPM that output the generated
|
||||||
/// code as an ELF object file.
|
/// code as an ELF object file.
|
||||||
///
|
///
|
||||||
void addX86ELFObjectWriterPass(PassManager &FPM,
|
void addX86ELFObjectWriterPass(FunctionPassManager &FPM,
|
||||||
std::ostream &o, X86TargetMachine &tm);
|
std::ostream &o, X86TargetMachine &tm);
|
||||||
|
|
||||||
/// createX86EmitCodeToMemory - Returns a pass that converts a register
|
/// createX86EmitCodeToMemory - Returns a pass that converts a register
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace {
|
||||||
/// addX86ELFObjectWriterPass - Returns a pass that outputs the generated code
|
/// addX86ELFObjectWriterPass - Returns a pass that outputs the generated code
|
||||||
/// as an ELF object file.
|
/// as an ELF object file.
|
||||||
///
|
///
|
||||||
void llvm::addX86ELFObjectWriterPass(PassManager &FPM,
|
void llvm::addX86ELFObjectWriterPass(FunctionPassManager &FPM,
|
||||||
std::ostream &O, X86TargetMachine &TM) {
|
std::ostream &O, X86TargetMachine &TM) {
|
||||||
X86ELFWriter *EW = new X86ELFWriter(O, TM);
|
X86ELFWriter *EW = new X86ELFWriter(O, TM);
|
||||||
FPM.add(EW);
|
FPM.add(EW);
|
||||||
|
|
|
@ -25,12 +25,6 @@ namespace llvm {
|
||||||
public:
|
public:
|
||||||
X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;}
|
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
|
/// replaceMachineCodeForFunction - Make it so that calling the function
|
||||||
/// whose machine code is at OLD turns into a call to NEW, perhaps by
|
/// 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
|
/// overwriting OLD with a branch to NEW. This is used for self-modifying
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include "llvm/Target/TargetMachineRegistry.h"
|
#include "llvm/Target/TargetMachineRegistry.h"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include "llvm/ADT/Statistic.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -33,9 +31,6 @@ extern "C" int X86TargetMachineModule;
|
||||||
int X86TargetMachineModule = 0;
|
int X86TargetMachineModule = 0;
|
||||||
|
|
||||||
namespace {
|
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.
|
// Register the target.
|
||||||
RegisterTarget<X86TargetMachine> X("x86", " IA-32 (Pentium and above)");
|
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_);
|
setRelocationModel(Reloc::PIC_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Pass Pipeline Configuration
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// addPassesToEmitFile - We currently use all of the same passes as the JIT
|
bool X86TargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
|
||||||
// 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());
|
|
||||||
|
|
||||||
// Install an instruction selector.
|
// Install an instruction selector.
|
||||||
PM.add(createX86ISelDag(*this, Fast));
|
PM.add(createX86ISelDag(*this, Fast));
|
||||||
|
return false;
|
||||||
// Print the instruction selected machine code...
|
}
|
||||||
if (PrintMachineCode)
|
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
bool X86TargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
|
||||||
|
PM.add(createX86FloatingPointStackifierPass());
|
||||||
// Perform register allocation to convert to a concrete x86 representation
|
return true; // -print-machineinstr should print after this.
|
||||||
PM.add(createRegisterAllocator());
|
}
|
||||||
|
|
||||||
if (PrintMachineCode)
|
bool X86TargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
std::ostream &Out) {
|
||||||
|
PM.add(createX86CodePrinterPass(Out, *this));
|
||||||
PM.add(createX86FloatingPointStackifierPass());
|
return false;
|
||||||
|
}
|
||||||
if (PrintMachineCode)
|
|
||||||
PM.add(createMachineFunctionPrinterPass(&std::cerr));
|
bool X86TargetMachine::addObjectWriter(FunctionPassManager &PM, bool Fast,
|
||||||
|
std::ostream &Out) {
|
||||||
// Insert prolog/epilog code. Eliminate abstract frame index references...
|
if (Subtarget.isTargetELF()) {
|
||||||
PM.add(createPrologEpilogCodeInserter());
|
addX86ELFObjectWriterPass(PM, Out, *this);
|
||||||
|
return false;
|
||||||
if (PrintMachineCode) // Print the register-allocated code
|
}
|
||||||
PM.add(createX86CodePrinterPass(std::cerr, *this));
|
return true;
|
||||||
|
}
|
||||||
if (!DisableOutput)
|
|
||||||
switch (FileType) {
|
bool X86TargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
|
||||||
default:
|
MachineCodeEmitter &MCE) {
|
||||||
assert(0 && "Unexpected filetype here!");
|
PM.add(createX86CodeEmitterPass(*this, MCE));
|
||||||
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!
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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));
|
|
||||||
|
|
||||||
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, TM));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool X86TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
|
|
||||||
MachineCodeEmitter &MCE) {
|
|
||||||
PM.add(createX86CodeEmitterPass(*this, MCE));
|
|
||||||
// Delete machine code for this function
|
|
||||||
PM.add(createMachineCodeDeleter());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Target/TargetFrameInfo.h"
|
#include "llvm/Target/TargetFrameInfo.h"
|
||||||
#include "llvm/PassManager.h"
|
|
||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
#include "X86InstrInfo.h"
|
#include "X86InstrInfo.h"
|
||||||
#include "X86JITInfo.h"
|
#include "X86JITInfo.h"
|
||||||
|
@ -26,7 +25,7 @@
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class X86TargetMachine : public TargetMachine {
|
class X86TargetMachine : public LLVMTargetMachine {
|
||||||
X86Subtarget Subtarget;
|
X86Subtarget Subtarget;
|
||||||
const TargetData DataLayout; // Calculates type size & alignment
|
const TargetData DataLayout; // Calculates type size & alignment
|
||||||
TargetFrameInfo FrameInfo;
|
TargetFrameInfo FrameInfo;
|
||||||
|
@ -48,14 +47,19 @@ public:
|
||||||
}
|
}
|
||||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
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 getModuleMatchQuality(const Module &M);
|
||||||
static unsigned getJITMatchQuality();
|
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
|
} // End llvm namespace
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,69 @@ GetFileNameRoot(const std::string &InputFilename) {
|
||||||
return outputFilename;
|
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.
|
// 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!");
|
assert(target.get() && "Could not allocate target machine!");
|
||||||
TargetMachine &Target = *target.get();
|
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...
|
// Figure out where we are going to send the output...
|
||||||
std::ostream *Out = 0;
|
std::ostream *Out = GetOutputStream(argv[0]);
|
||||||
if (OutputFilename != "") {
|
if (Out == 0) return 1;
|
||||||
if (OutputFilename != "-") {
|
|
||||||
// Specified an output filename?
|
// If this target requires addPassesToEmitWholeFile, do it now. This is
|
||||||
if (!Force && std::ifstream(OutputFilename.c_str())) {
|
// used by strange things like the C backend.
|
||||||
// If force is not specified, make sure not to overwrite a file!
|
if (Target.WantsWholeFile()) {
|
||||||
std::cerr << argv[0] << ": error opening '" << OutputFilename
|
PassManager PM;
|
||||||
<< "': file exists!\n"
|
PM.add(new TargetData(*Target.getTargetData()));
|
||||||
<< "Use -f command line argument to force output\n";
|
if (!NoVerify)
|
||||||
return 1;
|
PM.add(createVerifierPass());
|
||||||
}
|
|
||||||
Out = new std::ofstream(OutputFilename.c_str());
|
// Ask the target to add backend passes as necessary.
|
||||||
|
if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) {
|
||||||
// Make sure that the Out file gets unlinked from the disk if we get a
|
std::cerr << argv[0] << ": target does not support generation of this"
|
||||||
// SIGINT
|
<< " file type!\n";
|
||||||
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
|
if (Out != &std::cout) delete Out;
|
||||||
} else {
|
// And the Out file is empty and useless, so remove it now.
|
||||||
Out = &std::cout;
|
sys::Path(OutputFilename).eraseFromDisk();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
PM.run(mod);
|
||||||
} else {
|
} else {
|
||||||
if (InputFilename == "-") {
|
// Build up all of the passes that we want to do to the module.
|
||||||
OutputFilename = "-";
|
FunctionPassManager Passes(new ExistingModuleProvider(M.get()));
|
||||||
Out = &std::cout;
|
Passes.add(new TargetData(*Target.getTargetData()));
|
||||||
} else {
|
|
||||||
OutputFilename = GetFileNameRoot(InputFilename);
|
#ifndef NDEBUG
|
||||||
|
if (!NoVerify)
|
||||||
switch (FileType) {
|
Passes.add(createVerifierPass());
|
||||||
case TargetMachine::AssemblyFile:
|
#endif
|
||||||
if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
|
|
||||||
OutputFilename += ".s";
|
// Ask the target to add backend passes as necessary.
|
||||||
else
|
if (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) {
|
||||||
OutputFilename += ".cbe.c";
|
std::cerr << argv[0] << ": target does not support generation of this"
|
||||||
break;
|
<< " file type!\n";
|
||||||
case TargetMachine::ObjectFile:
|
if (Out != &std::cout) delete Out;
|
||||||
OutputFilename += ".o";
|
// And the Out file is empty and useless, so remove it now.
|
||||||
break;
|
sys::Path(OutputFilename).eraseFromDisk();
|
||||||
case TargetMachine::DynamicLibrary:
|
return 1;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Passes.doInitialization();
|
||||||
// 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 {
|
|
||||||
// Run our queue of passes all at once now, efficiently.
|
// 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
|
// Delete the ostream if it's not a stdout stream
|
||||||
if (Out != &std::cout) delete Out;
|
if (Out != &std::cout) delete Out;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue