blob: bbda6e0ade7e4231a62af12c9cafb90ab1a83e1e [file] [log] [blame]
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001/*
Zonr Chang932648d2010-10-13 22:23:56 +08002 * Copyright 2010, The Android Open Source Project
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003 *
Zonr Chang932648d2010-10-13 22:23:56 +08004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Shih-wei Liao77ed6142010-04-07 12:21:42 -070015 */
16
Zonr Chang932648d2010-10-13 22:23:56 +080017// Bitcode compiler (bcc) for Android:
18// This is an eager-compilation JIT running on Android.
19
Shih-wei Liao77ed6142010-04-07 12:21:42 -070020#define LOG_TAG "bcc"
21#include <cutils/log.h>
22
23#include <ctype.h>
24#include <errno.h>
25#include <limits.h>
26#include <stdarg.h>
27#include <stdint.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -070032#include <sys/mman.h>
Shih-wei Liao77ed6142010-04-07 12:21:42 -070033
34#include <cutils/hashmap.h>
35
Shih-wei Liao77ed6142010-04-07 12:21:42 -070036#if defined(__arm__)
Zonr Chang932648d2010-10-13 22:23:56 +080037# define DEFAULT_ARM_CODEGEN
38# define PROVIDE_ARM_CODEGEN
Shih-wei Liao77ed6142010-04-07 12:21:42 -070039#elif defined(__i386__)
Zonr Chang932648d2010-10-13 22:23:56 +080040# define DEFAULT_X86_CODEGEN
41# define PROVIDE_X86_CODEGEN
Shih-wei Liao77ed6142010-04-07 12:21:42 -070042#elif defined(__x86_64__)
Zonr Chang932648d2010-10-13 22:23:56 +080043# define DEFAULT_X64_CODEGEN
44# define PROVIDE_X64_CODEGEN
Shih-wei Liao77ed6142010-04-07 12:21:42 -070045#endif
46
47#if defined(FORCE_ARM_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +080048# define DEFAULT_ARM_CODEGEN
49# undef DEFAULT_X86_CODEGEN
50# undef DEFAULT_X64_CODEGEN
51# define PROVIDE_ARM_CODEGEN
52# undef PROVIDE_X86_CODEGEN
53# undef PROVIDE_X64_CODEGEN
Shih-wei Liao77ed6142010-04-07 12:21:42 -070054#elif defined(FORCE_X86_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +080055# undef DEFAULT_ARM_CODEGEN
56# define DEFAULT_X86_CODEGEN
57# undef DEFAULT_X64_CODEGEN
58# undef PROVIDE_ARM_CODEGEN
59# define PROVIDE_X86_CODEGEN
60# undef PROVIDE_X64_CODEGEN
Shih-wei Liao77ed6142010-04-07 12:21:42 -070061#elif defined(FORCE_X64_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +080062# undef DEFAULT_ARM_CODEGEN
63# undef DEFAULT_X86_CODEGEN
64# define DEFAULT_X64_CODEGEN
65# undef PROVIDE_ARM_CODEGEN
66# undef PROVIDE_X86_CODEGEN
67# define PROVIDE_X64_CODEGEN
Shih-wei Liao77ed6142010-04-07 12:21:42 -070068#endif
69
70#if defined(DEFAULT_ARM_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +080071# define TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
Shih-wei Liao77ed6142010-04-07 12:21:42 -070072#elif defined(DEFAULT_X86_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +080073# define TARGET_TRIPLE_STRING "i686-unknown-linux"
Shih-wei Liao77ed6142010-04-07 12:21:42 -070074#elif defined(DEFAULT_X64_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +080075# define TARGET_TRIPLE_STRING "x86_64-unknown-linux"
Shih-wei Liao77ed6142010-04-07 12:21:42 -070076#endif
77
78#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
Zonr Chang932648d2010-10-13 22:23:56 +080079# define ARM_USE_VFP
Shih-wei Liao77ed6142010-04-07 12:21:42 -070080#endif
81
82#include <bcc/bcc.h>
83#include "bcc_runtime.h"
84
Zonr Chang932648d2010-10-13 22:23:56 +080085#define LOG_API(...) do {} while (0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -070086// #define LOG_API(...) fprintf (stderr, __VA_ARGS__)
87
Zonr Chang932648d2010-10-13 22:23:56 +080088#define LOG_STACK(...) do {} while (0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -070089// #define LOG_STACK(...) fprintf (stderr, __VA_ARGS__)
90
91// #define PROVIDE_TRACE_CODEGEN
92
93#if defined(USE_DISASSEMBLER)
Zonr Chang932648d2010-10-13 22:23:56 +080094# include "llvm/MC/MCInst.h"
95# include "llvm/MC/MCAsmInfo.h"
96# include "llvm/MC/MCInstPrinter.h"
97# include "llvm/MC/MCDisassembler.h"
Shih-wei Liao3cf39d12010-04-29 19:30:51 -070098// If you want the disassemble results written to file, define this:
99# define USE_DISASSEMBLER_FILE
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700100#endif
101
102#include <set>
103#include <map>
104#include <list>
105#include <cmath>
106#include <string>
107#include <cstring>
Zonr Chang932648d2010-10-13 22:23:56 +0800108#include <algorithm> // for std::reverse
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700109
Zonr Chang932648d2010-10-13 22:23:56 +0800110// VMCore
111#include "llvm/Use.h"
112#include "llvm/User.h"
Zonr Chang97f5e612010-10-22 20:38:26 +0800113#include "llvm/Linker.h"
Zonr Chang932648d2010-10-13 22:23:56 +0800114#include "llvm/Module.h"
115#include "llvm/Function.h"
116#include "llvm/Constant.h"
117#include "llvm/Constants.h"
118#include "llvm/Instruction.h"
119#include "llvm/PassManager.h"
120#include "llvm/LLVMContext.h"
121#include "llvm/GlobalValue.h"
122#include "llvm/Instructions.h"
123#include "llvm/OperandTraits.h"
124#include "llvm/TypeSymbolTable.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700125
126// System
Zonr Chang932648d2010-10-13 22:23:56 +0800127#include "llvm/System/Host.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700128
129// ADT
Zonr Chang932648d2010-10-13 22:23:56 +0800130#include "llvm/ADT/APInt.h"
131#include "llvm/ADT/APFloat.h"
132#include "llvm/ADT/DenseMap.h"
133#include "llvm/ADT/ValueMap.h"
134#include "llvm/ADT/StringMap.h"
135#include "llvm/ADT/OwningPtr.h"
136#include "llvm/ADT/SmallString.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700137
138// Target
Zonr Chang932648d2010-10-13 22:23:56 +0800139#include "llvm/Target/TargetData.h"
140#include "llvm/Target/TargetSelect.h"
141#include "llvm/Target/TargetOptions.h"
142#include "llvm/Target/TargetMachine.h"
143#include "llvm/Target/TargetJITInfo.h"
144#include "llvm/Target/TargetRegistry.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700145#include "llvm/Target/SubtargetFeature.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700146
147// Support
Zonr Chang932648d2010-10-13 22:23:56 +0800148#include "llvm/Support/Casting.h"
149#include "llvm/Support/raw_ostream.h"
150#include "llvm/Support/ValueHandle.h"
151#include "llvm/Support/MemoryBuffer.h"
152#include "llvm/Support/MemoryObject.h"
153#include "llvm/Support/ManagedStatic.h"
154#include "llvm/Support/ErrorHandling.h"
155#include "llvm/Support/StandardPasses.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700156#include "llvm/Support/FormattedStream.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700157
158// Bitcode
Zonr Chang932648d2010-10-13 22:23:56 +0800159#include "llvm/Bitcode/ReaderWriter.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700160
161// CodeGen
Zonr Chang932648d2010-10-13 22:23:56 +0800162#include "llvm/CodeGen/Passes.h"
163#include "llvm/CodeGen/JITCodeEmitter.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700164#include "llvm/CodeGen/MachineFunction.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700165#include "llvm/CodeGen/RegAllocRegistry.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700166#include "llvm/CodeGen/SchedulerRegistry.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700167#include "llvm/CodeGen/MachineRelocation.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700168#include "llvm/CodeGen/MachineModuleInfo.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700169#include "llvm/CodeGen/MachineCodeEmitter.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700170#include "llvm/CodeGen/MachineConstantPool.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700171#include "llvm/CodeGen/MachineJumpTableInfo.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700172
173// ExecutionEngine
174#include "llvm/ExecutionEngine/GenericValue.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700175#include "llvm/ExecutionEngine/JITMemoryManager.h"
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700176
Shih-wei Liaoe64c2872010-10-25 13:44:53 -0700177extern "C" void LLVMInitializeARMDisassembler();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700178
Zonr Chang932648d2010-10-13 22:23:56 +0800179//
180// Compilation class that suits Android's needs.
181// (Support: no argument passed, ...)
182//
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700183namespace bcc {
184
185class Compiler {
Zonr Chang932648d2010-10-13 22:23:56 +0800186 // This part is designed to be orthogonal to those exported bcc*() functions
187 // implementation and internal struct BCCscript.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700188
Zonr Chang932648d2010-10-13 22:23:56 +0800189 //////////////////////////////////////////////////////////////////////////////
190 // The variable section below (e.g., Triple, CodeGenOptLevel)
191 // is initialized in GlobalInitialization()
192 //
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700193 static bool GlobalInitialized;
194
Zonr Chang932648d2010-10-13 22:23:56 +0800195 // If given, this will be the name of the target triple to compile for.
196 // If not given, the initial values defined in this file will be used.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700197 static std::string Triple;
198
199 static llvm::CodeGenOpt::Level CodeGenOptLevel;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700200
Zonr Chang932648d2010-10-13 22:23:56 +0800201 // End of section of GlobalInitializing variables
202 //////////////////////////////////////////////////////////////////////////////
203
204 // If given, the name of the target CPU to generate code for.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700205 static std::string CPU;
206
Zonr Chang932648d2010-10-13 22:23:56 +0800207 // The list of target specific features to enable or disable -- this should
208 // be a list of strings starting with '+' (enable) or '-' (disable).
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700209 static std::vector<std::string> Features;
210
211 struct Runtime {
Zonr Chang932648d2010-10-13 22:23:56 +0800212 const char *mName;
213 void *mPtr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700214 };
215 static struct Runtime Runtimes[];
216
217 static void GlobalInitialization() {
Zonr Chang932648d2010-10-13 22:23:56 +0800218 if (GlobalInitialized)
219 return;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700220
Zonr Chang932648d2010-10-13 22:23:56 +0800221 // if (!llvm::llvm_is_multithreaded())
222 // llvm::llvm_start_multithreaded();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700223
Zonr Chang932648d2010-10-13 22:23:56 +0800224 // Set Triple, CPU and Features here
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700225 Triple = TARGET_TRIPLE_STRING;
226
Zonr Chang932648d2010-10-13 22:23:56 +0800227 // TODO(zonr): NEON for JIT
228 // Features.push_back("+neon");
229 // Features.push_back("+vmlx");
230 // Features.push_back("+neonfp");
Shih-wei Liao3cf39d12010-04-29 19:30:51 -0700231 Features.push_back("+vfp3");
Shih-wei Liao21ef3072010-10-23 22:33:12 -0700232 Features.push_back("+d16");
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700233
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700234#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
235 LLVMInitializeARMTargetInfo();
236 LLVMInitializeARMTarget();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700237#if defined(USE_DISASSEMBLER)
238 LLVMInitializeARMDisassembler();
239 LLVMInitializeARMAsmPrinter();
240#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700241#endif
242
243#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
244 LLVMInitializeX86TargetInfo();
245 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700246#if defined(USE_DISASSEMBLER)
247 LLVMInitializeX86Disassembler();
248 LLVMInitializeX86AsmPrinter();
249#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700250#endif
251
252#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
253 LLVMInitializeX86TargetInfo();
254 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700255#if defined(USE_DISASSEMBLER)
256 LLVMInitializeX86Disassembler();
257 LLVMInitializeX86AsmPrinter();
258#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700259#endif
260
Zonr Chang932648d2010-10-13 22:23:56 +0800261 // -O0: llvm::CodeGenOpt::None
262 // -O1: llvm::CodeGenOpt::Less
263 // -O2: llvm::CodeGenOpt::Default
264 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liaobfda6c92010-10-24 02:43:04 -0700265 CodeGenOptLevel = llvm::CodeGenOpt::None;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700266
Zonr Chang932648d2010-10-13 22:23:56 +0800267 // Below are the global settings to LLVM
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700268
Zonr Chang932648d2010-10-13 22:23:56 +0800269 // Disable frame pointer elimination optimization
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700270 llvm::NoFramePointerElim = false;
271
Zonr Chang932648d2010-10-13 22:23:56 +0800272 // Use hardfloat ABI
273 //
274 // FIXME: Need to detect the CPU capability and decide whether to use
275 // softfp. To use softfp, change following 2 lines to
276 //
277 // llvm::FloatABIType = llvm::FloatABI::Soft;
278 // llvm::UseSoftFloat = true;
279 //
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700280 llvm::FloatABIType = llvm::FloatABI::Soft;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700281 llvm::UseSoftFloat = false;
282
Zonr Chang932648d2010-10-13 22:23:56 +0800283 // BCC needs all unknown symbols resolved at JIT/compilation time.
284 // So we don't need any dynamic relocation model.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700285 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
286
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700287#if defined(DEFAULT_X64_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +0800288 // Data address in X86_64 architecture may reside in a far-away place
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700289 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
290#else
Zonr Chang932648d2010-10-13 22:23:56 +0800291 // This is set for the linker (specify how large of the virtual addresses
292 // we can access for all unknown symbols.)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700293 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
294#endif
295
Zonr Chang932648d2010-10-13 22:23:56 +0800296 // Register the scheduler
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700297 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
298
Zonr Chang932648d2010-10-13 22:23:56 +0800299 // Register allocation policy:
300 // createFastRegisterAllocator: fast but bad quality
301 // createLinearScanRegisterAllocator: not so fast but good quality
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700302 llvm::RegisterRegAlloc::setDefault
303 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
Shih-wei Liao16016012010-09-10 17:55:03 -0700304 llvm::createFastRegisterAllocator :
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700305 llvm::createLinearScanRegisterAllocator);
306
307 GlobalInitialized = true;
308 return;
309 }
310
311 static void LLVMErrorHandler(void *UserData, const std::string &Message) {
Zonr Chang932648d2010-10-13 22:23:56 +0800312 std::string *Error = static_cast<std::string*>(UserData);
Shih-wei Liao066d5ef2010-05-11 03:28:39 -0700313 Error->assign(Message);
Nick Kralevichfc97e9f2010-05-17 14:59:16 -0700314 LOGE("%s", Message.c_str());
Zonr Chang932648d2010-10-13 22:23:56 +0800315 exit(1);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700316 }
317
318 static const llvm::StringRef PragmaMetadataName;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700319 static const llvm::StringRef ExportVarMetadataName;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700320 static const llvm::StringRef ExportFuncMetadataName;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700321
322 private:
Shih-wei Liaoc5611992010-05-09 06:37:55 -0700323 std::string mError;
324
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700325 inline bool hasError() const {
326 return !mError.empty();
327 }
Zonr Chang932648d2010-10-13 22:23:56 +0800328 inline void setError(const char *Error) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700329 mError.assign(Error); // Copying
330 return;
331 }
Zonr Chang932648d2010-10-13 22:23:56 +0800332 inline void setError(const std::string &Error) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700333 mError = Error;
334 return;
335 }
336
337 typedef std::list< std::pair<std::string, std::string> > PragmaList;
338 PragmaList mPragmas;
339
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700340 typedef std::list<void*> ExportVarList;
341 ExportVarList mExportVars;
342
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700343 typedef std::list<void*> ExportFuncList;
344 ExportFuncList mExportFuncs;
345
Zonr Chang932648d2010-10-13 22:23:56 +0800346 //////////////////////////////////////////////////////////////////////////////
347 // Memory manager for the code reside in memory
348 //
349 // The memory for our code emitter is very simple and is conforming to the
350 // design decisions of Android RenderScript's Exection Environment:
351 // The code, data, and symbol sizes are limited (currently 100KB.)
352 //
353 // It's very different from typical compiler, which has no limitation
354 // on the code size. How does code emitter know the size of the code
355 // it is about to emit? It does not know beforehand. We want to solve
356 // this without complicating the code emitter too much.
357 //
358 // We solve this by pre-allocating a certain amount of memory,
359 // and then start the code emission. Once the buffer overflows, the emitter
360 // simply discards all the subsequent emission but still has a counter
361 // on how many bytes have been emitted.
362 //
363 // So once the whole emission is done, if there's a buffer overflow,
364 // it re-allocates the buffer with enough size (based on the
365 // counter from previous emission) and re-emit again.
366 //
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700367 class CodeMemoryManager : public llvm::JITMemoryManager {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700368 private:
Zonr Chang932648d2010-10-13 22:23:56 +0800369 // 128 KiB for code
370 static const unsigned int MaxCodeSize = 128 * 1024;
371 // 1 KiB for global offset table (GOT)
372 static const unsigned int MaxGOTSize = 1 * 1024;
373 // 128 KiB for global variable
374 static const unsigned int MaxGlobalVarSize = 128 * 1024;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700375
Zonr Chang932648d2010-10-13 22:23:56 +0800376 //
377 // Our memory layout is as follows:
378 //
379 // The direction of arrows (-> and <-) shows memory's growth direction
380 // when more space is needed.
381 //
382 // @mpCodeMem:
383 // +--------------------------------------------------------------+
384 // | Function Memory ... -> <- ... Stub/GOT |
385 // +--------------------------------------------------------------+
386 // |<------------------ Total: @MaxCodeSize KiB ----------------->|
387 //
388 // Where size of GOT is @MaxGOTSize KiB.
389 //
390 // @mpGVMem:
391 // +--------------------------------------------------------------+
392 // | Global variable ... -> |
393 // +--------------------------------------------------------------+
394 // |<--------------- Total: @MaxGlobalVarSize KiB --------------->|
395 //
396 //
397 // @mCurFuncMemIdx: The current index (starting from 0) of the last byte
398 // of function code's memory usage
399 // @mCurSGMemIdx: The current index (starting from tail) of the last byte
400 // of stub/GOT's memory usage
401 // @mCurGVMemIdx: The current index (starting from tail) of the last byte
402 // of global variable's memory usage
403 //
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700404 uintptr_t mCurFuncMemIdx;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700405 uintptr_t mCurSGMemIdx;
406 uintptr_t mCurGVMemIdx;
Zonr Chang932648d2010-10-13 22:23:56 +0800407 void *mpCodeMem;
408 void *mpGVMem;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700409
Zonr Chang932648d2010-10-13 22:23:56 +0800410 // GOT Base
411 uint8_t *mpGOTBase;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700412
413 typedef std::map<const llvm::Function*, pair<void* /* start address */,
414 void* /* end address */>
415 > FunctionMapTy;
416 FunctionMapTy mFunctionMap;
417
Zonr Chang932648d2010-10-13 22:23:56 +0800418 inline intptr_t getFreeCodeMemSize() const {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700419 return mCurSGMemIdx - mCurFuncMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700420 }
Zonr Chang932648d2010-10-13 22:23:56 +0800421 inline uint8_t *getCodeMemBase() const {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700422 return reinterpret_cast<uint8_t*>(mpCodeMem);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700423 }
424
Zonr Chang932648d2010-10-13 22:23:56 +0800425 uint8_t *allocateSGMemory(uintptr_t Size,
426 unsigned Alignment = 1 /* no alignment */) {
427 intptr_t FreeMemSize = getFreeCodeMemSize();
428 if ((FreeMemSize < 0) || (static_cast<uintptr_t>(FreeMemSize) < Size))
429 // The code size excesses our limit
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700430 return NULL;
431
Zonr Chang932648d2010-10-13 22:23:56 +0800432 if (Alignment == 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700433 Alignment = 1;
434
Zonr Chang932648d2010-10-13 22:23:56 +0800435 uint8_t *result = getCodeMemBase() + mCurSGMemIdx - Size;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700436 result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
437
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700438 mCurSGMemIdx = result - getCodeMemBase();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700439
440 return result;
441 }
442
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700443 inline uintptr_t getFreeGVMemSize() const {
444 return MaxGlobalVarSize - mCurGVMemIdx;
445 }
Zonr Chang932648d2010-10-13 22:23:56 +0800446 inline uint8_t *getGVMemBase() const {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700447 return reinterpret_cast<uint8_t*>(mpGVMem);
448 }
449
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700450 public:
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700451 CodeMemoryManager() : mpCodeMem(NULL), mpGVMem(NULL), mpGOTBase(NULL) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700452 reset();
453 std::string ErrMsg;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700454
Shih-wei Liaoc7c9cd52010-09-27 11:23:25 -0700455 mpCodeMem = ::mmap(NULL, MaxCodeSize, PROT_READ | PROT_EXEC,
Ying Wang78db12e2010-09-25 17:48:59 -0700456 MAP_PRIVATE | MAP_ANON, -1, 0);
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700457 if (mpCodeMem == MAP_FAILED)
Zonr Chang932648d2010-10-13 22:23:56 +0800458 llvm::report_fatal_error("Failed to allocate memory for emitting "
459 "function codes\n" + ErrMsg);
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700460
461 mpGVMem = ::mmap(mpCodeMem, MaxGlobalVarSize,
Shih-wei Liaoc7c9cd52010-09-27 11:23:25 -0700462 PROT_READ | PROT_WRITE,
Ying Wang78db12e2010-09-25 17:48:59 -0700463 MAP_PRIVATE | MAP_ANON, -1, 0);
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700464 if (mpGVMem == MAP_FAILED)
Zonr Chang932648d2010-10-13 22:23:56 +0800465 llvm::report_fatal_error("Failed to allocate memory for emitting "
466 "global variables\n" + ErrMsg);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700467
468 return;
469 }
470
Zonr Chang932648d2010-10-13 22:23:56 +0800471 // setMemoryWritable - When code generation is in progress, the code pages
472 // may need permissions changed.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700473 void setMemoryWritable() {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700474 ::mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700475 return;
476 }
477
Zonr Chang932648d2010-10-13 22:23:56 +0800478 // When code generation is done and we're ready to start execution, the
479 // code pages may need permissions changed.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700480 void setMemoryExecutable() {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700481 ::mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_EXEC);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700482 return;
483 }
484
Zonr Chang932648d2010-10-13 22:23:56 +0800485 // Setting this flag to true makes the memory manager garbage values over
486 // freed memory. This is useful for testing and debugging, and is to be
487 // turned on by default in debug mode.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700488 void setPoisonMemory(bool poison) {
Zonr Chang932648d2010-10-13 22:23:56 +0800489 // no effect
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700490 return;
491 }
492
Zonr Chang932648d2010-10-13 22:23:56 +0800493 // Global Offset Table Management
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700494
Zonr Chang932648d2010-10-13 22:23:56 +0800495 // If the current table requires a Global Offset Table, this method is
496 // invoked to allocate it. This method is required to set HasGOT to true.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700497 void AllocateGOT() {
498 assert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700499 mpGOTBase = allocateSGMemory(MaxGOTSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700500 HasGOT = true;
501 return;
502 }
503
Zonr Chang932648d2010-10-13 22:23:56 +0800504 // If this is managing a Global Offset Table, this method should return a
505 // pointer to its base.
506 uint8_t *getGOTBase() const {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700507 return mpGOTBase;
508 }
509
Zonr Chang932648d2010-10-13 22:23:56 +0800510 // Main Allocation Functions
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700511
Zonr Chang932648d2010-10-13 22:23:56 +0800512 // When we start JITing a function, the JIT calls this method to allocate a
513 // block of free RWX memory, which returns a pointer to it. If the JIT wants
514 // to request a block of memory of at least a certain size, it passes that
515 // value as ActualSize, and this method returns a block with at least that
516 // much space. If the JIT doesn't know ahead of time how much space it will
517 // need to emit the function, it passes 0 for the ActualSize. In either
518 // case, this method is required to pass back the size of the allocated
519 // block through ActualSize. The JIT will be careful to not write more than
520 // the returned ActualSize bytes of memory.
521 uint8_t *startFunctionBody(const llvm::Function *F, uintptr_t &ActualSize) {
522 intptr_t FreeMemSize = getFreeCodeMemSize();
523 if ((FreeMemSize < 0) ||
524 (static_cast<uintptr_t>(FreeMemSize) < ActualSize))
525 // The code size excesses our limit
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700526 return NULL;
527
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700528 ActualSize = getFreeCodeMemSize();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700529 return (getCodeMemBase() + mCurFuncMemIdx);
530 }
531
Zonr Chang932648d2010-10-13 22:23:56 +0800532 // This method is called by the JIT to allocate space for a function stub
533 // (used to handle limited branch displacements) while it is JIT compiling a
534 // function. For example, if foo calls bar, and if bar either needs to be
535 // lazily compiled or is a native function that exists too far away from the
536 // call site to work, this method will be used to make a thunk for it. The
537 // stub should be "close" to the current function body, but should not be
538 // included in the 'actualsize' returned by startFunctionBody.
539 uint8_t *allocateStub(const llvm::GlobalValue *F, unsigned StubSize,
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700540 unsigned Alignment) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700541 return allocateSGMemory(StubSize, Alignment);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700542 }
543
Zonr Chang932648d2010-10-13 22:23:56 +0800544 // This method is called when the JIT is done codegen'ing the specified
545 // function. At this point we know the size of the JIT compiled function.
546 // This passes in FunctionStart (which was returned by the startFunctionBody
547 // method) and FunctionEnd which is a pointer to the actual end of the
548 // function. This method should mark the space allocated and remember where
549 // it is in case the client wants to deallocate it.
550 void endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
551 uint8_t *FunctionEnd) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700552 assert(FunctionEnd > FunctionStart);
553 assert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
554 "Mismatched function start/end!");
555
Zonr Chang932648d2010-10-13 22:23:56 +0800556 // Advance the pointer
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700557 intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700558 assert(FunctionCodeSize <= getFreeCodeMemSize() &&
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700559 "Code size excess the limitation!");
560 mCurFuncMemIdx += FunctionCodeSize;
561
Zonr Chang932648d2010-10-13 22:23:56 +0800562 // Record there's a function in our memory start from @FunctionStart
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700563 assert(mFunctionMap.find(F) == mFunctionMap.end() &&
564 "Function already emitted!");
Zonr Chang932648d2010-10-13 22:23:56 +0800565 mFunctionMap.insert(
566 std::make_pair<const llvm::Function*, std::pair<void*, void*> >(
567 F, std::make_pair(FunctionStart, FunctionEnd)));
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700568
569 return;
570 }
571
Zonr Chang932648d2010-10-13 22:23:56 +0800572 // Allocate a (function code) memory block of the given size. This method
573 // cannot be called between calls to startFunctionBody and endFunctionBody.
574 uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
575 if (getFreeCodeMemSize() < Size)
576 // The code size excesses our limit
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700577 return NULL;
578
Zonr Chang932648d2010-10-13 22:23:56 +0800579 if (Alignment == 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700580 Alignment = 1;
581
Zonr Chang932648d2010-10-13 22:23:56 +0800582 uint8_t *result = getCodeMemBase() + mCurFuncMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700583 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
Zonr Chang932648d2010-10-13 22:23:56 +0800584 ~(intptr_t) (Alignment - 1));
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700585
586 mCurFuncMemIdx = (result + Size) - getCodeMemBase();
587
588 return result;
589 }
590
Zonr Chang932648d2010-10-13 22:23:56 +0800591 // Allocate memory for a global variable.
592 uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700593 if (getFreeGVMemSize() < Size) {
Zonr Chang932648d2010-10-13 22:23:56 +0800594 // The code size excesses our limit
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700595 LOGE("No Global Memory");
596 return NULL;
597 }
598
Zonr Chang932648d2010-10-13 22:23:56 +0800599 if (Alignment == 0)
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700600 Alignment = 1;
601
Zonr Chang932648d2010-10-13 22:23:56 +0800602 uint8_t *result = getGVMemBase() + mCurGVMemIdx;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700603 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
Zonr Chang932648d2010-10-13 22:23:56 +0800604 ~(intptr_t) (Alignment - 1));
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700605
606 mCurGVMemIdx = (result + Size) - getGVMemBase();
607
608 return result;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700609 }
610
Zonr Chang932648d2010-10-13 22:23:56 +0800611 // Free the specified function body. The argument must be the return value
612 // from a call to startFunctionBody() that hasn't been deallocated yet. This
613 // is never called when the JIT is currently emitting a function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700614 void deallocateFunctionBody(void *Body) {
Zonr Chang932648d2010-10-13 22:23:56 +0800615 // linear search
616 uint8_t *FunctionStart = NULL, *FunctionEnd = NULL;
617 for (FunctionMapTy::iterator I = mFunctionMap.begin(),
618 E = mFunctionMap.end();
619 I != E;
620 I++)
621 if (I->second.first == Body) {
622 FunctionStart = reinterpret_cast<uint8_t*>(I->second.first);
623 FunctionEnd = reinterpret_cast<uint8_t*>(I->second.second);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700624 break;
Zonr Chang932648d2010-10-13 22:23:56 +0800625 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700626
Zonr Chang932648d2010-10-13 22:23:56 +0800627 assert((FunctionStart == NULL) && "Memory is never allocated!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700628
Zonr Chang932648d2010-10-13 22:23:56 +0800629 // free the memory
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700630 intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
631
632 assert(SizeNeedMove >= 0 &&
633 "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
634 " be correctly calculated!");
635
Zonr Chang932648d2010-10-13 22:23:56 +0800636 if (SizeNeedMove > 0)
637 // there's data behind deallocating function
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700638 ::memmove(FunctionStart, FunctionEnd, SizeNeedMove);
639 mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
640
641 return;
642 }
643
Zonr Chang932648d2010-10-13 22:23:56 +0800644 // When we finished JITing the function, if exception handling is set, we
645 // emit the exception table.
646 uint8_t *startExceptionTable(const llvm::Function *F,
647 uintptr_t &ActualSize) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700648 assert(false && "Exception is not allowed in our language specification");
649 return NULL;
650 }
651
Zonr Chang932648d2010-10-13 22:23:56 +0800652 // This method is called when the JIT is done emitting the exception table.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700653 void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
Zonr Chang932648d2010-10-13 22:23:56 +0800654 uint8_t *TableEnd, uint8_t *FrameRegister) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700655 assert(false && "Exception is not allowed in our language specification");
656 return;
657 }
658
Zonr Chang932648d2010-10-13 22:23:56 +0800659 // Free the specified exception table's memory. The argument must be the
660 // return value from a call to startExceptionTable() that hasn't been
661 // deallocated yet. This is never called when the JIT is currently emitting
662 // an exception table.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700663 void deallocateExceptionTable(void *ET) {
664 assert(false && "Exception is not allowed in our language specification");
665 return;
666 }
667
Zonr Chang932648d2010-10-13 22:23:56 +0800668 // Below are the methods we create
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700669 void reset() {
670 mpGOTBase = NULL;
671 HasGOT = false;
672
673 mCurFuncMemIdx = 0;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700674 mCurSGMemIdx = MaxCodeSize - 1;
675 mCurGVMemIdx = 0;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700676
677 mFunctionMap.clear();
678
679 return;
680 }
681
682 ~CodeMemoryManager() {
Zonr Chang932648d2010-10-13 22:23:56 +0800683 if (mpCodeMem != NULL)
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700684 ::munmap(mpCodeMem, MaxCodeSize);
Zonr Chang932648d2010-10-13 22:23:56 +0800685 if (mpGVMem != NULL)
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700686 ::munmap(mpGVMem, MaxGlobalVarSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700687 return;
688 }
Zonr Chang932648d2010-10-13 22:23:56 +0800689 };
690 // End of class CodeMemoryManager
691 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700692
Zonr Chang932648d2010-10-13 22:23:56 +0800693 // The memory manager for code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700694 llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
Zonr Chang932648d2010-10-13 22:23:56 +0800695 CodeMemoryManager *createCodeMemoryManager() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700696 mCodeMemMgr.reset(new CodeMemoryManager());
697 return mCodeMemMgr.get();
698 }
699
Zonr Chang932648d2010-10-13 22:23:56 +0800700 //////////////////////////////////////////////////////////////////////////////
701 // Code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700702 class CodeEmitter : public llvm::JITCodeEmitter {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700703 public:
704 typedef llvm::DenseMap<const llvm::GlobalValue*, void*> GlobalAddressMapTy;
705 typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
706
707 private:
Zonr Chang932648d2010-10-13 22:23:56 +0800708 CodeMemoryManager *mpMemMgr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700709
Zonr Chang932648d2010-10-13 22:23:56 +0800710 // The JITInfo for the target we are compiling to
711 const llvm::Target *mpTarget;
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700712
Zonr Chang932648d2010-10-13 22:23:56 +0800713 llvm::TargetJITInfo *mpTJI;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700714
Zonr Chang932648d2010-10-13 22:23:56 +0800715 const llvm::TargetData *mpTD;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700716
717 class EmittedFunctionCode {
718 public:
Zonr Chang932648d2010-10-13 22:23:56 +0800719 // Beginning of the function's allocation.
720 void *FunctionBody;
721
722 // The address the function's code actually starts at.
723 void *Code;
724
725 // The size of the function code
726 int Size;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700727
728 EmittedFunctionCode() : FunctionBody(NULL), Code(NULL) { return; }
729 };
Zonr Chang932648d2010-10-13 22:23:56 +0800730 EmittedFunctionCode *mpCurEmitFunction;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700731
Zonr Chang932648d2010-10-13 22:23:56 +0800732 typedef std::map<const std::string,
733 EmittedFunctionCode*> EmittedFunctionsMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700734 EmittedFunctionsMapTy mEmittedFunctions;
735
Zonr Chang932648d2010-10-13 22:23:56 +0800736 // This vector is a mapping from MBB ID's to their address. It is filled in
737 // by the StartMachineBasicBlock callback and queried by the
738 // getMachineBasicBlockAddress callback.
739 std::vector<uintptr_t> mMBBLocations;
740
741 // The constant pool for the current function.
742 llvm::MachineConstantPool *mpConstantPool;
743
744 // A pointer to the first entry in the constant pool.
745 void *mpConstantPoolBase;
746
747 // Addresses of individual constant pool entries.
748 llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
749
750 // The jump tables for the current function.
751 llvm::MachineJumpTableInfo *mpJumpTable;
752
753 // A pointer to the first entry in the jump table.
754 void *mpJumpTableBase;
755
756 // When outputting a function stub in the context of some other function, we
757 // save BufferBegin/BufferEnd/CurBufferPtr here.
758 uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
759
760 // These are the relocations that the function needs, as emitted.
761 std::vector<llvm::MachineRelocation> mRelocations;
762
763 // This vector is a mapping from Label ID's to their address.
764 llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
765
766 // Machine module info for exception informations
767 llvm::MachineModuleInfo *mpMMI;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700768
769 GlobalAddressMapTy mGlobalAddressMap;
770
Zonr Chang932648d2010-10-13 22:23:56 +0800771 // Replace an existing mapping for GV with a new address. This updates both
772 // maps as required. If Addr is null, the entry for the global is removed
773 // from the mappings.
774 void *UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
775 if (Addr == NULL) {
776 // Removing mapping
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700777 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
778 void *OldVal;
779
Zonr Chang932648d2010-10-13 22:23:56 +0800780 if (I == mGlobalAddressMap.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700781 OldVal = NULL;
Zonr Chang932648d2010-10-13 22:23:56 +0800782 } else {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700783 OldVal = I->second;
784 mGlobalAddressMap.erase(I);
785 }
786
787 return OldVal;
788 }
789
Zonr Chang932648d2010-10-13 22:23:56 +0800790 void *&CurVal = mGlobalAddressMap[GV];
791 void *OldVal = CurVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700792
793 CurVal = Addr;
794
795 return OldVal;
796 }
797
Zonr Chang932648d2010-10-13 22:23:56 +0800798 // Tell the execution engine that the specified global is at the specified
799 // location. This is used internally as functions are JIT'd and as global
800 // variables are laid out in memory.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700801 void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
Zonr Chang932648d2010-10-13 22:23:56 +0800802 void *&CurVal = mGlobalAddressMap[GV];
803 assert((CurVal == 0 || Addr == 0) &&
804 "GlobalMapping already established!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700805 CurVal = Addr;
806 return;
807 }
808
Zonr Chang932648d2010-10-13 22:23:56 +0800809 // This returns the address of the specified global value if it is has
810 // already been codegen'd, otherwise it returns null.
811 void *GetPointerToGlobalIfAvailable(const llvm::GlobalValue *GV) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700812 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700813 return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
814 }
815
Zonr Chang932648d2010-10-13 22:23:56 +0800816 unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool *MCP) {
817 const std::vector<llvm::MachineConstantPoolEntry> &Constants =
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700818 MCP->getConstants();
819
Zonr Chang932648d2010-10-13 22:23:56 +0800820 if (Constants.empty())
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700821 return 0;
822
823 unsigned int Size = 0;
Zonr Chang932648d2010-10-13 22:23:56 +0800824 for (int i = 0, e = Constants.size(); i != e; i++) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700825 llvm::MachineConstantPoolEntry CPE = Constants[i];
826 unsigned int AlignMask = CPE.getAlignment() - 1;
827 Size = (Size + AlignMask) & ~AlignMask;
Zonr Chang932648d2010-10-13 22:23:56 +0800828 const llvm::Type *Ty = CPE.getType();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700829 Size += mpTD->getTypeAllocSize(Ty);
830 }
831
832 return Size;
833 }
834
Zonr Chang932648d2010-10-13 22:23:56 +0800835 // This function converts a Constant* into a GenericValue. The interesting
836 // part is if C is a ConstantExpr.
837 void GetConstantValue(const llvm::Constant *C, llvm::GenericValue &Result) {
838 if (C->getValueID() == llvm::Value::UndefValueVal)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700839 return;
Zonr Chang932648d2010-10-13 22:23:56 +0800840 else if (C->getValueID() == llvm::Value::ConstantExprVal) {
841 const llvm::ConstantExpr *CE = (llvm::ConstantExpr*) C;
842 const llvm::Constant *Op0 = CE->getOperand(0);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700843
Zonr Chang932648d2010-10-13 22:23:56 +0800844 switch (CE->getOpcode()) {
845 case llvm::Instruction::GetElementPtr: {
846 // Compute the index
847 llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
848 CE->op_end());
849 uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(),
850 &Indices[0],
851 Indices.size());
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700852
Zonr Chang932648d2010-10-13 22:23:56 +0800853 GetConstantValue(Op0, Result);
854 Result.PointerVal =
855 static_cast<uint8_t*>(Result.PointerVal) + Offset;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700856
Zonr Chang932648d2010-10-13 22:23:56 +0800857 return;
858 }
859 case llvm::Instruction::Trunc: {
860 uint32_t BitWidth =
861 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
862
863 GetConstantValue(Op0, Result);
864 Result.IntVal = Result.IntVal.trunc(BitWidth);
865
866 return;
867 }
868 case llvm::Instruction::ZExt: {
869 uint32_t BitWidth =
870 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
871
872 GetConstantValue(Op0, Result);
873 Result.IntVal = Result.IntVal.zext(BitWidth);
874
875 return;
876 }
877 case llvm::Instruction::SExt: {
878 uint32_t BitWidth =
879 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
880
881 GetConstantValue(Op0, Result);
882 Result.IntVal = Result.IntVal.sext(BitWidth);
883
884 return;
885 }
886 case llvm::Instruction::FPTrunc: {
887 // FIXME: long double
888 GetConstantValue(Op0, Result);
889 Result.FloatVal = static_cast<float>(Result.DoubleVal);
890 return;
891 }
892 case llvm::Instruction::FPExt: {
893 // FIXME: long double
894 GetConstantValue(Op0, Result);
895 Result.DoubleVal = static_cast<double>(Result.FloatVal);
896 return;
897 }
898 case llvm::Instruction::UIToFP: {
899 GetConstantValue(Op0, Result);
900 if (CE->getType()->isFloatTy())
901 Result.FloatVal =
902 static_cast<float>(Result.IntVal.roundToDouble());
903 else if (CE->getType()->isDoubleTy())
904 Result.DoubleVal = Result.IntVal.roundToDouble();
905 else if (CE->getType()->isX86_FP80Ty()) {
906 const uint64_t zero[] = { 0, 0 };
907 llvm::APFloat apf(llvm::APInt(80, 2, zero));
908 apf.convertFromAPInt(Result.IntVal,
909 false,
910 llvm::APFloat::rmNearestTiesToEven);
911 Result.IntVal = apf.bitcastToAPInt();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700912 }
Zonr Chang932648d2010-10-13 22:23:56 +0800913 return;
914 }
915 case llvm::Instruction::SIToFP: {
916 GetConstantValue(Op0, Result);
917 if (CE->getType()->isFloatTy())
918 Result.FloatVal =
919 static_cast<float>(Result.IntVal.signedRoundToDouble());
920 else if (CE->getType()->isDoubleTy())
921 Result.DoubleVal = Result.IntVal.signedRoundToDouble();
922 else if (CE->getType()->isX86_FP80Ty()) {
923 const uint64_t zero[] = { 0, 0 };
924 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
925 apf.convertFromAPInt(Result.IntVal,
926 true,
927 llvm::APFloat::rmNearestTiesToEven);
928 Result.IntVal = apf.bitcastToAPInt();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700929 }
Zonr Chang932648d2010-10-13 22:23:56 +0800930 return;
931 }
932 // double->APInt conversion handles sign
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700933 case llvm::Instruction::FPToUI:
Zonr Chang932648d2010-10-13 22:23:56 +0800934 case llvm::Instruction::FPToSI: {
935 uint32_t BitWidth =
936 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700937
Zonr Chang932648d2010-10-13 22:23:56 +0800938 GetConstantValue(Op0, Result);
939 if (Op0->getType()->isFloatTy())
940 Result.IntVal =
941 llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
942 else if (Op0->getType()->isDoubleTy())
943 Result.IntVal =
944 llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal,
945 BitWidth);
946 else if (Op0->getType()->isX86_FP80Ty()) {
947 llvm::APFloat apf = llvm::APFloat(Result.IntVal);
948 uint64_t V;
949 bool Ignored;
950 apf.convertToInteger(&V,
951 BitWidth,
952 CE->getOpcode() == llvm::Instruction::FPToSI,
953 llvm::APFloat::rmTowardZero,
954 &Ignored);
955 Result.IntVal = V; // endian?
956 }
957 return;
958 }
959 case llvm::Instruction::PtrToInt: {
960 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
961
962 GetConstantValue(Op0, Result);
963 Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
964 (Result.PointerVal));
965
966 return;
967 }
968 case llvm::Instruction::IntToPtr: {
969 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
970
971 GetConstantValue(Op0, Result);
972 if (PtrWidth != Result.IntVal.getBitWidth())
973 Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
974 assert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
975
976 Result.PointerVal =
977 llvm::PointerTy(
978 static_cast<uintptr_t>(Result.IntVal.getZExtValue()));
979
980 return;
981 }
982 case llvm::Instruction::BitCast: {
983 GetConstantValue(Op0, Result);
984 const llvm::Type *DestTy = CE->getType();
985
986 switch (Op0->getType()->getTypeID()) {
987 case llvm::Type::IntegerTyID: {
988 assert(DestTy->isFloatingPointTy() && "invalid bitcast");
989 if (DestTy->isFloatTy())
990 Result.FloatVal = Result.IntVal.bitsToFloat();
991 else if (DestTy->isDoubleTy())
992 Result.DoubleVal = Result.IntVal.bitsToDouble();
993 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700994 }
Zonr Chang932648d2010-10-13 22:23:56 +0800995 case llvm::Type::FloatTyID: {
996 assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
997 Result.IntVal.floatToBits(Result.FloatVal);
998 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700999 }
Zonr Chang932648d2010-10-13 22:23:56 +08001000 case llvm::Type::DoubleTyID: {
1001 assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
1002 Result.IntVal.doubleToBits(Result.DoubleVal);
1003 break;
1004 }
1005 case llvm::Type::PointerTyID: {
1006 assert(DestTy->isPointerTy() && "Invalid bitcast");
1007 break; // getConstantValue(Op0) above already converted it
1008 }
1009 default: {
1010 llvm_unreachable("Invalid bitcast operand");
1011 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001012 }
Zonr Chang932648d2010-10-13 22:23:56 +08001013 return;
1014 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001015 case llvm::Instruction::Add:
1016 case llvm::Instruction::FAdd:
1017 case llvm::Instruction::Sub:
1018 case llvm::Instruction::FSub:
1019 case llvm::Instruction::Mul:
1020 case llvm::Instruction::FMul:
1021 case llvm::Instruction::UDiv:
1022 case llvm::Instruction::SDiv:
1023 case llvm::Instruction::URem:
1024 case llvm::Instruction::SRem:
1025 case llvm::Instruction::And:
1026 case llvm::Instruction::Or:
Zonr Chang932648d2010-10-13 22:23:56 +08001027 case llvm::Instruction::Xor: {
1028 llvm::GenericValue LHS, RHS;
1029 GetConstantValue(Op0, LHS);
1030 GetConstantValue(CE->getOperand(1), RHS);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001031
Zonr Chang932648d2010-10-13 22:23:56 +08001032 switch (Op0->getType()->getTypeID()) {
1033 case llvm::Type::IntegerTyID: {
1034 switch (CE->getOpcode()) {
1035 case llvm::Instruction::Add: {
1036 Result.IntVal = LHS.IntVal + RHS.IntVal;
1037 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001038 }
Zonr Chang932648d2010-10-13 22:23:56 +08001039 case llvm::Instruction::Sub: {
1040 Result.IntVal = LHS.IntVal - RHS.IntVal;
1041 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001042 }
Zonr Chang932648d2010-10-13 22:23:56 +08001043 case llvm::Instruction::Mul: {
1044 Result.IntVal = LHS.IntVal * RHS.IntVal;
1045 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001046 }
Zonr Chang932648d2010-10-13 22:23:56 +08001047 case llvm::Instruction::UDiv: {
1048 Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
1049 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001050 }
Zonr Chang932648d2010-10-13 22:23:56 +08001051 case llvm::Instruction::SDiv: {
1052 Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
1053 break;
1054 }
1055 case llvm::Instruction::URem: {
1056 Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
1057 break;
1058 }
1059 case llvm::Instruction::SRem: {
1060 Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
1061 break;
1062 }
1063 case llvm::Instruction::And: {
1064 Result.IntVal = LHS.IntVal & RHS.IntVal;
1065 break;
1066 }
1067 case llvm::Instruction::Or: {
1068 Result.IntVal = LHS.IntVal | RHS.IntVal;
1069 break;
1070 }
1071 case llvm::Instruction::Xor: {
1072 Result.IntVal = LHS.IntVal ^ RHS.IntVal;
1073 break;
1074 }
1075 default: {
1076 llvm_unreachable("Invalid integer opcode");
1077 }
1078 }
1079 break;
1080 }
1081 case llvm::Type::FloatTyID: {
1082 switch (CE->getOpcode()) {
1083 case llvm::Instruction::FAdd: {
1084 Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
1085 break;
1086 }
1087 case llvm::Instruction::FSub: {
1088 Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
1089 break;
1090 }
1091 case llvm::Instruction::FMul: {
1092 Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
1093 break;
1094 }
1095 case llvm::Instruction::FDiv: {
1096 Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
1097 break;
1098 }
1099 case llvm::Instruction::FRem: {
1100 Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
1101 break;
1102 }
1103 default: {
1104 llvm_unreachable("Invalid float opcode");
1105 }
1106 }
1107 break;
1108 }
1109 case llvm::Type::DoubleTyID: {
1110 switch (CE->getOpcode()) {
1111 case llvm::Instruction::FAdd: {
1112 Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
1113 break;
1114 }
1115 case llvm::Instruction::FSub: {
1116 Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
1117 break;
1118 }
1119 case llvm::Instruction::FMul: {
1120 Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
1121 break;
1122 }
1123 case llvm::Instruction::FDiv: {
1124 Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
1125 break;
1126 }
1127 case llvm::Instruction::FRem: {
1128 Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
1129 break;
1130 }
1131 default: {
1132 llvm_unreachable("Invalid double opcode");
1133 }
1134 }
1135 break;
1136 }
1137 case llvm::Type::X86_FP80TyID:
1138 case llvm::Type::PPC_FP128TyID:
1139 case llvm::Type::FP128TyID: {
1140 llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
1141 switch (CE->getOpcode()) {
1142 case llvm::Instruction::FAdd: {
1143 apfLHS.add(llvm::APFloat(RHS.IntVal),
1144 llvm::APFloat::rmNearestTiesToEven);
1145 break;
1146 }
1147 case llvm::Instruction::FSub: {
1148 apfLHS.subtract(llvm::APFloat(RHS.IntVal),
1149 llvm::APFloat::rmNearestTiesToEven);
1150 break;
1151 }
1152 case llvm::Instruction::FMul: {
1153 apfLHS.multiply(llvm::APFloat(RHS.IntVal),
1154 llvm::APFloat::rmNearestTiesToEven);
1155 break;
1156 }
1157 case llvm::Instruction::FDiv: {
1158 apfLHS.divide(llvm::APFloat(RHS.IntVal),
1159 llvm::APFloat::rmNearestTiesToEven);
1160 break;
1161 }
1162 case llvm::Instruction::FRem: {
1163 apfLHS.mod(llvm::APFloat(RHS.IntVal),
1164 llvm::APFloat::rmNearestTiesToEven);
1165 break;
1166 }
1167 default: {
1168 llvm_unreachable("Invalid long double opcode");
1169 }
1170 }
1171 Result.IntVal = apfLHS.bitcastToAPInt();
1172 break;
1173 }
1174 default: {
1175 llvm_unreachable("Bad add type!");
1176 }
1177 } // End switch (Op0->getType()->getTypeID())
1178 return;
1179 }
1180 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001181 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001182 }
1183 } // End switch (CE->getOpcode())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001184
1185 std::string msg;
1186 llvm::raw_string_ostream Msg(msg);
1187 Msg << "ConstantExpr not handled: " << *CE;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001188 llvm::report_fatal_error(Msg.str());
Zonr Chang932648d2010-10-13 22:23:56 +08001189 } // C->getValueID() == llvm::Value::ConstantExprVal
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001190
1191 switch (C->getType()->getTypeID()) {
Zonr Chang932648d2010-10-13 22:23:56 +08001192 case llvm::Type::FloatTyID: {
1193 Result.FloatVal =
1194 llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToFloat();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001195 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001196 }
1197 case llvm::Type::DoubleTyID: {
1198 Result.DoubleVal =
1199 llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToDouble();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001200 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001201 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001202 case llvm::Type::X86_FP80TyID:
1203 case llvm::Type::FP128TyID:
Zonr Chang932648d2010-10-13 22:23:56 +08001204 case llvm::Type::PPC_FP128TyID: {
1205 Result.IntVal =
1206 llvm::cast<llvm::ConstantFP>(C)->getValueAPF().bitcastToAPInt();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001207 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001208 }
1209 case llvm::Type::IntegerTyID: {
1210 Result.IntVal =
1211 llvm::cast<llvm::ConstantInt>(C)->getValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001212 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001213 }
1214 case llvm::Type::PointerTyID: {
1215 switch (C->getValueID()) {
1216 case llvm::Value::ConstantPointerNullVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001217 Result.PointerVal = NULL;
1218 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001219 }
1220 case llvm::Value::FunctionVal: {
1221 const llvm::Function *F = static_cast<const llvm::Function*>(C);
1222 Result.PointerVal =
1223 GetPointerToFunctionOrStub(const_cast<llvm::Function*>(F));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001224 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001225 }
1226 case llvm::Value::GlobalVariableVal: {
1227 const llvm::GlobalVariable *GV =
1228 static_cast<const llvm::GlobalVariable*>(C);
1229 Result.PointerVal =
1230 GetOrEmitGlobalVariable(const_cast<llvm::GlobalVariable*>(GV));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001231 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001232 }
1233 case llvm::Value::BlockAddressVal: {
1234 assert(false && "JIT does not support address-of-label yet!");
1235 }
1236 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001237 llvm_unreachable("Unknown constant pointer type!");
Zonr Chang932648d2010-10-13 22:23:56 +08001238 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001239 }
1240 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001241 }
1242 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001243 std::string msg;
1244 llvm::raw_string_ostream Msg(msg);
1245 Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001246 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001247 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001248 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001249 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001250 return;
1251 }
1252
Zonr Chang932648d2010-10-13 22:23:56 +08001253 // Stores the data in @Val of type @Ty at address @Addr.
1254 void StoreValueToMemory(const llvm::GenericValue &Val, void *Addr,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001255 const llvm::Type *Ty) {
1256 const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
1257
Zonr Chang932648d2010-10-13 22:23:56 +08001258 switch (Ty->getTypeID()) {
1259 case llvm::Type::IntegerTyID: {
1260 const llvm::APInt &IntVal = Val.IntVal;
1261 assert(((IntVal.getBitWidth() + 7) / 8 >= StoreBytes) &&
1262 "Integer too small!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001263
Zonr Chang932648d2010-10-13 22:23:56 +08001264 const uint8_t *Src =
1265 reinterpret_cast<const uint8_t*>(IntVal.getRawData());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001266
Zonr Chang932648d2010-10-13 22:23:56 +08001267 if (llvm::sys::isLittleEndianHost()) {
1268 // Little-endian host - the source is ordered from LSB to MSB.
1269 // Order the destination from LSB to MSB: Do a straight copy.
1270 memcpy(Addr, Src, StoreBytes);
1271 } else {
1272 // Big-endian host - the source is an array of 64 bit words
1273 // ordered from LSW to MSW.
1274 //
1275 // Each word is ordered from MSB to LSB.
1276 //
1277 // Order the destination from MSB to LSB:
1278 // Reverse the word order, but not the bytes in a word.
1279 unsigned int i = StoreBytes;
1280 while (i > sizeof(uint64_t)) {
1281 i -= sizeof(uint64_t);
1282 ::memcpy(reinterpret_cast<uint8_t*>(Addr) + i,
1283 Src,
1284 sizeof(uint64_t));
1285 Src += sizeof(uint64_t);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001286 }
Zonr Chang932648d2010-10-13 22:23:56 +08001287 ::memcpy(Addr, Src + sizeof(uint64_t) - i, i);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001288 }
1289 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001290 }
1291 case llvm::Type::FloatTyID: {
1292 *reinterpret_cast<float*>(Addr) = Val.FloatVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001293 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001294 }
1295 case llvm::Type::DoubleTyID: {
1296 *reinterpret_cast<double*>(Addr) = Val.DoubleVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001297 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001298 }
1299 case llvm::Type::X86_FP80TyID: {
1300 memcpy(Addr, Val.IntVal.getRawData(), 10);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001301 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001302 }
1303 case llvm::Type::PointerTyID: {
1304 // Ensure 64 bit target pointers are fully initialized on 32 bit
1305 // hosts.
1306 if (StoreBytes != sizeof(llvm::PointerTy))
1307 memset(Addr, 0, StoreBytes);
1308 *((llvm::PointerTy*) Addr) = Val.PointerVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001309 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001310 }
1311 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001312 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001313 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001314 }
1315
Zonr Chang932648d2010-10-13 22:23:56 +08001316 if (llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
1317 std::reverse(reinterpret_cast<uint8_t*>(Addr),
1318 reinterpret_cast<uint8_t*>(Addr) + StoreBytes);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001319
1320 return;
1321 }
1322
Zonr Chang932648d2010-10-13 22:23:56 +08001323 // Recursive function to apply a @Constant value into the specified memory
1324 // location @Addr.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001325 void InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
Zonr Chang932648d2010-10-13 22:23:56 +08001326 switch (C->getValueID()) {
1327 case llvm::Value::UndefValueVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001328 // Nothing to do
1329 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001330 }
1331 case llvm::Value::ConstantVectorVal: {
1332 // dynamic cast may hurt performance
1333 const llvm::ConstantVector *CP = (llvm::ConstantVector*) C;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001334
Zonr Chang932648d2010-10-13 22:23:56 +08001335 unsigned int ElementSize = mpTD->getTypeAllocSize
1336 (CP->getType()->getElementType());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001337
Zonr Chang932648d2010-10-13 22:23:56 +08001338 for (int i = 0, e = CP->getNumOperands(); i != e;i++)
1339 InitializeConstantToMemory(
1340 CP->getOperand(i),
1341 reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001342 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001343 }
1344 case llvm::Value::ConstantAggregateZeroVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001345 memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
1346 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001347 }
1348 case llvm::Value::ConstantArrayVal: {
1349 const llvm::ConstantArray *CPA = (llvm::ConstantArray*) C;
1350 unsigned int ElementSize = mpTD->getTypeAllocSize
1351 (CPA->getType()->getElementType());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001352
Zonr Chang932648d2010-10-13 22:23:56 +08001353 for (int i = 0, e = CPA->getNumOperands(); i != e; i++)
1354 InitializeConstantToMemory(
1355 CPA->getOperand(i),
1356 reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
1357 break;
1358 }
1359 case llvm::Value::ConstantStructVal: {
1360 const llvm::ConstantStruct *CPS =
1361 static_cast<const llvm::ConstantStruct*>(C);
1362 const llvm::StructLayout *SL = mpTD->getStructLayout
1363 (llvm::cast<llvm::StructType>(CPS->getType()));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001364
Zonr Chang932648d2010-10-13 22:23:56 +08001365 for (int i = 0, e = CPS->getNumOperands(); i != e; i++)
1366 InitializeConstantToMemory(
1367 CPS->getOperand(i),
1368 reinterpret_cast<uint8_t*>(Addr) + SL->getElementOffset(i));
1369 break;
1370 }
1371 default: {
1372 if (C->getType()->isFirstClassType()) {
1373 llvm::GenericValue Val;
1374 GetConstantValue(C, Val);
1375 StoreValueToMemory(Val, Addr, C->getType());
1376 } else {
1377 llvm_unreachable("Unknown constant type to initialize memory "
1378 "with!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001379 }
1380 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001381 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001382 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001383 return;
1384 }
1385
1386 void emitConstantPool(llvm::MachineConstantPool *MCP) {
Zonr Chang932648d2010-10-13 22:23:56 +08001387 if (mpTJI->hasCustomConstantPool())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001388 return;
1389
Zonr Chang932648d2010-10-13 22:23:56 +08001390 // Constant pool address resolution is handled by the target itself in ARM
1391 // (TargetJITInfo::hasCustomConstantPool() returns true).
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001392#if !defined(PROVIDE_ARM_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +08001393 const std::vector<llvm::MachineConstantPoolEntry> &Constants =
1394 MCP->getConstants();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001395
Zonr Chang932648d2010-10-13 22:23:56 +08001396 if (Constants.empty())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001397 return;
1398
1399 unsigned Size = GetConstantPoolSizeInBytes(MCP);
1400 unsigned Align = MCP->getConstantPoolAlignment();
1401
1402 mpConstantPoolBase = allocateSpace(Size, Align);
1403 mpConstantPool = MCP;
1404
Zonr Chang932648d2010-10-13 22:23:56 +08001405 if (mpConstantPoolBase == NULL)
1406 return; // out of memory
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001407
1408 unsigned Offset = 0;
Zonr Chang932648d2010-10-13 22:23:56 +08001409 for (int i = 0, e = Constants.size(); i != e; i++) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001410 llvm::MachineConstantPoolEntry CPE = Constants[i];
1411 unsigned AlignMask = CPE.getAlignment() - 1;
1412 Offset = (Offset + AlignMask) & ~AlignMask;
1413
1414 uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
1415 mConstPoolAddresses.push_back(CAddr);
1416
Zonr Chang932648d2010-10-13 22:23:56 +08001417 if (CPE.isMachineConstantPoolEntry())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001418 llvm::report_fatal_error
Zonr Chang932648d2010-10-13 22:23:56 +08001419 ("Initialize memory with machine specific constant pool"
1420 " entry has not been implemented!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001421
1422 InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
1423
1424 const llvm::Type *Ty = CPE.Val.ConstVal->getType();
1425 Offset += mpTD->getTypeAllocSize(Ty);
1426 }
1427#endif
1428 return;
1429 }
1430
1431 void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
Zonr Chang932648d2010-10-13 22:23:56 +08001432 if (mpTJI->hasCustomJumpTables())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001433 return;
1434
Zonr Chang932648d2010-10-13 22:23:56 +08001435 const std::vector<llvm::MachineJumpTableEntry> &JT =
1436 MJTI->getJumpTables();
1437 if (JT.empty())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001438 return;
1439
1440 unsigned NumEntries = 0;
Zonr Chang932648d2010-10-13 22:23:56 +08001441 for (int i = 0, e = JT.size(); i != e; i++)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001442 NumEntries += JT[i].MBBs.size();
1443
1444 unsigned EntrySize = MJTI->getEntrySize(*mpTD);
1445
Zonr Chang932648d2010-10-13 22:23:56 +08001446 mpJumpTable = MJTI;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001447 mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
Zonr Chang932648d2010-10-13 22:23:56 +08001448 MJTI->getEntryAlignment(*mpTD));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001449
1450 return;
1451 }
1452
1453 void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
Zonr Chang932648d2010-10-13 22:23:56 +08001454 if (mpTJI->hasCustomJumpTables())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001455 return;
1456
Zonr Chang932648d2010-10-13 22:23:56 +08001457 const std::vector<llvm::MachineJumpTableEntry> &JT =
1458 MJTI->getJumpTables();
1459 if (JT.empty() || mpJumpTableBase == 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001460 return;
1461
Zonr Chang932648d2010-10-13 22:23:56 +08001462 assert(llvm::TargetMachine::getRelocationModel() == llvm::Reloc::Static &&
1463 (MJTI->getEntrySize(*mpTD) == sizeof(mpTD /* a pointer type */)) &&
1464 "Cross JIT'ing?");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001465
Zonr Chang932648d2010-10-13 22:23:56 +08001466 // For each jump table, map each target in the jump table to the
1467 // address of an emitted MachineBasicBlock.
1468 intptr_t *SlotPtr = reinterpret_cast<intptr_t*>(mpJumpTableBase);
1469 for (int i = 0, ie = JT.size(); i != ie; i++) {
1470 const std::vector<llvm::MachineBasicBlock*> &MBBs = JT[i].MBBs;
1471 // Store the address of the basic block for this jump table slot in the
1472 // memory we allocated for the jump table in 'initJumpTableInfo'
1473 for (int j = 0, je = MBBs.size(); j != je; j++)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001474 *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
1475 }
1476 }
1477
Zonr Chang932648d2010-10-13 22:23:56 +08001478 void *GetPointerToGlobal(llvm::GlobalValue *V, void *Reference,
1479 bool MayNeedFarStub) {
1480 switch (V->getValueID()) {
1481 case llvm::Value::FunctionVal: {
1482 llvm::Function *F = (llvm::Function*) V;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001483
Zonr Chang932648d2010-10-13 22:23:56 +08001484 // If we have code, go ahead and return that.
1485 if (void *ResultPtr = GetPointerToGlobalIfAvailable(F))
1486 return ResultPtr;
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001487
Zonr Chang932648d2010-10-13 22:23:56 +08001488 if (void *FnStub = GetLazyFunctionStubIfAvailable(F))
1489 // Return the function stub if it's already created.
1490 // We do this first so that:
1491 // we're returning the same address for the function as any
1492 // previous call.
1493 //
1494 // TODO(llvm.org): Yes, this is wrong. The lazy stub isn't
1495 // guaranteed to be close enough to call.
1496 return FnStub;
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001497
Zonr Chang932648d2010-10-13 22:23:56 +08001498 // If we know the target can handle arbitrary-distance calls, try to
1499 // return a direct pointer.
1500 if (!MayNeedFarStub) {
1501 //
1502 // x86_64 architecture may encounter the bug:
1503 // http://llvm.org/bugs/show_bug.cgi?id=5201
1504 // which generate instruction "call" instead of "callq".
1505 //
1506 // And once the real address of stub is greater than 64-bit
1507 // long, the replacement will truncate to 32-bit resulting a
1508 // serious problem.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001509#if !defined(__x86_64__)
Zonr Chang932648d2010-10-13 22:23:56 +08001510 // If this is an external function pointer, we can force the JIT
1511 // to 'compile' it, which really just adds it to the map.
1512 if (F->isDeclaration() || F->hasAvailableExternallyLinkage())
1513 return GetPointerToFunction(F, /* AbortOnFailure = */true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001514#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001515 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001516
Zonr Chang932648d2010-10-13 22:23:56 +08001517 // Otherwise, we may need a to emit a stub, and, conservatively, we
1518 // always do so.
1519 return GetLazyFunctionStub(F);
1520 break;
1521 }
1522 case llvm::Value::GlobalVariableVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001523 return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
1524 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001525 }
1526 case llvm::Value::GlobalAliasVal: {
1527 llvm::GlobalAlias *GA = (llvm::GlobalAlias*) V;
1528 const llvm::GlobalValue *GV = GA->resolveAliasedGlobal(false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001529
Zonr Chang932648d2010-10-13 22:23:56 +08001530 switch (GV->getValueID()) {
1531 case llvm::Value::FunctionVal: {
1532 // FIXME: is there's any possibility that the function is not
1533 // code-gen'd?
1534 return GetPointerToFunction(
1535 static_cast<const llvm::Function*>(GV),
1536 /* AbortOnFailure = */true);
1537 break;
1538 }
1539 case llvm::Value::GlobalVariableVal: {
1540 if (void *P = mGlobalAddressMap[GV])
1541 return P;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001542
Zonr Chang932648d2010-10-13 22:23:56 +08001543 llvm::GlobalVariable *GVar = (llvm::GlobalVariable*) GV;
1544 EmitGlobalVariable(GVar);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001545
Zonr Chang932648d2010-10-13 22:23:56 +08001546 return mGlobalAddressMap[GV];
1547 break;
1548 }
1549 case llvm::Value::GlobalAliasVal: {
1550 assert(false && "Alias should be resolved ultimately!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001551 }
1552 }
1553 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001554 }
1555 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001556 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001557 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001558 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001559 llvm_unreachable("Unknown type of global value!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001560 }
1561
Zonr Chang932648d2010-10-13 22:23:56 +08001562 // If the specified function has been code-gen'd, return a pointer to the
1563 // function. If not, compile it, or use a stub to implement lazy compilation
1564 // if available.
1565 void *GetPointerToFunctionOrStub(llvm::Function *F) {
1566 // If we have already code generated the function, just return the
1567 // address.
1568 if (void *Addr = GetPointerToGlobalIfAvailable(F))
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001569 return Addr;
1570
Zonr Chang932648d2010-10-13 22:23:56 +08001571 // Get a stub if the target supports it.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001572 return GetLazyFunctionStub(F);
1573 }
1574
Zonr Chang932648d2010-10-13 22:23:56 +08001575 typedef llvm::DenseMap<const llvm::Function*,
1576 void*> FunctionToLazyStubMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001577 FunctionToLazyStubMapTy mFunctionToLazyStubMap;
1578
Zonr Chang932648d2010-10-13 22:23:56 +08001579 void *GetLazyFunctionStubIfAvailable(llvm::Function *F) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001580 return mFunctionToLazyStubMap.lookup(F);
1581 }
1582
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001583 std::set<const llvm::Function*> PendingFunctions;
Zonr Chang932648d2010-10-13 22:23:56 +08001584 void *GetLazyFunctionStub(llvm::Function *F) {
1585 // If we already have a lazy stub for this function, recycle it.
1586 void *&Stub = mFunctionToLazyStubMap[F];
1587 if (Stub)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001588 return Stub;
1589
Zonr Chang932648d2010-10-13 22:23:56 +08001590 // In any cases, we should NOT resolve function at runtime (though we are
1591 // able to). We resolve this right now.
1592 void *Actual = NULL;
1593 if (F->isDeclaration() || F->hasAvailableExternallyLinkage())
1594 Actual = GetPointerToFunction(F, /* AbortOnFailure = */true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001595
Zonr Chang932648d2010-10-13 22:23:56 +08001596 // Codegen a new stub, calling the actual address of the external
1597 // function, if it was resolved.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001598 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1599 startGVStub(F, SL.Size, SL.Alignment);
1600 Stub = mpTJI->emitFunctionStub(F, Actual, *this);
1601 finishGVStub();
1602
Zonr Chang932648d2010-10-13 22:23:56 +08001603 // We really want the address of the stub in the GlobalAddressMap for the
1604 // JIT, not the address of the external function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001605 UpdateGlobalMapping(F, Stub);
1606
Zonr Chang932648d2010-10-13 22:23:56 +08001607 if (!Actual)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001608 PendingFunctions.insert(F);
1609 else
Zonr Chang932648d2010-10-13 22:23:56 +08001610 Disassemble(F->getName(), reinterpret_cast<uint8_t*>(Stub),
1611 SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001612
1613 return Stub;
1614 }
1615
Zonr Chang932648d2010-10-13 22:23:56 +08001616 void *GetPointerToFunction(const llvm::Function *F, bool AbortOnFailure) {
1617 void *Addr = GetPointerToGlobalIfAvailable(F);
1618 if (Addr)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001619 return Addr;
1620
1621 assert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
1622 "Internal error: only external defined function routes here!");
1623
Zonr Chang932648d2010-10-13 22:23:56 +08001624 // Handle the failure resolution by ourselves.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001625 Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
Zonr Chang932648d2010-10-13 22:23:56 +08001626 /* AbortOnFailure = */ false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001627
Zonr Chang932648d2010-10-13 22:23:56 +08001628 // If we resolved the symbol to a null address (eg. a weak external)
1629 // return a null pointer let the application handle it.
1630 if (Addr == NULL) {
1631 if (AbortOnFailure)
1632 llvm::report_fatal_error("Could not resolve external function "
1633 "address: " + F->getName());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001634 else
1635 return NULL;
Zonr Chang932648d2010-10-13 22:23:56 +08001636 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001637
1638 AddGlobalMapping(F, Addr);
1639
1640 return Addr;
1641 }
1642
Zonr Chang932648d2010-10-13 22:23:56 +08001643 void *GetPointerToNamedSymbol(const std::string &Name,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001644 bool AbortOnFailure) {
Zonr Chang932648d2010-10-13 22:23:56 +08001645 if (void *Addr = FindRuntimeFunction(Name.c_str()))
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001646 return Addr;
1647
Zonr Chang932648d2010-10-13 22:23:56 +08001648 if (mpSymbolLookupFn)
1649 if (void *Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001650 return Addr;
1651
Zonr Chang932648d2010-10-13 22:23:56 +08001652 if (AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001653 llvm::report_fatal_error("Program used external symbol '" + Name +
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001654 "' which could not be resolved!");
1655
1656 return NULL;
1657 }
1658
Zonr Chang932648d2010-10-13 22:23:56 +08001659 // Return the address of the specified global variable, possibly emitting it
1660 // to memory if needed. This is used by the Emitter.
1661 void *GetOrEmitGlobalVariable(const llvm::GlobalVariable *GV) {
1662 void *Ptr = GetPointerToGlobalIfAvailable(GV);
1663 if (Ptr)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001664 return Ptr;
1665
Zonr Chang932648d2010-10-13 22:23:56 +08001666 if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
1667 // If the global is external, just remember the address.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001668 Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
1669 AddGlobalMapping(GV, Ptr);
1670 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08001671 // If the global hasn't been emitted to memory yet, allocate space and
1672 // emit it into memory.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001673 Ptr = GetMemoryForGV(GV);
1674 AddGlobalMapping(GV, Ptr);
1675 EmitGlobalVariable(GV);
1676 }
1677
1678 return Ptr;
1679 }
1680
Zonr Chang932648d2010-10-13 22:23:56 +08001681 // This method abstracts memory allocation of global variable so that the
1682 // JIT can allocate thread local variables depending on the target.
1683 void *GetMemoryForGV(const llvm::GlobalVariable *GV) {
1684 void *Ptr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001685
Zonr Chang932648d2010-10-13 22:23:56 +08001686 const llvm::Type *GlobalType = GV->getType()->getElementType();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001687 size_t S = mpTD->getTypeAllocSize(GlobalType);
1688 size_t A = mpTD->getPreferredAlignment(GV);
1689
Zonr Chang932648d2010-10-13 22:23:56 +08001690 if (GV->isThreadLocal()) {
1691 // We can support TLS by
1692 //
1693 // Ptr = TJI.allocateThreadLocalMemory(S);
1694 //
1695 // But I tend not to.
1696 // (should we disable this in the front-end (i.e., slang)?).
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001697 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001698 ("Compilation of Thread Local Storage (TLS) is disabled!");
1699
Zonr Chang932648d2010-10-13 22:23:56 +08001700 } else if (mpTJI->allocateSeparateGVMemory()) {
1701 if (A <= 8) {
1702 Ptr = malloc(S);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001703 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08001704 // Allocate (S + A) bytes of memory, then use an aligned pointer
1705 // within that space.
1706 Ptr = malloc(S + A);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001707 unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
Zonr Chang932648d2010-10-13 22:23:56 +08001708 Ptr = reinterpret_cast<uint8_t*>(Ptr) +
1709 (MisAligned ? (A - MisAligned) : 0);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001710 }
1711 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08001712 Ptr = allocateGlobal(S, A);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001713 }
1714
1715 return Ptr;
1716 }
1717
1718 void EmitGlobalVariable(const llvm::GlobalVariable *GV) {
Zonr Chang932648d2010-10-13 22:23:56 +08001719 void *GA = GetPointerToGlobalIfAvailable(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001720
Zonr Chang932648d2010-10-13 22:23:56 +08001721 if (GV->isThreadLocal())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001722 llvm::report_fatal_error
1723 ("We don't support Thread Local Storage (TLS)!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001724
Zonr Chang932648d2010-10-13 22:23:56 +08001725 if (GA == NULL) {
1726 // If it's not already specified, allocate memory for the global.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001727 GA = GetMemoryForGV(GV);
1728 AddGlobalMapping(GV, GA);
1729 }
1730
1731 InitializeConstantToMemory(GV->getInitializer(), GA);
1732
Zonr Chang932648d2010-10-13 22:23:56 +08001733 // You can do some statistics on global variable here.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001734 return;
1735 }
1736
1737 typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void*
1738 > GlobalToIndirectSymMapTy;
1739 GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
1740
Zonr Chang932648d2010-10-13 22:23:56 +08001741 void *GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
1742 // Make sure GV is emitted first, and create a stub containing the fully
1743 // resolved address.
1744 void *GVAddress = GetPointerToGlobal(V, Reference, false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001745
Zonr Chang932648d2010-10-13 22:23:56 +08001746 // If we already have a stub for this global variable, recycle it.
1747 void *&IndirectSym = GlobalToIndirectSymMap[V];
1748 // Otherwise, codegen a new indirect symbol.
1749 if (!IndirectSym)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001750 IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
1751
1752 return IndirectSym;
1753 }
1754
Zonr Chang932648d2010-10-13 22:23:56 +08001755 // This is the equivalent of FunctionToLazyStubMap for external functions.
1756 //
1757 // TODO(llvm.org): Of course, external functions don't need a lazy stub.
1758 // It's actually here to make it more likely that far calls
1759 // succeed, but no single stub can guarantee that. I'll
1760 // remove this in a subsequent checkin when I actually fix
1761 // far calls.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001762 std::map<void*, void*> ExternalFnToStubMap;
1763
Zonr Chang932648d2010-10-13 22:23:56 +08001764 // Return a stub for the function at the specified address.
1765 void *GetExternalFunctionStub(void *FnAddr) {
1766 void *&Stub = ExternalFnToStubMap[FnAddr];
1767 if (Stub)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001768 return Stub;
1769
1770 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1771 startGVStub(0, SL.Size, SL.Alignment);
1772 Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
1773 finishGVStub();
1774
1775 return Stub;
1776 }
1777
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001778#if defined(USE_DISASSEMBLER)
Zonr Chang932648d2010-10-13 22:23:56 +08001779 const llvm::MCAsmInfo *mpAsmInfo;
1780 const llvm::MCDisassembler *mpDisassmbler;
1781 llvm::MCInstPrinter *mpIP;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001782
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001783 class BufferMemoryObject : public llvm::MemoryObject {
1784 private:
Zonr Chang932648d2010-10-13 22:23:56 +08001785 const uint8_t *mBytes;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001786 uint64_t mLength;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001787
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001788 public:
1789 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) :
1790 mBytes(Bytes), mLength(Length) { }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001791
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001792 uint64_t getBase() const { return 0; }
1793 uint64_t getExtent() const { return mLength; }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001794
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001795 int readByte(uint64_t Addr, uint8_t *Byte) const {
Zonr Chang932648d2010-10-13 22:23:56 +08001796 if (Addr > getExtent())
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001797 return -1;
1798 *Byte = mBytes[Addr];
1799 return 0;
1800 }
1801 };
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001802
Zonr Chang932648d2010-10-13 22:23:56 +08001803 void Disassemble(const llvm::StringRef &Name, uint8_t *Start,
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001804 size_t Length, bool IsStub) {
Zonr Chang932648d2010-10-13 22:23:56 +08001805 llvm::raw_fd_ostream *OS;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001806#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001807 std::string ErrorInfo;
Zonr Chang932648d2010-10-13 22:23:56 +08001808 OS = new llvm::raw_fd_ostream("/data/local/tmp/out.S",
1809 ErrorInfo,
1810 llvm::raw_fd_ostream::F_Append);
1811 if (!ErrorInfo.empty()) { // some errors occurred
1812 // LOGE("Error in creating disassembly file");
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001813 delete OS;
1814 return;
1815 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001816#else
1817 OS = &llvm::outs();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001818#endif
Zonr Chang932648d2010-10-13 22:23:56 +08001819 *OS << "JIT: Disassembled code: " << Name << ((IsStub) ? " (stub)" : "")
1820 << "\n";
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001821
Zonr Chang932648d2010-10-13 22:23:56 +08001822 if (mpAsmInfo == NULL)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001823 mpAsmInfo = mpTarget->createAsmInfo(Triple);
Zonr Chang932648d2010-10-13 22:23:56 +08001824 if (mpDisassmbler == NULL)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001825 mpDisassmbler = mpTarget->createMCDisassembler();
Zonr Chang932648d2010-10-13 22:23:56 +08001826 if (mpIP == NULL)
1827 mpIP = mpTarget->createMCInstPrinter(mpAsmInfo->getAssemblerDialect(),
1828 *mpAsmInfo);
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001829
Zonr Chang932648d2010-10-13 22:23:56 +08001830 const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Start,
1831 Length);
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001832 uint64_t Size;
1833 uint64_t Index;
1834
Zonr Chang932648d2010-10-13 22:23:56 +08001835 for (Index = 0; Index < Length; Index += Size) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001836 llvm::MCInst Inst;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001837
Zonr Chang932648d2010-10-13 22:23:56 +08001838 if (mpDisassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
1839 /* REMOVED */ llvm::nulls())) {
1840 (*OS).indent(4)
1841 .write("0x", 2)
1842 .write_hex((uint32_t) Start + Index)
1843 .write(':');
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001844 mpIP->printInst(&Inst, *OS);
1845 *OS << "\n";
1846 } else {
1847 if (Size == 0)
Zonr Chang932648d2010-10-13 22:23:56 +08001848 Size = 1; // skip illegible bytes
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001849 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001850 }
1851
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001852 *OS << "\n";
1853 delete BufferMObj;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001854
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001855#if defined(USE_DISASSEMBLER_FILE)
Zonr Chang932648d2010-10-13 22:23:56 +08001856 // If you want the disassemble results write to file, uncomment this.
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001857 OS->close();
1858 delete OS;
1859#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001860 return;
1861 }
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001862#else
Zonr Chang932648d2010-10-13 22:23:56 +08001863 inline void Disassemble(const std::string &Name, uint8_t *Start,
1864 size_t Length, bool IsStub) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001865 return;
1866 }
Zonr Chang932648d2010-10-13 22:23:56 +08001867#endif // defined(USE_DISASSEMBLER)
1868
1869 // Resolver to undefined symbol in CodeEmitter
1870 BCCSymbolLookupFn mpSymbolLookupFn;
1871 void *mpSymbolLookupContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001872
1873 public:
Zonr Chang932648d2010-10-13 22:23:56 +08001874 // Will take the ownership of @MemMgr
1875 explicit CodeEmitter(CodeMemoryManager *pMemMgr)
1876 : mpMemMgr(pMemMgr),
1877 mpTarget(NULL),
1878 mpTJI(NULL),
1879 mpTD(NULL),
1880 mpCurEmitFunction(NULL),
1881 mpConstantPool(NULL),
1882 mpJumpTable(NULL),
1883 mpMMI(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001884#if defined(USE_DISASSEMBLER)
Zonr Chang932648d2010-10-13 22:23:56 +08001885 mpAsmInfo(NULL),
1886 mpDisassmbler(NULL),
1887 mpIP(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001888#endif
Zonr Chang932648d2010-10-13 22:23:56 +08001889 mpSymbolLookupFn(NULL),
1890 mpSymbolLookupContext(NULL) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001891 return;
1892 }
1893
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001894 inline global_addresses_const_iterator global_address_begin() const {
1895 return mGlobalAddressMap.begin();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001896 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001897 inline global_addresses_const_iterator global_address_end() const {
1898 return mGlobalAddressMap.end();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001899 }
1900
Zonr Chang932648d2010-10-13 22:23:56 +08001901 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001902 mpSymbolLookupFn = pFn;
1903 mpSymbolLookupContext = pContext;
1904 return;
1905 }
1906
Zonr Chang932648d2010-10-13 22:23:56 +08001907 void setTargetMachine(llvm::TargetMachine &TM) {
1908 // Set Target
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001909 mpTarget = &TM.getTarget();
Zonr Chang932648d2010-10-13 22:23:56 +08001910 // Set TargetJITInfo
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001911 mpTJI = TM.getJITInfo();
Zonr Chang932648d2010-10-13 22:23:56 +08001912 // set TargetData
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001913 mpTD = TM.getTargetData();
1914
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001915 assert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
1916
1917 return;
1918 }
1919
Zonr Chang932648d2010-10-13 22:23:56 +08001920 // This callback is invoked when the specified function is about to be code
1921 // generated. This initializes the BufferBegin/End/Ptr fields.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001922 void startFunction(llvm::MachineFunction &F) {
1923 uintptr_t ActualSize = 0;
1924
1925 mpMemMgr->setMemoryWritable();
Zonr Chang932648d2010-10-13 22:23:56 +08001926
1927 // BufferBegin, BufferEnd and CurBufferPtr are all inherited from class
1928 // MachineCodeEmitter, which is the super class of the class
1929 // JITCodeEmitter.
1930 //
1931 // BufferBegin/BufferEnd - Pointers to the start and end of the memory
1932 // allocated for this code buffer.
1933 //
1934 // CurBufferPtr - Pointer to the next byte of memory to fill when emitting
1935 // code. This is guranteed to be in the range
1936 // [BufferBegin, BufferEnd]. If this pointer is at
1937 // BufferEnd, it will never move due to code emission, and
1938 // all code emission requests will be ignored (this is the
1939 // buffer overflow condition).
1940 BufferBegin = CurBufferPtr =
1941 mpMemMgr->startFunctionBody(F.getFunction(), ActualSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001942 BufferEnd = BufferBegin + ActualSize;
1943
Zonr Chang932648d2010-10-13 22:23:56 +08001944 if (mpCurEmitFunction == NULL)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001945 mpCurEmitFunction = new EmittedFunctionCode();
1946 mpCurEmitFunction->FunctionBody = BufferBegin;
1947
Zonr Chang932648d2010-10-13 22:23:56 +08001948 // Ensure the constant pool/jump table info is at least 4-byte aligned.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001949 emitAlignment(16);
1950
1951 emitConstantPool(F.getConstantPool());
Zonr Chang932648d2010-10-13 22:23:56 +08001952 if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001953 initJumpTableInfo(MJTI);
1954
Zonr Chang932648d2010-10-13 22:23:56 +08001955 // About to start emitting the machine code for the function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001956 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
1957
1958 UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
1959
1960 mpCurEmitFunction->Code = CurBufferPtr;
1961
1962 mMBBLocations.clear();
1963
1964 return;
1965 }
1966
Zonr Chang932648d2010-10-13 22:23:56 +08001967 // This callback is invoked when the specified function has finished code
1968 // generation. If a buffer overflow has occurred, this method returns true
1969 // (the callee is required to try again).
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001970 bool finishFunction(llvm::MachineFunction &F) {
Zonr Chang932648d2010-10-13 22:23:56 +08001971 if (CurBufferPtr == BufferEnd) {
1972 // No enough memory
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001973 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
1974 return false;
1975 }
1976
Zonr Chang932648d2010-10-13 22:23:56 +08001977 if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001978 emitJumpTableInfo(MJTI);
1979
Zonr Chang932648d2010-10-13 22:23:56 +08001980 // FnStart is the start of the text, not the start of the constant pool
1981 // and other per-function data.
1982 uint8_t *FnStart =
1983 reinterpret_cast<uint8_t*>(
1984 GetPointerToGlobalIfAvailable(F.getFunction()));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001985
Zonr Chang932648d2010-10-13 22:23:56 +08001986 // FnEnd is the end of the function's machine code.
1987 uint8_t *FnEnd = CurBufferPtr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001988
Zonr Chang932648d2010-10-13 22:23:56 +08001989 if (!mRelocations.empty()) {
1990 // Resolve the relocations to concrete pointers.
1991 for (int i = 0, e = mRelocations.size(); i != e; i++) {
1992 llvm::MachineRelocation &MR = mRelocations[i];
1993 void *ResultPtr = NULL;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001994
Zonr Chang932648d2010-10-13 22:23:56 +08001995 if (!MR.letTargetResolve()) {
1996 if (MR.isExternalSymbol()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001997 ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
Zonr Chang932648d2010-10-13 22:23:56 +08001998 if (MR.mayNeedFarStub())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001999 ResultPtr = GetExternalFunctionStub(ResultPtr);
Zonr Chang932648d2010-10-13 22:23:56 +08002000 } else if (MR.isGlobalValue()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002001 ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
2002 BufferBegin
2003 + MR.getMachineCodeOffset(),
2004 MR.mayNeedFarStub());
Zonr Chang932648d2010-10-13 22:23:56 +08002005 } else if (MR.isIndirectSymbol()) {
2006 ResultPtr =
2007 GetPointerToGVIndirectSym(
2008 MR.getGlobalValue(),
2009 BufferBegin + MR.getMachineCodeOffset());
2010 } else if (MR.isBasicBlock()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002011 ResultPtr =
2012 (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
Zonr Chang932648d2010-10-13 22:23:56 +08002013 } else if (MR.isConstantPoolIndex()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002014 ResultPtr =
Zonr Chang932648d2010-10-13 22:23:56 +08002015 (void*) getConstantPoolEntryAddress(MR.getConstantPoolIndex());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002016 } else {
2017 assert(MR.isJumpTableIndex() && "Unknown type of relocation");
2018 ResultPtr =
2019 (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
2020 }
2021
2022 MR.setResultPointer(ResultPtr);
2023 }
2024 }
2025
2026 mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
2027 mpMemMgr->getGOTBase());
2028 }
2029
2030 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
Zonr Chang932648d2010-10-13 22:23:56 +08002031 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
2032 // global variables that were referenced in the relocations.
2033 if (CurBufferPtr == BufferEnd)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002034 return false;
2035
Zonr Chang932648d2010-10-13 22:23:56 +08002036 // Now that we've succeeded in emitting the function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002037 mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
2038 BufferBegin = CurBufferPtr = 0;
2039
Zonr Chang932648d2010-10-13 22:23:56 +08002040 if (F.getFunction()->hasName())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002041 mEmittedFunctions[F.getFunction()->getNameStr()] = mpCurEmitFunction;
2042 mpCurEmitFunction = NULL;
2043
2044 mRelocations.clear();
2045 mConstPoolAddresses.clear();
2046
Zonr Chang932648d2010-10-13 22:23:56 +08002047 if (mpMMI)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002048 mpMMI->EndFunction();
2049
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002050 updateFunctionStub(F.getFunction());
2051
Zonr Chang932648d2010-10-13 22:23:56 +08002052 // Mark code region readable and executable if it's not so already.
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -07002053 mpMemMgr->setMemoryExecutable();
2054
2055 Disassemble(F.getFunction()->getName(), FnStart, FnEnd - FnStart, false);
2056
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002057 return false;
2058 }
2059
Zonr Chang932648d2010-10-13 22:23:56 +08002060 void startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002061 unsigned Alignment) {
2062 mpSavedBufferBegin = BufferBegin;
2063 mpSavedBufferEnd = BufferEnd;
2064 mpSavedCurBufferPtr = CurBufferPtr;
2065
2066 BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
2067 Alignment);
2068 BufferEnd = BufferBegin + StubSize + 1;
2069
2070 return;
2071 }
2072
Zonr Chang932648d2010-10-13 22:23:56 +08002073 void startGVStub(void *Buffer, unsigned StubSize) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002074 mpSavedBufferBegin = BufferBegin;
2075 mpSavedBufferEnd = BufferEnd;
2076 mpSavedCurBufferPtr = CurBufferPtr;
2077
Zonr Chang932648d2010-10-13 22:23:56 +08002078 BufferBegin = CurBufferPtr = reinterpret_cast<uint8_t *>(Buffer);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002079 BufferEnd = BufferBegin + StubSize + 1;
2080
2081 return;
2082 }
2083
2084 void finishGVStub() {
2085 assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
2086
Zonr Chang932648d2010-10-13 22:23:56 +08002087 // restore
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002088 BufferBegin = mpSavedBufferBegin;
2089 BufferEnd = mpSavedBufferEnd;
2090 CurBufferPtr = mpSavedCurBufferPtr;
2091
2092 return;
2093 }
2094
Zonr Chang932648d2010-10-13 22:23:56 +08002095 // Allocates and fills storage for an indirect GlobalValue, and returns the
2096 // address.
2097 void *allocIndirectGV(const llvm::GlobalValue *GV,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002098 const uint8_t *Buffer, size_t Size,
2099 unsigned Alignment) {
Zonr Chang932648d2010-10-13 22:23:56 +08002100 uint8_t *IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002101 memcpy(IndGV, Buffer, Size);
2102 return IndGV;
2103 }
2104
Zonr Chang932648d2010-10-13 22:23:56 +08002105 // Emits a label
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002106 void emitLabel(llvm::MCSymbol *Label) {
2107 mLabelLocations[Label] = getCurrentPCValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002108 return;
2109 }
2110
Zonr Chang932648d2010-10-13 22:23:56 +08002111 // Allocate memory for a global. Unlike allocateSpace, this method does not
2112 // allocate memory in the current output buffer, because a global may live
2113 // longer than the current function.
2114 void *allocateGlobal(uintptr_t Size, unsigned Alignment) {
2115 // Delegate this call through the memory manager.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002116 return mpMemMgr->allocateGlobal(Size, Alignment);
2117 }
2118
Zonr Chang932648d2010-10-13 22:23:56 +08002119 // This should be called by the target when a new basic block is about to be
2120 // emitted. This way the MCE knows where the start of the block is, and can
2121 // implement getMachineBasicBlockAddress.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002122 void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
Zonr Chang932648d2010-10-13 22:23:56 +08002123 if (mMBBLocations.size() <= (unsigned) MBB->getNumber())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002124 mMBBLocations.resize((MBB->getNumber() + 1) * 2);
2125 mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
2126 return;
2127 }
2128
Zonr Chang932648d2010-10-13 22:23:56 +08002129 // Whenever a relocatable address is needed, it should be noted with this
2130 // interface.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002131 void addRelocation(const llvm::MachineRelocation &MR) {
2132 mRelocations.push_back(MR);
2133 return;
2134 }
2135
Zonr Chang932648d2010-10-13 22:23:56 +08002136 // Return the address of the @Index entry in the constant pool that was
2137 // last emitted with the emitConstantPool method.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002138 uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
2139 assert(Index < mpConstantPool->getConstants().size() &&
2140 "Invalid constant pool index!");
2141 return mConstPoolAddresses[Index];
2142 }
2143
Zonr Chang932648d2010-10-13 22:23:56 +08002144 // Return the address of the jump table with index @Index in the function
2145 // that last called initJumpTableInfo.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002146 uintptr_t getJumpTableEntryAddress(unsigned Index) const {
Zonr Chang932648d2010-10-13 22:23:56 +08002147 const std::vector<llvm::MachineJumpTableEntry> &JT =
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002148 mpJumpTable->getJumpTables();
2149
Zonr Chang932648d2010-10-13 22:23:56 +08002150 assert((Index < JT.size()) && "Invalid jump table index!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002151
2152 unsigned int Offset = 0;
2153 unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
2154
Zonr Chang932648d2010-10-13 22:23:56 +08002155 for (unsigned i = 0; i < Index; i++)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002156 Offset += JT[i].MBBs.size();
2157 Offset *= EntrySize;
2158
Zonr Chang932648d2010-10-13 22:23:56 +08002159 return (uintptr_t)(reinterpret_cast<uint8_t*>(mpJumpTableBase) + Offset);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002160 }
2161
Zonr Chang932648d2010-10-13 22:23:56 +08002162 // Return the address of the specified MachineBasicBlock, only usable after
2163 // the label for the MBB has been emitted.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002164 uintptr_t getMachineBasicBlockAddress(llvm::MachineBasicBlock *MBB) const {
2165 assert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
Zonr Chang932648d2010-10-13 22:23:56 +08002166 mMBBLocations[MBB->getNumber()] &&
2167 "MBB not emitted!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002168 return mMBBLocations[MBB->getNumber()];
2169 }
2170
Zonr Chang932648d2010-10-13 22:23:56 +08002171 // Return the address of the specified LabelID, only usable after the
2172 // LabelID has been emitted.
2173 uintptr_t getLabelAddress(llvm::MCSymbol *Label) const {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002174 assert(mLabelLocations.count(Label) && "Label not emitted!");
2175 return mLabelLocations.find(Label)->second;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002176 }
2177
Zonr Chang932648d2010-10-13 22:23:56 +08002178 // Specifies the MachineModuleInfo object. This is used for exception
2179 // handling purposes.
2180 void setModuleInfo(llvm::MachineModuleInfo *Info) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002181 mpMMI = Info;
2182 return;
2183 }
2184
Zonr Chang932648d2010-10-13 22:23:56 +08002185 void updateFunctionStub(const llvm::Function *F) {
2186 // Get the empty stub we generated earlier.
2187 void *Stub;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002188 std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
Zonr Chang932648d2010-10-13 22:23:56 +08002189 if (I != PendingFunctions.end())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002190 Stub = mFunctionToLazyStubMap[F];
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002191 else
2192 return;
2193
Zonr Chang932648d2010-10-13 22:23:56 +08002194 void *Addr = GetPointerToGlobalIfAvailable(F);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002195
2196 assert(Addr != Stub &&
2197 "Function must have non-stub address to be updated.");
2198
Zonr Chang932648d2010-10-13 22:23:56 +08002199 // Tell the target jit info to rewrite the stub at the specified address,
2200 // rather than creating a new one.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002201 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
2202 startGVStub(Stub, SL.Size);
2203 mpTJI->emitFunctionStub(F, Addr, *this);
2204 finishGVStub();
2205
Zonr Chang932648d2010-10-13 22:23:56 +08002206 Disassemble(F->getName(), reinterpret_cast<uint8_t*>(Stub),
2207 SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002208
2209 PendingFunctions.erase(I);
2210
2211 return;
2212 }
2213
Zonr Chang932648d2010-10-13 22:23:56 +08002214 // Once you finish the compilation on a translation unit, you can call this
2215 // function to recycle the memory (which is used at compilation time and not
2216 // needed for runtime).
2217 //
2218 // NOTE: You should not call this funtion until the code-gen passes for a
2219 // given module is done. Otherwise, the results is undefined and may
2220 // cause the system crash!
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002221 void releaseUnnecessary() {
2222 mMBBLocations.clear();
2223 mLabelLocations.clear();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002224 mGlobalAddressMap.clear();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002225 mFunctionToLazyStubMap.clear();
2226 GlobalToIndirectSymMap.clear();
2227 ExternalFnToStubMap.clear();
2228 PendingFunctions.clear();
2229
2230 return;
2231 }
2232
2233 void reset() {
2234 releaseUnnecessary();
2235
2236 mpSymbolLookupFn = NULL;
2237 mpSymbolLookupContext = NULL;
2238
2239 mpTJI = NULL;
2240 mpTD = NULL;
2241
Zonr Chang932648d2010-10-13 22:23:56 +08002242 for (EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin(),
2243 E = mEmittedFunctions.end();
2244 I != E;
2245 I++)
2246 if (I->second != NULL)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002247 delete I->second;
2248 mEmittedFunctions.clear();
2249
2250 mpMemMgr->reset();
2251
2252 return;
2253 }
2254
Zonr Chang932648d2010-10-13 22:23:56 +08002255 void *lookup(const char *Name) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002256 return lookup( llvm::StringRef(Name) );
2257 }
2258
Zonr Chang932648d2010-10-13 22:23:56 +08002259 void *lookup(const llvm::StringRef &Name) {
2260 EmittedFunctionsMapTy::const_iterator I =
2261 mEmittedFunctions.find(Name.str());
2262 if (I == mEmittedFunctions.end())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002263 return NULL;
2264 else
2265 return I->second->Code;
2266 }
2267
Zonr Chang932648d2010-10-13 22:23:56 +08002268 void getFunctionNames(BCCsizei *actualFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002269 BCCsizei maxFunctionCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002270 BCCchar **functions) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002271 int functionCount = mEmittedFunctions.size();
2272
Zonr Chang932648d2010-10-13 22:23:56 +08002273 if (actualFunctionCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002274 *actualFunctionCount = functionCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002275 if (functionCount > maxFunctionCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002276 functionCount = maxFunctionCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002277 if (functions)
2278 for (EmittedFunctionsMapTy::const_iterator
2279 I = mEmittedFunctions.begin(), E = mEmittedFunctions.end();
2280 (I != E) && (functionCount > 0);
2281 I++, functionCount--)
2282 *functions++ = const_cast<BCCchar*>(I->first.c_str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002283
2284 return;
2285 }
2286
Zonr Chang932648d2010-10-13 22:23:56 +08002287 void getFunctionBinary(BCCchar *label,
2288 BCCvoid **base,
2289 BCCsizei *length) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002290 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(label);
Zonr Chang932648d2010-10-13 22:23:56 +08002291 if (I == mEmittedFunctions.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002292 *base = NULL;
2293 *length = 0;
2294 } else {
2295 *base = I->second->Code;
2296 *length = I->second->Size;
2297 }
2298 return;
2299 }
2300
2301 ~CodeEmitter() {
Zonr Chang932648d2010-10-13 22:23:56 +08002302 delete mpMemMgr;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002303#if defined(USE_DISASSEMBLER)
Zonr Chang932648d2010-10-13 22:23:56 +08002304 delete mpAsmInfo;
2305 delete mpDisassmbler;
2306 delete mpIP;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002307#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002308 return;
2309 }
Zonr Chang932648d2010-10-13 22:23:56 +08002310 };
2311 // End of Class CodeEmitter
2312 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002313
Zonr Chang932648d2010-10-13 22:23:56 +08002314 // The CodeEmitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002315 llvm::OwningPtr<CodeEmitter> mCodeEmitter;
Zonr Chang932648d2010-10-13 22:23:56 +08002316 CodeEmitter *createCodeEmitter() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002317 mCodeEmitter.reset(new CodeEmitter(mCodeMemMgr.take()));
2318 return mCodeEmitter.get();
2319 }
2320
2321 BCCSymbolLookupFn mpSymbolLookupFn;
Zonr Chang932648d2010-10-13 22:23:56 +08002322 void *mpSymbolLookupContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002323
Zonr Chang932648d2010-10-13 22:23:56 +08002324 llvm::LLVMContext *mContext;
2325 llvm::Module *mModule;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002326
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002327 bool mHasLinked;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002328
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002329 public:
Zonr Chang932648d2010-10-13 22:23:56 +08002330 Compiler()
2331 : mpSymbolLookupFn(NULL),
2332 mpSymbolLookupContext(NULL),
2333 mContext(NULL),
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002334 mModule(NULL),
2335 mHasLinked(NULL) {
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002336 llvm::remove_fatal_error_handler();
2337 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002338 mContext = new llvm::LLVMContext();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002339 return;
2340 }
2341
Zonr Chang932648d2010-10-13 22:23:56 +08002342 // interface for BCCscript::registerSymbolCallback()
2343 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002344 mpSymbolLookupFn = pFn;
2345 mpSymbolLookupContext = pContext;
2346 return;
2347 }
2348
Zonr Changdbee68b2010-10-22 05:02:16 +08002349 int loadModule(llvm::Module *module) {
2350 GlobalInitialization();
2351 mModule = module;
2352 return hasError();
2353 }
2354
Zonr Chang932648d2010-10-13 22:23:56 +08002355 int loadModule(const char *bitcode, size_t bitcodeSize) {
Zonr Chang97f5e612010-10-22 20:38:26 +08002356 llvm::OwningPtr<llvm::MemoryBuffer> SB;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002357
Zonr Chang932648d2010-10-13 22:23:56 +08002358 if (bitcode == NULL || bitcodeSize <= 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002359 return 0;
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002360
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002361 GlobalInitialization();
2362
Zonr Chang932648d2010-10-13 22:23:56 +08002363 // Package input to object MemoryBuffer
Zonr Chang97f5e612010-10-22 20:38:26 +08002364 SB.reset(llvm::MemoryBuffer::getMemBuffer(
2365 llvm::StringRef(bitcode, bitcodeSize)));
2366
2367 if (SB.get() == NULL) {
2368 setError("Error reading input program bitcode into memory");
2369 return hasError();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002370 }
2371
Zonr Chang932648d2010-10-13 22:23:56 +08002372 // Read the input Bitcode as a Module
Zonr Chang97f5e612010-10-22 20:38:26 +08002373 mModule = llvm::ParseBitcodeFile(SB.get(), *mContext, &mError);
2374 SB.reset();
2375 return hasError();
2376 }
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002377
Zonr Chang97f5e612010-10-22 20:38:26 +08002378 int linkModule(const char *bitcode, size_t bitcodeSize) {
2379 llvm::OwningPtr<llvm::MemoryBuffer> SB;
2380
2381 if (bitcode == NULL || bitcodeSize <= 0)
2382 return 0;
2383
2384 if (mModule == NULL) {
2385 setError("No module presents for linking");
2386 return hasError();
2387 }
2388
2389 SB.reset(llvm::MemoryBuffer::getMemBuffer(
2390 llvm::StringRef(bitcode, bitcodeSize)));
2391
2392 if (SB.get() == NULL) {
2393 setError("Error reading input library bitcode into memory");
2394 return hasError();
2395 }
2396
2397 llvm::OwningPtr<llvm::Module> Lib(llvm::ParseBitcodeFile(SB.get(),
2398 *mContext,
2399 &mError));
2400 if (Lib.get() == NULL)
2401 return hasError();
2402
2403 if (llvm::Linker::LinkModules(mModule, Lib.take(), &mError))
2404 return hasError();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002405
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002406 // Everything for linking should be settled down here with no error occurs
2407 mHasLinked = true;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002408 return hasError();
2409 }
2410
Zonr Chang932648d2010-10-13 22:23:56 +08002411 // interace for bccCompileScript()
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002412 int compile() {
Zonr Chang932648d2010-10-13 22:23:56 +08002413 llvm::TargetData *TD = NULL;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002414
Zonr Chang932648d2010-10-13 22:23:56 +08002415 llvm::TargetMachine *TM = NULL;
2416 const llvm::Target *Target;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002417 std::string FeaturesStr;
2418
Zonr Chang932648d2010-10-13 22:23:56 +08002419 llvm::FunctionPassManager *CodeGenPasses = NULL;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002420
Zonr Chang932648d2010-10-13 22:23:56 +08002421 const llvm::NamedMDNode *PragmaMetadata;
2422 const llvm::NamedMDNode *ExportVarMetadata;
2423 const llvm::NamedMDNode *ExportFuncMetadata;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002424
Zonr Chang932648d2010-10-13 22:23:56 +08002425 if (mModule == NULL) // No module was loaded
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002426 return 0;
2427
Zonr Chang932648d2010-10-13 22:23:56 +08002428 // Create TargetMachine
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002429 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
Zonr Chang932648d2010-10-13 22:23:56 +08002430 if (hasError())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002431 goto on_bcc_compile_error;
2432
Zonr Chang932648d2010-10-13 22:23:56 +08002433 if (!CPU.empty() || !Features.empty()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002434 llvm::SubtargetFeatures F;
2435 F.setCPU(CPU);
Zonr Chang932648d2010-10-13 22:23:56 +08002436 for (std::vector<std::string>::const_iterator I = Features.begin(),
2437 E = Features.end();
2438 I != E;
2439 I++)
2440 F.AddFeature(*I);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002441 FeaturesStr = F.getString();
2442 }
2443
2444 TM = Target->createTargetMachine(Triple, FeaturesStr);
Zonr Chang932648d2010-10-13 22:23:56 +08002445 if (TM == NULL) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002446 setError("Failed to create target machine implementation for the"
2447 " specified triple '" + Triple + "'");
2448 goto on_bcc_compile_error;
2449 }
2450
Zonr Chang932648d2010-10-13 22:23:56 +08002451 // Create memory manager for creation of code emitter later.
2452 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002453 setError("Failed to startup memory management for further compilation");
2454 goto on_bcc_compile_error;
2455 }
2456
Zonr Chang932648d2010-10-13 22:23:56 +08002457 // Create code emitter
2458 if (!mCodeEmitter.get()) {
2459 if (!createCodeEmitter()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002460 setError("Failed to create machine code emitter to complete"
2461 " the compilation");
2462 goto on_bcc_compile_error;
2463 }
2464 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08002465 // Reuse the code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002466 mCodeEmitter->reset();
2467 }
2468
2469 mCodeEmitter->setTargetMachine(*TM);
2470 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
2471 mpSymbolLookupContext);
2472
Zonr Chang932648d2010-10-13 22:23:56 +08002473 // Get target data from Module
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002474 TD = new llvm::TargetData(mModule);
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002475
Zonr Chang5d35b972010-10-23 14:36:47 +08002476 // Load named metadata
2477 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
2478 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
2479 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
2480
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002481 // Create LTO passes and run them on the mModule
2482 if (mHasLinked) {
Zonr Chang5d35b972010-10-23 14:36:47 +08002483 llvm::TimePassesIsEnabled = true;
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002484 llvm::PassManager LTOPasses;
Zonr Chang5d35b972010-10-23 14:36:47 +08002485 LTOPasses.add(new llvm::TargetData(*TD));
2486
2487 std::vector<const char*> ExportSymbols;
2488
2489 // A workaround for getting export variable and function name. Will refine
2490 // it soon.
2491 if (ExportVarMetadata) {
2492 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
2493 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
2494 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2495 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
2496 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
2497 llvm::StringRef ExportVarName =
2498 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
2499 ExportSymbols.push_back(ExportVarName.data());
2500 }
2501 }
2502 }
2503 }
2504
2505 if (ExportFuncMetadata) {
2506 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
2507 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
2508 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
2509 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
2510 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
2511 llvm::StringRef ExportFuncName =
2512 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
2513 ExportSymbols.push_back(ExportFuncName.data());
2514 }
2515 }
2516 }
2517 }
2518 // root() and init() are born to be exported
2519 ExportSymbols.push_back("root");
2520 ExportSymbols.push_back("init");
2521
Zonr Change5c7a542010-10-24 01:07:27 +08002522 // We now create passes list performing LTO. These are copied from
2523 // (including comments) llvm::createStandardLTOPasses().
2524
2525 // Internalize all other symbols not listed in ExportSymbols
Zonr Chang5d35b972010-10-23 14:36:47 +08002526 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002527
Zonr Change5c7a542010-10-24 01:07:27 +08002528 // Propagate constants at call sites into the functions they call. This
2529 // opens opportunities for globalopt (and inlining) by substituting
2530 // function pointers passed as arguments to direct uses of functions.
2531 LTOPasses.add(llvm::createIPSCCPPass());
2532
2533 // Now that we internalized some globals, see if we can hack on them!
2534 LTOPasses.add(llvm::createGlobalOptimizerPass());
2535
2536 // Linking modules together can lead to duplicated global constants, only
2537 // keep one copy of each constant...
2538 LTOPasses.add(llvm::createConstantMergePass());
2539
2540 // Remove unused arguments from functions...
2541 LTOPasses.add(llvm::createDeadArgEliminationPass());
2542
2543 // Reduce the code after globalopt and ipsccp. Both can open up
2544 // significant simplification opportunities, and both can propagate
2545 // functions through function pointers. When this happens, we often have
2546 // to resolve varargs calls, etc, so let instcombine do this.
2547 LTOPasses.add(llvm::createInstructionCombiningPass());
2548
2549 // Inline small functions
2550 LTOPasses.add(llvm::createFunctionInliningPass());
2551
2552 // Remove dead EH info.
2553 LTOPasses.add(llvm::createPruneEHPass());
2554
2555 // Internalize the globals again after inlining
2556 LTOPasses.add(llvm::createGlobalOptimizerPass());
2557
2558 // Remove dead functions.
2559 LTOPasses.add(llvm::createGlobalDCEPass());
2560
2561 // If we didn't decide to inline a function, check to see if we can
2562 // transform it to pass arguments by value instead of by reference.
2563 LTOPasses.add(llvm::createArgumentPromotionPass());
2564
2565 // The IPO passes may leave cruft around. Clean up after them.
2566 LTOPasses.add(llvm::createInstructionCombiningPass());
2567 LTOPasses.add(llvm::createJumpThreadingPass());
2568
2569 // Break up allocas
2570 LTOPasses.add(llvm::createScalarReplAggregatesPass());
2571
2572 // Run a few AA driven optimizations here and now, to cleanup the code.
2573 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
2574 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
2575
2576 // Hoist loop invariants.
2577 LTOPasses.add(llvm::createLICMPass());
2578
2579 // Remove redundancies.
2580 LTOPasses.add(llvm::createGVNPass());
2581
2582 // Remove dead memcpys.
2583 LTOPasses.add(llvm::createMemCpyOptPass());
2584
2585 // Nuke dead stores.
2586 LTOPasses.add(llvm::createDeadStoreEliminationPass());
2587
2588 // Cleanup and simplify the code after the scalar optimizations.
2589 LTOPasses.add(llvm::createInstructionCombiningPass());
2590
2591 LTOPasses.add(llvm::createJumpThreadingPass());
2592
2593 // Delete basic blocks, which optimization passes may have killed.
2594 LTOPasses.add(llvm::createCFGSimplificationPass());
2595
2596 // Now that we have optimized the program, discard unreachable functions.
2597 LTOPasses.add(llvm::createGlobalDCEPass());
2598
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002599 LTOPasses.run(*mModule);
2600 }
2601
Zonr Chang932648d2010-10-13 22:23:56 +08002602 // Create code-gen pass to run the code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002603 CodeGenPasses = new llvm::FunctionPassManager(mModule);
Zonr Chang932648d2010-10-13 22:23:56 +08002604 CodeGenPasses->add(TD); // Will take the ownership of TD
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002605
Zonr Chang932648d2010-10-13 22:23:56 +08002606 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
2607 *mCodeEmitter,
2608 CodeGenOptLevel)) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002609 setError("The machine code emission is not supported by BCC on target '"
2610 + Triple + "'");
2611 goto on_bcc_compile_error;
2612 }
2613
Zonr Chang932648d2010-10-13 22:23:56 +08002614 // Run the pass (the code emitter) on every non-declaration function in the
2615 // module
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002616 CodeGenPasses->doInitialization();
Zonr Chang932648d2010-10-13 22:23:56 +08002617 for (llvm::Module::iterator I = mModule->begin(), E = mModule->end();
2618 I != E;
2619 I++)
2620 if (!I->isDeclaration())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002621 CodeGenPasses->run(*I);
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002622
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002623 CodeGenPasses->doFinalization();
2624
Zonr Chang932648d2010-10-13 22:23:56 +08002625 // Copy the global address mapping from code emitter and remapping
Zonr Chang932648d2010-10-13 22:23:56 +08002626 if (ExportVarMetadata) {
2627 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
2628 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
2629 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2630 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
2631 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002632 llvm::StringRef ExportVarName =
2633 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
Zonr Chang932648d2010-10-13 22:23:56 +08002634 CodeEmitter::global_addresses_const_iterator I, E;
2635 for (I = mCodeEmitter->global_address_begin(),
2636 E = mCodeEmitter->global_address_end();
2637 I != E;
2638 I++) {
2639 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002640 continue;
Zonr Chang932648d2010-10-13 22:23:56 +08002641 if (ExportVarName == I->first->getName()) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002642 mExportVars.push_back(I->second);
2643 break;
2644 }
2645 }
Zonr Chang932648d2010-10-13 22:23:56 +08002646 if (I != mCodeEmitter->global_address_end())
2647 continue; // found
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002648 }
2649 }
Zonr Chang932648d2010-10-13 22:23:56 +08002650 // if here, the global variable record in metadata is not found, make an
2651 // empty slot
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002652 mExportVars.push_back(NULL);
2653 }
2654 assert((mExportVars.size() == ExportVarMetadata->getNumOperands()) &&
2655 "Number of slots doesn't match the number of export variables!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002656 }
2657
Zonr Chang932648d2010-10-13 22:23:56 +08002658 if (ExportFuncMetadata) {
2659 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
2660 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
2661 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
2662 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
2663 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002664 llvm::StringRef ExportFuncName =
2665 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
2666 mExportFuncs.push_back(mCodeEmitter->lookup(ExportFuncName));
2667 }
2668 }
2669 }
2670 }
2671
Zonr Chang932648d2010-10-13 22:23:56 +08002672 // Tell code emitter now can release the memory using during the JIT since
2673 // we have done the code emission
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002674 mCodeEmitter->releaseUnnecessary();
2675
Zonr Chang932648d2010-10-13 22:23:56 +08002676 // Finally, read pragma information from the metadata node of the @Module if
2677 // any.
Zonr Chang932648d2010-10-13 22:23:56 +08002678 if (PragmaMetadata)
2679 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
2680 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
2681 if (Pragma != NULL &&
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002682 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
Zonr Chang932648d2010-10-13 22:23:56 +08002683 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
2684 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002685
Zonr Chang932648d2010-10-13 22:23:56 +08002686 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002687 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
2688 llvm::StringRef PragmaName =
2689 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
2690 llvm::StringRef PragmaValue =
2691 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
2692
Zonr Chang932648d2010-10-13 22:23:56 +08002693 mPragmas.push_back(
2694 std::make_pair(std::string(PragmaName.data(),
2695 PragmaName.size()),
2696 std::string(PragmaValue.data(),
2697 PragmaValue.size())));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002698 }
2699 }
2700 }
2701
2702 on_bcc_compile_error:
Zonr Chang932648d2010-10-13 22:23:56 +08002703 // LOGE("on_bcc_compiler_error");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002704 if (CodeGenPasses) {
2705 delete CodeGenPasses;
2706 } else if (TD) {
2707 delete TD;
2708 }
2709 if (TM)
2710 delete TM;
2711
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002712 if (mError.empty()) {
2713 return false;
2714 }
2715
Zonr Chang932648d2010-10-13 22:23:56 +08002716 // LOGE(getErrorMessage());
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002717 return true;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002718 }
2719
Zonr Chang932648d2010-10-13 22:23:56 +08002720 // interface for bccGetScriptInfoLog()
2721 char *getErrorMessage() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002722 return const_cast<char*>(mError.c_str());
2723 }
2724
Zonr Chang932648d2010-10-13 22:23:56 +08002725 // interface for bccGetScriptLabel()
2726 void *lookup(const char *name) {
2727 void *addr = NULL;
2728 if (mCodeEmitter.get())
2729 // Find function pointer
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002730 addr = mCodeEmitter->lookup(name);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002731 return addr;
2732 }
2733
Zonr Chang932648d2010-10-13 22:23:56 +08002734 // Interface for bccGetExportVars()
2735 void getExportVars(BCCsizei *actualVarCount,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002736 BCCsizei maxVarCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002737 BCCvoid **vars) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002738 int varCount = mExportVars.size();
2739
Zonr Chang932648d2010-10-13 22:23:56 +08002740 if (actualVarCount)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002741 *actualVarCount = varCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002742 if (varCount > maxVarCount)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002743 varCount = maxVarCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002744 if (vars)
2745 for (ExportVarList::const_iterator I = mExportVars.begin(),
2746 E = mExportVars.end();
2747 I != E;
2748 I++)
2749 *vars++ = *I;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002750
2751 return;
2752 }
2753
Zonr Chang932648d2010-10-13 22:23:56 +08002754 // Interface for bccGetExportFuncs()
2755 void getExportFuncs(BCCsizei *actualFuncCount,
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002756 BCCsizei maxFuncCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002757 BCCvoid **funcs) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002758 int funcCount = mExportFuncs.size();
2759
Zonr Chang932648d2010-10-13 22:23:56 +08002760 if (actualFuncCount)
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002761 *actualFuncCount = funcCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002762 if (funcCount > maxFuncCount)
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002763 funcCount = maxFuncCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002764 if (funcs)
2765 for (ExportFuncList::const_iterator I = mExportFuncs.begin(),
2766 E = mExportFuncs.end();
2767 I != E;
2768 I++)
2769 *funcs++ = *I;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002770
2771 return;
2772 }
2773
Zonr Chang932648d2010-10-13 22:23:56 +08002774 // Interface for bccGetPragmas()
2775 void getPragmas(BCCsizei *actualStringCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002776 BCCsizei maxStringCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002777 BCCchar **strings) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002778 int stringCount = mPragmas.size() * 2;
2779
Zonr Chang932648d2010-10-13 22:23:56 +08002780 if (actualStringCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002781 *actualStringCount = stringCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002782 if (stringCount > maxStringCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002783 stringCount = maxStringCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002784 if (strings)
2785 for (PragmaList::const_iterator it = mPragmas.begin();
2786 stringCount > 0;
2787 stringCount -= 2, it++) {
2788 *strings++ = const_cast<BCCchar*>(it->first.c_str());
2789 *strings++ = const_cast<BCCchar*>(it->second.c_str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002790 }
2791
2792 return;
2793 }
2794
Zonr Chang932648d2010-10-13 22:23:56 +08002795 // Interface for bccGetFunctions()
2796 void getFunctions(BCCsizei *actualFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002797 BCCsizei maxFunctionCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002798 BCCchar **functions) {
2799 if (mCodeEmitter.get())
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002800 mCodeEmitter->getFunctionNames(actualFunctionCount,
2801 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002802 functions);
2803 else
2804 *actualFunctionCount = 0;
2805
2806 return;
2807 }
2808
Zonr Chang932648d2010-10-13 22:23:56 +08002809 // Interface for bccGetFunctionBinary()
2810 void getFunctionBinary(BCCchar *function,
2811 BCCvoid **base,
2812 BCCsizei *length) {
2813 if (mCodeEmitter.get()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002814 mCodeEmitter->getFunctionBinary(function, base, length);
2815 } else {
2816 *base = NULL;
2817 *length = 0;
2818 }
2819 return;
2820 }
2821
Zonr Chang932648d2010-10-13 22:23:56 +08002822 inline const llvm::Module *getModule() const {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002823 return mModule;
2824 }
2825
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002826 ~Compiler() {
2827 delete mModule;
Zonr Chang932648d2010-10-13 22:23:56 +08002828 // llvm::llvm_shutdown();
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002829 delete mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002830 return;
2831 }
Zonr Chang932648d2010-10-13 22:23:56 +08002832};
2833// End of Class Compiler
2834////////////////////////////////////////////////////////////////////////////////
2835
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002836
2837bool Compiler::GlobalInitialized = false;
2838
Zonr Chang932648d2010-10-13 22:23:56 +08002839// Code generation optimization level for the compiler
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002840llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
2841
2842std::string Compiler::Triple;
2843
2844std::string Compiler::CPU;
2845
2846std::vector<std::string> Compiler::Features;
2847
Zonr Chang932648d2010-10-13 22:23:56 +08002848// The named of metadata node that pragma resides (should be synced with
2849// slang.cpp)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002850const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
2851
Zonr Chang932648d2010-10-13 22:23:56 +08002852// The named of metadata node that export variable name resides (should be
2853// synced with slang_rs_metadata.h)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002854const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
2855
Zonr Chang932648d2010-10-13 22:23:56 +08002856// The named of metadata node that export function name resides (should be
2857// synced with slang_rs_metadata.h)
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002858const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
2859
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002860struct BCCscript {
Zonr Chang932648d2010-10-13 22:23:56 +08002861 //////////////////////////////////////////////////////////////////////////////
2862 // Part I. Compiler
2863 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002864 Compiler compiler;
2865
Zonr Chang932648d2010-10-13 22:23:56 +08002866 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002867 compiler.registerSymbolCallback(pFn, pContext);
2868 }
2869
Zonr Chang932648d2010-10-13 22:23:56 +08002870 //////////////////////////////////////////////////////////////////////////////
2871 // Part II. Logistics & Error handling
2872 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002873 BCCscript() {
2874 bccError = BCC_NO_ERROR;
2875 }
2876
2877 ~BCCscript() {
2878 }
2879
2880 void setError(BCCenum error) {
2881 if (bccError == BCC_NO_ERROR && error != BCC_NO_ERROR) {
2882 bccError = error;
2883 }
2884 }
2885
2886 BCCenum getError() {
2887 BCCenum result = bccError;
2888 bccError = BCC_NO_ERROR;
2889 return result;
2890 }
2891
2892 BCCenum bccError;
2893};
2894
2895
2896extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002897BCCscript *bccCreateScript() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002898 return new BCCscript();
2899}
2900
2901extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002902BCCenum bccGetError(BCCscript *script) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002903 return script->getError();
2904}
2905
2906extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002907void bccDeleteScript(BCCscript *script) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002908 delete script;
2909}
2910
2911extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002912void bccRegisterSymbolCallback(BCCscript *script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002913 BCCSymbolLookupFn pFn,
Zonr Chang932648d2010-10-13 22:23:56 +08002914 BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002915 script->registerSymbolCallback(pFn, pContext);
2916}
2917
2918extern "C"
Zonr Changdbee68b2010-10-22 05:02:16 +08002919void bccScriptModule(BCCscript *script,
2920 BCCvoid *module) {
2921 script->compiler.loadModule(reinterpret_cast<llvm::Module*>(module));
2922}
2923
2924extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002925void bccScriptBitcode(BCCscript *script,
2926 const BCCchar *bitcode,
2927 BCCint size) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002928 script->compiler.loadModule(bitcode, size);
2929}
2930
2931extern "C"
Zonr Chang97f5e612010-10-22 20:38:26 +08002932void bccLinkBitcode(BCCscript *script,
2933 const BCCchar *bitcode,
2934 BCCint size) {
2935 script->compiler.linkModule(bitcode, size);
2936}
2937
2938extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002939void bccCompileScript(BCCscript *script) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002940 int result = script->compiler.compile();
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002941 if (result)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002942 script->setError(BCC_INVALID_OPERATION);
2943}
2944
2945extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002946void bccGetScriptInfoLog(BCCscript *script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002947 BCCsizei maxLength,
Zonr Chang932648d2010-10-13 22:23:56 +08002948 BCCsizei *length,
2949 BCCchar *infoLog) {
2950 char *message = script->compiler.getErrorMessage();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002951 int messageLength = strlen(message) + 1;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002952 if (length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002953 *length = messageLength;
2954
2955 if (infoLog && maxLength > 0) {
2956 int trimmedLength = maxLength < messageLength ? maxLength : messageLength;
2957 memcpy(infoLog, message, trimmedLength);
2958 infoLog[trimmedLength] = 0;
2959 }
2960}
2961
2962extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002963void bccGetScriptLabel(BCCscript *script,
2964 const BCCchar *name,
2965 BCCvoid **address) {
2966 void *value = script->compiler.lookup(name);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002967 if (value)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002968 *address = value;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002969 else
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002970 script->setError(BCC_INVALID_VALUE);
2971}
2972
2973extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002974void bccGetExportVars(BCCscript *script,
2975 BCCsizei *actualVarCount,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002976 BCCsizei maxVarCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002977 BCCvoid **vars) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002978 script->compiler.getExportVars(actualVarCount, maxVarCount, vars);
2979}
2980
2981extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002982void bccGetExportFuncs(BCCscript *script,
2983 BCCsizei *actualFuncCount,
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002984 BCCsizei maxFuncCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002985 BCCvoid **funcs) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002986 script->compiler.getExportFuncs(actualFuncCount, maxFuncCount, funcs);
2987}
2988
2989extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002990void bccGetPragmas(BCCscript *script,
2991 BCCsizei *actualStringCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002992 BCCsizei maxStringCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002993 BCCchar **strings) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002994 script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
2995}
2996
2997extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002998void bccGetFunctions(BCCscript *script,
2999 BCCsizei *actualFunctionCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003000 BCCsizei maxFunctionCount,
Zonr Chang932648d2010-10-13 22:23:56 +08003001 BCCchar **functions) {
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003002 script->compiler.getFunctions(actualFunctionCount,
3003 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003004 functions);
3005}
3006
3007extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08003008void bccGetFunctionBinary(BCCscript *script,
3009 BCCchar *function,
3010 BCCvoid **base,
3011 BCCsizei *length) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003012 script->compiler.getFunctionBinary(function, base, length);
3013}
3014
3015struct BCCtype {
Zonr Chang932648d2010-10-13 22:23:56 +08003016 const Compiler *compiler;
3017 const llvm::Type *t;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003018};
3019
Zonr Chang932648d2010-10-13 22:23:56 +08003020} // namespace bcc