blob: 9fa6d4d99dbab05835518bc2347043c55bb7ab79 [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
Logan1f028c02010-11-27 01:02:48 +080073namespace bcc {
74
75//////////////////////////////////////////////////////////////////////////////
76// BCC Compiler Static Variables
77//////////////////////////////////////////////////////////////////////////////
78
79bool Compiler::GlobalInitialized = false;
80
Logan1f028c02010-11-27 01:02:48 +080081// Code generation optimization level for the compiler
82llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
83
84std::string Compiler::Triple;
85
86std::string Compiler::CPU;
87
88std::vector<std::string> Compiler::Features;
89
Stephen Hines071288a2011-01-27 14:38:26 -080090// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +080091// slang.cpp)
92const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
93
Stephen Hines071288a2011-01-27 14:38:26 -080094// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +080095// synced with slang_rs_metadata.h)
96const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
97
Stephen Hines071288a2011-01-27 14:38:26 -080098// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +080099// synced with slang_rs_metadata.h)
100const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
101
Stephen Hines071288a2011-01-27 14:38:26 -0800102// Name of metadata node where RS object slot info resides (should be
103// synced with slang_rs_metadata.h)
104const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800105
106//////////////////////////////////////////////////////////////////////////////
107// Compiler
108//////////////////////////////////////////////////////////////////////////////
109
110void Compiler::GlobalInitialization() {
111 if (GlobalInitialized)
112 return;
113
Logane1323992011-01-12 04:47:13 +0800114 LOGI("LIBBCC BUILD: %s\n", libbcc_build_time);
Logan87066272010-12-29 00:34:32 +0800115
Logan1f028c02010-11-27 01:02:48 +0800116 // if (!llvm::llvm_is_multithreaded())
117 // llvm::llvm_start_multithreaded();
118
119 // Set Triple, CPU and Features here
120 Triple = TARGET_TRIPLE_STRING;
121
Logan1f028c02010-11-27 01:02:48 +0800122 Features.push_back("+vfp3");
123 Features.push_back("+d16");
124
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.
128 Features.push_back("-neon"); // TODO(sliao): NEON for JIT
129 Features.push_back("-neonfp");
130 Features.push_back("-vmlx");
131
Logan1f028c02010-11-27 01:02:48 +0800132#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
133 LLVMInitializeARMTargetInfo();
134 LLVMInitializeARMTarget();
Logan35849002011-01-15 07:30:43 +0800135#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800136 LLVMInitializeARMDisassembler();
137 LLVMInitializeARMAsmPrinter();
138#endif
139#endif
140
141#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
142 LLVMInitializeX86TargetInfo();
143 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800144#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800145 LLVMInitializeX86Disassembler();
146 LLVMInitializeX86AsmPrinter();
147#endif
148#endif
149
150#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
151 LLVMInitializeX86TargetInfo();
152 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800153#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800154 LLVMInitializeX86Disassembler();
155 LLVMInitializeX86AsmPrinter();
156#endif
157#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
Logan75cc8a52011-01-07 06:06:52 +0800206 // Calculate the SHA1 checksum of libbcc and libRS.
Logan35849002011-01-15 07:30:43 +0800207#if USE_LIBBCC_SHA1SUM
Logan75cc8a52011-01-07 06:06:52 +0800208 calcFileSHA1(sha1LibBCC, pathLibBCC);
Logane1323992011-01-12 04:47:13 +0800209#endif
Logan75cc8a52011-01-07 06:06:52 +0800210 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800211#endif
Logan75cc8a52011-01-07 06:06:52 +0800212
Logan1f028c02010-11-27 01:02:48 +0800213 GlobalInitialized = true;
214}
215
216
217void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
218 std::string *Error = static_cast<std::string*>(UserData);
219 Error->assign(Message);
220 LOGE("%s", Message.c_str());
221 exit(1);
222}
223
224
Logan Chienda5e0c32011-06-13 03:47:21 +0800225#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800226CodeMemoryManager *Compiler::createCodeMemoryManager() {
227 mCodeMemMgr.reset(new CodeMemoryManager());
228 return mCodeMemMgr.get();
229}
Logan Chienda5e0c32011-06-13 03:47:21 +0800230#endif
Logan1f028c02010-11-27 01:02:48 +0800231
232
Logan Chienda5e0c32011-06-13 03:47:21 +0800233#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800234CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800235 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800236 return mCodeEmitter.get();
237}
Logan Chienda5e0c32011-06-13 03:47:21 +0800238#endif
Logan1f028c02010-11-27 01:02:48 +0800239
240
Logan2a6dc822011-01-06 04:05:20 +0800241Compiler::Compiler(ScriptCompiled *result)
242 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800243#if USE_MCJIT
244 mRSExecutable(NULL),
245#endif
Logan1f028c02010-11-27 01:02:48 +0800246 mpSymbolLookupFn(NULL),
247 mpSymbolLookupContext(NULL),
248 mContext(NULL),
249 mModule(NULL),
250 mHasLinked(false) /* Turn off linker */ {
251 llvm::remove_fatal_error_handler();
252 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
253 mContext = new llvm::LLVMContext();
254 return;
255}
256
Logan1f028c02010-11-27 01:02:48 +0800257
Logan Chienda5e0c32011-06-13 03:47:21 +0800258#if USE_MCJIT
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700259// input objPath: For example,
260// /data/user/0/com.example.android.rs.fountain/cache/
261// @com.example.android.rs.fountain:raw@fountain.oBCC
262// output objPath: /data/user/0/com.example.android.rs.fountain/cache/
263// fountain.o
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700264//
265bool Compiler::getObjPath(std::string &objPath) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700266 size_t found0 = objPath.find("@");
267 size_t found1 = objPath.rfind("@");
268
269 if (found0 == found1 ||
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800270 found0 == std::string::npos ||
271 found1 == std::string::npos) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700272 LOGE("Ill formatted resource name '%s'. The name should contain 2 @s",
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700273 objPath.c_str());
274 return false;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700275 }
276
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700277 objPath.replace(found0, found1 - found0 + 1, "", 0);
278 objPath.resize(objPath.length() - 3);
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700279
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700280 LOGV("objPath = %s", objPath.c_str());
281 return true;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700282}
Logan Chienda5e0c32011-06-13 03:47:21 +0800283#endif
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700284
285
Logan474cbd22011-01-31 01:47:44 +0800286llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
287 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800288
Logan474cbd22011-01-31 01:47:44 +0800289 if (!result) {
290 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
291 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800292 }
293
Logan474cbd22011-01-31 01:47:44 +0800294 return result;
Logan1f028c02010-11-27 01:02:48 +0800295}
296
297
Logan474cbd22011-01-31 01:47:44 +0800298int Compiler::linkModule(llvm::Module *moduleWith) {
299 if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800300 return hasError();
301 }
302
Logan1f028c02010-11-27 01:02:48 +0800303 // Everything for linking should be settled down here with no error occurs
304 mHasLinked = true;
305 return hasError();
306}
307
308
Logan1f028c02010-11-27 01:02:48 +0800309int Compiler::compile() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800310 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800311 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800312 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800313
Logan1f028c02010-11-27 01:02:48 +0800314 std::string FeaturesStr;
315
Logan Chienda5e0c32011-06-13 03:47:21 +0800316 llvm::NamedMDNode const *PragmaMetadata;
317 llvm::NamedMDNode const *ExportVarMetadata;
318 llvm::NamedMDNode const *ExportFuncMetadata;
319 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800320
Logan1f028c02010-11-27 01:02:48 +0800321 if (mModule == NULL) // No module was loaded
322 return 0;
323
324 // Create TargetMachine
325 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
326 if (hasError())
327 goto on_bcc_compile_error;
328
329 if (!CPU.empty() || !Features.empty()) {
330 llvm::SubtargetFeatures F;
331 F.setCPU(CPU);
Logana4994f52010-11-27 14:06:02 +0800332
333 for (std::vector<std::string>::const_iterator
334 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800335 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800336 }
337
Logan1f028c02010-11-27 01:02:48 +0800338 FeaturesStr = F.getString();
339 }
340
341 TM = Target->createTargetMachine(Triple, FeaturesStr);
342 if (TM == NULL) {
343 setError("Failed to create target machine implementation for the"
344 " specified triple '" + Triple + "'");
345 goto on_bcc_compile_error;
346 }
347
Logan Chienda5e0c32011-06-13 03:47:21 +0800348 // Get target data from Module
349 TD = new llvm::TargetData(mModule);
350
351 // Load named metadata
352 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
353 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
354 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
355 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
356
357 // Perform link-time optimization if we have multiple modules
358 if (mHasLinked) {
359 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
360 }
361
362 // Perform code generation
363#if USE_OLD_JIT
364 if (runCodeGen(new llvm::TargetData(*TD), TM,
365 ExportVarMetadata, ExportFuncMetadata) != 0) {
366 goto on_bcc_compile_error;
367 }
368#endif
369
370#if USE_MCJIT
371 if (runMCCodeGen(new llvm::TargetData(*TD), TM,
372 ExportVarMetadata, ExportFuncMetadata) != 0) {
373 goto on_bcc_compile_error;
374 }
375#endif
376
377 // Read pragma information from the metadata node of the module.
378 if (PragmaMetadata) {
379 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
380
381 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
382 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
383 if (Pragma != NULL &&
384 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
385 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
386 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
387
388 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
389 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
390 llvm::StringRef PragmaName =
391 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
392 llvm::StringRef PragmaValue =
393 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
394
395 pragmaList.push_back(
396 std::make_pair(std::string(PragmaName.data(),
397 PragmaName.size()),
398 std::string(PragmaValue.data(),
399 PragmaValue.size())));
400 }
401 }
402 }
403 LOGD("Found %d pragma\n", pragmaList.size());
404 }
405
406 if (ObjectSlotMetadata) {
407 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
408
409 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
410 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
411 if (ObjectSlot != NULL &&
412 ObjectSlot->getNumOperands() == 1) {
413 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
414 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
415 llvm::StringRef Slot =
416 static_cast<llvm::MDString*>(SlotMDS)->getString();
417 uint32_t USlot = 0;
418 if (Slot.getAsInteger(10, USlot)) {
419 setError("Non-integer object slot value '" + Slot.str() + "'");
420 goto on_bcc_compile_error;
421 }
422 objectSlotList.push_back(USlot);
423 }
424 }
425 }
426 LOGD("Found %d object slot\n", objectSlotList.size());
427 }
428
429on_bcc_compile_error:
430 // LOGE("on_bcc_compiler_error");
431 if (TD) {
432 delete TD;
433 }
434
435 if (TM) {
436 delete TM;
437 }
438
439 if (mError.empty()) {
440 return 0;
441 }
442
443 // LOGE(getErrorMessage());
444 return 1;
445}
446
447
448#if USE_OLD_JIT
449int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
450 llvm::NamedMDNode const *ExportVarMetadata,
451 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800452 // Create memory manager for creation of code emitter later.
453 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
454 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800455 return 1;
Logan1f028c02010-11-27 01:02:48 +0800456 }
Logan02286cb2011-01-07 00:30:47 +0800457
458 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800459
460 // Create code emitter
461 if (!mCodeEmitter.get()) {
462 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800463 setError("Failed to create machine code emitter for compilation");
464 return 1;
Logan1f028c02010-11-27 01:02:48 +0800465 }
466 } else {
467 // Reuse the code emitter
468 mCodeEmitter->reset();
469 }
470
471 mCodeEmitter->setTargetMachine(*TM);
472 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
473 mpSymbolLookupContext);
474
Logan1f028c02010-11-27 01:02:48 +0800475 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800476 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
477 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800478
Logan Chienda5e0c32011-06-13 03:47:21 +0800479 // Add TargetData to code generation pass manager
480 CodeGenPasses->add(TD);
481
482 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800483 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
484 *mCodeEmitter,
485 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800486 setError("The machine code emission is not supported on '" + Triple + "'");
487 return 1;
Logan1f028c02010-11-27 01:02:48 +0800488 }
489
Logan Chienda5e0c32011-06-13 03:47:21 +0800490 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800491 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800492 for (llvm::Module::iterator
493 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800494 if (!I->isDeclaration()) {
495 CodeGenPasses->run(*I);
496 }
497 }
498
499 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800500
Logan1f028c02010-11-27 01:02:48 +0800501 // Copy the global address mapping from code emitter and remapping
502 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800503 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
504
Logan1f028c02010-11-27 01:02:48 +0800505 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
506 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
507 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
508 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
509 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
510 llvm::StringRef ExportVarName =
511 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
512
513 CodeEmitter::global_addresses_const_iterator I, E;
514 for (I = mCodeEmitter->global_address_begin(),
515 E = mCodeEmitter->global_address_end();
516 I != E; I++) {
517 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
518 continue;
519 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800520 varList.push_back(I->second);
Logan Chienda5e0c32011-06-13 03:47:21 +0800521 LOGD("Exported VAR: %s\n", ExportVarName.str().c_str());
Logan1f028c02010-11-27 01:02:48 +0800522 break;
523 }
524 }
525 if (I != mCodeEmitter->global_address_end())
526 continue; // found
527 }
528 }
529 // if reaching here, we know the global variable record in metadata is
530 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800531 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800532 }
Logan2a6dc822011-01-06 04:05:20 +0800533
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700534 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
535 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800536 }
537
538 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800539 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
540
Logan1f028c02010-11-27 01:02:48 +0800541 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
542 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
543 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
544 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
545 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
546 llvm::StringRef ExportFuncName =
547 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800548 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Logan Chienda5e0c32011-06-13 03:47:21 +0800549 LOGD("Exported Func: %s\n", ExportFuncName.str().c_str());
Logan1f028c02010-11-27 01:02:48 +0800550 }
551 }
552 }
553 }
554
555 // Tell code emitter now can release the memory using during the JIT since
556 // we have done the code emission
557 mCodeEmitter->releaseUnnecessary();
558
Logan Chienda5e0c32011-06-13 03:47:21 +0800559 return 0;
Logan1f028c02010-11-27 01:02:48 +0800560}
Logan Chienda5e0c32011-06-13 03:47:21 +0800561#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800562
563
Logan Chienda5e0c32011-06-13 03:47:21 +0800564#if USE_MCJIT
565int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
566 llvm::NamedMDNode const *ExportVarMetadata,
567 llvm::NamedMDNode const *ExportFuncMetadata) {
568 // Decorate mEmittedELFExecutable with formatted ostream
569 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
570
571 // Relax all machine instructions
572 TM->setMCRelaxAll(/* RelaxAll= */ true);
573
574 // Create MC code generation pass manager
575 llvm::PassManager MCCodeGenPasses;
576
577 // Add TargetData to MC code generation pass manager
578 MCCodeGenPasses.add(TD);
579
580 // Add MC code generation passes to pass manager
581 llvm::MCContext *Ctx;
582 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
583 CodeGenOptLevel, false)) {
584 setError("Fail to add passes to emit file");
585 return 1;
586 }
587
588 MCCodeGenPasses.run(*mModule);
589 OutSVOS.flush();
590
591 // Load the ELF Object
592 mRSExecutable =
593 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
594 mEmittedELFExecutable.size(),
595 &resolveSymbolAdapter, this);
596
597 if (!mRSExecutable) {
598 setError("Fail to load emitted ELF relocatable file");
599 return 1;
600 }
601
602#if !USE_OLD_JIT
603 // Note: If old JIT is compiled then we prefer the old version instead of the
604 // new version.
605
606 if (ExportVarMetadata) {
607 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
608
609 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
610 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
Logan Chien70dd9982011-06-13 23:21:39 +0800611 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
612 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
613 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
614 llvm::StringRef ExportVarName =
615 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
616
617 varList.push_back(
618 rsloaderGetSymbolAddress(mRSExecutable,
619 ExportVarName.str().c_str()));
620 LOGD("MC/ Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
621 varList.back());
622 continue;
623 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800624 }
625
Logan Chien70dd9982011-06-13 23:21:39 +0800626 varList.push_back(NULL);
Logan Chienda5e0c32011-06-13 03:47:21 +0800627 }
628 }
629
630 if (ExportFuncMetadata) {
631 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
632
633 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
634 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
635 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
636 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
637 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
638 llvm::StringRef ExportFuncName =
639 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
640
641 funcList.push_back(
642 rsloaderGetSymbolAddress(mRSExecutable,
643 ExportFuncName.str().c_str()));
644 }
645 }
646 }
647 }
648#endif // !USE_OLD_JIT
649
650#if USE_CACHE
651 // Write generated executable to file.
652 if (writeELFExecToFile() != 0) {
653 setError("Fail to write mcjit-ed executable to file");
654 return 1;
655 }
656#endif
657
658 return 0;
659}
660#endif // USE_MCJIT
661
662
663int Compiler::runLTO(llvm::TargetData *TD,
664 llvm::NamedMDNode const *ExportVarMetadata,
665 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800666 llvm::PassManager LTOPasses;
667
668 // Add TargetData to LTO passes
669 LTOPasses.add(TD);
670
671 // Collect All Exported Symbols
672 std::vector<const char*> ExportSymbols;
673
674 // Note: This is a workaround for getting export variable and function name.
675 // We should refine it soon.
676 if (ExportVarMetadata) {
677 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
678 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
679 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
680 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
681 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
682 llvm::StringRef ExportVarName =
683 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
684 ExportSymbols.push_back(ExportVarName.data());
685 }
686 }
687 }
688 }
689
690 if (ExportFuncMetadata) {
691 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
692 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
693 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
694 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
695 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
696 llvm::StringRef ExportFuncName =
697 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
698 ExportSymbols.push_back(ExportFuncName.data());
699 }
700 }
701 }
702 }
703
704 // root() and init() are born to be exported
705 ExportSymbols.push_back("root");
706 ExportSymbols.push_back("init");
707
708 // We now create passes list performing LTO. These are copied from
709 // (including comments) llvm::createStandardLTOPasses().
710
711 // Internalize all other symbols not listed in ExportSymbols
712 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
713
714 // Propagate constants at call sites into the functions they call. This
715 // opens opportunities for globalopt (and inlining) by substituting
716 // function pointers passed as arguments to direct uses of functions.
717 LTOPasses.add(llvm::createIPSCCPPass());
718
719 // Now that we internalized some globals, see if we can hack on them!
720 LTOPasses.add(llvm::createGlobalOptimizerPass());
721
722 // Linking modules together can lead to duplicated global constants, only
723 // keep one copy of each constant...
724 LTOPasses.add(llvm::createConstantMergePass());
725
726 // Remove unused arguments from functions...
727 LTOPasses.add(llvm::createDeadArgEliminationPass());
728
729 // Reduce the code after globalopt and ipsccp. Both can open up
730 // significant simplification opportunities, and both can propagate
731 // functions through function pointers. When this happens, we often have
732 // to resolve varargs calls, etc, so let instcombine do this.
733 LTOPasses.add(llvm::createInstructionCombiningPass());
734
735 // Inline small functions
736 LTOPasses.add(llvm::createFunctionInliningPass());
737
738 // Remove dead EH info.
739 LTOPasses.add(llvm::createPruneEHPass());
740
741 // Internalize the globals again after inlining
742 LTOPasses.add(llvm::createGlobalOptimizerPass());
743
744 // Remove dead functions.
745 LTOPasses.add(llvm::createGlobalDCEPass());
746
747 // If we didn't decide to inline a function, check to see if we can
748 // transform it to pass arguments by value instead of by reference.
749 LTOPasses.add(llvm::createArgumentPromotionPass());
750
751 // The IPO passes may leave cruft around. Clean up after them.
752 LTOPasses.add(llvm::createInstructionCombiningPass());
753 LTOPasses.add(llvm::createJumpThreadingPass());
754
755 // Break up allocas
756 LTOPasses.add(llvm::createScalarReplAggregatesPass());
757
758 // Run a few AA driven optimizations here and now, to cleanup the code.
759 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
760 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
761
762 // Hoist loop invariants.
763 LTOPasses.add(llvm::createLICMPass());
764
765 // Remove redundancies.
766 LTOPasses.add(llvm::createGVNPass());
767
768 // Remove dead memcpys.
769 LTOPasses.add(llvm::createMemCpyOptPass());
770
771 // Nuke dead stores.
772 LTOPasses.add(llvm::createDeadStoreEliminationPass());
773
774 // Cleanup and simplify the code after the scalar optimizations.
775 LTOPasses.add(llvm::createInstructionCombiningPass());
776
777 LTOPasses.add(llvm::createJumpThreadingPass());
778
779 // Delete basic blocks, which optimization passes may have killed.
780 LTOPasses.add(llvm::createCFGSimplificationPass());
781
782 // Now that we have optimized the program, discard unreachable functions.
783 LTOPasses.add(llvm::createGlobalDCEPass());
784
785 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800786
787 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800788}
789
790
Logan Chienda5e0c32011-06-13 03:47:21 +0800791#if USE_MCJIT
792int Compiler::writeELFExecToFile() {
793 std::string objPath(mCachePath);
794 if (!getObjPath(objPath)) {
795 LOGE("Fail to create objPath");
796 return 1;
797 }
798
799 FileHandle file;
800
801 int Fd = file.open(objPath.c_str(), OpenMode::Write);
802 if (Fd < 0) {
803 LOGE("Fail to open file '%s'", objPath.c_str());
804 return 1;
805 }
806
807 file.write(&*mEmittedELFExecutable.begin(), mEmittedELFExecutable.size());
808
809 return 0;
810}
811#endif
812
813
814#if USE_MCJIT
815void *Compiler::getSymbolAddress(char const *name) {
816 return rsloaderGetSymbolAddress(mRSExecutable, name);
817}
818#endif
819
820
821#if USE_MCJIT
822void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
823 Compiler *self = reinterpret_cast<Compiler *>(context);
824
825 if (void *Addr = FindRuntimeFunction(name)) {
826 return Addr;
827 }
828
829 if (self->mpSymbolLookupFn) {
830 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
831 return Addr;
832 }
833 }
834
835 LOGE("Unable to resolve symbol: %s\n", name);
836 return NULL;
837}
838#endif
839
840
Logan1f028c02010-11-27 01:02:48 +0800841Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800842 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800843 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800844
Logan Chienda5e0c32011-06-13 03:47:21 +0800845#if USE_MCJIT
846 rsloaderDisposeExec(mRSExecutable);
847#endif
848
Logana4994f52010-11-27 14:06:02 +0800849 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800850}
851
Logan1f028c02010-11-27 01:02:48 +0800852} // namespace bcc