blob: 3751edfcc9d378b6e6dc2a36bab6b43279f0cc9e [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>
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -070019#include <sys/mman.h>
Shih-wei Liao77ed6142010-04-07 12:21:42 -070020
21#include <cutils/hashmap.h>
22
Shih-wei Liao77ed6142010-04-07 12:21:42 -070023#if defined(__arm__)
24 #define DEFAULT_ARM_CODEGEN
25 #define PROVIDE_ARM_CODEGEN
26#elif defined(__i386__)
27 #define DEFAULT_X86_CODEGEN
28 #define PROVIDE_X86_CODEGEN
29#elif defined(__x86_64__)
30 #define DEFAULT_X64_CODEGEN
31 #define PROVIDE_X64_CODEGEN
32#endif
33
34#if defined(FORCE_ARM_CODEGEN)
35 #define DEFAULT_ARM_CODEGEN
36 #undef DEFAULT_X86_CODEGEN
37 #undef DEFAULT_X64_CODEGEN
38 #define PROVIDE_ARM_CODEGEN
39 #undef PROVIDE_X86_CODEGEN
40 #undef PROVIDE_X64_CODEGEN
41#elif defined(FORCE_X86_CODEGEN)
42 #undef DEFAULT_ARM_CODEGEN
43 #define DEFAULT_X86_CODEGEN
44 #undef DEFAULT_X64_CODEGEN
45 #undef PROVIDE_ARM_CODEGEN
46 #define PROVIDE_X86_CODEGEN
47 #undef PROVIDE_X64_CODEGEN
48#elif defined(FORCE_X64_CODEGEN)
49 #undef DEFAULT_ARM_CODEGEN
50 #undef DEFAULT_X86_CODEGEN
51 #define DEFAULT_X64_CODEGEN
52 #undef PROVIDE_ARM_CODEGEN
53 #undef PROVIDE_X86_CODEGEN
54 #define PROVIDE_X64_CODEGEN
55#endif
56
57#if defined(DEFAULT_ARM_CODEGEN)
58 #define TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
59#elif defined(DEFAULT_X86_CODEGEN)
60 #define TARGET_TRIPLE_STRING "i686-unknown-linux"
61#elif defined(DEFAULT_X64_CODEGEN)
62 #define TARGET_TRIPLE_STRING "x86_64-unknown-linux"
63#endif
64
65#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
66#define ARM_USE_VFP
67#endif
68
69#include <bcc/bcc.h>
70#include "bcc_runtime.h"
71
72#define LOG_API(...) do {} while(0)
73// #define LOG_API(...) fprintf (stderr, __VA_ARGS__)
74
75#define LOG_STACK(...) do {} while(0)
76// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__)
77
78// #define PROVIDE_TRACE_CODEGEN
79
80#if defined(USE_DISASSEMBLER)
Shih-wei Liaocd61af32010-04-29 00:02:57 -070081# include "llvm/MC/MCInst.h" /* for class llvm::MCInst */
82# include "llvm/MC/MCAsmInfo.h" /* for class llvm::MCAsmInfo */
83# include "llvm/MC/MCInstPrinter.h" /* for class llvm::MCInstPrinter */
84# include "llvm/MC/MCDisassembler.h" /* for class llvm::MCDisassembler */
Shih-wei Liao3cf39d12010-04-29 19:30:51 -070085// If you want the disassemble results written to file, define this:
86# define USE_DISASSEMBLER_FILE
Shih-wei Liao77ed6142010-04-07 12:21:42 -070087#endif
88
89#include <set>
90#include <map>
91#include <list>
92#include <cmath>
93#include <string>
94#include <cstring>
95#include <algorithm> /* for std::reverse */
96
97// Basic
98#include "llvm/Use.h" /* for class llvm::Use */
99#include "llvm/User.h" /* for class llvm::User */
100#include "llvm/Module.h" /* for class llvm::Module */
101#include "llvm/Function.h" /* for class llvm::Function */
102#include "llvm/Constant.h" /* for class llvm::Constant */
103#include "llvm/Constants.h" /* for class llvm::ConstantExpr */
104#include "llvm/Instruction.h" /* for class llvm::Instruction */
105#include "llvm/PassManager.h" /* for class llvm::PassManager and
106 * llvm::FunctionPassManager
107 */
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700108#include "llvm/LLVMContext.h" /* for class llvm::LLVMContext */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700109#include "llvm/GlobalValue.h" /* for class llvm::GlobalValue */
110#include "llvm/Instructions.h" /* for class llvm::CallInst */
111#include "llvm/OperandTraits.h" /* for macro
112 * DECLARE_TRANSPARENT_OPERAND_ACCESSORS
113 * and macro
114 * DEFINE_TRANSPARENT_OPERAND_ACCESSORS
115 */
116#include "llvm/TypeSymbolTable.h" /* for Type Reflection */
117
118// System
119#include "llvm/System/Host.h" /* for function
120 * llvm::sys::isLittleEndianHost()
121 */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700122
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]
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700138 * [TargetInfo|Target|Disassembler|
139 * AsmPrinter]()
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700140 */
141#include "llvm/Target/TargetOptions.h" /* for
142 * variable bool llvm::UseSoftFloat
143 * FloatABI::ABIType llvm::FloatABIType
144 * bool llvm::NoZerosInBSS
145 */
146#include "llvm/Target/TargetMachine.h" /* for class llvm::TargetMachine and
147 * llvm::TargetMachine::AssemblyFile
148 */
149#include "llvm/Target/TargetJITInfo.h" /* for class llvm::TargetJITInfo */
150#include "llvm/Target/TargetRegistry.h" /* for class llvm::TargetRegistry */
151#include "llvm/Target/SubtargetFeature.h"
152 /* for class llvm::SubtargetFeature */
153
154// Support
155#include "llvm/Support/Casting.h" /* for class cast<> */
156#include "llvm/Support/raw_ostream.h" /* for class llvm::raw_ostream and
157 * llvm::raw_string_ostream
158 */
159#include "llvm/Support/ValueHandle.h" /* for class AssertingVH<> */
160#include "llvm/Support/MemoryBuffer.h" /* for class llvm::MemoryBuffer */
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700161#include "llvm/Support/MemoryObject.h" /* for class llvm::MemoryObject */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700162#include "llvm/Support/ManagedStatic.h" /* for class llvm::llvm_shutdown */
163#include "llvm/Support/ErrorHandling.h" /* for function
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700164 * llvm::remove_fatal_error_handler()
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700165 * llvm::install_fatal_error_handler()
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700166 * and macro llvm_unreachable()
167 */
168#include "llvm/Support/StandardPasses.h"/* for function
169 * llvm::createStandardFunctionPasses()
170 * and
171 * llvm::createStandardModulePasses()
172 */
173#include "llvm/Support/FormattedStream.h"
174 /* for
175 * class llvm::formatted_raw_ostream
176 * llvm::formatted_raw_ostream::
177 * PRESERVE_STREAM
178 * llvm::FileModel::Error
179 */
180
181// Bitcode
182#include "llvm/Bitcode/ReaderWriter.h" /* for function
183 * llvm::ParseBitcodeFile()
184 */
185
186// CodeGen
187#include "llvm/CodeGen/Passes.h" /* for
Shih-wei Liao16016012010-09-10 17:55:03 -0700188 * llvm::createFastRegisterAllocator()
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700189 * and
190 * llvm::
191 * createLinearScanRegisterAllocator()
192 */
193#include "llvm/CodeGen/JITCodeEmitter.h"/* for class llvm::JITCodeEmitter */
194#include "llvm/CodeGen/MachineFunction.h"
195 /* for class llvm::MachineFunction */
196#include "llvm/CodeGen/RegAllocRegistry.h"
197 /* for class llvm::RegisterRegAlloc */
198#include "llvm/CodeGen/SchedulerRegistry.h"
199 /* for class llvm::RegisterScheduler
200 * and llvm::createDefaultScheduler()
201 */
202#include "llvm/CodeGen/MachineRelocation.h"
203 /* for class llvm::MachineRelocation */
204#include "llvm/CodeGen/MachineModuleInfo.h"
205 /* for class llvm::MachineModuleInfo */
206#include "llvm/CodeGen/MachineCodeEmitter.h"
207 /* for class llvm::MachineCodeEmitter */
208#include "llvm/CodeGen/MachineConstantPool.h"
209 /* for class llvm::MachineConstantPool
210 */
211#include "llvm/CodeGen/MachineJumpTableInfo.h"
212 /* for class llvm::MachineJumpTableInfo
213 */
214
215// ExecutionEngine
216#include "llvm/ExecutionEngine/GenericValue.h"
217 /* for struct llvm::GenericValue */
218#include "llvm/ExecutionEngine/JITMemoryManager.h"
219 /* for class llvm::JITMemoryManager */
220
221
222/*
223 * Compilation class that suits Android's needs.
224 * (Support: no argument passed, ...)
225 */
226
227namespace bcc {
228
229class Compiler {
230 /*
231 * This part is designed to be orthogonal to those exported bcc*() functions
232 * implementation and internal struct BCCscript.
233 */
234
235
236 /*********************************************
237 * The variable section below (e.g., Triple, CodeGenOptLevel)
238 * is initialized in GlobalInitialization()
239 */
240 static bool GlobalInitialized;
241
242 /*
243 * If given, this will be the name of the target triple to compile for.
244 * If not given, the initial values defined in this file will be used.
245 */
246 static std::string Triple;
247
248 static llvm::CodeGenOpt::Level CodeGenOptLevel;
249 /*
250 * End of section of GlobalInitializing variables
251 **********************************************/
252
253 /* If given, the name of the target CPU to generate code for. */
254 static std::string CPU;
255
256 /*
257 * The list of target specific features to enable or disable -- this should
258 * be a list of strings starting with '+' (enable) or '-' (disable).
259 */
260 static std::vector<std::string> Features;
261
262 struct Runtime {
263 const char* mName;
264 void* mPtr;
265 };
266 static struct Runtime Runtimes[];
267
268 static void GlobalInitialization() {
269 if(GlobalInitialized) return;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700270
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700271 // if (!llvm::llvm_is_multithreaded())
272 // llvm::llvm_start_multithreaded();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700273
274 /* Set Triple, CPU and Features here */
275 Triple = TARGET_TRIPLE_STRING;
276
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700277 /* TODO: NEON for JIT */
278 //Features.push_back("+neon");
279 //Features.push_back("+vmlx");
280 //Features.push_back("+neonfp");
Shih-wei Liao3cf39d12010-04-29 19:30:51 -0700281 Features.push_back("+vfp3");
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700282
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700283#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
284 LLVMInitializeARMTargetInfo();
285 LLVMInitializeARMTarget();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700286#if defined(USE_DISASSEMBLER)
287 LLVMInitializeARMDisassembler();
288 LLVMInitializeARMAsmPrinter();
289#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700290#endif
291
292#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
293 LLVMInitializeX86TargetInfo();
294 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700295#if defined(USE_DISASSEMBLER)
296 LLVMInitializeX86Disassembler();
297 LLVMInitializeX86AsmPrinter();
298#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700299#endif
300
301#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
302 LLVMInitializeX86TargetInfo();
303 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700304#if defined(USE_DISASSEMBLER)
305 LLVMInitializeX86Disassembler();
306 LLVMInitializeX86AsmPrinter();
307#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700308#endif
309
310 /*
311 * -O0: llvm::CodeGenOpt::None
312 * -O1: llvm::CodeGenOpt::Less
313 * -O2: llvm::CodeGenOpt::Default
314 * -O3: llvm::CodeGenOpt::Aggressive
315 */
316 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
317
318 /* Below are the global settings to LLVM */
319
320 /* Disable frame pointer elimination optimization */
321 llvm::NoFramePointerElim = false;
322
323 /*
324 * Use hardfloat ABI
325 *
326 * FIXME: Need to detect the CPU capability and decide whether to use
327 * softfp. To use softfp, change following 2 lines to
328 *
329 * llvm::FloatABIType = llvm::FloatABI::Soft;
330 * llvm::UseSoftFloat = true;
331 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700332 llvm::FloatABIType = llvm::FloatABI::Soft;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700333 llvm::UseSoftFloat = false;
334
335 /*
336 * BCC needs all unknown symbols resolved at JIT/compilation time.
337 * So we don't need any dynamic relocation model.
338 */
339 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
340
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700341#if defined(DEFAULT_X64_CODEGEN)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700342 /* Data address in X86_64 architecture may reside in a far-away place */
343 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
344#else
345 /*
346 * This is set for the linker (specify how large of the virtual addresses
347 * we can access for all unknown symbols.)
348 */
349 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
350#endif
351
352 /* Register the scheduler */
353 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
354
355 /*
356 * Register allocation policy:
Shih-wei Liao16016012010-09-10 17:55:03 -0700357 * createFastRegisterAllocator: fast but bad quality
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700358 * createLinearScanRegisterAllocator: not so fast but good quality
359 */
360 llvm::RegisterRegAlloc::setDefault
361 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
Shih-wei Liao16016012010-09-10 17:55:03 -0700362 llvm::createFastRegisterAllocator :
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700363 llvm::createLinearScanRegisterAllocator);
364
365 GlobalInitialized = true;
366 return;
367 }
368
369 static void LLVMErrorHandler(void *UserData, const std::string &Message) {
Shih-wei Liao066d5ef2010-05-11 03:28:39 -0700370 std::string* Error = static_cast<std::string*>(UserData);
371 Error->assign(Message);
Nick Kralevichfc97e9f2010-05-17 14:59:16 -0700372 LOGE("%s", Message.c_str());
Shih-wei Liao066d5ef2010-05-11 03:28:39 -0700373 return;
374 //fprintf(stderr, "%s\n", Message.c_str());
375 //exit(1);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700376 }
377
378 static const llvm::StringRef PragmaMetadataName;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700379 static const llvm::StringRef ExportVarMetadataName;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700380 static const llvm::StringRef ExportFuncMetadataName;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700381
382 private:
Shih-wei Liaoc5611992010-05-09 06:37:55 -0700383 std::string mError;
384
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700385 inline bool hasError() const {
386 return !mError.empty();
387 }
388 inline void setError(const char* Error) {
389 mError.assign(Error); // Copying
390 return;
391 }
392 inline void setError(const std::string& Error) {
393 mError = Error;
394 return;
395 }
396
397 typedef std::list< std::pair<std::string, std::string> > PragmaList;
398 PragmaList mPragmas;
399
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700400 typedef std::list<void*> ExportVarList;
401 ExportVarList mExportVars;
402
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700403 typedef std::list<void*> ExportFuncList;
404 ExportFuncList mExportFuncs;
405
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700406 /* Memory manager for the code reside in memory */
407 /*
408 * The memory for our code emitter is very simple and is conforming to the
409 * design decisions of Android RenderScript's Exection Environment:
410 * The code, data, and symbol sizes are limited (currently 100KB.)
411 *
412 * It's very different from typical compiler, which has no limitation
413 * on the code size. How does code emitter know the size of the code
414 * it is about to emit? It does not know beforehand. We want to solve
415 * this without complicating the code emitter too much.
416 *
417 * We solve this by pre-allocating a certain amount of memory,
418 * and then start the code emission. Once the buffer overflows, the emitter
419 * simply discards all the subsequent emission but still has a counter
420 * on how many bytes have been emitted.
421
422 * So once the whole emission is done, if there's a buffer overflow,
423 * it re-allocates the buffer with enough size (based on the
424 * counter from previous emission) and re-emit again.
425 */
426 class CodeMemoryManager : public llvm::JITMemoryManager {
427 /* {{{ */
428 private:
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700429 static const unsigned int MaxCodeSize = 128 * 1024; /* 128 KiB for code */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700430 static const unsigned int MaxGOTSize = 1 * 1024; /* 1 KiB for global
431 offset table (GOT) */
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700432 static const unsigned int MaxGlobalVarSize = 128 * 1024; /* 128 KiB for global
433 variable */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700434
435 /*
436 * Our memory layout is as follows:
437 *
438 * The direction of arrows (-> and <-) shows memory's growth direction
439 * when more space is needed.
440 *
441 * @mpCodeMem:
442 * +--------------------------------------------------------------+
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700443 * | Function Memory ... -> <- ... Stub/GOT |
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700444 * +--------------------------------------------------------------+
445 * |<------------------ Total: @MaxCodeSize KiB ----------------->|
446 *
447 * Where size of GOT is @MaxGOTSize KiB.
448 *
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700449 * @mpGVMem:
450 * +--------------------------------------------------------------+
451 * | Global variable ... -> |
452 * +--------------------------------------------------------------+
453 * |<--------------- Total: @MaxGlobalVarSize KiB --------------->|
454 *
455 *
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700456 * @mCurFuncMemIdx: The current index (starting from 0) of the last byte
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700457 * of function code's memory usage
458 * @mCurSGMemIdx: The current index (starting from tail) of the last byte
459 * of stub/GOT's memory usage
460 * @mCurGVMemIdx: The current index (starting from tail) of the last byte
461 * of global variable's memory usage
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700462 *
463 */
464
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700465 uintptr_t mCurFuncMemIdx;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700466 uintptr_t mCurSGMemIdx;
467 uintptr_t mCurGVMemIdx;
468 void* mpCodeMem;
469 void* mpGVMem;
470
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700471
472 /* GOT Base */
473 uint8_t* mpGOTBase;
474
475 typedef std::map<const llvm::Function*, pair<void* /* start address */,
476 void* /* end address */>
477 > FunctionMapTy;
478 FunctionMapTy mFunctionMap;
479
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700480 inline uintptr_t getFreeCodeMemSize() const {
481 return mCurSGMemIdx - mCurFuncMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700482 }
483 inline uint8_t* getCodeMemBase() const {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700484 return reinterpret_cast<uint8_t*>(mpCodeMem);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700485 }
486
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700487 uint8_t* allocateSGMemory(uintptr_t Size,
488 unsigned Alignment = 1 /* no alignment */)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700489 {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700490 if(getFreeCodeMemSize() < Size)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700491 /* The code size excesses our limit */
492 return NULL;
493
494 if(Alignment == 0)
495 Alignment = 1;
496
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700497 uint8_t* result = getCodeMemBase() + mCurSGMemIdx - Size;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700498 result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
499
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700500 mCurSGMemIdx = result - getCodeMemBase();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700501
502 return result;
503 }
504
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700505 inline uintptr_t getFreeGVMemSize() const {
506 return MaxGlobalVarSize - mCurGVMemIdx;
507 }
508 inline uint8_t* getGVMemBase() const {
509 return reinterpret_cast<uint8_t*>(mpGVMem);
510 }
511
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700512 public:
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700513 CodeMemoryManager() : mpCodeMem(NULL), mpGVMem(NULL), mpGOTBase(NULL) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700514 reset();
515 std::string ErrMsg;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700516
517 mpCodeMem = ::mmap(NULL, MaxCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC,
518 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
519 if (mpCodeMem == MAP_FAILED)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700520 llvm::report_fatal_error(
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700521 "Failed to allocate memory for emitting function codes\n" + ErrMsg
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700522 );
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700523
524 mpGVMem = ::mmap(mpCodeMem, MaxGlobalVarSize,
525 PROT_READ | PROT_WRITE | PROT_EXEC,
526 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
527 if (mpGVMem == MAP_FAILED)
528 llvm::report_fatal_error(
529 "Failed to allocate memory for emitting global variables\n" + ErrMsg
530 );
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700531
532 return;
533 }
534
535 /*
536 * setMemoryWritable - When code generation is in progress,
537 * the code pages may need permissions changed.
538 */
539 void setMemoryWritable() {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700540 ::mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700541 return;
542 }
543
544 /*
545 * setMemoryExecutable - When code generation is done and we're ready to
546 * start execution, the code pages may need permissions changed.
547 */
548 void setMemoryExecutable() {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700549 ::mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_EXEC);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700550 return;
551 }
552
553 /*
554 * setPoisonMemory - Setting this flag to true makes the memory manager
555 * garbage values over freed memory. This is useful for testing and
556 * debugging, and is to be turned on by default in debug mode.
557 */
558 void setPoisonMemory(bool poison) {
559 /* no effect */
560 return;
561 }
562
563 /* Global Offset Table Management */
564
565 /*
566 * AllocateGOT - If the current table requires a Global Offset Table, this
567 * method is invoked to allocate it. This method is required to set HasGOT
568 * to true.
569 */
570 void AllocateGOT() {
571 assert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700572 mpGOTBase = allocateSGMemory(MaxGOTSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700573 HasGOT = true;
574 return;
575 }
576
577 /*
578 * getGOTBase - If this is managing a Global Offset Table, this method
579 * should return a pointer to its base.
580 */
581 uint8_t* getGOTBase() const {
582 return mpGOTBase;
583 }
584
585 /* Main Allocation Functions */
586
587 /*
588 * startFunctionBody - When we start JITing a function, the JIT calls this
589 * method to allocate a block of free RWX memory, which returns a pointer to
590 * it. If the JIT wants to request a block of memory of at least a certain
591 * size, it passes that value as ActualSize, and this method returns a block
592 * with at least that much space. If the JIT doesn't know ahead of time how
593 * much space it will need to emit the function, it passes 0 for the
594 * ActualSize. In either case, this method is required to pass back the size
595 * of the allocated block through ActualSize. The JIT will be careful to
596 * not write more than the returned ActualSize bytes of memory.
597 */
598 uint8_t* startFunctionBody(const llvm::Function *F, uintptr_t &ActualSize) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700599 if(getFreeCodeMemSize() < ActualSize)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700600 /* The code size excesses our limit */
601 return NULL;
602
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700603 ActualSize = getFreeCodeMemSize();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700604 return (getCodeMemBase() + mCurFuncMemIdx);
605 }
606
607 /*
608 * allocateStub - This method is called by the JIT to allocate space for a
609 * function stub (used to handle limited branch displacements) while it is
610 * JIT compiling a function. For example, if foo calls bar, and if bar
611 * either needs to be lazily compiled or is a native function that exists
612 * too
613 * far away from the call site to work, this method will be used to make a
614 * thunk for it. The stub should be "close" to the current function body,
615 * but should not be included in the 'actualsize' returned by
616 * startFunctionBody.
617 */
618 uint8_t* allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
619 unsigned Alignment) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700620 return allocateSGMemory(StubSize, Alignment);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700621 }
622
623 /*
624 * endFunctionBody - This method is called when the JIT is done codegen'ing
625 * the specified function. At this point we know the size of the JIT
626 * compiled function. This passes in FunctionStart (which was returned by
627 * the startFunctionBody method) and FunctionEnd which is a pointer to the
628 * actual end of the function. This method should mark the space allocated
629 * and remember where it is in case the client wants to deallocate it.
630 */
631 void endFunctionBody(const llvm::Function* F, uint8_t* FunctionStart,
632 uint8_t* FunctionEnd) {
633 assert(FunctionEnd > FunctionStart);
634 assert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
635 "Mismatched function start/end!");
636
637 /* Advance the pointer */
638 intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700639 assert(FunctionCodeSize <= getFreeCodeMemSize() &&
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700640 "Code size excess the limitation!");
641 mCurFuncMemIdx += FunctionCodeSize;
642
643 /* Record there's a function in our memory start from @FunctionStart */
644 assert(mFunctionMap.find(F) == mFunctionMap.end() &&
645 "Function already emitted!");
646 mFunctionMap.insert( make_pair<const llvm::Function*, pair<void*, void*>
647 >(F, make_pair(FunctionStart, FunctionEnd))
648 );
649
650 return;
651 }
652
653 /*
654 * allocateSpace - Allocate a (function code) memory block of the
655 * given size. This method cannot be called between
656 * calls to startFunctionBody and endFunctionBody.
657 */
658 uint8_t* allocateSpace(intptr_t Size, unsigned Alignment) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700659 if(getFreeCodeMemSize() < Size)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700660 /* The code size excesses our limit */
661 return NULL;
662
663 if(Alignment == 0)
664 Alignment = 1;
665
666 uint8_t* result = getCodeMemBase() + mCurFuncMemIdx;
667 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
668 ~(intptr_t) (Alignment - 1)
669 );
670
671 mCurFuncMemIdx = (result + Size) - getCodeMemBase();
672
673 return result;
674 }
675
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700676 /* allocateGlobal - Allocate memory for a global variable. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700677 uint8_t* allocateGlobal(uintptr_t Size, unsigned Alignment) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700678 if (getFreeGVMemSize() < Size) {
679 /* The code size excesses our limit */
680 LOGE("No Global Memory");
681 return NULL;
682 }
683
684 if(Alignment == 0)
685 Alignment = 1;
686
687 uint8_t* result = getGVMemBase() + mCurGVMemIdx;
688 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
689 ~(intptr_t) (Alignment - 1)
690 );
691
692 mCurGVMemIdx = (result + Size) - getGVMemBase();
693
694 return result;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700695 }
696
697 /*
698 * deallocateFunctionBody - Free the specified function body. The argument
699 * must be the return value from a call to startFunctionBody() that hasn't
700 * been deallocated yet. This is never called when the JIT is currently
701 * emitting a function.
702 */
703 void deallocateFunctionBody(void *Body) {
704 /* linear search */
705 FunctionMapTy::iterator I;
706 for(I = mFunctionMap.begin();
707 I != mFunctionMap.end();
708 I++)
709 if(I->second.first == Body)
710 break;
711
712 assert(I != mFunctionMap.end() && "Memory is never allocated!");
713
714 /* free the memory */
715 uint8_t* FunctionStart = (uint8_t*) I->second.first;
716 uint8_t* FunctionEnd = (uint8_t*) I->second.second;
717 intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
718
719 assert(SizeNeedMove >= 0 &&
720 "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
721 " be correctly calculated!");
722
723 if(SizeNeedMove > 0)
724 /* there's data behind deallocating function */
725 ::memmove(FunctionStart, FunctionEnd, SizeNeedMove);
726 mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
727
728 return;
729 }
730
731 /*
732 * startExceptionTable - When we finished JITing the function, if exception
733 * handling is set, we emit the exception table.
734 */
735 uint8_t* startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize)
736 {
737 assert(false && "Exception is not allowed in our language specification");
738 return NULL;
739 }
740
741 /*
742 * endExceptionTable - This method is called when the JIT is done emitting
743 * the exception table.
744 */
745 void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
746 uint8_t *TableEnd, uint8_t* FrameRegister) {
747 assert(false && "Exception is not allowed in our language specification");
748 return;
749 }
750
751 /*
752 * deallocateExceptionTable - Free the specified exception table's memory.
753 * The argument must be the return value from a call to
754 * startExceptionTable()
755 * that hasn't been deallocated yet. This is never called when the JIT is
756 * currently emitting an exception table.
757 */
758 void deallocateExceptionTable(void *ET) {
759 assert(false && "Exception is not allowed in our language specification");
760 return;
761 }
762
763 /* Below are the methods we create */
764 void reset() {
765 mpGOTBase = NULL;
766 HasGOT = false;
767
768 mCurFuncMemIdx = 0;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700769 mCurSGMemIdx = MaxCodeSize - 1;
770 mCurGVMemIdx = 0;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700771
772 mFunctionMap.clear();
773
774 return;
775 }
776
777 ~CodeMemoryManager() {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700778 if(mpCodeMem != NULL) {
779 ::munmap(mpCodeMem, MaxCodeSize);
780 }
781 if(mpGVMem != NULL) {
782 ::munmap(mpGVMem, MaxGlobalVarSize);
783 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700784 return;
785 }
786 /* }}} */
787 }; /* End of class CodeMemoryManager */
788
789 /* The memory manager for code emitter */
790 llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
791 CodeMemoryManager* createCodeMemoryManager() {
792 mCodeMemMgr.reset(new CodeMemoryManager());
793 return mCodeMemMgr.get();
794 }
795
796 /* Code emitter */
797 class CodeEmitter : public llvm::JITCodeEmitter {
798 /* {{{ */
799 public:
800 typedef llvm::DenseMap<const llvm::GlobalValue*, void*> GlobalAddressMapTy;
801 typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
802
803 private:
804 CodeMemoryManager* mpMemMgr;
805
806 /* The JITInfo for the target we are compiling to */
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700807 const llvm::Target* mpTarget;
808
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700809 llvm::TargetJITInfo* mpTJI;
810
811 const llvm::TargetData* mpTD;
812
813 /*
814 * MBBLocations - This vector is a mapping from MBB ID's to their address.
815 * It is filled in by the StartMachineBasicBlock callback and queried by
816 * the getMachineBasicBlockAddress callback.
817 */
818 std::vector<uintptr_t> mMBBLocations;
819
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700820 /* mpConstantPool - The constant pool for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700821 llvm::MachineConstantPool* mpConstantPool;
822
823 /* ConstantPoolBase - A pointer to the first entry in the constant pool. */
824 void *mpConstantPoolBase;
825
826 /* ConstPoolAddresses - Addresses of individual constant pool entries. */
827 llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
828
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700829 /* mpJumpTable - The jump tables for the current function. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700830 llvm::MachineJumpTableInfo *mpJumpTable;
831
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700832 /* mpJumpTableBase - A pointer to the first entry in the jump table. */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700833 void *mpJumpTableBase;
834
835 /*
836 * When outputting a function stub in the context of some other function, we
837 * save BufferBegin/BufferEnd/CurBufferPtr here.
838 */
839 uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
840
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700841 /* mRelocations - These are the relocations that the function needs,
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700842 as emitted. */
843 std::vector<llvm::MachineRelocation> mRelocations;
844
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700845 /* mLabelLocations - This vector is a mapping from Label ID's to their
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700846 address. */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700847 llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700848
849 class EmittedFunctionCode {
850 public:
851 void* FunctionBody; // Beginning of the function's allocation.
852 void* Code; // The address the function's code actually starts at.
853 int Size; // The size of the function code
854
855 EmittedFunctionCode() : FunctionBody(NULL), Code(NULL) { return; }
856 };
857 EmittedFunctionCode* mpCurEmitFunction;
858
859 typedef std::map<const std::string, EmittedFunctionCode*
860 > EmittedFunctionsMapTy;
861 EmittedFunctionsMapTy mEmittedFunctions;
862
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700863 /* mpMMI - Machine module info for exception informations */
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700864 llvm::MachineModuleInfo* mpMMI;
865
866 GlobalAddressMapTy mGlobalAddressMap;
867
868 /*
869 * UpdateGlobalMapping - Replace an existing mapping for GV with a new
870 * address. This updates both maps as required. If "Addr" is null, the
871 * entry for the global is removed from the mappings.
872 */
873 void* UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
874 if(Addr == NULL) {
875 /* Removing mapping */
876 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
877 void *OldVal;
878
879 if(I == mGlobalAddressMap.end())
880 OldVal = NULL;
881 else {
882 OldVal = I->second;
883 mGlobalAddressMap.erase(I);
884 }
885
886 return OldVal;
887 }
888
889 void*& CurVal = mGlobalAddressMap[GV];
890 void* OldVal = CurVal;
891
892 CurVal = Addr;
893
894 return OldVal;
895 }
896
897 /*
898 * AddGlobalMapping - Tell the execution engine that the specified global is
899 * at the specified location. This is used internally as functions are
900 * JIT'd
901 * and as global variables are laid out in memory.
902 */
903 void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
904 void*& CurVal = mGlobalAddressMap[GV];
905 assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
906 CurVal = Addr;
907 return;
908 }
909
910 /*
911 * GetPointerToGlobalIfAvailable - This returns the address of the specified
912 * global value if it is has already been codegen'd,
913 * otherwise it returns null.
914 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700915 void* GetPointerToGlobalIfAvailable(const llvm::GlobalValue* GV) {
916 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700917 return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
918 }
919
920 unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool* MCP) {
921 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
922 MCP->getConstants();
923
924 if(Constants.empty())
925 return 0;
926
927 unsigned int Size = 0;
928 for(int i=0;i<Constants.size();i++) {
929 llvm::MachineConstantPoolEntry CPE = Constants[i];
930 unsigned int AlignMask = CPE.getAlignment() - 1;
931 Size = (Size + AlignMask) & ~AlignMask;
932 const llvm::Type* Ty = CPE.getType();
933 Size += mpTD->getTypeAllocSize(Ty);
934 }
935
936 return Size;
937 }
938
939 /*
940 * This function converts a Constant* into a GenericValue. The interesting
941 * part is if C is a ConstantExpr.
942 */
943 void GetConstantValue(const llvm::Constant *C, llvm::GenericValue& Result) {
944 if(C->getValueID() == llvm::Value::UndefValueVal)
945 return;
946 else if(C->getValueID() == llvm::Value::ConstantExprVal) {
947 const llvm::ConstantExpr* CE = (llvm::ConstantExpr*) C;
948 const llvm::Constant* Op0 = CE->getOperand(0);
949
950 switch(CE->getOpcode()) {
951 case llvm::Instruction::GetElementPtr:
952 {
953 /* Compute the index */
954 llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
955 CE->op_end());
956 uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(),
957 &Indices[0],
958 Indices.size());
959
960 GetConstantValue(Op0, Result);
961 Result.PointerVal = (char*) Result.PointerVal + Offset;
962
963 return;
964 }
965 break;
966
967 case llvm::Instruction::Trunc:
968 {
969 uint32_t BitWidth =
970 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
971
972 GetConstantValue(Op0, Result);
973 Result.IntVal = Result.IntVal.trunc(BitWidth);
974
975 return;
976 }
977 break;
978
979 case llvm::Instruction::ZExt:
980 {
981 uint32_t BitWidth =
982 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
983
984 GetConstantValue(Op0, Result);
985 Result.IntVal = Result.IntVal.zext(BitWidth);
986
987 return;
988 }
989 break;
990
991 case llvm::Instruction::SExt:
992 {
993 uint32_t BitWidth =
994 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
995
996 GetConstantValue(Op0, Result);
997 Result.IntVal = Result.IntVal.sext(BitWidth);
998
999 return;
1000 }
1001 break;
1002
1003
1004 case llvm::Instruction::FPTrunc:
1005 {
1006 /* FIXME long double */
1007 GetConstantValue(Op0, Result);
1008 Result.FloatVal = float(Result.DoubleVal);
1009 return;
1010 }
1011 break;
1012
1013
1014 case llvm::Instruction::FPExt:
1015 {
1016 /* FIXME long double */
1017 GetConstantValue(Op0, Result);
1018 Result.DoubleVal = double(Result.FloatVal);
1019 return;
1020 }
1021 break;
1022
1023
1024 case llvm::Instruction::UIToFP:
1025 {
1026 GetConstantValue(Op0, Result);
1027 if(CE->getType()->isFloatTy())
1028 Result.FloatVal = float(Result.IntVal.roundToDouble());
1029 else if(CE->getType()->isDoubleTy())
1030 Result.DoubleVal = Result.IntVal.roundToDouble();
1031 else if(CE->getType()->isX86_FP80Ty()) {
1032 const uint64_t zero[] = { 0, 0 };
1033 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
1034 apf.convertFromAPInt(Result.IntVal,
1035 false,
1036 llvm::APFloat::rmNearestTiesToEven);
1037 Result.IntVal = apf.bitcastToAPInt();
1038 }
1039 return;
1040 }
1041 break;
1042
1043 case llvm::Instruction::SIToFP:
1044 {
1045 GetConstantValue(Op0, Result);
1046 if(CE->getType()->isFloatTy())
1047 Result.FloatVal = float(Result.IntVal.signedRoundToDouble());
1048 else if(CE->getType()->isDoubleTy())
1049 Result.DoubleVal = Result.IntVal.signedRoundToDouble();
1050 else if(CE->getType()->isX86_FP80Ty()) {
1051 const uint64_t zero[] = { 0, 0 };
1052 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
1053 apf.convertFromAPInt(Result.IntVal,
1054 true,
1055 llvm::APFloat::rmNearestTiesToEven);
1056 Result.IntVal = apf.bitcastToAPInt();
1057 }
1058 return;
1059 }
1060 break;
1061
1062 /* double->APInt conversion handles sign */
1063 case llvm::Instruction::FPToUI:
1064 case llvm::Instruction::FPToSI:
1065 {
1066 uint32_t BitWidth =
1067 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
1068
1069 GetConstantValue(Op0, Result);
1070 if(Op0->getType()->isFloatTy())
1071 Result.IntVal =
1072 llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
1073 else if(Op0->getType()->isDoubleTy())
1074 Result.IntVal =
1075 llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal, BitWidth);
1076 else if(Op0->getType()->isX86_FP80Ty()) {
1077 llvm::APFloat apf = llvm::APFloat(Result.IntVal);
1078 uint64_t v;
1079 bool ignored;
1080 apf.convertToInteger(&v,
1081 BitWidth,
1082 CE->getOpcode()
1083 == llvm::Instruction::FPToSI,
1084 llvm::APFloat::rmTowardZero,
1085 &ignored);
1086 Result.IntVal = v; // endian?
1087 }
1088 return;
1089 }
1090 break;
1091
1092 case llvm::Instruction::PtrToInt:
1093 {
1094 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1095
1096 GetConstantValue(Op0, Result);
1097 Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
1098 (Result.PointerVal));
1099
1100 return;
1101 }
1102 break;
1103
1104 case llvm::Instruction::IntToPtr:
1105 {
1106 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
1107
1108 GetConstantValue(Op0, Result);
1109 if(PtrWidth != Result.IntVal.getBitWidth())
1110 Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
1111 assert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
1112
1113 Result.PointerVal = llvm::PointerTy
1114 (uintptr_t(Result.IntVal.getZExtValue()));
1115
1116 return;
1117 }
1118 break;
1119
1120 case llvm::Instruction::BitCast:
1121 {
1122 GetConstantValue(Op0, Result);
1123 const llvm::Type* DestTy = CE->getType();
1124
1125 switch(Op0->getType()->getTypeID()) {
1126 case llvm::Type::IntegerTyID:
1127 assert(DestTy->isFloatingPointTy() && "invalid bitcast");
1128 if(DestTy->isFloatTy())
1129 Result.FloatVal = Result.IntVal.bitsToFloat();
1130 else if(DestTy->isDoubleTy())
1131 Result.DoubleVal = Result.IntVal.bitsToDouble();
1132 break;
1133
1134 case llvm::Type::FloatTyID:
1135 assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
1136 Result.IntVal.floatToBits(Result.FloatVal);
1137 break;
1138
1139 case llvm::Type::DoubleTyID:
1140 assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
1141 Result.IntVal.doubleToBits(Result.DoubleVal);
1142 break;
1143
1144 case llvm::Type::PointerTyID:
1145 assert(DestTy->isPointerTy() && "Invalid bitcast");
1146 break; // getConstantValue(Op0) above already converted it
1147
1148 default:
1149 llvm_unreachable("Invalid bitcast operand");
1150 break;
1151 }
1152
1153 return;
1154 }
1155 break;
1156
1157 case llvm::Instruction::Add:
1158 case llvm::Instruction::FAdd:
1159 case llvm::Instruction::Sub:
1160 case llvm::Instruction::FSub:
1161 case llvm::Instruction::Mul:
1162 case llvm::Instruction::FMul:
1163 case llvm::Instruction::UDiv:
1164 case llvm::Instruction::SDiv:
1165 case llvm::Instruction::URem:
1166 case llvm::Instruction::SRem:
1167 case llvm::Instruction::And:
1168 case llvm::Instruction::Or:
1169 case llvm::Instruction::Xor:
1170 {
1171 llvm::GenericValue LHS, RHS;
1172 GetConstantValue(Op0, LHS);
1173 GetConstantValue(CE->getOperand(1), RHS);
1174
1175 switch(Op0->getType()->getTypeID()) {
1176 case llvm::Type::IntegerTyID:
1177 switch (CE->getOpcode()) {
1178 case llvm::Instruction::Add:
1179 Result.IntVal = LHS.IntVal + RHS.IntVal;
1180 break;
1181 case llvm::Instruction::Sub:
1182 Result.IntVal = LHS.IntVal - RHS.IntVal;
1183 break;
1184 case llvm::Instruction::Mul:
1185 Result.IntVal = LHS.IntVal * RHS.IntVal;
1186 break;
1187 case llvm::Instruction::UDiv:
1188 Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
1189 break;
1190 case llvm::Instruction::SDiv:
1191 Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
1192 break;
1193 case llvm::Instruction::URem:
1194 Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
1195 break;
1196 case llvm::Instruction::SRem:
1197 Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
1198 break;
1199 case llvm::Instruction::And:
1200 Result.IntVal = LHS.IntVal & RHS.IntVal;
1201 break;
1202 case llvm::Instruction::Or:
1203 Result.IntVal = LHS.IntVal | RHS.IntVal;
1204 break;
1205 case llvm::Instruction::Xor:
1206 Result.IntVal = LHS.IntVal ^ RHS.IntVal;
1207 break;
1208 default:
1209 llvm_unreachable("Invalid integer opcode");
1210 break;
1211 }
1212 break;
1213
1214 case llvm::Type::FloatTyID:
1215 switch (CE->getOpcode()) {
1216 case llvm::Instruction::FAdd:
1217 Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
1218 break;
1219 case llvm::Instruction::FSub:
1220 Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
1221 break;
1222 case llvm::Instruction::FMul:
1223 Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
1224 break;
1225 case llvm::Instruction::FDiv:
1226 Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
1227 break;
1228 case llvm::Instruction::FRem:
1229 Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
1230 break;
1231 default:
1232 llvm_unreachable("Invalid float opcode");
1233 break;
1234 }
1235 break;
1236
1237 case llvm::Type::DoubleTyID:
1238 switch (CE->getOpcode()) {
1239 case llvm::Instruction::FAdd:
1240 Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
1241 break;
1242 case llvm::Instruction::FSub:
1243 Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
1244 break;
1245 case llvm::Instruction::FMul:
1246 Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
1247 break;
1248 case llvm::Instruction::FDiv:
1249 Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
1250 break;
1251 case llvm::Instruction::FRem:
1252 Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
1253 break;
1254 default:
1255 llvm_unreachable("Invalid double opcode");
1256 break;
1257 }
1258 break;
1259
1260 case llvm::Type::X86_FP80TyID:
1261 case llvm::Type::PPC_FP128TyID:
1262 case llvm::Type::FP128TyID:
1263 {
1264 llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
1265 switch (CE->getOpcode()) {
1266 case llvm::Instruction::FAdd:
1267 apfLHS.add(llvm::APFloat(RHS.IntVal),
1268 llvm::APFloat::rmNearestTiesToEven);
1269 break;
1270 case llvm::Instruction::FSub:
1271 apfLHS.subtract(llvm::APFloat(RHS.IntVal),
1272 llvm::APFloat::rmNearestTiesToEven);
1273 break;
1274 case llvm::Instruction::FMul:
1275 apfLHS.multiply(llvm::APFloat(RHS.IntVal),
1276 llvm::APFloat::rmNearestTiesToEven);
1277 break;
1278 case llvm::Instruction::FDiv:
1279 apfLHS.divide(llvm::APFloat(RHS.IntVal),
1280 llvm::APFloat::rmNearestTiesToEven);
1281 break;
1282 case llvm::Instruction::FRem:
1283 apfLHS.mod(llvm::APFloat(RHS.IntVal),
1284 llvm::APFloat::rmNearestTiesToEven);
1285 break;
1286 default:
1287 llvm_unreachable("Invalid long double opcode");
1288 llvm_unreachable(0);
1289 break;
1290 }
1291
1292 Result.IntVal = apfLHS.bitcastToAPInt();
1293 }
1294 break;
1295
1296 default:
1297 llvm_unreachable("Bad add type!");
1298 break;
1299 } /* End switch(Op0->getType()->getTypeID()) */
1300
1301 return;
1302 }
1303
1304 default:
1305 break;
1306 } /* End switch(CE->getOpcode()) */
1307
1308 std::string msg;
1309 llvm::raw_string_ostream Msg(msg);
1310 Msg << "ConstantExpr not handled: " << *CE;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001311 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001312 } /* C->getValueID() == llvm::Value::ConstantExprVal */
1313
1314 switch (C->getType()->getTypeID()) {
1315 case llvm::Type::FloatTyID:
1316 Result.FloatVal = llvm::cast<llvm::ConstantFP>(C)
1317 ->getValueAPF().convertToFloat();
1318 break;
1319
1320 case llvm::Type::DoubleTyID:
1321 Result.DoubleVal = llvm::cast<llvm::ConstantFP>(C)
1322 ->getValueAPF().convertToDouble();
1323 break;
1324
1325 case llvm::Type::X86_FP80TyID:
1326 case llvm::Type::FP128TyID:
1327 case llvm::Type::PPC_FP128TyID:
1328 Result.IntVal = llvm::cast <llvm::ConstantFP>(C)
1329 ->getValueAPF().bitcastToAPInt();
1330 break;
1331
1332 case llvm::Type::IntegerTyID:
1333 Result.IntVal = llvm::cast<llvm::ConstantInt>(C)
1334 ->getValue();
1335 break;
1336
1337 case llvm::Type::PointerTyID:
1338 switch(C->getValueID()) {
1339 case llvm::Value::ConstantPointerNullVal:
1340 Result.PointerVal = NULL;
1341 break;
1342
1343 case llvm::Value::FunctionVal:
1344 {
1345 const llvm::Function* F = (llvm::Function*) C;
1346 Result.PointerVal = GetPointerToFunctionOrStub
1347 (const_cast<llvm::Function*>(F)
1348 );
1349 }
1350 break;
1351
1352 case llvm::Value::GlobalVariableVal:
1353 {
1354 const llvm::GlobalVariable* GV = (llvm::GlobalVariable*) C;
1355 Result.PointerVal = GetOrEmitGlobalVariable
1356 (const_cast<llvm::GlobalVariable*>(GV)
1357 );
1358 }
1359 break;
1360
1361 case llvm::Value::BlockAddressVal:
1362 {
1363 // const llvm::BlockAddress* BA = (llvm::BlockAddress*) C;
1364 // Result.PointerVal = getPointerToBasicBlock
1365 // (const_cast<llvm::BasicBlock*>(BA->getBasicBlock()));
1366 assert(false && "JIT does not support address-of-label yet!");
1367 }
1368 break;
1369
1370 default:
1371 llvm_unreachable("Unknown constant pointer type!");
1372 break;
1373 }
1374 break;
1375
1376 default:
1377 std::string msg;
1378 llvm::raw_string_ostream Msg(msg);
1379 Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001380 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001381 break;
1382 }
1383
1384 return;
1385 }
1386
1387 /*
1388 * StoreValueToMemory -
1389 * Stores the data in @Val of type @Ty at address @Addr.
1390 */
1391 void StoreValueToMemory(const llvm::GenericValue& Val, void* Addr,
1392 const llvm::Type *Ty) {
1393 const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
1394
1395 switch(Ty->getTypeID()) {
1396 case llvm::Type::IntegerTyID:
1397 {
1398 const llvm::APInt& IntVal = Val.IntVal;
1399 assert((IntVal.getBitWidth() + 7) / 8 >= StoreBytes &&
1400 "Integer too small!");
1401
1402 uint8_t *Src = (uint8_t*) IntVal.getRawData();
1403
1404 if(llvm::sys::isLittleEndianHost()) {
1405 /*
1406 * Little-endian host - the source is ordered from LSB to MSB.
1407 * Order the destination from LSB to MSB: Do a straight copy.
1408 */
1409 memcpy(Addr, Src, StoreBytes);
1410 } else {
1411 /*
1412 * Big-endian host - the source is an array of 64 bit words
1413 * ordered from LSW to MSW.
1414 *
1415 * Each word is ordered from MSB to LSB.
1416 *
1417 * Order the destination from MSB to LSB:
1418 * Reverse the word order, but not the bytes in a word.
1419 */
1420 unsigned int i = StoreBytes;
1421 while(i > sizeof(uint64_t)) {
1422 i -= sizeof(uint64_t);
1423 memcpy((uint8_t*) Addr + i, Src, sizeof(uint64_t));
1424 Src += sizeof(uint64_t);
1425 }
1426
1427 memcpy(Addr, Src + sizeof(uint64_t) - i, i);
1428 }
1429 }
1430 break;
1431
1432 case llvm::Type::FloatTyID:
1433 {
1434 *((float*) Addr) = Val.FloatVal;
1435 }
1436 break;
1437
1438 case llvm::Type::DoubleTyID:
1439 {
1440 *((double*) Addr) = Val.DoubleVal;
1441 }
1442 break;
1443
1444 case llvm::Type::X86_FP80TyID:
1445 {
1446 memcpy(Addr, Val.IntVal.getRawData(), 10);
1447 }
1448 break;
1449
1450 case llvm::Type::PointerTyID:
1451 {
1452 /*
1453 * Ensure 64 bit target pointers are fully
1454 * initialized on 32 bit hosts.
1455 */
1456 if(StoreBytes != sizeof(llvm::PointerTy))
1457 memset(Addr, 0, StoreBytes);
1458 *((llvm::PointerTy*) Addr) = Val.PointerVal;
1459 }
1460 break;
1461
1462 default:
1463 break;
1464 }
1465
1466 if(llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
1467 std::reverse((uint8_t*) Addr, (uint8_t*) Addr + StoreBytes);
1468
1469 return;
1470 }
1471
1472 /*
1473 * InitializeConstantToMemory -
1474 * Recursive function to apply a @Constant value into the
1475 * specified memory location @Addr.
1476 */
1477 void InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
1478 switch(C->getValueID()) {
1479 case llvm::Value::UndefValueVal:
1480 // Nothing to do
1481 break;
1482
1483 case llvm::Value::ConstantVectorVal:
1484 {
1485 // dynamic cast may hurt performance
1486 const llvm::ConstantVector* CP = (llvm::ConstantVector*) C;
1487
1488 unsigned int ElementSize = mpTD->getTypeAllocSize
1489 (CP->getType()->getElementType());
1490
1491 for(int i=0;i<CP->getNumOperands();i++)
1492 InitializeConstantToMemory(CP->getOperand(i),
1493 (char*) Addr + i * ElementSize);
1494 }
1495 break;
1496
1497 case llvm::Value::ConstantAggregateZeroVal:
1498 memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
1499 break;
1500
1501 case llvm::Value::ConstantArrayVal:
1502 {
1503 const llvm::ConstantArray* CPA = (llvm::ConstantArray*) C;
1504 unsigned int ElementSize = mpTD->getTypeAllocSize
1505 (CPA->getType()->getElementType());
1506
1507 for(int i=0;i<CPA->getNumOperands();i++)
1508 InitializeConstantToMemory(CPA->getOperand(i),
1509 (char*) Addr + i * ElementSize);
1510 }
1511 break;
1512
1513 case llvm::Value::ConstantStructVal:
1514 {
1515 const llvm::ConstantStruct* CPS = (llvm::ConstantStruct*) C;
1516 const llvm::StructLayout* SL = mpTD->getStructLayout
1517 (llvm::cast<llvm::StructType>(CPS->getType()));
1518
1519 for(int i=0;i<CPS->getNumOperands();i++)
1520 InitializeConstantToMemory(CPS->getOperand(i),
1521 (char*) Addr +
1522 SL->getElementOffset(i));
1523 }
1524 break;
1525
1526 default:
1527 {
1528 if(C->getType()->isFirstClassType()) {
1529 llvm::GenericValue Val;
1530 GetConstantValue(C, Val);
1531 StoreValueToMemory(Val, Addr, C->getType());
1532 } else
1533 llvm_unreachable
1534 ("Unknown constant type to initialize memory with!");
1535 }
1536 break;
1537 }
1538
1539 return;
1540 }
1541
1542 void emitConstantPool(llvm::MachineConstantPool *MCP) {
1543 if(mpTJI->hasCustomConstantPool())
1544 return;
1545
1546 /*
1547 * Constant pool address resolution is handled by the target itself in ARM
1548 * (TargetJITInfo::hasCustomConstantPool() return true).
1549 */
1550#if !defined(PROVIDE_ARM_CODEGEN)
1551 const std::vector<llvm::MachineConstantPoolEntry>& Constants =
1552 MCP->getConstants();
1553
1554 if(Constants.empty())
1555 return;
1556
1557 unsigned Size = GetConstantPoolSizeInBytes(MCP);
1558 unsigned Align = MCP->getConstantPoolAlignment();
1559
1560 mpConstantPoolBase = allocateSpace(Size, Align);
1561 mpConstantPool = MCP;
1562
1563 if(mpConstantPoolBase == NULL)
1564 return; /* out of memory */
1565
1566 unsigned Offset = 0;
1567 for(int i=0;i<Constants.size();i++) {
1568 llvm::MachineConstantPoolEntry CPE = Constants[i];
1569 unsigned AlignMask = CPE.getAlignment() - 1;
1570 Offset = (Offset + AlignMask) & ~AlignMask;
1571
1572 uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
1573 mConstPoolAddresses.push_back(CAddr);
1574
1575 if(CPE.isMachineConstantPoolEntry())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001576 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001577 ("Initialize memory with machine specific constant pool"
1578 " entry has not been implemented!");
1579
1580 InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
1581
1582 const llvm::Type *Ty = CPE.Val.ConstVal->getType();
1583 Offset += mpTD->getTypeAllocSize(Ty);
1584 }
1585#endif
1586 return;
1587 }
1588
1589 void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1590 if(mpTJI->hasCustomJumpTables())
1591 return;
1592
1593 const std::vector<llvm::MachineJumpTableEntry>& JT =
1594 MJTI->getJumpTables();
1595 if(JT.empty())
1596 return;
1597
1598 unsigned NumEntries = 0;
1599 for(int i=0;i<JT.size();i++)
1600 NumEntries += JT[i].MBBs.size();
1601
1602 unsigned EntrySize = MJTI->getEntrySize(*mpTD);
1603
1604 mpJumpTable = MJTI;;
1605 mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
1606 MJTI->getEntryAlignment(*mpTD));
1607
1608 return;
1609 }
1610
1611 void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
1612 if(mpTJI->hasCustomJumpTables())
1613 return;
1614
1615 const std::vector<llvm::MachineJumpTableEntry>& JT =
1616 MJTI->getJumpTables();
1617 if(JT.empty() || mpJumpTableBase == 0)
1618 return;
1619
1620 assert((llvm::TargetMachine::getRelocationModel() == llvm::Reloc::Static)
1621 && "Cross JIT'ing?");
1622 assert(MJTI->getEntrySize(*mpTD) == sizeof(void*) && "Cross JIT'ing?");
1623
1624 /*
1625 * For each jump table, map each target in the jump table to the
1626 * address of an emitted MachineBasicBlock.
1627 */
1628 intptr_t *SlotPtr = (intptr_t*) mpJumpTableBase;
1629 for(int i=0;i<JT.size();i++) {
1630 const std::vector<llvm::MachineBasicBlock*>& MBBs = JT[i].MBBs;
1631 /*
1632 * Store the address of the basic block for this jump table slot in the
1633 * memory we allocated for the jump table in 'initJumpTableInfo'
1634 */
1635 for(int j=0;j<MBBs.size();j++)
1636 *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
1637 }
1638 }
1639
1640 void* GetPointerToGlobal(llvm::GlobalValue* V, void* Reference,
1641 bool MayNeedFarStub) {
1642 switch(V->getValueID()) {
1643 case llvm::Value::FunctionVal:
1644 {
1645 llvm::Function* F = (llvm::Function*) V;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001646
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001647 /* If we have code, go ahead and return that. */
1648 if(void* ResultPtr = GetPointerToGlobalIfAvailable(F))
1649 return ResultPtr;
1650
1651 if(void* FnStub = GetLazyFunctionStubIfAvailable(F))
1652 /*
1653 * Return the function stub if it's already created.
1654 * We do this first so that:
1655 * we're returning the same address for the function
1656 * as any previous call.
1657 *
1658 * TODO: Yes, this is wrong. The lazy stub isn't guaranteed
1659 * to be close enough to call.
1660 */
1661 return FnStub;
1662
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001663 /*
1664 * If we know the target can handle arbitrary-distance calls, try to
1665 * return a direct pointer.
1666 */
1667 if(!MayNeedFarStub) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001668 /*
1669 * x86_64 architecture may encounter the bug
1670 * http://hlvm.llvm.org/bugs/show_bug.cgi?id=5201
1671 * which generate instruction "call" instead of "callq".
1672 *
1673 * And once the real address of stub is
1674 * greater than 64-bit long, the replacement will truncate
1675 * to 32-bit resulting a serious problem.
1676 */
1677#if !defined(__x86_64__)
1678 /*
1679 * If this is an external function pointer,
1680 * we can force the JIT to
1681 * 'compile' it, which really just adds it to the map.
1682 */
1683 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1684 return GetPointerToFunction(F, /* AbortOnFailure */true);
1685#endif
1686 }
1687
1688 /*
1689 * Otherwise, we may need a to emit a stub, and, conservatively, we
1690 * always do so.
1691 */
1692 return GetLazyFunctionStub(F);
1693 }
1694 break;
1695
1696 case llvm::Value::GlobalVariableVal:
1697 return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
1698 break;
1699
1700 case llvm::Value::GlobalAliasVal:
1701 {
1702 llvm::GlobalAlias* GA = (llvm::GlobalAlias*) V;
1703 const llvm::GlobalValue* GV = GA->resolveAliasedGlobal(false);
1704
1705 switch(GV->getValueID()) {
1706 case llvm::Value::FunctionVal:
1707 /* FIXME: is there's any possibility that the function
1708 is not code-gen'd? */
1709 return GetPointerToFunction(
1710 const_cast<llvm::Function*>((const llvm::Function*) GV),
1711 /* AbortOnFailure */true
1712 );
1713 break;
1714
1715 case llvm::Value::GlobalVariableVal:
1716 {
1717 if(void* p = mGlobalAddressMap[GV])
1718 return p;
1719
1720 llvm::GlobalVariable* GVar = (llvm::GlobalVariable*) GV;
1721 EmitGlobalVariable(GVar);
1722
1723 return mGlobalAddressMap[GV];
1724 }
1725 break;
1726
1727 case llvm::Value::GlobalAliasVal:
1728 assert(false && "Alias should be resolved ultimately!");
1729 break;
1730 }
1731 }
1732 break;
1733
1734 default:
1735 break;
1736 }
1737
1738 llvm_unreachable("Unknown type of global value!");
1739
1740 }
1741
1742 /*
1743 * GetPointerToFunctionOrStub - If the specified function has been
1744 * code-gen'd, return a pointer to the function.
1745 * If not, compile it, or use
1746 * a stub to implement lazy compilation if available.
1747 */
1748 void* GetPointerToFunctionOrStub(llvm::Function* F) {
1749 /*
1750 * If we have already code generated the function,
1751 * just return the address.
1752 */
1753 if(void* Addr = GetPointerToGlobalIfAvailable(F))
1754 return Addr;
1755
1756 /* Get a stub if the target supports it. */
1757 return GetLazyFunctionStub(F);
1758 }
1759
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001760 typedef llvm::DenseMap<const llvm::Function*, void*> FunctionToLazyStubMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001761 FunctionToLazyStubMapTy mFunctionToLazyStubMap;
1762
1763 void* GetLazyFunctionStubIfAvailable(llvm::Function* F) {
1764 return mFunctionToLazyStubMap.lookup(F);
1765 }
1766
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001767 std::set<const llvm::Function*> PendingFunctions;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001768 void* GetLazyFunctionStub(llvm::Function* F) {
1769 /* If we already have a lazy stub for this function, recycle it. */
1770 void*& Stub = mFunctionToLazyStubMap[F];
1771 if(Stub)
1772 return Stub;
1773
1774 /*
1775 * In any cases, we should NOT resolve function at runtime
1776 * (though we are able to).
1777 * We resolve this right now.
1778 */
1779 void* Actual = NULL;
1780 if(F->isDeclaration() || F->hasAvailableExternallyLinkage())
1781 Actual = GetPointerToFunction(F, /* AbortOnFailure */true);
1782
1783 /*
1784 * Codegen a new stub, calling the actual address of
1785 * the external function, if it was resolved.
1786 */
1787 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1788 startGVStub(F, SL.Size, SL.Alignment);
1789 Stub = mpTJI->emitFunctionStub(F, Actual, *this);
1790 finishGVStub();
1791
1792 /*
1793 * We really want the address of the stub in the GlobalAddressMap
1794 * for the JIT, not the address of the external function.
1795 */
1796 UpdateGlobalMapping(F, Stub);
1797
1798 if(!Actual)
1799 PendingFunctions.insert(F);
1800 else
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001801 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001802
1803 return Stub;
1804 }
1805
1806 /* Our resolver to undefined symbol */
1807 BCCSymbolLookupFn mpSymbolLookupFn;
1808 void* mpSymbolLookupContext;
1809
1810 void* GetPointerToFunction(llvm::Function* F, bool AbortOnFailure) {
1811 void* Addr = GetPointerToGlobalIfAvailable(F);
1812 if(Addr)
1813 return Addr;
1814
1815 assert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
1816 "Internal error: only external defined function routes here!");
1817
1818 /* Handle the failure resolution by ourselves. */
1819 Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
1820 /* AbortOnFailure */ false);
1821
1822 /*
1823 * If we resolved the symbol to a null address (eg. a weak external)
1824 * return a null pointer let the application handle it.
1825 */
1826 if(Addr == NULL)
1827 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001828 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001829 ("Could not resolve external function address: " + F->getName()
1830 );
1831 else
1832 return NULL;
1833
1834 AddGlobalMapping(F, Addr);
1835
1836 return Addr;
1837 }
1838
1839 void* GetPointerToNamedSymbol(const std::string& Name,
1840 bool AbortOnFailure) {
1841 if(void* Addr = FindRuntimeFunction(Name.c_str()))
1842 return Addr;
1843
1844 if(mpSymbolLookupFn)
1845 if(void* Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
1846 return Addr;
1847
1848 if(AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001849 llvm::report_fatal_error("Program used external symbol '" + Name +
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001850 "' which could not be resolved!");
1851
1852 return NULL;
1853 }
1854
1855 /*
1856 * GetOrEmitGlobalVariable - Return the address of the specified global
1857 * variable, possibly emitting it to memory if needed. This is used by the
1858 * Emitter.
1859 */
1860 void* GetOrEmitGlobalVariable(const llvm::GlobalVariable *GV) {
1861 void* Ptr = GetPointerToGlobalIfAvailable(GV);
1862 if(Ptr)
1863 return Ptr;
1864
1865 if(GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
1866 /* If the global is external, just remember the address. */
1867 Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
1868 AddGlobalMapping(GV, Ptr);
1869 } else {
1870 /* If the global hasn't been emitted to memory yet,
1871 allocate space and emit it into memory. */
1872 Ptr = GetMemoryForGV(GV);
1873 AddGlobalMapping(GV, Ptr);
1874 EmitGlobalVariable(GV);
1875 }
1876
1877 return Ptr;
1878 }
1879
1880 /*
1881 * GetMemoryForGV - This method abstracts memory allocation of global
1882 * variable so that the JIT can allocate thread local variables depending
1883 * on the target.
1884 */
1885 void* GetMemoryForGV(const llvm::GlobalVariable* GV) {
1886 char* Ptr;
1887
1888 const llvm::Type* GlobalType = GV->getType()->getElementType();
1889 size_t S = mpTD->getTypeAllocSize(GlobalType);
1890 size_t A = mpTD->getPreferredAlignment(GV);
1891
1892 if(GV->isThreadLocal()) {
1893 /*
1894 * We can support TLS by
1895 *
1896 * Ptr = TJI.allocateThreadLocalMemory(S);
1897 *
1898 * But I tend not to .
1899 * (should we disable this in the front-end (i.e. slang)?).
1900 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001901 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001902 ("Compilation of Thread Local Storage (TLS) is disabled!");
1903
1904 } else if(mpTJI->allocateSeparateGVMemory()) {
1905 /*
1906 * On the Apple's ARM target (such as iPhone),
1907 * the global variable should be
1908 * placed in separately allocated heap memory rather than in the same
1909 * code memory.
1910 * The question is, how about the Android?
1911 */
1912 if(A <= 8) {
1913 Ptr = (char*) malloc(S);
1914 } else {
1915 /*
1916 * Allocate (S + A) bytes of memory,
1917 * then use an aligned pointer within that space.
1918 */
1919 Ptr = (char*) malloc(S + A);
1920 unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
1921 Ptr = Ptr + (MisAligned ? (A - MisAligned) : 0);
1922 }
1923 } else {
1924 Ptr = (char*) allocateGlobal(S, A);
1925 }
1926
1927 return Ptr;
1928 }
1929
1930 void EmitGlobalVariable(const llvm::GlobalVariable *GV) {
1931 void* GA = GetPointerToGlobalIfAvailable(GV);
1932
1933 if(GV->isThreadLocal())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001934 llvm::report_fatal_error
1935 ("We don't support Thread Local Storage (TLS)!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001936
1937 if(GA == NULL) {
1938 /* If it's not already specified, allocate memory for the global. */
1939 GA = GetMemoryForGV(GV);
1940 AddGlobalMapping(GV, GA);
1941 }
1942
1943 InitializeConstantToMemory(GV->getInitializer(), GA);
1944
1945 /* You can do some statistics on global variable here */
1946 return;
1947 }
1948
1949 typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void*
1950 > GlobalToIndirectSymMapTy;
1951 GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
1952
1953 void* GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
1954 /*
1955 * Make sure GV is emitted first, and create a stub containing the fully
1956 * resolved address.
1957 */
1958 void* GVAddress = GetPointerToGlobal(V, Reference, false);
1959
1960 /* If we already have a stub for this global variable, recycle it. */
1961 void*& IndirectSym = GlobalToIndirectSymMap[V];
1962 /* Otherwise, codegen a new indirect symbol. */
1963 if(!IndirectSym)
1964 IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
1965
1966 return IndirectSym;
1967 }
1968
1969 /*
1970 * ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap
1971 * for external functions.
1972 *
1973 * TODO: Of course, external functions don't need a lazy stub.
1974 * It's actually
1975 * here to make it more likely that far calls succeed, but no single
1976 * stub can guarantee that. I'll remove this in a subsequent checkin
1977 * when I actually fix far calls. (comment from LLVM source)
1978 */
1979 std::map<void*, void*> ExternalFnToStubMap;
1980
1981 /*
1982 * GetExternalFunctionStub - Return a stub for the function at the
1983 * specified address.
1984 */
1985 void* GetExternalFunctionStub(void* FnAddr) {
1986 void*& Stub = ExternalFnToStubMap[FnAddr];
1987 if(Stub)
1988 return Stub;
1989
1990 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1991 startGVStub(0, SL.Size, SL.Alignment);
1992 Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
1993 finishGVStub();
1994
1995 return Stub;
1996 }
1997
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001998#if defined(USE_DISASSEMBLER)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001999 const llvm::MCAsmInfo* mpAsmInfo;
2000 const llvm::MCDisassembler* mpDisassmbler;
2001 llvm::MCInstPrinter* mpIP;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002002
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002003 class BufferMemoryObject : public llvm::MemoryObject {
2004 private:
2005 const uint8_t* mBytes;
2006 uint64_t mLength;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002007
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002008 public:
2009 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) :
2010 mBytes(Bytes), mLength(Length) { }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002011
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002012 uint64_t getBase() const { return 0; }
2013 uint64_t getExtent() const { return mLength; }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002014
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002015 int readByte(uint64_t Addr, uint8_t *Byte) const {
2016 if(Addr > getExtent())
2017 return -1;
2018 *Byte = mBytes[Addr];
2019 return 0;
2020 }
2021 };
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002022
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002023 void Disassemble(const llvm::StringRef& Name, uint8_t* Start,
2024 size_t Length, bool IsStub) {
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002025 llvm::raw_fd_ostream* OS;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002026#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002027 std::string ErrorInfo;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002028 OS = new llvm::raw_fd_ostream(
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002029 "/data/local/tmp/out.S", ErrorInfo, llvm::raw_fd_ostream::F_Append);
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002030 if(!ErrorInfo.empty()) { // some errors occurred
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002031 //LOGE("Error in creating disassembly file");
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002032 delete OS;
2033 return;
2034 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002035#else
2036 OS = &llvm::outs();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002037#endif
2038
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002039
2040 *OS << "JIT: Disassembled code: " << Name
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002041 << ((IsStub) ? " (stub)" : "") << "\n";
2042
2043 if(mpAsmInfo == NULL)
2044 mpAsmInfo = mpTarget->createAsmInfo(Triple);
2045 if(mpDisassmbler == NULL)
2046 mpDisassmbler = mpTarget->createMCDisassembler();
2047 if(mpIP == NULL)
2048 mpIP = mpTarget->createMCInstPrinter(
2049 mpAsmInfo->getAssemblerDialect(), *mpAsmInfo);
2050
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002051 const BufferMemoryObject* BufferMObj =
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002052 new BufferMemoryObject(Start, Length);
2053 uint64_t Size;
2054 uint64_t Index;
2055
2056 for(Index=0;Index<Length;Index+=Size) {
2057 llvm::MCInst Inst;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002058
2059 if(mpDisassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
2060 /* REMOVED */ llvm::nulls()))
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002061 {
2062 OS->indent(4).write("0x", 2).
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002063 write_hex((uint32_t) Start + Index).write(':');
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002064 mpIP->printInst(&Inst, *OS);
2065 *OS << "\n";
2066 } else {
2067 if (Size == 0)
2068 Size = 1; // skip illegible bytes
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002069 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002070 }
2071
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002072 *OS << "\n";
2073 delete BufferMObj;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002074
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002075#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002076 /* If you want the disassemble results write to file, uncomment this */
2077 OS->close();
2078 delete OS;
2079#endif
2080
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002081 return;
2082 }
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002083#else
2084 void Disassemble(const std::string& Name, uint8_t* Start,
2085 size_t Length, bool IsStub) {
2086 return;
2087 }
2088#endif /* defined(USE_DISASSEMBLER) */
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002089
2090 public:
2091 /* Will take the ownership of @MemMgr */
2092 CodeEmitter(CodeMemoryManager* pMemMgr) :
2093 mpMemMgr(pMemMgr),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002094 mpTarget(NULL),
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002095 mpTJI(NULL),
2096 mpTD(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002097#if defined(USE_DISASSEMBLER)
2098 mpAsmInfo(NULL),
2099 mpDisassmbler(NULL),
2100 mpIP(NULL),
2101#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002102 mpCurEmitFunction(NULL),
2103 mpConstantPool(NULL),
2104 mpJumpTable(NULL),
2105 mpMMI(NULL),
2106 mpSymbolLookupFn(NULL),
2107 mpSymbolLookupContext(NULL)
2108 {
2109 return;
2110 }
2111
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002112 inline global_addresses_const_iterator global_address_begin() const {
2113 return mGlobalAddressMap.begin();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002114 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002115 inline global_addresses_const_iterator global_address_end() const {
2116 return mGlobalAddressMap.end();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002117 }
2118
2119 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2120 mpSymbolLookupFn = pFn;
2121 mpSymbolLookupContext = pContext;
2122 return;
2123 }
2124
2125 void setTargetMachine(llvm::TargetMachine& TM) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002126 /* set Target */
2127 mpTarget = &TM.getTarget();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002128 /* set TargetJITInfo */
2129 mpTJI = TM.getJITInfo();
2130 /* set TargetData */
2131 mpTD = TM.getTargetData();
2132
2133 /*
2134 if(mpTJI->needsGOT())
2135 mpMemMgr->AllocateGOT(); // however,
2136 // both X86 and ARM target don't need GOT
2137 // (mpTJI->needsGOT() always returns false)
2138 */
2139 assert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
2140
2141 return;
2142 }
2143
2144 /*
2145 * startFunction - This callback is invoked when the specified function is
2146 * about to be code generated. This initializes the BufferBegin/End/Ptr
2147 * fields.
2148 */
2149 void startFunction(llvm::MachineFunction &F) {
2150 uintptr_t ActualSize = 0;
2151
2152 mpMemMgr->setMemoryWritable();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002153 /*
2154 * BufferBegin, BufferEnd and CurBufferPtr
2155 * are all inherited from class MachineCodeEmitter,
2156 * which is the super class of the class JITCodeEmitter.
2157 *
2158 * BufferBegin/BufferEnd - Pointers to the start and end of the memory
2159 * allocated for this code buffer.
2160 *
2161 * CurBufferPtr - Pointer to the next byte of memory to fill when emitting
2162 * code.
2163 * This is guranteed to be in the range [BufferBegin,BufferEnd]. If
2164 * this pointer is at BufferEnd, it will never move due to code emission,
2165 * and
2166 * all code emission requests will be ignored (this is
2167 * the buffer overflow condition).
2168 */
2169 BufferBegin = CurBufferPtr = mpMemMgr
2170 ->startFunctionBody(F.getFunction(), ActualSize);
2171 BufferEnd = BufferBegin + ActualSize;
2172
2173 if(mpCurEmitFunction == NULL)
2174 mpCurEmitFunction = new EmittedFunctionCode();
2175 mpCurEmitFunction->FunctionBody = BufferBegin;
2176
2177 /* Ensure the constant pool/jump table info is at least 4-byte aligned. */
2178 emitAlignment(16);
2179
2180 emitConstantPool(F.getConstantPool());
2181 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2182 initJumpTableInfo(MJTI);
2183
2184 /* About to start emitting the machine code for the function. */
2185 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
2186
2187 UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
2188
2189 mpCurEmitFunction->Code = CurBufferPtr;
2190
2191 mMBBLocations.clear();
2192
2193 return;
2194 }
2195
2196 /*
2197 * finishFunction - This callback is invoked
2198 * when the specified function has
2199 * finished code generation.
2200 * If a buffer overflow has occurred, this method
2201 * returns true (the callee is required to try again), otherwise it returns
2202 * false.
2203 */
2204 bool finishFunction(llvm::MachineFunction &F) {
2205 if(CurBufferPtr == BufferEnd) {
2206 /* No enough memory */
2207 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2208 return false;
2209 }
2210
2211 if(llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
2212 emitJumpTableInfo(MJTI);
2213
2214 /*
2215 * FnStart is the start of the text,
2216 * not the start of the constant pool and other per-function data.
2217 */
2218 uint8_t* FnStart = (uint8_t*) GetPointerToGlobalIfAvailable
2219 (F.getFunction());
2220
2221 /* FnEnd is the end of the function's machine code. */
2222 uint8_t* FnEnd = CurBufferPtr;
2223
2224 if(!mRelocations.empty()) {
2225 /* Resolve the relocations to concrete pointers. */
2226 for(int i=0;i<mRelocations.size();i++) {
2227 llvm::MachineRelocation& MR = mRelocations[i];
2228 void* ResultPtr = NULL;
2229
2230 if(!MR.letTargetResolve()) {
2231 if(MR.isExternalSymbol()) {
2232 ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
2233 if(MR.mayNeedFarStub())
2234 ResultPtr = GetExternalFunctionStub(ResultPtr);
2235 } else if(MR.isGlobalValue()) {
2236 ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
2237 BufferBegin
2238 + MR.getMachineCodeOffset(),
2239 MR.mayNeedFarStub());
2240 } else if(MR.isIndirectSymbol()) {
2241 ResultPtr = GetPointerToGVIndirectSym
2242 (MR.getGlobalValue(),
2243 BufferBegin + MR.getMachineCodeOffset()
2244 );
2245 } else if(MR.isBasicBlock()) {
2246 ResultPtr =
2247 (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
2248 } else if(MR.isConstantPoolIndex()) {
2249 ResultPtr =
2250 (void*) getConstantPoolEntryAddress
2251 (MR.getConstantPoolIndex());
2252 } else {
2253 assert(MR.isJumpTableIndex() && "Unknown type of relocation");
2254 ResultPtr =
2255 (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
2256 }
2257
2258 MR.setResultPointer(ResultPtr);
2259 }
2260 }
2261
2262 mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
2263 mpMemMgr->getGOTBase());
2264 }
2265
2266 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
2267 /*
2268 * CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
2269 * global variables that were referenced in the relocations.
2270 */
2271 if(CurBufferPtr == BufferEnd)
2272 return false;
2273
2274 /* Now that we've succeeded in emitting the function */
2275 mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
2276 BufferBegin = CurBufferPtr = 0;
2277
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002278 if(F.getFunction()->hasName())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002279 mEmittedFunctions[F.getFunction()->getNameStr()] = mpCurEmitFunction;
2280 mpCurEmitFunction = NULL;
2281
2282 mRelocations.clear();
2283 mConstPoolAddresses.clear();
2284
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002285 if(mpMMI)
2286 mpMMI->EndFunction();
2287
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002288 updateFunctionStub(F.getFunction());
2289
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -07002290 /* Mark code region readable and executable if it's not so already. */
2291 mpMemMgr->setMemoryExecutable();
2292
2293 Disassemble(F.getFunction()->getName(), FnStart, FnEnd - FnStart, false);
2294
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002295 return false;
2296 }
2297
2298 void startGVStub(const llvm::GlobalValue* GV, unsigned StubSize,
2299 unsigned Alignment) {
2300 mpSavedBufferBegin = BufferBegin;
2301 mpSavedBufferEnd = BufferEnd;
2302 mpSavedCurBufferPtr = CurBufferPtr;
2303
2304 BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
2305 Alignment);
2306 BufferEnd = BufferBegin + StubSize + 1;
2307
2308 return;
2309 }
2310
2311 void startGVStub(void* Buffer, unsigned StubSize) {
2312 mpSavedBufferBegin = BufferBegin;
2313 mpSavedBufferEnd = BufferEnd;
2314 mpSavedCurBufferPtr = CurBufferPtr;
2315
2316 BufferBegin = CurBufferPtr = (uint8_t *) Buffer;
2317 BufferEnd = BufferBegin + StubSize + 1;
2318
2319 return;
2320 }
2321
2322 void finishGVStub() {
2323 assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
2324
2325 /* restore */
2326 BufferBegin = mpSavedBufferBegin;
2327 BufferEnd = mpSavedBufferEnd;
2328 CurBufferPtr = mpSavedCurBufferPtr;
2329
2330 return;
2331 }
2332
2333 /*
2334 * allocIndirectGV - Allocates and fills storage for an indirect
2335 * GlobalValue, and returns the address.
2336 */
2337 void* allocIndirectGV(const llvm::GlobalValue *GV,
2338 const uint8_t *Buffer, size_t Size,
2339 unsigned Alignment) {
2340 uint8_t* IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
2341 memcpy(IndGV, Buffer, Size);
2342 return IndGV;
2343 }
2344
2345 /* emitLabel - Emits a label */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002346 void emitLabel(llvm::MCSymbol *Label) {
2347 mLabelLocations[Label] = getCurrentPCValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002348 return;
2349 }
2350
2351 /*
2352 * allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
2353 * this method does not allocate memory in the current output buffer,
2354 * because a global may live longer than the current function.
2355 */
2356 void* allocateGlobal(uintptr_t Size, unsigned Alignment) {
2357 /* Delegate this call through the memory manager. */
2358 return mpMemMgr->allocateGlobal(Size, Alignment);
2359 }
2360
2361 /*
2362 * StartMachineBasicBlock - This should be called by the target when a new
2363 * basic block is about to be emitted. This way the MCE knows where the
2364 * start of the block is, and can implement getMachineBasicBlockAddress.
2365 */
2366 void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
2367 if(mMBBLocations.size() <= (unsigned) MBB->getNumber())
2368 mMBBLocations.resize((MBB->getNumber() + 1) * 2);
2369 mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
2370 return;
2371 }
2372
2373 /*
2374 * addRelocation - Whenever a relocatable address is needed, it should be
2375 * noted with this interface.
2376 */
2377 void addRelocation(const llvm::MachineRelocation &MR) {
2378 mRelocations.push_back(MR);
2379 return;
2380 }
2381
2382 /*
2383 * getConstantPoolEntryAddress - Return the address of the 'Index' entry in
2384 * the constant pool that was last emitted with
2385 * the emitConstantPool method.
2386 */
2387 uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
2388 assert(Index < mpConstantPool->getConstants().size() &&
2389 "Invalid constant pool index!");
2390 return mConstPoolAddresses[Index];
2391 }
2392
2393 /*
2394 * getJumpTableEntryAddress - Return the address of the jump table
2395 * with index
2396 * 'Index' in the function that last called initJumpTableInfo.
2397 */
2398 uintptr_t getJumpTableEntryAddress(unsigned Index) const {
2399 const std::vector<llvm::MachineJumpTableEntry>& JT =
2400 mpJumpTable->getJumpTables();
2401
2402 assert(Index < JT.size() && "Invalid jump table index!");
2403
2404 unsigned int Offset = 0;
2405 unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
2406
2407 for(int i=0;i<Index;i++)
2408 Offset += JT[i].MBBs.size();
2409 Offset *= EntrySize;
2410
2411 return (uintptr_t)((char *) mpJumpTableBase + Offset);
2412 }
2413
2414 /*
2415 * getMachineBasicBlockAddress - Return the address of the specified
2416 * MachineBasicBlock, only usable after the label for the MBB has been
2417 * emitted.
2418 */
2419 uintptr_t getMachineBasicBlockAddress(llvm::MachineBasicBlock *MBB) const {
2420 assert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
2421 mMBBLocations[MBB->getNumber()] && "MBB not emitted!");
2422 return mMBBLocations[MBB->getNumber()];
2423 }
2424
2425 /*
2426 * getLabelAddress - Return the address of the specified LabelID,
2427 * only usable after the LabelID has been emitted.
2428 */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002429 uintptr_t getLabelAddress(llvm::MCSymbol* Label) const {
2430 assert(mLabelLocations.count(Label) && "Label not emitted!");
2431 return mLabelLocations.find(Label)->second;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002432 }
2433
2434 /*
2435 * Specifies the MachineModuleInfo object.
2436 * This is used for exception handling
2437 * purposes.
2438 */
2439 void setModuleInfo(llvm::MachineModuleInfo* Info) {
2440 mpMMI = Info;
2441 return;
2442 }
2443
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002444 void updateFunctionStub(const llvm::Function* F) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002445 /* Get the empty stub we generated earlier. */
2446 void* Stub;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002447 std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002448 if(I != PendingFunctions.end())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002449 Stub = mFunctionToLazyStubMap[F];
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002450 else
2451 return;
2452
2453 void* Addr = GetPointerToGlobalIfAvailable(F);
2454
2455 assert(Addr != Stub &&
2456 "Function must have non-stub address to be updated.");
2457
2458 /*
2459 * Tell the target jit info to rewrite the stub at the specified address,
2460 * rather than creating a new one.
2461 */
2462 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
2463 startGVStub(Stub, SL.Size);
2464 mpTJI->emitFunctionStub(F, Addr, *this);
2465 finishGVStub();
2466
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002467 Disassemble(F->getName(), (uint8_t*) Stub, SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002468
2469 PendingFunctions.erase(I);
2470
2471 return;
2472 }
2473
2474 /*
2475 * Once you finish the compilation on a translation unit,
2476 * you can call this function to recycle the memory
2477 * (which is used at compilation time and not needed for runtime).
2478 *
2479 * NOTE: You should not call this funtion until the code-gen passes
2480 * for a given module is done.
2481 * Otherwise, the results is undefined and may cause the system crash!
2482 */
2483 void releaseUnnecessary() {
2484 mMBBLocations.clear();
2485 mLabelLocations.clear();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002486 mGlobalAddressMap.clear();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002487 mFunctionToLazyStubMap.clear();
2488 GlobalToIndirectSymMap.clear();
2489 ExternalFnToStubMap.clear();
2490 PendingFunctions.clear();
2491
2492 return;
2493 }
2494
2495 void reset() {
2496 releaseUnnecessary();
2497
2498 mpSymbolLookupFn = NULL;
2499 mpSymbolLookupContext = NULL;
2500
2501 mpTJI = NULL;
2502 mpTD = NULL;
2503
2504 for(EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin();
2505 I != mEmittedFunctions.end();
2506 I++)
2507 if(I->second != NULL)
2508 delete I->second;
2509 mEmittedFunctions.clear();
2510
2511 mpMemMgr->reset();
2512
2513 return;
2514 }
2515
2516 void* lookup(const char* Name) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002517 return lookup( llvm::StringRef(Name) );
2518 }
2519
2520 void* lookup(const llvm::StringRef& Name) {
2521 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(Name.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002522 if(I == mEmittedFunctions.end())
2523 return NULL;
2524 else
2525 return I->second->Code;
2526 }
2527
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002528 void getFunctionNames(BCCsizei* actualFunctionCount,
2529 BCCsizei maxFunctionCount,
2530 BCCchar** functions) {
2531 int functionCount = mEmittedFunctions.size();
2532
2533 if(actualFunctionCount)
2534 *actualFunctionCount = functionCount;
2535 if(functionCount > maxFunctionCount)
2536 functionCount = maxFunctionCount;
2537 if(functions)
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002538 for(EmittedFunctionsMapTy::const_iterator it =
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002539 mEmittedFunctions.begin();
2540 functionCount > 0;
2541 functionCount--, it++)
2542 *functions++ = (BCCchar*) it->first.c_str();
2543
2544 return;
2545 }
2546
2547 void getFunctionBinary(BCCchar* label,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002548 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002549 BCCsizei* length) {
2550 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(label);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002551 if(I == mEmittedFunctions.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002552 *base = NULL;
2553 *length = 0;
2554 } else {
2555 *base = I->second->Code;
2556 *length = I->second->Size;
2557 }
2558 return;
2559 }
2560
2561 ~CodeEmitter() {
2562 if(mpMemMgr)
2563 delete mpMemMgr;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002564#if defined(USE_DISASSEMBLER)
2565 if(mpAsmInfo)
2566 delete mpAsmInfo;
2567 if(mpDisassmbler)
2568 delete mpDisassmbler;
2569 if(mpIP)
2570 delete mpIP;
2571#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002572 return;
2573 }
2574 /* }}} */
2575 }; /* End of Class CodeEmitter */
2576
2577 /* The CodeEmitter */
2578 llvm::OwningPtr<CodeEmitter> mCodeEmitter;
2579 CodeEmitter* createCodeEmitter() {
2580 mCodeEmitter.reset(new CodeEmitter(mCodeMemMgr.take()));
2581 return mCodeEmitter.get();
2582 }
2583
2584 BCCSymbolLookupFn mpSymbolLookupFn;
2585 void* mpSymbolLookupContext;
2586
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002587 llvm::LLVMContext* mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002588 llvm::Module* mModule;
2589
2590 bool mTypeInformationPrepared;
2591 std::vector<const llvm::Type*> mTypes;
2592
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002593 public:
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002594 Compiler() :
2595 mpSymbolLookupFn(NULL),
2596 mpSymbolLookupContext(NULL),
2597 mContext(NULL),
2598 mModule(NULL)
2599 {
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002600 llvm::remove_fatal_error_handler();
2601 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002602 mContext = new llvm::LLVMContext();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002603 return;
2604 }
2605
2606 /* interface for BCCscript::registerSymbolCallback() */
2607 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2608 mpSymbolLookupFn = pFn;
2609 mpSymbolLookupContext = pContext;
2610 return;
2611 }
2612
2613 int loadModule(const char* bitcode, size_t bitcodeSize) {
2614 llvm::MemoryBuffer* SB = NULL;
2615
2616 if(bitcode == NULL || bitcodeSize <= 0)
2617 return 0;
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002618
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002619 GlobalInitialization();
2620
2621 /* Package input to object MemoryBuffer */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002622 SB = llvm::MemoryBuffer::getMemBuffer(
2623 llvm::StringRef(bitcode, bitcodeSize));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002624 if(SB == NULL) {
Shih-wei Liao7a0e42a2010-05-11 03:41:56 -07002625 LOGE("Error reading input Bitcode into memory");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002626 setError("Error reading input Bitcode into memory");
2627 goto on_bcc_load_module_error;
2628 }
2629
2630 /* Read the input Bitcode as a Module */
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002631 mModule = llvm::ParseBitcodeFile(SB, *mContext, &mError);
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002632
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002633on_bcc_load_module_error:
2634 if (SB)
2635 delete SB;
2636
2637 return hasError();
2638 }
2639
2640 /* interace for bccCompileScript() */
2641 int compile() {
2642 llvm::TargetData* TD = NULL;
2643
2644 llvm::TargetMachine* TM = NULL;
2645 const llvm::Target* Target;
2646 std::string FeaturesStr;
2647
2648 llvm::FunctionPassManager* CodeGenPasses = NULL;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002649
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002650 const llvm::NamedMDNode* PragmaMetadata;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002651 const llvm::NamedMDNode* ExportVarMetadata;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002652 const llvm::NamedMDNode* ExportFuncMetadata;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002653
2654 if(mModule == NULL) /* No module was loaded */
2655 return 0;
2656
2657 /* Create TargetMachine */
2658 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
2659 if(hasError())
2660 goto on_bcc_compile_error;
2661
2662 if(!CPU.empty() || !Features.empty()) {
2663 llvm::SubtargetFeatures F;
2664 F.setCPU(CPU);
2665 for(std::vector<std::string>::const_iterator it = Features.begin();
2666 it != Features.end();
2667 it++)
2668 F.AddFeature(*it);
2669 FeaturesStr = F.getString();
2670 }
2671
2672 TM = Target->createTargetMachine(Triple, FeaturesStr);
2673 if(TM == NULL) {
2674 setError("Failed to create target machine implementation for the"
2675 " specified triple '" + Triple + "'");
2676 goto on_bcc_compile_error;
2677 }
2678
2679 /* Create memory manager for creation of code emitter later */
2680 if(!mCodeMemMgr.get() && !createCodeMemoryManager()) {
2681 setError("Failed to startup memory management for further compilation");
2682 goto on_bcc_compile_error;
2683 }
2684
2685 /* Create code emitter */
2686 if(!mCodeEmitter.get()) {
2687 if(!createCodeEmitter()) {
2688 setError("Failed to create machine code emitter to complete"
2689 " the compilation");
2690 goto on_bcc_compile_error;
2691 }
2692 } else {
2693 /* reuse the code emitter */
2694 mCodeEmitter->reset();
2695 }
2696
2697 mCodeEmitter->setTargetMachine(*TM);
2698 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
2699 mpSymbolLookupContext);
2700
2701 /* Get target data from Module */
2702 TD = new llvm::TargetData(mModule);
2703 /* Create code-gen pass to run the code emitter */
2704 CodeGenPasses = new llvm::FunctionPassManager(mModule);
2705 CodeGenPasses->add(TD); // Will take the ownership of TD
2706
2707 if(TM->addPassesToEmitMachineCode(*CodeGenPasses,
2708 *mCodeEmitter, CodeGenOptLevel)) {
2709 setError("The machine code emission is not supported by BCC on target '"
2710 + Triple + "'");
2711 goto on_bcc_compile_error;
2712 }
2713
2714 /*
2715 * Run the pass (the code emitter) on every non-declaration function
2716 * in the module
2717 */
2718 CodeGenPasses->doInitialization();
2719 for(llvm::Module::iterator I = mModule->begin();
2720 I != mModule->end();
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002721 I++) {
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002722 if(!I->isDeclaration()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002723 CodeGenPasses->run(*I);
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002724 }
2725 }
2726
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002727 CodeGenPasses->doFinalization();
2728
2729 /* Copy the global address mapping from code emitter and remapping */
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002730 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
2731 if(ExportVarMetadata) {
2732 for(int i=0;i<ExportVarMetadata->getNumOperands();i++) {
2733 llvm::MDNode* ExportVar = ExportVarMetadata->getOperand(i);
2734 if(ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2735 llvm::Value* ExportVarNameMDS = ExportVar->getOperand(0);
2736 if(ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
2737 llvm::StringRef ExportVarName =
2738 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
2739 CodeEmitter::global_addresses_const_iterator I;
2740 for(I = mCodeEmitter->global_address_begin();
2741 I != mCodeEmitter->global_address_end();
2742 I++)
2743 {
2744 if(I->first->getValueID() != llvm::Value::GlobalVariableVal)
2745 continue;
2746 if(ExportVarName == I->first->getName()) {
2747 mExportVars.push_back(I->second);
2748 break;
2749 }
2750 }
2751 if(I != mCodeEmitter->global_address_end())
2752 continue; // found
2753 }
2754 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002755 // if here, the global variable record in metadata is not
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002756 // found, make an empty slot
2757 mExportVars.push_back(NULL);
2758 }
2759 assert((mExportVars.size() == ExportVarMetadata->getNumOperands()) &&
2760 "Number of slots doesn't match the number of export variables!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002761 }
2762
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002763 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
2764 if(ExportFuncMetadata) {
2765 for(int i=0;i<ExportFuncMetadata->getNumOperands();i++) {
2766 llvm::MDNode* ExportFunc = ExportFuncMetadata->getOperand(i);
2767 if(ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
2768 llvm::Value* ExportFuncNameMDS = ExportFunc->getOperand(0);
2769 if(ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
2770 llvm::StringRef ExportFuncName =
2771 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
2772 mExportFuncs.push_back(mCodeEmitter->lookup(ExportFuncName));
2773 }
2774 }
2775 }
2776 }
2777
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002778 /*
2779 * Tell code emitter now can release the memory using
2780 * during the JIT since we have done the code emission
2781 */
2782 mCodeEmitter->releaseUnnecessary();
2783
2784 /*
2785 * Finally, read pragma information from the metadata node
2786 * of the @Module if any
2787 */
2788 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
2789 if(PragmaMetadata)
2790 for(int i=0;i<PragmaMetadata->getNumOperands();i++) {
2791 llvm::MDNode* Pragma = PragmaMetadata->getOperand(i);
2792 if(Pragma != NULL &&
2793 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
2794 llvm::Value* PragmaNameMDS = Pragma->getOperand(0);
2795 llvm::Value* PragmaValueMDS = Pragma->getOperand(1);
2796
2797 if((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
2798 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
2799 llvm::StringRef PragmaName =
2800 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
2801 llvm::StringRef PragmaValue =
2802 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
2803
2804 mPragmas.push_back( make_pair( std::string(PragmaName.data(),
2805 PragmaName.size()),
2806 std::string(PragmaValue.data(),
2807 PragmaValue.size())
2808 )
2809 );
2810 }
2811 }
2812 }
2813
2814 on_bcc_compile_error:
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002815 //LOGE("on_bcc_compiler_error");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002816 if (CodeGenPasses) {
2817 delete CodeGenPasses;
2818 } else if (TD) {
2819 delete TD;
2820 }
2821 if (TM)
2822 delete TM;
2823
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002824 if (mError.empty()) {
2825 return false;
2826 }
2827
2828 // LOGE(getErrorMessage());
2829 return true;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002830 }
2831
2832 /* interface for bccGetScriptInfoLog() */
2833 char* getErrorMessage() {
2834 return const_cast<char*>(mError.c_str());
2835 }
2836
2837 /* interface for bccGetScriptLabel() */
2838 void* lookup(const char* name) {
2839 void* addr = NULL;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002840 if(mCodeEmitter.get())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002841 /* Find function pointer */
2842 addr = mCodeEmitter->lookup(name);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002843 return addr;
2844 }
2845
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002846 /* Interface for bccGetExportVars() */
2847 void getExportVars(BCCsizei* actualVarCount,
2848 BCCsizei maxVarCount,
2849 BCCvoid** vars) {
2850 int varCount = mExportVars.size();
2851
2852 if(actualVarCount)
2853 *actualVarCount = varCount;
2854 if(varCount > maxVarCount)
2855 varCount = maxVarCount;
2856 if(vars)
2857 for(ExportVarList::const_iterator it = mExportVars.begin();
2858 it != mExportVars.end();
2859 it++)
2860 {
2861 *vars++ = *it;
2862 }
2863
2864 return;
2865 }
2866
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002867 /* Interface for bccGetExportFuncs() */
2868 void getExportFuncs(BCCsizei* actualFuncCount,
2869 BCCsizei maxFuncCount,
2870 BCCvoid** funcs) {
2871 int funcCount = mExportFuncs.size();
2872
2873 if(actualFuncCount)
2874 *actualFuncCount = funcCount;
2875 if(funcCount > maxFuncCount)
2876 funcCount = maxFuncCount;
2877 if(funcs)
2878 for(ExportFuncList::const_iterator it = mExportFuncs.begin();
2879 it != mExportFuncs.end();
2880 it++)
2881 {
2882 *funcs++ = *it;
2883 }
2884
2885 return;
2886 }
2887
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002888 /* Interface for bccGetPragmas() */
2889 void getPragmas(BCCsizei* actualStringCount,
2890 BCCsizei maxStringCount,
2891 BCCchar** strings) {
2892 int stringCount = mPragmas.size() * 2;
2893
2894 if(actualStringCount)
2895 *actualStringCount = stringCount;
2896 if(stringCount > maxStringCount)
2897 stringCount = maxStringCount;
2898 if(strings)
2899 for(PragmaList::const_iterator it = mPragmas.begin();
2900 stringCount > 0;
2901 stringCount-=2, it++)
2902 {
2903 *strings++ = (BCCchar*) it->first.c_str();
2904 *strings++ = (BCCchar*) it->second.c_str();
2905 }
2906
2907 return;
2908 }
2909
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002910 /* Interface for bccGetFunctions() */
2911 void getFunctions(BCCsizei* actualFunctionCount,
2912 BCCsizei maxFunctionCount,
2913 BCCchar** functions) {
2914 if(mCodeEmitter.get())
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002915 mCodeEmitter->getFunctionNames(actualFunctionCount,
2916 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002917 functions);
2918 else
2919 *actualFunctionCount = 0;
2920
2921 return;
2922 }
2923
2924 /* Interface for bccGetFunctionBinary() */
2925 void getFunctionBinary(BCCchar* function,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002926 BCCvoid** base,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002927 BCCsizei* length) {
2928 if(mCodeEmitter.get()) {
2929 mCodeEmitter->getFunctionBinary(function, base, length);
2930 } else {
2931 *base = NULL;
2932 *length = 0;
2933 }
2934 return;
2935 }
2936
2937 inline const llvm::Module* getModule() const {
2938 return mModule;
2939 }
2940
2941 inline const std::vector<const llvm::Type*>& getTypes() const {
2942 return mTypes;
2943 }
2944
2945 ~Compiler() {
2946 delete mModule;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -07002947 //llvm::llvm_shutdown();
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002948 delete mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002949 return;
2950 }
2951}; /* End of Class Compiler */
2952
2953bool Compiler::GlobalInitialized = false;
2954
2955/* Code generation optimization level for the compiler */
2956llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
2957
2958std::string Compiler::Triple;
2959
2960std::string Compiler::CPU;
2961
2962std::vector<std::string> Compiler::Features;
2963
2964/*
2965 * The named of metadata node that pragma resides
2966 * (should be synced with slang.cpp)
2967 */
2968const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
2969
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002970/*
2971 * The named of metadata node that export variable name resides
2972 * (should be synced with slang.cpp)
2973 */
2974const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
2975
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002976/*
2977 * The named of metadata node that export function name resides
2978 * (should be synced with slang.cpp)
2979 */
2980const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
2981
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002982struct BCCscript {
2983 /*
2984 * Part I. Compiler
2985 */
2986
2987 Compiler compiler;
2988
2989 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid* pContext) {
2990 compiler.registerSymbolCallback(pFn, pContext);
2991 }
2992
2993 /*
2994 * Part II. Logistics & Error handling
2995 */
2996
2997 BCCscript() {
2998 bccError = BCC_NO_ERROR;
2999 }
3000
3001 ~BCCscript() {
3002 }
3003
3004 void setError(BCCenum error) {
3005 if (bccError == BCC_NO_ERROR && error != BCC_NO_ERROR) {
3006 bccError = error;
3007 }
3008 }
3009
3010 BCCenum getError() {
3011 BCCenum result = bccError;
3012 bccError = BCC_NO_ERROR;
3013 return result;
3014 }
3015
3016 BCCenum bccError;
3017};
3018
3019
3020extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003021BCCscript* bccCreateScript()
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003022{
3023 return new BCCscript();
3024}
3025
3026extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003027BCCenum bccGetError( BCCscript* script )
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003028{
3029 return script->getError();
3030}
3031
3032extern "C"
3033void bccDeleteScript(BCCscript* script) {
3034 delete script;
3035}
3036
3037extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003038void bccRegisterSymbolCallback(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003039 BCCSymbolLookupFn pFn,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003040 BCCvoid* pContext)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003041{
3042 script->registerSymbolCallback(pFn, pContext);
3043}
3044
3045extern "C"
3046void bccScriptBitcode(BCCscript* script,
3047 const BCCchar* bitcode,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003048 BCCint size)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003049{
3050 script->compiler.loadModule(bitcode, size);
3051}
3052
3053extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003054void bccCompileScript(BCCscript* script)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003055{
3056 int result = script->compiler.compile();
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003057 if (result)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003058 script->setError(BCC_INVALID_OPERATION);
3059}
3060
3061extern "C"
3062void bccGetScriptInfoLog(BCCscript* script,
3063 BCCsizei maxLength,
3064 BCCsizei* length,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003065 BCCchar* infoLog)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003066{
3067 char* message = script->compiler.getErrorMessage();
3068 int messageLength = strlen(message) + 1;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003069 if (length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003070 *length = messageLength;
3071
3072 if (infoLog && maxLength > 0) {
3073 int trimmedLength = maxLength < messageLength ? maxLength : messageLength;
3074 memcpy(infoLog, message, trimmedLength);
3075 infoLog[trimmedLength] = 0;
3076 }
3077}
3078
3079extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003080void bccGetScriptLabel(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003081 const BCCchar * name,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003082 BCCvoid ** address)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003083{
3084 void* value = script->compiler.lookup(name);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003085 if (value)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003086 *address = value;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003087 else
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003088 script->setError(BCC_INVALID_VALUE);
3089}
3090
3091extern "C"
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07003092void bccGetExportVars(BCCscript* script,
3093 BCCsizei* actualVarCount,
3094 BCCsizei maxVarCount,
3095 BCCvoid** vars)
3096{
3097 script->compiler.getExportVars(actualVarCount, maxVarCount, vars);
3098}
3099
3100extern "C"
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07003101void bccGetExportFuncs(BCCscript* script,
3102 BCCsizei* actualFuncCount,
3103 BCCsizei maxFuncCount,
3104 BCCvoid** funcs)
3105{
3106 script->compiler.getExportFuncs(actualFuncCount, maxFuncCount, funcs);
3107}
3108
3109extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003110void bccGetPragmas(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003111 BCCsizei* actualStringCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003112 BCCsizei maxStringCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003113 BCCchar** strings)
3114{
3115 script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
3116}
3117
3118extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003119void bccGetFunctions(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003120 BCCsizei* actualFunctionCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003121 BCCsizei maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003122 BCCchar** functions)
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003123{
3124 script->compiler.getFunctions(actualFunctionCount,
3125 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003126 functions);
3127}
3128
3129extern "C"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003130void bccGetFunctionBinary(BCCscript* script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003131 BCCchar* function,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003132 BCCvoid** base,
3133 BCCsizei* length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003134{
3135 script->compiler.getFunctionBinary(function, base, length);
3136}
3137
3138struct BCCtype {
3139 const Compiler* compiler;
3140 const llvm::Type* t;
3141};
3142
3143} /* End of namespace bcc */