blob: 78dbb47bbfe03dbb8e56ef985c5aa8741ed1b5ab [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
45#include "llvm/Target/SubtargetFeature.h"
46#include "llvm/Target/TargetData.h"
47#include "llvm/Target/TargetMachine.h"
48#include "llvm/Target/TargetOptions.h"
49#include "llvm/Target/TargetRegistry.h"
50#include "llvm/Target/TargetSelect.h"
51
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070052#if USE_DISASSEMBLER
53#include "llvm/MC/MCAsmInfo.h"
54#include "llvm/MC/MCDisassembler.h"
55#include "llvm/MC/MCInst.h"
56#include "llvm/MC/MCInstPrinter.h"
57#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
112#define DEBUG_MCJIT REFLECT 0
Shih-wei Liao320b5492011-06-20 22:53:33 -0700113#define DEBUG_MCJIT_DISASSEMBLE 0
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700114
Logan1f028c02010-11-27 01:02:48 +0800115namespace bcc {
116
117//////////////////////////////////////////////////////////////////////////////
118// BCC Compiler Static Variables
119//////////////////////////////////////////////////////////////////////////////
120
121bool Compiler::GlobalInitialized = false;
122
Logan1f028c02010-11-27 01:02:48 +0800123// Code generation optimization level for the compiler
124llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
125
126std::string Compiler::Triple;
127
128std::string Compiler::CPU;
129
130std::vector<std::string> Compiler::Features;
131
Stephen Hines071288a2011-01-27 14:38:26 -0800132// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800133// slang.cpp)
134const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
135
Stephen Hines071288a2011-01-27 14:38:26 -0800136// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800137// synced with slang_rs_metadata.h)
138const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
139
Stephen Hines071288a2011-01-27 14:38:26 -0800140// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800141// synced with slang_rs_metadata.h)
142const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
143
Stephen Hines071288a2011-01-27 14:38:26 -0800144// Name of metadata node where RS object slot info resides (should be
145// synced with slang_rs_metadata.h)
146const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800147
148//////////////////////////////////////////////////////////////////////////////
149// Compiler
150//////////////////////////////////////////////////////////////////////////////
151
152void Compiler::GlobalInitialization() {
153 if (GlobalInitialized)
154 return;
Stephen Hinesd18a3df2011-06-24 17:38:56 -0700155
156 LOGI("LIBBCC BUILD CHECKSUM: %s\n", libbcc_build_checksum);
157
Logan1f028c02010-11-27 01:02:48 +0800158 // if (!llvm::llvm_is_multithreaded())
159 // llvm::llvm_start_multithreaded();
160
161 // Set Triple, CPU and Features here
162 Triple = TARGET_TRIPLE_STRING;
163
Logan1f028c02010-11-27 01:02:48 +0800164 Features.push_back("+vfp3");
Logan1f028c02010-11-27 01:02:48 +0800165
Logan4fe966f2011-02-27 08:26:40 +0800166 // NOTE: Currently, we have to turn off the support for NEON explicitly.
167 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
168 // instructions.
Joseph Wen51001b82011-06-23 18:56:45 -0700169#if ARCH_ARM_HAVE_NEON
170 Features.push_back("+d32");
171 Features.push_back("+neon");
172 Features.push_back("+neonfp");
173#else
174 Features.push_back("+d16");
175 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800176 Features.push_back("-neonfp");
Joseph Wen51001b82011-06-23 18:56:45 -0700177#endif
178
Logan4fe966f2011-02-27 08:26:40 +0800179 Features.push_back("-vmlx");
180
Logan1f028c02010-11-27 01:02:48 +0800181#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
182 LLVMInitializeARMTargetInfo();
183 LLVMInitializeARMTarget();
Logan35849002011-01-15 07:30:43 +0800184#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800185 LLVMInitializeARMDisassembler();
186 LLVMInitializeARMAsmPrinter();
187#endif
188#endif
189
190#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_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#if defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
200 LLVMInitializeX86TargetInfo();
201 LLVMInitializeX86Target();
Logan35849002011-01-15 07:30:43 +0800202#if USE_DISASSEMBLER
Logan1f028c02010-11-27 01:02:48 +0800203 LLVMInitializeX86Disassembler();
204 LLVMInitializeX86AsmPrinter();
205#endif
206#endif
207
208 // -O0: llvm::CodeGenOpt::None
209 // -O1: llvm::CodeGenOpt::Less
210 // -O2: llvm::CodeGenOpt::Default
211 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800212 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800213
214 // Below are the global settings to LLVM
215
216 // Disable frame pointer elimination optimization
217 llvm::NoFramePointerElim = false;
218
219 // Use hardfloat ABI
220 //
221 // TODO(all): Need to detect the CPU capability and decide whether to use
222 // softfp. To use softfp, change following 2 lines to
223 //
224 // llvm::FloatABIType = llvm::FloatABI::Soft;
225 // llvm::UseSoftFloat = true;
226 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800227 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800228 llvm::UseSoftFloat = false;
229
230 // BCC needs all unknown symbols resolved at JIT/compilation time.
231 // So we don't need any dynamic relocation model.
232 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static);
233
234#if defined(DEFAULT_X64_CODEGEN)
235 // Data address in X86_64 architecture may reside in a far-away place
236 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
237#else
238 // This is set for the linker (specify how large of the virtual addresses
239 // we can access for all unknown symbols.)
240 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
241#endif
242
243 // Register the scheduler
244 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
245
246 // Register allocation policy:
247 // createFastRegisterAllocator: fast but bad quality
248 // createLinearScanRegisterAllocator: not so fast but good quality
249 llvm::RegisterRegAlloc::setDefault
250 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
251 llvm::createFastRegisterAllocator :
252 llvm::createLinearScanRegisterAllocator);
253
Logan35849002011-01-15 07:30:43 +0800254#if USE_CACHE
Logan75cc8a52011-01-07 06:06:52 +0800255 // Calculate the SHA1 checksum of libbcc and libRS.
Stephen Hinesd18a3df2011-06-24 17:38:56 -0700256#if USE_LIBBCC_SHA1SUM
257 calcFileSHA1(sha1LibBCC, pathLibBCC);
258#endif
259 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800260#endif
Logan75cc8a52011-01-07 06:06:52 +0800261
Logan1f028c02010-11-27 01:02:48 +0800262 GlobalInitialized = true;
263}
264
265
266void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
267 std::string *Error = static_cast<std::string*>(UserData);
268 Error->assign(Message);
269 LOGE("%s", Message.c_str());
270 exit(1);
271}
272
273
Logan Chienda5e0c32011-06-13 03:47:21 +0800274#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800275CodeMemoryManager *Compiler::createCodeMemoryManager() {
276 mCodeMemMgr.reset(new CodeMemoryManager());
277 return mCodeMemMgr.get();
278}
Logan Chienda5e0c32011-06-13 03:47:21 +0800279#endif
Logan1f028c02010-11-27 01:02:48 +0800280
281
Logan Chienda5e0c32011-06-13 03:47:21 +0800282#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800283CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800284 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800285 return mCodeEmitter.get();
286}
Logan Chienda5e0c32011-06-13 03:47:21 +0800287#endif
Logan1f028c02010-11-27 01:02:48 +0800288
289
Logan2a6dc822011-01-06 04:05:20 +0800290Compiler::Compiler(ScriptCompiled *result)
291 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800292#if USE_MCJIT
293 mRSExecutable(NULL),
294#endif
Logan1f028c02010-11-27 01:02:48 +0800295 mpSymbolLookupFn(NULL),
296 mpSymbolLookupContext(NULL),
297 mContext(NULL),
298 mModule(NULL),
299 mHasLinked(false) /* Turn off linker */ {
300 llvm::remove_fatal_error_handler();
301 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
302 mContext = new llvm::LLVMContext();
303 return;
304}
305
Logan1f028c02010-11-27 01:02:48 +0800306
Logan Chienda5e0c32011-06-13 03:47:21 +0800307#if USE_MCJIT
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700308// input objPath: For example,
309// /data/user/0/com.example.android.rs.fountain/cache/
310// @com.example.android.rs.fountain:raw@fountain.oBCC
311// output objPath: /data/user/0/com.example.android.rs.fountain/cache/
312// fountain.o
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700313//
314bool Compiler::getObjPath(std::string &objPath) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700315 size_t found0 = objPath.find("@");
316 size_t found1 = objPath.rfind("@");
317
318 if (found0 == found1 ||
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800319 found0 == std::string::npos ||
320 found1 == std::string::npos) {
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700321 LOGE("Ill formatted resource name '%s'. The name should contain 2 @s",
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700322 objPath.c_str());
323 return false;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700324 }
325
Shih-wei Liao5c00f4f2011-05-20 04:14:54 -0700326 objPath.replace(found0, found1 - found0 + 1, "", 0);
327 objPath.resize(objPath.length() - 3);
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700328
Shih-wei Liaode0ba062011-05-19 03:16:33 -0700329 LOGV("objPath = %s", objPath.c_str());
330 return true;
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700331}
Logan Chienda5e0c32011-06-13 03:47:21 +0800332#endif
Shih-wei Liao898c5a92011-05-18 07:02:39 -0700333
334
Logan474cbd22011-01-31 01:47:44 +0800335llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
336 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800337
Logan474cbd22011-01-31 01:47:44 +0800338 if (!result) {
339 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
340 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800341 }
342
Logan474cbd22011-01-31 01:47:44 +0800343 return result;
Logan1f028c02010-11-27 01:02:48 +0800344}
345
346
Logan474cbd22011-01-31 01:47:44 +0800347int Compiler::linkModule(llvm::Module *moduleWith) {
348 if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800349 return hasError();
350 }
351
Logan1f028c02010-11-27 01:02:48 +0800352 // Everything for linking should be settled down here with no error occurs
353 mHasLinked = true;
354 return hasError();
355}
356
357
Logan1f028c02010-11-27 01:02:48 +0800358int Compiler::compile() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800359 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800360 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800361 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800362
Logan1f028c02010-11-27 01:02:48 +0800363 std::string FeaturesStr;
364
Logan Chienda5e0c32011-06-13 03:47:21 +0800365 llvm::NamedMDNode const *PragmaMetadata;
366 llvm::NamedMDNode const *ExportVarMetadata;
367 llvm::NamedMDNode const *ExportFuncMetadata;
368 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800369
Logan1f028c02010-11-27 01:02:48 +0800370 if (mModule == NULL) // No module was loaded
371 return 0;
372
373 // Create TargetMachine
374 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
375 if (hasError())
376 goto on_bcc_compile_error;
377
378 if (!CPU.empty() || !Features.empty()) {
379 llvm::SubtargetFeatures F;
380 F.setCPU(CPU);
Logana4994f52010-11-27 14:06:02 +0800381
382 for (std::vector<std::string>::const_iterator
383 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800384 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800385 }
386
Logan1f028c02010-11-27 01:02:48 +0800387 FeaturesStr = F.getString();
388 }
389
390 TM = Target->createTargetMachine(Triple, FeaturesStr);
391 if (TM == NULL) {
392 setError("Failed to create target machine implementation for the"
393 " specified triple '" + Triple + "'");
394 goto on_bcc_compile_error;
395 }
396
Logan Chienda5e0c32011-06-13 03:47:21 +0800397 // Get target data from Module
398 TD = new llvm::TargetData(mModule);
399
400 // Load named metadata
401 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
402 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
403 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
404 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
405
406 // Perform link-time optimization if we have multiple modules
407 if (mHasLinked) {
408 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
409 }
410
411 // Perform code generation
412#if USE_OLD_JIT
413 if (runCodeGen(new llvm::TargetData(*TD), TM,
414 ExportVarMetadata, ExportFuncMetadata) != 0) {
415 goto on_bcc_compile_error;
416 }
417#endif
418
419#if USE_MCJIT
420 if (runMCCodeGen(new llvm::TargetData(*TD), TM,
421 ExportVarMetadata, ExportFuncMetadata) != 0) {
422 goto on_bcc_compile_error;
423 }
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700424#if USE_DISASSEMBLER && DEBUG_MCJIT_DISASSEMBLE
425 {
Shih-wei Liao320b5492011-06-20 22:53:33 -0700426 // llvm::LLVMContext Ctx;
427 // LOGD("@ long long alignment: %d\n", TD->getABITypeAlignment((llvm::Type const *)llvm::Type::getInt64Ty(Ctx)));
428 char const *func_list[] = { "root" };
429
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700430 size_t func_list_size = sizeof(func_list) / sizeof(char const *);
431
432 for (size_t i = 0; i < func_list_size; ++i) {
433 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
434 if (func) {
435 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
436 Disassemble(Target, TM, func_list[i], (unsigned char const *)func, size);
437 }
438 }
439 }
440#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800441#endif
442
443 // Read pragma information from the metadata node of the module.
444 if (PragmaMetadata) {
445 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
446
447 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
448 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
449 if (Pragma != NULL &&
450 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
451 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
452 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
453
454 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
455 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
456 llvm::StringRef PragmaName =
457 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
458 llvm::StringRef PragmaValue =
459 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
460
461 pragmaList.push_back(
462 std::make_pair(std::string(PragmaName.data(),
463 PragmaName.size()),
464 std::string(PragmaValue.data(),
465 PragmaValue.size())));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700466#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700467 LOGD("compile(): Pragma: %s -> %s\n", pragmaList.back().first.c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800468 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700469#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800470 }
471 }
472 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800473 }
474
475 if (ObjectSlotMetadata) {
476 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
477
478 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
479 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
480 if (ObjectSlot != NULL &&
481 ObjectSlot->getNumOperands() == 1) {
482 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
483 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
484 llvm::StringRef Slot =
485 static_cast<llvm::MDString*>(SlotMDS)->getString();
486 uint32_t USlot = 0;
487 if (Slot.getAsInteger(10, USlot)) {
488 setError("Non-integer object slot value '" + Slot.str() + "'");
489 goto on_bcc_compile_error;
490 }
491 objectSlotList.push_back(USlot);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700492#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700493 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
494#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800495 }
496 }
497 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800498 }
499
500on_bcc_compile_error:
501 // LOGE("on_bcc_compiler_error");
502 if (TD) {
503 delete TD;
504 }
505
506 if (TM) {
507 delete TM;
508 }
509
510 if (mError.empty()) {
511 return 0;
512 }
513
514 // LOGE(getErrorMessage());
515 return 1;
516}
517
518
519#if USE_OLD_JIT
520int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
521 llvm::NamedMDNode const *ExportVarMetadata,
522 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800523 // Create memory manager for creation of code emitter later.
524 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
525 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800526 return 1;
Logan1f028c02010-11-27 01:02:48 +0800527 }
Logan02286cb2011-01-07 00:30:47 +0800528
529 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800530
531 // Create code emitter
532 if (!mCodeEmitter.get()) {
533 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800534 setError("Failed to create machine code emitter for compilation");
535 return 1;
Logan1f028c02010-11-27 01:02:48 +0800536 }
537 } else {
538 // Reuse the code emitter
539 mCodeEmitter->reset();
540 }
541
542 mCodeEmitter->setTargetMachine(*TM);
543 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
544 mpSymbolLookupContext);
545
Logan1f028c02010-11-27 01:02:48 +0800546 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800547 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
548 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800549
Logan Chienda5e0c32011-06-13 03:47:21 +0800550 // Add TargetData to code generation pass manager
551 CodeGenPasses->add(TD);
552
553 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800554 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
555 *mCodeEmitter,
556 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800557 setError("The machine code emission is not supported on '" + Triple + "'");
558 return 1;
Logan1f028c02010-11-27 01:02:48 +0800559 }
560
Logan Chienda5e0c32011-06-13 03:47:21 +0800561 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800562 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800563 for (llvm::Module::iterator
564 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800565 if (!I->isDeclaration()) {
566 CodeGenPasses->run(*I);
567 }
568 }
569
570 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800571
Logan1f028c02010-11-27 01:02:48 +0800572 // Copy the global address mapping from code emitter and remapping
573 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800574 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
575
Logan1f028c02010-11-27 01:02:48 +0800576 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
577 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
578 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
579 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
580 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
581 llvm::StringRef ExportVarName =
582 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
583
584 CodeEmitter::global_addresses_const_iterator I, E;
585 for (I = mCodeEmitter->global_address_begin(),
586 E = mCodeEmitter->global_address_end();
587 I != E; I++) {
588 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
589 continue;
590 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800591 varList.push_back(I->second);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700592#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700593 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
594#endif
Logan1f028c02010-11-27 01:02:48 +0800595 break;
596 }
597 }
598 if (I != mCodeEmitter->global_address_end())
599 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800600
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700601#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700602 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800603 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700604#endif
Logan1f028c02010-11-27 01:02:48 +0800605 }
606 }
607 // if reaching here, we know the global variable record in metadata is
608 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800609 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800610 }
Logan2a6dc822011-01-06 04:05:20 +0800611
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700612 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
613 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800614 }
615
616 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800617 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
618
Logan1f028c02010-11-27 01:02:48 +0800619 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
620 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
621 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
622 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
623 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
624 llvm::StringRef ExportFuncName =
625 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800626 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700627#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700628 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800629 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700630#endif
Logan1f028c02010-11-27 01:02:48 +0800631 }
632 }
633 }
634 }
635
636 // Tell code emitter now can release the memory using during the JIT since
637 // we have done the code emission
638 mCodeEmitter->releaseUnnecessary();
639
Logan Chienda5e0c32011-06-13 03:47:21 +0800640 return 0;
Logan1f028c02010-11-27 01:02:48 +0800641}
Logan Chienda5e0c32011-06-13 03:47:21 +0800642#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800643
644
Logan Chienda5e0c32011-06-13 03:47:21 +0800645#if USE_MCJIT
646int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
647 llvm::NamedMDNode const *ExportVarMetadata,
648 llvm::NamedMDNode const *ExportFuncMetadata) {
649 // Decorate mEmittedELFExecutable with formatted ostream
650 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
651
652 // Relax all machine instructions
653 TM->setMCRelaxAll(/* RelaxAll= */ true);
654
655 // Create MC code generation pass manager
656 llvm::PassManager MCCodeGenPasses;
657
658 // Add TargetData to MC code generation pass manager
659 MCCodeGenPasses.add(TD);
660
661 // Add MC code generation passes to pass manager
662 llvm::MCContext *Ctx;
663 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
664 CodeGenOptLevel, false)) {
665 setError("Fail to add passes to emit file");
666 return 1;
667 }
668
669 MCCodeGenPasses.run(*mModule);
670 OutSVOS.flush();
671
672 // Load the ELF Object
673 mRSExecutable =
674 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
675 mEmittedELFExecutable.size(),
676 &resolveSymbolAdapter, this);
677
678 if (!mRSExecutable) {
679 setError("Fail to load emitted ELF relocatable file");
680 return 1;
681 }
682
683#if !USE_OLD_JIT
684 // Note: If old JIT is compiled then we prefer the old version instead of the
685 // new version.
686
687 if (ExportVarMetadata) {
688 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
689
690 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
691 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
Logan Chien70dd9982011-06-13 23:21:39 +0800692 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
693 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
694 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
695 llvm::StringRef ExportVarName =
696 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
697
698 varList.push_back(
699 rsloaderGetSymbolAddress(mRSExecutable,
700 ExportVarName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700701#if DEBUG_MCJIT_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700702 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Logan Chien70dd9982011-06-13 23:21:39 +0800703 varList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700704#endif
Logan Chien70dd9982011-06-13 23:21:39 +0800705 continue;
706 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800707 }
708
Logan Chien70dd9982011-06-13 23:21:39 +0800709 varList.push_back(NULL);
Logan Chienda5e0c32011-06-13 03:47:21 +0800710 }
711 }
712
713 if (ExportFuncMetadata) {
714 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
715
716 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
717 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
718 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
719 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
720 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
721 llvm::StringRef ExportFuncName =
722 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
723
724 funcList.push_back(
725 rsloaderGetSymbolAddress(mRSExecutable,
726 ExportFuncName.str().c_str()));
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700727#if DEBUG_MCJIT_RELECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700728 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800729 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700730#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800731 }
732 }
733 }
734 }
735#endif // !USE_OLD_JIT
736
737#if USE_CACHE
738 // Write generated executable to file.
739 if (writeELFExecToFile() != 0) {
740 setError("Fail to write mcjit-ed executable to file");
741 return 1;
742 }
743#endif
744
745 return 0;
746}
747#endif // USE_MCJIT
748
749
750int Compiler::runLTO(llvm::TargetData *TD,
751 llvm::NamedMDNode const *ExportVarMetadata,
752 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800753 llvm::PassManager LTOPasses;
754
755 // Add TargetData to LTO passes
756 LTOPasses.add(TD);
757
758 // Collect All Exported Symbols
759 std::vector<const char*> ExportSymbols;
760
761 // Note: This is a workaround for getting export variable and function name.
762 // We should refine it soon.
763 if (ExportVarMetadata) {
764 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
765 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
766 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
767 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
768 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
769 llvm::StringRef ExportVarName =
770 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
771 ExportSymbols.push_back(ExportVarName.data());
772 }
773 }
774 }
775 }
776
777 if (ExportFuncMetadata) {
778 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
779 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
780 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
781 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
782 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
783 llvm::StringRef ExportFuncName =
784 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
785 ExportSymbols.push_back(ExportFuncName.data());
786 }
787 }
788 }
789 }
790
791 // root() and init() are born to be exported
792 ExportSymbols.push_back("root");
793 ExportSymbols.push_back("init");
794
795 // We now create passes list performing LTO. These are copied from
796 // (including comments) llvm::createStandardLTOPasses().
797
798 // Internalize all other symbols not listed in ExportSymbols
799 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
800
801 // Propagate constants at call sites into the functions they call. This
802 // opens opportunities for globalopt (and inlining) by substituting
803 // function pointers passed as arguments to direct uses of functions.
804 LTOPasses.add(llvm::createIPSCCPPass());
805
806 // Now that we internalized some globals, see if we can hack on them!
807 LTOPasses.add(llvm::createGlobalOptimizerPass());
808
809 // Linking modules together can lead to duplicated global constants, only
810 // keep one copy of each constant...
811 LTOPasses.add(llvm::createConstantMergePass());
812
813 // Remove unused arguments from functions...
814 LTOPasses.add(llvm::createDeadArgEliminationPass());
815
816 // Reduce the code after globalopt and ipsccp. Both can open up
817 // significant simplification opportunities, and both can propagate
818 // functions through function pointers. When this happens, we often have
819 // to resolve varargs calls, etc, so let instcombine do this.
820 LTOPasses.add(llvm::createInstructionCombiningPass());
821
822 // Inline small functions
823 LTOPasses.add(llvm::createFunctionInliningPass());
824
825 // Remove dead EH info.
826 LTOPasses.add(llvm::createPruneEHPass());
827
828 // Internalize the globals again after inlining
829 LTOPasses.add(llvm::createGlobalOptimizerPass());
830
831 // Remove dead functions.
832 LTOPasses.add(llvm::createGlobalDCEPass());
833
834 // If we didn't decide to inline a function, check to see if we can
835 // transform it to pass arguments by value instead of by reference.
836 LTOPasses.add(llvm::createArgumentPromotionPass());
837
838 // The IPO passes may leave cruft around. Clean up after them.
839 LTOPasses.add(llvm::createInstructionCombiningPass());
840 LTOPasses.add(llvm::createJumpThreadingPass());
841
842 // Break up allocas
843 LTOPasses.add(llvm::createScalarReplAggregatesPass());
844
845 // Run a few AA driven optimizations here and now, to cleanup the code.
846 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
847 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
848
849 // Hoist loop invariants.
850 LTOPasses.add(llvm::createLICMPass());
851
852 // Remove redundancies.
853 LTOPasses.add(llvm::createGVNPass());
854
855 // Remove dead memcpys.
856 LTOPasses.add(llvm::createMemCpyOptPass());
857
858 // Nuke dead stores.
859 LTOPasses.add(llvm::createDeadStoreEliminationPass());
860
861 // Cleanup and simplify the code after the scalar optimizations.
862 LTOPasses.add(llvm::createInstructionCombiningPass());
863
864 LTOPasses.add(llvm::createJumpThreadingPass());
865
866 // Delete basic blocks, which optimization passes may have killed.
867 LTOPasses.add(llvm::createCFGSimplificationPass());
868
869 // Now that we have optimized the program, discard unreachable functions.
870 LTOPasses.add(llvm::createGlobalDCEPass());
871
872 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800873
874 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800875}
876
877
Logan Chienda5e0c32011-06-13 03:47:21 +0800878#if USE_MCJIT
879int Compiler::writeELFExecToFile() {
880 std::string objPath(mCachePath);
881 if (!getObjPath(objPath)) {
882 LOGE("Fail to create objPath");
883 return 1;
884 }
885
886 FileHandle file;
887
888 int Fd = file.open(objPath.c_str(), OpenMode::Write);
889 if (Fd < 0) {
890 LOGE("Fail to open file '%s'", objPath.c_str());
891 return 1;
892 }
893
894 file.write(&*mEmittedELFExecutable.begin(), mEmittedELFExecutable.size());
895
896 return 0;
897}
898#endif
899
900
901#if USE_MCJIT
902void *Compiler::getSymbolAddress(char const *name) {
903 return rsloaderGetSymbolAddress(mRSExecutable, name);
904}
905#endif
906
907
908#if USE_MCJIT
909void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
910 Compiler *self = reinterpret_cast<Compiler *>(context);
911
912 if (void *Addr = FindRuntimeFunction(name)) {
913 return Addr;
914 }
915
916 if (self->mpSymbolLookupFn) {
917 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
918 return Addr;
919 }
920 }
921
922 LOGE("Unable to resolve symbol: %s\n", name);
923 return NULL;
924}
925#endif
926
927
Logan1f028c02010-11-27 01:02:48 +0800928Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800929 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800930 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800931
Logan Chienda5e0c32011-06-13 03:47:21 +0800932#if USE_MCJIT
933 rsloaderDisposeExec(mRSExecutable);
934#endif
935
Logana4994f52010-11-27 14:06:02 +0800936 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800937}
938
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700939#if USE_MCJIT && USE_DISASSEMBLER
940void Compiler::Disassemble(llvm::Target const *Target,
941 llvm::TargetMachine *TM,
942 std::string const &Name,
943 unsigned char const *Func,
944 size_t FuncSize) {
945 llvm::raw_ostream *OS;
946
947#if USE_DISASSEMBLER_FILE
948 std::string ErrorInfo;
949 OS = new llvm::raw_fd_ostream("/data/local/tmp/mcjit-dis.s", ErrorInfo,
950 llvm::raw_fd_ostream::F_Append);
951
952 if (!ErrorInfo.empty()) { // some errors occurred
953 // LOGE("Error in creating disassembly file");
954 delete OS;
955 return;
956 }
957#else
958 OS = &llvm::outs();
959#endif
960
961 *OS << "MC/ Disassembled code: " << Name << "\n";
962
963 const llvm::MCAsmInfo *AsmInfo;
964 const llvm::MCDisassembler *Disassmbler;
965 llvm::MCInstPrinter *IP;
966
967 AsmInfo = Target->createAsmInfo(Compiler::Triple);
968 Disassmbler = Target->createMCDisassembler();
969 IP = Target->createMCInstPrinter(*TM,
970 AsmInfo->getAssemblerDialect(),
971 *AsmInfo);
972
973 const BufferMemoryObject *BufferMObj = new BufferMemoryObject(Func, FuncSize);
974
975 uint64_t Size;
976 uint64_t Index;
977
978 for (Index = 0; Index < FuncSize; Index += Size) {
979 llvm::MCInst Inst;
980
981 if (Disassmbler->getInstruction(Inst, Size, *BufferMObj, Index,
982 /* REMOVED */ llvm::nulls())) {
983 OS->indent(4);
984 OS->write("0x", 2);
985 OS->write_hex((uint32_t)Func + Index);
986 OS->write(": 0x", 4);
987 OS->write_hex(*(uint32_t *)(Func + Index));
988 IP->printInst(&Inst, *OS);
989 *OS << "\n";
990 } else {
991 if (Size == 0)
992 Size = 1; // skip illegible bytes
993 }
994 }
995
996 *OS << "\n";
997 delete BufferMObj;
998
999 delete AsmInfo;
1000 delete Disassmbler;
1001 delete IP;
1002
1003#if USE_DISASSEMBLER_FILE
1004 // If you want the disassemble results write to file, uncomment this.
1005 ((llvm::raw_fd_ostream*)OS)->close();
1006 delete OS;
1007#endif
1008}
1009#endif
1010
1011
Logan1f028c02010-11-27 01:02:48 +08001012} // namespace bcc