blob: 1f6562571a0db4a83b3149ab81d2e28e46add9df [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
177
Zonr Chang932648d2010-10-13 22:23:56 +0800178//
179// Compilation class that suits Android's needs.
180// (Support: no argument passed, ...)
181//
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700182namespace bcc {
183
184class Compiler {
Zonr Chang932648d2010-10-13 22:23:56 +0800185 // This part is designed to be orthogonal to those exported bcc*() functions
186 // implementation and internal struct BCCscript.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700187
Zonr Chang932648d2010-10-13 22:23:56 +0800188 //////////////////////////////////////////////////////////////////////////////
189 // The variable section below (e.g., Triple, CodeGenOptLevel)
190 // is initialized in GlobalInitialization()
191 //
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700192 static bool GlobalInitialized;
193
Zonr Chang932648d2010-10-13 22:23:56 +0800194 // If given, this will be the name of the target triple to compile for.
195 // If not given, the initial values defined in this file will be used.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700196 static std::string Triple;
197
198 static llvm::CodeGenOpt::Level CodeGenOptLevel;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700199
Zonr Chang932648d2010-10-13 22:23:56 +0800200 // End of section of GlobalInitializing variables
201 //////////////////////////////////////////////////////////////////////////////
202
203 // If given, the name of the target CPU to generate code for.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700204 static std::string CPU;
205
Zonr Chang932648d2010-10-13 22:23:56 +0800206 // The list of target specific features to enable or disable -- this should
207 // be a list of strings starting with '+' (enable) or '-' (disable).
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700208 static std::vector<std::string> Features;
209
210 struct Runtime {
Zonr Chang932648d2010-10-13 22:23:56 +0800211 const char *mName;
212 void *mPtr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700213 };
214 static struct Runtime Runtimes[];
215
216 static void GlobalInitialization() {
Zonr Chang932648d2010-10-13 22:23:56 +0800217 if (GlobalInitialized)
218 return;
Shih-wei Liaobe5c5312010-05-09 05:30:09 -0700219
Zonr Chang932648d2010-10-13 22:23:56 +0800220 // if (!llvm::llvm_is_multithreaded())
221 // llvm::llvm_start_multithreaded();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700222
Zonr Chang932648d2010-10-13 22:23:56 +0800223 // Set Triple, CPU and Features here
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700224 Triple = TARGET_TRIPLE_STRING;
225
Zonr Chang932648d2010-10-13 22:23:56 +0800226 // TODO(zonr): NEON for JIT
227 // Features.push_back("+neon");
228 // Features.push_back("+vmlx");
229 // Features.push_back("+neonfp");
Shih-wei Liao3cf39d12010-04-29 19:30:51 -0700230 Features.push_back("+vfp3");
Shih-wei Liao21ef3072010-10-23 22:33:12 -0700231 Features.push_back("+d16");
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700232
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700233#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
234 LLVMInitializeARMTargetInfo();
235 LLVMInitializeARMTarget();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700236#if defined(USE_DISASSEMBLER)
237 LLVMInitializeARMDisassembler();
238 LLVMInitializeARMAsmPrinter();
239#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700240#endif
241
242#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
243 LLVMInitializeX86TargetInfo();
244 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700245#if defined(USE_DISASSEMBLER)
246 LLVMInitializeX86Disassembler();
247 LLVMInitializeX86AsmPrinter();
248#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700249#endif
250
251#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
252 LLVMInitializeX86TargetInfo();
253 LLVMInitializeX86Target();
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700254#if defined(USE_DISASSEMBLER)
255 LLVMInitializeX86Disassembler();
256 LLVMInitializeX86AsmPrinter();
257#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700258#endif
259
Zonr Chang932648d2010-10-13 22:23:56 +0800260 // -O0: llvm::CodeGenOpt::None
261 // -O1: llvm::CodeGenOpt::Less
262 // -O2: llvm::CodeGenOpt::Default
263 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liaobfda6c92010-10-24 02:43:04 -0700264 CodeGenOptLevel = llvm::CodeGenOpt::None;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700265
Zonr Chang932648d2010-10-13 22:23:56 +0800266 // Below are the global settings to LLVM
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700267
Zonr Chang932648d2010-10-13 22:23:56 +0800268 // Disable frame pointer elimination optimization
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700269 llvm::NoFramePointerElim = false;
270
Zonr Chang932648d2010-10-13 22:23:56 +0800271 // Use hardfloat ABI
272 //
273 // FIXME: Need to detect the CPU capability and decide whether to use
274 // softfp. To use softfp, change following 2 lines to
275 //
276 // llvm::FloatABIType = llvm::FloatABI::Soft;
277 // llvm::UseSoftFloat = true;
278 //
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700279 llvm::FloatABIType = llvm::FloatABI::Soft;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700280 llvm::UseSoftFloat = false;
281
Zonr Chang932648d2010-10-13 22:23:56 +0800282 // BCC needs all unknown symbols resolved at JIT/compilation time.
283 // So we don't need any dynamic relocation model.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700284 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
285
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700286#if defined(DEFAULT_X64_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +0800287 // Data address in X86_64 architecture may reside in a far-away place
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700288 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
289#else
Zonr Chang932648d2010-10-13 22:23:56 +0800290 // This is set for the linker (specify how large of the virtual addresses
291 // we can access for all unknown symbols.)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700292 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
293#endif
294
Zonr Chang932648d2010-10-13 22:23:56 +0800295 // Register the scheduler
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700296 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
297
Zonr Chang932648d2010-10-13 22:23:56 +0800298 // Register allocation policy:
299 // createFastRegisterAllocator: fast but bad quality
300 // createLinearScanRegisterAllocator: not so fast but good quality
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700301 llvm::RegisterRegAlloc::setDefault
302 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
Shih-wei Liao16016012010-09-10 17:55:03 -0700303 llvm::createFastRegisterAllocator :
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700304 llvm::createLinearScanRegisterAllocator);
305
306 GlobalInitialized = true;
307 return;
308 }
309
310 static void LLVMErrorHandler(void *UserData, const std::string &Message) {
Zonr Chang932648d2010-10-13 22:23:56 +0800311 std::string *Error = static_cast<std::string*>(UserData);
Shih-wei Liao066d5ef2010-05-11 03:28:39 -0700312 Error->assign(Message);
Nick Kralevichfc97e9f2010-05-17 14:59:16 -0700313 LOGE("%s", Message.c_str());
Zonr Chang932648d2010-10-13 22:23:56 +0800314 exit(1);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700315 }
316
317 static const llvm::StringRef PragmaMetadataName;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700318 static const llvm::StringRef ExportVarMetadataName;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700319 static const llvm::StringRef ExportFuncMetadataName;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700320
321 private:
Shih-wei Liaoc5611992010-05-09 06:37:55 -0700322 std::string mError;
323
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700324 inline bool hasError() const {
325 return !mError.empty();
326 }
Zonr Chang932648d2010-10-13 22:23:56 +0800327 inline void setError(const char *Error) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700328 mError.assign(Error); // Copying
329 return;
330 }
Zonr Chang932648d2010-10-13 22:23:56 +0800331 inline void setError(const std::string &Error) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700332 mError = Error;
333 return;
334 }
335
336 typedef std::list< std::pair<std::string, std::string> > PragmaList;
337 PragmaList mPragmas;
338
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700339 typedef std::list<void*> ExportVarList;
340 ExportVarList mExportVars;
341
Shih-wei Liao6bfd5422010-05-07 05:20:22 -0700342 typedef std::list<void*> ExportFuncList;
343 ExportFuncList mExportFuncs;
344
Zonr Chang932648d2010-10-13 22:23:56 +0800345 //////////////////////////////////////////////////////////////////////////////
346 // Memory manager for the code reside in memory
347 //
348 // The memory for our code emitter is very simple and is conforming to the
349 // design decisions of Android RenderScript's Exection Environment:
350 // The code, data, and symbol sizes are limited (currently 100KB.)
351 //
352 // It's very different from typical compiler, which has no limitation
353 // on the code size. How does code emitter know the size of the code
354 // it is about to emit? It does not know beforehand. We want to solve
355 // this without complicating the code emitter too much.
356 //
357 // We solve this by pre-allocating a certain amount of memory,
358 // and then start the code emission. Once the buffer overflows, the emitter
359 // simply discards all the subsequent emission but still has a counter
360 // on how many bytes have been emitted.
361 //
362 // So once the whole emission is done, if there's a buffer overflow,
363 // it re-allocates the buffer with enough size (based on the
364 // counter from previous emission) and re-emit again.
365 //
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700366 class CodeMemoryManager : public llvm::JITMemoryManager {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700367 private:
Zonr Chang932648d2010-10-13 22:23:56 +0800368 // 128 KiB for code
369 static const unsigned int MaxCodeSize = 128 * 1024;
370 // 1 KiB for global offset table (GOT)
371 static const unsigned int MaxGOTSize = 1 * 1024;
372 // 128 KiB for global variable
373 static const unsigned int MaxGlobalVarSize = 128 * 1024;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700374
Zonr Chang932648d2010-10-13 22:23:56 +0800375 //
376 // Our memory layout is as follows:
377 //
378 // The direction of arrows (-> and <-) shows memory's growth direction
379 // when more space is needed.
380 //
381 // @mpCodeMem:
382 // +--------------------------------------------------------------+
383 // | Function Memory ... -> <- ... Stub/GOT |
384 // +--------------------------------------------------------------+
385 // |<------------------ Total: @MaxCodeSize KiB ----------------->|
386 //
387 // Where size of GOT is @MaxGOTSize KiB.
388 //
389 // @mpGVMem:
390 // +--------------------------------------------------------------+
391 // | Global variable ... -> |
392 // +--------------------------------------------------------------+
393 // |<--------------- Total: @MaxGlobalVarSize KiB --------------->|
394 //
395 //
396 // @mCurFuncMemIdx: The current index (starting from 0) of the last byte
397 // of function code's memory usage
398 // @mCurSGMemIdx: The current index (starting from tail) of the last byte
399 // of stub/GOT's memory usage
400 // @mCurGVMemIdx: The current index (starting from tail) of the last byte
401 // of global variable's memory usage
402 //
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700403 uintptr_t mCurFuncMemIdx;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700404 uintptr_t mCurSGMemIdx;
405 uintptr_t mCurGVMemIdx;
Zonr Chang932648d2010-10-13 22:23:56 +0800406 void *mpCodeMem;
407 void *mpGVMem;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700408
Zonr Chang932648d2010-10-13 22:23:56 +0800409 // GOT Base
410 uint8_t *mpGOTBase;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700411
412 typedef std::map<const llvm::Function*, pair<void* /* start address */,
413 void* /* end address */>
414 > FunctionMapTy;
415 FunctionMapTy mFunctionMap;
416
Zonr Chang932648d2010-10-13 22:23:56 +0800417 inline intptr_t getFreeCodeMemSize() const {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700418 return mCurSGMemIdx - mCurFuncMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700419 }
Zonr Chang932648d2010-10-13 22:23:56 +0800420 inline uint8_t *getCodeMemBase() const {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700421 return reinterpret_cast<uint8_t*>(mpCodeMem);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700422 }
423
Zonr Chang932648d2010-10-13 22:23:56 +0800424 uint8_t *allocateSGMemory(uintptr_t Size,
425 unsigned Alignment = 1 /* no alignment */) {
426 intptr_t FreeMemSize = getFreeCodeMemSize();
427 if ((FreeMemSize < 0) || (static_cast<uintptr_t>(FreeMemSize) < Size))
428 // The code size excesses our limit
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700429 return NULL;
430
Zonr Chang932648d2010-10-13 22:23:56 +0800431 if (Alignment == 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700432 Alignment = 1;
433
Zonr Chang932648d2010-10-13 22:23:56 +0800434 uint8_t *result = getCodeMemBase() + mCurSGMemIdx - Size;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700435 result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
436
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700437 mCurSGMemIdx = result - getCodeMemBase();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700438
439 return result;
440 }
441
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700442 inline uintptr_t getFreeGVMemSize() const {
443 return MaxGlobalVarSize - mCurGVMemIdx;
444 }
Zonr Chang932648d2010-10-13 22:23:56 +0800445 inline uint8_t *getGVMemBase() const {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700446 return reinterpret_cast<uint8_t*>(mpGVMem);
447 }
448
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700449 public:
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700450 CodeMemoryManager() : mpCodeMem(NULL), mpGVMem(NULL), mpGOTBase(NULL) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700451 reset();
452 std::string ErrMsg;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700453
Shih-wei Liaoc7c9cd52010-09-27 11:23:25 -0700454 mpCodeMem = ::mmap(NULL, MaxCodeSize, PROT_READ | PROT_EXEC,
Ying Wang78db12e2010-09-25 17:48:59 -0700455 MAP_PRIVATE | MAP_ANON, -1, 0);
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700456 if (mpCodeMem == MAP_FAILED)
Zonr Chang932648d2010-10-13 22:23:56 +0800457 llvm::report_fatal_error("Failed to allocate memory for emitting "
458 "function codes\n" + ErrMsg);
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700459
460 mpGVMem = ::mmap(mpCodeMem, MaxGlobalVarSize,
Shih-wei Liaoc7c9cd52010-09-27 11:23:25 -0700461 PROT_READ | PROT_WRITE,
Ying Wang78db12e2010-09-25 17:48:59 -0700462 MAP_PRIVATE | MAP_ANON, -1, 0);
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700463 if (mpGVMem == MAP_FAILED)
Zonr Chang932648d2010-10-13 22:23:56 +0800464 llvm::report_fatal_error("Failed to allocate memory for emitting "
465 "global variables\n" + ErrMsg);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700466
467 return;
468 }
469
Zonr Chang932648d2010-10-13 22:23:56 +0800470 // setMemoryWritable - When code generation is in progress, the code pages
471 // may need permissions changed.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700472 void setMemoryWritable() {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700473 ::mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700474 return;
475 }
476
Zonr Chang932648d2010-10-13 22:23:56 +0800477 // When code generation is done and we're ready to start execution, the
478 // code pages may need permissions changed.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700479 void setMemoryExecutable() {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700480 ::mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_EXEC);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700481 return;
482 }
483
Zonr Chang932648d2010-10-13 22:23:56 +0800484 // Setting this flag to true makes the memory manager garbage values over
485 // freed memory. This is useful for testing and debugging, and is to be
486 // turned on by default in debug mode.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700487 void setPoisonMemory(bool poison) {
Zonr Chang932648d2010-10-13 22:23:56 +0800488 // no effect
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700489 return;
490 }
491
Zonr Chang932648d2010-10-13 22:23:56 +0800492 // Global Offset Table Management
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700493
Zonr Chang932648d2010-10-13 22:23:56 +0800494 // If the current table requires a Global Offset Table, this method is
495 // invoked to allocate it. This method is required to set HasGOT to true.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700496 void AllocateGOT() {
497 assert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700498 mpGOTBase = allocateSGMemory(MaxGOTSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700499 HasGOT = true;
500 return;
501 }
502
Zonr Chang932648d2010-10-13 22:23:56 +0800503 // If this is managing a Global Offset Table, this method should return a
504 // pointer to its base.
505 uint8_t *getGOTBase() const {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700506 return mpGOTBase;
507 }
508
Zonr Chang932648d2010-10-13 22:23:56 +0800509 // Main Allocation Functions
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700510
Zonr Chang932648d2010-10-13 22:23:56 +0800511 // When we start JITing a function, the JIT calls this method to allocate a
512 // block of free RWX memory, which returns a pointer to it. If the JIT wants
513 // to request a block of memory of at least a certain size, it passes that
514 // value as ActualSize, and this method returns a block with at least that
515 // much space. If the JIT doesn't know ahead of time how much space it will
516 // need to emit the function, it passes 0 for the ActualSize. In either
517 // case, this method is required to pass back the size of the allocated
518 // block through ActualSize. The JIT will be careful to not write more than
519 // the returned ActualSize bytes of memory.
520 uint8_t *startFunctionBody(const llvm::Function *F, uintptr_t &ActualSize) {
521 intptr_t FreeMemSize = getFreeCodeMemSize();
522 if ((FreeMemSize < 0) ||
523 (static_cast<uintptr_t>(FreeMemSize) < ActualSize))
524 // The code size excesses our limit
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700525 return NULL;
526
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700527 ActualSize = getFreeCodeMemSize();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700528 return (getCodeMemBase() + mCurFuncMemIdx);
529 }
530
Zonr Chang932648d2010-10-13 22:23:56 +0800531 // This method is called by the JIT to allocate space for a function stub
532 // (used to handle limited branch displacements) while it is JIT compiling a
533 // function. For example, if foo calls bar, and if bar either needs to be
534 // lazily compiled or is a native function that exists too far away from the
535 // call site to work, this method will be used to make a thunk for it. The
536 // stub should be "close" to the current function body, but should not be
537 // included in the 'actualsize' returned by startFunctionBody.
538 uint8_t *allocateStub(const llvm::GlobalValue *F, unsigned StubSize,
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700539 unsigned Alignment) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700540 return allocateSGMemory(StubSize, Alignment);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700541 }
542
Zonr Chang932648d2010-10-13 22:23:56 +0800543 // This method is called when the JIT is done codegen'ing the specified
544 // function. At this point we know the size of the JIT compiled function.
545 // This passes in FunctionStart (which was returned by the startFunctionBody
546 // method) and FunctionEnd which is a pointer to the actual end of the
547 // function. This method should mark the space allocated and remember where
548 // it is in case the client wants to deallocate it.
549 void endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
550 uint8_t *FunctionEnd) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700551 assert(FunctionEnd > FunctionStart);
552 assert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
553 "Mismatched function start/end!");
554
Zonr Chang932648d2010-10-13 22:23:56 +0800555 // Advance the pointer
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700556 intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700557 assert(FunctionCodeSize <= getFreeCodeMemSize() &&
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700558 "Code size excess the limitation!");
559 mCurFuncMemIdx += FunctionCodeSize;
560
Zonr Chang932648d2010-10-13 22:23:56 +0800561 // Record there's a function in our memory start from @FunctionStart
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700562 assert(mFunctionMap.find(F) == mFunctionMap.end() &&
563 "Function already emitted!");
Zonr Chang932648d2010-10-13 22:23:56 +0800564 mFunctionMap.insert(
565 std::make_pair<const llvm::Function*, std::pair<void*, void*> >(
566 F, std::make_pair(FunctionStart, FunctionEnd)));
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700567
568 return;
569 }
570
Zonr Chang932648d2010-10-13 22:23:56 +0800571 // Allocate a (function code) memory block of the given size. This method
572 // cannot be called between calls to startFunctionBody and endFunctionBody.
573 uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
574 if (getFreeCodeMemSize() < Size)
575 // The code size excesses our limit
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700576 return NULL;
577
Zonr Chang932648d2010-10-13 22:23:56 +0800578 if (Alignment == 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700579 Alignment = 1;
580
Zonr Chang932648d2010-10-13 22:23:56 +0800581 uint8_t *result = getCodeMemBase() + mCurFuncMemIdx;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700582 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
Zonr Chang932648d2010-10-13 22:23:56 +0800583 ~(intptr_t) (Alignment - 1));
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700584
585 mCurFuncMemIdx = (result + Size) - getCodeMemBase();
586
587 return result;
588 }
589
Zonr Chang932648d2010-10-13 22:23:56 +0800590 // Allocate memory for a global variable.
591 uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700592 if (getFreeGVMemSize() < Size) {
Zonr Chang932648d2010-10-13 22:23:56 +0800593 // The code size excesses our limit
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700594 LOGE("No Global Memory");
595 return NULL;
596 }
597
Zonr Chang932648d2010-10-13 22:23:56 +0800598 if (Alignment == 0)
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700599 Alignment = 1;
600
Zonr Chang932648d2010-10-13 22:23:56 +0800601 uint8_t *result = getGVMemBase() + mCurGVMemIdx;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700602 result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
Zonr Chang932648d2010-10-13 22:23:56 +0800603 ~(intptr_t) (Alignment - 1));
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700604
605 mCurGVMemIdx = (result + Size) - getGVMemBase();
606
607 return result;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700608 }
609
Zonr Chang932648d2010-10-13 22:23:56 +0800610 // Free the specified function body. The argument must be the return value
611 // from a call to startFunctionBody() that hasn't been deallocated yet. This
612 // is never called when the JIT is currently emitting a function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700613 void deallocateFunctionBody(void *Body) {
Zonr Chang932648d2010-10-13 22:23:56 +0800614 // linear search
615 uint8_t *FunctionStart = NULL, *FunctionEnd = NULL;
616 for (FunctionMapTy::iterator I = mFunctionMap.begin(),
617 E = mFunctionMap.end();
618 I != E;
619 I++)
620 if (I->second.first == Body) {
621 FunctionStart = reinterpret_cast<uint8_t*>(I->second.first);
622 FunctionEnd = reinterpret_cast<uint8_t*>(I->second.second);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700623 break;
Zonr Chang932648d2010-10-13 22:23:56 +0800624 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700625
Zonr Chang932648d2010-10-13 22:23:56 +0800626 assert((FunctionStart == NULL) && "Memory is never allocated!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700627
Zonr Chang932648d2010-10-13 22:23:56 +0800628 // free the memory
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700629 intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
630
631 assert(SizeNeedMove >= 0 &&
632 "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
633 " be correctly calculated!");
634
Zonr Chang932648d2010-10-13 22:23:56 +0800635 if (SizeNeedMove > 0)
636 // there's data behind deallocating function
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700637 ::memmove(FunctionStart, FunctionEnd, SizeNeedMove);
638 mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
639
640 return;
641 }
642
Zonr Chang932648d2010-10-13 22:23:56 +0800643 // When we finished JITing the function, if exception handling is set, we
644 // emit the exception table.
645 uint8_t *startExceptionTable(const llvm::Function *F,
646 uintptr_t &ActualSize) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700647 assert(false && "Exception is not allowed in our language specification");
648 return NULL;
649 }
650
Zonr Chang932648d2010-10-13 22:23:56 +0800651 // This method is called when the JIT is done emitting the exception table.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700652 void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
Zonr Chang932648d2010-10-13 22:23:56 +0800653 uint8_t *TableEnd, uint8_t *FrameRegister) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700654 assert(false && "Exception is not allowed in our language specification");
655 return;
656 }
657
Zonr Chang932648d2010-10-13 22:23:56 +0800658 // Free the specified exception table's memory. The argument must be the
659 // return value from a call to startExceptionTable() that hasn't been
660 // deallocated yet. This is never called when the JIT is currently emitting
661 // an exception table.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700662 void deallocateExceptionTable(void *ET) {
663 assert(false && "Exception is not allowed in our language specification");
664 return;
665 }
666
Zonr Chang932648d2010-10-13 22:23:56 +0800667 // Below are the methods we create
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700668 void reset() {
669 mpGOTBase = NULL;
670 HasGOT = false;
671
672 mCurFuncMemIdx = 0;
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700673 mCurSGMemIdx = MaxCodeSize - 1;
674 mCurGVMemIdx = 0;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700675
676 mFunctionMap.clear();
677
678 return;
679 }
680
681 ~CodeMemoryManager() {
Zonr Chang932648d2010-10-13 22:23:56 +0800682 if (mpCodeMem != NULL)
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700683 ::munmap(mpCodeMem, MaxCodeSize);
Zonr Chang932648d2010-10-13 22:23:56 +0800684 if (mpGVMem != NULL)
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -0700685 ::munmap(mpGVMem, MaxGlobalVarSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700686 return;
687 }
Zonr Chang932648d2010-10-13 22:23:56 +0800688 };
689 // End of class CodeMemoryManager
690 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700691
Zonr Chang932648d2010-10-13 22:23:56 +0800692 // The memory manager for code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700693 llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
Zonr Chang932648d2010-10-13 22:23:56 +0800694 CodeMemoryManager *createCodeMemoryManager() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700695 mCodeMemMgr.reset(new CodeMemoryManager());
696 return mCodeMemMgr.get();
697 }
698
Zonr Chang932648d2010-10-13 22:23:56 +0800699 //////////////////////////////////////////////////////////////////////////////
700 // Code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700701 class CodeEmitter : public llvm::JITCodeEmitter {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700702 public:
703 typedef llvm::DenseMap<const llvm::GlobalValue*, void*> GlobalAddressMapTy;
704 typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
705
706 private:
Zonr Chang932648d2010-10-13 22:23:56 +0800707 CodeMemoryManager *mpMemMgr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700708
Zonr Chang932648d2010-10-13 22:23:56 +0800709 // The JITInfo for the target we are compiling to
710 const llvm::Target *mpTarget;
Shih-wei Liaocd61af32010-04-29 00:02:57 -0700711
Zonr Chang932648d2010-10-13 22:23:56 +0800712 llvm::TargetJITInfo *mpTJI;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700713
Zonr Chang932648d2010-10-13 22:23:56 +0800714 const llvm::TargetData *mpTD;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700715
716 class EmittedFunctionCode {
717 public:
Zonr Chang932648d2010-10-13 22:23:56 +0800718 // Beginning of the function's allocation.
719 void *FunctionBody;
720
721 // The address the function's code actually starts at.
722 void *Code;
723
724 // The size of the function code
725 int Size;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700726
727 EmittedFunctionCode() : FunctionBody(NULL), Code(NULL) { return; }
728 };
Zonr Chang932648d2010-10-13 22:23:56 +0800729 EmittedFunctionCode *mpCurEmitFunction;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700730
Zonr Chang932648d2010-10-13 22:23:56 +0800731 typedef std::map<const std::string,
732 EmittedFunctionCode*> EmittedFunctionsMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700733 EmittedFunctionsMapTy mEmittedFunctions;
734
Zonr Chang932648d2010-10-13 22:23:56 +0800735 // This vector is a mapping from MBB ID's to their address. It is filled in
736 // by the StartMachineBasicBlock callback and queried by the
737 // getMachineBasicBlockAddress callback.
738 std::vector<uintptr_t> mMBBLocations;
739
740 // The constant pool for the current function.
741 llvm::MachineConstantPool *mpConstantPool;
742
743 // A pointer to the first entry in the constant pool.
744 void *mpConstantPoolBase;
745
746 // Addresses of individual constant pool entries.
747 llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
748
749 // The jump tables for the current function.
750 llvm::MachineJumpTableInfo *mpJumpTable;
751
752 // A pointer to the first entry in the jump table.
753 void *mpJumpTableBase;
754
755 // When outputting a function stub in the context of some other function, we
756 // save BufferBegin/BufferEnd/CurBufferPtr here.
757 uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
758
759 // These are the relocations that the function needs, as emitted.
760 std::vector<llvm::MachineRelocation> mRelocations;
761
762 // This vector is a mapping from Label ID's to their address.
763 llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
764
765 // Machine module info for exception informations
766 llvm::MachineModuleInfo *mpMMI;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700767
768 GlobalAddressMapTy mGlobalAddressMap;
769
Zonr Chang932648d2010-10-13 22:23:56 +0800770 // Replace an existing mapping for GV with a new address. This updates both
771 // maps as required. If Addr is null, the entry for the global is removed
772 // from the mappings.
773 void *UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
774 if (Addr == NULL) {
775 // Removing mapping
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700776 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
777 void *OldVal;
778
Zonr Chang932648d2010-10-13 22:23:56 +0800779 if (I == mGlobalAddressMap.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700780 OldVal = NULL;
Zonr Chang932648d2010-10-13 22:23:56 +0800781 } else {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700782 OldVal = I->second;
783 mGlobalAddressMap.erase(I);
784 }
785
786 return OldVal;
787 }
788
Zonr Chang932648d2010-10-13 22:23:56 +0800789 void *&CurVal = mGlobalAddressMap[GV];
790 void *OldVal = CurVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700791
792 CurVal = Addr;
793
794 return OldVal;
795 }
796
Zonr Chang932648d2010-10-13 22:23:56 +0800797 // Tell the execution engine that the specified global is at the specified
798 // location. This is used internally as functions are JIT'd and as global
799 // variables are laid out in memory.
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700800 void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
Zonr Chang932648d2010-10-13 22:23:56 +0800801 void *&CurVal = mGlobalAddressMap[GV];
802 assert((CurVal == 0 || Addr == 0) &&
803 "GlobalMapping already established!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700804 CurVal = Addr;
805 return;
806 }
807
Zonr Chang932648d2010-10-13 22:23:56 +0800808 // This returns the address of the specified global value if it is has
809 // already been codegen'd, otherwise it returns null.
810 void *GetPointerToGlobalIfAvailable(const llvm::GlobalValue *GV) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -0700811 GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700812 return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
813 }
814
Zonr Chang932648d2010-10-13 22:23:56 +0800815 unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool *MCP) {
816 const std::vector<llvm::MachineConstantPoolEntry> &Constants =
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700817 MCP->getConstants();
818
Zonr Chang932648d2010-10-13 22:23:56 +0800819 if (Constants.empty())
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700820 return 0;
821
822 unsigned int Size = 0;
Zonr Chang932648d2010-10-13 22:23:56 +0800823 for (int i = 0, e = Constants.size(); i != e; i++) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700824 llvm::MachineConstantPoolEntry CPE = Constants[i];
825 unsigned int AlignMask = CPE.getAlignment() - 1;
826 Size = (Size + AlignMask) & ~AlignMask;
Zonr Chang932648d2010-10-13 22:23:56 +0800827 const llvm::Type *Ty = CPE.getType();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700828 Size += mpTD->getTypeAllocSize(Ty);
829 }
830
831 return Size;
832 }
833
Zonr Chang932648d2010-10-13 22:23:56 +0800834 // This function converts a Constant* into a GenericValue. The interesting
835 // part is if C is a ConstantExpr.
836 void GetConstantValue(const llvm::Constant *C, llvm::GenericValue &Result) {
837 if (C->getValueID() == llvm::Value::UndefValueVal)
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700838 return;
Zonr Chang932648d2010-10-13 22:23:56 +0800839 else if (C->getValueID() == llvm::Value::ConstantExprVal) {
840 const llvm::ConstantExpr *CE = (llvm::ConstantExpr*) C;
841 const llvm::Constant *Op0 = CE->getOperand(0);
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700842
Zonr Chang932648d2010-10-13 22:23:56 +0800843 switch (CE->getOpcode()) {
844 case llvm::Instruction::GetElementPtr: {
845 // Compute the index
846 llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
847 CE->op_end());
848 uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(),
849 &Indices[0],
850 Indices.size());
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700851
Zonr Chang932648d2010-10-13 22:23:56 +0800852 GetConstantValue(Op0, Result);
853 Result.PointerVal =
854 static_cast<uint8_t*>(Result.PointerVal) + Offset;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700855
Zonr Chang932648d2010-10-13 22:23:56 +0800856 return;
857 }
858 case llvm::Instruction::Trunc: {
859 uint32_t BitWidth =
860 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
861
862 GetConstantValue(Op0, Result);
863 Result.IntVal = Result.IntVal.trunc(BitWidth);
864
865 return;
866 }
867 case llvm::Instruction::ZExt: {
868 uint32_t BitWidth =
869 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
870
871 GetConstantValue(Op0, Result);
872 Result.IntVal = Result.IntVal.zext(BitWidth);
873
874 return;
875 }
876 case llvm::Instruction::SExt: {
877 uint32_t BitWidth =
878 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
879
880 GetConstantValue(Op0, Result);
881 Result.IntVal = Result.IntVal.sext(BitWidth);
882
883 return;
884 }
885 case llvm::Instruction::FPTrunc: {
886 // FIXME: long double
887 GetConstantValue(Op0, Result);
888 Result.FloatVal = static_cast<float>(Result.DoubleVal);
889 return;
890 }
891 case llvm::Instruction::FPExt: {
892 // FIXME: long double
893 GetConstantValue(Op0, Result);
894 Result.DoubleVal = static_cast<double>(Result.FloatVal);
895 return;
896 }
897 case llvm::Instruction::UIToFP: {
898 GetConstantValue(Op0, Result);
899 if (CE->getType()->isFloatTy())
900 Result.FloatVal =
901 static_cast<float>(Result.IntVal.roundToDouble());
902 else if (CE->getType()->isDoubleTy())
903 Result.DoubleVal = Result.IntVal.roundToDouble();
904 else if (CE->getType()->isX86_FP80Ty()) {
905 const uint64_t zero[] = { 0, 0 };
906 llvm::APFloat apf(llvm::APInt(80, 2, zero));
907 apf.convertFromAPInt(Result.IntVal,
908 false,
909 llvm::APFloat::rmNearestTiesToEven);
910 Result.IntVal = apf.bitcastToAPInt();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700911 }
Zonr Chang932648d2010-10-13 22:23:56 +0800912 return;
913 }
914 case llvm::Instruction::SIToFP: {
915 GetConstantValue(Op0, Result);
916 if (CE->getType()->isFloatTy())
917 Result.FloatVal =
918 static_cast<float>(Result.IntVal.signedRoundToDouble());
919 else if (CE->getType()->isDoubleTy())
920 Result.DoubleVal = Result.IntVal.signedRoundToDouble();
921 else if (CE->getType()->isX86_FP80Ty()) {
922 const uint64_t zero[] = { 0, 0 };
923 llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
924 apf.convertFromAPInt(Result.IntVal,
925 true,
926 llvm::APFloat::rmNearestTiesToEven);
927 Result.IntVal = apf.bitcastToAPInt();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700928 }
Zonr Chang932648d2010-10-13 22:23:56 +0800929 return;
930 }
931 // double->APInt conversion handles sign
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700932 case llvm::Instruction::FPToUI:
Zonr Chang932648d2010-10-13 22:23:56 +0800933 case llvm::Instruction::FPToSI: {
934 uint32_t BitWidth =
935 llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700936
Zonr Chang932648d2010-10-13 22:23:56 +0800937 GetConstantValue(Op0, Result);
938 if (Op0->getType()->isFloatTy())
939 Result.IntVal =
940 llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
941 else if (Op0->getType()->isDoubleTy())
942 Result.IntVal =
943 llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal,
944 BitWidth);
945 else if (Op0->getType()->isX86_FP80Ty()) {
946 llvm::APFloat apf = llvm::APFloat(Result.IntVal);
947 uint64_t V;
948 bool Ignored;
949 apf.convertToInteger(&V,
950 BitWidth,
951 CE->getOpcode() == llvm::Instruction::FPToSI,
952 llvm::APFloat::rmTowardZero,
953 &Ignored);
954 Result.IntVal = V; // endian?
955 }
956 return;
957 }
958 case llvm::Instruction::PtrToInt: {
959 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
960
961 GetConstantValue(Op0, Result);
962 Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
963 (Result.PointerVal));
964
965 return;
966 }
967 case llvm::Instruction::IntToPtr: {
968 uint32_t PtrWidth = mpTD->getPointerSizeInBits();
969
970 GetConstantValue(Op0, Result);
971 if (PtrWidth != Result.IntVal.getBitWidth())
972 Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
973 assert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
974
975 Result.PointerVal =
976 llvm::PointerTy(
977 static_cast<uintptr_t>(Result.IntVal.getZExtValue()));
978
979 return;
980 }
981 case llvm::Instruction::BitCast: {
982 GetConstantValue(Op0, Result);
983 const llvm::Type *DestTy = CE->getType();
984
985 switch (Op0->getType()->getTypeID()) {
986 case llvm::Type::IntegerTyID: {
987 assert(DestTy->isFloatingPointTy() && "invalid bitcast");
988 if (DestTy->isFloatTy())
989 Result.FloatVal = Result.IntVal.bitsToFloat();
990 else if (DestTy->isDoubleTy())
991 Result.DoubleVal = Result.IntVal.bitsToDouble();
992 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700993 }
Zonr Chang932648d2010-10-13 22:23:56 +0800994 case llvm::Type::FloatTyID: {
995 assert(DestTy->isIntegerTy(32) && "Invalid bitcast");
996 Result.IntVal.floatToBits(Result.FloatVal);
997 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -0700998 }
Zonr Chang932648d2010-10-13 22:23:56 +0800999 case llvm::Type::DoubleTyID: {
1000 assert(DestTy->isIntegerTy(64) && "Invalid bitcast");
1001 Result.IntVal.doubleToBits(Result.DoubleVal);
1002 break;
1003 }
1004 case llvm::Type::PointerTyID: {
1005 assert(DestTy->isPointerTy() && "Invalid bitcast");
1006 break; // getConstantValue(Op0) above already converted it
1007 }
1008 default: {
1009 llvm_unreachable("Invalid bitcast operand");
1010 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001011 }
Zonr Chang932648d2010-10-13 22:23:56 +08001012 return;
1013 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001014 case llvm::Instruction::Add:
1015 case llvm::Instruction::FAdd:
1016 case llvm::Instruction::Sub:
1017 case llvm::Instruction::FSub:
1018 case llvm::Instruction::Mul:
1019 case llvm::Instruction::FMul:
1020 case llvm::Instruction::UDiv:
1021 case llvm::Instruction::SDiv:
1022 case llvm::Instruction::URem:
1023 case llvm::Instruction::SRem:
1024 case llvm::Instruction::And:
1025 case llvm::Instruction::Or:
Zonr Chang932648d2010-10-13 22:23:56 +08001026 case llvm::Instruction::Xor: {
1027 llvm::GenericValue LHS, RHS;
1028 GetConstantValue(Op0, LHS);
1029 GetConstantValue(CE->getOperand(1), RHS);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001030
Zonr Chang932648d2010-10-13 22:23:56 +08001031 switch (Op0->getType()->getTypeID()) {
1032 case llvm::Type::IntegerTyID: {
1033 switch (CE->getOpcode()) {
1034 case llvm::Instruction::Add: {
1035 Result.IntVal = LHS.IntVal + RHS.IntVal;
1036 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001037 }
Zonr Chang932648d2010-10-13 22:23:56 +08001038 case llvm::Instruction::Sub: {
1039 Result.IntVal = LHS.IntVal - RHS.IntVal;
1040 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001041 }
Zonr Chang932648d2010-10-13 22:23:56 +08001042 case llvm::Instruction::Mul: {
1043 Result.IntVal = LHS.IntVal * RHS.IntVal;
1044 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001045 }
Zonr Chang932648d2010-10-13 22:23:56 +08001046 case llvm::Instruction::UDiv: {
1047 Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
1048 break;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001049 }
Zonr Chang932648d2010-10-13 22:23:56 +08001050 case llvm::Instruction::SDiv: {
1051 Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
1052 break;
1053 }
1054 case llvm::Instruction::URem: {
1055 Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
1056 break;
1057 }
1058 case llvm::Instruction::SRem: {
1059 Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
1060 break;
1061 }
1062 case llvm::Instruction::And: {
1063 Result.IntVal = LHS.IntVal & RHS.IntVal;
1064 break;
1065 }
1066 case llvm::Instruction::Or: {
1067 Result.IntVal = LHS.IntVal | RHS.IntVal;
1068 break;
1069 }
1070 case llvm::Instruction::Xor: {
1071 Result.IntVal = LHS.IntVal ^ RHS.IntVal;
1072 break;
1073 }
1074 default: {
1075 llvm_unreachable("Invalid integer opcode");
1076 }
1077 }
1078 break;
1079 }
1080 case llvm::Type::FloatTyID: {
1081 switch (CE->getOpcode()) {
1082 case llvm::Instruction::FAdd: {
1083 Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
1084 break;
1085 }
1086 case llvm::Instruction::FSub: {
1087 Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
1088 break;
1089 }
1090 case llvm::Instruction::FMul: {
1091 Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
1092 break;
1093 }
1094 case llvm::Instruction::FDiv: {
1095 Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
1096 break;
1097 }
1098 case llvm::Instruction::FRem: {
1099 Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
1100 break;
1101 }
1102 default: {
1103 llvm_unreachable("Invalid float opcode");
1104 }
1105 }
1106 break;
1107 }
1108 case llvm::Type::DoubleTyID: {
1109 switch (CE->getOpcode()) {
1110 case llvm::Instruction::FAdd: {
1111 Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
1112 break;
1113 }
1114 case llvm::Instruction::FSub: {
1115 Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
1116 break;
1117 }
1118 case llvm::Instruction::FMul: {
1119 Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
1120 break;
1121 }
1122 case llvm::Instruction::FDiv: {
1123 Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
1124 break;
1125 }
1126 case llvm::Instruction::FRem: {
1127 Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
1128 break;
1129 }
1130 default: {
1131 llvm_unreachable("Invalid double opcode");
1132 }
1133 }
1134 break;
1135 }
1136 case llvm::Type::X86_FP80TyID:
1137 case llvm::Type::PPC_FP128TyID:
1138 case llvm::Type::FP128TyID: {
1139 llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
1140 switch (CE->getOpcode()) {
1141 case llvm::Instruction::FAdd: {
1142 apfLHS.add(llvm::APFloat(RHS.IntVal),
1143 llvm::APFloat::rmNearestTiesToEven);
1144 break;
1145 }
1146 case llvm::Instruction::FSub: {
1147 apfLHS.subtract(llvm::APFloat(RHS.IntVal),
1148 llvm::APFloat::rmNearestTiesToEven);
1149 break;
1150 }
1151 case llvm::Instruction::FMul: {
1152 apfLHS.multiply(llvm::APFloat(RHS.IntVal),
1153 llvm::APFloat::rmNearestTiesToEven);
1154 break;
1155 }
1156 case llvm::Instruction::FDiv: {
1157 apfLHS.divide(llvm::APFloat(RHS.IntVal),
1158 llvm::APFloat::rmNearestTiesToEven);
1159 break;
1160 }
1161 case llvm::Instruction::FRem: {
1162 apfLHS.mod(llvm::APFloat(RHS.IntVal),
1163 llvm::APFloat::rmNearestTiesToEven);
1164 break;
1165 }
1166 default: {
1167 llvm_unreachable("Invalid long double opcode");
1168 }
1169 }
1170 Result.IntVal = apfLHS.bitcastToAPInt();
1171 break;
1172 }
1173 default: {
1174 llvm_unreachable("Bad add type!");
1175 }
1176 } // End switch (Op0->getType()->getTypeID())
1177 return;
1178 }
1179 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001180 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001181 }
1182 } // End switch (CE->getOpcode())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001183
1184 std::string msg;
1185 llvm::raw_string_ostream Msg(msg);
1186 Msg << "ConstantExpr not handled: " << *CE;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001187 llvm::report_fatal_error(Msg.str());
Zonr Chang932648d2010-10-13 22:23:56 +08001188 } // C->getValueID() == llvm::Value::ConstantExprVal
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001189
1190 switch (C->getType()->getTypeID()) {
Zonr Chang932648d2010-10-13 22:23:56 +08001191 case llvm::Type::FloatTyID: {
1192 Result.FloatVal =
1193 llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToFloat();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001194 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001195 }
1196 case llvm::Type::DoubleTyID: {
1197 Result.DoubleVal =
1198 llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToDouble();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001199 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001200 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001201 case llvm::Type::X86_FP80TyID:
1202 case llvm::Type::FP128TyID:
Zonr Chang932648d2010-10-13 22:23:56 +08001203 case llvm::Type::PPC_FP128TyID: {
1204 Result.IntVal =
1205 llvm::cast<llvm::ConstantFP>(C)->getValueAPF().bitcastToAPInt();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001206 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001207 }
1208 case llvm::Type::IntegerTyID: {
1209 Result.IntVal =
1210 llvm::cast<llvm::ConstantInt>(C)->getValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001211 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001212 }
1213 case llvm::Type::PointerTyID: {
1214 switch (C->getValueID()) {
1215 case llvm::Value::ConstantPointerNullVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001216 Result.PointerVal = NULL;
1217 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001218 }
1219 case llvm::Value::FunctionVal: {
1220 const llvm::Function *F = static_cast<const llvm::Function*>(C);
1221 Result.PointerVal =
1222 GetPointerToFunctionOrStub(const_cast<llvm::Function*>(F));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001223 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001224 }
1225 case llvm::Value::GlobalVariableVal: {
1226 const llvm::GlobalVariable *GV =
1227 static_cast<const llvm::GlobalVariable*>(C);
1228 Result.PointerVal =
1229 GetOrEmitGlobalVariable(const_cast<llvm::GlobalVariable*>(GV));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001230 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001231 }
1232 case llvm::Value::BlockAddressVal: {
1233 assert(false && "JIT does not support address-of-label yet!");
1234 }
1235 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001236 llvm_unreachable("Unknown constant pointer type!");
Zonr Chang932648d2010-10-13 22:23:56 +08001237 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001238 }
1239 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001240 }
1241 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001242 std::string msg;
1243 llvm::raw_string_ostream Msg(msg);
1244 Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001245 llvm::report_fatal_error(Msg.str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001246 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001247 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001248 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001249 return;
1250 }
1251
Zonr Chang932648d2010-10-13 22:23:56 +08001252 // Stores the data in @Val of type @Ty at address @Addr.
1253 void StoreValueToMemory(const llvm::GenericValue &Val, void *Addr,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001254 const llvm::Type *Ty) {
1255 const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
1256
Zonr Chang932648d2010-10-13 22:23:56 +08001257 switch (Ty->getTypeID()) {
1258 case llvm::Type::IntegerTyID: {
1259 const llvm::APInt &IntVal = Val.IntVal;
1260 assert(((IntVal.getBitWidth() + 7) / 8 >= StoreBytes) &&
1261 "Integer too small!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001262
Zonr Chang932648d2010-10-13 22:23:56 +08001263 const uint8_t *Src =
1264 reinterpret_cast<const uint8_t*>(IntVal.getRawData());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001265
Zonr Chang932648d2010-10-13 22:23:56 +08001266 if (llvm::sys::isLittleEndianHost()) {
1267 // Little-endian host - the source is ordered from LSB to MSB.
1268 // Order the destination from LSB to MSB: Do a straight copy.
1269 memcpy(Addr, Src, StoreBytes);
1270 } else {
1271 // Big-endian host - the source is an array of 64 bit words
1272 // ordered from LSW to MSW.
1273 //
1274 // Each word is ordered from MSB to LSB.
1275 //
1276 // Order the destination from MSB to LSB:
1277 // Reverse the word order, but not the bytes in a word.
1278 unsigned int i = StoreBytes;
1279 while (i > sizeof(uint64_t)) {
1280 i -= sizeof(uint64_t);
1281 ::memcpy(reinterpret_cast<uint8_t*>(Addr) + i,
1282 Src,
1283 sizeof(uint64_t));
1284 Src += sizeof(uint64_t);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001285 }
Zonr Chang932648d2010-10-13 22:23:56 +08001286 ::memcpy(Addr, Src + sizeof(uint64_t) - i, i);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001287 }
1288 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001289 }
1290 case llvm::Type::FloatTyID: {
1291 *reinterpret_cast<float*>(Addr) = Val.FloatVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001292 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001293 }
1294 case llvm::Type::DoubleTyID: {
1295 *reinterpret_cast<double*>(Addr) = Val.DoubleVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001296 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001297 }
1298 case llvm::Type::X86_FP80TyID: {
1299 memcpy(Addr, Val.IntVal.getRawData(), 10);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001300 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001301 }
1302 case llvm::Type::PointerTyID: {
1303 // Ensure 64 bit target pointers are fully initialized on 32 bit
1304 // hosts.
1305 if (StoreBytes != sizeof(llvm::PointerTy))
1306 memset(Addr, 0, StoreBytes);
1307 *((llvm::PointerTy*) Addr) = Val.PointerVal;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001308 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001309 }
1310 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001311 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001312 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001313 }
1314
Zonr Chang932648d2010-10-13 22:23:56 +08001315 if (llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
1316 std::reverse(reinterpret_cast<uint8_t*>(Addr),
1317 reinterpret_cast<uint8_t*>(Addr) + StoreBytes);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001318
1319 return;
1320 }
1321
Zonr Chang932648d2010-10-13 22:23:56 +08001322 // Recursive function to apply a @Constant value into the specified memory
1323 // location @Addr.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001324 void InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
Zonr Chang932648d2010-10-13 22:23:56 +08001325 switch (C->getValueID()) {
1326 case llvm::Value::UndefValueVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001327 // Nothing to do
1328 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001329 }
1330 case llvm::Value::ConstantVectorVal: {
1331 // dynamic cast may hurt performance
1332 const llvm::ConstantVector *CP = (llvm::ConstantVector*) C;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001333
Zonr Chang932648d2010-10-13 22:23:56 +08001334 unsigned int ElementSize = mpTD->getTypeAllocSize
1335 (CP->getType()->getElementType());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001336
Zonr Chang932648d2010-10-13 22:23:56 +08001337 for (int i = 0, e = CP->getNumOperands(); i != e;i++)
1338 InitializeConstantToMemory(
1339 CP->getOperand(i),
1340 reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001341 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001342 }
1343 case llvm::Value::ConstantAggregateZeroVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001344 memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
1345 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001346 }
1347 case llvm::Value::ConstantArrayVal: {
1348 const llvm::ConstantArray *CPA = (llvm::ConstantArray*) C;
1349 unsigned int ElementSize = mpTD->getTypeAllocSize
1350 (CPA->getType()->getElementType());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001351
Zonr Chang932648d2010-10-13 22:23:56 +08001352 for (int i = 0, e = CPA->getNumOperands(); i != e; i++)
1353 InitializeConstantToMemory(
1354 CPA->getOperand(i),
1355 reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
1356 break;
1357 }
1358 case llvm::Value::ConstantStructVal: {
1359 const llvm::ConstantStruct *CPS =
1360 static_cast<const llvm::ConstantStruct*>(C);
1361 const llvm::StructLayout *SL = mpTD->getStructLayout
1362 (llvm::cast<llvm::StructType>(CPS->getType()));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001363
Zonr Chang932648d2010-10-13 22:23:56 +08001364 for (int i = 0, e = CPS->getNumOperands(); i != e; i++)
1365 InitializeConstantToMemory(
1366 CPS->getOperand(i),
1367 reinterpret_cast<uint8_t*>(Addr) + SL->getElementOffset(i));
1368 break;
1369 }
1370 default: {
1371 if (C->getType()->isFirstClassType()) {
1372 llvm::GenericValue Val;
1373 GetConstantValue(C, Val);
1374 StoreValueToMemory(Val, Addr, C->getType());
1375 } else {
1376 llvm_unreachable("Unknown constant type to initialize memory "
1377 "with!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001378 }
1379 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001380 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001381 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001382 return;
1383 }
1384
1385 void emitConstantPool(llvm::MachineConstantPool *MCP) {
Zonr Chang932648d2010-10-13 22:23:56 +08001386 if (mpTJI->hasCustomConstantPool())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001387 return;
1388
Zonr Chang932648d2010-10-13 22:23:56 +08001389 // Constant pool address resolution is handled by the target itself in ARM
1390 // (TargetJITInfo::hasCustomConstantPool() returns true).
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001391#if !defined(PROVIDE_ARM_CODEGEN)
Zonr Chang932648d2010-10-13 22:23:56 +08001392 const std::vector<llvm::MachineConstantPoolEntry> &Constants =
1393 MCP->getConstants();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001394
Zonr Chang932648d2010-10-13 22:23:56 +08001395 if (Constants.empty())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001396 return;
1397
1398 unsigned Size = GetConstantPoolSizeInBytes(MCP);
1399 unsigned Align = MCP->getConstantPoolAlignment();
1400
1401 mpConstantPoolBase = allocateSpace(Size, Align);
1402 mpConstantPool = MCP;
1403
Zonr Chang932648d2010-10-13 22:23:56 +08001404 if (mpConstantPoolBase == NULL)
1405 return; // out of memory
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001406
1407 unsigned Offset = 0;
Zonr Chang932648d2010-10-13 22:23:56 +08001408 for (int i = 0, e = Constants.size(); i != e; i++) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001409 llvm::MachineConstantPoolEntry CPE = Constants[i];
1410 unsigned AlignMask = CPE.getAlignment() - 1;
1411 Offset = (Offset + AlignMask) & ~AlignMask;
1412
1413 uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
1414 mConstPoolAddresses.push_back(CAddr);
1415
Zonr Chang932648d2010-10-13 22:23:56 +08001416 if (CPE.isMachineConstantPoolEntry())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001417 llvm::report_fatal_error
Zonr Chang932648d2010-10-13 22:23:56 +08001418 ("Initialize memory with machine specific constant pool"
1419 " entry has not been implemented!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001420
1421 InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
1422
1423 const llvm::Type *Ty = CPE.Val.ConstVal->getType();
1424 Offset += mpTD->getTypeAllocSize(Ty);
1425 }
1426#endif
1427 return;
1428 }
1429
1430 void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
Zonr Chang932648d2010-10-13 22:23:56 +08001431 if (mpTJI->hasCustomJumpTables())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001432 return;
1433
Zonr Chang932648d2010-10-13 22:23:56 +08001434 const std::vector<llvm::MachineJumpTableEntry> &JT =
1435 MJTI->getJumpTables();
1436 if (JT.empty())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001437 return;
1438
1439 unsigned NumEntries = 0;
Zonr Chang932648d2010-10-13 22:23:56 +08001440 for (int i = 0, e = JT.size(); i != e; i++)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001441 NumEntries += JT[i].MBBs.size();
1442
1443 unsigned EntrySize = MJTI->getEntrySize(*mpTD);
1444
Zonr Chang932648d2010-10-13 22:23:56 +08001445 mpJumpTable = MJTI;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001446 mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
Zonr Chang932648d2010-10-13 22:23:56 +08001447 MJTI->getEntryAlignment(*mpTD));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001448
1449 return;
1450 }
1451
1452 void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
Zonr Chang932648d2010-10-13 22:23:56 +08001453 if (mpTJI->hasCustomJumpTables())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001454 return;
1455
Zonr Chang932648d2010-10-13 22:23:56 +08001456 const std::vector<llvm::MachineJumpTableEntry> &JT =
1457 MJTI->getJumpTables();
1458 if (JT.empty() || mpJumpTableBase == 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001459 return;
1460
Zonr Chang932648d2010-10-13 22:23:56 +08001461 assert(llvm::TargetMachine::getRelocationModel() == llvm::Reloc::Static &&
1462 (MJTI->getEntrySize(*mpTD) == sizeof(mpTD /* a pointer type */)) &&
1463 "Cross JIT'ing?");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001464
Zonr Chang932648d2010-10-13 22:23:56 +08001465 // For each jump table, map each target in the jump table to the
1466 // address of an emitted MachineBasicBlock.
1467 intptr_t *SlotPtr = reinterpret_cast<intptr_t*>(mpJumpTableBase);
1468 for (int i = 0, ie = JT.size(); i != ie; i++) {
1469 const std::vector<llvm::MachineBasicBlock*> &MBBs = JT[i].MBBs;
1470 // Store the address of the basic block for this jump table slot in the
1471 // memory we allocated for the jump table in 'initJumpTableInfo'
1472 for (int j = 0, je = MBBs.size(); j != je; j++)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001473 *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
1474 }
1475 }
1476
Zonr Chang932648d2010-10-13 22:23:56 +08001477 void *GetPointerToGlobal(llvm::GlobalValue *V, void *Reference,
1478 bool MayNeedFarStub) {
1479 switch (V->getValueID()) {
1480 case llvm::Value::FunctionVal: {
1481 llvm::Function *F = (llvm::Function*) V;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001482
Zonr Chang932648d2010-10-13 22:23:56 +08001483 // If we have code, go ahead and return that.
1484 if (void *ResultPtr = GetPointerToGlobalIfAvailable(F))
1485 return ResultPtr;
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001486
Zonr Chang932648d2010-10-13 22:23:56 +08001487 if (void *FnStub = GetLazyFunctionStubIfAvailable(F))
1488 // Return the function stub if it's already created.
1489 // We do this first so that:
1490 // we're returning the same address for the function as any
1491 // previous call.
1492 //
1493 // TODO(llvm.org): Yes, this is wrong. The lazy stub isn't
1494 // guaranteed to be close enough to call.
1495 return FnStub;
Shih-wei Liao800e9c22010-04-18 16:08:16 -07001496
Zonr Chang932648d2010-10-13 22:23:56 +08001497 // If we know the target can handle arbitrary-distance calls, try to
1498 // return a direct pointer.
1499 if (!MayNeedFarStub) {
1500 //
1501 // x86_64 architecture may encounter the bug:
1502 // http://llvm.org/bugs/show_bug.cgi?id=5201
1503 // which generate instruction "call" instead of "callq".
1504 //
1505 // And once the real address of stub is greater than 64-bit
1506 // long, the replacement will truncate to 32-bit resulting a
1507 // serious problem.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001508#if !defined(__x86_64__)
Zonr Chang932648d2010-10-13 22:23:56 +08001509 // If this is an external function pointer, we can force the JIT
1510 // to 'compile' it, which really just adds it to the map.
1511 if (F->isDeclaration() || F->hasAvailableExternallyLinkage())
1512 return GetPointerToFunction(F, /* AbortOnFailure = */true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001513#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001514 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001515
Zonr Chang932648d2010-10-13 22:23:56 +08001516 // Otherwise, we may need a to emit a stub, and, conservatively, we
1517 // always do so.
1518 return GetLazyFunctionStub(F);
1519 break;
1520 }
1521 case llvm::Value::GlobalVariableVal: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001522 return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
1523 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001524 }
1525 case llvm::Value::GlobalAliasVal: {
1526 llvm::GlobalAlias *GA = (llvm::GlobalAlias*) V;
1527 const llvm::GlobalValue *GV = GA->resolveAliasedGlobal(false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001528
Zonr Chang932648d2010-10-13 22:23:56 +08001529 switch (GV->getValueID()) {
1530 case llvm::Value::FunctionVal: {
1531 // FIXME: is there's any possibility that the function is not
1532 // code-gen'd?
1533 return GetPointerToFunction(
1534 static_cast<const llvm::Function*>(GV),
1535 /* AbortOnFailure = */true);
1536 break;
1537 }
1538 case llvm::Value::GlobalVariableVal: {
1539 if (void *P = mGlobalAddressMap[GV])
1540 return P;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001541
Zonr Chang932648d2010-10-13 22:23:56 +08001542 llvm::GlobalVariable *GVar = (llvm::GlobalVariable*) GV;
1543 EmitGlobalVariable(GVar);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001544
Zonr Chang932648d2010-10-13 22:23:56 +08001545 return mGlobalAddressMap[GV];
1546 break;
1547 }
1548 case llvm::Value::GlobalAliasVal: {
1549 assert(false && "Alias should be resolved ultimately!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001550 }
1551 }
1552 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001553 }
1554 default: {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001555 break;
Zonr Chang932648d2010-10-13 22:23:56 +08001556 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001557 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001558 llvm_unreachable("Unknown type of global value!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001559 }
1560
Zonr Chang932648d2010-10-13 22:23:56 +08001561 // If the specified function has been code-gen'd, return a pointer to the
1562 // function. If not, compile it, or use a stub to implement lazy compilation
1563 // if available.
1564 void *GetPointerToFunctionOrStub(llvm::Function *F) {
1565 // If we have already code generated the function, just return the
1566 // address.
1567 if (void *Addr = GetPointerToGlobalIfAvailable(F))
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001568 return Addr;
1569
Zonr Chang932648d2010-10-13 22:23:56 +08001570 // Get a stub if the target supports it.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001571 return GetLazyFunctionStub(F);
1572 }
1573
Zonr Chang932648d2010-10-13 22:23:56 +08001574 typedef llvm::DenseMap<const llvm::Function*,
1575 void*> FunctionToLazyStubMapTy;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001576 FunctionToLazyStubMapTy mFunctionToLazyStubMap;
1577
Zonr Chang932648d2010-10-13 22:23:56 +08001578 void *GetLazyFunctionStubIfAvailable(llvm::Function *F) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001579 return mFunctionToLazyStubMap.lookup(F);
1580 }
1581
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001582 std::set<const llvm::Function*> PendingFunctions;
Zonr Chang932648d2010-10-13 22:23:56 +08001583 void *GetLazyFunctionStub(llvm::Function *F) {
1584 // If we already have a lazy stub for this function, recycle it.
1585 void *&Stub = mFunctionToLazyStubMap[F];
1586 if (Stub)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001587 return Stub;
1588
Zonr Chang932648d2010-10-13 22:23:56 +08001589 // In any cases, we should NOT resolve function at runtime (though we are
1590 // able to). We resolve this right now.
1591 void *Actual = NULL;
1592 if (F->isDeclaration() || F->hasAvailableExternallyLinkage())
1593 Actual = GetPointerToFunction(F, /* AbortOnFailure = */true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001594
Zonr Chang932648d2010-10-13 22:23:56 +08001595 // Codegen a new stub, calling the actual address of the external
1596 // function, if it was resolved.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001597 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1598 startGVStub(F, SL.Size, SL.Alignment);
1599 Stub = mpTJI->emitFunctionStub(F, Actual, *this);
1600 finishGVStub();
1601
Zonr Chang932648d2010-10-13 22:23:56 +08001602 // We really want the address of the stub in the GlobalAddressMap for the
1603 // JIT, not the address of the external function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001604 UpdateGlobalMapping(F, Stub);
1605
Zonr Chang932648d2010-10-13 22:23:56 +08001606 if (!Actual)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001607 PendingFunctions.insert(F);
1608 else
Zonr Chang932648d2010-10-13 22:23:56 +08001609 Disassemble(F->getName(), reinterpret_cast<uint8_t*>(Stub),
1610 SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001611
1612 return Stub;
1613 }
1614
Zonr Chang932648d2010-10-13 22:23:56 +08001615 void *GetPointerToFunction(const llvm::Function *F, bool AbortOnFailure) {
1616 void *Addr = GetPointerToGlobalIfAvailable(F);
1617 if (Addr)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001618 return Addr;
1619
1620 assert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
1621 "Internal error: only external defined function routes here!");
1622
Zonr Chang932648d2010-10-13 22:23:56 +08001623 // Handle the failure resolution by ourselves.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001624 Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
Zonr Chang932648d2010-10-13 22:23:56 +08001625 /* AbortOnFailure = */ false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001626
Zonr Chang932648d2010-10-13 22:23:56 +08001627 // If we resolved the symbol to a null address (eg. a weak external)
1628 // return a null pointer let the application handle it.
1629 if (Addr == NULL) {
1630 if (AbortOnFailure)
1631 llvm::report_fatal_error("Could not resolve external function "
1632 "address: " + F->getName());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001633 else
1634 return NULL;
Zonr Chang932648d2010-10-13 22:23:56 +08001635 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001636
1637 AddGlobalMapping(F, Addr);
1638
1639 return Addr;
1640 }
1641
Zonr Chang932648d2010-10-13 22:23:56 +08001642 void *GetPointerToNamedSymbol(const std::string &Name,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001643 bool AbortOnFailure) {
Zonr Chang932648d2010-10-13 22:23:56 +08001644 if (void *Addr = FindRuntimeFunction(Name.c_str()))
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001645 return Addr;
1646
Zonr Chang932648d2010-10-13 22:23:56 +08001647 if (mpSymbolLookupFn)
1648 if (void *Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001649 return Addr;
1650
Zonr Chang932648d2010-10-13 22:23:56 +08001651 if (AbortOnFailure)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001652 llvm::report_fatal_error("Program used external symbol '" + Name +
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001653 "' which could not be resolved!");
1654
1655 return NULL;
1656 }
1657
Zonr Chang932648d2010-10-13 22:23:56 +08001658 // Return the address of the specified global variable, possibly emitting it
1659 // to memory if needed. This is used by the Emitter.
1660 void *GetOrEmitGlobalVariable(const llvm::GlobalVariable *GV) {
1661 void *Ptr = GetPointerToGlobalIfAvailable(GV);
1662 if (Ptr)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001663 return Ptr;
1664
Zonr Chang932648d2010-10-13 22:23:56 +08001665 if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
1666 // If the global is external, just remember the address.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001667 Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
1668 AddGlobalMapping(GV, Ptr);
1669 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08001670 // If the global hasn't been emitted to memory yet, allocate space and
1671 // emit it into memory.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001672 Ptr = GetMemoryForGV(GV);
1673 AddGlobalMapping(GV, Ptr);
1674 EmitGlobalVariable(GV);
1675 }
1676
1677 return Ptr;
1678 }
1679
Zonr Chang932648d2010-10-13 22:23:56 +08001680 // This method abstracts memory allocation of global variable so that the
1681 // JIT can allocate thread local variables depending on the target.
1682 void *GetMemoryForGV(const llvm::GlobalVariable *GV) {
1683 void *Ptr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001684
Zonr Chang932648d2010-10-13 22:23:56 +08001685 const llvm::Type *GlobalType = GV->getType()->getElementType();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001686 size_t S = mpTD->getTypeAllocSize(GlobalType);
1687 size_t A = mpTD->getPreferredAlignment(GV);
1688
Zonr Chang932648d2010-10-13 22:23:56 +08001689 if (GV->isThreadLocal()) {
1690 // We can support TLS by
1691 //
1692 // Ptr = TJI.allocateThreadLocalMemory(S);
1693 //
1694 // But I tend not to.
1695 // (should we disable this in the front-end (i.e., slang)?).
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001696 llvm::report_fatal_error
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001697 ("Compilation of Thread Local Storage (TLS) is disabled!");
1698
Zonr Chang932648d2010-10-13 22:23:56 +08001699 } else if (mpTJI->allocateSeparateGVMemory()) {
1700 if (A <= 8) {
1701 Ptr = malloc(S);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001702 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08001703 // Allocate (S + A) bytes of memory, then use an aligned pointer
1704 // within that space.
1705 Ptr = malloc(S + A);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001706 unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
Zonr Chang932648d2010-10-13 22:23:56 +08001707 Ptr = reinterpret_cast<uint8_t*>(Ptr) +
1708 (MisAligned ? (A - MisAligned) : 0);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001709 }
1710 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08001711 Ptr = allocateGlobal(S, A);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001712 }
1713
1714 return Ptr;
1715 }
1716
1717 void EmitGlobalVariable(const llvm::GlobalVariable *GV) {
Zonr Chang932648d2010-10-13 22:23:56 +08001718 void *GA = GetPointerToGlobalIfAvailable(GV);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001719
Zonr Chang932648d2010-10-13 22:23:56 +08001720 if (GV->isThreadLocal())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07001721 llvm::report_fatal_error
1722 ("We don't support Thread Local Storage (TLS)!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001723
Zonr Chang932648d2010-10-13 22:23:56 +08001724 if (GA == NULL) {
1725 // If it's not already specified, allocate memory for the global.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001726 GA = GetMemoryForGV(GV);
1727 AddGlobalMapping(GV, GA);
1728 }
1729
1730 InitializeConstantToMemory(GV->getInitializer(), GA);
1731
Zonr Chang932648d2010-10-13 22:23:56 +08001732 // You can do some statistics on global variable here.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001733 return;
1734 }
1735
1736 typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void*
1737 > GlobalToIndirectSymMapTy;
1738 GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
1739
Zonr Chang932648d2010-10-13 22:23:56 +08001740 void *GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
1741 // Make sure GV is emitted first, and create a stub containing the fully
1742 // resolved address.
1743 void *GVAddress = GetPointerToGlobal(V, Reference, false);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001744
Zonr Chang932648d2010-10-13 22:23:56 +08001745 // If we already have a stub for this global variable, recycle it.
1746 void *&IndirectSym = GlobalToIndirectSymMap[V];
1747 // Otherwise, codegen a new indirect symbol.
1748 if (!IndirectSym)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001749 IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
1750
1751 return IndirectSym;
1752 }
1753
Zonr Chang932648d2010-10-13 22:23:56 +08001754 // This is the equivalent of FunctionToLazyStubMap for external functions.
1755 //
1756 // TODO(llvm.org): Of course, external functions don't need a lazy stub.
1757 // It's actually here to make it more likely that far calls
1758 // succeed, but no single stub can guarantee that. I'll
1759 // remove this in a subsequent checkin when I actually fix
1760 // far calls.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001761 std::map<void*, void*> ExternalFnToStubMap;
1762
Zonr Chang932648d2010-10-13 22:23:56 +08001763 // Return a stub for the function at the specified address.
1764 void *GetExternalFunctionStub(void *FnAddr) {
1765 void *&Stub = ExternalFnToStubMap[FnAddr];
1766 if (Stub)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001767 return Stub;
1768
1769 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
1770 startGVStub(0, SL.Size, SL.Alignment);
1771 Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
1772 finishGVStub();
1773
1774 return Stub;
1775 }
1776
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001777#if defined(USE_DISASSEMBLER)
Zonr Chang932648d2010-10-13 22:23:56 +08001778 const llvm::MCAsmInfo *mpAsmInfo;
1779 const llvm::MCDisassembler *mpDisassmbler;
1780 llvm::MCInstPrinter *mpIP;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001781
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001782 class BufferMemoryObject : public llvm::MemoryObject {
1783 private:
Zonr Chang932648d2010-10-13 22:23:56 +08001784 const uint8_t *mBytes;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001785 uint64_t mLength;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001786
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001787 public:
1788 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length) :
1789 mBytes(Bytes), mLength(Length) { }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001790
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001791 uint64_t getBase() const { return 0; }
1792 uint64_t getExtent() const { return mLength; }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001793
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001794 int readByte(uint64_t Addr, uint8_t *Byte) const {
Zonr Chang932648d2010-10-13 22:23:56 +08001795 if (Addr > getExtent())
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001796 return -1;
1797 *Byte = mBytes[Addr];
1798 return 0;
1799 }
1800 };
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001801
Zonr Chang932648d2010-10-13 22:23:56 +08001802 void Disassemble(const llvm::StringRef &Name, uint8_t *Start,
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001803 size_t Length, bool IsStub) {
Zonr Chang932648d2010-10-13 22:23:56 +08001804 llvm::raw_fd_ostream *OS;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001805#if defined(USE_DISASSEMBLER_FILE)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001806 std::string ErrorInfo;
Zonr Chang932648d2010-10-13 22:23:56 +08001807 OS = new llvm::raw_fd_ostream("/data/local/tmp/out.S",
1808 ErrorInfo,
1809 llvm::raw_fd_ostream::F_Append);
1810 if (!ErrorInfo.empty()) { // some errors occurred
1811 // LOGE("Error in creating disassembly file");
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001812 delete OS;
1813 return;
1814 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001815#else
1816 OS = &llvm::outs();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001817#endif
Zonr Chang932648d2010-10-13 22:23:56 +08001818 *OS << "JIT: Disassembled code: " << Name << ((IsStub) ? " (stub)" : "")
1819 << "\n";
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001820
Zonr Chang932648d2010-10-13 22:23:56 +08001821 if (mpAsmInfo == NULL)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001822 mpAsmInfo = mpTarget->createAsmInfo(Triple);
Zonr Chang932648d2010-10-13 22:23:56 +08001823 if (mpDisassmbler == NULL)
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001824 mpDisassmbler = mpTarget->createMCDisassembler();
Zonr Chang932648d2010-10-13 22:23:56 +08001825 if (mpIP == NULL)
1826 mpIP = mpTarget->createMCInstPrinter(mpAsmInfo->getAssemblerDialect(),
1827 *mpAsmInfo);
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001828
Zonr Chang932648d2010-10-13 22:23:56 +08001829 const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Start,
1830 Length);
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001831 uint64_t Size;
1832 uint64_t Index;
1833
Zonr Chang932648d2010-10-13 22:23:56 +08001834 for (Index = 0; Index < Length; Index += Size) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001835 llvm::MCInst Inst;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001836
Zonr Chang932648d2010-10-13 22:23:56 +08001837 if (mpDisassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
1838 /* REMOVED */ llvm::nulls())) {
1839 (*OS).indent(4)
1840 .write("0x", 2)
1841 .write_hex((uint32_t) Start + Index)
1842 .write(':');
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001843 mpIP->printInst(&Inst, *OS);
1844 *OS << "\n";
1845 } else {
1846 if (Size == 0)
Zonr Chang932648d2010-10-13 22:23:56 +08001847 Size = 1; // skip illegible bytes
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001848 }
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001849 }
1850
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001851 *OS << "\n";
1852 delete BufferMObj;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001853
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07001854#if defined(USE_DISASSEMBLER_FILE)
Zonr Chang932648d2010-10-13 22:23:56 +08001855 // If you want the disassemble results write to file, uncomment this.
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001856 OS->close();
1857 delete OS;
1858#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001859 return;
1860 }
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001861#else
Zonr Chang932648d2010-10-13 22:23:56 +08001862 inline void Disassemble(const std::string &Name, uint8_t *Start,
1863 size_t Length, bool IsStub) {
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001864 return;
1865 }
Zonr Chang932648d2010-10-13 22:23:56 +08001866#endif // defined(USE_DISASSEMBLER)
1867
1868 // Resolver to undefined symbol in CodeEmitter
1869 BCCSymbolLookupFn mpSymbolLookupFn;
1870 void *mpSymbolLookupContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001871
1872 public:
Zonr Chang932648d2010-10-13 22:23:56 +08001873 // Will take the ownership of @MemMgr
1874 explicit CodeEmitter(CodeMemoryManager *pMemMgr)
1875 : mpMemMgr(pMemMgr),
1876 mpTarget(NULL),
1877 mpTJI(NULL),
1878 mpTD(NULL),
1879 mpCurEmitFunction(NULL),
1880 mpConstantPool(NULL),
1881 mpJumpTable(NULL),
1882 mpMMI(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001883#if defined(USE_DISASSEMBLER)
Zonr Chang932648d2010-10-13 22:23:56 +08001884 mpAsmInfo(NULL),
1885 mpDisassmbler(NULL),
1886 mpIP(NULL),
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001887#endif
Zonr Chang932648d2010-10-13 22:23:56 +08001888 mpSymbolLookupFn(NULL),
1889 mpSymbolLookupContext(NULL) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001890 return;
1891 }
1892
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001893 inline global_addresses_const_iterator global_address_begin() const {
1894 return mGlobalAddressMap.begin();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001895 }
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07001896 inline global_addresses_const_iterator global_address_end() const {
1897 return mGlobalAddressMap.end();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001898 }
1899
Zonr Chang932648d2010-10-13 22:23:56 +08001900 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001901 mpSymbolLookupFn = pFn;
1902 mpSymbolLookupContext = pContext;
1903 return;
1904 }
1905
Zonr Chang932648d2010-10-13 22:23:56 +08001906 void setTargetMachine(llvm::TargetMachine &TM) {
1907 // Set Target
Shih-wei Liaocd61af32010-04-29 00:02:57 -07001908 mpTarget = &TM.getTarget();
Zonr Chang932648d2010-10-13 22:23:56 +08001909 // Set TargetJITInfo
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001910 mpTJI = TM.getJITInfo();
Zonr Chang932648d2010-10-13 22:23:56 +08001911 // set TargetData
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001912 mpTD = TM.getTargetData();
1913
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001914 assert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
1915
1916 return;
1917 }
1918
Zonr Chang932648d2010-10-13 22:23:56 +08001919 // This callback is invoked when the specified function is about to be code
1920 // generated. This initializes the BufferBegin/End/Ptr fields.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001921 void startFunction(llvm::MachineFunction &F) {
1922 uintptr_t ActualSize = 0;
1923
1924 mpMemMgr->setMemoryWritable();
Zonr Chang932648d2010-10-13 22:23:56 +08001925
1926 // BufferBegin, BufferEnd and CurBufferPtr are all inherited from class
1927 // MachineCodeEmitter, which is the super class of the class
1928 // JITCodeEmitter.
1929 //
1930 // BufferBegin/BufferEnd - Pointers to the start and end of the memory
1931 // allocated for this code buffer.
1932 //
1933 // CurBufferPtr - Pointer to the next byte of memory to fill when emitting
1934 // code. This is guranteed to be in the range
1935 // [BufferBegin, BufferEnd]. If this pointer is at
1936 // BufferEnd, it will never move due to code emission, and
1937 // all code emission requests will be ignored (this is the
1938 // buffer overflow condition).
1939 BufferBegin = CurBufferPtr =
1940 mpMemMgr->startFunctionBody(F.getFunction(), ActualSize);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001941 BufferEnd = BufferBegin + ActualSize;
1942
Zonr Chang932648d2010-10-13 22:23:56 +08001943 if (mpCurEmitFunction == NULL)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001944 mpCurEmitFunction = new EmittedFunctionCode();
1945 mpCurEmitFunction->FunctionBody = BufferBegin;
1946
Zonr Chang932648d2010-10-13 22:23:56 +08001947 // Ensure the constant pool/jump table info is at least 4-byte aligned.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001948 emitAlignment(16);
1949
1950 emitConstantPool(F.getConstantPool());
Zonr Chang932648d2010-10-13 22:23:56 +08001951 if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001952 initJumpTableInfo(MJTI);
1953
Zonr Chang932648d2010-10-13 22:23:56 +08001954 // About to start emitting the machine code for the function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001955 emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
1956
1957 UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
1958
1959 mpCurEmitFunction->Code = CurBufferPtr;
1960
1961 mMBBLocations.clear();
1962
1963 return;
1964 }
1965
Zonr Chang932648d2010-10-13 22:23:56 +08001966 // This callback is invoked when the specified function has finished code
1967 // generation. If a buffer overflow has occurred, this method returns true
1968 // (the callee is required to try again).
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001969 bool finishFunction(llvm::MachineFunction &F) {
Zonr Chang932648d2010-10-13 22:23:56 +08001970 if (CurBufferPtr == BufferEnd) {
1971 // No enough memory
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001972 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
1973 return false;
1974 }
1975
Zonr Chang932648d2010-10-13 22:23:56 +08001976 if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001977 emitJumpTableInfo(MJTI);
1978
Zonr Chang932648d2010-10-13 22:23:56 +08001979 // FnStart is the start of the text, not the start of the constant pool
1980 // and other per-function data.
1981 uint8_t *FnStart =
1982 reinterpret_cast<uint8_t*>(
1983 GetPointerToGlobalIfAvailable(F.getFunction()));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001984
Zonr Chang932648d2010-10-13 22:23:56 +08001985 // FnEnd is the end of the function's machine code.
1986 uint8_t *FnEnd = CurBufferPtr;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001987
Zonr Chang932648d2010-10-13 22:23:56 +08001988 if (!mRelocations.empty()) {
1989 // Resolve the relocations to concrete pointers.
1990 for (int i = 0, e = mRelocations.size(); i != e; i++) {
1991 llvm::MachineRelocation &MR = mRelocations[i];
1992 void *ResultPtr = NULL;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001993
Zonr Chang932648d2010-10-13 22:23:56 +08001994 if (!MR.letTargetResolve()) {
1995 if (MR.isExternalSymbol()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001996 ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
Zonr Chang932648d2010-10-13 22:23:56 +08001997 if (MR.mayNeedFarStub())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07001998 ResultPtr = GetExternalFunctionStub(ResultPtr);
Zonr Chang932648d2010-10-13 22:23:56 +08001999 } else if (MR.isGlobalValue()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002000 ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
2001 BufferBegin
2002 + MR.getMachineCodeOffset(),
2003 MR.mayNeedFarStub());
Zonr Chang932648d2010-10-13 22:23:56 +08002004 } else if (MR.isIndirectSymbol()) {
2005 ResultPtr =
2006 GetPointerToGVIndirectSym(
2007 MR.getGlobalValue(),
2008 BufferBegin + MR.getMachineCodeOffset());
2009 } else if (MR.isBasicBlock()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002010 ResultPtr =
2011 (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
Zonr Chang932648d2010-10-13 22:23:56 +08002012 } else if (MR.isConstantPoolIndex()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002013 ResultPtr =
Zonr Chang932648d2010-10-13 22:23:56 +08002014 (void*) getConstantPoolEntryAddress(MR.getConstantPoolIndex());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002015 } else {
2016 assert(MR.isJumpTableIndex() && "Unknown type of relocation");
2017 ResultPtr =
2018 (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
2019 }
2020
2021 MR.setResultPointer(ResultPtr);
2022 }
2023 }
2024
2025 mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
2026 mpMemMgr->getGOTBase());
2027 }
2028
2029 mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
Zonr Chang932648d2010-10-13 22:23:56 +08002030 // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
2031 // global variables that were referenced in the relocations.
2032 if (CurBufferPtr == BufferEnd)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002033 return false;
2034
Zonr Chang932648d2010-10-13 22:23:56 +08002035 // Now that we've succeeded in emitting the function.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002036 mpCurEmitFunction->Size = CurBufferPtr - BufferBegin;
2037 BufferBegin = CurBufferPtr = 0;
2038
Zonr Chang932648d2010-10-13 22:23:56 +08002039 if (F.getFunction()->hasName())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002040 mEmittedFunctions[F.getFunction()->getNameStr()] = mpCurEmitFunction;
2041 mpCurEmitFunction = NULL;
2042
2043 mRelocations.clear();
2044 mConstPoolAddresses.clear();
2045
Zonr Chang932648d2010-10-13 22:23:56 +08002046 if (mpMMI)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002047 mpMMI->EndFunction();
2048
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002049 updateFunctionStub(F.getFunction());
2050
Zonr Chang932648d2010-10-13 22:23:56 +08002051 // Mark code region readable and executable if it's not so already.
Shih-wei Liaoc4e4ddf2010-09-24 14:50:26 -07002052 mpMemMgr->setMemoryExecutable();
2053
2054 Disassemble(F.getFunction()->getName(), FnStart, FnEnd - FnStart, false);
2055
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002056 return false;
2057 }
2058
Zonr Chang932648d2010-10-13 22:23:56 +08002059 void startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002060 unsigned Alignment) {
2061 mpSavedBufferBegin = BufferBegin;
2062 mpSavedBufferEnd = BufferEnd;
2063 mpSavedCurBufferPtr = CurBufferPtr;
2064
2065 BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
2066 Alignment);
2067 BufferEnd = BufferBegin + StubSize + 1;
2068
2069 return;
2070 }
2071
Zonr Chang932648d2010-10-13 22:23:56 +08002072 void startGVStub(void *Buffer, unsigned StubSize) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002073 mpSavedBufferBegin = BufferBegin;
2074 mpSavedBufferEnd = BufferEnd;
2075 mpSavedCurBufferPtr = CurBufferPtr;
2076
Zonr Chang932648d2010-10-13 22:23:56 +08002077 BufferBegin = CurBufferPtr = reinterpret_cast<uint8_t *>(Buffer);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002078 BufferEnd = BufferBegin + StubSize + 1;
2079
2080 return;
2081 }
2082
2083 void finishGVStub() {
2084 assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
2085
Zonr Chang932648d2010-10-13 22:23:56 +08002086 // restore
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002087 BufferBegin = mpSavedBufferBegin;
2088 BufferEnd = mpSavedBufferEnd;
2089 CurBufferPtr = mpSavedCurBufferPtr;
2090
2091 return;
2092 }
2093
Zonr Chang932648d2010-10-13 22:23:56 +08002094 // Allocates and fills storage for an indirect GlobalValue, and returns the
2095 // address.
2096 void *allocIndirectGV(const llvm::GlobalValue *GV,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002097 const uint8_t *Buffer, size_t Size,
2098 unsigned Alignment) {
Zonr Chang932648d2010-10-13 22:23:56 +08002099 uint8_t *IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002100 memcpy(IndGV, Buffer, Size);
2101 return IndGV;
2102 }
2103
Zonr Chang932648d2010-10-13 22:23:56 +08002104 // Emits a label
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002105 void emitLabel(llvm::MCSymbol *Label) {
2106 mLabelLocations[Label] = getCurrentPCValue();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002107 return;
2108 }
2109
Zonr Chang932648d2010-10-13 22:23:56 +08002110 // Allocate memory for a global. Unlike allocateSpace, this method does not
2111 // allocate memory in the current output buffer, because a global may live
2112 // longer than the current function.
2113 void *allocateGlobal(uintptr_t Size, unsigned Alignment) {
2114 // Delegate this call through the memory manager.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002115 return mpMemMgr->allocateGlobal(Size, Alignment);
2116 }
2117
Zonr Chang932648d2010-10-13 22:23:56 +08002118 // This should be called by the target when a new basic block is about to be
2119 // emitted. This way the MCE knows where the start of the block is, and can
2120 // implement getMachineBasicBlockAddress.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002121 void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
Zonr Chang932648d2010-10-13 22:23:56 +08002122 if (mMBBLocations.size() <= (unsigned) MBB->getNumber())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002123 mMBBLocations.resize((MBB->getNumber() + 1) * 2);
2124 mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
2125 return;
2126 }
2127
Zonr Chang932648d2010-10-13 22:23:56 +08002128 // Whenever a relocatable address is needed, it should be noted with this
2129 // interface.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002130 void addRelocation(const llvm::MachineRelocation &MR) {
2131 mRelocations.push_back(MR);
2132 return;
2133 }
2134
Zonr Chang932648d2010-10-13 22:23:56 +08002135 // Return the address of the @Index entry in the constant pool that was
2136 // last emitted with the emitConstantPool method.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002137 uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
2138 assert(Index < mpConstantPool->getConstants().size() &&
2139 "Invalid constant pool index!");
2140 return mConstPoolAddresses[Index];
2141 }
2142
Zonr Chang932648d2010-10-13 22:23:56 +08002143 // Return the address of the jump table with index @Index in the function
2144 // that last called initJumpTableInfo.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002145 uintptr_t getJumpTableEntryAddress(unsigned Index) const {
Zonr Chang932648d2010-10-13 22:23:56 +08002146 const std::vector<llvm::MachineJumpTableEntry> &JT =
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002147 mpJumpTable->getJumpTables();
2148
Zonr Chang932648d2010-10-13 22:23:56 +08002149 assert((Index < JT.size()) && "Invalid jump table index!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002150
2151 unsigned int Offset = 0;
2152 unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
2153
Zonr Chang932648d2010-10-13 22:23:56 +08002154 for (unsigned i = 0; i < Index; i++)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002155 Offset += JT[i].MBBs.size();
2156 Offset *= EntrySize;
2157
Zonr Chang932648d2010-10-13 22:23:56 +08002158 return (uintptr_t)(reinterpret_cast<uint8_t*>(mpJumpTableBase) + Offset);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002159 }
2160
Zonr Chang932648d2010-10-13 22:23:56 +08002161 // Return the address of the specified MachineBasicBlock, only usable after
2162 // the label for the MBB has been emitted.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002163 uintptr_t getMachineBasicBlockAddress(llvm::MachineBasicBlock *MBB) const {
2164 assert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
Zonr Chang932648d2010-10-13 22:23:56 +08002165 mMBBLocations[MBB->getNumber()] &&
2166 "MBB not emitted!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002167 return mMBBLocations[MBB->getNumber()];
2168 }
2169
Zonr Chang932648d2010-10-13 22:23:56 +08002170 // Return the address of the specified LabelID, only usable after the
2171 // LabelID has been emitted.
2172 uintptr_t getLabelAddress(llvm::MCSymbol *Label) const {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002173 assert(mLabelLocations.count(Label) && "Label not emitted!");
2174 return mLabelLocations.find(Label)->second;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002175 }
2176
Zonr Chang932648d2010-10-13 22:23:56 +08002177 // Specifies the MachineModuleInfo object. This is used for exception
2178 // handling purposes.
2179 void setModuleInfo(llvm::MachineModuleInfo *Info) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002180 mpMMI = Info;
2181 return;
2182 }
2183
Zonr Chang932648d2010-10-13 22:23:56 +08002184 void updateFunctionStub(const llvm::Function *F) {
2185 // Get the empty stub we generated earlier.
2186 void *Stub;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002187 std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
Zonr Chang932648d2010-10-13 22:23:56 +08002188 if (I != PendingFunctions.end())
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002189 Stub = mFunctionToLazyStubMap[F];
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002190 else
2191 return;
2192
Zonr Chang932648d2010-10-13 22:23:56 +08002193 void *Addr = GetPointerToGlobalIfAvailable(F);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002194
2195 assert(Addr != Stub &&
2196 "Function must have non-stub address to be updated.");
2197
Zonr Chang932648d2010-10-13 22:23:56 +08002198 // Tell the target jit info to rewrite the stub at the specified address,
2199 // rather than creating a new one.
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002200 llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
2201 startGVStub(Stub, SL.Size);
2202 mpTJI->emitFunctionStub(F, Addr, *this);
2203 finishGVStub();
2204
Zonr Chang932648d2010-10-13 22:23:56 +08002205 Disassemble(F->getName(), reinterpret_cast<uint8_t*>(Stub),
2206 SL.Size, true);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002207
2208 PendingFunctions.erase(I);
2209
2210 return;
2211 }
2212
Zonr Chang932648d2010-10-13 22:23:56 +08002213 // Once you finish the compilation on a translation unit, you can call this
2214 // function to recycle the memory (which is used at compilation time and not
2215 // needed for runtime).
2216 //
2217 // NOTE: You should not call this funtion until the code-gen passes for a
2218 // given module is done. Otherwise, the results is undefined and may
2219 // cause the system crash!
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002220 void releaseUnnecessary() {
2221 mMBBLocations.clear();
2222 mLabelLocations.clear();
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002223 mGlobalAddressMap.clear();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002224 mFunctionToLazyStubMap.clear();
2225 GlobalToIndirectSymMap.clear();
2226 ExternalFnToStubMap.clear();
2227 PendingFunctions.clear();
2228
2229 return;
2230 }
2231
2232 void reset() {
2233 releaseUnnecessary();
2234
2235 mpSymbolLookupFn = NULL;
2236 mpSymbolLookupContext = NULL;
2237
2238 mpTJI = NULL;
2239 mpTD = NULL;
2240
Zonr Chang932648d2010-10-13 22:23:56 +08002241 for (EmittedFunctionsMapTy::iterator I = mEmittedFunctions.begin(),
2242 E = mEmittedFunctions.end();
2243 I != E;
2244 I++)
2245 if (I->second != NULL)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002246 delete I->second;
2247 mEmittedFunctions.clear();
2248
2249 mpMemMgr->reset();
2250
2251 return;
2252 }
2253
Zonr Chang932648d2010-10-13 22:23:56 +08002254 void *lookup(const char *Name) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002255 return lookup( llvm::StringRef(Name) );
2256 }
2257
Zonr Chang932648d2010-10-13 22:23:56 +08002258 void *lookup(const llvm::StringRef &Name) {
2259 EmittedFunctionsMapTy::const_iterator I =
2260 mEmittedFunctions.find(Name.str());
2261 if (I == mEmittedFunctions.end())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002262 return NULL;
2263 else
2264 return I->second->Code;
2265 }
2266
Zonr Chang932648d2010-10-13 22:23:56 +08002267 void getFunctionNames(BCCsizei *actualFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002268 BCCsizei maxFunctionCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002269 BCCchar **functions) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002270 int functionCount = mEmittedFunctions.size();
2271
Zonr Chang932648d2010-10-13 22:23:56 +08002272 if (actualFunctionCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002273 *actualFunctionCount = functionCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002274 if (functionCount > maxFunctionCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002275 functionCount = maxFunctionCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002276 if (functions)
2277 for (EmittedFunctionsMapTy::const_iterator
2278 I = mEmittedFunctions.begin(), E = mEmittedFunctions.end();
2279 (I != E) && (functionCount > 0);
2280 I++, functionCount--)
2281 *functions++ = const_cast<BCCchar*>(I->first.c_str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002282
2283 return;
2284 }
2285
Zonr Chang932648d2010-10-13 22:23:56 +08002286 void getFunctionBinary(BCCchar *label,
2287 BCCvoid **base,
2288 BCCsizei *length) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002289 EmittedFunctionsMapTy::const_iterator I = mEmittedFunctions.find(label);
Zonr Chang932648d2010-10-13 22:23:56 +08002290 if (I == mEmittedFunctions.end()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002291 *base = NULL;
2292 *length = 0;
2293 } else {
2294 *base = I->second->Code;
2295 *length = I->second->Size;
2296 }
2297 return;
2298 }
2299
2300 ~CodeEmitter() {
Zonr Chang932648d2010-10-13 22:23:56 +08002301 delete mpMemMgr;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002302#if defined(USE_DISASSEMBLER)
Zonr Chang932648d2010-10-13 22:23:56 +08002303 delete mpAsmInfo;
2304 delete mpDisassmbler;
2305 delete mpIP;
Shih-wei Liaocd61af32010-04-29 00:02:57 -07002306#endif
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002307 return;
2308 }
Zonr Chang932648d2010-10-13 22:23:56 +08002309 };
2310 // End of Class CodeEmitter
2311 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002312
Zonr Chang932648d2010-10-13 22:23:56 +08002313 // The CodeEmitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002314 llvm::OwningPtr<CodeEmitter> mCodeEmitter;
Zonr Chang932648d2010-10-13 22:23:56 +08002315 CodeEmitter *createCodeEmitter() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002316 mCodeEmitter.reset(new CodeEmitter(mCodeMemMgr.take()));
2317 return mCodeEmitter.get();
2318 }
2319
2320 BCCSymbolLookupFn mpSymbolLookupFn;
Zonr Chang932648d2010-10-13 22:23:56 +08002321 void *mpSymbolLookupContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002322
Zonr Chang932648d2010-10-13 22:23:56 +08002323 llvm::LLVMContext *mContext;
2324 llvm::Module *mModule;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002325
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002326 bool mHasLinked;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002327
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002328 public:
Zonr Chang932648d2010-10-13 22:23:56 +08002329 Compiler()
2330 : mpSymbolLookupFn(NULL),
2331 mpSymbolLookupContext(NULL),
2332 mContext(NULL),
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002333 mModule(NULL),
2334 mHasLinked(NULL) {
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002335 llvm::remove_fatal_error_handler();
2336 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002337 mContext = new llvm::LLVMContext();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002338 return;
2339 }
2340
Zonr Chang932648d2010-10-13 22:23:56 +08002341 // interface for BCCscript::registerSymbolCallback()
2342 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002343 mpSymbolLookupFn = pFn;
2344 mpSymbolLookupContext = pContext;
2345 return;
2346 }
2347
Zonr Changdbee68b2010-10-22 05:02:16 +08002348 int loadModule(llvm::Module *module) {
2349 GlobalInitialization();
2350 mModule = module;
2351 return hasError();
2352 }
2353
Zonr Chang932648d2010-10-13 22:23:56 +08002354 int loadModule(const char *bitcode, size_t bitcodeSize) {
Zonr Chang97f5e612010-10-22 20:38:26 +08002355 llvm::OwningPtr<llvm::MemoryBuffer> SB;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002356
Zonr Chang932648d2010-10-13 22:23:56 +08002357 if (bitcode == NULL || bitcodeSize <= 0)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002358 return 0;
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002359
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002360 GlobalInitialization();
2361
Zonr Chang932648d2010-10-13 22:23:56 +08002362 // Package input to object MemoryBuffer
Zonr Chang97f5e612010-10-22 20:38:26 +08002363 SB.reset(llvm::MemoryBuffer::getMemBuffer(
2364 llvm::StringRef(bitcode, bitcodeSize)));
2365
2366 if (SB.get() == NULL) {
2367 setError("Error reading input program bitcode into memory");
2368 return hasError();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002369 }
2370
Zonr Chang932648d2010-10-13 22:23:56 +08002371 // Read the input Bitcode as a Module
Zonr Chang97f5e612010-10-22 20:38:26 +08002372 mModule = llvm::ParseBitcodeFile(SB.get(), *mContext, &mError);
2373 SB.reset();
2374 return hasError();
2375 }
Shih-wei Liaoc5611992010-05-09 06:37:55 -07002376
Zonr Chang97f5e612010-10-22 20:38:26 +08002377 int linkModule(const char *bitcode, size_t bitcodeSize) {
2378 llvm::OwningPtr<llvm::MemoryBuffer> SB;
2379
2380 if (bitcode == NULL || bitcodeSize <= 0)
2381 return 0;
2382
2383 if (mModule == NULL) {
2384 setError("No module presents for linking");
2385 return hasError();
2386 }
2387
2388 SB.reset(llvm::MemoryBuffer::getMemBuffer(
2389 llvm::StringRef(bitcode, bitcodeSize)));
2390
2391 if (SB.get() == NULL) {
2392 setError("Error reading input library bitcode into memory");
2393 return hasError();
2394 }
2395
2396 llvm::OwningPtr<llvm::Module> Lib(llvm::ParseBitcodeFile(SB.get(),
2397 *mContext,
2398 &mError));
2399 if (Lib.get() == NULL)
2400 return hasError();
2401
2402 if (llvm::Linker::LinkModules(mModule, Lib.take(), &mError))
2403 return hasError();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002404
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002405 // Everything for linking should be settled down here with no error occurs
2406 mHasLinked = true;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002407 return hasError();
2408 }
2409
Zonr Chang932648d2010-10-13 22:23:56 +08002410 // interace for bccCompileScript()
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002411 int compile() {
Zonr Chang932648d2010-10-13 22:23:56 +08002412 llvm::TargetData *TD = NULL;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002413
Zonr Chang932648d2010-10-13 22:23:56 +08002414 llvm::TargetMachine *TM = NULL;
2415 const llvm::Target *Target;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002416 std::string FeaturesStr;
2417
Zonr Chang932648d2010-10-13 22:23:56 +08002418 llvm::FunctionPassManager *CodeGenPasses = NULL;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002419
Zonr Chang932648d2010-10-13 22:23:56 +08002420 const llvm::NamedMDNode *PragmaMetadata;
2421 const llvm::NamedMDNode *ExportVarMetadata;
2422 const llvm::NamedMDNode *ExportFuncMetadata;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002423
Zonr Chang932648d2010-10-13 22:23:56 +08002424 if (mModule == NULL) // No module was loaded
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002425 return 0;
2426
Zonr Chang932648d2010-10-13 22:23:56 +08002427 // Create TargetMachine
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002428 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
Zonr Chang932648d2010-10-13 22:23:56 +08002429 if (hasError())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002430 goto on_bcc_compile_error;
2431
Zonr Chang932648d2010-10-13 22:23:56 +08002432 if (!CPU.empty() || !Features.empty()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002433 llvm::SubtargetFeatures F;
2434 F.setCPU(CPU);
Zonr Chang932648d2010-10-13 22:23:56 +08002435 for (std::vector<std::string>::const_iterator I = Features.begin(),
2436 E = Features.end();
2437 I != E;
2438 I++)
2439 F.AddFeature(*I);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002440 FeaturesStr = F.getString();
2441 }
2442
2443 TM = Target->createTargetMachine(Triple, FeaturesStr);
Zonr Chang932648d2010-10-13 22:23:56 +08002444 if (TM == NULL) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002445 setError("Failed to create target machine implementation for the"
2446 " specified triple '" + Triple + "'");
2447 goto on_bcc_compile_error;
2448 }
2449
Zonr Chang932648d2010-10-13 22:23:56 +08002450 // Create memory manager for creation of code emitter later.
2451 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002452 setError("Failed to startup memory management for further compilation");
2453 goto on_bcc_compile_error;
2454 }
2455
Zonr Chang932648d2010-10-13 22:23:56 +08002456 // Create code emitter
2457 if (!mCodeEmitter.get()) {
2458 if (!createCodeEmitter()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002459 setError("Failed to create machine code emitter to complete"
2460 " the compilation");
2461 goto on_bcc_compile_error;
2462 }
2463 } else {
Zonr Chang932648d2010-10-13 22:23:56 +08002464 // Reuse the code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002465 mCodeEmitter->reset();
2466 }
2467
2468 mCodeEmitter->setTargetMachine(*TM);
2469 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
2470 mpSymbolLookupContext);
2471
Zonr Chang932648d2010-10-13 22:23:56 +08002472 // Get target data from Module
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002473 TD = new llvm::TargetData(mModule);
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002474
Zonr Chang5d35b972010-10-23 14:36:47 +08002475 // Load named metadata
2476 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
2477 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
2478 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
2479
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002480 // Create LTO passes and run them on the mModule
2481 if (mHasLinked) {
Zonr Chang5d35b972010-10-23 14:36:47 +08002482 llvm::TimePassesIsEnabled = true;
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002483 llvm::PassManager LTOPasses;
Zonr Chang5d35b972010-10-23 14:36:47 +08002484 LTOPasses.add(new llvm::TargetData(*TD));
2485
2486 std::vector<const char*> ExportSymbols;
2487
2488 // A workaround for getting export variable and function name. Will refine
2489 // it soon.
2490 if (ExportVarMetadata) {
2491 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
2492 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
2493 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2494 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
2495 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
2496 llvm::StringRef ExportVarName =
2497 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
2498 ExportSymbols.push_back(ExportVarName.data());
2499 }
2500 }
2501 }
2502 }
2503
2504 if (ExportFuncMetadata) {
2505 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
2506 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
2507 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
2508 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
2509 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
2510 llvm::StringRef ExportFuncName =
2511 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
2512 ExportSymbols.push_back(ExportFuncName.data());
2513 }
2514 }
2515 }
2516 }
2517 // root() and init() are born to be exported
2518 ExportSymbols.push_back("root");
2519 ExportSymbols.push_back("init");
2520
Zonr Change5c7a542010-10-24 01:07:27 +08002521 // We now create passes list performing LTO. These are copied from
2522 // (including comments) llvm::createStandardLTOPasses().
2523
2524 // Internalize all other symbols not listed in ExportSymbols
Zonr Chang5d35b972010-10-23 14:36:47 +08002525 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002526
Zonr Change5c7a542010-10-24 01:07:27 +08002527 // Propagate constants at call sites into the functions they call. This
2528 // opens opportunities for globalopt (and inlining) by substituting
2529 // function pointers passed as arguments to direct uses of functions.
2530 LTOPasses.add(llvm::createIPSCCPPass());
2531
2532 // Now that we internalized some globals, see if we can hack on them!
2533 LTOPasses.add(llvm::createGlobalOptimizerPass());
2534
2535 // Linking modules together can lead to duplicated global constants, only
2536 // keep one copy of each constant...
2537 LTOPasses.add(llvm::createConstantMergePass());
2538
2539 // Remove unused arguments from functions...
2540 LTOPasses.add(llvm::createDeadArgEliminationPass());
2541
2542 // Reduce the code after globalopt and ipsccp. Both can open up
2543 // significant simplification opportunities, and both can propagate
2544 // functions through function pointers. When this happens, we often have
2545 // to resolve varargs calls, etc, so let instcombine do this.
2546 LTOPasses.add(llvm::createInstructionCombiningPass());
2547
2548 // Inline small functions
2549 LTOPasses.add(llvm::createFunctionInliningPass());
2550
2551 // Remove dead EH info.
2552 LTOPasses.add(llvm::createPruneEHPass());
2553
2554 // Internalize the globals again after inlining
2555 LTOPasses.add(llvm::createGlobalOptimizerPass());
2556
2557 // Remove dead functions.
2558 LTOPasses.add(llvm::createGlobalDCEPass());
2559
2560 // If we didn't decide to inline a function, check to see if we can
2561 // transform it to pass arguments by value instead of by reference.
2562 LTOPasses.add(llvm::createArgumentPromotionPass());
2563
2564 // The IPO passes may leave cruft around. Clean up after them.
2565 LTOPasses.add(llvm::createInstructionCombiningPass());
2566 LTOPasses.add(llvm::createJumpThreadingPass());
2567
2568 // Break up allocas
2569 LTOPasses.add(llvm::createScalarReplAggregatesPass());
2570
2571 // Run a few AA driven optimizations here and now, to cleanup the code.
2572 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
2573 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
2574
2575 // Hoist loop invariants.
2576 LTOPasses.add(llvm::createLICMPass());
2577
2578 // Remove redundancies.
2579 LTOPasses.add(llvm::createGVNPass());
2580
2581 // Remove dead memcpys.
2582 LTOPasses.add(llvm::createMemCpyOptPass());
2583
2584 // Nuke dead stores.
2585 LTOPasses.add(llvm::createDeadStoreEliminationPass());
2586
2587 // Cleanup and simplify the code after the scalar optimizations.
2588 LTOPasses.add(llvm::createInstructionCombiningPass());
2589
2590 LTOPasses.add(llvm::createJumpThreadingPass());
2591
2592 // Delete basic blocks, which optimization passes may have killed.
2593 LTOPasses.add(llvm::createCFGSimplificationPass());
2594
2595 // Now that we have optimized the program, discard unreachable functions.
2596 LTOPasses.add(llvm::createGlobalDCEPass());
2597
Zonr Chang6e1d6c32010-10-23 11:57:16 +08002598 LTOPasses.run(*mModule);
2599 }
2600
Zonr Chang932648d2010-10-13 22:23:56 +08002601 // Create code-gen pass to run the code emitter
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002602 CodeGenPasses = new llvm::FunctionPassManager(mModule);
Zonr Chang932648d2010-10-13 22:23:56 +08002603 CodeGenPasses->add(TD); // Will take the ownership of TD
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002604
Zonr Chang932648d2010-10-13 22:23:56 +08002605 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
2606 *mCodeEmitter,
2607 CodeGenOptLevel)) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002608 setError("The machine code emission is not supported by BCC on target '"
2609 + Triple + "'");
2610 goto on_bcc_compile_error;
2611 }
2612
Zonr Chang932648d2010-10-13 22:23:56 +08002613 // Run the pass (the code emitter) on every non-declaration function in the
2614 // module
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002615 CodeGenPasses->doInitialization();
Zonr Chang932648d2010-10-13 22:23:56 +08002616 for (llvm::Module::iterator I = mModule->begin(), E = mModule->end();
2617 I != E;
2618 I++)
2619 if (!I->isDeclaration())
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002620 CodeGenPasses->run(*I);
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002621
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002622 CodeGenPasses->doFinalization();
2623
Zonr Chang932648d2010-10-13 22:23:56 +08002624 // Copy the global address mapping from code emitter and remapping
Zonr Chang932648d2010-10-13 22:23:56 +08002625 if (ExportVarMetadata) {
2626 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
2627 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
2628 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
2629 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
2630 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002631 llvm::StringRef ExportVarName =
2632 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
Zonr Chang932648d2010-10-13 22:23:56 +08002633 CodeEmitter::global_addresses_const_iterator I, E;
2634 for (I = mCodeEmitter->global_address_begin(),
2635 E = mCodeEmitter->global_address_end();
2636 I != E;
2637 I++) {
2638 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002639 continue;
Zonr Chang932648d2010-10-13 22:23:56 +08002640 if (ExportVarName == I->first->getName()) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002641 mExportVars.push_back(I->second);
2642 break;
2643 }
2644 }
Zonr Chang932648d2010-10-13 22:23:56 +08002645 if (I != mCodeEmitter->global_address_end())
2646 continue; // found
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002647 }
2648 }
Zonr Chang932648d2010-10-13 22:23:56 +08002649 // if here, the global variable record in metadata is not found, make an
2650 // empty slot
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002651 mExportVars.push_back(NULL);
2652 }
2653 assert((mExportVars.size() == ExportVarMetadata->getNumOperands()) &&
2654 "Number of slots doesn't match the number of export variables!");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002655 }
2656
Zonr Chang932648d2010-10-13 22:23:56 +08002657 if (ExportFuncMetadata) {
2658 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
2659 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
2660 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
2661 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
2662 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002663 llvm::StringRef ExportFuncName =
2664 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
2665 mExportFuncs.push_back(mCodeEmitter->lookup(ExportFuncName));
2666 }
2667 }
2668 }
2669 }
2670
Zonr Chang932648d2010-10-13 22:23:56 +08002671 // Tell code emitter now can release the memory using during the JIT since
2672 // we have done the code emission
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002673 mCodeEmitter->releaseUnnecessary();
2674
Zonr Chang932648d2010-10-13 22:23:56 +08002675 // Finally, read pragma information from the metadata node of the @Module if
2676 // any.
Zonr Chang932648d2010-10-13 22:23:56 +08002677 if (PragmaMetadata)
2678 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
2679 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
2680 if (Pragma != NULL &&
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002681 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
Zonr Chang932648d2010-10-13 22:23:56 +08002682 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
2683 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002684
Zonr Chang932648d2010-10-13 22:23:56 +08002685 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002686 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
2687 llvm::StringRef PragmaName =
2688 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
2689 llvm::StringRef PragmaValue =
2690 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
2691
Zonr Chang932648d2010-10-13 22:23:56 +08002692 mPragmas.push_back(
2693 std::make_pair(std::string(PragmaName.data(),
2694 PragmaName.size()),
2695 std::string(PragmaValue.data(),
2696 PragmaValue.size())));
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002697 }
2698 }
2699 }
2700
2701 on_bcc_compile_error:
Zonr Chang932648d2010-10-13 22:23:56 +08002702 // LOGE("on_bcc_compiler_error");
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002703 if (CodeGenPasses) {
2704 delete CodeGenPasses;
2705 } else if (TD) {
2706 delete TD;
2707 }
2708 if (TM)
2709 delete TM;
2710
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002711 if (mError.empty()) {
2712 return false;
2713 }
2714
Zonr Chang932648d2010-10-13 22:23:56 +08002715 // LOGE(getErrorMessage());
Shih-wei Liao066d5ef2010-05-11 03:28:39 -07002716 return true;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002717 }
2718
Zonr Chang932648d2010-10-13 22:23:56 +08002719 // interface for bccGetScriptInfoLog()
2720 char *getErrorMessage() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002721 return const_cast<char*>(mError.c_str());
2722 }
2723
Zonr Chang932648d2010-10-13 22:23:56 +08002724 // interface for bccGetScriptLabel()
2725 void *lookup(const char *name) {
2726 void *addr = NULL;
2727 if (mCodeEmitter.get())
2728 // Find function pointer
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002729 addr = mCodeEmitter->lookup(name);
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002730 return addr;
2731 }
2732
Zonr Chang932648d2010-10-13 22:23:56 +08002733 // Interface for bccGetExportVars()
2734 void getExportVars(BCCsizei *actualVarCount,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002735 BCCsizei maxVarCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002736 BCCvoid **vars) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002737 int varCount = mExportVars.size();
2738
Zonr Chang932648d2010-10-13 22:23:56 +08002739 if (actualVarCount)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002740 *actualVarCount = varCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002741 if (varCount > maxVarCount)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002742 varCount = maxVarCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002743 if (vars)
2744 for (ExportVarList::const_iterator I = mExportVars.begin(),
2745 E = mExportVars.end();
2746 I != E;
2747 I++)
2748 *vars++ = *I;
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002749
2750 return;
2751 }
2752
Zonr Chang932648d2010-10-13 22:23:56 +08002753 // Interface for bccGetExportFuncs()
2754 void getExportFuncs(BCCsizei *actualFuncCount,
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002755 BCCsizei maxFuncCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002756 BCCvoid **funcs) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002757 int funcCount = mExportFuncs.size();
2758
Zonr Chang932648d2010-10-13 22:23:56 +08002759 if (actualFuncCount)
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002760 *actualFuncCount = funcCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002761 if (funcCount > maxFuncCount)
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002762 funcCount = maxFuncCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002763 if (funcs)
2764 for (ExportFuncList::const_iterator I = mExportFuncs.begin(),
2765 E = mExportFuncs.end();
2766 I != E;
2767 I++)
2768 *funcs++ = *I;
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002769
2770 return;
2771 }
2772
Zonr Chang932648d2010-10-13 22:23:56 +08002773 // Interface for bccGetPragmas()
2774 void getPragmas(BCCsizei *actualStringCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002775 BCCsizei maxStringCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002776 BCCchar **strings) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002777 int stringCount = mPragmas.size() * 2;
2778
Zonr Chang932648d2010-10-13 22:23:56 +08002779 if (actualStringCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002780 *actualStringCount = stringCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002781 if (stringCount > maxStringCount)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002782 stringCount = maxStringCount;
Zonr Chang932648d2010-10-13 22:23:56 +08002783 if (strings)
2784 for (PragmaList::const_iterator it = mPragmas.begin();
2785 stringCount > 0;
2786 stringCount -= 2, it++) {
2787 *strings++ = const_cast<BCCchar*>(it->first.c_str());
2788 *strings++ = const_cast<BCCchar*>(it->second.c_str());
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002789 }
2790
2791 return;
2792 }
2793
Zonr Chang932648d2010-10-13 22:23:56 +08002794 // Interface for bccGetFunctions()
2795 void getFunctions(BCCsizei *actualFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002796 BCCsizei maxFunctionCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002797 BCCchar **functions) {
2798 if (mCodeEmitter.get())
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002799 mCodeEmitter->getFunctionNames(actualFunctionCount,
2800 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002801 functions);
2802 else
2803 *actualFunctionCount = 0;
2804
2805 return;
2806 }
2807
Zonr Chang932648d2010-10-13 22:23:56 +08002808 // Interface for bccGetFunctionBinary()
2809 void getFunctionBinary(BCCchar *function,
2810 BCCvoid **base,
2811 BCCsizei *length) {
2812 if (mCodeEmitter.get()) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002813 mCodeEmitter->getFunctionBinary(function, base, length);
2814 } else {
2815 *base = NULL;
2816 *length = 0;
2817 }
2818 return;
2819 }
2820
Zonr Chang932648d2010-10-13 22:23:56 +08002821 inline const llvm::Module *getModule() const {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002822 return mModule;
2823 }
2824
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002825 ~Compiler() {
2826 delete mModule;
Zonr Chang932648d2010-10-13 22:23:56 +08002827 // llvm::llvm_shutdown();
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002828 delete mContext;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002829 return;
2830 }
Zonr Chang932648d2010-10-13 22:23:56 +08002831};
2832// End of Class Compiler
2833////////////////////////////////////////////////////////////////////////////////
2834
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002835
2836bool Compiler::GlobalInitialized = false;
2837
Zonr Chang932648d2010-10-13 22:23:56 +08002838// Code generation optimization level for the compiler
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002839llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
2840
2841std::string Compiler::Triple;
2842
2843std::string Compiler::CPU;
2844
2845std::vector<std::string> Compiler::Features;
2846
Zonr Chang932648d2010-10-13 22:23:56 +08002847// The named of metadata node that pragma resides (should be synced with
2848// slang.cpp)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002849const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
2850
Zonr Chang932648d2010-10-13 22:23:56 +08002851// The named of metadata node that export variable name resides (should be
2852// synced with slang_rs_metadata.h)
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002853const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
2854
Zonr Chang932648d2010-10-13 22:23:56 +08002855// The named of metadata node that export function name resides (should be
2856// synced with slang_rs_metadata.h)
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002857const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
2858
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002859struct BCCscript {
Zonr Chang932648d2010-10-13 22:23:56 +08002860 //////////////////////////////////////////////////////////////////////////////
2861 // Part I. Compiler
2862 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002863 Compiler compiler;
2864
Zonr Chang932648d2010-10-13 22:23:56 +08002865 void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002866 compiler.registerSymbolCallback(pFn, pContext);
2867 }
2868
Zonr Chang932648d2010-10-13 22:23:56 +08002869 //////////////////////////////////////////////////////////////////////////////
2870 // Part II. Logistics & Error handling
2871 //////////////////////////////////////////////////////////////////////////////
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002872 BCCscript() {
2873 bccError = BCC_NO_ERROR;
2874 }
2875
2876 ~BCCscript() {
2877 }
2878
2879 void setError(BCCenum error) {
2880 if (bccError == BCC_NO_ERROR && error != BCC_NO_ERROR) {
2881 bccError = error;
2882 }
2883 }
2884
2885 BCCenum getError() {
2886 BCCenum result = bccError;
2887 bccError = BCC_NO_ERROR;
2888 return result;
2889 }
2890
2891 BCCenum bccError;
2892};
2893
2894
2895extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002896BCCscript *bccCreateScript() {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002897 return new BCCscript();
2898}
2899
2900extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002901BCCenum bccGetError(BCCscript *script) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002902 return script->getError();
2903}
2904
2905extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002906void bccDeleteScript(BCCscript *script) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002907 delete script;
2908}
2909
2910extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002911void bccRegisterSymbolCallback(BCCscript *script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002912 BCCSymbolLookupFn pFn,
Zonr Chang932648d2010-10-13 22:23:56 +08002913 BCCvoid *pContext) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002914 script->registerSymbolCallback(pFn, pContext);
2915}
2916
2917extern "C"
Zonr Changdbee68b2010-10-22 05:02:16 +08002918void bccScriptModule(BCCscript *script,
2919 BCCvoid *module) {
2920 script->compiler.loadModule(reinterpret_cast<llvm::Module*>(module));
2921}
2922
2923extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002924void bccScriptBitcode(BCCscript *script,
2925 const BCCchar *bitcode,
2926 BCCint size) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002927 script->compiler.loadModule(bitcode, size);
2928}
2929
2930extern "C"
Zonr Chang97f5e612010-10-22 20:38:26 +08002931void bccLinkBitcode(BCCscript *script,
2932 const BCCchar *bitcode,
2933 BCCint size) {
2934 script->compiler.linkModule(bitcode, size);
2935}
2936
2937extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002938void bccCompileScript(BCCscript *script) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002939 int result = script->compiler.compile();
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002940 if (result)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002941 script->setError(BCC_INVALID_OPERATION);
2942}
2943
2944extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002945void bccGetScriptInfoLog(BCCscript *script,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002946 BCCsizei maxLength,
Zonr Chang932648d2010-10-13 22:23:56 +08002947 BCCsizei *length,
2948 BCCchar *infoLog) {
2949 char *message = script->compiler.getErrorMessage();
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002950 int messageLength = strlen(message) + 1;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002951 if (length)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002952 *length = messageLength;
2953
2954 if (infoLog && maxLength > 0) {
2955 int trimmedLength = maxLength < messageLength ? maxLength : messageLength;
2956 memcpy(infoLog, message, trimmedLength);
2957 infoLog[trimmedLength] = 0;
2958 }
2959}
2960
2961extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002962void bccGetScriptLabel(BCCscript *script,
2963 const BCCchar *name,
2964 BCCvoid **address) {
2965 void *value = script->compiler.lookup(name);
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002966 if (value)
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002967 *address = value;
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002968 else
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002969 script->setError(BCC_INVALID_VALUE);
2970}
2971
2972extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002973void bccGetExportVars(BCCscript *script,
2974 BCCsizei *actualVarCount,
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002975 BCCsizei maxVarCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002976 BCCvoid **vars) {
Shih-wei Liaoabd1e3d2010-04-28 01:47:00 -07002977 script->compiler.getExportVars(actualVarCount, maxVarCount, vars);
2978}
2979
2980extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002981void bccGetExportFuncs(BCCscript *script,
2982 BCCsizei *actualFuncCount,
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002983 BCCsizei maxFuncCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002984 BCCvoid **funcs) {
Shih-wei Liao6bfd5422010-05-07 05:20:22 -07002985 script->compiler.getExportFuncs(actualFuncCount, maxFuncCount, funcs);
2986}
2987
2988extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002989void bccGetPragmas(BCCscript *script,
2990 BCCsizei *actualStringCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002991 BCCsizei maxStringCount,
Zonr Chang932648d2010-10-13 22:23:56 +08002992 BCCchar **strings) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07002993 script->compiler.getPragmas(actualStringCount, maxStringCount, strings);
2994}
2995
2996extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08002997void bccGetFunctions(BCCscript *script,
2998 BCCsizei *actualFunctionCount,
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07002999 BCCsizei maxFunctionCount,
Zonr Chang932648d2010-10-13 22:23:56 +08003000 BCCchar **functions) {
Shih-wei Liao3cf39d12010-04-29 19:30:51 -07003001 script->compiler.getFunctions(actualFunctionCount,
3002 maxFunctionCount,
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003003 functions);
3004}
3005
3006extern "C"
Zonr Chang932648d2010-10-13 22:23:56 +08003007void bccGetFunctionBinary(BCCscript *script,
3008 BCCchar *function,
3009 BCCvoid **base,
3010 BCCsizei *length) {
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003011 script->compiler.getFunctionBinary(function, base, length);
3012}
3013
3014struct BCCtype {
Zonr Chang932648d2010-10-13 22:23:56 +08003015 const Compiler *compiler;
3016 const llvm::Type *t;
Shih-wei Liao77ed6142010-04-07 12:21:42 -07003017};
3018
Zonr Chang932648d2010-10-13 22:23:56 +08003019} // namespace bcc