llvm.org GIT mirror llvm / 1e60a91
Rip JIT specific stuff out of TargetMachine, as per PR176 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10542 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 16 years ago
15 changed file(s) with 218 addition(s) and 105 deletion(s). Raw diff Collapse all Expand all
0 //===- Target/TargetJITInfo.h - Target Information for JIT ------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the LLVM research group and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file exposes an abstract interface used by the Just-In-Time code
10 // generator to perform target-specific activities, such as emitting stubs. If
11 // a TargetMachine supports JIT code generation, it should provide one of these
12 // objects through the getJITInfo() method.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_TARGET_TARGETJITINFO_H
17 #define LLVM_TARGET_TARGETJITINFO_H
18
19 namespace llvm {
20 class Function;
21 class FunctionPassManager;
22 class MachineCodeEmitter;
23
24 /// TargetJITInfo - Target specific information required by the Just-In-Time
25 /// code generator.
26 struct TargetJITInfo {
27 virtual ~TargetJITInfo() {}
28
29 /// addPassesToJITCompile - Add passes to the specified pass manager to
30 /// implement a fast code generator for this target.
31 ///
32 virtual void addPassesToJITCompile(FunctionPassManager &PM) = 0;
33
34 /// replaceMachineCodeForFunction - Make it so that calling the function
35 /// whose machine code is at OLD turns into a call to NEW, perhaps by
36 /// overwriting OLD with a branch to NEW. This is used for self-modifying
37 /// code.
38 ///
39 virtual void replaceMachineCodeForFunction (void *Old, void *New) = 0;
40
41 /// getJITStubForFunction - Create or return a stub for the specified
42 /// function. This stub acts just like the specified function, except that
43 /// it allows the "address" of the function to be taken without having to
44 /// generate code for it. Targets do not need to implement this method, but
45 /// doing so will allow for faster startup of the JIT.
46 ///
47 virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE) {
48 return 0;
49 }
50 };
51 } // End llvm namespace
52
53 #endif
2020
2121 class TargetInstrInfo;
2222 class TargetInstrDescriptor;
23 class TargetJITInfo;
2324 class TargetSchedInfo;
2425 class TargetRegInfo;
2526 class TargetFrameInfo;
7879 ///
7980 virtual const MRegisterInfo* getRegisterInfo() const { return 0; }
8081
81 // Data storage information
82 /// getJITInfo - If this target supports a JIT, return information for it,
83 /// otherwise return null.
84 ///
85 virtual TargetJITInfo *getJITInfo() { return 0; }
86
87 // Data storage information. FIXME, this should be moved out to sparc
88 // specific code.
8289 //
8390 virtual unsigned findOptimalStorageSize(const Type* ty) const;
8491
85 /// addPassesToJITCompile - Add passes to the specified pass manager to
86 /// implement a fast dynamic compiler for this target. Return true if this is
87 /// not supported for this target.
88 ///
89 virtual bool addPassesToJITCompile(FunctionPassManager &PM) { return true; }
90
9192 /// addPassesToEmitAssembly - Add passes to the specified pass manager to get
9293 /// assembly langage code emitted. Typically this will involve several steps
9394 /// of code generation. This method should return true if assembly emission
107108 MachineCodeEmitter &MCE) {
108109 return true;
109110 }
110
111 /// replaceMachineCodeForFunction - Make it so that calling the
112 /// function whose machine code is at OLD turns into a call to NEW,
113 /// perhaps by overwriting OLD with a branch to NEW.
114 ///
115 /// FIXME: this is JIT-specific.
116 ///
117 virtual void replaceMachineCodeForFunction (void *Old, void *New) {
118 assert (0 && "Current target cannot replace machine code for functions");
119 }
120
121 /// getJITStubForFunction - Create or return a stub for the specified
122 /// function. This stub acts just like the specified function, except that it
123 /// allows the "address" of the function to be taken without having to
124 /// generate code for it.
125 virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE) {
126 return 0;
127 }
128111 };
129112
130113 } // End llvm namespace
7979 // Allocate a target...
8080 TargetMachine *Target = TargetMachineAllocator(*MP->getModule());
8181 assert(Target && "Could not allocate target machine!");
82
83 // Create the virtual machine object...
84 return new VM(MP, Target);
82
83 // If the target supports JIT code generation, return a new JIT now.
84 if (TargetJITInfo *TJ = Target->getJITInfo())
85 return new VM(MP, *Target, *TJ);
86 return 0;
8587 }
8688
87 VM::VM(ModuleProvider *MP, TargetMachine *tm) : ExecutionEngine(MP), TM(*tm),
88 PM(MP)
89 {
89 VM::VM(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji)
90 : ExecutionEngine(MP), TM(tm), TJI(tji), PM(MP) {
9091 setTargetData(TM.getTargetData());
9192
9293 // Initialize MCE
9394 MCE = createEmitter(*this);
94
95
9596 setupPassManager();
9697
9798 emitGlobals();
2323 class GlobalValue;
2424 class Constant;
2525 class TargetMachine;
26 class TargetJITInfo;
2627 class MachineCodeEmitter;
2728
2829 class VM : public ExecutionEngine {
2930 TargetMachine &TM; // The current target we are compiling to
31 TargetJITInfo &TJI; // The JITInfo for the target we are compiling to
32
3033 FunctionPassManager PM; // Passes to compile a function
3134 MachineCodeEmitter *MCE; // MCE object
3235
36 VM(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji);
3337 public:
34 VM(ModuleProvider *MP, TargetMachine *tm);
3538 ~VM();
3639
3740 /// create - Create an return a new JIT compiler if there is one available
1717 #include "llvm/CodeGen/MachineCodeEmitter.h"
1818 #include "llvm/CodeGen/MachineFunction.h"
1919 #include "llvm/Target/TargetMachine.h"
20 #include "llvm/Target/TargetJITInfo.h"
2021 using namespace llvm;
2122
2223 VM::~VM() {
2930 ///
3031 void VM::setupPassManager() {
3132 // Compile LLVM Code down to machine code in the intermediate representation
32 if (TM.addPassesToJITCompile(PM)) {
33 std::cerr << "lli: target '" << TM.getName()
34 << "' doesn't support JIT compilation!\n";
35 abort();
36 }
33 TJI.addPassesToJITCompile(PM);
3734
3835 // Turn the machine code intermediate representation into bytes in memory that
3936 // may be executed.
8683 if (I != GlobalAddress.end()) return I->second;
8784
8885 // If the target supports "stubs" for functions, get a stub now.
89 if (void *Ptr = TM.getJITStubForFunction(F, *MCE))
86 if (void *Ptr = TJI.getJITStubForFunction(F, *MCE))
9087 return Ptr;
9188
9289 // Otherwise, if the target doesn't support it, just codegen the function.
111108 MachineFunction::destruct(F);
112109 runJITOnFunction(F);
113110 assert(Addr && "Code generation didn't add function to GlobalAddress table!");
114 TM.replaceMachineCodeForFunction(OldAddr, Addr);
111 TJI.replaceMachineCodeForFunction(OldAddr, Addr);
115112 return Addr;
116113 }
2323 class GlobalValue;
2424 class Constant;
2525 class TargetMachine;
26 class TargetJITInfo;
2627 class MachineCodeEmitter;
2728
2829 class VM : public ExecutionEngine {
2930 TargetMachine &TM; // The current target we are compiling to
31 TargetJITInfo &TJI; // The JITInfo for the target we are compiling to
32
3033 FunctionPassManager PM; // Passes to compile a function
3134 MachineCodeEmitter *MCE; // MCE object
3235
36 VM(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji);
3337 public:
34 VM(ModuleProvider *MP, TargetMachine *tm);
3538 ~VM();
3639
3740 /// create - Create an return a new JIT compiler if there is one available
581581 }
582582 }
583583
584 void SparcTargetMachine::replaceMachineCodeForFunction (void *Old, void *New) {
584 void SparcJITInfo::replaceMachineCodeForFunction (void *Old, void *New) {
585585 assert (TheJITResolver &&
586586 "Can only call replaceMachineCodeForFunction from within JIT");
587587 uint64_t Target = (uint64_t)(intptr_t)New;
0 //===- SparcJITInfo.h - Sparc implementation of the JIT interface -*-C++-*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the LLVM research group and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the Sparc implementation of the TargetJITInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef SPARCJITINFO_H
14 #define SPARCJITINFO_H
15
16 #include "llvm/Target/TargetJITInfo.h"
17
18 namespace llvm {
19 class TargetMachine;
20 class SparcJITInfo : public TargetJITInfo {
21 TargetMachine &TM;
22 public:
23 SparcJITInfo(TargetMachine &tm) : TM(tm) {}
24
25 /// addPassesToJITCompile - Add passes to the specified pass manager to
26 /// implement a fast dynamic compiler for this target. Return true if this
27 /// is not supported for this target.
28 ///
29 virtual void addPassesToJITCompile(FunctionPassManager &PM);
30
31 /// replaceMachineCodeForFunction - Make it so that calling the function
32 /// whose machine code is at OLD turns into a call to NEW, perhaps by
33 /// overwriting OLD with a branch to NEW. This is used for self-modifying
34 /// code.
35 ///
36 virtual void replaceMachineCodeForFunction (void *Old, void *New);
37
38 /// getJITStubForFunction - Create or return a stub for the specified
39 /// function. This stub acts just like the specified function, except that
40 /// it allows the "address" of the function to be taken without having to
41 /// generate code for it.
42 //virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE);
43 };
44 }
45
46 #endif
7272 schedInfo(*this),
7373 regInfo(*this),
7474 frameInfo(*this),
75 cacheInfo(*this) {
75 cacheInfo(*this),
76 jitInfo(*this) {
7677 }
7778
7879 // addPassesToEmitAssembly - This method controls the entire code generation
151152 // addPassesToJITCompile - This method controls the JIT method of code
152153 // generation for the UltraSparc.
153154 //
154 bool SparcTargetMachine::addPassesToJITCompile(FunctionPassManager &PM) {
155 const TargetData &TD = getTargetData();
155 void SparcJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
156 const TargetData &TD = TM.getTargetData();
156157
157158 PM.add(new TargetData("lli", TD.isLittleEndian(), TD.getPointerSize(),
158159 TD.getPointerAlignment(), TD.getDoubleAlignment()));
172173 PM.add(createDecomposeMultiDimRefsPass());
173174
174175 // Construct and initialize the MachineFunction object for this fn.
175 PM.add(createMachineCodeConstructionPass(*this));
176 PM.add(createMachineCodeConstructionPass(TM));
176177
177178 // Specialize LLVM code for this target machine and then
178179 // run basic dataflow optimizations on LLVM code.
179 PM.add(createPreSelectionPass(*this));
180 PM.add(createPreSelectionPass(TM));
180181 // Run basic dataflow optimizations on LLVM code
181182 PM.add(createReassociatePass());
182183
184185 //PM.add(createLICMPass());
185186 //PM.add(createGCSEPass());
186187
187 PM.add(createInstructionSelectionPass(*this));
188
189 PM.add(getRegisterAllocator(*this));
188 PM.add(createInstructionSelectionPass(TM));
189
190 PM.add(getRegisterAllocator(TM));
190191 PM.add(createPrologEpilogInsertionPass());
191192
192193 if (!DisablePeephole)
193 PM.add(createPeepholeOptsPass(*this));
194
195 return false; // success!
194 PM.add(createPeepholeOptsPass(TM));
196195 }
197196
198197 //----------------------------------------------------------------------------
200199 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
201200 //----------------------------------------------------------------------------
202201
203 namespace llvm {
204
205 TargetMachine *allocateSparcTargetMachine(const Module &M) {
202 TargetMachine *llvm::allocateSparcTargetMachine(const Module &M) {
206203 return new SparcTargetMachine();
207204 }
208
209 }
2121 #include "SparcInternals.h"
2222 #include "SparcRegInfo.h"
2323 #include "SparcFrameInfo.h"
24 #include "SparcJITInfo.h"
2425
2526 namespace llvm {
2627
3031 SparcRegInfo regInfo;
3132 SparcFrameInfo frameInfo;
3233 SparcCacheInfo cacheInfo;
34 SparcJITInfo jitInfo;
3335 public:
3436 SparcTargetMachine();
3537
3840 virtual const TargetRegInfo &getRegInfo() const { return regInfo; }
3941 virtual const TargetFrameInfo &getFrameInfo() const { return frameInfo; }
4042 virtual const TargetCacheInfo &getCacheInfo() const { return cacheInfo; }
43 virtual TargetJITInfo *getJITInfo() { return &jitInfo; }
4144
4245 virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
43 virtual bool addPassesToJITCompile(FunctionPassManager &PM);
4446 virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
4547 MachineCodeEmitter &MCE);
46 virtual void replaceMachineCodeForFunction(void *Old, void *New);
47
48 /// getJITStubForFunction - Create or return a stub for the specified
49 /// function. This stub acts just like the specified function, except that it
50 /// allows the "address" of the function to be taken without having to
51 /// generate code for it.
52 ///
53 ///virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE);
5448 };
5549
5650 } // End llvm namespace
5252 JITResolver *TheJITResolver;
5353 }
5454
55 void *X86TargetMachine::getJITStubForFunction(Function *F,
56 MachineCodeEmitter &MCE) {
55 void *X86JITInfo::getJITStubForFunction(Function *F, MachineCodeEmitter &MCE) {
5756 if (TheJITResolver == 0)
5857 TheJITResolver = new JITResolver(MCE);
5958 return (void*)((unsigned long)TheJITResolver->getLazyResolver(F));
59 }
60
61 void X86JITInfo::replaceMachineCodeForFunction (void *Old, void *New) {
62 char *OldByte = (char *) Old;
63 *OldByte++ = 0xE9; // Emit JMP opcode.
64 int32_t *OldWord = (int32_t *) OldByte;
65 int32_t NewAddr = (intptr_t) New;
66 int32_t OldAddr = (intptr_t) OldWord;
67 *OldWord = NewAddr - OldAddr - 4; // Emit PC-relative addr of New code.
6068 }
6169
6270 /// addFunctionReference - This method is called when we need to emit the
None //===- X86InstructionInfo.h - X86 Instruction Information ---------*-C++-*-===//
0 //===- X86InstrInfo.h - X86 Instruction Information ------------*- C++ -*- ===//
11 //
22 // The LLVM Compiler Infrastructure
33 //
0 //===- X86JITInfo.h - X86 implementation of the JIT interface --*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the LLVM research group and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the X86 implementation of the TargetJITInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef X86JITINFO_H
14 #define X86JITINFO_H
15
16 #include "llvm/Target/TargetJITInfo.h"
17
18 namespace llvm {
19 class TargetMachine;
20 class X86JITInfo : public TargetJITInfo {
21 TargetMachine &TM;
22 public:
23 X86JITInfo(TargetMachine &tm) : TM(tm) {}
24
25 /// addPassesToJITCompile - Add passes to the specified pass manager to
26 /// implement a fast dynamic compiler for this target. Return true if this
27 /// is not supported for this target.
28 ///
29 virtual void addPassesToJITCompile(FunctionPassManager &PM);
30
31 /// replaceMachineCodeForFunction - Make it so that calling the function
32 /// whose machine code is at OLD turns into a call to NEW, perhaps by
33 /// overwriting OLD with a branch to NEW. This is used for self-modifying
34 /// code.
35 ///
36 virtual void replaceMachineCodeForFunction (void *Old, void *New);
37
38 /// getJITStubForFunction - Create or return a stub for the specified
39 /// function. This stub acts just like the specified function, except that
40 /// it allows the "address" of the function to be taken without having to
41 /// generate code for it.
42 virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE);
43 };
44 }
45
46 #endif
2020 #include "llvm/Transforms/Scalar.h"
2121 #include "Support/CommandLine.h"
2222 #include "Support/Statistic.h"
23
24 namespace llvm {
23 using namespace llvm;
2524
2625 namespace {
2726 cl::opt PrintCode("print-machineinstrs",
3534 // allocateX86TargetMachine - Allocate and return a subclass of TargetMachine
3635 // that implements the X86 backend.
3736 //
38 TargetMachine *allocateX86TargetMachine(const Module &M) {
37 TargetMachine *llvm::allocateX86TargetMachine(const Module &M) {
3938 return new X86TargetMachine(M);
4039 }
4140
4443 ///
4544 X86TargetMachine::X86TargetMachine(const Module &M)
4645 : TargetMachine("X86", true, 4, 4, 4, 4, 4),
47 FrameInfo(TargetFrameInfo::StackGrowsDown, 8/*16 for SSE*/, 4) {
46 FrameInfo(TargetFrameInfo::StackGrowsDown, 8/*16 for SSE*/, 4),
47 JITInfo(*this) {
4848 }
4949
5050
107107 /// implement a fast dynamic compiler for this target. Return true if this is
108108 /// not supported for this target.
109109 ///
110 bool X86TargetMachine::addPassesToJITCompile(FunctionPassManager &PM) {
110 void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
111111 // FIXME: Implement the switch instruction in the instruction selector!
112112 PM.add(createLowerSwitchPass());
113113
119119 PM.add(createCFGSimplificationPass());
120120
121121 if (NoPatternISel)
122 PM.add(createX86SimpleInstructionSelector(*this));
122 PM.add(createX86SimpleInstructionSelector(TM));
123123 else
124 PM.add(createX86PatternInstructionSelector(*this));
124 PM.add(createX86PatternInstructionSelector(TM));
125125
126126 // Run optional SSA-based machine code optimizations next...
127127 if (!NoSSAPeephole)
155155 PM.add(createX86PeepholeOptimizerPass());
156156
157157 if (PrintCode) // Print the register-allocated code
158 PM.add(createX86CodePrinterPass(std::cerr, *this));
159 return false; // success!
158 PM.add(createX86CodePrinterPass(std::cerr, TM));
160159 }
161160
162 void X86TargetMachine::replaceMachineCodeForFunction (void *Old, void *New) {
163 // FIXME: This code could perhaps live in a more appropriate place.
164 char *OldByte = (char *) Old;
165 *OldByte++ = 0xE9; // Emit JMP opcode.
166 int32_t *OldWord = (int32_t *) OldByte;
167 int32_t NewAddr = (intptr_t) New;
168 int32_t OldAddr = (intptr_t) OldWord;
169 *OldWord = NewAddr - OldAddr - 4; // Emit PC-relative addr of New code.
170 }
171
172 } // End llvm namespace
1717 #include "llvm/Target/TargetFrameInfo.h"
1818 #include "llvm/PassManager.h"
1919 #include "X86InstrInfo.h"
20 #include "X86JITInfo.h"
2021
2122 namespace llvm {
2223
2324 class X86TargetMachine : public TargetMachine {
24 X86InstrInfo InstrInfo;
25 X86InstrInfo InstrInfo;
2526 TargetFrameInfo FrameInfo;
27 X86JITInfo JITInfo;
2628 public:
2729 X86TargetMachine(const Module &M);
2830
3234 return &InstrInfo.getRegisterInfo();
3335 }
3436
37 virtual TargetJITInfo *getJITInfo() {
38 return &JITInfo;
39 }
40
41
3542 virtual const TargetSchedInfo &getSchedInfo() const { abort(); }
3643 virtual const TargetRegInfo &getRegInfo() const { abort(); }
3744 virtual const TargetCacheInfo &getCacheInfo() const { abort(); }
38
39 /// addPassesToJITCompile - Add passes to the specified pass manager to
40 /// implement a fast dynamic compiler for this target. Return true if this is
41 /// not supported for this target.
42 ///
43 virtual bool addPassesToJITCompile(FunctionPassManager &PM);
4445
4546 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
4647 /// get machine code emitted. This uses a MachineCodeEmitter object to handle
5253 MachineCodeEmitter &MCE);
5354
5455 virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
55
56 virtual void replaceMachineCodeForFunction (void *Old, void *New);
57
58 /// getJITStubForFunction - Create or return a stub for the specified
59 /// function. This stub acts just like the specified function, except that it
60 /// allows the "address" of the function to be taken without having to
61 /// generate code for it.
62 virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE);
6356 };
6457
6558 } // End llvm namespace