Skip to content

Commit

Permalink
Completely rearchitect the interface between targets and the pass man…
Browse files Browse the repository at this point in the history
…ager.

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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30081 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
lattner committed Sep 4, 2006
1 parent dd842e1 commit 1911fd4
Show file tree
Hide file tree
Showing 26 changed files with 380 additions and 616 deletions.
5 changes: 0 additions & 5 deletions include/llvm/Target/TargetJITInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
102 changes: 96 additions & 6 deletions include/llvm/Target/TargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file describes the general parts of a Target machine.
// This file defines the TargetMachine and LLVMTargetMachine classes.
//
//===----------------------------------------------------------------------===//

Expand Down Expand Up @@ -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() { }

Expand Down Expand Up @@ -151,19 +151,109 @@ class TargetMachine {
/// 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;
}
};
Expand Down
10 changes: 5 additions & 5 deletions lib/ExecutionEngine/JIT/JIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
56 changes: 6 additions & 50 deletions lib/Target/ARM/ARMTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}

9 changes: 5 additions & 4 deletions lib/Target/ARM/ARMTargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@
#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"

namespace llvm {

class Module;

class ARMTargetMachine : public TargetMachine {
class ARMTargetMachine : public LLVMTargetMachine {
const TargetData DataLayout; // Calculates type size & alignment
ARMInstrInfo InstrInfo;
ARMFrameInfo FrameInfo;
Expand All @@ -41,8 +40,10 @@ class ARMTargetMachine : public TargetMachine {
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
Expand Down
6 changes: 0 additions & 6 deletions lib/Target/Alpha/AlphaJITInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 1911fd4

Please sign in to comment.