blob: be11021c6430cbc68393a56d4ae10560d1bae96a [file] [log] [blame]
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001/*
2 * Bitcode compiler (bcc) for Android:
3 * This is an eager-compilation JIT running on Android.
4 *
5 */
6
7#define LOG_TAG "bcc"
8#include <cutils/log.h>
9
10#include <ctype.h>
11#include <errno.h>
12#include <limits.h>
13#include <stdarg.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
19
20#include <cutils/hashmap.h>
21
22#if defined(__i386__)
23#include <sys/mman.h>
24#endif
25
26#if defined(__arm__)
27 #define DEFAULT_ARM_CODEGEN
28 #define PROVIDE_ARM_CODEGEN
29#elif defined(__i386__)
30 #define DEFAULT_X86_CODEGEN
31 #define PROVIDE_X86_CODEGEN
32#elif defined(__x86_64__)
33 #define DEFAULT_X64_CODEGEN
34 #define PROVIDE_X64_CODEGEN
35#endif
36
37#if defined(FORCE_ARM_CODEGEN)
38 #define DEFAULT_ARM_CODEGEN
39 #undef DEFAULT_X86_CODEGEN
40 #undef DEFAULT_X64_CODEGEN
41 #define PROVIDE_ARM_CODEGEN
42 #undef PROVIDE_X86_CODEGEN
43 #undef PROVIDE_X64_CODEGEN
44#elif defined(FORCE_X86_CODEGEN)
45 #undef DEFAULT_ARM_CODEGEN
46 #define DEFAULT_X86_CODEGEN
47 #undef DEFAULT_X64_CODEGEN
48 #undef PROVIDE_ARM_CODEGEN
49 #define PROVIDE_X86_CODEGEN
50 #undef PROVIDE_X64_CODEGEN
51#elif defined(FORCE_X64_CODEGEN)
52 #undef DEFAULT_ARM_CODEGEN
53 #undef DEFAULT_X86_CODEGEN
54 #define DEFAULT_X64_CODEGEN
55 #undef PROVIDE_ARM_CODEGEN
56 #undef PROVIDE_X86_CODEGEN
57 #define PROVIDE_X64_CODEGEN
58#endif
59
60#if defined(DEFAULT_ARM_CODEGEN)
61 #define TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
62#elif defined(DEFAULT_X86_CODEGEN)
63 #define TARGET_TRIPLE_STRING "i686-unknown-linux"
64#elif defined(DEFAULT_X64_CODEGEN)
65 #define TARGET_TRIPLE_STRING "x86_64-unknown-linux"
66#endif
67
68#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
69#define ARM_USE_VFP
70#endif
71
72#include <bcc/bcc.h>
73#include "bcc_runtime.h"
74
75#define LOG_API(...) do {} while(0)
76// #define LOG_API(...) fprintf (stderr, __VA_ARGS__)
77
78#define LOG_STACK(...) do {} while(0)
79// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__)
80
81// #define PROVIDE_TRACE_CODEGEN
82
83#if defined(USE_DISASSEMBLER)
Shih-wei Liaocd61af32010-04-29 00:02:57 -070084# include "llvm/MC/MCInst.h" /* for class llvm::MCInst */
85# include "llvm/MC/MCAsmInfo.h" /* for class llvm::MCAsmInfo */
86# include "llvm/MC/MCInstPrinter.h" /* for class llvm::MCInstPrinter */
87# include "llvm/MC/MCDisassembler.h" /* for class llvm::MCDisassembler */
Shih-wei Liao77ed6142010-04-07 12:21:42 -070088#endif
89
90#include <set>
91#include <map>
92#include <list>
93#include <cmath>
94#include <string>
95#include <cstring>
96#include <algorithm> /* for std::reverse */
97
98// Basic
99#include "llvm/Use.h" /* for class llvm::Use */
100#include "llvm/User.h" /* for class llvm::User */
101#include "llvm/Module.h" /* for class llvm::Module */
102#include "llvm/Function.h" /* for class llvm::Function */
103#include "llvm/Constant.h" /* for class llvm::Constant */
104#include "llvm/Constants.h" /* for class llvm::ConstantExpr */
105#include "llvm/Instruction.h" /* for class llvm::Instruction */
106#include "llvm/PassManager.h" /* for class llvm::PassManager and
107 * llvm::FunctionPassManager
108 */
109#include "llvm/LLVMContext.h" /* for llvm::getGlobalContext() */
110#include "llvm/GlobalValue.h" /* for class llvm::GlobalValue */
111#include "llvm/Instructions.h" /* for class llvm::CallInst */
112#include "llvm/OperandTraits.h" /* for macro
113 * DECLARE_TRANSPARENT_OPERAND_ACCESSORS
114 * and macro
115 * DEFINE_TRANSPARENT_OPERAND_ACCESSORS
116 */
117#include "llvm/TypeSymbolTable.h" /* for Type Reflection */
118
119// System
120#include "llvm/System/Host.h" /* for function
121 * llvm::sys::isLittleEndianHost()
122 */
123#include "llvm/System/Memory.h" /* for class llvm::sys::MemoryBlock */
124
125// ADT
126#include "llvm/ADT/APInt.h" /* for class llvm::APInt */
127#include "llvm/ADT/APFloat.h" /* for class llvm::APFloat */
128#include "llvm/ADT/DenseMap.h" /* for class llvm::DenseMap */
129#include "llvm/ADT/ValueMap.h" /* for class llvm::ValueMap and
130 * class llvm::ValueMapConfig
131 */
132#include "llvm/ADT/StringMap.h" /* for class llvm::StringMap */
133#include "llvm/ADT/OwningPtr.h" /* for class llvm::OwningPtr */
134#include "llvm/ADT/SmallString.h" /* for class llvm::SmallString */
135
136// Target
137#include "llvm/Target/TargetData.h" /* for class llvm::TargetData */
138#include "llvm/Target/TargetSelect.h" /* for function
139 * LLVMInitialize[ARM|X86]
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700140 * [TargetInfo|Target|Disassembler|
141 * AsmPrinter]()
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700142 */
143#include "llvm/Target/TargetOptions.h" /* for
144 * variable bool llvm::UseSoftFloat
145 * FloatABI::ABIType llvm::FloatABIType
146 * bool llvm::NoZerosInBSS
147 */
148#include "llvm/Target/TargetMachine.h" /* for class llvm::TargetMachine and
149 * llvm::TargetMachine::AssemblyFile
150 */
151#include "llvm/Target/TargetJITInfo.h" /* for class llvm::TargetJITInfo */
152#include "llvm/Target/TargetRegistry.h" /* for class llvm::TargetRegistry */
153#include "llvm/Target/SubtargetFeature.h"
154 /* for class llvm::SubtargetFeature */
155
156// Support
157#include "llvm/Support/Casting.h" /* for class cast<> */
158#include "llvm/Support/raw_ostream.h" /* for class llvm::raw_ostream and
159 * llvm::raw_string_ostream
160 */
161#include "llvm/Support/ValueHandle.h" /* for class AssertingVH<> */
162#include "llvm/Support/MemoryBuffer.h" /* for class llvm::MemoryBuffer */
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700163#include "llvm/Support/MemoryObject.h" /* for class llvm::MemoryObject */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700164#include "llvm/Support/ManagedStatic.h" /* for class llvm::llvm_shutdown */
165#include "llvm/Support/ErrorHandling.h" /* for function
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700166 * llvm::install_fatal_error_handler()
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700167 * and macro llvm_unreachable()
168 */
169#include "llvm/Support/StandardPasses.h"/* for function
170 * llvm::createStandardFunctionPasses()
171 * and
172 * llvm::createStandardModulePasses()
173 */
174#include "llvm/Support/FormattedStream.h"
175 /* for
176 * class llvm::formatted_raw_ostream
177 * llvm::formatted_raw_ostream::
178 * PRESERVE_STREAM
179 * llvm::FileModel::Error
180 */
181
182// Bitcode
183#include "llvm/Bitcode/ReaderWriter.h" /* for function
184 * llvm::ParseBitcodeFile()
185 */
186
187// CodeGen
188#include "llvm/CodeGen/Passes.h" /* for
189 * llvm::createLocalRegisterAllocator()
190 * and
191 * llvm::
192 * createLinearScanRegisterAllocator()
193 */
194#include "llvm/CodeGen/JITCodeEmitter.h"/* for class llvm::JITCodeEmitter */
195#include "llvm/CodeGen/MachineFunction.h"
196 /* for class llvm::MachineFunction */
197#include "llvm/CodeGen/RegAllocRegistry.h"
198 /* for class llvm::RegisterRegAlloc */
199#include "llvm/CodeGen/SchedulerRegistry.h"
200 /* for class llvm::RegisterScheduler
201 * and llvm::createDefaultScheduler()
202 */
203#include "llvm/CodeGen/MachineRelocation.h"
204 /* for class llvm::MachineRelocation */
205#include "llvm/CodeGen/MachineModuleInfo.h"
206 /* for class llvm::MachineModuleInfo */
207#include "llvm/CodeGen/MachineCodeEmitter.h"
208 /* for class llvm::MachineCodeEmitter */
209#include "llvm/CodeGen/MachineConstantPool.h"
210 /* for class llvm::MachineConstantPool
211 */
212#include "llvm/CodeGen/MachineJumpTableInfo.h"
213 /* for class llvm::MachineJumpTableInfo
214 */
215
216// ExecutionEngine
217#include "llvm/ExecutionEngine/GenericValue.h"
218 /* for struct llvm::GenericValue */
219#include "llvm/ExecutionEngine/JITMemoryManager.h"
220 /* for class llvm::JITMemoryManager */
221
222
223/*
224 * Compilation class that suits Android's needs.
225 * (Support: no argument passed, ...)
226 */
227
228namespace bcc {
229
230class Compiler {
231 /*
232 * This part is designed to be orthogonal to those exported bcc*() functions
233 * implementation and internal struct BCCscript.
234 */
235
236
237 /*********************************************
238 * The variable section below (e.g., Triple, CodeGenOptLevel)
239 * is initialized in GlobalInitialization()
240 */
241 static bool GlobalInitialized;
242
243 /*
244 * If given, this will be the name of the target triple to compile for.
245 * If not given, the initial values defined in this file will be used.
246 */
247 static std::string Triple;
248
249 static llvm::CodeGenOpt::Level CodeGenOptLevel;
250 /*
251 * End of section of GlobalInitializing variables
252 **********************************************/
253
254 /* If given, the name of the target CPU to generate code for. */
255 static std::string CPU;
256
257 /*
258 * The list of target specific features to enable or disable -- this should
259 * be a list of strings starting with '+' (enable) or '-' (disable).
260 */
261 static std::vector<std::string> Features;
262
263 struct Runtime {
264 const char* mName;
265 void* mPtr;
266 };
267 static struct Runtime Runtimes[];
268
269 static void GlobalInitialization() {
270 if(GlobalInitialized) return;
271
272 /* Set Triple, CPU and Features here */
273 Triple = TARGET_TRIPLE_STRING;
274
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700275 Features.push_back("+neon");
276 Features.push_back("+vmlx");
277 Features.push_back("+neonfp");
278
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700279#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
280 LLVMInitializeARMTargetInfo();
281 LLVMInitializeARMTarget();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700282#if defined(USE_DISASSEMBLER)
283 LLVMInitializeARMDisassembler();
284 LLVMInitializeARMAsmPrinter();
285#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700286#endif
287
288#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
289 LLVMInitializeX86TargetInfo();
290 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700291#if defined(USE_DISASSEMBLER)
292 LLVMInitializeX86Disassembler();
293 LLVMInitializeX86AsmPrinter();
294#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700295#endif
296
297#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
298 LLVMInitializeX86TargetInfo();
299 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700300#if defined(USE_DISASSEMBLER)
301 LLVMInitializeX86Disassembler();
302 LLVMInitializeX86AsmPrinter();
303#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700304#endif
305
306 /*
307 * -O0: llvm::CodeGenOpt::None
308 * -O1: llvm::CodeGenOpt::Less
309 * -O2: llvm::CodeGenOpt::Default
310 * -O3: llvm::CodeGenOpt::Aggressive
311 */
312 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
313
314 /* Below are the global settings to LLVM */
315
316 /* Disable frame pointer elimination optimization */
317 llvm::NoFramePointerElim = false;
318
319 /*
320 * Use hardfloat ABI
321 *
322 * FIXME: Need to detect the CPU capability and decide whether to use
323 * softfp. To use softfp, change following 2 lines to
324 *
325 * llvm::FloatABIType = llvm::FloatABI::Soft;
326 * llvm::UseSoftFloat = true;
327 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700328 llvm::FloatABIType = llvm::FloatABI::Soft;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700329 llvm::UseSoftFloat = false;
330
331 /*
332 * BCC needs all unknown symbols resolved at JIT/compilation time.
333 * So we don't need any dynamic relocation model.
334 */
335 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
336
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700337#if defined(DEFAULT_X64_CODEGEN)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700338 /* Data address in X86_64 architecture may reside in a far-away place */
339 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
340#else
341 /*
342 * This is set for the linker (specify how large of the virtual addresses
343 * we can access for all unknown symbols.)
344 */
345 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
346#endif
347
348 /* Register the scheduler */
349 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
350
351 /*
352 * Register allocation policy:
353 * createLocalRegisterAllocator: fast but bad quality
354 * createLinearScanRegisterAllocator: not so fast but good quality
355 */
356 llvm::RegisterRegAlloc::setDefault
357 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
358 llvm::createLocalRegisterAllocator :
359 llvm::createLinearScanRegisterAllocator);
360
361 GlobalInitialized = true;
362 return;
363 }
364
365 static void LLVMErrorHandler(void *UserData, const std::string &Message) {
366 // std::string* Error = static_cast<std::string*>(UserData);
367 // Error->assign(Message);
368 // return;
369 fprintf(stderr, "%s\n", Message.c_str());
370 exit(1);
371 }
372
373 static const llvm::StringRef PragmaMetadataName;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700374 static const llvm::StringRef ExportVarMetadataName;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700375
376 private:
377 std::string mError;
378
379 inline bool hasError() const {
380 return !mError.empty();
381 }
382 inline void setError(const char* Error) {
383 mError.assign(Error); // Copying
384 return;
385 }
386 inline void setError(const std::string& Error) {
387 mError = Error;
388 return;
389 }
390
391 typedef std::list< std::pair<std::string, std::string> > PragmaList;
392 PragmaList mPragmas;
393
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700394 typedef std::list<void*> ExportVarList;
395 ExportVarList mExportVars;
396
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700397 /* Memory manager for the code reside in memory */
398 /*
399 * The memory for our code emitter is very simple and is conforming to the
400 * design decisions of Android RenderScript's Exection Environment:
401 * The code, data, and symbol sizes are limited (currently 100KB.)
402 *
403 * It's very different from typical compiler, which has no limitation
404 * on the code size. How does code emitter know the size of the code
405 * it is about to emit? It does not know beforehand. We want to solve
406 * this without complicating the code emitter too much.
407 *
408 * We solve this by pre-allocating a certain amount of memory,
409 * and then start the code emission. Once the buffer overflows, the emitter
410 * simply discards all the subsequent emission but still has a counter
411 * on how many bytes have been emitted.
412
413 * So once the whole emission is done, if there's a buffer overflow,
414 * it re-allocates the buffer with enough size (based on the
415 * counter from previous emission) and re-emit again.
416 */
417 class CodeMemoryManager : public llvm::JITMemoryManager {
418 /* {{{ */
419 private:
420 static const unsigned int MaxCodeSize = 100 * 1024; /* 100 KiB for code */
421 static const unsigned int MaxGOTSize = 1 * 1024; /* 1 KiB for global
422 offset table (GOT) */
423
424 /*
425 * Our memory layout is as follows:
426 *
427 * The direction of arrows (-> and <-) shows memory's growth direction
428 * when more space is needed.
429 *
430 * @mpCodeMem:
431 * +--------------------------------------------------------------+
432 * | Function Memory ... -> <- ... Global/Stub/GOT |
433 * +--------------------------------------------------------------+
434 * |<------------------ Total: @MaxCodeSize KiB ----------------->|
435 *
436 * Where size of GOT is @MaxGOTSize KiB.
437 *
438 * @mCurFuncMemIdx: The current index (starting from 0) of the last byte
439 * of function code's memoey usage
440 * @mCurGSGMemIdx: The current index (starting from 0) of the last byte
441 * of Global Stub/GOT's memory usage
442 *
443 */
444
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700445 uintptr_t mCurFuncMemIdx;
446 uintptr_t mCurGSGMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700447 llvm::sys::MemoryBlock* mpCodeMem;
448
449 /* GOT Base */
450 uint8_t* mpGOTBase;
451
452 typedef std::map<const llvm::Function*, pair<void* /* start address */,
453 void* /* end address */>
454 > FunctionMapTy;
455 FunctionMapTy mFunctionMap;
456
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700457 inline uintptr_t getFreeMemSize() const {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700458 return mCurGSGMemIdx - mCurFuncMemIdx;
459 }
460 inline uint8_t* getCodeMemBase() const {
461 return static_cast<uint8_t*>(mpCodeMem->base());
462 }
463
464 uint8_t* allocateGSGMemory(uintptr_t Size,
465 unsigned Alignment = 1 /* no alignment */)
466 {
467 if(getFreeMemSize() < Size)
468 /* The code size excesses our limit */
469 return NULL;
470
471 if(Alignment == 0)
472 Alignment = 1;
473
474 uint8_t* result = getCodeMemBase() + mCurGSGMemIdx - Size;
475 result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
476
477 mCurGSGMemIdx = result - getCodeMemBase();
478
479 return result;
480 }
481
482 public:
483 CodeMemoryManager() : mpCodeMem(NULL), mpGOTBase(NULL) {
484 reset();
485 std::string ErrMsg;
486 llvm::sys::MemoryBlock B = llvm::sys::Memory::
487 AllocateRWX(MaxCodeSize, NULL, &ErrMsg);
488 if(B.base() == 0)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700489 llvm::report_fatal_error(
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700490 "Failed to allocate Memory for code emitter\n" + ErrMsg
491 );
492 mpCodeMem = new llvm::sys::MemoryBlock(B.base(), B.size());
493
494 return;
495 }
496
497 /*
498 * setMemoryWritable - When code generation is in progress,
499 * the code pages may need permissions changed.
500 */
501 void setMemoryWritable() {
502 llvm::sys::Memory::setWritable(*mpCodeMem);
503 return;
504 }
505
506 /*
507 * setMemoryExecutable - When code generation is done and we're ready to
508 * start execution, the code pages may need permissions changed.
509 */
510 void setMemoryExecutable() {
511 llvm::sys::Memory::setExecutable(*mpCodeMem);
512 return;
513 }
514
515 /*
516 * setPoisonMemory - Setting this flag to true makes the memory manager
517 * garbage values over freed memory. This is useful for testing and
518 * debugging, and is to be turned on by default in debug mode.
519 */
520 void setPoisonMemory(bool poison) {
521 /* no effect */
522 return;
523 }
524
525 /* Global Offset Table Management */
526
527 /*
528 * AllocateGOT - If the current table requires a Global Offset Table, this
529 * method is invoked to allocate it. This method is required to set HasGOT
530 * to true.
531 */
532 void AllocateGOT() {
533 assert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
534 mpGOTBase = allocateGSGMemory(MaxGOTSize);
535 HasGOT = true;
536 return;
537 }
538
539 /*
540 * getGOTBase - If this is managing a Global Offset Table, this method
541 * should return a pointer to its base.
542 */
543 uint8_t* getGOTBase() const {
544 return mpGOTBase;
545 }
546
547 /* Main Allocation Functions */
548
549 /*
550 * startFunctionBody - When we start JITing a function, the JIT calls this
551 * method to allocate a block of free RWX memory, which returns a pointer to
552 * it. If the JIT wants to request a block of memory of at least a certain
553 * size, it passes that value as ActualSize, and this method returns a block
554 * with at least that much space. If the JIT doesn't know ahead of time how
555 * much space it will need to emit the function, it passes 0 for the
556 * ActualSize. In either case, this method is required to pass back the size
557 * of the allocated block through ActualSize. The JIT will be careful to
558 * not write more than the returned ActualSize bytes of memory.
559 */
560 uint8_t* startFunctionBody(const llvm::Function *F, uintptr_t &ActualSize) {
561 if(getFreeMemSize() < ActualSize)
562 /* The code size excesses our limit */
563 return NULL;
564
565 ActualSize = getFreeMemSize();
566 return (getCodeMemBase() + mCurFuncMemIdx);
567 }
568
569 /*
570 * allocateStub - This method is called by the JIT to allocate space for a
571 * function stub (used to handle limited branch displacements) while it is
572 * JIT compiling a function. For example, if foo calls bar, and if bar
573 * either needs to be lazily compiled or is a native function that exists
574 * too
575 * far away from the call site to work, this method will be used to make a
576 * thunk for it. The stub should be "close" to the current function body,
577 * but should not be included in the 'actualsize' returned by
578 * startFunctionBody.
579 */
580 uint8_t* allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
581 unsigned Alignment) {
582 return allocateGSGMemory(StubSize, Alignment);
583 }
584
585 /*
586 * endFunctionBody - This method is called when the JIT is done codegen'ing
587 * the specified function. At this point we know the size of the JIT
588 * compiled function. This passes in FunctionStart (which was returned by
589 * the startFunctionBody method) and FunctionEnd which is a pointer to the
590 * actual end of the function. This method should mark the space allocated
591 * and remember where it is in case the client wants to deallocate it.
592 */
593 void endFunctionBody(const llvm::Function* F, uint8_t* FunctionStart,
594 uint8_t* FunctionEnd) {
595 assert(FunctionEnd > FunctionStart);
596 assert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
597 "Mismatched function start/end!");
598
599 /* Advance the pointer */
600 intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
601 assert(FunctionCodeSize <= getFreeMemSize() &&
602 "Code size excess the limitation!");
603 mCurFuncMemIdx += FunctionCodeSize;
604
605 /* Record there's a function in our memory start from @FunctionStart */
606 assert(mFunctionMap.find(F) == mFunctionMap.end() &&
607 "Function already emitted!");
608 mFunctionMap.insert( make_pair<const llvm::Function*, pair<void*, void*>
609 >(F, make_pair(FunctionStart, FunctionEnd))
610 );
611
612 return;
613 }
614
615 /*
616 * allocateSpace - Allocate a (function code) memory block of the
617 * given size. This method cannot be called between
618 * calls to startFunctionBody and endFunctionBody.
619 */
620 uint8_t* allocateSpace(intptr_t Size, unsigned Alignment) {
621 if(getFreeMemSize() < Size)
622 /* The code size excesses our limit */
623 return NULL;
624
625 if(Alignment == 0)
626 Alignment = 1;
627
628 uint8_t* result = getCodeMemBase() + mCurFuncMemIdx;
629 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
630 ~(intptr_t) (Alignment - 1)
631 );
632
633 mCurFuncMemIdx = (result + Size) - getCodeMemBase();
634
635 return result;
636 }
637
638 /* allocateGlobal - Allocate memory for a global. */
639 uint8_t* allocateGlobal(uintptr_t Size, unsigned Alignment) {
640 return allocateGSGMemory(Size, Alignment);
641 }
642
643 /*
644 * deallocateFunctionBody - Free the specified function body. The argument
645 * must be the return value from a call to startFunctionBody() that hasn't
646 * been deallocated yet. This is never called when the JIT is currently
647 * emitting a function.
648 */
649 void deallocateFunctionBody(void *Body) {
650 /* linear search */
651 FunctionMapTy::iterator I;
652 for(I = mFunctionMap.begin();
653 I != mFunctionMap.end();
654 I++)
655 if(I->second.first == Body)
656 break;
657
658 assert(I != mFunctionMap.end() && "Memory is never allocated!");
659
660 /* free the memory */
661 uint8_t* FunctionStart = (uint8_t*) I->second.first;
662 uint8_t* FunctionEnd = (uint8_t*) I->second.second;
663 intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
664
665 assert(SizeNeedMove >= 0 &&
666 "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
667 " be correctly calculated!");
668
669 if(SizeNeedMove > 0)
670 /* there's data behind deallocating function */
671 ::memmove(FunctionStart, FunctionEnd, SizeNeedMove);
672 mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
673
674 return;
675 }
676
677 /*
678 * startExceptionTable - When we finished JITing the function, if exception
679 * handling is set, we emit the exception table.
680 */
681 uint8_t* startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize)
682 {
683 assert(false && "Exception is not allowed in our language specification");
684 return NULL;
685 }
686
687 /*
688 * endExceptionTable - This method is called when the JIT is done emitting
689 * the exception table.
690 */
691 void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
692 uint8_t *TableEnd, uint8_t* FrameRegister) {
693 assert(false && "Exception is not allowed in our language specification");
694 return;
695 }
696
697 /*
698 * deallocateExceptionTable - Free the specified exception table's memory.
699 * The argument must be the return value from a call to
700 * startExceptionTable()
701 * that hasn't been deallocated yet. This is never called when the JIT is
702 * currently emitting an exception table.
703 */
704 void deallocateExceptionTable(void *ET) {
705 assert(false && "Exception is not allowed in our language specification");
706 return;
707 }
708
709 /* Below are the methods we create */
710 void reset() {
711 mpGOTBase = NULL;
712 HasGOT = false;
713
714 mCurFuncMemIdx = 0;
715 mCurGSGMemIdx = MaxCodeSize - 1;
716
717 mFunctionMap.clear();
718
719 return;
720 }
721
722 ~CodeMemoryManager() {
723 if(mpCodeMem != NULL)
724 llvm::sys::Memory::ReleaseRWX(*mpCodeMem);
725 return;
726 }
727 /* }}} */
728 }; /* End of class CodeMemoryManager */
729
730 /* The memory manager for code emitter */
731 llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
732 CodeMemoryManager* createCodeMemoryManager() {
733 mCodeMemMgr.reset(new CodeMemoryManager());
734 return mCodeMemMgr.get();
735 }
736
737 /* Code emitter */
738 class CodeEmitter : public llvm::JITCodeEmitter {
739 /* {{{ */
740 public:
741 typedef llvm::DenseMap<const llvm::GlobalValue*, void*> GlobalAddressMapTy;
742 typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
743
744 private:
745 CodeMemoryManager* mpMemMgr;
746
747 /* The JITInfo for the target we are compiling to */
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700748 const llvm::Target* mpTarget;
749
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700750 llvm::TargetJITInfo* mpTJI;
751
752 const llvm::TargetData* mpTD;
753
754 /*
755 * MBBLocations - This vector is a mapping from MBB ID's to their address.
756 * It is filled in by the StartMachineBasicBlock callback and queried by
757 * the getMachineBasicBlockAddress callback.
758 */
759 std::vector<uintptr_t> mMBBLocations;
760
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700761 /* mpConstantPool - The constant pool for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700762 llvm::MachineConstantPool* mpConstantPool;
763
764 /* ConstantPoolBase - A pointer to the first entry in the constant pool. */
765 void *mpConstantPoolBase;
766
767 /* ConstPoolAddresses - Addresses of individual constant pool entries. */
768 llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
769
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700770 /* mpJumpTable - The jump tables for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700771 llvm::MachineJumpTableInfo *mpJumpTable;
772
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700773 /* mpJumpTableBase - A pointer to the first entry in the jump table. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700774 void *mpJumpTableBase;
775
776 /*
777 * When outputting a function stub in the context of some other function, we
778 * save BufferBegin/BufferEnd/CurBufferPtr here.
779 */
780 uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
781
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700782 /* mRelocations - These are the relocations that the function needs,
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700783 as emitted. */
784 std::vector<llvm::MachineRelocation> mRelocations;
785
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700786 /* mLabelLocations - This vector is a mapping from Label ID's to their
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700787 address. */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700788 llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700789
790 class EmittedFunctionCode {
791 public:
792 void* FunctionBody; // Beginning of the function's allocation.
793 void* Code; // The address the function's code actually starts at.
794 int Size; // The size of the function code
795
796 EmittedFunctionCode() : FunctionBody(NULL), Code(NULL) { return; }
797 };
798 EmittedFunctionCode* mpCurEmitFunction;
799
800 typedef std::map<const std::string, EmittedFunctionCode*
801 > EmittedFunctionsMapTy;
802 EmittedFunctionsMapTy mEmittedFunctions;
803
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700804 /* mpMMI - Machine module info for exception informations */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700805 llvm::MachineModuleInfo* mpMMI;
806
807 GlobalAddressMapTy mGlobalAddressMap;
808
809 /*
810 * UpdateGlobalMapping - Replace an existing mapping for GV with a new
811 * address. This updates both maps as required. If "Addr" is null, the
812 * entry for the global is removed from the mappings.
813 */
814 void* UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
815 if(Addr == NULL) {
816 /* Removing mapping */
817 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
818 void *OldVal;
819
820 if(I == mGlobalAddressMap.end())
821 OldVal = NULL;
822 else {
823 OldVal = I->second;
824 mGlobalAddressMap.erase(I);
825 }
826
827 return OldVal;
828 }
829
830 void*& CurVal = mGlobalAddressMap[GV];
831 void* OldVal = CurVal;
832
833 CurVal = Addr;
834
835 return OldVal;
836 }
837
838 /*
839 * AddGlobalMapping - Tell the execution engine that the specified global is
840 * at the specified location. This is used internally as functions are
841 * JIT'd
842 * and as global variables are laid out in memory.
843 */
844 void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
845 void*& CurVal = mGlobalAddressMap[GV];
846 assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
847 CurVal = Addr;
848 return;
849 }
850
851 /*
852 * GetPointerToGlobalIfAvailable - This returns the address of the specified
853 * global value if it is has already been codegen'd,
854 * otherwise it returns null.
855 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700856 void* GetPointerToGlobalIfAvailable(const llvm::GlobalValue* GV) {
857 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700858 return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
859 }
860
861 unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool* MCP) {
862 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
863 MCP->getConstants();
864
865 if(Constants.empty())
866 return 0;
867
868 unsigned int Size = 0;
869 for(int i=0;i<Constants.size();i++) {
870 llvm::MachineConstantPoolEntry CPE = Constants[i];
871 unsigned int AlignMask = CPE.getAlignment() - 1;
872 Size = (Size + AlignMask) & ~AlignMask;
873 const llvm::Type* Ty = CPE.getType();
874 Size += mpTD->getTypeAllocSize(Ty);
875 }
876
877 return Size;
878 }
879
880 /*
881 * This function converts a Constant* into a GenericValue. The interesting
882 * part is if C is a ConstantExpr.
883 */
884 void GetConstantValue(const llvm::Constant *C, llvm::GenericValue& Result) {
885 if(C->getValueID() == llvm::Value::UndefValueVal)
886 return;
887 else if(C->getValueID() == llvm::Value::ConstantExprVal) {
888 const llvm::ConstantExpr* CE = (llvm::ConstantExpr*) C;
889 const llvm::Constant* Op0 = CE->getOperand(0);
890
891 switch(CE->getOpcode()) {
892 case llvm::Instruction::GetElementPtr:
893 {
894 /* Compute the index */
895 llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
896 CE->op_end());
897 uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(),
898 &Indices[0],
899 Indices.size());
900
901 GetConstantValue(Op0, Result);
902 Result.PointerVal = (char*) Result.PointerVal + Offset;
903
904 return;
905 }
906 break;
907
908 case llvm::Instruction::Trunc:
909 {
910 uint32_t BitWidth =
911 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
912
913 GetConstantValue(Op0, Result);
914 Result.IntVal = Result.IntVal.trunc(BitWidth);
915
916 return;
917 }
918 break;
919
920 case llvm::Instruction::ZExt:
921 {
922 uint32_t BitWidth =
923 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
924
925 GetConstantValue(Op0, Result);
926 Result.IntVal = Result.IntVal.zext(BitWidth);
927
928 return;
929 }
930 break;
931
932 case llvm::Instruction::SExt:
933 {
934 uint32_t BitWidth =
935 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
936
937 GetConstantValue(Op0, Result);
938 Result.IntVal = Result.IntVal.sext(BitWidth);
939
940 return;
941 }
942 break;
943
944
945 case llvm::Instruction::FPTrunc:
946 {
947 /* FIXME long double */
948 GetConstantValue(Op0, Result);
949 Result.FloatVal = float(Result.DoubleVal);
950 return;
951 }
952 break;
953
954
955 case llvm::Instruction::FPExt:
956 {
957 /* FIXME long double */
958 GetConstantValue(Op0, Result);
959 Result.DoubleVal = double(Result.FloatVal);
960 return;
961 }
962 break;
963
964
965 case llvm::Instruction::UIToFP:
966 {
967 GetConstantValue(Op0, Result);
968 if(CE->getType()->isFloatTy())
969 Result.FloatVal = float(Result.IntVal.roundToDouble());
970 else if(CE->getType()->isDoubleTy())
971 Result.DoubleVal = Result.IntVal.roundToDouble();
972 else if(CE->getType()->isX86_FP80Ty()) {
973 const uint64_t zero[] = { 0, 0 };
974 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
975 apf.convertFromAPInt(Result.IntVal,
976 false,
977 llvm::APFloat::rmNearestTiesToEven);
978 Result.IntVal = apf.bitcastToAPInt();
979 }
980 return;
981 }
982 break;
983
984 case llvm::Instruction::SIToFP:
985 {
986 GetConstantValue(Op0, Result);
987 if(CE->getType()->isFloatTy())
988 Result.FloatVal = float(Result.IntVal.signedRoundToDouble());
989 else if(CE->getType()->isDoubleTy())
990 Result.DoubleVal = Result.IntVal.signedRoundToDouble();
991 else if(CE->getType()->isX86_FP80Ty()) {
992 const uint64_t zero[] = { 0, 0 };
993 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
994 apf.convertFromAPInt(Result.IntVal,
995 true,
996 llvm::APFloat::rmNearestTiesToEven);
997 Result.IntVal = apf.bitcastToAPInt();
998 }
999 return;
1000 }
1001 break;
1002
1003 /* double->APInt conversion handles sign */
1004 case llvm::Instruction::FPToUI:
1005 case llvm::Instruction::FPToSI:
1006 {
1007 uint32_t BitWidth =
1008 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
1009
1010 GetConstantValue(Op0, Result);
1011 if(Op0->getType()->isFloatTy())
1012 Result.IntVal =
1013 llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
1014 else if(Op0->getType()->isDoubleTy())
1015 Result.IntVal =
1016 llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal, BitWidth);
1017 else if(Op0->getType()->isX86_FP80Ty()) {
1018 llvm::APFloat apf = llvm::APFloat(Result.IntVal);
1019 uint64_t v;
1020 bool ignored;
1021 apf.convertToInteger(&v,
1022 BitWidth,
1023 CE->getOpcode()
1024 == llvm::Instruction::FPToSI,
1025 llvm::APFloat::rmTowardZero,
1026 &ignored);
1027 Result.IntVal = v; // endian?
1028 }
1029 return;
1030 }
1031 break;
1032
1033 case llvm::Instruction::PtrToInt:
1034 {
1035 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1036
1037 GetConstantValue(Op0, Result);
1038 Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
1039 (Result.PointerVal));
1040
1041 return;
1042 }
1043 break;
1044
1045 case llvm::Instruction::IntToPtr:
1046 {
1047 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1048
1049 GetConstantValue(Op0, Result);
1050 if(PtrWidth != Result.IntVal.getBitWidth())
1051 Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
1052 assert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
1053
1054 Result.PointerVal = llvm::PointerTy
1055 (uintptr_t(Result.IntVal.getZExtValue()));
1056
1057 return;
1058 }
1059 break;
1060
1061 case llvm::Instruction::BitCast:
1062 {
1063 GetConstantValue(Op0, Result);
1064 const llvm::Type* DestTy = CE->getType();
1065
1066 switch(Op0->getType()->getTypeID()) {
1067 case llvm::Type::IntegerTyID:
1068 assert(DestTy->isFloatingPointTy() && "invalid bitcast");
1069 if(DestTy->isFloatTy())
1070 Result.FloatVal = Result.IntVal.bitsToFloat();
1071 else if(DestTy->isDoubleTy())
1072 Result.DoubleVal = Result.IntVal.bitsToDouble();
1073 break;
1074
1075 case llvm::Type::FloatTyID:
1076 assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
1077 Result.IntVal.floatToBits(Result.FloatVal);
1078 break;
1079
1080 case llvm::Type::DoubleTyID:
1081 assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
1082 Result.IntVal.doubleToBits(Result.DoubleVal);
1083 break;
1084
1085 case llvm::Type::PointerTyID:
1086 assert(DestTy->isPointerTy() && "Invalid bitcast");
1087 break; // getConstantValue(Op0) above already converted it
1088
1089 default:
1090 llvm_unreachable("Invalid bitcast operand");
1091 break;
1092 }
1093
1094 return;
1095 }
1096 break;
1097
1098 case llvm::Instruction::Add:
1099 case llvm::Instruction::FAdd:
1100 case llvm::Instruction::Sub:
1101 case llvm::Instruction::FSub:
1102 case llvm::Instruction::Mul:
1103 case llvm::Instruction::FMul:
1104 case llvm::Instruction::UDiv:
1105 case llvm::Instruction::SDiv:
1106 case llvm::Instruction::URem:
1107 case llvm::Instruction::SRem:
1108 case llvm::Instruction::And:
1109 case llvm::Instruction::Or:
1110 case llvm::Instruction::Xor:
1111 {
1112 llvm::GenericValue LHS, RHS;
1113 GetConstantValue(Op0, LHS);
1114 GetConstantValue(CE->getOperand(1), RHS);
1115
1116 switch(Op0->getType()->getTypeID()) {
1117 case llvm::Type::IntegerTyID:
1118 switch (CE->getOpcode()) {
1119 case llvm::Instruction::Add:
1120 Result.IntVal = LHS.IntVal + RHS.IntVal;
1121 break;
1122 case llvm::Instruction::Sub:
1123 Result.IntVal = LHS.IntVal - RHS.IntVal;
1124 break;
1125 case llvm::Instruction::Mul:
1126 Result.IntVal = LHS.IntVal * RHS.IntVal;
1127 break;
1128 case llvm::Instruction::UDiv:
1129 Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
1130 break;
1131 case llvm::Instruction::SDiv:
1132 Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
1133 break;
1134 case llvm::Instruction::URem:
1135 Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
1136 break;
1137 case llvm::Instruction::SRem:
1138 Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
1139 break;
1140 case llvm::Instruction::And:
1141 Result.IntVal = LHS.IntVal & RHS.IntVal;
1142 break;
1143 case llvm::Instruction::Or:
1144 Result.IntVal = LHS.IntVal | RHS.IntVal;
1145 break;
1146 case llvm::Instruction::Xor:
1147 Result.IntVal = LHS.IntVal ^ RHS.IntVal;
1148 break;
1149 default:
1150 llvm_unreachable("Invalid integer opcode");
1151 break;
1152 }
1153 break;
1154
1155 case llvm::Type::FloatTyID:
1156 switch (CE->getOpcode()) {
1157 case llvm::Instruction::FAdd:
1158 Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
1159 break;
1160 case llvm::Instruction::FSub:
1161 Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
1162 break;
1163 case llvm::Instruction::FMul:
1164 Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
1165 break;
1166 case llvm::Instruction::FDiv:
1167 Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
1168 break;
1169 case llvm::Instruction::FRem:
1170 Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
1171 break;
1172 default:
1173 llvm_unreachable("Invalid float opcode");
1174 break;
1175 }
1176 break;
1177
1178 case llvm::Type::DoubleTyID:
1179 switch (CE->getOpcode()) {
1180 case llvm::Instruction::FAdd:
1181 Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
1182 break;
1183 case llvm::Instruction::FSub:
1184 Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
1185 break;
1186 case llvm::Instruction::FMul:
1187 Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
1188 break;
1189 case llvm::Instruction::FDiv:
1190 Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
1191 break;
1192 case llvm::Instruction::FRem:
1193 Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
1194 break;
1195 default:
1196 llvm_unreachable("Invalid double opcode");
1197 break;
1198 }
1199 break;
1200
1201 case llvm::Type::X86_FP80TyID:
1202 case llvm::Type::PPC_FP128TyID:
1203 case llvm::Type::FP128TyID:
1204 {
1205 llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
1206 switch (CE->getOpcode()) {
1207 case llvm::Instruction::FAdd:
1208 apfLHS.add(llvm::APFloat(RHS.IntVal),
1209 llvm::APFloat::rmNearestTiesToEven);
1210 break;
1211 case llvm::Instruction::FSub:
1212 apfLHS.subtract(llvm::APFloat(RHS.IntVal),
1213 llvm::APFloat::rmNearestTiesToEven);
1214 break;
1215 case llvm::Instruction::FMul:
1216 apfLHS.multiply(llvm::APFloat(RHS.IntVal),
1217 llvm::APFloat::rmNearestTiesToEven);
1218 break;
1219 case llvm::Instruction::FDiv:
1220 apfLHS.divide(llvm::APFloat(RHS.IntVal),
1221 llvm::APFloat::rmNearestTiesToEven);
1222 break;
1223 case llvm::Instruction::FRem:
1224 apfLHS.mod(llvm::APFloat(RHS.IntVal),
1225 llvm::APFloat::rmNearestTiesToEven);
1226 break;
1227 default:
1228 llvm_unreachable("Invalid long double opcode");
1229 llvm_unreachable(0);
1230 break;
1231 }
1232
1233 Result.IntVal = apfLHS.bitcastToAPInt();
1234 }
1235 break;
1236
1237 default:
1238 llvm_unreachable("Bad add type!");
1239 break;
1240 } /* End switch(Op0->getType()->getTypeID()) */
1241
1242 return;
1243 }
1244
1245 default:
1246 break;
1247 } /* End switch(CE->getOpcode()) */
1248
1249 std::string msg;
1250 llvm::raw_string_ostream Msg(msg);
1251 Msg << "ConstantExpr not handled: " << *CE;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001252 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001253 } /* C->getValueID() == llvm::Value::ConstantExprVal */
1254
1255 switch (C->getType()->getTypeID()) {
1256 case llvm::Type::FloatTyID:
1257 Result.FloatVal = llvm::cast<llvm::ConstantFP>(C)
1258 ->getValueAPF().convertToFloat();
1259 break;
1260
1261 case llvm::Type::DoubleTyID:
1262 Result.DoubleVal = llvm::cast<llvm::ConstantFP>(C)
1263 ->getValueAPF().convertToDouble();
1264 break;
1265
1266 case llvm::Type::X86_FP80TyID:
1267 case llvm::Type::FP128TyID:
1268 case llvm::Type::PPC_FP128TyID:
1269 Result.IntVal = llvm::cast <llvm::ConstantFP>(C)
1270 ->getValueAPF().bitcastToAPInt();
1271 break;
1272
1273 case llvm::Type::IntegerTyID:
1274 Result.IntVal = llvm::cast<llvm::ConstantInt>(C)
1275 ->getValue();
1276 break;
1277
1278 case llvm::Type::PointerTyID:
1279 switch(C->getValueID()) {
1280 case llvm::Value::ConstantPointerNullVal:
1281 Result.PointerVal = NULL;
1282 break;
1283
1284 case llvm::Value::FunctionVal:
1285 {
1286 const llvm::Function* F = (llvm::Function*) C;
1287 Result.PointerVal = GetPointerToFunctionOrStub
1288 (const_cast<llvm::Function*>(F)
1289 );
1290 }
1291 break;
1292
1293 case llvm::Value::GlobalVariableVal:
1294 {
1295 const llvm::GlobalVariable* GV = (llvm::GlobalVariable*) C;
1296 Result.PointerVal = GetOrEmitGlobalVariable
1297 (const_cast<llvm::GlobalVariable*>(GV)
1298 );
1299 }
1300 break;
1301
1302 case llvm::Value::BlockAddressVal:
1303 {
1304 // const llvm::BlockAddress* BA = (llvm::BlockAddress*) C;
1305 // Result.PointerVal = getPointerToBasicBlock
1306 // (const_cast<llvm::BasicBlock*>(BA->getBasicBlock()));
1307 assert(false && "JIT does not support address-of-label yet!");
1308 }
1309 break;
1310
1311 default:
1312 llvm_unreachable("Unknown constant pointer type!");
1313 break;
1314 }
1315 break;
1316
1317 default:
1318 std::string msg;
1319 llvm::raw_string_ostream Msg(msg);
1320 Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001321 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001322 break;
1323 }
1324
1325 return;
1326 }
1327
1328 /*
1329 * StoreValueToMemory -
1330 * Stores the data in @Val of type @Ty at address @Addr.
1331 */
1332 void StoreValueToMemory(const llvm::GenericValue& Val, void* Addr,
1333 const llvm::Type *Ty) {
1334 const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
1335
1336 switch(Ty->getTypeID()) {
1337 case llvm::Type::IntegerTyID:
1338 {
1339 const llvm::APInt& IntVal = Val.IntVal;
1340 assert((IntVal.getBitWidth() + 7) / 8 >= StoreBytes &&
1341 "Integer too small!");
1342
1343 uint8_t *Src = (uint8_t*) IntVal.getRawData();
1344
1345 if(llvm::sys::isLittleEndianHost()) {
1346 /*
1347 * Little-endian host - the source is ordered from LSB to MSB.
1348 * Order the destination from LSB to MSB: Do a straight copy.
1349 */
1350 memcpy(Addr, Src, StoreBytes);
1351 } else {
1352 /*
1353 * Big-endian host - the source is an array of 64 bit words
1354 * ordered from LSW to MSW.
1355 *
1356 * Each word is ordered from MSB to LSB.
1357 *
1358 * Order the destination from MSB to LSB:
1359 * Reverse the word order, but not the bytes in a word.
1360 */
1361 unsigned int i = StoreBytes;
1362 while(i > sizeof(uint64_t)) {
1363 i -= sizeof(uint64_t);
1364 memcpy((uint8_t*) Addr + i, Src, sizeof(uint64_t));
1365 Src += sizeof(uint64_t);
1366 }
1367
1368 memcpy(Addr, Src + sizeof(uint64_t) - i, i);
1369 }
1370 }
1371 break;
1372
1373 case llvm::Type::FloatTyID:
1374 {
1375 *((float*) Addr) = Val.FloatVal;
1376 }
1377 break;
1378
1379 case llvm::Type::DoubleTyID:
1380 {
1381 *((double*) Addr) = Val.DoubleVal;
1382 }
1383 break;
1384
1385 case llvm::Type::X86_FP80TyID:
1386 {
1387 memcpy(Addr, Val.IntVal.getRawData(), 10);
1388 }
1389 break;
1390
1391 case llvm::Type::PointerTyID:
1392 {
1393 /*
1394 * Ensure 64 bit target pointers are fully
1395 * initialized on 32 bit hosts.
1396 */
1397 if(StoreBytes != sizeof(llvm::PointerTy))
1398 memset(Addr, 0, StoreBytes);
1399 *((llvm::PointerTy*) Addr) = Val.PointerVal;
1400 }
1401 break;
1402
1403 default:
1404 break;
1405 }
1406
1407 if(llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
1408 std::reverse((uint8_t*) Addr, (uint8_t*) Addr + StoreBytes);
1409
1410 return;
1411 }
1412
1413 /*
1414 * InitializeConstantToMemory -
1415 * Recursive function to apply a @Constant value into the
1416 * specified memory location @Addr.
1417 */
1418 void InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
1419 switch(C->getValueID()) {
1420 case llvm::Value::UndefValueVal:
1421 // Nothing to do
1422 break;
1423
1424 case llvm::Value::ConstantVectorVal:
1425 {
1426 // dynamic cast may hurt performance
1427 const llvm::ConstantVector* CP = (llvm::ConstantVector*) C;
1428
1429 unsigned int ElementSize = mpTD->getTypeAllocSize
1430 (CP->getType()->getElementType());
1431
1432 for(int i=0;i<CP->getNumOperands();i++)
1433 InitializeConstantToMemory(CP->getOperand(i),
1434 (char*) Addr + i * ElementSize);
1435 }
1436 break;
1437
1438 case llvm::Value::ConstantAggregateZeroVal:
1439 memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
1440 break;
1441
1442 case llvm::Value::ConstantArrayVal:
1443 {
1444 const llvm::ConstantArray* CPA = (llvm::ConstantArray*) C;
1445 unsigned int ElementSize = mpTD->getTypeAllocSize
1446 (CPA->getType()->getElementType());
1447
1448 for(int i=0;i<CPA->getNumOperands();i++)
1449 InitializeConstantToMemory(CPA->getOperand(i),
1450 (char*) Addr + i * ElementSize);
1451 }
1452 break;
1453
1454 case llvm::Value::ConstantStructVal:
1455 {
1456 const llvm::ConstantStruct* CPS = (llvm::ConstantStruct*) C;
1457 const llvm::StructLayout* SL = mpTD->getStructLayout
1458 (llvm::cast<llvm::StructType>(CPS->getType()));
1459
1460 for(int i=0;i<CPS->getNumOperands();i++)
1461 InitializeConstantToMemory(CPS->getOperand(i),
1462 (char*) Addr +
1463 SL->getElementOffset(i));
1464 }
1465 break;
1466
1467 default:
1468 {
1469 if(C->getType()->isFirstClassType()) {
1470 llvm::GenericValue Val;
1471 GetConstantValue(C, Val);
1472 StoreValueToMemory(Val, Addr, C->getType());
1473 } else
1474 llvm_unreachable
1475 ("Unknown constant type to initialize memory with!");
1476 }
1477 break;
1478 }
1479
1480 return;
1481 }
1482
1483 void emitConstantPool(llvm::MachineConstantPool *MCP) {
1484 if(mpTJI->hasCustomConstantPool())
1485 return;
1486
1487 /*
1488 * Constant pool address resolution is handled by the target itself in ARM
1489 * (TargetJITInfo::hasCustomConstantPool() return true).
1490 */
1491#if !defined(PROVIDE_ARM_CODEGEN)
1492 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
1493 MCP->getConstants();
1494
1495 if(Constants.empty())
1496 return;
1497
1498 unsigned Size = GetConstantPoolSizeInBytes(MCP);
1499 unsigned Align = MCP->getConstantPoolAlignment();
1500
1501 mpConstantPoolBase = allocateSpace(Size, Align);
1502 mpConstantPool = MCP;
1503
1504 if(mpConstantPoolBase == NULL)
1505 return; /* out of memory */
1506
1507 unsigned Offset = 0;
1508 for(int i=0;i<Constants.size();i++) {
1509 llvm::MachineConstantPoolEntry CPE = Constants[i];
1510 unsigned AlignMask = CPE.getAlignment() - 1;
1511 Offset = (Offset + AlignMask) & ~AlignMask;
1512
1513 uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
1514 mConstPoolAddresses.push_back(CAddr);
1515
1516 if(CPE.isMachineConstantPoolEntry())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001517 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001518 ("Initialize memory with machine specific constant pool"
1519 " entry has not been implemented!");
1520
1521 InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
1522
1523 const llvm::Type *Ty = CPE.Val.ConstVal->getType();
1524 Offset += mpTD->getTypeAllocSize(Ty);
1525 }
1526#endif
1527 return;
1528 }
1529
1530 void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1531 if(mpTJI->hasCustomJumpTables())
1532 return;
1533
1534 const std::vector<llvm::MachineJumpTableEntry>& JT =
1535 MJTI->getJumpTables();
1536 if(JT.empty())
1537 return;
1538
1539 unsigned NumEntries = 0;
1540 for(int i=0;i<JT.size();i++)
1541 NumEntries += JT[i].MBBs.size();
1542
1543 unsigned EntrySize = MJTI->getEntrySize(*mpTD);
1544
1545 mpJumpTable = MJTI;;
1546 mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
1547 MJTI->getEntryAlignment(*mpTD));
1548
1549 return;
1550 }
1551
1552 void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1553 if(mpTJI->hasCustomJumpTables())
1554 return;
1555
1556 const std::vector<llvm::MachineJumpTableEntry>& JT =
1557 MJTI->getJumpTables();
1558 if(JT.empty() || mpJumpTableBase == 0)
1559 return;
1560
1561 assert((llvm::TargetMachine::getRelocationModel() == llvm::Reloc::Static)
1562 && "Cross JIT'ing?");
1563 assert(MJTI->getEntrySize(*mpTD) == sizeof(void*) && "Cross JIT'ing?");
1564
1565 /*
1566 * For each jump table, map each target in the jump table to the
1567 * address of an emitted MachineBasicBlock.
1568 */
1569 intptr_t *SlotPtr = (intptr_t*) mpJumpTableBase;
1570 for(int i=0;i<JT.size();i++) {
1571 const std::vector<llvm::MachineBasicBlock*>& MBBs = JT[i].MBBs;
1572 /*
1573 * Store the address of the basic block for this jump table slot in the
1574 * memory we allocated for the jump table in 'initJumpTableInfo'
1575 */
1576 for(int j=0;j<MBBs.size();j++)
1577 *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
1578 }
1579 }
1580
1581 void* GetPointerToGlobal(llvm::GlobalValue* V, void* Reference,
1582 bool MayNeedFarStub) {
1583 switch(V->getValueID()) {
1584 case llvm::Value::FunctionVal:
1585 {
1586 llvm::Function* F = (llvm::Function*) V;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001587
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001588 /* If we have code, go ahead and return that. */
1589 if(void* ResultPtr = GetPointerToGlobalIfAvailable(F))
1590 return ResultPtr;
1591
1592 if(void* FnStub = GetLazyFunctionStubIfAvailable(F))
1593 /*
1594 * Return the function stub if it's already created.
1595 * We do this first so that:
1596 * we're returning the same address for the function
1597 * as any previous call.
1598 *
1599 * TODO: Yes, this is wrong. The lazy stub isn't guaranteed
1600 * to be close enough to call.
1601 */
1602 return FnStub;
1603
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001604 /*
1605 * If we know the target can handle arbitrary-distance calls, try to
1606 * return a direct pointer.
1607 */
1608 if(!MayNeedFarStub) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001609 /*
1610 * x86_64 architecture may encounter the bug
1611 * http://hlvm.llvm.org/bugs/show_bug.cgi?id=5201
1612 * which generate instruction "call" instead of "callq".
1613 *
1614 * And once the real address of stub is
1615 * greater than 64-bit long, the replacement will truncate
1616 * to 32-bit resulting a serious problem.
1617 */
1618#if !defined(__x86_64__)
1619 /*
1620 * If this is an external function pointer,
1621 * we can force the JIT to
1622 * 'compile' it, which really just adds it to the map.
1623 */
1624 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1625 return GetPointerToFunction(F, /* AbortOnFailure */true);
1626#endif
1627 }
1628
1629 /*
1630 * Otherwise, we may need a to emit a stub, and, conservatively, we
1631 * always do so.
1632 */
1633 return GetLazyFunctionStub(F);
1634 }
1635 break;
1636
1637 case llvm::Value::GlobalVariableVal:
1638 return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
1639 break;
1640
1641 case llvm::Value::GlobalAliasVal:
1642 {
1643 llvm::GlobalAlias* GA = (llvm::GlobalAlias*) V;
1644 const llvm::GlobalValue* GV = GA->resolveAliasedGlobal(false);
1645
1646 switch(GV->getValueID()) {
1647 case llvm::Value::FunctionVal:
1648 /* FIXME: is there's any possibility that the function
1649 is not code-gen'd? */
1650 return GetPointerToFunction(
1651 const_cast<llvm::Function*>((const llvm::Function*) GV),
1652 /* AbortOnFailure */true
1653 );
1654 break;
1655
1656 case llvm::Value::GlobalVariableVal:
1657 {
1658 if(void* p = mGlobalAddressMap[GV])
1659 return p;
1660
1661 llvm::GlobalVariable* GVar = (llvm::GlobalVariable*) GV;
1662 EmitGlobalVariable(GVar);
1663
1664 return mGlobalAddressMap[GV];
1665 }
1666 break;
1667
1668 case llvm::Value::GlobalAliasVal:
1669 assert(false && "Alias should be resolved ultimately!");
1670 break;
1671 }
1672 }
1673 break;
1674
1675 default:
1676 break;
1677 }
1678
1679 llvm_unreachable("Unknown type of global value!");
1680
1681 }
1682
1683 /*
1684 * GetPointerToFunctionOrStub - If the specified function has been
1685 * code-gen'd, return a pointer to the function.
1686 * If not, compile it, or use
1687 * a stub to implement lazy compilation if available.
1688 */
1689 void* GetPointerToFunctionOrStub(llvm::Function* F) {
1690 /*
1691 * If we have already code generated the function,
1692 * just return the address.
1693 */
1694 if(void* Addr = GetPointerToGlobalIfAvailable(F))
1695 return Addr;
1696
1697 /* Get a stub if the target supports it. */
1698 return GetLazyFunctionStub(F);
1699 }
1700
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001701 typedef llvm::DenseMap<const llvm::Function*, void*> FunctionToLazyStubMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001702 FunctionToLazyStubMapTy mFunctionToLazyStubMap;
1703
1704 void* GetLazyFunctionStubIfAvailable(llvm::Function* F) {
1705 return mFunctionToLazyStubMap.lookup(F);
1706 }
1707
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001708 std::set<const llvm::Function*> PendingFunctions;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001709 void* GetLazyFunctionStub(llvm::Function* F) {
1710 /* If we already have a lazy stub for this function, recycle it. */
1711 void*& Stub = mFunctionToLazyStubMap[F];
1712 if(Stub)
1713 return Stub;
1714
1715 /*
1716 * In any cases, we should NOT resolve function at runtime
1717 * (though we are able to).
1718 * We resolve this right now.
1719 */
1720 void* Actual = NULL;
1721 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1722 Actual = GetPointerToFunction(F, /* AbortOnFailure */true);
1723
1724 /*
1725 * Codegen a new stub, calling the actual address of
1726 * the external function, if it was resolved.
1727 */
1728 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1729 startGVStub(F, SL.Size, SL.Alignment);
1730 Stub = mpTJI->emitFunctionStub(F, Actual, *this);
1731 finishGVStub();
1732
1733 /*
1734 * We really want the address of the stub in the GlobalAddressMap
1735 * for the JIT, not the address of the external function.
1736 */
1737 UpdateGlobalMapping(F, Stub);
1738
1739 if(!Actual)
1740 PendingFunctions.insert(F);
1741 else
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001742 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001743
1744 return Stub;
1745 }
1746
1747 /* Our resolver to undefined symbol */
1748 BCCSymbolLookupFn mpSymbolLookupFn;
1749 void* mpSymbolLookupContext;
1750
1751 void* GetPointerToFunction(llvm::Function* F, bool AbortOnFailure) {
1752 void* Addr = GetPointerToGlobalIfAvailable(F);
1753 if(Addr)
1754 return Addr;
1755
1756 assert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
1757 "Internal error: only external defined function routes here!");
1758
1759 /* Handle the failure resolution by ourselves. */
1760 Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
1761 /* AbortOnFailure */ false);
1762
1763 /*
1764 * If we resolved the symbol to a null address (eg. a weak external)
1765 * return a null pointer let the application handle it.
1766 */
1767 if(Addr == NULL)
1768 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001769 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001770 ("Could not resolve external function address: " + F->getName()
1771 );
1772 else
1773 return NULL;
1774
1775 AddGlobalMapping(F, Addr);
1776
1777 return Addr;
1778 }
1779
1780 void* GetPointerToNamedSymbol(const std::string& Name,
1781 bool AbortOnFailure) {
1782 if(void* Addr = FindRuntimeFunction(Name.c_str()))
1783 return Addr;
1784
1785 if(mpSymbolLookupFn)
1786 if(void* Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
1787 return Addr;
1788
1789 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001790 llvm::report_fatal_error("Program used external symbol '" + Name +
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001791 "' which could not be resolved!");
1792
1793 return NULL;
1794 }
1795
1796 /*
1797 * GetOrEmitGlobalVariable - Return the address of the specified global
1798 * variable, possibly emitting it to memory if needed. This is used by the
1799 * Emitter.
1800 */
1801 void* GetOrEmitGlobalVariable(const llvm::GlobalVariable *GV) {
1802 void* Ptr = GetPointerToGlobalIfAvailable(GV);
1803 if(Ptr)
1804 return Ptr;
1805
1806 if(GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
1807 /* If the global is external, just remember the address. */
1808 Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
1809 AddGlobalMapping(GV, Ptr);
1810 } else {
1811 /* If the global hasn't been emitted to memory yet,
1812 allocate space and emit it into memory. */
1813 Ptr = GetMemoryForGV(GV);
1814 AddGlobalMapping(GV, Ptr);
1815 EmitGlobalVariable(GV);
1816 }
1817
1818 return Ptr;
1819 }
1820
1821 /*
1822 * GetMemoryForGV - This method abstracts memory allocation of global
1823 * variable so that the JIT can allocate thread local variables depending
1824 * on the target.
1825 */
1826 void* GetMemoryForGV(const llvm::GlobalVariable* GV) {
1827 char* Ptr;
1828
1829 const llvm::Type* GlobalType = GV->getType()->getElementType();
1830 size_t S = mpTD->getTypeAllocSize(GlobalType);
1831 size_t A = mpTD->getPreferredAlignment(GV);
1832
1833 if(GV->isThreadLocal()) {
1834 /*
1835 * We can support TLS by
1836 *
1837 * Ptr = TJI.allocateThreadLocalMemory(S);
1838 *
1839 * But I tend not to .
1840 * (should we disable this in the front-end (i.e. slang)?).
1841 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001842 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001843 ("Compilation of Thread Local Storage (TLS) is disabled!");
1844
1845 } else if(mpTJI->allocateSeparateGVMemory()) {
1846 /*
1847 * On the Apple's ARM target (such as iPhone),
1848 * the global variable should be
1849 * placed in separately allocated heap memory rather than in the same
1850 * code memory.
1851 * The question is, how about the Android?
1852 */
1853 if(A <= 8) {
1854 Ptr = (char*) malloc(S);
1855 } else {
1856 /*
1857 * Allocate (S + A) bytes of memory,
1858 * then use an aligned pointer within that space.
1859 */
1860 Ptr = (char*) malloc(S + A);
1861 unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
1862 Ptr = Ptr + (MisAligned ? (A - MisAligned) : 0);
1863 }
1864 } else {
1865 Ptr = (char*) allocateGlobal(S, A);
1866 }
1867
1868 return Ptr;
1869 }
1870
1871 void EmitGlobalVariable(const llvm::GlobalVariable *GV) {
1872 void* GA = GetPointerToGlobalIfAvailable(GV);
1873
1874 if(GV->isThreadLocal())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001875 llvm::report_fatal_error
1876 ("We don't support Thread Local Storage (TLS)!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001877
1878 if(GA == NULL) {
1879 /* If it's not already specified, allocate memory for the global. */
1880 GA = GetMemoryForGV(GV);
1881 AddGlobalMapping(GV, GA);
1882 }
1883
1884 InitializeConstantToMemory(GV->getInitializer(), GA);
1885
1886 /* You can do some statistics on global variable here */
1887 return;
1888 }
1889
1890 typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void*
1891 > GlobalToIndirectSymMapTy;
1892 GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
1893
1894 void* GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
1895 /*
1896 * Make sure GV is emitted first, and create a stub containing the fully
1897 * resolved address.
1898 */
1899 void* GVAddress = GetPointerToGlobal(V, Reference, false);
1900
1901 /* If we already have a stub for this global variable, recycle it. */
1902 void*& IndirectSym = GlobalToIndirectSymMap[V];
1903 /* Otherwise, codegen a new indirect symbol. */
1904 if(!IndirectSym)
1905 IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
1906
1907 return IndirectSym;
1908 }
1909
1910 /*
1911 * ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap
1912 * for external functions.
1913 *
1914 * TODO: Of course, external functions don't need a lazy stub.
1915 * It's actually
1916 * here to make it more likely that far calls succeed, but no single
1917 * stub can guarantee that. I'll remove this in a subsequent checkin
1918 * when I actually fix far calls. (comment from LLVM source)
1919 */
1920 std::map<void*, void*> ExternalFnToStubMap;
1921
1922 /*
1923 * GetExternalFunctionStub - Return a stub for the function at the
1924 * specified address.
1925 */
1926 void* GetExternalFunctionStub(void* FnAddr) {
1927 void*& Stub = ExternalFnToStubMap[FnAddr];
1928 if(Stub)
1929 return Stub;
1930
1931 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1932 startGVStub(0, SL.Size, SL.Alignment);
1933 Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
1934 finishGVStub();
1935
1936 return Stub;
1937 }
1938
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001939#if defined(USE_DISASSEMBLER)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001940 const llvm::MCAsmInfo* mpAsmInfo;
1941 const llvm::MCDisassembler* mpDisassmbler;
1942 llvm::MCInstPrinter* mpIP;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001943
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001944 class BufferMemoryObject : public llvm::MemoryObject {
1945 private:
1946 const uint8_t* mBytes;
1947 uint64_t mLength;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001948
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001949 public:
1950 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) :
1951 mBytes(Bytes), mLength(Length) { }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001952
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001953 uint64_t getBase() const { return 0; }
1954 uint64_t getExtent() const { return mLength; }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001955
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001956 int readByte(uint64_t Addr, uint8_t *Byte) const {
1957 if(Addr > getExtent())
1958 return -1;
1959 *Byte = mBytes[Addr];
1960 return 0;
1961 }
1962 };
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001963
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001964 void Disassemble(const llvm::StringRef& Name, uint8_t* Start,
1965 size_t Length, bool IsStub) {
1966
1967 llvm::raw_ostream* OS = &llvm::outs();
1968
1969#if 0
1970 /* If you want the disassemble results write to file, uncomment this */
1971 std::string ErrorInfo;
1972 llvm::raw_fd_ostream* OS = new llvm::raw_fd_ostream(
1973 <const char* FileName>, ErrorInfo, llvm::raw_fd_ostream::F_Append);
1974 if(!ErrorInfo.empty()) { // some errors occurred
1975 delete OS;
1976 return;
1977 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001978#endif
1979
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001980 *OS << "JIT: Disassembled code: " << Name
1981 << ((IsStub) ? " (stub)" : "") << "\n";
1982
1983 if(mpAsmInfo == NULL)
1984 mpAsmInfo = mpTarget->createAsmInfo(Triple);
1985 if(mpDisassmbler == NULL)
1986 mpDisassmbler = mpTarget->createMCDisassembler();
1987 if(mpIP == NULL)
1988 mpIP = mpTarget->createMCInstPrinter(
1989 mpAsmInfo->getAssemblerDialect(), *mpAsmInfo);
1990
1991 const BufferMemoryObject* BufferMObj =
1992 new BufferMemoryObject(Start, Length);
1993 uint64_t Size;
1994 uint64_t Index;
1995
1996 for(Index=0;Index<Length;Index+=Size) {
1997 llvm::MCInst Inst;
1998
1999 if(mpDisassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
2000 /* REMOVED */ llvm::nulls()))
2001 {
2002 OS->indent(4).write("0x", 2).
2003 write_hex((uint64_t) Start + Index).write(':');
2004 mpIP->printInst(&Inst, *OS);
2005 *OS << "\n";
2006 } else {
2007 if (Size == 0)
2008 Size = 1; // skip illegible bytes
2009 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002010 }
2011
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002012 *OS << "\n";
2013 delete BufferMObj;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002014
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002015#if 0
2016 /* If you want the disassemble results write to file, uncomment this */
2017 OS->close();
2018 delete OS;
2019#endif
2020
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002021 return;
2022 }
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002023#else
2024 void Disassemble(const std::string& Name, uint8_t* Start,
2025 size_t Length, bool IsStub) {
2026 return;
2027 }
2028#endif /* defined(USE_DISASSEMBLER) */
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002029
2030 public:
2031 /* Will take the ownership of @MemMgr */
2032 CodeEmitter(CodeMemoryManager* pMemMgr) :
2033 mpMemMgr(pMemMgr),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002034 mpTarget(NULL),
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002035 mpTJI(NULL),
2036 mpTD(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002037#if defined(USE_DISASSEMBLER)
2038 mpAsmInfo(NULL),
2039 mpDisassmbler(NULL),
2040 mpIP(NULL),
2041#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002042 mpCurEmitFunction(NULL),
2043 mpConstantPool(NULL),
2044 mpJumpTable(NULL),
2045 mpMMI(NULL),
2046 mpSymbolLookupFn(NULL),
2047 mpSymbolLookupContext(NULL)
2048 {
2049 return;
2050 }
2051
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002052 inline global_addresses_const_iterator global_address_begin() const {
2053 return mGlobalAddressMap.begin();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002054 }
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002055 inline global_addresses_const_iterator global_address_end() const {
2056 return mGlobalAddressMap.end();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002057 }
2058
2059 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2060 mpSymbolLookupFn = pFn;
2061 mpSymbolLookupContext = pContext;
2062 return;
2063 }
2064
2065 void setTargetMachine(llvm::TargetMachine& TM) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002066 /* set Target */
2067 mpTarget = &TM.getTarget();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002068 /* set TargetJITInfo */
2069 mpTJI = TM.getJITInfo();
2070 /* set TargetData */
2071 mpTD = TM.getTargetData();
2072
2073 /*
2074 if(mpTJI->needsGOT())
2075 mpMemMgr->AllocateGOT(); // however,
2076 // both X86 and ARM target don't need GOT
2077 // (mpTJI->needsGOT() always returns false)
2078 */
2079 assert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
2080
2081 return;
2082 }
2083
2084 /*
2085 * startFunction - This callback is invoked when the specified function is
2086 * about to be code generated. This initializes the BufferBegin/End/Ptr
2087 * fields.
2088 */
2089 void startFunction(llvm::MachineFunction &F) {
2090 uintptr_t ActualSize = 0;
2091
2092 mpMemMgr->setMemoryWritable();
2093
2094 /*
2095 * BufferBegin, BufferEnd and CurBufferPtr
2096 * are all inherited from class MachineCodeEmitter,
2097 * which is the super class of the class JITCodeEmitter.
2098 *
2099 * BufferBegin/BufferEnd - Pointers to the start and end of the memory
2100 * allocated for this code buffer.
2101 *
2102 * CurBufferPtr - Pointer to the next byte of memory to fill when emitting
2103 * code.
2104 * This is guranteed to be in the range [BufferBegin,BufferEnd]. If
2105 * this pointer is at BufferEnd, it will never move due to code emission,
2106 * and
2107 * all code emission requests will be ignored (this is
2108 * the buffer overflow condition).
2109 */
2110 BufferBegin = CurBufferPtr = mpMemMgr
2111 ->startFunctionBody(F.getFunction(), ActualSize);
2112 BufferEnd = BufferBegin + ActualSize;
2113
2114 if(mpCurEmitFunction == NULL)
2115 mpCurEmitFunction = new EmittedFunctionCode();
2116 mpCurEmitFunction->FunctionBody = BufferBegin;
2117
2118 /* Ensure the constant pool/jump table info is at least 4-byte aligned. */
2119 emitAlignment(16);
2120
2121 emitConstantPool(F.getConstantPool());
2122 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2123 initJumpTableInfo(MJTI);
2124
2125 /* About to start emitting the machine code for the function. */
2126 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
2127
2128 UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
2129
2130 mpCurEmitFunction->Code = CurBufferPtr;
2131
2132 mMBBLocations.clear();
2133
2134 return;
2135 }
2136
2137 /*
2138 * finishFunction - This callback is invoked
2139 * when the specified function has
2140 * finished code generation.
2141 * If a buffer overflow has occurred, this method
2142 * returns true (the callee is required to try again), otherwise it returns
2143 * false.
2144 */
2145 bool finishFunction(llvm::MachineFunction &F) {
2146 if(CurBufferPtr == BufferEnd) {
2147 /* No enough memory */
2148 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2149 return false;
2150 }
2151
2152 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2153 emitJumpTableInfo(MJTI);
2154
2155 /*
2156 * FnStart is the start of the text,
2157 * not the start of the constant pool and other per-function data.
2158 */
2159 uint8_t* FnStart = (uint8_t*) GetPointerToGlobalIfAvailable
2160 (F.getFunction());
2161
2162 /* FnEnd is the end of the function's machine code. */
2163 uint8_t* FnEnd = CurBufferPtr;
2164
2165 if(!mRelocations.empty()) {
2166 /* Resolve the relocations to concrete pointers. */
2167 for(int i=0;i<mRelocations.size();i++) {
2168 llvm::MachineRelocation& MR = mRelocations[i];
2169 void* ResultPtr = NULL;
2170
2171 if(!MR.letTargetResolve()) {
2172 if(MR.isExternalSymbol()) {
2173 ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
2174 if(MR.mayNeedFarStub())
2175 ResultPtr = GetExternalFunctionStub(ResultPtr);
2176 } else if(MR.isGlobalValue()) {
2177 ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
2178 BufferBegin
2179 + MR.getMachineCodeOffset(),
2180 MR.mayNeedFarStub());
2181 } else if(MR.isIndirectSymbol()) {
2182 ResultPtr = GetPointerToGVIndirectSym
2183 (MR.getGlobalValue(),
2184 BufferBegin + MR.getMachineCodeOffset()
2185 );
2186 } else if(MR.isBasicBlock()) {
2187 ResultPtr =
2188 (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
2189 } else if(MR.isConstantPoolIndex()) {
2190 ResultPtr =
2191 (void*) getConstantPoolEntryAddress
2192 (MR.getConstantPoolIndex());
2193 } else {
2194 assert(MR.isJumpTableIndex() && "Unknown type of relocation");
2195 ResultPtr =
2196 (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
2197 }
2198
2199 MR.setResultPointer(ResultPtr);
2200 }
2201 }
2202
2203 mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
2204 mpMemMgr->getGOTBase());
2205 }
2206
2207 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2208 /*
2209 * CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
2210 * global variables that were referenced in the relocations.
2211 */
2212 if(CurBufferPtr == BufferEnd)
2213 return false;
2214
2215 /* Now that we've succeeded in emitting the function */
2216 mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
2217 BufferBegin = CurBufferPtr = 0;
2218
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002219 if(F.getFunction()->hasName())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002220 mEmittedFunctions[F.getFunction()->getNameStr()] = mpCurEmitFunction;
2221 mpCurEmitFunction = NULL;
2222
2223 mRelocations.clear();
2224 mConstPoolAddresses.clear();
2225
2226 /* Mark code region readable and executable if it's not so already. */
2227 mpMemMgr->setMemoryExecutable();
2228
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002229 Disassemble(F.getFunction()->getName(), FnStart, FnEnd - FnStart, false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002230
2231 if(mpMMI)
2232 mpMMI->EndFunction();
2233
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002234 updateFunctionStub(F.getFunction());
2235
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002236 return false;
2237 }
2238
2239 void startGVStub(const llvm::GlobalValue* GV, unsigned StubSize,
2240 unsigned Alignment) {
2241 mpSavedBufferBegin = BufferBegin;
2242 mpSavedBufferEnd = BufferEnd;
2243 mpSavedCurBufferPtr = CurBufferPtr;
2244
2245 BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
2246 Alignment);
2247 BufferEnd = BufferBegin + StubSize + 1;
2248
2249 return;
2250 }
2251
2252 void startGVStub(void* Buffer, unsigned StubSize) {
2253 mpSavedBufferBegin = BufferBegin;
2254 mpSavedBufferEnd = BufferEnd;
2255 mpSavedCurBufferPtr = CurBufferPtr;
2256
2257 BufferBegin = CurBufferPtr = (uint8_t *) Buffer;
2258 BufferEnd = BufferBegin + StubSize + 1;
2259
2260 return;
2261 }
2262
2263 void finishGVStub() {
2264 assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
2265
2266 /* restore */
2267 BufferBegin = mpSavedBufferBegin;
2268 BufferEnd = mpSavedBufferEnd;
2269 CurBufferPtr = mpSavedCurBufferPtr;
2270
2271 return;
2272 }
2273
2274 /*
2275 * allocIndirectGV - Allocates and fills storage for an indirect
2276 * GlobalValue, and returns the address.
2277 */
2278 void* allocIndirectGV(const llvm::GlobalValue *GV,
2279 const uint8_t *Buffer, size_t Size,
2280 unsigned Alignment) {
2281 uint8_t* IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
2282 memcpy(IndGV, Buffer, Size);
2283 return IndGV;
2284 }
2285
2286 /* emitLabel - Emits a label */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002287 void emitLabel(llvm::MCSymbol *Label) {
2288 mLabelLocations[Label] = getCurrentPCValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002289 return;
2290 }
2291
2292 /*
2293 * allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
2294 * this method does not allocate memory in the current output buffer,
2295 * because a global may live longer than the current function.
2296 */
2297 void* allocateGlobal(uintptr_t Size, unsigned Alignment) {
2298 /* Delegate this call through the memory manager. */
2299 return mpMemMgr->allocateGlobal(Size, Alignment);
2300 }
2301
2302 /*
2303 * StartMachineBasicBlock - This should be called by the target when a new
2304 * basic block is about to be emitted. This way the MCE knows where the
2305 * start of the block is, and can implement getMachineBasicBlockAddress.
2306 */
2307 void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
2308 if(mMBBLocations.size() <= (unsigned) MBB->getNumber())
2309 mMBBLocations.resize((MBB->getNumber() + 1) * 2);
2310 mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
2311 return;
2312 }
2313
2314 /*
2315 * addRelocation - Whenever a relocatable address is needed, it should be
2316 * noted with this interface.
2317 */
2318 void addRelocation(const llvm::MachineRelocation &MR) {
2319 mRelocations.push_back(MR);
2320 return;
2321 }
2322
2323 /*
2324 * getConstantPoolEntryAddress - Return the address of the 'Index' entry in
2325 * the constant pool that was last emitted with
2326 * the emitConstantPool method.
2327 */
2328 uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
2329 assert(Index < mpConstantPool->getConstants().size() &&
2330 "Invalid constant pool index!");
2331 return mConstPoolAddresses[Index];
2332 }
2333
2334 /*
2335 * getJumpTableEntryAddress - Return the address of the jump table
2336 * with index
2337 * 'Index' in the function that last called initJumpTableInfo.
2338 */
2339 uintptr_t getJumpTableEntryAddress(unsigned Index) const {
2340 const std::vector<llvm::MachineJumpTableEntry>& JT =
2341 mpJumpTable->getJumpTables();
2342
2343 assert(Index < JT.size() && "Invalid jump table index!");
2344
2345 unsigned int Offset = 0;
2346 unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
2347
2348 for(int i=0;i<Index;i++)
2349 Offset += JT[i].MBBs.size();
2350 Offset *= EntrySize;
2351
2352 return (uintptr_t)((char *) mpJumpTableBase + Offset);
2353 }
2354
2355 /*
2356 * getMachineBasicBlockAddress - Return the address of the specified
2357 * MachineBasicBlock, only usable after the label for the MBB has been
2358 * emitted.
2359 */
2360 uintptr_t getMachineBasicBlockAddress(llvm::MachineBasicBlock *MBB) const {
2361 assert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
2362 mMBBLocations[MBB->getNumber()] && "MBB not emitted!");
2363 return mMBBLocations[MBB->getNumber()];
2364 }
2365
2366 /*
2367 * getLabelAddress - Return the address of the specified LabelID,
2368 * only usable after the LabelID has been emitted.
2369 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002370 uintptr_t getLabelAddress(llvm::MCSymbol* Label) const {
2371 assert(mLabelLocations.count(Label) && "Label not emitted!");
2372 return mLabelLocations.find(Label)->second;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002373 }
2374
2375 /*
2376 * Specifies the MachineModuleInfo object.
2377 * This is used for exception handling
2378 * purposes.
2379 */
2380 void setModuleInfo(llvm::MachineModuleInfo* Info) {
2381 mpMMI = Info;
2382 return;
2383 }
2384
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002385 void updateFunctionStub(const llvm::Function* F) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002386 /* Get the empty stub we generated earlier. */
2387 void* Stub;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002388 std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002389 if(I != PendingFunctions.end())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002390 Stub = mFunctionToLazyStubMap[F];
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002391 else
2392 return;
2393
2394 void* Addr = GetPointerToGlobalIfAvailable(F);
2395
2396 assert(Addr != Stub &&
2397 "Function must have non-stub address to be updated.");
2398
2399 /*
2400 * Tell the target jit info to rewrite the stub at the specified address,
2401 * rather than creating a new one.
2402 */
2403 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
2404 startGVStub(Stub, SL.Size);
2405 mpTJI->emitFunctionStub(F, Addr, *this);
2406 finishGVStub();
2407
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002408 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002409
2410 PendingFunctions.erase(I);
2411
2412 return;
2413 }
2414
2415 /*
2416 * Once you finish the compilation on a translation unit,
2417 * you can call this function to recycle the memory
2418 * (which is used at compilation time and not needed for runtime).
2419 *
2420 * NOTE: You should not call this funtion until the code-gen passes
2421 * for a given module is done.
2422 * Otherwise, the results is undefined and may cause the system crash!
2423 */
2424 void releaseUnnecessary() {
2425 mMBBLocations.clear();
2426 mLabelLocations.clear();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002427 mGlobalAddressMap.clear();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002428 mFunctionToLazyStubMap.clear();
2429 GlobalToIndirectSymMap.clear();
2430 ExternalFnToStubMap.clear();
2431 PendingFunctions.clear();
2432
2433 return;
2434 }
2435
2436 void reset() {
2437 releaseUnnecessary();
2438
2439 mpSymbolLookupFn = NULL;
2440 mpSymbolLookupContext = NULL;
2441
2442 mpTJI = NULL;
2443 mpTD = NULL;
2444
2445 for(EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin();
2446 I != mEmittedFunctions.end();
2447 I++)
2448 if(I->second != NULL)
2449 delete I->second;
2450 mEmittedFunctions.clear();
2451
2452 mpMemMgr->reset();
2453
2454 return;
2455 }
2456
2457 void* lookup(const char* Name) {
2458 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(Name);
2459 if(I == mEmittedFunctions.end())
2460 return NULL;
2461 else
2462 return I->second->Code;
2463 }
2464
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002465 void getFunctionNames(BCCsizei* actualFunctionCount,
2466 BCCsizei maxFunctionCount,
2467 BCCchar** functions) {
2468 int functionCount = mEmittedFunctions.size();
2469
2470 if(actualFunctionCount)
2471 *actualFunctionCount = functionCount;
2472 if(functionCount > maxFunctionCount)
2473 functionCount = maxFunctionCount;
2474 if(functions)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002475 for(EmittedFunctionsMapTy::const_iterator it =
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002476 mEmittedFunctions.begin();
2477 functionCount > 0;
2478 functionCount--, it++)
2479 *functions++ = (BCCchar*) it->first.c_str();
2480
2481 return;
2482 }
2483
2484 void getFunctionBinary(BCCchar* label,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002485 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002486 BCCsizei* length) {
2487 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(label);
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002488 if(I == mEmittedFunctions.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002489 *base = NULL;
2490 *length = 0;
2491 } else {
2492 *base = I->second->Code;
2493 *length = I->second->Size;
2494 }
2495 return;
2496 }
2497
2498 ~CodeEmitter() {
2499 if(mpMemMgr)
2500 delete mpMemMgr;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002501#if defined(USE_DISASSEMBLER)
2502 if(mpAsmInfo)
2503 delete mpAsmInfo;
2504 if(mpDisassmbler)
2505 delete mpDisassmbler;
2506 if(mpIP)
2507 delete mpIP;
2508#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002509 return;
2510 }
2511 /* }}} */
2512 }; /* End of Class CodeEmitter */
2513
2514 /* The CodeEmitter */
2515 llvm::OwningPtr<CodeEmitter> mCodeEmitter;
2516 CodeEmitter* createCodeEmitter() {
2517 mCodeEmitter.reset(new CodeEmitter(mCodeMemMgr.take()));
2518 return mCodeEmitter.get();
2519 }
2520
2521 BCCSymbolLookupFn mpSymbolLookupFn;
2522 void* mpSymbolLookupContext;
2523
2524 llvm::Module* mModule;
2525
2526 bool mTypeInformationPrepared;
2527 std::vector<const llvm::Type*> mTypes;
2528
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002529 public:
2530 Compiler() : mpSymbolLookupFn(NULL), mpSymbolLookupContext(NULL), mModule(NULL) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002531 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002532 return;
2533 }
2534
2535 /* interface for BCCscript::registerSymbolCallback() */
2536 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2537 mpSymbolLookupFn = pFn;
2538 mpSymbolLookupContext = pContext;
2539 return;
2540 }
2541
2542 int loadModule(const char* bitcode, size_t bitcodeSize) {
2543 llvm::MemoryBuffer* SB = NULL;
2544
2545 if(bitcode == NULL || bitcodeSize <= 0)
2546 return 0;
2547
2548 GlobalInitialization();
2549
2550 /* Package input to object MemoryBuffer */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002551 SB = llvm::MemoryBuffer::getMemBuffer(
2552 llvm::StringRef(bitcode, bitcodeSize));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002553 if(SB == NULL) {
2554 setError("Error reading input Bitcode into memory");
2555 goto on_bcc_load_module_error;
2556 }
2557
2558 /* Read the input Bitcode as a Module */
2559 mModule = llvm::ParseBitcodeFile(SB, llvm::getGlobalContext(), &mError);
2560
2561on_bcc_load_module_error:
2562 if (SB)
2563 delete SB;
2564
2565 return hasError();
2566 }
2567
2568 /* interace for bccCompileScript() */
2569 int compile() {
2570 llvm::TargetData* TD = NULL;
2571
2572 llvm::TargetMachine* TM = NULL;
2573 const llvm::Target* Target;
2574 std::string FeaturesStr;
2575
2576 llvm::FunctionPassManager* CodeGenPasses = NULL;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002577
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002578 const llvm::NamedMDNode* PragmaMetadata;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002579 const llvm::NamedMDNode* ExportVarMetadata;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002580
2581 if(mModule == NULL) /* No module was loaded */
2582 return 0;
2583
2584 /* Create TargetMachine */
2585 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
2586 if(hasError())
2587 goto on_bcc_compile_error;
2588
2589 if(!CPU.empty() || !Features.empty()) {
2590 llvm::SubtargetFeatures F;
2591 F.setCPU(CPU);
2592 for(std::vector<std::string>::const_iterator it = Features.begin();
2593 it != Features.end();
2594 it++)
2595 F.AddFeature(*it);
2596 FeaturesStr = F.getString();
2597 }
2598
2599 TM = Target->createTargetMachine(Triple, FeaturesStr);
2600 if(TM == NULL) {
2601 setError("Failed to create target machine implementation for the"
2602 " specified triple '" + Triple + "'");
2603 goto on_bcc_compile_error;
2604 }
2605
2606 /* Create memory manager for creation of code emitter later */
2607 if(!mCodeMemMgr.get() && !createCodeMemoryManager()) {
2608 setError("Failed to startup memory management for further compilation");
2609 goto on_bcc_compile_error;
2610 }
2611
2612 /* Create code emitter */
2613 if(!mCodeEmitter.get()) {
2614 if(!createCodeEmitter()) {
2615 setError("Failed to create machine code emitter to complete"
2616 " the compilation");
2617 goto on_bcc_compile_error;
2618 }
2619 } else {
2620 /* reuse the code emitter */
2621 mCodeEmitter->reset();
2622 }
2623
2624 mCodeEmitter->setTargetMachine(*TM);
2625 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
2626 mpSymbolLookupContext);
2627
2628 /* Get target data from Module */
2629 TD = new llvm::TargetData(mModule);
2630 /* Create code-gen pass to run the code emitter */
2631 CodeGenPasses = new llvm::FunctionPassManager(mModule);
2632 CodeGenPasses->add(TD); // Will take the ownership of TD
2633
2634 if(TM->addPassesToEmitMachineCode(*CodeGenPasses,
2635 *mCodeEmitter, CodeGenOptLevel)) {
2636 setError("The machine code emission is not supported by BCC on target '"
2637 + Triple + "'");
2638 goto on_bcc_compile_error;
2639 }
2640
2641 /*
2642 * Run the pass (the code emitter) on every non-declaration function
2643 * in the module
2644 */
2645 CodeGenPasses->doInitialization();
2646 for(llvm::Module::iterator I = mModule->begin();
2647 I != mModule->end();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002648 I++)
2649 if(!I->isDeclaration())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002650 CodeGenPasses->run(*I);
2651
2652 CodeGenPasses->doFinalization();
2653
2654 /* Copy the global address mapping from code emitter and remapping */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002655 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
2656 if(ExportVarMetadata) {
2657 for(int i=0;i<ExportVarMetadata->getNumOperands();i++) {
2658 llvm::MDNode* ExportVar = ExportVarMetadata->getOperand(i);
2659 if(ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2660 llvm::Value* ExportVarNameMDS = ExportVar->getOperand(0);
2661 if(ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
2662 llvm::StringRef ExportVarName =
2663 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
2664 CodeEmitter::global_addresses_const_iterator I;
2665 for(I = mCodeEmitter->global_address_begin();
2666 I != mCodeEmitter->global_address_end();
2667 I++)
2668 {
2669 if(I->first->getValueID() != llvm::Value::GlobalVariableVal)
2670 continue;
2671 if(ExportVarName == I->first->getName()) {
2672 mExportVars.push_back(I->second);
2673 break;
2674 }
2675 }
2676 if(I != mCodeEmitter->global_address_end())
2677 continue; // found
2678 }
2679 }
2680 // if here, the global variable record in metadata is not
2681 // found, make an empty slot
2682 mExportVars.push_back(NULL);
2683 }
2684 assert((mExportVars.size() == ExportVarMetadata->getNumOperands()) &&
2685 "Number of slots doesn't match the number of export variables!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002686 }
2687
2688 /*
2689 * Tell code emitter now can release the memory using
2690 * during the JIT since we have done the code emission
2691 */
2692 mCodeEmitter->releaseUnnecessary();
2693
2694 /*
2695 * Finally, read pragma information from the metadata node
2696 * of the @Module if any
2697 */
2698 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
2699 if(PragmaMetadata)
2700 for(int i=0;i<PragmaMetadata->getNumOperands();i++) {
2701 llvm::MDNode* Pragma = PragmaMetadata->getOperand(i);
2702 if(Pragma != NULL &&
2703 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
2704 llvm::Value* PragmaNameMDS = Pragma->getOperand(0);
2705 llvm::Value* PragmaValueMDS = Pragma->getOperand(1);
2706
2707 if((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
2708 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
2709 llvm::StringRef PragmaName =
2710 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
2711 llvm::StringRef PragmaValue =
2712 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
2713
2714 mPragmas.push_back( make_pair( std::string(PragmaName.data(),
2715 PragmaName.size()),
2716 std::string(PragmaValue.data(),
2717 PragmaValue.size())
2718 )
2719 );
2720 }
2721 }
2722 }
2723
2724 on_bcc_compile_error:
2725 if (CodeGenPasses) {
2726 delete CodeGenPasses;
2727 } else if (TD) {
2728 delete TD;
2729 }
2730 if (TM)
2731 delete TM;
2732
2733 return hasError();
2734 }
2735
2736 /* interface for bccGetScriptInfoLog() */
2737 char* getErrorMessage() {
2738 return const_cast<char*>(mError.c_str());
2739 }
2740
2741 /* interface for bccGetScriptLabel() */
2742 void* lookup(const char* name) {
2743 void* addr = NULL;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002744 if(mCodeEmitter.get())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002745 /* Find function pointer */
2746 addr = mCodeEmitter->lookup(name);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002747 return addr;
2748 }
2749
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002750 /* Interface for bccGetExportVars() */
2751 void getExportVars(BCCsizei* actualVarCount,
2752 BCCsizei maxVarCount,
2753 BCCvoid** vars) {
2754 int varCount = mExportVars.size();
2755
2756 if(actualVarCount)
2757 *actualVarCount = varCount;
2758 if(varCount > maxVarCount)
2759 varCount = maxVarCount;
2760 if(vars)
2761 for(ExportVarList::const_iterator it = mExportVars.begin();
2762 it != mExportVars.end();
2763 it++)
2764 {
2765 *vars++ = *it;
2766 }
2767
2768 return;
2769 }
2770
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002771 /* Interface for bccGetPragmas() */
2772 void getPragmas(BCCsizei* actualStringCount,
2773 BCCsizei maxStringCount,
2774 BCCchar** strings) {
2775 int stringCount = mPragmas.size() * 2;
2776
2777 if(actualStringCount)
2778 *actualStringCount = stringCount;
2779 if(stringCount > maxStringCount)
2780 stringCount = maxStringCount;
2781 if(strings)
2782 for(PragmaList::const_iterator it = mPragmas.begin();
2783 stringCount > 0;
2784 stringCount-=2, it++)
2785 {
2786 *strings++ = (BCCchar*) it->first.c_str();
2787 *strings++ = (BCCchar*) it->second.c_str();
2788 }
2789
2790 return;
2791 }
2792
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002793 /* Interface for bccGetFunctions() */
2794 void getFunctions(BCCsizei* actualFunctionCount,
2795 BCCsizei maxFunctionCount,
2796 BCCchar** functions) {
2797 if(mCodeEmitter.get())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002798 mCodeEmitter->getFunctionNames(actualFunctionCount,
2799 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002800 functions);
2801 else
2802 *actualFunctionCount = 0;
2803
2804 return;
2805 }
2806
2807 /* Interface for bccGetFunctionBinary() */
2808 void getFunctionBinary(BCCchar* function,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002809 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002810 BCCsizei* length) {
2811 if(mCodeEmitter.get()) {
2812 mCodeEmitter->getFunctionBinary(function, base, length);
2813 } else {
2814 *base = NULL;
2815 *length = 0;
2816 }
2817 return;
2818 }
2819
2820 inline const llvm::Module* getModule() const {
2821 return mModule;
2822 }
2823
2824 inline const std::vector<const llvm::Type*>& getTypes() const {
2825 return mTypes;
2826 }
2827
2828 ~Compiler() {
2829 delete mModule;
2830 llvm::llvm_shutdown();
2831 return;
2832 }
2833}; /* End of Class Compiler */
2834
2835bool Compiler::GlobalInitialized = false;
2836
2837/* Code generation optimization level for the compiler */
2838llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
2839
2840std::string Compiler::Triple;
2841
2842std::string Compiler::CPU;
2843
2844std::vector<std::string> Compiler::Features;
2845
2846/*
2847 * The named of metadata node that pragma resides
2848 * (should be synced with slang.cpp)
2849 */
2850const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
2851
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002852/*
2853 * The named of metadata node that export variable name resides
2854 * (should be synced with slang.cpp)
2855 */
2856const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
2857
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002858struct BCCscript {
2859 /*
2860 * Part I. Compiler
2861 */
2862
2863 Compiler compiler;
2864
2865 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2866 compiler.registerSymbolCallback(pFn, pContext);
2867 }
2868
2869 /*
2870 * Part II. Logistics & Error handling
2871 */
2872
2873 BCCscript() {
2874 bccError = BCC_NO_ERROR;
2875 }
2876
2877 ~BCCscript() {
2878 }
2879
2880 void setError(BCCenum error) {
2881 if (bccError == BCC_NO_ERROR && error != BCC_NO_ERROR) {
2882 bccError = error;
2883 }
2884 }
2885
2886 BCCenum getError() {
2887 BCCenum result = bccError;
2888 bccError = BCC_NO_ERROR;
2889 return result;
2890 }
2891
2892 BCCenum bccError;
2893};
2894
2895
2896extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002897BCCscript* bccCreateScript()
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002898{
2899 return new BCCscript();
2900}
2901
2902extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002903BCCenum bccGetError( BCCscript* script )
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002904{
2905 return script->getError();
2906}
2907
2908extern "C"
2909void bccDeleteScript(BCCscript* script) {
2910 delete script;
2911}
2912
2913extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002914void bccRegisterSymbolCallback(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002915 BCCSymbolLookupFn pFn,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002916 BCCvoid* pContext)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002917{
2918 script->registerSymbolCallback(pFn, pContext);
2919}
2920
2921extern "C"
2922void bccScriptBitcode(BCCscript* script,
2923 const BCCchar* bitcode,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002924 BCCint size)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002925{
2926 script->compiler.loadModule(bitcode, size);
2927}
2928
2929extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002930void bccCompileScript(BCCscript* script)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002931{
2932 int result = script->compiler.compile();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002933 if (result)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002934 script->setError(BCC_INVALID_OPERATION);
2935}
2936
2937extern "C"
2938void bccGetScriptInfoLog(BCCscript* script,
2939 BCCsizei maxLength,
2940 BCCsizei* length,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002941 BCCchar* infoLog)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002942{
2943 char* message = script->compiler.getErrorMessage();
2944 int messageLength = strlen(message) + 1;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002945 if (length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002946 *length = messageLength;
2947
2948 if (infoLog && maxLength > 0) {
2949 int trimmedLength = maxLength < messageLength ? maxLength : messageLength;
2950 memcpy(infoLog, message, trimmedLength);
2951 infoLog[trimmedLength] = 0;
2952 }
2953}
2954
2955extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002956void bccGetScriptLabel(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002957 const BCCchar * name,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002958 BCCvoid ** address)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002959{
2960 void* value = script->compiler.lookup(name);
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002961 if (value)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002962 *address = value;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002963 else
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002964 script->setError(BCC_INVALID_VALUE);
2965}
2966
2967extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002968void bccGetExportVars(BCCscript* script,
2969 BCCsizei* actualVarCount,
2970 BCCsizei maxVarCount,
2971 BCCvoid** vars)
2972{
2973 script->compiler.getExportVars(actualVarCount, maxVarCount, vars);
2974}
2975
2976extern "C"
2977void bccGetPragmas(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002978 BCCsizei* actualStringCount,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002979 BCCsizei maxStringCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002980 BCCchar** strings)
2981{
2982 script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
2983}
2984
2985extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002986void bccGetFunctions(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002987 BCCsizei* actualFunctionCount,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002988 BCCsizei maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002989 BCCchar** functions)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002990{
2991 script->compiler.getFunctions(actualFunctionCount,
2992 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002993 functions);
2994}
2995
2996extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002997void bccGetFunctionBinary(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002998 BCCchar* function,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002999 BCCvoid** base,
3000 BCCsizei* length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003001{
3002 script->compiler.getFunctionBinary(function, base, length);
3003}
3004
3005struct BCCtype {
3006 const Compiler* compiler;
3007 const llvm::Type* t;
3008};
3009
3010} /* End of namespace bcc */