blob: 2336a01fad9cdb90860803bb17ab9bce4354987b [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
Loganeb3d12b2010-12-16 06:20:18 +080021#include "ContextManager.h"
Logan4dcd6792011-02-28 05:12:00 +080022#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070023#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080024#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080025#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080026#include "Sha1Helper.h"
Loganeb3d12b2010-12-16 06:20:18 +080027
Shih-wei Liao320b5492011-06-20 22:53:33 -070028#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080029#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070030#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080031
Logandf23afa2010-11-27 11:04:54 +080032#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080033
Logandf23afa2010-11-27 11:04:54 +080034#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080035
Logan1f028c02010-11-27 01:02:48 +080036#include "llvm/Bitcode/ReaderWriter.h"
37
Logan1f028c02010-11-27 01:02:48 +080038#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080039#include "llvm/CodeGen/RegAllocRegistry.h"
40#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080041
Logan Chien9347e0b2011-07-07 19:51:47 +080042#include "llvm/MC/SubtargetFeature.h"
43
Logandf23afa2010-11-27 11:04:54 +080044#include "llvm/Transforms/IPO.h"
45#include "llvm/Transforms/Scalar.h"
46
Logandf23afa2010-11-27 11:04:54 +080047#include "llvm/Target/TargetData.h"
48#include "llvm/Target/TargetMachine.h"
49#include "llvm/Target/TargetOptions.h"
50#include "llvm/Target/TargetRegistry.h"
51#include "llvm/Target/TargetSelect.h"
52
53#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070054#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080055#include "llvm/Support/MemoryBuffer.h"
56
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070057#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080058#include "llvm/GlobalValue.h"
59#include "llvm/Linker.h"
60#include "llvm/LLVMContext.h"
61#include "llvm/Metadata.h"
62#include "llvm/Module.h"
63#include "llvm/PassManager.h"
64#include "llvm/Value.h"
65
66#include <errno.h>
67#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080068#include <sys/stat.h>
69#include <sys/types.h>
70#include <unistd.h>
71
Logan75cc8a52011-01-07 06:06:52 +080072#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080073
Logandf23afa2010-11-27 11:04:54 +080074#include <string>
75#include <vector>
Logan1f028c02010-11-27 01:02:48 +080076
Logan1f028c02010-11-27 01:02:48 +080077namespace bcc {
78
79//////////////////////////////////////////////////////////////////////////////
80// BCC Compiler Static Variables
81//////////////////////////////////////////////////////////////////////////////
82
83bool Compiler::GlobalInitialized = false;
84
Logan1f028c02010-11-27 01:02:48 +080085// Code generation optimization level for the compiler
86llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
87
88std::string Compiler::Triple;
89
90std::string Compiler::CPU;
91
92std::vector<std::string> Compiler::Features;
93
Stephen Hines071288a2011-01-27 14:38:26 -080094// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +080095// slang.cpp)
96const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
97
Stephen Hines071288a2011-01-27 14:38:26 -080098// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +080099// synced with slang_rs_metadata.h)
100const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
101
Stephen Hines071288a2011-01-27 14:38:26 -0800102// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800103// synced with slang_rs_metadata.h)
104const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
105
Stephen Hines071288a2011-01-27 14:38:26 -0800106// Name of metadata node where RS object slot info resides (should be
107// synced with slang_rs_metadata.h)
108const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800109
110//////////////////////////////////////////////////////////////////////////////
111// Compiler
112//////////////////////////////////////////////////////////////////////////////
113
114void Compiler::GlobalInitialization() {
115 if (GlobalInitialized)
116 return;
Logan1f028c02010-11-27 01:02:48 +0800117 // if (!llvm::llvm_is_multithreaded())
118 // llvm::llvm_start_multithreaded();
119
120 // Set Triple, CPU and Features here
121 Triple = TARGET_TRIPLE_STRING;
122
Logan1f028c02010-11-27 01:02:48 +0800123 Features.push_back("+vfp3");
Logan1f028c02010-11-27 01:02:48 +0800124
Logan4fe966f2011-02-27 08:26:40 +0800125 // NOTE: Currently, we have to turn off the support for NEON explicitly.
126 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
127 // instructions.
Joseph Wen51001b82011-06-23 18:56:45 -0700128#if ARCH_ARM_HAVE_NEON
129 Features.push_back("+d32");
130 Features.push_back("+neon");
131 Features.push_back("+neonfp");
132#else
133 Features.push_back("+d16");
134 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800135 Features.push_back("-neonfp");
Joseph Wen51001b82011-06-23 18:56:45 -0700136#endif
137
Logan4fe966f2011-02-27 08:26:40 +0800138 Features.push_back("-vmlx");
139
Logan1f028c02010-11-27 01:02:48 +0800140#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
141 LLVMInitializeARMTargetInfo();
142 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800143#endif
144
145#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
146 LLVMInitializeX86TargetInfo();
147 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800148#endif
149
150#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
151 LLVMInitializeX86TargetInfo();
152 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800153#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800154
155#if USE_DISASSEMBLER
156 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800157#endif
158
159 // -O0: llvm::CodeGenOpt::None
160 // -O1: llvm::CodeGenOpt::Less
161 // -O2: llvm::CodeGenOpt::Default
162 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800163 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800164
165 // Below are the global settings to LLVM
166
167 // Disable frame pointer elimination optimization
168 llvm::NoFramePointerElim = false;
169
170 // Use hardfloat ABI
171 //
172 // TODO(all): Need to detect the CPU capability and decide whether to use
173 // softfp. To use softfp, change following 2 lines to
174 //
175 // llvm::FloatABIType = llvm::FloatABI::Soft;
176 // llvm::UseSoftFloat = true;
177 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800178 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800179 llvm::UseSoftFloat = false;
180
181 // BCC needs all unknown symbols resolved at JIT/compilation time.
182 // So we don't need any dynamic relocation model.
183 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
184
185#if defined(DEFAULT_X64_CODEGEN)
186 // Data address in X86_64 architecture may reside in a far-away place
187 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
188#else
189 // This is set for the linker (specify how large of the virtual addresses
190 // we can access for all unknown symbols.)
191 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
192#endif
193
194 // Register the scheduler
195 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
196
197 // Register allocation policy:
198 // createFastRegisterAllocator: fast but bad quality
199 // createLinearScanRegisterAllocator: not so fast but good quality
200 llvm::RegisterRegAlloc::setDefault
201 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
202 llvm::createFastRegisterAllocator :
203 llvm::createLinearScanRegisterAllocator);
204
Logan35849002011-01-15 07:30:43 +0800205#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700206 // Read in SHA1 checksum of libbcc and libRS.
207 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700208
209 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800210#endif
Logan75cc8a52011-01-07 06:06:52 +0800211
Logan1f028c02010-11-27 01:02:48 +0800212 GlobalInitialized = true;
213}
214
215
216void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
217 std::string *Error = static_cast<std::string*>(UserData);
218 Error->assign(Message);
219 LOGE("%s", Message.c_str());
220 exit(1);
221}
222
223
Logan Chienda5e0c32011-06-13 03:47:21 +0800224#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800225CodeMemoryManager *Compiler::createCodeMemoryManager() {
226 mCodeMemMgr.reset(new CodeMemoryManager());
227 return mCodeMemMgr.get();
228}
Logan Chienda5e0c32011-06-13 03:47:21 +0800229#endif
Logan1f028c02010-11-27 01:02:48 +0800230
231
Logan Chienda5e0c32011-06-13 03:47:21 +0800232#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800233CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800234 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800235 return mCodeEmitter.get();
236}
Logan Chienda5e0c32011-06-13 03:47:21 +0800237#endif
Logan1f028c02010-11-27 01:02:48 +0800238
239
Logan2a6dc822011-01-06 04:05:20 +0800240Compiler::Compiler(ScriptCompiled *result)
241 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800242#if USE_MCJIT
243 mRSExecutable(NULL),
244#endif
Logan1f028c02010-11-27 01:02:48 +0800245 mpSymbolLookupFn(NULL),
246 mpSymbolLookupContext(NULL),
247 mContext(NULL),
248 mModule(NULL),
249 mHasLinked(false) /* Turn off linker */ {
250 llvm::remove_fatal_error_handler();
251 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
252 mContext = new llvm::LLVMContext();
253 return;
254}
255
Logan1f028c02010-11-27 01:02:48 +0800256
Logan Chienda5e0c32011-06-13 03:47:21 +0800257#if USE_MCJIT
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700258// input objPath: For example,
259// /data/user/0/com.example.android.rs.fountain/cache/
260// @com.example.android.rs.fountain:raw@fountain.oBCC
261// output objPath: /data/user/0/com.example.android.rs.fountain/cache/
262// fountain.o
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700263//
264bool Compiler::getObjPath(std::string &objPath) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700265 size_t found0 = objPath.find("@");
266 size_t found1 = objPath.rfind("@");
267
268 if (found0 == found1 ||
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800269 found0 == std::string::npos ||
270 found1 == std::string::npos) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700271 LOGE("Ill formatted resource name '%s'. The name should contain 2 @s",
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700272 objPath.c_str());
273 return false;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700274 }
275
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700276 objPath.replace(found0, found1 - found0 + 1, "", 0);
277 objPath.resize(objPath.length() - 3);
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700278
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700279 LOGV("objPath = %s", objPath.c_str());
280 return true;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700281}
Logan Chienda5e0c32011-06-13 03:47:21 +0800282#endif
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700283
284
Logan474cbd22011-01-31 01:47:44 +0800285llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
286 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800287
Logan474cbd22011-01-31 01:47:44 +0800288 if (!result) {
289 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
290 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800291 }
292
Logan474cbd22011-01-31 01:47:44 +0800293 return result;
Logan1f028c02010-11-27 01:02:48 +0800294}
295
296
Logan474cbd22011-01-31 01:47:44 +0800297int Compiler::linkModule(llvm::Module *moduleWith) {
298 if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800299 return hasError();
300 }
301
Logan1f028c02010-11-27 01:02:48 +0800302 // Everything for linking should be settled down here with no error occurs
303 mHasLinked = true;
304 return hasError();
305}
306
307
Logan1f028c02010-11-27 01:02:48 +0800308int Compiler::compile() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800309 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800310 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800311 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800312
Logan1f028c02010-11-27 01:02:48 +0800313 std::string FeaturesStr;
314
Logan Chienda5e0c32011-06-13 03:47:21 +0800315 llvm::NamedMDNode const *PragmaMetadata;
316 llvm::NamedMDNode const *ExportVarMetadata;
317 llvm::NamedMDNode const *ExportFuncMetadata;
318 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800319
Logan1f028c02010-11-27 01:02:48 +0800320 if (mModule == NULL) // No module was loaded
321 return 0;
322
323 // Create TargetMachine
324 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
325 if (hasError())
326 goto on_bcc_compile_error;
327
328 if (!CPU.empty() || !Features.empty()) {
329 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800330
331 for (std::vector<std::string>::const_iterator
332 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800333 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800334 }
335
Logan1f028c02010-11-27 01:02:48 +0800336 FeaturesStr = F.getString();
337 }
338
Shih-wei Liao029057e2011-07-02 11:34:35 -0700339 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr);
Logan1f028c02010-11-27 01:02:48 +0800340 if (TM == NULL) {
341 setError("Failed to create target machine implementation for the"
342 " specified triple '" + Triple + "'");
343 goto on_bcc_compile_error;
344 }
345
Logan Chienda5e0c32011-06-13 03:47:21 +0800346 // Get target data from Module
347 TD = new llvm::TargetData(mModule);
348
349 // Load named metadata
350 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
351 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
352 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
353 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
354
355 // Perform link-time optimization if we have multiple modules
356 if (mHasLinked) {
357 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
358 }
359
360 // Perform code generation
361#if USE_OLD_JIT
362 if (runCodeGen(new llvm::TargetData(*TD), TM,
363 ExportVarMetadata, ExportFuncMetadata) != 0) {
364 goto on_bcc_compile_error;
365 }
366#endif
367
368#if USE_MCJIT
369 if (runMCCodeGen(new llvm::TargetData(*TD), TM,
370 ExportVarMetadata, ExportFuncMetadata) != 0) {
371 goto on_bcc_compile_error;
372 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800373
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700374#if USE_DISASSEMBLER && DEBUG_MCJIT_DISASSEMBLE
375 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700376 // Get MC codegen emitted function name list
377 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
378 std::vector<char const *> func_list(func_list_size, NULL);
379 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700380
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700381 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700382 for (size_t i = 0; i < func_list_size; ++i) {
383 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
384 if (func) {
385 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800386 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
387 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700388 }
389 }
390 }
391#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800392#endif
393
394 // Read pragma information from the metadata node of the module.
395 if (PragmaMetadata) {
396 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
397
398 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
399 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
400 if (Pragma != NULL &&
401 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
402 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
403 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
404
405 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
406 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
407 llvm::StringRef PragmaName =
408 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
409 llvm::StringRef PragmaValue =
410 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
411
412 pragmaList.push_back(
413 std::make_pair(std::string(PragmaName.data(),
414 PragmaName.size()),
415 std::string(PragmaValue.data(),
416 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700417#if DEBUG_BCC_REFLECT
418 LOGD("compile(): Pragma: %s -> %s\n",
419 pragmaList.back().first.c_str(),
420 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700421#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800422 }
423 }
424 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800425 }
426
427 if (ObjectSlotMetadata) {
428 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
429
430 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
431 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
432 if (ObjectSlot != NULL &&
433 ObjectSlot->getNumOperands() == 1) {
434 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
435 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
436 llvm::StringRef Slot =
437 static_cast<llvm::MDString*>(SlotMDS)->getString();
438 uint32_t USlot = 0;
439 if (Slot.getAsInteger(10, USlot)) {
440 setError("Non-integer object slot value '" + Slot.str() + "'");
441 goto on_bcc_compile_error;
442 }
443 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700444#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700445 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
446#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800447 }
448 }
449 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800450 }
451
452on_bcc_compile_error:
453 // LOGE("on_bcc_compiler_error");
454 if (TD) {
455 delete TD;
456 }
457
458 if (TM) {
459 delete TM;
460 }
461
462 if (mError.empty()) {
463 return 0;
464 }
465
466 // LOGE(getErrorMessage());
467 return 1;
468}
469
470
471#if USE_OLD_JIT
472int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
473 llvm::NamedMDNode const *ExportVarMetadata,
474 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800475 // Create memory manager for creation of code emitter later.
476 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
477 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800478 return 1;
Logan1f028c02010-11-27 01:02:48 +0800479 }
Logan02286cb2011-01-07 00:30:47 +0800480
481 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800482
483 // Create code emitter
484 if (!mCodeEmitter.get()) {
485 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800486 setError("Failed to create machine code emitter for compilation");
487 return 1;
Logan1f028c02010-11-27 01:02:48 +0800488 }
489 } else {
490 // Reuse the code emitter
491 mCodeEmitter->reset();
492 }
493
494 mCodeEmitter->setTargetMachine(*TM);
495 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
496 mpSymbolLookupContext);
497
Logan1f028c02010-11-27 01:02:48 +0800498 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800499 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
500 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800501
Logan Chienda5e0c32011-06-13 03:47:21 +0800502 // Add TargetData to code generation pass manager
503 CodeGenPasses->add(TD);
504
505 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800506 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
507 *mCodeEmitter,
508 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800509 setError("The machine code emission is not supported on '" + Triple + "'");
510 return 1;
Logan1f028c02010-11-27 01:02:48 +0800511 }
512
Logan Chienda5e0c32011-06-13 03:47:21 +0800513 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800514 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800515 for (llvm::Module::iterator
516 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800517 if (!I->isDeclaration()) {
518 CodeGenPasses->run(*I);
519 }
520 }
521
522 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800523
Logan1f028c02010-11-27 01:02:48 +0800524 // Copy the global address mapping from code emitter and remapping
525 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800526 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
527
Logan1f028c02010-11-27 01:02:48 +0800528 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
529 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
530 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
531 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
532 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
533 llvm::StringRef ExportVarName =
534 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
535
536 CodeEmitter::global_addresses_const_iterator I, E;
537 for (I = mCodeEmitter->global_address_begin(),
538 E = mCodeEmitter->global_address_end();
539 I != E; I++) {
540 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
541 continue;
542 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800543 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700544#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700545 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
546#endif
Logan1f028c02010-11-27 01:02:48 +0800547 break;
548 }
549 }
550 if (I != mCodeEmitter->global_address_end())
551 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800552
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700553#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700554 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800555 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700556#endif
Logan1f028c02010-11-27 01:02:48 +0800557 }
558 }
559 // if reaching here, we know the global variable record in metadata is
560 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800561 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800562 }
Logan2a6dc822011-01-06 04:05:20 +0800563
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700564 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
565 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800566 }
567
568 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800569 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
570
Logan1f028c02010-11-27 01:02:48 +0800571 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
572 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
573 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
574 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
575 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
576 llvm::StringRef ExportFuncName =
577 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800578 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700579#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700580 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800581 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700582#endif
Logan1f028c02010-11-27 01:02:48 +0800583 }
584 }
585 }
586 }
587
588 // Tell code emitter now can release the memory using during the JIT since
589 // we have done the code emission
590 mCodeEmitter->releaseUnnecessary();
591
Logan Chienda5e0c32011-06-13 03:47:21 +0800592 return 0;
Logan1f028c02010-11-27 01:02:48 +0800593}
Logan Chienda5e0c32011-06-13 03:47:21 +0800594#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800595
596
Logan Chienda5e0c32011-06-13 03:47:21 +0800597#if USE_MCJIT
598int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
599 llvm::NamedMDNode const *ExportVarMetadata,
600 llvm::NamedMDNode const *ExportFuncMetadata) {
601 // Decorate mEmittedELFExecutable with formatted ostream
602 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
603
604 // Relax all machine instructions
605 TM->setMCRelaxAll(/* RelaxAll= */ true);
606
607 // Create MC code generation pass manager
608 llvm::PassManager MCCodeGenPasses;
609
610 // Add TargetData to MC code generation pass manager
611 MCCodeGenPasses.add(TD);
612
613 // Add MC code generation passes to pass manager
614 llvm::MCContext *Ctx;
615 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
616 CodeGenOptLevel, false)) {
617 setError("Fail to add passes to emit file");
618 return 1;
619 }
620
621 MCCodeGenPasses.run(*mModule);
622 OutSVOS.flush();
623
624 // Load the ELF Object
625 mRSExecutable =
626 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
627 mEmittedELFExecutable.size(),
628 &resolveSymbolAdapter, this);
629
630 if (!mRSExecutable) {
631 setError("Fail to load emitted ELF relocatable file");
632 return 1;
633 }
634
635#if !USE_OLD_JIT
636 // Note: If old JIT is compiled then we prefer the old version instead of the
637 // new version.
638
639 if (ExportVarMetadata) {
640 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
Joseph Wenf36637f2011-07-06 18:27:12 -0700641 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
Logan Chienda5e0c32011-06-13 03:47:21 +0800642
643 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
644 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
Logan Chien70dd9982011-06-13 23:21:39 +0800645 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
646 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
647 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
648 llvm::StringRef ExportVarName =
649 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
650
651 varList.push_back(
652 rsloaderGetSymbolAddress(mRSExecutable,
653 ExportVarName.str().c_str()));
Joseph Wenf36637f2011-07-06 18:27:12 -0700654 varNameList.push_back(ExportVarName.str());
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700655#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700656 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Logan Chien70dd9982011-06-13 23:21:39 +0800657 varList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700658#endif
Logan Chien70dd9982011-06-13 23:21:39 +0800659 continue;
660 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800661 }
662
Logan Chien70dd9982011-06-13 23:21:39 +0800663 varList.push_back(NULL);
Logan Chienda5e0c32011-06-13 03:47:21 +0800664 }
665 }
666
667 if (ExportFuncMetadata) {
668 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
Joseph Wenf36637f2011-07-06 18:27:12 -0700669 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
Logan Chienda5e0c32011-06-13 03:47:21 +0800670
671 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
672 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
673 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
674 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
675 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
676 llvm::StringRef ExportFuncName =
677 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
678
679 funcList.push_back(
680 rsloaderGetSymbolAddress(mRSExecutable,
681 ExportFuncName.str().c_str()));
Joseph Wenf36637f2011-07-06 18:27:12 -0700682 funcNameList.push_back(ExportFuncName.str());
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700683#if DEBUG_MCJIT_RELECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700684 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800685 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700686#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800687 }
688 }
689 }
690 }
691#endif // !USE_OLD_JIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800692 return 0;
693}
694#endif // USE_MCJIT
695
696
697int Compiler::runLTO(llvm::TargetData *TD,
698 llvm::NamedMDNode const *ExportVarMetadata,
699 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800700 llvm::PassManager LTOPasses;
701
702 // Add TargetData to LTO passes
703 LTOPasses.add(TD);
704
705 // Collect All Exported Symbols
706 std::vector<const char*> ExportSymbols;
707
708 // Note: This is a workaround for getting export variable and function name.
709 // We should refine it soon.
710 if (ExportVarMetadata) {
711 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
712 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
713 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
714 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
715 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
716 llvm::StringRef ExportVarName =
717 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
718 ExportSymbols.push_back(ExportVarName.data());
719 }
720 }
721 }
722 }
723
724 if (ExportFuncMetadata) {
725 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
726 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
727 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
728 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
729 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
730 llvm::StringRef ExportFuncName =
731 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
732 ExportSymbols.push_back(ExportFuncName.data());
733 }
734 }
735 }
736 }
737
738 // root() and init() are born to be exported
739 ExportSymbols.push_back("root");
740 ExportSymbols.push_back("init");
741
742 // We now create passes list performing LTO. These are copied from
743 // (including comments) llvm::createStandardLTOPasses().
744
745 // Internalize all other symbols not listed in ExportSymbols
746 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
747
748 // Propagate constants at call sites into the functions they call. This
749 // opens opportunities for globalopt (and inlining) by substituting
750 // function pointers passed as arguments to direct uses of functions.
751 LTOPasses.add(llvm::createIPSCCPPass());
752
753 // Now that we internalized some globals, see if we can hack on them!
754 LTOPasses.add(llvm::createGlobalOptimizerPass());
755
756 // Linking modules together can lead to duplicated global constants, only
757 // keep one copy of each constant...
758 LTOPasses.add(llvm::createConstantMergePass());
759
760 // Remove unused arguments from functions...
761 LTOPasses.add(llvm::createDeadArgEliminationPass());
762
763 // Reduce the code after globalopt and ipsccp. Both can open up
764 // significant simplification opportunities, and both can propagate
765 // functions through function pointers. When this happens, we often have
766 // to resolve varargs calls, etc, so let instcombine do this.
767 LTOPasses.add(llvm::createInstructionCombiningPass());
768
769 // Inline small functions
770 LTOPasses.add(llvm::createFunctionInliningPass());
771
772 // Remove dead EH info.
773 LTOPasses.add(llvm::createPruneEHPass());
774
775 // Internalize the globals again after inlining
776 LTOPasses.add(llvm::createGlobalOptimizerPass());
777
778 // Remove dead functions.
779 LTOPasses.add(llvm::createGlobalDCEPass());
780
781 // If we didn't decide to inline a function, check to see if we can
782 // transform it to pass arguments by value instead of by reference.
783 LTOPasses.add(llvm::createArgumentPromotionPass());
784
785 // The IPO passes may leave cruft around. Clean up after them.
786 LTOPasses.add(llvm::createInstructionCombiningPass());
787 LTOPasses.add(llvm::createJumpThreadingPass());
788
789 // Break up allocas
790 LTOPasses.add(llvm::createScalarReplAggregatesPass());
791
792 // Run a few AA driven optimizations here and now, to cleanup the code.
793 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
794 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
795
796 // Hoist loop invariants.
797 LTOPasses.add(llvm::createLICMPass());
798
799 // Remove redundancies.
800 LTOPasses.add(llvm::createGVNPass());
801
802 // Remove dead memcpys.
803 LTOPasses.add(llvm::createMemCpyOptPass());
804
805 // Nuke dead stores.
806 LTOPasses.add(llvm::createDeadStoreEliminationPass());
807
808 // Cleanup and simplify the code after the scalar optimizations.
809 LTOPasses.add(llvm::createInstructionCombiningPass());
810
811 LTOPasses.add(llvm::createJumpThreadingPass());
812
813 // Delete basic blocks, which optimization passes may have killed.
814 LTOPasses.add(llvm::createCFGSimplificationPass());
815
816 // Now that we have optimized the program, discard unreachable functions.
817 LTOPasses.add(llvm::createGlobalDCEPass());
818
819 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800820
821 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800822}
823
824
Logan Chienda5e0c32011-06-13 03:47:21 +0800825#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800826void *Compiler::getSymbolAddress(char const *name) {
827 return rsloaderGetSymbolAddress(mRSExecutable, name);
828}
829#endif
830
831
832#if USE_MCJIT
833void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
834 Compiler *self = reinterpret_cast<Compiler *>(context);
835
836 if (void *Addr = FindRuntimeFunction(name)) {
837 return Addr;
838 }
839
840 if (self->mpSymbolLookupFn) {
841 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
842 return Addr;
843 }
844 }
845
846 LOGE("Unable to resolve symbol: %s\n", name);
847 return NULL;
848}
849#endif
850
851
Logan1f028c02010-11-27 01:02:48 +0800852Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800853 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800854 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800855
Logan Chienda5e0c32011-06-13 03:47:21 +0800856#if USE_MCJIT
857 rsloaderDisposeExec(mRSExecutable);
858#endif
859
Logana4994f52010-11-27 14:06:02 +0800860 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800861}
862
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700863
Logan1f028c02010-11-27 01:02:48 +0800864} // namespace bcc