Skip to content

Commit 12e9730

Browse files
committed
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
1 parent e8ce162 commit 12e9730

25 files changed

+376
-614
lines changed

llvm/include/llvm/Target/TargetJITInfo.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@ namespace llvm {
3333
public:
3434
virtual ~TargetJITInfo() {}
3535

36-
/// addPassesToJITCompile - Add passes to the specified pass manager to
37-
/// implement a fast code generator for this target.
38-
///
39-
virtual void addPassesToJITCompile(FunctionPassManager &PM) = 0;
40-
4136
/// replaceMachineCodeForFunction - Make it so that calling the function
4237
/// whose machine code is at OLD turns into a call to NEW, perhaps by
4338
/// overwriting OLD with a branch to NEW. This is used for self-modifying

llvm/include/llvm/Target/TargetMachine.h

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88
//===----------------------------------------------------------------------===//
99
//
10-
// This file describes the general parts of a Target machine.
10+
// This file defines the TargetMachine and LLVMTargetMachine classes.
1111
//
1212
//===----------------------------------------------------------------------===//
1313

@@ -62,8 +62,8 @@ namespace CodeModel {
6262
/// through this interface.
6363
///
6464
class TargetMachine {
65-
TargetMachine(const TargetMachine&); // DO NOT IMPLEMENT
66-
void operator=(const TargetMachine&); // DO NOT IMPLEMENT
65+
TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT
66+
void operator=(const TargetMachine &); // DO NOT IMPLEMENT
6767
protected: // Can only create subclasses.
6868
TargetMachine() { }
6969

@@ -151,19 +151,109 @@ class TargetMachine {
151151
/// code as fast as possible, without regard for compile time. This method
152152
/// should return true if emission of this file type is not supported.
153153
///
154-
virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
154+
virtual bool addPassesToEmitFile(FunctionPassManager &PM, std::ostream &Out,
155155
CodeGenFileType FileType, bool Fast) {
156156
return true;
157157
}
158+
159+
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
160+
/// get machine code emitted. This uses a MachineCodeEmitter object to handle
161+
/// actually outputting the machine code and resolving things like the address
162+
/// of functions. This method returns true if machine code emission is
163+
/// not supported.
164+
///
165+
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
166+
MachineCodeEmitter &MCE, bool Fast) {
167+
return true;
168+
}
169+
158170

171+
/// addPassesToEmitWholeFile - This method can be implemented by targets that
172+
/// require having the entire module at once. This is not recommended, do not
173+
/// use this.
174+
virtual bool WantsWholeFile() const { return false; }
175+
virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
176+
CodeGenFileType FileType, bool Fast) {
177+
return true;
178+
}
179+
};
180+
181+
/// LLVMTargetMachine - This class describes a target machine that is
182+
/// implemented with the LLVM target-independent code generator.
183+
///
184+
class LLVMTargetMachine : public TargetMachine {
185+
protected: // Can only create subclasses.
186+
LLVMTargetMachine() { }
187+
public:
188+
189+
/// addPassesToEmitFile - Add passes to the specified pass manager to get
190+
/// the specified file emitted. Typically this will involve several steps of
191+
/// code generation. If Fast is set to true, the code generator should emit
192+
/// code as fast as possible, without regard for compile time. This method
193+
/// should return true if emission of this file type is not supported.
194+
///
195+
/// The default implementation of this method adds components from the
196+
/// LLVM retargetable code generator, invoking the methods below to get
197+
/// target-specific passes in standard locations.
198+
///
199+
virtual bool addPassesToEmitFile(FunctionPassManager &PM, std::ostream &Out,
200+
CodeGenFileType FileType, bool Fast);
201+
159202
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
160203
/// get machine code emitted. This uses a MachineCodeEmitter object to handle
161204
/// actually outputting the machine code and resolving things like the address
162-
/// of functions. This method should returns true if machine code emission is
205+
/// of functions. This method returns true if machine code emission is
163206
/// not supported.
164207
///
165208
virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
166-
MachineCodeEmitter &MCE) {
209+
MachineCodeEmitter &MCE, bool Fast);
210+
211+
/// Target-Independent Code Generator Pass Configuration Options.
212+
213+
/// addInstSelector - This method should add any "last minute" LLVM->LLVM
214+
/// passes, then install an instruction selector pass, which converts from
215+
/// LLVM code to machine instructions.
216+
virtual bool addInstSelector(FunctionPassManager &PM, bool Fast) {
217+
return true;
218+
}
219+
220+
/// addPostRegAllocPasses - This method may be implemented by targets that
221+
/// want to run passes after register allocation but before prolog-epilog
222+
/// insertion. This should return true if -print-machineinstrs should print
223+
/// after these passes.
224+
virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
225+
return false;
226+
}
227+
228+
/// addPreEmitPass - This pass may be implemented by targets that want to run
229+
/// passes immediately before machine code is emitted. This should return
230+
/// true if -print-machineinstrs should print out the code after the passes.
231+
virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast) {
232+
return false;
233+
}
234+
235+
236+
/// addAssemblyEmitter - This pass should be overridden by the target to add
237+
/// the asmprinter, if asm emission is supported. If this is not supported,
238+
/// 'true' should be returned.
239+
virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
240+
std::ostream &Out) {
241+
return true;
242+
}
243+
244+
/// addObjectWriter - This pass should be overridden by the target to add
245+
/// the object-file writer, if supported. If this is not supported,
246+
/// 'true' should be returned.
247+
virtual bool addObjectWriter(FunctionPassManager &PM, bool Fast,
248+
std::ostream &Out) {
249+
return true;
250+
}
251+
252+
/// addCodeEmitter - This pass should be overridden by the target to add a
253+
/// code emitter, if supported. If this is not supported, 'true' should be
254+
/// returned.
255+
virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
256+
MachineCodeEmitter &MCE) {
167257
return true;
168258
}
169259
};

