blob: 1a22ad51c80d9d42dd7fd33c528720c12be0884c [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
Logan Chienda5e0c32011-06-13 03:47:21 +080028#include "librsloader.h"
29
Logandf23afa2010-11-27 11:04:54 +080030#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080031
Logandf23afa2010-11-27 11:04:54 +080032#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080033
Logan1f028c02010-11-27 01:02:48 +080034#include "llvm/Bitcode/ReaderWriter.h"
35
Logan1f028c02010-11-27 01:02:48 +080036#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080037#include "llvm/CodeGen/RegAllocRegistry.h"
38#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080039
Logandf23afa2010-11-27 11:04:54 +080040#include "llvm/Transforms/IPO.h"
41#include "llvm/Transforms/Scalar.h"
42
43#include "llvm/Target/SubtargetFeature.h"
44#include "llvm/Target/TargetData.h"
45#include "llvm/Target/TargetMachine.h"
46#include "llvm/Target/TargetOptions.h"
47#include "llvm/Target/TargetRegistry.h"
48#include "llvm/Target/TargetSelect.h"
49
50#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070051#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080052#include "llvm/Support/MemoryBuffer.h"
53
54#include "llvm/GlobalValue.h"
55#include "llvm/Linker.h"
56#include "llvm/LLVMContext.h"
57#include "llvm/Metadata.h"
58#include "llvm/Module.h"
59#include "llvm/PassManager.h"
60#include "llvm/Value.h"
61
62#include <errno.h>
63#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080064#include <sys/stat.h>
65#include <sys/types.h>
66#include <unistd.h>
67
Logan75cc8a52011-01-07 06:06:52 +080068#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080069
Logandf23afa2010-11-27 11:04:54 +080070#include <string>
71#include <vector>
Logan1f028c02010-11-27 01:02:48 +080072
Shih-wei Liao749a51c2011-06-17 16:02:18 -070073#define DEBUG_BCC_REFLECT_TO_LIBRS 0
74
Logan1f028c02010-11-27 01:02:48 +080075namespace bcc {
76
77//////////////////////////////////////////////////////////////////////////////
78// BCC Compiler Static Variables
79//////////////////////////////////////////////////////////////////////////////
80
81bool Compiler::GlobalInitialized = false;
82
Logan1f028c02010-11-27 01:02:48 +080083// Code generation optimization level for the compiler
84llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
85
86std::string Compiler::Triple;
87
88std::string Compiler::CPU;
89
90std::vector<std::string> Compiler::Features;
91
Stephen Hines071288a2011-01-27 14:38:26 -080092// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +080093// slang.cpp)
94const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
95
Stephen Hines071288a2011-01-27 14:38:26 -080096// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +080097// synced with slang_rs_metadata.h)
98const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
99
Stephen Hines071288a2011-01-27 14:38:26 -0800100// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800101// synced with slang_rs_metadata.h)
102const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
103
Stephen Hines071288a2011-01-27 14:38:26 -0800104// Name of metadata node where RS object slot info resides (should be
105// synced with slang_rs_metadata.h)
106const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800107
108//////////////////////////////////////////////////////////////////////////////
109// Compiler
110//////////////////////////////////////////////////////////////////////////////
111
112void Compiler::GlobalInitialization() {
113 if (GlobalInitialized)
114 return;
115
Logane1323992011-01-12 04:47:13 +0800116 LOGI("LIBBCC BUILD: %s\n", libbcc_build_time);
Logan87066272010-12-29 00:34:32 +0800117
Logan1f028c02010-11-27 01:02:48 +0800118 // if (!llvm::llvm_is_multithreaded())
119 // llvm::llvm_start_multithreaded();
120
121 // Set Triple, CPU and Features here
122 Triple = TARGET_TRIPLE_STRING;
123
Logan1f028c02010-11-27 01:02:48 +0800124 Features.push_back("+vfp3");
125 Features.push_back("+d16");
126
Logan4fe966f2011-02-27 08:26:40 +0800127 // NOTE: Currently, we have to turn off the support for NEON explicitly.
128 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
129 // instructions.
130 Features.push_back("-neon"); // TODO(sliao): NEON for JIT
131 Features.push_back("-neonfp");
132 Features.push_back("-vmlx");
133
Logan1f028c02010-11-27 01:02:48 +0800134#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
135 LLVMInitializeARMTargetInfo();
136 LLVMInitializeARMTarget();
Logan35849002011-01-15 07:30:43 +0800137#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800138 LLVMInitializeARMDisassembler();
139 LLVMInitializeARMAsmPrinter();
140#endif
141#endif
142
143#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
144 LLVMInitializeX86TargetInfo();
145 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800146#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800147 LLVMInitializeX86Disassembler();
148 LLVMInitializeX86AsmPrinter();
149#endif
150#endif
151
152#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
153 LLVMInitializeX86TargetInfo();
154 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800155#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800156 LLVMInitializeX86Disassembler();
157 LLVMInitializeX86AsmPrinter();
158#endif
159#endif
160
161 // -O0: llvm::CodeGenOpt::None
162 // -O1: llvm::CodeGenOpt::Less
163 // -O2: llvm::CodeGenOpt::Default
164 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800165 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800166
167 // Below are the global settings to LLVM
168
169 // Disable frame pointer elimination optimization
170 llvm::NoFramePointerElim = false;
171
172 // Use hardfloat ABI
173 //
174 // TODO(all): Need to detect the CPU capability and decide whether to use
175 // softfp. To use softfp, change following 2 lines to
176 //
177 // llvm::FloatABIType = llvm::FloatABI::Soft;
178 // llvm::UseSoftFloat = true;
179 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800180 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800181 llvm::UseSoftFloat = false;
182
183 // BCC needs all unknown symbols resolved at JIT/compilation time.
184 // So we don't need any dynamic relocation model.
185 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
186
187#if defined(DEFAULT_X64_CODEGEN)
188 // Data address in X86_64 architecture may reside in a far-away place
189 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
190#else
191 // This is set for the linker (specify how large of the virtual addresses
192 // we can access for all unknown symbols.)
193 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
194#endif
195
196 // Register the scheduler
197 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
198
199 // Register allocation policy:
200 // createFastRegisterAllocator: fast but bad quality
201 // createLinearScanRegisterAllocator: not so fast but good quality
202 llvm::RegisterRegAlloc::setDefault
203 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
204 llvm::createFastRegisterAllocator :
205 llvm::createLinearScanRegisterAllocator);
206
Logan35849002011-01-15 07:30:43 +0800207#if USE_CACHE
Logan75cc8a52011-01-07 06:06:52 +0800208 // Calculate the SHA1 checksum of libbcc and libRS.
Logan35849002011-01-15 07:30:43 +0800209#if USE_LIBBCC_SHA1SUM
Logan75cc8a52011-01-07 06:06:52 +0800210 calcFileSHA1(sha1LibBCC, pathLibBCC);
Logane1323992011-01-12 04:47:13 +0800211#endif
Logan75cc8a52011-01-07 06:06:52 +0800212 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
Logan Chienda5e0c32011-06-13 03:47:21 +0800260#if USE_MCJIT
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700261// input objPath: For example,
262// /data/user/0/com.example.android.rs.fountain/cache/
263// @com.example.android.rs.fountain:raw@fountain.oBCC
264// output objPath: /data/user/0/com.example.android.rs.fountain/cache/
265// fountain.o
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700266//
267bool Compiler::getObjPath(std::string &objPath) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700268 size_t found0 = objPath.find("@");
269 size_t found1 = objPath.rfind("@");
270
271 if (found0 == found1 ||
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800272 found0 == std::string::npos ||
273 found1 == std::string::npos) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700274 LOGE("Ill formatted resource name '%s'. The name should contain 2 @s",
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700275 objPath.c_str());
276 return false;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700277 }
278
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700279 objPath.replace(found0, found1 - found0 + 1, "", 0);
280 objPath.resize(objPath.length() - 3);
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700281
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700282 LOGV("objPath = %s", objPath.c_str());
283 return true;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700284}
Logan Chienda5e0c32011-06-13 03:47:21 +0800285#endif
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700286
287
Logan474cbd22011-01-31 01:47:44 +0800288llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
289 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800290
Logan474cbd22011-01-31 01:47:44 +0800291 if (!result) {
292 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
293 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800294 }
295
Logan474cbd22011-01-31 01:47:44 +0800296 return result;
Logan1f028c02010-11-27 01:02:48 +0800297}
298
299
Logan474cbd22011-01-31 01:47:44 +0800300int Compiler::linkModule(llvm::Module *moduleWith) {
301 if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800302 return hasError();
303 }
304
Logan1f028c02010-11-27 01:02:48 +0800305 // Everything for linking should be settled down here with no error occurs
306 mHasLinked = true;
307 return hasError();
308}
309
310
Logan1f028c02010-11-27 01:02:48 +0800311int Compiler::compile() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800312 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800313 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800314 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800315
Logan1f028c02010-11-27 01:02:48 +0800316 std::string FeaturesStr;
317
Logan Chienda5e0c32011-06-13 03:47:21 +0800318 llvm::NamedMDNode const *PragmaMetadata;
319 llvm::NamedMDNode const *ExportVarMetadata;
320 llvm::NamedMDNode const *ExportFuncMetadata;
321 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800322
Logan1f028c02010-11-27 01:02:48 +0800323 if (mModule == NULL) // No module was loaded
324 return 0;
325
326 // Create TargetMachine
327 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
328 if (hasError())
329 goto on_bcc_compile_error;
330
331 if (!CPU.empty() || !Features.empty()) {
332 llvm::SubtargetFeatures F;
333 F.setCPU(CPU);
Logana4994f52010-11-27 14:06:02 +0800334
335 for (std::vector<std::string>::const_iterator
336 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800337 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800338 }
339
Logan1f028c02010-11-27 01:02:48 +0800340 FeaturesStr = F.getString();
341 }
342
343 TM = Target->createTargetMachine(Triple, FeaturesStr);
344 if (TM == NULL) {
345 setError("Failed to create target machine implementation for the"
346 " specified triple '" + Triple + "'");
347 goto on_bcc_compile_error;
348 }
349
Logan Chienda5e0c32011-06-13 03:47:21 +0800350 // Get target data from Module
351 TD = new llvm::TargetData(mModule);
352
353 // Load named metadata
354 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
355 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
356 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
357 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
358
359 // Perform link-time optimization if we have multiple modules
360 if (mHasLinked) {
361 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
362 }
363
364 // Perform code generation
365#if USE_OLD_JIT
366 if (runCodeGen(new llvm::TargetData(*TD), TM,
367 ExportVarMetadata, ExportFuncMetadata) != 0) {
368 goto on_bcc_compile_error;
369 }
370#endif
371
372#if USE_MCJIT
373 if (runMCCodeGen(new llvm::TargetData(*TD), TM,
374 ExportVarMetadata, ExportFuncMetadata) != 0) {
375 goto on_bcc_compile_error;
376 }
377#endif
378
379 // Read pragma information from the metadata node of the module.
380 if (PragmaMetadata) {
381 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
382
383 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
384 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
385 if (Pragma != NULL &&
386 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
387 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
388 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
389
390 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
391 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
392 llvm::StringRef PragmaName =
393 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
394 llvm::StringRef PragmaValue =
395 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
396
397 pragmaList.push_back(
398 std::make_pair(std::string(PragmaName.data(),
399 PragmaName.size()),
400 std::string(PragmaValue.data(),
401 PragmaValue.size())));
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700402#if DEBUG_BCC_REFLECT_TO_LIBRS
403 LOGD("compile(): Pragma: %s -> %s\n", pragmaList.back().first.c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800404 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700405#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800406 }
407 }
408 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800409 }
410
411 if (ObjectSlotMetadata) {
412 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
413
414 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
415 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
416 if (ObjectSlot != NULL &&
417 ObjectSlot->getNumOperands() == 1) {
418 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
419 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
420 llvm::StringRef Slot =
421 static_cast<llvm::MDString*>(SlotMDS)->getString();
422 uint32_t USlot = 0;
423 if (Slot.getAsInteger(10, USlot)) {
424 setError("Non-integer object slot value '" + Slot.str() + "'");
425 goto on_bcc_compile_error;
426 }
427 objectSlotList.push_back(USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700428#if DEBUG_BCC_REFLECT_TO_LIBRS
429 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
430#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800431 }
432 }
433 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800434 }
435
436on_bcc_compile_error:
437 // LOGE("on_bcc_compiler_error");
438 if (TD) {
439 delete TD;
440 }
441
442 if (TM) {
443 delete TM;
444 }
445
446 if (mError.empty()) {
447 return 0;
448 }
449
450 // LOGE(getErrorMessage());
451 return 1;
452}
453
454
455#if USE_OLD_JIT
456int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
457 llvm::NamedMDNode const *ExportVarMetadata,
458 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800459 // Create memory manager for creation of code emitter later.
460 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
461 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800462 return 1;
Logan1f028c02010-11-27 01:02:48 +0800463 }
Logan02286cb2011-01-07 00:30:47 +0800464
465 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800466
467 // Create code emitter
468 if (!mCodeEmitter.get()) {
469 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800470 setError("Failed to create machine code emitter for compilation");
471 return 1;
Logan1f028c02010-11-27 01:02:48 +0800472 }
473 } else {
474 // Reuse the code emitter
475 mCodeEmitter->reset();
476 }
477
478 mCodeEmitter->setTargetMachine(*TM);
479 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
480 mpSymbolLookupContext);
481
Logan1f028c02010-11-27 01:02:48 +0800482 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800483 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
484 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800485
Logan Chienda5e0c32011-06-13 03:47:21 +0800486 // Add TargetData to code generation pass manager
487 CodeGenPasses->add(TD);
488
489 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800490 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
491 *mCodeEmitter,
492 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800493 setError("The machine code emission is not supported on '" + Triple + "'");
494 return 1;
Logan1f028c02010-11-27 01:02:48 +0800495 }
496
Logan Chienda5e0c32011-06-13 03:47:21 +0800497 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800498 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800499 for (llvm::Module::iterator
500 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800501 if (!I->isDeclaration()) {
502 CodeGenPasses->run(*I);
503 }
504 }
505
506 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800507
Logan1f028c02010-11-27 01:02:48 +0800508 // Copy the global address mapping from code emitter and remapping
509 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800510 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
511
Logan1f028c02010-11-27 01:02:48 +0800512 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
513 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
514 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
515 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
516 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
517 llvm::StringRef ExportVarName =
518 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
519
520 CodeEmitter::global_addresses_const_iterator I, E;
521 for (I = mCodeEmitter->global_address_begin(),
522 E = mCodeEmitter->global_address_end();
523 I != E; I++) {
524 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
525 continue;
526 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800527 varList.push_back(I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700528#if DEBUG_BCC_REFLECT_TO_LIBRS
529 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
530#endif
Logan1f028c02010-11-27 01:02:48 +0800531 break;
532 }
533 }
534 if (I != mCodeEmitter->global_address_end())
535 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800536
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700537#if DEBUG_BCC_REFLECT_TO_LIBRS
538 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800539 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700540#endif
Logan1f028c02010-11-27 01:02:48 +0800541 }
542 }
543 // if reaching here, we know the global variable record in metadata is
544 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800545 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800546 }
Logan2a6dc822011-01-06 04:05:20 +0800547
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700548 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
549 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800550 }
551
552 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800553 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
554
Logan1f028c02010-11-27 01:02:48 +0800555 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
556 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
557 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
558 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
559 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
560 llvm::StringRef ExportFuncName =
561 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800562 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700563#if DEBUG_BCC_REFLECT_TO_LIBRS
564 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800565 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700566#endif
Logan1f028c02010-11-27 01:02:48 +0800567 }
568 }
569 }
570 }
571
572 // Tell code emitter now can release the memory using during the JIT since
573 // we have done the code emission
574 mCodeEmitter->releaseUnnecessary();
575
Logan Chienda5e0c32011-06-13 03:47:21 +0800576 return 0;
Logan1f028c02010-11-27 01:02:48 +0800577}
Logan Chienda5e0c32011-06-13 03:47:21 +0800578#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800579
580
Logan Chienda5e0c32011-06-13 03:47:21 +0800581#if USE_MCJIT
582int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
583 llvm::NamedMDNode const *ExportVarMetadata,
584 llvm::NamedMDNode const *ExportFuncMetadata) {
585 // Decorate mEmittedELFExecutable with formatted ostream
586 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
587
588 // Relax all machine instructions
589 TM->setMCRelaxAll(/* RelaxAll= */ true);
590
591 // Create MC code generation pass manager
592 llvm::PassManager MCCodeGenPasses;
593
594 // Add TargetData to MC code generation pass manager
595 MCCodeGenPasses.add(TD);
596
597 // Add MC code generation passes to pass manager
598 llvm::MCContext *Ctx;
599 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
600 CodeGenOptLevel, false)) {
601 setError("Fail to add passes to emit file");
602 return 1;
603 }
604
605 MCCodeGenPasses.run(*mModule);
606 OutSVOS.flush();
607
608 // Load the ELF Object
609 mRSExecutable =
610 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
611 mEmittedELFExecutable.size(),
612 &resolveSymbolAdapter, this);
613
614 if (!mRSExecutable) {
615 setError("Fail to load emitted ELF relocatable file");
616 return 1;
617 }
618
619#if !USE_OLD_JIT
620 // Note: If old JIT is compiled then we prefer the old version instead of the
621 // new version.
622
623 if (ExportVarMetadata) {
624 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
625
626 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
627 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
Logan Chien70dd9982011-06-13 23:21:39 +0800628 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
629 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
630 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
631 llvm::StringRef ExportVarName =
632 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
633
634 varList.push_back(
635 rsloaderGetSymbolAddress(mRSExecutable,
636 ExportVarName.str().c_str()));
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700637#if DEBUG_BCC_REFLECT_TO_LIBRS
638 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Logan Chien70dd9982011-06-13 23:21:39 +0800639 varList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700640#endif
Logan Chien70dd9982011-06-13 23:21:39 +0800641 continue;
642 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800643 }
644
Logan Chien70dd9982011-06-13 23:21:39 +0800645 varList.push_back(NULL);
Logan Chienda5e0c32011-06-13 03:47:21 +0800646 }
647 }
648
649 if (ExportFuncMetadata) {
650 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
651
652 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
653 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
654 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
655 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
656 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
657 llvm::StringRef ExportFuncName =
658 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
659
660 funcList.push_back(
661 rsloaderGetSymbolAddress(mRSExecutable,
662 ExportFuncName.str().c_str()));
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700663#if DEBUG_BCC_REFLECT_TO_LIBRS
664 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800665 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700666#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800667 }
668 }
669 }
670 }
671#endif // !USE_OLD_JIT
672
673#if USE_CACHE
674 // Write generated executable to file.
675 if (writeELFExecToFile() != 0) {
676 setError("Fail to write mcjit-ed executable to file");
677 return 1;
678 }
679#endif
680
681 return 0;
682}
683#endif // USE_MCJIT
684
685
686int Compiler::runLTO(llvm::TargetData *TD,
687 llvm::NamedMDNode const *ExportVarMetadata,
688 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800689 llvm::PassManager LTOPasses;
690
691 // Add TargetData to LTO passes
692 LTOPasses.add(TD);
693
694 // Collect All Exported Symbols
695 std::vector<const char*> ExportSymbols;
696
697 // Note: This is a workaround for getting export variable and function name.
698 // We should refine it soon.
699 if (ExportVarMetadata) {
700 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
701 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
702 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
703 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
704 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
705 llvm::StringRef ExportVarName =
706 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
707 ExportSymbols.push_back(ExportVarName.data());
708 }
709 }
710 }
711 }
712
713 if (ExportFuncMetadata) {
714 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
715 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
716 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
717 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
718 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
719 llvm::StringRef ExportFuncName =
720 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
721 ExportSymbols.push_back(ExportFuncName.data());
722 }
723 }
724 }
725 }
726
727 // root() and init() are born to be exported
728 ExportSymbols.push_back("root");
729 ExportSymbols.push_back("init");
730
731 // We now create passes list performing LTO. These are copied from
732 // (including comments) llvm::createStandardLTOPasses().
733
734 // Internalize all other symbols not listed in ExportSymbols
735 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
736
737 // Propagate constants at call sites into the functions they call. This
738 // opens opportunities for globalopt (and inlining) by substituting
739 // function pointers passed as arguments to direct uses of functions.
740 LTOPasses.add(llvm::createIPSCCPPass());
741
742 // Now that we internalized some globals, see if we can hack on them!
743 LTOPasses.add(llvm::createGlobalOptimizerPass());
744
745 // Linking modules together can lead to duplicated global constants, only
746 // keep one copy of each constant...
747 LTOPasses.add(llvm::createConstantMergePass());
748
749 // Remove unused arguments from functions...
750 LTOPasses.add(llvm::createDeadArgEliminationPass());
751
752 // Reduce the code after globalopt and ipsccp. Both can open up
753 // significant simplification opportunities, and both can propagate
754 // functions through function pointers. When this happens, we often have
755 // to resolve varargs calls, etc, so let instcombine do this.
756 LTOPasses.add(llvm::createInstructionCombiningPass());
757
758 // Inline small functions
759 LTOPasses.add(llvm::createFunctionInliningPass());
760
761 // Remove dead EH info.
762 LTOPasses.add(llvm::createPruneEHPass());
763
764 // Internalize the globals again after inlining
765 LTOPasses.add(llvm::createGlobalOptimizerPass());
766
767 // Remove dead functions.
768 LTOPasses.add(llvm::createGlobalDCEPass());
769
770 // If we didn't decide to inline a function, check to see if we can
771 // transform it to pass arguments by value instead of by reference.
772 LTOPasses.add(llvm::createArgumentPromotionPass());
773
774 // The IPO passes may leave cruft around. Clean up after them.
775 LTOPasses.add(llvm::createInstructionCombiningPass());
776 LTOPasses.add(llvm::createJumpThreadingPass());
777
778 // Break up allocas
779 LTOPasses.add(llvm::createScalarReplAggregatesPass());
780
781 // Run a few AA driven optimizations here and now, to cleanup the code.
782 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
783 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
784
785 // Hoist loop invariants.
786 LTOPasses.add(llvm::createLICMPass());
787
788 // Remove redundancies.
789 LTOPasses.add(llvm::createGVNPass());
790
791 // Remove dead memcpys.
792 LTOPasses.add(llvm::createMemCpyOptPass());
793
794 // Nuke dead stores.
795 LTOPasses.add(llvm::createDeadStoreEliminationPass());
796
797 // Cleanup and simplify the code after the scalar optimizations.
798 LTOPasses.add(llvm::createInstructionCombiningPass());
799
800 LTOPasses.add(llvm::createJumpThreadingPass());
801
802 // Delete basic blocks, which optimization passes may have killed.
803 LTOPasses.add(llvm::createCFGSimplificationPass());
804
805 // Now that we have optimized the program, discard unreachable functions.
806 LTOPasses.add(llvm::createGlobalDCEPass());
807
808 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800809
810 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800811}
812
813
Logan Chienda5e0c32011-06-13 03:47:21 +0800814#if USE_MCJIT
815int Compiler::writeELFExecToFile() {
816 std::string objPath(mCachePath);
817 if (!getObjPath(objPath)) {
818 LOGE("Fail to create objPath");
819 return 1;
820 }
821
822 FileHandle file;
823
824 int Fd = file.open(objPath.c_str(), OpenMode::Write);
825 if (Fd < 0) {
826 LOGE("Fail to open file '%s'", objPath.c_str());
827 return 1;
828 }
829
830 file.write(&*mEmittedELFExecutable.begin(), mEmittedELFExecutable.size());
831
832 return 0;
833}
834#endif
835
836
837#if USE_MCJIT
838void *Compiler::getSymbolAddress(char const *name) {
839 return rsloaderGetSymbolAddress(mRSExecutable, name);
840}
841#endif
842
843
844#if USE_MCJIT
845void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
846 Compiler *self = reinterpret_cast<Compiler *>(context);
847
848 if (void *Addr = FindRuntimeFunction(name)) {
849 return Addr;
850 }
851
852 if (self->mpSymbolLookupFn) {
853 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
854 return Addr;
855 }
856 }
857
858 LOGE("Unable to resolve symbol: %s\n", name);
859 return NULL;
860}
861#endif
862
863
Logan1f028c02010-11-27 01:02:48 +0800864Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800865 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800866 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800867
Logan Chienda5e0c32011-06-13 03:47:21 +0800868#if USE_MCJIT
869 rsloaderDisposeExec(mRSExecutable);
870#endif
871
Logana4994f52010-11-27 14:06:02 +0800872 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800873}
874
Logan1f028c02010-11-27 01:02:48 +0800875} // namespace bcc