blob: 16bd68701eaf4efc0d5ea0e0441f51894ac91f4a [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * 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.
15 */
16
Loganc4395232010-11-27 18:54:17 +080017#include "Compiler.h"
Logan1f028c02010-11-27 01:02:48 +080018
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
20
Logan Chiend2a5f302011-07-19 20:32:25 +080021#if USE_OLD_JIT
22#include "OldJIT/ContextManager.h"
23#endif
24
Logan Chien4885cf82011-07-20 10:18:05 +080025#if USE_DISASSEMBLER
26#include "Disassembler/Disassembler.h"
27#endif
28
Logan4dcd6792011-02-28 05:12:00 +080029#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070030#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080031#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080032#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080033#include "Sha1Helper.h"
Loganeb3d12b2010-12-16 06:20:18 +080034
Shih-wei Liao320b5492011-06-20 22:53:33 -070035#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080036#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070037#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080038
Logandf23afa2010-11-27 11:04:54 +080039#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080040
Logandf23afa2010-11-27 11:04:54 +080041#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080042
Logan1f028c02010-11-27 01:02:48 +080043#include "llvm/Bitcode/ReaderWriter.h"
44
Logan1f028c02010-11-27 01:02:48 +080045#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080046#include "llvm/CodeGen/RegAllocRegistry.h"
47#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080048
Logan Chien9347e0b2011-07-07 19:51:47 +080049#include "llvm/MC/SubtargetFeature.h"
50
Logandf23afa2010-11-27 11:04:54 +080051#include "llvm/Transforms/IPO.h"
52#include "llvm/Transforms/Scalar.h"
53
Logandf23afa2010-11-27 11:04:54 +080054#include "llvm/Target/TargetData.h"
55#include "llvm/Target/TargetMachine.h"
56#include "llvm/Target/TargetOptions.h"
57#include "llvm/Target/TargetRegistry.h"
58#include "llvm/Target/TargetSelect.h"
59
60#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070061#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080062#include "llvm/Support/MemoryBuffer.h"
63
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070064#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080065#include "llvm/GlobalValue.h"
66#include "llvm/Linker.h"
67#include "llvm/LLVMContext.h"
68#include "llvm/Metadata.h"
69#include "llvm/Module.h"
70#include "llvm/PassManager.h"
71#include "llvm/Value.h"
72
73#include <errno.h>
74#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080075#include <sys/stat.h>
76#include <sys/types.h>
77#include <unistd.h>
78
Logan75cc8a52011-01-07 06:06:52 +080079#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080080
Logandf23afa2010-11-27 11:04:54 +080081#include <string>
82#include <vector>
Logan1f028c02010-11-27 01:02:48 +080083
Logan1f028c02010-11-27 01:02:48 +080084namespace bcc {
85
86//////////////////////////////////////////////////////////////////////////////
87// BCC Compiler Static Variables
88//////////////////////////////////////////////////////////////////////////////
89
90bool Compiler::GlobalInitialized = false;
91
Logan1f028c02010-11-27 01:02:48 +080092// Code generation optimization level for the compiler
93llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
94
95std::string Compiler::Triple;
96
97std::string Compiler::CPU;
98
99std::vector<std::string> Compiler::Features;
100
Stephen Hines071288a2011-01-27 14:38:26 -0800101// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800102// slang.cpp)
103const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
104
Stephen Hines071288a2011-01-27 14:38:26 -0800105// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800106// synced with slang_rs_metadata.h)
107const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
108
Stephen Hines071288a2011-01-27 14:38:26 -0800109// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800110// synced with slang_rs_metadata.h)
111const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
112
Stephen Hines071288a2011-01-27 14:38:26 -0800113// Name of metadata node where RS object slot info resides (should be
114// synced with slang_rs_metadata.h)
115const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800116
117//////////////////////////////////////////////////////////////////////////////
118// Compiler
119//////////////////////////////////////////////////////////////////////////////
120
121void Compiler::GlobalInitialization() {
122 if (GlobalInitialized)
123 return;
Logan1f028c02010-11-27 01:02:48 +0800124 // if (!llvm::llvm_is_multithreaded())
125 // llvm::llvm_start_multithreaded();
126
127 // Set Triple, CPU and Features here
128 Triple = TARGET_TRIPLE_STRING;
129
Logan1f028c02010-11-27 01:02:48 +0800130 Features.push_back("+vfp3");
Logan1f028c02010-11-27 01:02:48 +0800131
Logan4fe966f2011-02-27 08:26:40 +0800132 // NOTE: Currently, we have to turn off the support for NEON explicitly.
133 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
134 // instructions.
Joseph Wen51001b82011-06-23 18:56:45 -0700135#if ARCH_ARM_HAVE_NEON
136 Features.push_back("+d32");
137 Features.push_back("+neon");
138 Features.push_back("+neonfp");
139#else
140 Features.push_back("+d16");
141 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800142 Features.push_back("-neonfp");
Joseph Wen51001b82011-06-23 18:56:45 -0700143#endif
144
Logan4fe966f2011-02-27 08:26:40 +0800145 Features.push_back("-vmlx");
146
Logan1f028c02010-11-27 01:02:48 +0800147#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
Shih-wei Liaoc2e23c32011-07-19 05:20:58 -0700148 LLVMInitializeARMMCAsmInfo();
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800149 LLVMInitializeARMAsmPrinter();
Logan1f028c02010-11-27 01:02:48 +0800150 LLVMInitializeARMTargetInfo();
151 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800152#endif
153
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800154#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN) || \
155 defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
Shih-wei Liaoc2e23c32011-07-19 05:20:58 -0700156 LLVMInitializeX86MCAsmInfo();
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800157 LLVMInitializeX86AsmPrinter();
Logan1f028c02010-11-27 01:02:48 +0800158 LLVMInitializeX86TargetInfo();
159 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800160#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800161
162#if USE_DISASSEMBLER
163 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800164#endif
165
166 // -O0: llvm::CodeGenOpt::None
167 // -O1: llvm::CodeGenOpt::Less
168 // -O2: llvm::CodeGenOpt::Default
169 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800170 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800171
172 // Below are the global settings to LLVM
173
174 // Disable frame pointer elimination optimization
175 llvm::NoFramePointerElim = false;
176
177 // Use hardfloat ABI
178 //
179 // TODO(all): Need to detect the CPU capability and decide whether to use
180 // softfp. To use softfp, change following 2 lines to
181 //
182 // llvm::FloatABIType = llvm::FloatABI::Soft;
183 // llvm::UseSoftFloat = true;
184 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800185 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800186 llvm::UseSoftFloat = false;
187
Logan1f028c02010-11-27 01:02:48 +0800188#if defined(DEFAULT_X64_CODEGEN)
189 // Data address in X86_64 architecture may reside in a far-away place
190 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
191#else
192 // This is set for the linker (specify how large of the virtual addresses
193 // we can access for all unknown symbols.)
194 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
195#endif
196
197 // Register the scheduler
198 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
199
200 // Register allocation policy:
201 // createFastRegisterAllocator: fast but bad quality
202 // createLinearScanRegisterAllocator: not so fast but good quality
203 llvm::RegisterRegAlloc::setDefault
204 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
205 llvm::createFastRegisterAllocator :
206 llvm::createLinearScanRegisterAllocator);
207
Logan35849002011-01-15 07:30:43 +0800208#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700209 // Read in SHA1 checksum of libbcc and libRS.
210 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700211
212 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800213#endif
Logan75cc8a52011-01-07 06:06:52 +0800214
Logan1f028c02010-11-27 01:02:48 +0800215 GlobalInitialized = true;
216}
217
218
219void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
220 std::string *Error = static_cast<std::string*>(UserData);
221 Error->assign(Message);
222 LOGE("%s", Message.c_str());
223 exit(1);
224}
225
226
Logan Chienda5e0c32011-06-13 03:47:21 +0800227#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800228CodeMemoryManager *Compiler::createCodeMemoryManager() {
229 mCodeMemMgr.reset(new CodeMemoryManager());
230 return mCodeMemMgr.get();
231}
Logan Chienda5e0c32011-06-13 03:47:21 +0800232#endif
Logan1f028c02010-11-27 01:02:48 +0800233
234
Logan Chienda5e0c32011-06-13 03:47:21 +0800235#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800236CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800237 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800238 return mCodeEmitter.get();
239}
Logan Chienda5e0c32011-06-13 03:47:21 +0800240#endif
Logan1f028c02010-11-27 01:02:48 +0800241
242
Logan2a6dc822011-01-06 04:05:20 +0800243Compiler::Compiler(ScriptCompiled *result)
244 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800245#if USE_MCJIT
246 mRSExecutable(NULL),
247#endif
Logan1f028c02010-11-27 01:02:48 +0800248 mpSymbolLookupFn(NULL),
249 mpSymbolLookupContext(NULL),
250 mContext(NULL),
251 mModule(NULL),
252 mHasLinked(false) /* Turn off linker */ {
253 llvm::remove_fatal_error_handler();
254 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
255 mContext = new llvm::LLVMContext();
256 return;
257}
258
Logan1f028c02010-11-27 01:02:48 +0800259
Logan474cbd22011-01-31 01:47:44 +0800260llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
261 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800262
Logan474cbd22011-01-31 01:47:44 +0800263 if (!result) {
264 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
265 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800266 }
267
Logan474cbd22011-01-31 01:47:44 +0800268 return result;
Logan1f028c02010-11-27 01:02:48 +0800269}
270
271
Logan474cbd22011-01-31 01:47:44 +0800272int Compiler::linkModule(llvm::Module *moduleWith) {
273 if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800274 return hasError();
275 }
276
Logan1f028c02010-11-27 01:02:48 +0800277 // Everything for linking should be settled down here with no error occurs
278 mHasLinked = true;
279 return hasError();
280}
281
282
Joseph Wen34c600a2011-07-25 17:59:17 -0700283int Compiler::compile(bool compileOnly) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800284 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800285 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800286 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800287
Logan1f028c02010-11-27 01:02:48 +0800288 std::string FeaturesStr;
289
Logan Chienda5e0c32011-06-13 03:47:21 +0800290 llvm::NamedMDNode const *PragmaMetadata;
291 llvm::NamedMDNode const *ExportVarMetadata;
292 llvm::NamedMDNode const *ExportFuncMetadata;
293 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800294
Logan1f028c02010-11-27 01:02:48 +0800295 if (mModule == NULL) // No module was loaded
296 return 0;
297
298 // Create TargetMachine
299 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
300 if (hasError())
301 goto on_bcc_compile_error;
302
303 if (!CPU.empty() || !Features.empty()) {
304 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800305
306 for (std::vector<std::string>::const_iterator
307 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800308 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800309 }
310
Logan1f028c02010-11-27 01:02:48 +0800311 FeaturesStr = F.getString();
312 }
313
Logan Chiend3fe15c2011-07-20 22:08:39 +0800314 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
315 llvm::Reloc::Static);
Logan1f028c02010-11-27 01:02:48 +0800316 if (TM == NULL) {
317 setError("Failed to create target machine implementation for the"
318 " specified triple '" + Triple + "'");
319 goto on_bcc_compile_error;
320 }
321
Logan Chienda5e0c32011-06-13 03:47:21 +0800322 // Get target data from Module
323 TD = new llvm::TargetData(mModule);
324
325 // Load named metadata
326 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
327 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
328 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
329 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
330
331 // Perform link-time optimization if we have multiple modules
332 if (mHasLinked) {
333 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
334 }
335
336 // Perform code generation
337#if USE_OLD_JIT
338 if (runCodeGen(new llvm::TargetData(*TD), TM,
339 ExportVarMetadata, ExportFuncMetadata) != 0) {
340 goto on_bcc_compile_error;
341 }
342#endif
343
344#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700345 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800346 goto on_bcc_compile_error;
347 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800348
Joseph Wen34c600a2011-07-25 17:59:17 -0700349 if (compileOnly)
350 return 0;
351
352 // Load the ELF Object
353 mRSExecutable =
354 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
355 mEmittedELFExecutable.size(),
356 &resolveSymbolAdapter, this);
357
358 if (!mRSExecutable) {
359 setError("Fail to load emitted ELF relocatable file");
360 goto on_bcc_compile_error;
361 }
362
363 if (ExportVarMetadata) {
364 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
365 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
366
367 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
368 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
369 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
370 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
371 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
372 llvm::StringRef ExportVarName =
373 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
374
375 varList.push_back(
376 rsloaderGetSymbolAddress(mRSExecutable,
377 ExportVarName.str().c_str()));
378 varNameList.push_back(ExportVarName.str());
379#if DEBUG_MCJIT_REFLECT
380 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
381 varList.back());
382#endif
383 continue;
384 }
385 }
386
387 varList.push_back(NULL);
388 }
389 }
390
391 if (ExportFuncMetadata) {
392 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
393 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
394
395 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
396 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
397 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
398 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
399 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
400 llvm::StringRef ExportFuncName =
401 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
402
403 funcList.push_back(
404 rsloaderGetSymbolAddress(mRSExecutable,
405 ExportFuncName.str().c_str()));
406 funcNameList.push_back(ExportFuncName.str());
407#if DEBUG_MCJIT_RELECT
408 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
409 funcList.back());
410#endif
411 }
412 }
413 }
414 }
415
Logan Chien4885cf82011-07-20 10:18:05 +0800416#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700417 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700418 // Get MC codegen emitted function name list
419 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
420 std::vector<char const *> func_list(func_list_size, NULL);
421 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700422
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700423 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700424 for (size_t i = 0; i < func_list_size; ++i) {
425 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
426 if (func) {
427 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800428 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
429 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700430 }
431 }
432 }
433#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800434#endif
435
436 // Read pragma information from the metadata node of the module.
437 if (PragmaMetadata) {
438 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
439
440 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
441 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
442 if (Pragma != NULL &&
443 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
444 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
445 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
446
447 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
448 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
449 llvm::StringRef PragmaName =
450 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
451 llvm::StringRef PragmaValue =
452 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
453
454 pragmaList.push_back(
455 std::make_pair(std::string(PragmaName.data(),
456 PragmaName.size()),
457 std::string(PragmaValue.data(),
458 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700459#if DEBUG_BCC_REFLECT
460 LOGD("compile(): Pragma: %s -> %s\n",
461 pragmaList.back().first.c_str(),
462 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700463#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800464 }
465 }
466 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800467 }
468
469 if (ObjectSlotMetadata) {
470 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
471
472 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
473 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
474 if (ObjectSlot != NULL &&
475 ObjectSlot->getNumOperands() == 1) {
476 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
477 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
478 llvm::StringRef Slot =
479 static_cast<llvm::MDString*>(SlotMDS)->getString();
480 uint32_t USlot = 0;
481 if (Slot.getAsInteger(10, USlot)) {
482 setError("Non-integer object slot value '" + Slot.str() + "'");
483 goto on_bcc_compile_error;
484 }
485 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700486#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700487 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
488#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800489 }
490 }
491 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800492 }
493
494on_bcc_compile_error:
495 // LOGE("on_bcc_compiler_error");
496 if (TD) {
497 delete TD;
498 }
499
500 if (TM) {
501 delete TM;
502 }
503
504 if (mError.empty()) {
505 return 0;
506 }
507
508 // LOGE(getErrorMessage());
509 return 1;
510}
511
512
513#if USE_OLD_JIT
514int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
515 llvm::NamedMDNode const *ExportVarMetadata,
516 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800517 // Create memory manager for creation of code emitter later.
518 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
519 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800520 return 1;
Logan1f028c02010-11-27 01:02:48 +0800521 }
Logan02286cb2011-01-07 00:30:47 +0800522
523 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800524
525 // Create code emitter
526 if (!mCodeEmitter.get()) {
527 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800528 setError("Failed to create machine code emitter for compilation");
529 return 1;
Logan1f028c02010-11-27 01:02:48 +0800530 }
531 } else {
532 // Reuse the code emitter
533 mCodeEmitter->reset();
534 }
535
536 mCodeEmitter->setTargetMachine(*TM);
537 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
538 mpSymbolLookupContext);
539
Logan1f028c02010-11-27 01:02:48 +0800540 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800541 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
542 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800543
Logan Chienda5e0c32011-06-13 03:47:21 +0800544 // Add TargetData to code generation pass manager
545 CodeGenPasses->add(TD);
546
547 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800548 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
549 *mCodeEmitter,
550 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800551 setError("The machine code emission is not supported on '" + Triple + "'");
552 return 1;
Logan1f028c02010-11-27 01:02:48 +0800553 }
554
Logan Chienda5e0c32011-06-13 03:47:21 +0800555 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800556 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800557 for (llvm::Module::iterator
558 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800559 if (!I->isDeclaration()) {
560 CodeGenPasses->run(*I);
561 }
562 }
563
564 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800565
Logan1f028c02010-11-27 01:02:48 +0800566 // Copy the global address mapping from code emitter and remapping
567 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800568 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
569
Logan1f028c02010-11-27 01:02:48 +0800570 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
571 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
572 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
573 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
574 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
575 llvm::StringRef ExportVarName =
576 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
577
578 CodeEmitter::global_addresses_const_iterator I, E;
579 for (I = mCodeEmitter->global_address_begin(),
580 E = mCodeEmitter->global_address_end();
581 I != E; I++) {
582 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
583 continue;
584 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800585 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700586#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700587 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
588#endif
Logan1f028c02010-11-27 01:02:48 +0800589 break;
590 }
591 }
592 if (I != mCodeEmitter->global_address_end())
593 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800594
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700595#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700596 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800597 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700598#endif
Logan1f028c02010-11-27 01:02:48 +0800599 }
600 }
601 // if reaching here, we know the global variable record in metadata is
602 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800603 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800604 }
Logan2a6dc822011-01-06 04:05:20 +0800605
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700606 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
607 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800608 }
609
610 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800611 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
612
Logan1f028c02010-11-27 01:02:48 +0800613 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
614 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
615 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
616 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
617 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
618 llvm::StringRef ExportFuncName =
619 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800620 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700621#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700622 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800623 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700624#endif
Logan1f028c02010-11-27 01:02:48 +0800625 }
626 }
627 }
628 }
629
630 // Tell code emitter now can release the memory using during the JIT since
631 // we have done the code emission
632 mCodeEmitter->releaseUnnecessary();
633
Logan Chienda5e0c32011-06-13 03:47:21 +0800634 return 0;
Logan1f028c02010-11-27 01:02:48 +0800635}
Logan Chienda5e0c32011-06-13 03:47:21 +0800636#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800637
638
Logan Chienda5e0c32011-06-13 03:47:21 +0800639#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700640int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800641 // Decorate mEmittedELFExecutable with formatted ostream
642 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
643
644 // Relax all machine instructions
645 TM->setMCRelaxAll(/* RelaxAll= */ true);
646
647 // Create MC code generation pass manager
648 llvm::PassManager MCCodeGenPasses;
649
650 // Add TargetData to MC code generation pass manager
651 MCCodeGenPasses.add(TD);
652
653 // Add MC code generation passes to pass manager
654 llvm::MCContext *Ctx;
655 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
656 CodeGenOptLevel, false)) {
657 setError("Fail to add passes to emit file");
658 return 1;
659 }
660
661 MCCodeGenPasses.run(*mModule);
662 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800663 return 0;
664}
665#endif // USE_MCJIT
666
667
668int Compiler::runLTO(llvm::TargetData *TD,
669 llvm::NamedMDNode const *ExportVarMetadata,
670 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800671 llvm::PassManager LTOPasses;
672
673 // Add TargetData to LTO passes
674 LTOPasses.add(TD);
675
676 // Collect All Exported Symbols
677 std::vector<const char*> ExportSymbols;
678
679 // Note: This is a workaround for getting export variable and function name.
680 // We should refine it soon.
681 if (ExportVarMetadata) {
682 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
683 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
684 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
685 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
686 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
687 llvm::StringRef ExportVarName =
688 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
689 ExportSymbols.push_back(ExportVarName.data());
690 }
691 }
692 }
693 }
694
695 if (ExportFuncMetadata) {
696 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
697 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
698 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
699 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
700 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
701 llvm::StringRef ExportFuncName =
702 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
703 ExportSymbols.push_back(ExportFuncName.data());
704 }
705 }
706 }
707 }
708
709 // root() and init() are born to be exported
710 ExportSymbols.push_back("root");
711 ExportSymbols.push_back("init");
712
713 // We now create passes list performing LTO. These are copied from
714 // (including comments) llvm::createStandardLTOPasses().
715
716 // Internalize all other symbols not listed in ExportSymbols
717 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
718
719 // Propagate constants at call sites into the functions they call. This
720 // opens opportunities for globalopt (and inlining) by substituting
721 // function pointers passed as arguments to direct uses of functions.
722 LTOPasses.add(llvm::createIPSCCPPass());
723
724 // Now that we internalized some globals, see if we can hack on them!
725 LTOPasses.add(llvm::createGlobalOptimizerPass());
726
727 // Linking modules together can lead to duplicated global constants, only
728 // keep one copy of each constant...
729 LTOPasses.add(llvm::createConstantMergePass());
730
731 // Remove unused arguments from functions...
732 LTOPasses.add(llvm::createDeadArgEliminationPass());
733
734 // Reduce the code after globalopt and ipsccp. Both can open up
735 // significant simplification opportunities, and both can propagate
736 // functions through function pointers. When this happens, we often have
737 // to resolve varargs calls, etc, so let instcombine do this.
738 LTOPasses.add(llvm::createInstructionCombiningPass());
739
740 // Inline small functions
741 LTOPasses.add(llvm::createFunctionInliningPass());
742
743 // Remove dead EH info.
744 LTOPasses.add(llvm::createPruneEHPass());
745
746 // Internalize the globals again after inlining
747 LTOPasses.add(llvm::createGlobalOptimizerPass());
748
749 // Remove dead functions.
750 LTOPasses.add(llvm::createGlobalDCEPass());
751
752 // If we didn't decide to inline a function, check to see if we can
753 // transform it to pass arguments by value instead of by reference.
754 LTOPasses.add(llvm::createArgumentPromotionPass());
755
756 // The IPO passes may leave cruft around. Clean up after them.
757 LTOPasses.add(llvm::createInstructionCombiningPass());
758 LTOPasses.add(llvm::createJumpThreadingPass());
759
760 // Break up allocas
761 LTOPasses.add(llvm::createScalarReplAggregatesPass());
762
763 // Run a few AA driven optimizations here and now, to cleanup the code.
764 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
765 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
766
767 // Hoist loop invariants.
768 LTOPasses.add(llvm::createLICMPass());
769
770 // Remove redundancies.
771 LTOPasses.add(llvm::createGVNPass());
772
773 // Remove dead memcpys.
774 LTOPasses.add(llvm::createMemCpyOptPass());
775
776 // Nuke dead stores.
777 LTOPasses.add(llvm::createDeadStoreEliminationPass());
778
779 // Cleanup and simplify the code after the scalar optimizations.
780 LTOPasses.add(llvm::createInstructionCombiningPass());
781
782 LTOPasses.add(llvm::createJumpThreadingPass());
783
784 // Delete basic blocks, which optimization passes may have killed.
785 LTOPasses.add(llvm::createCFGSimplificationPass());
786
787 // Now that we have optimized the program, discard unreachable functions.
788 LTOPasses.add(llvm::createGlobalDCEPass());
789
790 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800791
792 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800793}
794
795
Logan Chienda5e0c32011-06-13 03:47:21 +0800796#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800797void *Compiler::getSymbolAddress(char const *name) {
798 return rsloaderGetSymbolAddress(mRSExecutable, name);
799}
800#endif
801
802
803#if USE_MCJIT
804void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
805 Compiler *self = reinterpret_cast<Compiler *>(context);
806
807 if (void *Addr = FindRuntimeFunction(name)) {
808 return Addr;
809 }
810
811 if (self->mpSymbolLookupFn) {
812 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
813 return Addr;
814 }
815 }
816
817 LOGE("Unable to resolve symbol: %s\n", name);
818 return NULL;
819}
820#endif
821
822
Logan1f028c02010-11-27 01:02:48 +0800823Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800824 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800825 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800826
Logan Chienda5e0c32011-06-13 03:47:21 +0800827#if USE_MCJIT
828 rsloaderDisposeExec(mRSExecutable);
829#endif
830
Logana4994f52010-11-27 14:06:02 +0800831 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800832}
833
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700834
Logan1f028c02010-11-27 01:02:48 +0800835} // namespace bcc