llvm/lib/ExecutionEngine/JIT/JIT.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,18 @@ JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji)
5858

5959
// Add target data
6060
MutexGuard locked(lock);
61-
FunctionPassManager& PM = state.getPM(locked);
61+
FunctionPassManager &PM = state.getPM(locked);
6262
PM.add(new TargetData(*TM.getTargetData()));
6363

64-
// Compile LLVM Code down to machine code in the intermediate representation
65-
TJI.addPassesToJITCompile(PM);
66-
6764
// Turn the machine code intermediate representation into bytes in memory that
6865
// may be executed.
69-
if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
66+
if (TM.addPassesToEmitMachineCode(PM, *MCE, false /*fast*/)) {
7067
std::cerr << "Target does not support machine code emission!\n";
7168
abort();
7269
}
70+
71+
// Initialize passes.
72+
PM.doInitialization();
7373
}
7474

7575
JIT::~JIT() {

llvm/lib/Target/ARM/ARMTargetMachine.cpp

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,9 @@
1414
#include "ARMTargetMachine.h"
1515
#include "ARMFrameInfo.h"
1616
#include "ARM.h"
17-
#include "llvm/Assembly/PrintModulePass.h"
1817
#include "llvm/Module.h"
1918
#include "llvm/PassManager.h"
20-
#include "llvm/CodeGen/MachineFunction.h"
21-
#include "llvm/CodeGen/Passes.h"
22-
#include "llvm/Target/TargetOptions.h"
2319
#include "llvm/Target/TargetMachineRegistry.h"
24-
#include "llvm/Transforms/Scalar.h"
25-
#include <iostream>
2620
using namespace llvm;
2721

2822
namespace {
@@ -47,54 +41,16 @@ unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
4741
return 0;
4842
}
4943

50-
/// addPassesToEmitFile - Add passes to the specified pass manager
51-
/// to implement a static compiler for this target.
52-
///
53-
bool ARMTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out,
54-
CodeGenFileType FileType,
55-
bool Fast) {
56-
if (FileType != TargetMachine::AssemblyFile)
57-
return true;
58-
59-
// Run loop strength reduction before anything else.
60-
if (!Fast)
61-
PM.add(createLoopStrengthReducePass());
62-
63-
if (!Fast)
64-
PM.add(createCFGSimplificationPass());
65-
66-
// FIXME: Implement efficient support for garbage collection intrinsics.
67-
PM.add(createLowerGCPass());
68-
69-
// FIXME: implement the invoke/unwind instructions!
70-
PM.add(createLowerInvokePass());
71-
72-
// Print LLVM code input to instruction selector:
73-
if (PrintMachineCode)
74-
PM.add(new PrintFunctionPass());
75-
76-
// Make sure that no unreachable blocks are instruction selected.
77-
PM.add(createUnreachableBlockEliminationPass());
7844

45+
// Pass Pipeline Configuration
46+
bool ARMTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
7947
PM.add(createARMISelDag(*this));
80-
81-
// Print machine instructions as they were initially generated.
82-
if (PrintMachineCode)
83-
PM.add(createMachineFunctionPrinterPass(&std::cerr));
84-
85-
PM.add(createRegisterAllocator());
86-
PM.add(createPrologEpilogCodeInserter());
87-
88-
// Print machine instructions after register allocation and prolog/epilog
89-
// insertion.
90-
if (PrintMachineCode)
91-
PM.add(createMachineFunctionPrinterPass(&std::cerr));
92-
48+
return false;
49+
}
50+
bool ARMTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
51+
std::ostream &Out) {
9352
// Output assembly language.
9453
PM.add(createARMCodePrinterPass(Out, *this));
95-
96-
// Delete the MachineInstrs we generated, since they're no longer needed.
97-
PM.add(createMachineCodeDeleter());
9854
return false;
9955
}
10056

llvm/lib/Target/ARM/ARMTargetMachine.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@
1818
#include "llvm/Target/TargetMachine.h"
1919
#include "llvm/Target/TargetData.h"
2020
#include "llvm/Target/TargetFrameInfo.h"
21-
#include "llvm/PassManager.h"
2221
#include "ARMInstrInfo.h"
2322
#include "ARMFrameInfo.h"
2423

2524
namespace llvm {
2625

2726
class Module;
2827

29-
class ARMTargetMachine : public TargetMachine {
28+
class ARMTargetMachine : public LLVMTargetMachine {
3029
const TargetData DataLayout; // Calculates type size & alignment
3130
ARMInstrInfo InstrInfo;
3231
ARMFrameInfo FrameInfo;
@@ -41,8 +40,10 @@ class ARMTargetMachine : public TargetMachine {
4140
virtual const TargetData *getTargetData() const { return &DataLayout; }
4241
static unsigned getModuleMatchQuality(const Module &M);
4342

44-
virtual bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
45-
CodeGenFileType FileType, bool Fast);
43+
// Pass Pipeline Configuration
44+
virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
45+
virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
46+
std::ostream &Out);
4647
};
4748

4849
} // end namespace llvm

llvm/lib/Target/Alpha/AlphaJITInfo.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ namespace llvm {
2929
AlphaJITInfo(TargetMachine &tm) : TM(tm)
3030
{ useGOT = true; }
3131

32-
/// addPassesToJITCompile - Add passes to the specified pass manager to
33-
/// implement a fast dynamic compiler for this target. Return true if this
34-
/// is not supported for this target.
35-
///
36-
virtual void addPassesToJITCompile(FunctionPassManager &PM);
37-
3832
virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
3933
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
4034
virtual void relocate(void *Function, MachineRelocation *MR,

0 commit comments

Comments
 (0)