From: José Fonseca Date: Sun, 13 Mar 2011 19:24:26 +0000 (+0000) Subject: gallivm: Use LLVM MC disassembler, instead of udis86. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e6314db0ac537695a20feb5fab8d77a30836eccf;p=mesa.git gallivm: Use LLVM MC disassembler, instead of udis86. Included in LLVM 2.7+. Unlink udis86, should support all instructions that LLVM can emit. --- diff --git a/configs/linux-llvm b/configs/linux-llvm index e6999539a17..dde40a38a07 100644 --- a/configs/linux-llvm +++ b/configs/linux-llvm @@ -12,7 +12,7 @@ GALLIUM_DRIVERS_DIRS += llvmpipe OPT_FLAGS = -O3 -ansi -pedantic ARCH_FLAGS = -mmmx -msse -msse2 -mstackrealign -DEFINES += -DNDEBUG -DGALLIUM_LLVMPIPE -DHAVE_UDIS86 +DEFINES += -DNDEBUG -DGALLIUM_LLVMPIPE # override -std=c99 CFLAGS += -std=gnu99 @@ -41,4 +41,4 @@ else endif LD = g++ -GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++ -ludis86 +GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++ diff --git a/configure.ac b/configure.ac index d33ca301f96..0de013f3241 100644 --- a/configure.ac +++ b/configure.ac @@ -1400,8 +1400,6 @@ if test "x$enable_gallium" = xno -a "x$enable_openvg" = xyes; then fi if test "x$enable_gallium" = xyes; then SRC_DIRS="$SRC_DIRS gallium gallium/winsys gallium/targets" - AC_CHECK_HEADER([udis86.h], [HAS_UDIS86="yes"], - [HAS_UDIS86="no"]) AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no]) fi @@ -1653,10 +1651,6 @@ if test "x$enable_gallium_llvm" = xyes; then LLVM_CFLAGS=`$LLVM_CONFIG --cppflags` LLVM_LIBS="`$LLVM_CONFIG --libs jit interpreter nativecodegen bitwriter` -lstdc++" - if test "x$HAS_UDIS86" != xno; then - LLVM_LIBS="$LLVM_LIBS -ludis86" - DEFINES="$DEFINES -DHAVE_UDIS86" - fi LLVM_LDFLAGS=`$LLVM_CONFIG --ldflags` GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS llvmpipe" DEFINES="$DEFINES -DGALLIUM_LLVMPIPE -D__STDC_CONSTANT_MACROS" diff --git a/scons/gallium.py b/scons/gallium.py index 34523d5898b..4dcb8d0a423 100755 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -602,7 +602,6 @@ def generate(env): env.Tool('yacc') if env['llvm']: env.Tool('llvm') - env.Tool('udis86') pkg_config_modules(env, 'x11', ['x11', 'xext']) pkg_config_modules(env, 'drm', ['libdrm']) diff --git a/scons/llvm.py b/scons/llvm.py index 3fef9e0900d..b89899bbf87 100644 --- a/scons/llvm.py +++ b/scons/llvm.py @@ -142,7 +142,7 @@ def generate(env): try: env.ParseConfig('llvm-config --cppflags') - env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter') + env.ParseConfig('llvm-config --libs') env.ParseConfig('llvm-config --ldflags') except OSError: print 'scons: llvm-config version %s failed' % llvm_version diff --git a/scons/udis86.py b/scons/udis86.py deleted file mode 100644 index bb91d3c35cf..00000000000 --- a/scons/udis86.py +++ /dev/null @@ -1,44 +0,0 @@ -"""udis86 - -Tool-specific initialization for udis86 - -""" - -# -# Copyright (c) 2009 VMware, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -def generate(env): - conf = env.Configure() - - if conf.CheckHeader('udis86.h'): # and conf.CheckLib('udis86'): - env['UDIS86'] = True - env.Prepend(LIBS = ['udis86']) - else: - env['UDIS86'] = False - - conf.Finish() - -def exists(env): - return True - -# vim:set ts=4 sw=4 et: diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 7b748fa29e7..c7654046a58 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -161,7 +161,6 @@ GALLIVM_SOURCES = \ gallivm/lp_bld_bitarit.c \ gallivm/lp_bld_const.c \ gallivm/lp_bld_conv.c \ - gallivm/lp_bld_debug.c \ gallivm/lp_bld_flow.c \ gallivm/lp_bld_format_aos.c \ gallivm/lp_bld_format_soa.c \ @@ -189,6 +188,7 @@ GALLIVM_SOURCES = \ draw/draw_pt_fetch_shade_pipeline_llvm.c GALLIVM_CPP_SOURCES = \ + gallivm/lp_bld_debug.cpp \ gallivm/lp_bld_misc.cpp GENERATED_SOURCES = \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 2855d5827ce..8e422b2c11f 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -203,16 +203,13 @@ source = [ ] if env['llvm']: - if env['UDIS86']: - env.Append(CPPDEFINES = [('HAVE_UDIS86', '1')]) - source += [ 'gallivm/lp_bld_arit.c', 'gallivm/lp_bld_assert.c', 'gallivm/lp_bld_bitarit.c', 'gallivm/lp_bld_const.c', 'gallivm/lp_bld_conv.c', - 'gallivm/lp_bld_debug.c', + 'gallivm/lp_bld_debug.cpp', 'gallivm/lp_bld_flow.c', 'gallivm/lp_bld_format_aos.c', 'gallivm/lp_bld_format_soa.c', diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.c b/src/gallium/auxiliary/gallivm/lp_bld_debug.c deleted file mode 100644 index 93e56553d7b..00000000000 --- a/src/gallium/auxiliary/gallivm/lp_bld_debug.c +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifdef HAVE_UDIS86 -#include -#endif - -#include "util/u_math.h" -#include "util/u_debug.h" -#include "lp_bld_debug.h" - - -/** - * Check alignment. - * - * It is important that this check is not implemented as a macro or inlined - * function, as the compiler assumptions in respect to alignment of global - * and stack variables would often make the check a no op, defeating the - * whole purpose of the exercise. - */ -boolean -lp_check_alignment(const void *ptr, unsigned alignment) -{ - assert(util_is_power_of_two(alignment)); - return ((uintptr_t)ptr & (alignment - 1)) == 0; -} - - -void -lp_disassemble(const void* func) -{ -#ifdef HAVE_UDIS86 - ud_t ud_obj; - uint64_t max_jmp_pc; - uint inst_no; - boolean emit_addrs = TRUE, emit_line_nos = FALSE; - - ud_init(&ud_obj); - - ud_set_input_buffer(&ud_obj, (void*)func, 0xffff); - - max_jmp_pc = (uint64_t) (uintptr_t) func; - ud_set_pc(&ud_obj, max_jmp_pc); - -#ifdef PIPE_ARCH_X86 - ud_set_mode(&ud_obj, 32); -#endif -#ifdef PIPE_ARCH_X86_64 - ud_set_mode(&ud_obj, 64); -#endif - - ud_set_syntax(&ud_obj, UD_SYN_ATT); - - while (ud_disassemble(&ud_obj)) { - - if (emit_addrs) { -#ifdef PIPE_ARCH_X86 - debug_printf("0x%08lx:\t", (unsigned long)ud_insn_off(&ud_obj)); -#endif -#ifdef PIPE_ARCH_X86_64 - debug_printf("0x%016llx:\t", (unsigned long long)ud_insn_off(&ud_obj)); -#endif - } - else if (emit_line_nos) { - debug_printf("%6d:\t", inst_no); - inst_no++; - } -#if 0 - debug_printf("%-16s ", ud_insn_hex(&ud_obj)); -#endif - - debug_printf("%s\n", ud_insn_asm(&ud_obj)); - - if(ud_obj.mnemonic != UD_Icall) { - unsigned i; - for(i = 0; i < 3; ++i) { - const struct ud_operand *op = &ud_obj.operand[i]; - if (op->type == UD_OP_JIMM){ - uint64_t pc = ud_obj.pc; - - switch (op->size) { - case 8: - pc += op->lval.sbyte; - break; - case 16: - pc += op->lval.sword; - break; - case 32: - pc += op->lval.sdword; - break; - default: - break; - } - if(pc > max_jmp_pc) - max_jmp_pc = pc; - } - } - } - - if (ud_obj.mnemonic == UD_Iinvalid || - (ud_insn_off(&ud_obj) >= max_jmp_pc && - (ud_obj.mnemonic == UD_Iret || - ud_obj.mnemonic == UD_Ijmp))) - break; - } - -#if 0 - /* Print GDB command, useful to verify udis86 output */ - debug_printf("disassemble %p %p\n", func, (void*)(uintptr_t)ud_obj.pc); -#endif - - debug_printf("\n"); -#else - (void)func; -#endif -} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp new file mode 100644 index 00000000000..49388aadcc8 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp @@ -0,0 +1,355 @@ +/************************************************************************** + * + * Copyright 2009-2011 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_LLVM >= 0x0207 +#include +#include +#include +#include +#endif /* HAVE_LLVM >= 0x0207 */ + +#include "util/u_math.h" +#include "util/u_debug.h" + +#include "lp_bld_debug.h" + + + +/** + * Check alignment. + * + * It is important that this check is not implemented as a macro or inlined + * function, as the compiler assumptions in respect to alignment of global + * and stack variables would often make the check a no op, defeating the + * whole purpose of the exercise. + */ +extern "C" boolean +lp_check_alignment(const void *ptr, unsigned alignment) +{ + assert(util_is_power_of_two(alignment)); + return ((uintptr_t)ptr & (alignment - 1)) == 0; +} + + +class raw_debug_ostream : + public llvm::raw_ostream +{ + uint64_t pos; + + void write_impl(const char *Ptr, size_t Size); + uint64_t current_pos() { return pos; } + uint64_t current_pos() const { return pos; } + +#if HAVE_LLVM >= 0x207 + uint64_t preferred_buffer_size() { return 512; } +#else + size_t preferred_buffer_size() { return 512; } +#endif +}; + + +void +raw_debug_ostream::write_impl(const char *Ptr, size_t Size) +{ + if (Size > 0) { + char *lastPtr = (char *)&Ptr[Size]; + char last = *lastPtr; + *lastPtr = 0; + _debug_printf("%*s", Size, Ptr); + *lastPtr = last; + pos += Size; + } +} + + +/** + * Same as LLVMDumpValue, but through our debugging channels. + */ +extern "C" void +lp_debug_dump_value(LLVMValueRef value) +{ +#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED) + raw_debug_ostream os; + llvm::unwrap(value)->print(os); + os.flush(); +#else + LLVMDumpValue(value); +#endif +} + + +/* + * MemoryObject wrapper around a buffer of memory, to be used by MC + * disassembler. + */ +class BufferMemoryObject: + public llvm::MemoryObject +{ +private: + const uint8_t *Bytes; + uint64_t Length; +public: + BufferMemoryObject(const uint8_t *bytes, uint64_t length) : + Bytes(bytes), Length(length) + { + } + + uint64_t getBase() const + { + return 0; + } + + uint64_t getExtent() const + { + return Length; + } + + int readByte(uint64_t addr, uint8_t *byte) const + { + if (addr > getExtent()) + return -1; + *byte = Bytes[addr]; + return 0; + } +}; + + +/* + * Disassemble a function, using the LLVM MC disassembler. + * + * See also: + * - http://blog.llvm.org/2010/01/x86-disassembler.html + * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html + */ +extern "C" void +lp_disassemble(const void* func) +{ +#if HAVE_LLVM >= 0x0207 + using namespace llvm; + + const uint8_t *bytes = (const uint8_t *)func; + + /* + * Limit disassembly to this extent + */ + const uint64_t extent = 0x10000; + + uint64_t max_pc = 0; + + /* + * Initialize all used objects. + */ + + std::string Triple = sys::getHostTriple(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget(Triple, Error); + +#if HAVE_LLVM >= 0x0208 + InitializeNativeTargetAsmPrinter(); +#else + InitializeAllAsmPrinters(); +#endif + + InitializeAllDisassemblers(); + + OwningPtr AsmInfo(T->createAsmInfo(Triple)); + + if (!AsmInfo) { + debug_printf("error: no assembly info for target %s\n", Triple.c_str()); + return; + } + + OwningPtr DisAsm(T->createMCDisassembler()); + if (!DisAsm) { + debug_printf("error: no disassembler for target %s\n", Triple.c_str()); + return; + } + + raw_debug_ostream Out; + + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); +#if HAVE_LLVM >= 0x0208 + OwningPtr Printer( + T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo)); +#else + OwningPtr Printer( + T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out)); +#endif + if (!Printer) { + debug_printf("error: no instruction printer for target %s\n", Triple.c_str()); + return; + } + + TargetMachine *TM = T->createTargetMachine(Triple, ""); + + const TargetInstrInfo *TII = TM->getInstrInfo(); + + /* + * Wrap the data in a MemoryObject + */ + BufferMemoryObject memoryObject((const uint8_t *)bytes, extent); + + uint64_t pc; + pc = 0; + while (true) { + MCInst Inst; + uint64_t Size; + + /* + * Print address. We use addresses relative to the start of the function, + * so that between runs. + */ + + debug_printf("%6lu:\t", (unsigned long)pc); + + if (!DisAsm->getInstruction(Inst, Size, memoryObject, + pc, + nulls())) { + debug_printf("invalid\n"); + pc += 1; + } + + /* + * Output the bytes in hexidecimal format. + */ + + if (0) { + unsigned i; + for (i = 0; i < Size; ++i) { + debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]); + } + for (; i < 16; ++i) { + debug_printf(" "); + } + } + + /* + * Print the instruction. + */ + +#if HAVE_LLVM >= 0x208 + Printer->printInst(&Inst, Out); +#else + Printer->printInst(&Inst); +#endif + Out.flush(); + + /* + * Advance. + */ + + pc += Size; + + const TargetInstrDesc &TID = TII->get(Inst.getOpcode()); + + /* + * Keep track of forward jumps to a nearby address. + */ + + if (TID.isBranch()) { + for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { + const MCOperand &operand = Inst.getOperand(i); + if (operand.isImm()) { + uint64_t jump; + + /* + * FIXME: Handle both relative and absolute addresses correctly. + * EDInstInfo actually has this info, but operandTypes and + * operandFlags enums are not exposed in the public interface. + */ + + if (1) { + /* + * PC relative addr. + */ + + jump = pc + operand.getImm(); + } else { + /* + * Absolute addr. + */ + + jump = (uint64_t)operand.getImm(); + } + + /* + * Output the address relative to the function start, given + * that MC will print the addresses relative the current pc. + */ + debug_printf("\t\t; %lu", (unsigned long)jump); + + /* + * Ignore far jumps given it could be actually a tail return to + * a random address. + */ + + if (jump > max_pc && + jump < extent) { + max_pc = jump; + } + } + } + } + + debug_printf("\n"); + + /* + * Stop disassembling on return statements, if there is no record of a + * jump to a successive address. + */ + + if (TID.isReturn()) { + if (pc > max_pc) { + break; + } + } + } + + /* + * Print GDB command, useful to verify output. + */ + + if (0) { + debug_printf("disassemble %p %p\n", bytes, bytes + pc); + } + + debug_printf("\n"); +#else + (void)func; +#endif +} + diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h index 8a58f95b78f..da873f30b2d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h @@ -45,6 +45,11 @@ #define GALLIVM_DEBUG_GC (1 << 6) +#ifdef __cplusplus +extern "C" { +#endif + + #ifdef DEBUG extern unsigned gallivm_debug; #else @@ -81,4 +86,9 @@ void lp_disassemble(const void* func); +#ifdef __cplusplus +} +#endif + + #endif /* !LP_BLD_DEBUG_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 46dd00d8224..843a14a500c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -46,66 +46,6 @@ #include "util/u_debug.h" -#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED) - -#include "llvm/Support/raw_ostream.h" - -class raw_debug_ostream : - public llvm::raw_ostream -{ - uint64_t pos; - - void write_impl(const char *Ptr, size_t Size); - uint64_t current_pos() { return pos; } - uint64_t current_pos() const { return pos; } - -#if HAVE_LLVM >= 0x207 - uint64_t preferred_buffer_size() { return 512; } -#else - size_t preferred_buffer_size() { return 512; } -#endif -}; - - -void -raw_debug_ostream::write_impl(const char *Ptr, size_t Size) -{ - if (Size > 0) { - char *lastPtr = (char *)&Ptr[Size]; - char last = *lastPtr; - *lastPtr = 0; - _debug_printf("%*s", Size, Ptr); - *lastPtr = last; - pos += Size; - } -} - - -/** - * Same as LLVMDumpValue, but through our debugging channels. - */ -extern "C" void -lp_debug_dump_value(LLVMValueRef value) -{ - raw_debug_ostream os; - llvm::unwrap(value)->print(os); - os.flush(); -} - - -#else - - -extern "C" void -lp_debug_dump_value(LLVMValueRef value) -{ - LLVMDumpValue(value); -} - - -#endif - - /** * Register the engine with oprofile. * diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index e9374cc6efa..1fc7746a834 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -12,7 +12,7 @@ Requirements See /proc/cpuinfo to know what your CPU supports. - - LLVM 2.6 (or later) + - LLVM. Version 2.8 recommended. 2.6 or later required. For Linux, on a recent Debian based distribution do: @@ -30,21 +30,8 @@ Requirements debug=no. This is necessary as LLVM builds as static library so the chosen MS CRT must match. - The version of LLVM from SVN ("2.7svn") from mid-March 2010 is pretty - stable and has some features not in version 2.6. - - scons (optional) - - udis86, http://udis86.sourceforge.net/ (optional). My personal repository - supports more opcodes which haven't been merged upstream yet: - - git clone git://anongit.freedesktop.org/~jrfonseca/udis86 - cd udis86 - ./autogen.sh - ./configure --with-pic - make - sudo make install - Building ======== @@ -94,13 +81,7 @@ that no tail call optimizations are done by gcc. To better profile JIT code you'll need to build LLVM with oprofile integration. - source_dir=$PWD/llvm-2.6 - build_dir=$source_dir/build/profile - install_dir=$source_dir-profile - - mkdir -p "$build_dir" - cd "$build_dir" && \ - $source_dir/configure \ + ./configure \ --prefix=$install_dir \ --enable-optimized \ --disable-profiling \