blob: f3a3343aae2507acaae0e043110a8359c0a1cd0a [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
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070050#if USE_DISASSEMBLER
51#include "llvm/MC/MCAsmInfo.h"
52#include "llvm/MC/MCDisassembler.h"
53#include "llvm/MC/MCInst.h"
54#include "llvm/MC/MCInstPrinter.h"
55#include "llvm/Support/MemoryObject.h"
56#include "llvm/LLVMContext.h"
57#endif
58
Logandf23afa2010-11-27 11:04:54 +080059#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070060#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080061#include "llvm/Support/MemoryBuffer.h"
62
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070063#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080064#include "llvm/GlobalValue.h"
65#include "llvm/Linker.h"
66#include "llvm/LLVMContext.h"
67#include "llvm/Metadata.h"
68#include "llvm/Module.h"
69#include "llvm/PassManager.h"
70#include "llvm/Value.h"
71
72#include <errno.h>
73#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080074#include <sys/stat.h>
75#include <sys/types.h>
76#include <unistd.h>
77
Logan75cc8a52011-01-07 06:06:52 +080078#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080079
Logandf23afa2010-11-27 11:04:54 +080080#include <string>
81#include <vector>
Logan1f028c02010-11-27 01:02:48 +080082
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070083namespace {
84
85#if USE_DISASSEMBLER
86class BufferMemoryObject : public llvm::MemoryObject {
87private:
88 const uint8_t *mBytes;
89 uint64_t mLength;
90
91public:
92 BufferMemoryObject(const uint8_t *Bytes, uint64_t Length)
93 : mBytes(Bytes), mLength(Length) {
94 }
95
96 virtual uint64_t getBase() const { return 0; }
97 virtual uint64_t getExtent() const { return mLength; }
98
99 virtual int readByte(uint64_t Addr, uint8_t *Byte) const {
100 if (Addr > getExtent())
101 return -1;
102 *Byte = mBytes[Addr];
103 return 0;
104 }
105};
106#endif
107
108}; // namespace anonymous
109
110#define DEBUG_MCJIT REFLECT 0
111#define DEBUG_MCJIT_DISASSEMBLE 1
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700112
Logan1f028c02010-11-27 01:02:48 +0800113namespace bcc {
114
115//////////////////////////////////////////////////////////////////////////////
116// BCC Compiler Static Variables
117//////////////////////////////////////////////////////////////////////////////
118
119bool Compiler::GlobalInitialized = false;
120
Logan1f028c02010-11-27 01:02:48 +0800121// Code generation optimization level for the compiler
122llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
123
124std::string Compiler::Triple;
125
126std::string Compiler::CPU;
127
128std::vector<std::string> Compiler::Features;
129
Stephen Hines071288a2011-01-27 14:38:26 -0800130// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800131// slang.cpp)
132const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
133
Stephen Hines071288a2011-01-27 14:38:26 -0800134// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800135// synced with slang_rs_metadata.h)
136const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
137
Stephen Hines071288a2011-01-27 14:38:26 -0800138// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800139// synced with slang_rs_metadata.h)
140const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
141
Stephen Hines071288a2011-01-27 14:38:26 -0800142// Name of metadata node where RS object slot info resides (should be
143// synced with slang_rs_metadata.h)
144const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800145
146//////////////////////////////////////////////////////////////////////////////
147// Compiler
148//////////////////////////////////////////////////////////////////////////////
149
150void Compiler::GlobalInitialization() {
151 if (GlobalInitialized)
152 return;
153
Logane1323992011-01-12 04:47:13 +0800154 LOGI("LIBBCC BUILD: %s\n", libbcc_build_time);
Logan87066272010-12-29 00:34:32 +0800155
Logan1f028c02010-11-27 01:02:48 +0800156 // if (!llvm::llvm_is_multithreaded())
157 // llvm::llvm_start_multithreaded();
158
159 // Set Triple, CPU and Features here
160 Triple = TARGET_TRIPLE_STRING;
161
Logan1f028c02010-11-27 01:02:48 +0800162 Features.push_back("+vfp3");
163 Features.push_back("+d16");
164
Logan4fe966f2011-02-27 08:26:40 +0800165 // NOTE: Currently, we have to turn off the support for NEON explicitly.
166 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
167 // instructions.
168 Features.push_back("-neon"); // TODO(sliao): NEON for JIT
169 Features.push_back("-neonfp");
170 Features.push_back("-vmlx");
171
Logan1f028c02010-11-27 01:02:48 +0800172#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
173 LLVMInitializeARMTargetInfo();
174 LLVMInitializeARMTarget();
Logan35849002011-01-15 07:30:43 +0800175#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800176 LLVMInitializeARMDisassembler();
177 LLVMInitializeARMAsmPrinter();
178#endif
179#endif
180
181#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN)
182 LLVMInitializeX86TargetInfo();
183 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800184#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800185 LLVMInitializeX86Disassembler();
186 LLVMInitializeX86AsmPrinter();
187#endif
188#endif
189
190#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
191 LLVMInitializeX86TargetInfo();
192 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800193#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800194 LLVMInitializeX86Disassembler();
195 LLVMInitializeX86AsmPrinter();
196#endif
197#endif
198
199 // -O0: llvm::CodeGenOpt::None
200 // -O1: llvm::CodeGenOpt::Less
201 // -O2: llvm::CodeGenOpt::Default
202 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800203 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800204
205 // Below are the global settings to LLVM
206
207 // Disable frame pointer elimination optimization
208 llvm::NoFramePointerElim = false;
209
210 // Use hardfloat ABI
211 //
212 // TODO(all): Need to detect the CPU capability and decide whether to use
213 // softfp. To use softfp, change following 2 lines to
214 //
215 // llvm::FloatABIType = llvm::FloatABI::Soft;
216 // llvm::UseSoftFloat = true;
217 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800218 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800219 llvm::UseSoftFloat = false;
220
221 // BCC needs all unknown symbols resolved at JIT/compilation time.
222 // So we don't need any dynamic relocation model.
223 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
224
225#if defined(DEFAULT_X64_CODEGEN)
226 // Data address in X86_64 architecture may reside in a far-away place
227 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
228#else
229 // This is set for the linker (specify how large of the virtual addresses
230 // we can access for all unknown symbols.)
231 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
232#endif
233
234 // Register the scheduler
235 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
236
237 // Register allocation policy:
238 // createFastRegisterAllocator: fast but bad quality
239 // createLinearScanRegisterAllocator: not so fast but good quality
240 llvm::RegisterRegAlloc::setDefault
241 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
242 llvm::createFastRegisterAllocator :
243 llvm::createLinearScanRegisterAllocator);
244
Logan35849002011-01-15 07:30:43 +0800245#if USE_CACHE
Logan75cc8a52011-01-07 06:06:52 +0800246 // Calculate the SHA1 checksum of libbcc and libRS.
Logan35849002011-01-15 07:30:43 +0800247#if USE_LIBBCC_SHA1SUM
Logan75cc8a52011-01-07 06:06:52 +0800248 calcFileSHA1(sha1LibBCC, pathLibBCC);
Logane1323992011-01-12 04:47:13 +0800249#endif
Logan75cc8a52011-01-07 06:06:52 +0800250 calcFileSHA1(sha1LibRS, pathLibRS);
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;
371 F.setCPU(CPU);
Logana4994f52010-11-27 14:06:02 +0800372
373 for (std::vector<std::string>::const_iterator
374 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800375 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800376 }
377
Logan1f028c02010-11-27 01:02:48 +0800378 FeaturesStr = F.getString();
379 }
380
381 TM = Target->createTargetMachine(Triple, FeaturesStr);
382 if (TM == NULL) {
383 setError("Failed to create target machine implementation for the"
384 " specified triple '" + Triple + "'");
385 goto on_bcc_compile_error;
386 }
387
Logan Chienda5e0c32011-06-13 03:47:21 +0800388 // Get target data from Module
389 TD = new llvm::TargetData(mModule);
390
391 // Load named metadata
392 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
393 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
394 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
395 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
396
397 // Perform link-time optimization if we have multiple modules
Shih-wei Liaoe2019762011-06-20 16:04:09 -0700398#if !USE_MCJIT || !DEBUG_MCJIT_DISASSEMBLE
Logan Chienda5e0c32011-06-13 03:47:21 +0800399 if (mHasLinked) {
400 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
401 }
Shih-wei Liaoe2019762011-06-20 16:04:09 -0700402#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800403
404 // Perform code generation
405#if USE_OLD_JIT
406 if (runCodeGen(new llvm::TargetData(*TD), TM,
407 ExportVarMetadata, ExportFuncMetadata) != 0) {
408 goto on_bcc_compile_error;
409 }
410#endif
411
412#if USE_MCJIT
413 if (runMCCodeGen(new llvm::TargetData(*TD), TM,
414 ExportVarMetadata, ExportFuncMetadata) != 0) {
415 goto on_bcc_compile_error;
416 }
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700417#if USE_DISASSEMBLER && DEBUG_MCJIT_DISASSEMBLE
418 {
419 llvm::LLVMContext Ctx;
420 LOGD("@ long long alignment: %d\n", TD->getABITypeAlignment((llvm::Type const *)llvm::Type::getInt64Ty(Ctx)));
Shih-wei Liaoe2019762011-06-20 16:04:09 -0700421 char const *func_list[] = { "root", "lookAt" };
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700422 size_t func_list_size = sizeof(func_list) / sizeof(char const *);
423
424 for (size_t i = 0; i < func_list_size; ++i) {
425 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
426 if (func) {
427 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
428 Disassemble(Target, TM, func_list[i], (unsigned char const *)func, size);
429 }
430 }
431 }
432#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800433#endif
434
435 // Read pragma information from the metadata node of the module.
436 if (PragmaMetadata) {
437 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
438
439 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
440 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
441 if (Pragma != NULL &&
442 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
443 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
444 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
445
446 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
447 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
448 llvm::StringRef PragmaName =
449 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
450 llvm::StringRef PragmaValue =
451 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
452
453 pragmaList.push_back(
454 std::make_pair(std::string(PragmaName.data(),
455 PragmaName.size()),
456 std::string(PragmaValue.data(),
457 PragmaValue.size())));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700458#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700459 LOGD("compile(): Pragma: %s -> %s\n", pragmaList.back().first.c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800460 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700461#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800462 }
463 }
464 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800465 }
466
467 if (ObjectSlotMetadata) {
468 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
469
470 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
471 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
472 if (ObjectSlot != NULL &&
473 ObjectSlot->getNumOperands() == 1) {
474 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
475 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
476 llvm::StringRef Slot =
477 static_cast<llvm::MDString*>(SlotMDS)->getString();
478 uint32_t USlot = 0;
479 if (Slot.getAsInteger(10, USlot)) {
480 setError("Non-integer object slot value '" + Slot.str() + "'");
481 goto on_bcc_compile_error;
482 }
483 objectSlotList.push_back(USlot);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700484#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700485 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
486#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800487 }
488 }
489 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800490 }
491
492on_bcc_compile_error:
493 // LOGE("on_bcc_compiler_error");
494 if (TD) {
495 delete TD;
496 }
497
498 if (TM) {
499 delete TM;
500 }
501
502 if (mError.empty()) {
503 return 0;
504 }
505
506 // LOGE(getErrorMessage());
507 return 1;
508}
509
510
511#if USE_OLD_JIT
512int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
513 llvm::NamedMDNode const *ExportVarMetadata,
514 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800515 // Create memory manager for creation of code emitter later.
516 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
517 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800518 return 1;
Logan1f028c02010-11-27 01:02:48 +0800519 }
Logan02286cb2011-01-07 00:30:47 +0800520
521 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800522
523 // Create code emitter
524 if (!mCodeEmitter.get()) {
525 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800526 setError("Failed to create machine code emitter for compilation");
527 return 1;
Logan1f028c02010-11-27 01:02:48 +0800528 }
529 } else {
530 // Reuse the code emitter
531 mCodeEmitter->reset();
532 }
533
534 mCodeEmitter->setTargetMachine(*TM);
535 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
536 mpSymbolLookupContext);
537
Logan1f028c02010-11-27 01:02:48 +0800538 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800539 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
540 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800541
Logan Chienda5e0c32011-06-13 03:47:21 +0800542 // Add TargetData to code generation pass manager
543 CodeGenPasses->add(TD);
544
545 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800546 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
547 *mCodeEmitter,
548 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800549 setError("The machine code emission is not supported on '" + Triple + "'");
550 return 1;
Logan1f028c02010-11-27 01:02:48 +0800551 }
552
Logan Chienda5e0c32011-06-13 03:47:21 +0800553 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800554 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800555 for (llvm::Module::iterator
556 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800557 if (!I->isDeclaration()) {
558 CodeGenPasses->run(*I);
559 }
560 }
561
562 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800563
Logan1f028c02010-11-27 01:02:48 +0800564 // Copy the global address mapping from code emitter and remapping
565 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800566 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
567
Logan1f028c02010-11-27 01:02:48 +0800568 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
569 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
570 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
571 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
572 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
573 llvm::StringRef ExportVarName =
574 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
575
576 CodeEmitter::global_addresses_const_iterator I, E;
577 for (I = mCodeEmitter->global_address_begin(),
578 E = mCodeEmitter->global_address_end();
579 I != E; I++) {
580 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
581 continue;
582 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800583 varList.push_back(I->second);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700584#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700585 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
586#endif
Logan1f028c02010-11-27 01:02:48 +0800587 break;
588 }
589 }
590 if (I != mCodeEmitter->global_address_end())
591 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800592
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700593#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700594 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800595 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700596#endif
Logan1f028c02010-11-27 01:02:48 +0800597 }
598 }
599 // if reaching here, we know the global variable record in metadata is
600 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800601 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800602 }
Logan2a6dc822011-01-06 04:05:20 +0800603
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700604 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
605 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800606 }
607
608 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800609 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
610
Logan1f028c02010-11-27 01:02:48 +0800611 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
612 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
613 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
614 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
615 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
616 llvm::StringRef ExportFuncName =
617 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800618 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700619#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700620 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800621 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700622#endif
Logan1f028c02010-11-27 01:02:48 +0800623 }
624 }
625 }
626 }
627
628 // Tell code emitter now can release the memory using during the JIT since
629 // we have done the code emission
630 mCodeEmitter->releaseUnnecessary();
631
Logan Chienda5e0c32011-06-13 03:47:21 +0800632 return 0;
Logan1f028c02010-11-27 01:02:48 +0800633}
Logan Chienda5e0c32011-06-13 03:47:21 +0800634#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800635
636
Logan Chienda5e0c32011-06-13 03:47:21 +0800637#if USE_MCJIT
638int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
639 llvm::NamedMDNode const *ExportVarMetadata,
640 llvm::NamedMDNode const *ExportFuncMetadata) {
641 // Decorate mEmittedELFExecutable with formatted ostream
642 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
643
644 // Relax all machine instructions
645 TM->setMCRelaxAll(/* RelaxAll= */ true);
646
647 // Create MC code generation pass manager
648 llvm::PassManager MCCodeGenPasses;
649
650 // Add TargetData to MC code generation pass manager
651 MCCodeGenPasses.add(TD);
652
653 // Add MC code generation passes to pass manager
654 llvm::MCContext *Ctx;
655 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
656 CodeGenOptLevel, false)) {
657 setError("Fail to add passes to emit file");
658 return 1;
659 }
660
661 MCCodeGenPasses.run(*mModule);
662 OutSVOS.flush();
663
664 // Load the ELF Object
665 mRSExecutable =
666 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
667 mEmittedELFExecutable.size(),
668 &resolveSymbolAdapter, this);
669
670 if (!mRSExecutable) {
671 setError("Fail to load emitted ELF relocatable file");
672 return 1;
673 }
674
675#if !USE_OLD_JIT
676 // Note: If old JIT is compiled then we prefer the old version instead of the
677 // new version.
678
679 if (ExportVarMetadata) {
680 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
681
682 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
683 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
Logan Chien70dd9982011-06-13 23:21:39 +0800684 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
685 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
686 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
687 llvm::StringRef ExportVarName =
688 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
689
690 varList.push_back(
691 rsloaderGetSymbolAddress(mRSExecutable,
692 ExportVarName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700693#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700694 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Logan Chien70dd9982011-06-13 23:21:39 +0800695 varList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700696#endif
Logan Chien70dd9982011-06-13 23:21:39 +0800697 continue;
698 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800699 }
700
Logan Chien70dd9982011-06-13 23:21:39 +0800701 varList.push_back(NULL);
Logan Chienda5e0c32011-06-13 03:47:21 +0800702 }
703 }
704
705 if (ExportFuncMetadata) {
706 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
707
708 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
709 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
710 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
711 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
712 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
713 llvm::StringRef ExportFuncName =
714 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
715
716 funcList.push_back(
717 rsloaderGetSymbolAddress(mRSExecutable,
718 ExportFuncName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700719#if DEBUG_MCJIT_RELECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700720 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800721 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700722#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800723 }
724 }
725 }
726 }
727#endif // !USE_OLD_JIT
728
729#if USE_CACHE
730 // Write generated executable to file.
731 if (writeELFExecToFile() != 0) {
732 setError("Fail to write mcjit-ed executable to file");
733 return 1;
734 }
735#endif
736
737 return 0;
738}
739#endif // USE_MCJIT
740
741
742int Compiler::runLTO(llvm::TargetData *TD,
743 llvm::NamedMDNode const *ExportVarMetadata,
744 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800745 llvm::PassManager LTOPasses;
746
747 // Add TargetData to LTO passes
748 LTOPasses.add(TD);
749
750 // Collect All Exported Symbols
751 std::vector<const char*> ExportSymbols;
752
753 // Note: This is a workaround for getting export variable and function name.
754 // We should refine it soon.
755 if (ExportVarMetadata) {
756 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
757 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
758 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
759 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
760 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
761 llvm::StringRef ExportVarName =
762 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
763 ExportSymbols.push_back(ExportVarName.data());
764 }
765 }
766 }
767 }
768
769 if (ExportFuncMetadata) {
770 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
771 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
772 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
773 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
774 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
775 llvm::StringRef ExportFuncName =
776 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
777 ExportSymbols.push_back(ExportFuncName.data());
778 }
779 }
780 }
781 }
782
783 // root() and init() are born to be exported
784 ExportSymbols.push_back("root");
785 ExportSymbols.push_back("init");
786
787 // We now create passes list performing LTO. These are copied from
788 // (including comments) llvm::createStandardLTOPasses().
789
790 // Internalize all other symbols not listed in ExportSymbols
791 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
792
793 // Propagate constants at call sites into the functions they call. This
794 // opens opportunities for globalopt (and inlining) by substituting
795 // function pointers passed as arguments to direct uses of functions.
796 LTOPasses.add(llvm::createIPSCCPPass());
797
798 // Now that we internalized some globals, see if we can hack on them!
799 LTOPasses.add(llvm::createGlobalOptimizerPass());
800
801 // Linking modules together can lead to duplicated global constants, only
802 // keep one copy of each constant...
803 LTOPasses.add(llvm::createConstantMergePass());
804
805 // Remove unused arguments from functions...
806 LTOPasses.add(llvm::createDeadArgEliminationPass());
807
808 // Reduce the code after globalopt and ipsccp. Both can open up
809 // significant simplification opportunities, and both can propagate
810 // functions through function pointers. When this happens, we often have
811 // to resolve varargs calls, etc, so let instcombine do this.
812 LTOPasses.add(llvm::createInstructionCombiningPass());
813
814 // Inline small functions
815 LTOPasses.add(llvm::createFunctionInliningPass());
816
817 // Remove dead EH info.
818 LTOPasses.add(llvm::createPruneEHPass());
819
820 // Internalize the globals again after inlining
821 LTOPasses.add(llvm::createGlobalOptimizerPass());
822
823 // Remove dead functions.
824 LTOPasses.add(llvm::createGlobalDCEPass());
825
826 // If we didn't decide to inline a function, check to see if we can
827 // transform it to pass arguments by value instead of by reference.
828 LTOPasses.add(llvm::createArgumentPromotionPass());
829
830 // The IPO passes may leave cruft around. Clean up after them.
831 LTOPasses.add(llvm::createInstructionCombiningPass());
832 LTOPasses.add(llvm::createJumpThreadingPass());
833
834 // Break up allocas
835 LTOPasses.add(llvm::createScalarReplAggregatesPass());
836
837 // Run a few AA driven optimizations here and now, to cleanup the code.
838 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
839 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
840
841 // Hoist loop invariants.
842 LTOPasses.add(llvm::createLICMPass());
843
844 // Remove redundancies.
845 LTOPasses.add(llvm::createGVNPass());
846
847 // Remove dead memcpys.
848 LTOPasses.add(llvm::createMemCpyOptPass());
849
850 // Nuke dead stores.
851 LTOPasses.add(llvm::createDeadStoreEliminationPass());
852
853 // Cleanup and simplify the code after the scalar optimizations.
854 LTOPasses.add(llvm::createInstructionCombiningPass());
855
856 LTOPasses.add(llvm::createJumpThreadingPass());
857
858 // Delete basic blocks, which optimization passes may have killed.
859 LTOPasses.add(llvm::createCFGSimplificationPass());
860
861 // Now that we have optimized the program, discard unreachable functions.
862 LTOPasses.add(llvm::createGlobalDCEPass());
863
864 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800865
866 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800867}
868
869
Logan Chienda5e0c32011-06-13 03:47:21 +0800870#if USE_MCJIT
871int Compiler::writeELFExecToFile() {
872 std::string objPath(mCachePath);
873 if (!getObjPath(objPath)) {
874 LOGE("Fail to create objPath");
875 return 1;
876 }
877
878 FileHandle file;
879
880 int Fd = file.open(objPath.c_str(), OpenMode::Write);
881 if (Fd < 0) {
882 LOGE("Fail to open file '%s'", objPath.c_str());
883 return 1;
884 }
885
886 file.write(&*mEmittedELFExecutable.begin(), mEmittedELFExecutable.size());
887
888 return 0;
889}
890#endif
891
892
893#if USE_MCJIT
894void *Compiler::getSymbolAddress(char const *name) {
895 return rsloaderGetSymbolAddress(mRSExecutable, name);
896}
897#endif
898
899
900#if USE_MCJIT
901void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
902 Compiler *self = reinterpret_cast<Compiler *>(context);
903
904 if (void *Addr = FindRuntimeFunction(name)) {
905 return Addr;
906 }
907
908 if (self->mpSymbolLookupFn) {
909 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
910 return Addr;
911 }
912 }
913
914 LOGE("Unable to resolve symbol: %s\n", name);
915 return NULL;
916}
917#endif
918
919
Logan1f028c02010-11-27 01:02:48 +0800920Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800921 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800922 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800923
Logan Chienda5e0c32011-06-13 03:47:21 +0800924#if USE_MCJIT
925 rsloaderDisposeExec(mRSExecutable);
926#endif
927
Logana4994f52010-11-27 14:06:02 +0800928 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800929}
930
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700931#if USE_MCJIT && USE_DISASSEMBLER
932void Compiler::Disassemble(llvm::Target const *Target,
933 llvm::TargetMachine *TM,
934 std::string const &Name,
935 unsigned char const *Func,
936 size_t FuncSize) {
937 llvm::raw_ostream *OS;
938
939#if USE_DISASSEMBLER_FILE
940 std::string ErrorInfo;
941 OS = new llvm::raw_fd_ostream("/data/local/tmp/mcjit-dis.s", ErrorInfo,
942 llvm::raw_fd_ostream::F_Append);
943
944 if (!ErrorInfo.empty()) { // some errors occurred
945 // LOGE("Error in creating disassembly file");
946 delete OS;
947 return;
948 }
949#else
950 OS = &llvm::outs();
951#endif
952
953 *OS << "MC/ Disassembled code: " << Name << "\n";
954
955 const llvm::MCAsmInfo *AsmInfo;
956 const llvm::MCDisassembler *Disassmbler;
957 llvm::MCInstPrinter *IP;
958
959 AsmInfo = Target->createAsmInfo(Compiler::Triple);
960 Disassmbler = Target->createMCDisassembler();
961 IP = Target->createMCInstPrinter(*TM,
962 AsmInfo->getAssemblerDialect(),
963 *AsmInfo);
964
965 const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Func, FuncSize);
966
967 uint64_t Size;
968 uint64_t Index;
969
970 for (Index = 0; Index < FuncSize; Index += Size) {
971 llvm::MCInst Inst;
972
973 if (Disassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
974 /* REMOVED */ llvm::nulls())) {
975 OS->indent(4);
976 OS->write("0x", 2);
977 OS->write_hex((uint32_t)Func + Index);
978 OS->write(": 0x", 4);
979 OS->write_hex(*(uint32_t *)(Func + Index));
980 IP->printInst(&Inst, *OS);
981 *OS << "\n";
982 } else {
983 if (Size == 0)
984 Size = 1; // skip illegible bytes
985 }
986 }
987
988 *OS << "\n";
989 delete BufferMObj;
990
991 delete AsmInfo;
992 delete Disassmbler;
993 delete IP;
994
995#if USE_DISASSEMBLER_FILE
996 // If you want the disassemble results write to file, uncomment this.
997 ((llvm::raw_fd_ostream*)OS)->close();
998 delete OS;
999#endif
1000}
1001#endif
1002
1003
Logan1f028c02010-11-27 01:02:48 +08001004} // namespace bcc