blob: 9d130392a9fe38c71c03aca8eea1194908a809d7 [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
Logandf23afa2010-11-27 11:04:54 +080042#include "llvm/Transforms/IPO.h"
43#include "llvm/Transforms/Scalar.h"
44
Logandf23afa2010-11-27 11:04:54 +080045#include "llvm/Target/TargetData.h"
46#include "llvm/Target/TargetMachine.h"
47#include "llvm/Target/TargetOptions.h"
48#include "llvm/Target/TargetRegistry.h"
49#include "llvm/Target/TargetSelect.h"
50
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070051#if USE_DISASSEMBLER
52#include "llvm/MC/MCAsmInfo.h"
53#include "llvm/MC/MCDisassembler.h"
54#include "llvm/MC/MCInst.h"
55#include "llvm/MC/MCInstPrinter.h"
Shih-wei Liao029057e2011-07-02 11:34:35 -070056#include "llvm/MC/SubtargetFeature.h"
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070057#include "llvm/Support/MemoryObject.h"
58#include "llvm/LLVMContext.h"
59#endif
60
Logandf23afa2010-11-27 11:04:54 +080061#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070062#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080063#include "llvm/Support/MemoryBuffer.h"
64
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070065#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080066#include "llvm/GlobalValue.h"
67#include "llvm/Linker.h"
68#include "llvm/LLVMContext.h"
69#include "llvm/Metadata.h"
70#include "llvm/Module.h"
71#include "llvm/PassManager.h"
72#include "llvm/Value.h"
73
74#include <errno.h>
75#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080076#include <sys/stat.h>
77#include <sys/types.h>
78#include <unistd.h>
79
Logan75cc8a52011-01-07 06:06:52 +080080#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080081
Logandf23afa2010-11-27 11:04:54 +080082#include <string>
83#include <vector>
Logan1f028c02010-11-27 01:02:48 +080084
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070085namespace {
86
87#if USE_DISASSEMBLER
88class BufferMemoryObject : public llvm::MemoryObject {
89private:
90 const uint8_t *mBytes;
91 uint64_t mLength;
92
93public:
94 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length)
95 : mBytes(Bytes), mLength(Length) {
96 }
97
98 virtual uint64_t getBase() const { return 0; }
99 virtual uint64_t getExtent() const { return mLength; }
100
101 virtual int readByte(uint64_t Addr, uint8_t *Byte) const {
102 if (Addr > getExtent())
103 return -1;
104 *Byte = mBytes[Addr];
105 return 0;
106 }
107};
108#endif
109
110}; // namespace anonymous
111
Logan1f028c02010-11-27 01:02:48 +0800112namespace bcc {
113
114//////////////////////////////////////////////////////////////////////////////
115// BCC Compiler Static Variables
116//////////////////////////////////////////////////////////////////////////////
117
118bool Compiler::GlobalInitialized = false;
119
Logan1f028c02010-11-27 01:02:48 +0800120// Code generation optimization level for the compiler
121llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
122
123std::string Compiler::Triple;
124
125std::string Compiler::CPU;
126
127std::vector<std::string> Compiler::Features;
128
Stephen Hines071288a2011-01-27 14:38:26 -0800129// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800130// slang.cpp)
131const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
132
Stephen Hines071288a2011-01-27 14:38:26 -0800133// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800134// synced with slang_rs_metadata.h)
135const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
136
Stephen Hines071288a2011-01-27 14:38:26 -0800137// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800138// synced with slang_rs_metadata.h)
139const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
140
Stephen Hines071288a2011-01-27 14:38:26 -0800141// Name of metadata node where RS object slot info resides (should be
142// synced with slang_rs_metadata.h)
143const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800144
145//////////////////////////////////////////////////////////////////////////////
146// Compiler
147//////////////////////////////////////////////////////////////////////////////
148
149void Compiler::GlobalInitialization() {
150 if (GlobalInitialized)
151 return;
Logan1f028c02010-11-27 01:02:48 +0800152 // if (!llvm::llvm_is_multithreaded())
153 // llvm::llvm_start_multithreaded();
154
155 // Set Triple, CPU and Features here
156 Triple = TARGET_TRIPLE_STRING;
157
Logan1f028c02010-11-27 01:02:48 +0800158 Features.push_back("+vfp3");
Logan1f028c02010-11-27 01:02:48 +0800159
Logan4fe966f2011-02-27 08:26:40 +0800160 // NOTE: Currently, we have to turn off the support for NEON explicitly.
161 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
162 // instructions.
Joseph Wen51001b82011-06-23 18:56:45 -0700163#if ARCH_ARM_HAVE_NEON
164 Features.push_back("+d32");
165 Features.push_back("+neon");
166 Features.push_back("+neonfp");
167#else
168 Features.push_back("+d16");
169 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800170 Features.push_back("-neonfp");
Joseph Wen51001b82011-06-23 18:56:45 -0700171#endif
172
Logan4fe966f2011-02-27 08:26:40 +0800173 Features.push_back("-vmlx");
174
Logan1f028c02010-11-27 01:02:48 +0800175#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
176 LLVMInitializeARMTargetInfo();
177 LLVMInitializeARMTarget();
Logan35849002011-01-15 07:30:43 +0800178#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800179 LLVMInitializeARMDisassembler();
180 LLVMInitializeARMAsmPrinter();
181#endif
182#endif
183
184#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
185 LLVMInitializeX86TargetInfo();
186 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800187#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800188 LLVMInitializeX86Disassembler();
189 LLVMInitializeX86AsmPrinter();
190#endif
191#endif
192
193#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
194 LLVMInitializeX86TargetInfo();
195 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800196#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800197 LLVMInitializeX86Disassembler();
198 LLVMInitializeX86AsmPrinter();
199#endif
200#endif
201
202 // -O0: llvm::CodeGenOpt::None
203 // -O1: llvm::CodeGenOpt::Less
204 // -O2: llvm::CodeGenOpt::Default
205 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800206 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800207
208 // Below are the global settings to LLVM
209
210 // Disable frame pointer elimination optimization
211 llvm::NoFramePointerElim = false;
212
213 // Use hardfloat ABI
214 //
215 // TODO(all): Need to detect the CPU capability and decide whether to use
216 // softfp. To use softfp, change following 2 lines to
217 //
218 // llvm::FloatABIType = llvm::FloatABI::Soft;
219 // llvm::UseSoftFloat = true;
220 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800221 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800222 llvm::UseSoftFloat = false;
223
224 // BCC needs all unknown symbols resolved at JIT/compilation time.
225 // So we don't need any dynamic relocation model.
226 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
227
228#if defined(DEFAULT_X64_CODEGEN)
229 // Data address in X86_64 architecture may reside in a far-away place
230 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
231#else
232 // This is set for the linker (specify how large of the virtual addresses
233 // we can access for all unknown symbols.)
234 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
235#endif
236
237 // Register the scheduler
238 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
239
240 // Register allocation policy:
241 // createFastRegisterAllocator: fast but bad quality
242 // createLinearScanRegisterAllocator: not so fast but good quality
243 llvm::RegisterRegAlloc::setDefault
244 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
245 llvm::createFastRegisterAllocator :
246 llvm::createLinearScanRegisterAllocator);
247
Logan35849002011-01-15 07:30:43 +0800248#if USE_CACHE
Logan75cc8a52011-01-07 06:06:52 +0800249 // Calculate the SHA1 checksum of libbcc and libRS.
Joseph Wen2ca6e572011-06-24 14:12:23 -0700250 calcFileSHA1(sha1LibBCC_SHA1, pathLibBCC_SHA1);
Logan35849002011-01-15 07:30:43 +0800251#endif
Logan75cc8a52011-01-07 06:06:52 +0800252
Logan1f028c02010-11-27 01:02:48 +0800253 GlobalInitialized = true;
254}
255
256
257void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
258 std::string *Error = static_cast<std::string*>(UserData);
259 Error->assign(Message);
260 LOGE("%s", Message.c_str());
261 exit(1);
262}
263
264
Logan Chienda5e0c32011-06-13 03:47:21 +0800265#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800266CodeMemoryManager *Compiler::createCodeMemoryManager() {
267 mCodeMemMgr.reset(new CodeMemoryManager());
268 return mCodeMemMgr.get();
269}
Logan Chienda5e0c32011-06-13 03:47:21 +0800270#endif
Logan1f028c02010-11-27 01:02:48 +0800271
272
Logan Chienda5e0c32011-06-13 03:47:21 +0800273#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800274CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800275 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800276 return mCodeEmitter.get();
277}
Logan Chienda5e0c32011-06-13 03:47:21 +0800278#endif
Logan1f028c02010-11-27 01:02:48 +0800279
280
Logan2a6dc822011-01-06 04:05:20 +0800281Compiler::Compiler(ScriptCompiled *result)
282 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800283#if USE_MCJIT
284 mRSExecutable(NULL),
285#endif
Logan1f028c02010-11-27 01:02:48 +0800286 mpSymbolLookupFn(NULL),
287 mpSymbolLookupContext(NULL),
288 mContext(NULL),
289 mModule(NULL),
290 mHasLinked(false) /* Turn off linker */ {
291 llvm::remove_fatal_error_handler();
292 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
293 mContext = new llvm::LLVMContext();
294 return;
295}
296
Logan1f028c02010-11-27 01:02:48 +0800297
Logan Chienda5e0c32011-06-13 03:47:21 +0800298#if USE_MCJIT
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700299// input objPath: For example,
300// /data/user/0/com.example.android.rs.fountain/cache/
301// @com.example.android.rs.fountain:raw@fountain.oBCC
302// output objPath: /data/user/0/com.example.android.rs.fountain/cache/
303// fountain.o
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700304//
305bool Compiler::getObjPath(std::string &objPath) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700306 size_t found0 = objPath.find("@");
307 size_t found1 = objPath.rfind("@");
308
309 if (found0 == found1 ||
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800310 found0 == std::string::npos ||
311 found1 == std::string::npos) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700312 LOGE("Ill formatted resource name '%s'. The name should contain 2 @s",
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700313 objPath.c_str());
314 return false;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700315 }
316
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700317 objPath.replace(found0, found1 - found0 + 1, "", 0);
318 objPath.resize(objPath.length() - 3);
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700319
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700320 LOGV("objPath = %s", objPath.c_str());
321 return true;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700322}
Logan Chienda5e0c32011-06-13 03:47:21 +0800323#endif
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700324
325
Logan474cbd22011-01-31 01:47:44 +0800326llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
327 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800328
Logan474cbd22011-01-31 01:47:44 +0800329 if (!result) {
330 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
331 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800332 }
333
Logan474cbd22011-01-31 01:47:44 +0800334 return result;
Logan1f028c02010-11-27 01:02:48 +0800335}
336
337
Logan474cbd22011-01-31 01:47:44 +0800338int Compiler::linkModule(llvm::Module *moduleWith) {
339 if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800340 return hasError();
341 }
342
Logan1f028c02010-11-27 01:02:48 +0800343 // Everything for linking should be settled down here with no error occurs
344 mHasLinked = true;
345 return hasError();
346}
347
348
Logan1f028c02010-11-27 01:02:48 +0800349int Compiler::compile() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800350 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800351 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800352 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800353
Logan1f028c02010-11-27 01:02:48 +0800354 std::string FeaturesStr;
355
Logan Chienda5e0c32011-06-13 03:47:21 +0800356 llvm::NamedMDNode const *PragmaMetadata;
357 llvm::NamedMDNode const *ExportVarMetadata;
358 llvm::NamedMDNode const *ExportFuncMetadata;
359 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800360
Logan1f028c02010-11-27 01:02:48 +0800361 if (mModule == NULL) // No module was loaded
362 return 0;
363
364 // Create TargetMachine
365 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
366 if (hasError())
367 goto on_bcc_compile_error;
368
369 if (!CPU.empty() || !Features.empty()) {
370 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800371
372 for (std::vector<std::string>::const_iterator
373 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800374 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800375 }
376
Logan1f028c02010-11-27 01:02:48 +0800377 FeaturesStr = F.getString();
378 }
379
Shih-wei Liao029057e2011-07-02 11:34:35 -0700380 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr);
Logan1f028c02010-11-27 01:02:48 +0800381 if (TM == NULL) {
382 setError("Failed to create target machine implementation for the"
383 " specified triple '" + Triple + "'");
384 goto on_bcc_compile_error;
385 }
386
Logan Chienda5e0c32011-06-13 03:47:21 +0800387 // Get target data from Module
388 TD = new llvm::TargetData(mModule);
389
390 // Load named metadata
391 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
392 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
393 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
394 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
395
396 // Perform link-time optimization if we have multiple modules
397 if (mHasLinked) {
398 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
399 }
400
401 // Perform code generation
402#if USE_OLD_JIT
403 if (runCodeGen(new llvm::TargetData(*TD), TM,
404 ExportVarMetadata, ExportFuncMetadata) != 0) {
405 goto on_bcc_compile_error;
406 }
407#endif
408
409#if USE_MCJIT
410 if (runMCCodeGen(new llvm::TargetData(*TD), TM,
411 ExportVarMetadata, ExportFuncMetadata) != 0) {
412 goto on_bcc_compile_error;
413 }
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700414#if USE_DISASSEMBLER && DEBUG_MCJIT_DISASSEMBLE
415 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700416 // Get MC codegen emitted function name list
417 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
418 std::vector<char const *> func_list(func_list_size, NULL);
419 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700420
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700421 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700422 for (size_t i = 0; i < func_list_size; ++i) {
423 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
424 if (func) {
425 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
426 Disassemble(Target, TM, func_list[i], (unsigned char const *)func, size);
427 }
428 }
429 }
430#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800431#endif
432
433 // Read pragma information from the metadata node of the module.
434 if (PragmaMetadata) {
435 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
436
437 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
438 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
439 if (Pragma != NULL &&
440 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
441 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
442 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
443
444 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
445 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
446 llvm::StringRef PragmaName =
447 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
448 llvm::StringRef PragmaValue =
449 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
450
451 pragmaList.push_back(
452 std::make_pair(std::string(PragmaName.data(),
453 PragmaName.size()),
454 std::string(PragmaValue.data(),
455 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700456#if DEBUG_BCC_REFLECT
457 LOGD("compile(): Pragma: %s -> %s\n",
458 pragmaList.back().first.c_str(),
459 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700460#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800461 }
462 }
463 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800464 }
465
466 if (ObjectSlotMetadata) {
467 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
468
469 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
470 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
471 if (ObjectSlot != NULL &&
472 ObjectSlot->getNumOperands() == 1) {
473 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
474 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
475 llvm::StringRef Slot =
476 static_cast<llvm::MDString*>(SlotMDS)->getString();
477 uint32_t USlot = 0;
478 if (Slot.getAsInteger(10, USlot)) {
479 setError("Non-integer object slot value '" + Slot.str() + "'");
480 goto on_bcc_compile_error;
481 }
482 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700483#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700484 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
485#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800486 }
487 }
488 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800489 }
490
491on_bcc_compile_error:
492 // LOGE("on_bcc_compiler_error");
493 if (TD) {
494 delete TD;
495 }
496
497 if (TM) {
498 delete TM;
499 }
500
501 if (mError.empty()) {
502 return 0;
503 }
504
505 // LOGE(getErrorMessage());
506 return 1;
507}
508
509
510#if USE_OLD_JIT
511int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
512 llvm::NamedMDNode const *ExportVarMetadata,
513 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800514 // Create memory manager for creation of code emitter later.
515 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
516 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800517 return 1;
Logan1f028c02010-11-27 01:02:48 +0800518 }
Logan02286cb2011-01-07 00:30:47 +0800519
520 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800521
522 // Create code emitter
523 if (!mCodeEmitter.get()) {
524 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800525 setError("Failed to create machine code emitter for compilation");
526 return 1;
Logan1f028c02010-11-27 01:02:48 +0800527 }
528 } else {
529 // Reuse the code emitter
530 mCodeEmitter->reset();
531 }
532
533 mCodeEmitter->setTargetMachine(*TM);
534 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
535 mpSymbolLookupContext);
536
Logan1f028c02010-11-27 01:02:48 +0800537 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800538 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
539 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800540
Logan Chienda5e0c32011-06-13 03:47:21 +0800541 // Add TargetData to code generation pass manager
542 CodeGenPasses->add(TD);
543
544 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800545 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
546 *mCodeEmitter,
547 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800548 setError("The machine code emission is not supported on '" + Triple + "'");
549 return 1;
Logan1f028c02010-11-27 01:02:48 +0800550 }
551
Logan Chienda5e0c32011-06-13 03:47:21 +0800552 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800553 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800554 for (llvm::Module::iterator
555 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800556 if (!I->isDeclaration()) {
557 CodeGenPasses->run(*I);
558 }
559 }
560
561 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800562
Logan1f028c02010-11-27 01:02:48 +0800563 // Copy the global address mapping from code emitter and remapping
564 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800565 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
566
Logan1f028c02010-11-27 01:02:48 +0800567 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
568 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
569 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
570 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
571 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
572 llvm::StringRef ExportVarName =
573 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
574
575 CodeEmitter::global_addresses_const_iterator I, E;
576 for (I = mCodeEmitter->global_address_begin(),
577 E = mCodeEmitter->global_address_end();
578 I != E; I++) {
579 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
580 continue;
581 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800582 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700583#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700584 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
585#endif
Logan1f028c02010-11-27 01:02:48 +0800586 break;
587 }
588 }
589 if (I != mCodeEmitter->global_address_end())
590 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800591
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700592#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700593 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800594 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700595#endif
Logan1f028c02010-11-27 01:02:48 +0800596 }
597 }
598 // if reaching here, we know the global variable record in metadata is
599 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800600 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800601 }
Logan2a6dc822011-01-06 04:05:20 +0800602
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700603 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
604 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800605 }
606
607 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800608 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
609
Logan1f028c02010-11-27 01:02:48 +0800610 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
611 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
612 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
613 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
614 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
615 llvm::StringRef ExportFuncName =
616 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800617 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700618#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700619 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800620 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700621#endif
Logan1f028c02010-11-27 01:02:48 +0800622 }
623 }
624 }
625 }
626
627 // Tell code emitter now can release the memory using during the JIT since
628 // we have done the code emission
629 mCodeEmitter->releaseUnnecessary();
630
Logan Chienda5e0c32011-06-13 03:47:21 +0800631 return 0;
Logan1f028c02010-11-27 01:02:48 +0800632}
Logan Chienda5e0c32011-06-13 03:47:21 +0800633#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800634
635
Logan Chienda5e0c32011-06-13 03:47:21 +0800636#if USE_MCJIT
637int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
638 llvm::NamedMDNode const *ExportVarMetadata,
639 llvm::NamedMDNode const *ExportFuncMetadata) {
640 // Decorate mEmittedELFExecutable with formatted ostream
641 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
642
643 // Relax all machine instructions
644 TM->setMCRelaxAll(/* RelaxAll= */ true);
645
646 // Create MC code generation pass manager
647 llvm::PassManager MCCodeGenPasses;
648
649 // Add TargetData to MC code generation pass manager
650 MCCodeGenPasses.add(TD);
651
652 // Add MC code generation passes to pass manager
653 llvm::MCContext *Ctx;
654 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
655 CodeGenOptLevel, false)) {
656 setError("Fail to add passes to emit file");
657 return 1;
658 }
659
660 MCCodeGenPasses.run(*mModule);
661 OutSVOS.flush();
662
663 // Load the ELF Object
664 mRSExecutable =
665 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
666 mEmittedELFExecutable.size(),
667 &resolveSymbolAdapter, this);
668
669 if (!mRSExecutable) {
670 setError("Fail to load emitted ELF relocatable file");
671 return 1;
672 }
673
674#if !USE_OLD_JIT
675 // Note: If old JIT is compiled then we prefer the old version instead of the
676 // new version.
677
678 if (ExportVarMetadata) {
679 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
680
681 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
682 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
Logan Chien70dd9982011-06-13 23:21:39 +0800683 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
684 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
685 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
686 llvm::StringRef ExportVarName =
687 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
688
689 varList.push_back(
690 rsloaderGetSymbolAddress(mRSExecutable,
691 ExportVarName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700692#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700693 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Logan Chien70dd9982011-06-13 23:21:39 +0800694 varList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700695#endif
Logan Chien70dd9982011-06-13 23:21:39 +0800696 continue;
697 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800698 }
699
Logan Chien70dd9982011-06-13 23:21:39 +0800700 varList.push_back(NULL);
Logan Chienda5e0c32011-06-13 03:47:21 +0800701 }
702 }
703
704 if (ExportFuncMetadata) {
705 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
706
707 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
708 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
709 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
710 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
711 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
712 llvm::StringRef ExportFuncName =
713 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
714
715 funcList.push_back(
716 rsloaderGetSymbolAddress(mRSExecutable,
717 ExportFuncName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700718#if DEBUG_MCJIT_RELECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700719 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800720 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700721#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800722 }
723 }
724 }
725 }
726#endif // !USE_OLD_JIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800727 return 0;
728}
729#endif // USE_MCJIT
730
731
732int Compiler::runLTO(llvm::TargetData *TD,
733 llvm::NamedMDNode const *ExportVarMetadata,
734 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800735 llvm::PassManager LTOPasses;
736
737 // Add TargetData to LTO passes
738 LTOPasses.add(TD);
739
740 // Collect All Exported Symbols
741 std::vector<const char*> ExportSymbols;
742
743 // Note: This is a workaround for getting export variable and function name.
744 // We should refine it soon.
745 if (ExportVarMetadata) {
746 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
747 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
748 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
749 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
750 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
751 llvm::StringRef ExportVarName =
752 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
753 ExportSymbols.push_back(ExportVarName.data());
754 }
755 }
756 }
757 }
758
759 if (ExportFuncMetadata) {
760 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
761 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
762 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
763 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
764 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
765 llvm::StringRef ExportFuncName =
766 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
767 ExportSymbols.push_back(ExportFuncName.data());
768 }
769 }
770 }
771 }
772
773 // root() and init() are born to be exported
774 ExportSymbols.push_back("root");
775 ExportSymbols.push_back("init");
776
777 // We now create passes list performing LTO. These are copied from
778 // (including comments) llvm::createStandardLTOPasses().
779
780 // Internalize all other symbols not listed in ExportSymbols
781 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
782
783 // Propagate constants at call sites into the functions they call. This
784 // opens opportunities for globalopt (and inlining) by substituting
785 // function pointers passed as arguments to direct uses of functions.
786 LTOPasses.add(llvm::createIPSCCPPass());
787
788 // Now that we internalized some globals, see if we can hack on them!
789 LTOPasses.add(llvm::createGlobalOptimizerPass());
790
791 // Linking modules together can lead to duplicated global constants, only
792 // keep one copy of each constant...
793 LTOPasses.add(llvm::createConstantMergePass());
794
795 // Remove unused arguments from functions...
796 LTOPasses.add(llvm::createDeadArgEliminationPass());
797
798 // Reduce the code after globalopt and ipsccp. Both can open up
799 // significant simplification opportunities, and both can propagate
800 // functions through function pointers. When this happens, we often have
801 // to resolve varargs calls, etc, so let instcombine do this.
802 LTOPasses.add(llvm::createInstructionCombiningPass());
803
804 // Inline small functions
805 LTOPasses.add(llvm::createFunctionInliningPass());
806
807 // Remove dead EH info.
808 LTOPasses.add(llvm::createPruneEHPass());
809
810 // Internalize the globals again after inlining
811 LTOPasses.add(llvm::createGlobalOptimizerPass());
812
813 // Remove dead functions.
814 LTOPasses.add(llvm::createGlobalDCEPass());
815
816 // If we didn't decide to inline a function, check to see if we can
817 // transform it to pass arguments by value instead of by reference.
818 LTOPasses.add(llvm::createArgumentPromotionPass());
819
820 // The IPO passes may leave cruft around. Clean up after them.
821 LTOPasses.add(llvm::createInstructionCombiningPass());
822 LTOPasses.add(llvm::createJumpThreadingPass());
823
824 // Break up allocas
825 LTOPasses.add(llvm::createScalarReplAggregatesPass());
826
827 // Run a few AA driven optimizations here and now, to cleanup the code.
828 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
829 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
830
831 // Hoist loop invariants.
832 LTOPasses.add(llvm::createLICMPass());
833
834 // Remove redundancies.
835 LTOPasses.add(llvm::createGVNPass());
836
837 // Remove dead memcpys.
838 LTOPasses.add(llvm::createMemCpyOptPass());
839
840 // Nuke dead stores.
841 LTOPasses.add(llvm::createDeadStoreEliminationPass());
842
843 // Cleanup and simplify the code after the scalar optimizations.
844 LTOPasses.add(llvm::createInstructionCombiningPass());
845
846 LTOPasses.add(llvm::createJumpThreadingPass());
847
848 // Delete basic blocks, which optimization passes may have killed.
849 LTOPasses.add(llvm::createCFGSimplificationPass());
850
851 // Now that we have optimized the program, discard unreachable functions.
852 LTOPasses.add(llvm::createGlobalDCEPass());
853
854 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800855
856 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800857}
858
859
Logan Chienda5e0c32011-06-13 03:47:21 +0800860#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800861void *Compiler::getSymbolAddress(char const *name) {
862 return rsloaderGetSymbolAddress(mRSExecutable, name);
863}
864#endif
865
866
867#if USE_MCJIT
868void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
869 Compiler *self = reinterpret_cast<Compiler *>(context);
870
871 if (void *Addr = FindRuntimeFunction(name)) {
872 return Addr;
873 }
874
875 if (self->mpSymbolLookupFn) {
876 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
877 return Addr;
878 }
879 }
880
881 LOGE("Unable to resolve symbol: %s\n", name);
882 return NULL;
883}
884#endif
885
886
Logan1f028c02010-11-27 01:02:48 +0800887Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800888 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800889 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800890
Logan Chienda5e0c32011-06-13 03:47:21 +0800891#if USE_MCJIT
892 rsloaderDisposeExec(mRSExecutable);
893#endif
894
Logana4994f52010-11-27 14:06:02 +0800895 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800896}
897
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700898#if USE_MCJIT && USE_DISASSEMBLER
899void Compiler::Disassemble(llvm::Target const *Target,
900 llvm::TargetMachine *TM,
901 std::string const &Name,
902 unsigned char const *Func,
903 size_t FuncSize) {
904 llvm::raw_ostream *OS;
905
906#if USE_DISASSEMBLER_FILE
907 std::string ErrorInfo;
908 OS = new llvm::raw_fd_ostream("/data/local/tmp/mcjit-dis.s", ErrorInfo,
909 llvm::raw_fd_ostream::F_Append);
910
911 if (!ErrorInfo.empty()) { // some errors occurred
912 // LOGE("Error in creating disassembly file");
913 delete OS;
914 return;
915 }
916#else
917 OS = &llvm::outs();
918#endif
919
920 *OS << "MC/ Disassembled code: " << Name << "\n";
921
922 const llvm::MCAsmInfo *AsmInfo;
923 const llvm::MCDisassembler *Disassmbler;
924 llvm::MCInstPrinter *IP;
925
926 AsmInfo = Target->createAsmInfo(Compiler::Triple);
927 Disassmbler = Target->createMCDisassembler();
928 IP = Target->createMCInstPrinter(*TM,
929 AsmInfo->getAssemblerDialect(),
930 *AsmInfo);
931
932 const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Func, FuncSize);
933
934 uint64_t Size;
935 uint64_t Index;
936
937 for (Index = 0; Index < FuncSize; Index += Size) {
938 llvm::MCInst Inst;
939
940 if (Disassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
941 /* REMOVED */ llvm::nulls())) {
942 OS->indent(4);
943 OS->write("0x", 2);
944 OS->write_hex((uint32_t)Func + Index);
945 OS->write(": 0x", 4);
946 OS->write_hex(*(uint32_t *)(Func + Index));
947 IP->printInst(&Inst, *OS);
948 *OS << "\n";
949 } else {
950 if (Size == 0)
951 Size = 1; // skip illegible bytes
952 }
953 }
954
955 *OS << "\n";
956 delete BufferMObj;
957
958 delete AsmInfo;
959 delete Disassmbler;
960 delete IP;
961
962#if USE_DISASSEMBLER_FILE
963 // If you want the disassemble results write to file, uncomment this.
964 ((llvm::raw_fd_ostream*)OS)->close();
965 delete OS;
966#endif
967}
968#endif
969
970
Logan1f028c02010-11-27 01:02:48 +0800971} // namespace bcc