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