Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  17.  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  18.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  21.  *
  22.  * The above copyright notice and this permission notice (including the
  23.  * next paragraph) shall be included in all copies or substantial portions
  24.  * of the Software.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  
  29. /**
  30.  * The purpose of this module is to expose LLVM functionality not available
  31.  * through the C++ bindings.
  32.  */
  33.  
  34.  
  35. #ifndef __STDC_LIMIT_MACROS
  36. #define __STDC_LIMIT_MACROS
  37. #endif
  38.  
  39. #ifndef __STDC_CONSTANT_MACROS
  40. #define __STDC_CONSTANT_MACROS
  41. #endif
  42.  
  43. // Undef these vars just to silence warnings
  44. #undef PACKAGE_BUGREPORT
  45. #undef PACKAGE_NAME
  46. #undef PACKAGE_STRING
  47. #undef PACKAGE_TARNAME
  48. #undef PACKAGE_VERSION
  49.  
  50.  
  51. #include <stddef.h>
  52.  
  53. #include <llvm-c/Core.h>
  54. #include <llvm-c/ExecutionEngine.h>
  55. #include <llvm/Target/TargetOptions.h>
  56. #include <llvm/ExecutionEngine/ExecutionEngine.h>
  57. #if HAVE_LLVM >= 0x0301
  58. #include <llvm/ADT/Triple.h>
  59. #include <llvm/ExecutionEngine/JITMemoryManager.h>
  60. #endif
  61. #include <llvm/Support/CommandLine.h>
  62. #include <llvm/Support/PrettyStackTrace.h>
  63.  
  64. #if HAVE_LLVM >= 0x0300
  65. #include <llvm/Support/TargetSelect.h>
  66. #else /* HAVE_LLVM < 0x0300 */
  67. #include <llvm/Target/TargetSelect.h>
  68. #endif /* HAVE_LLVM < 0x0300 */
  69.  
  70. #if HAVE_LLVM >= 0x0303
  71. #include <llvm/IR/IRBuilder.h>
  72. #include <llvm/IR/Module.h>
  73. #include <llvm/Support/CBindingWrapping.h>
  74. #endif
  75.  
  76. #include "pipe/p_config.h"
  77. #include "util/u_debug.h"
  78. #include "util/u_cpu_detect.h"
  79.  
  80. #include "lp_bld_misc.h"
  81.  
  82. namespace {
  83.  
  84. class LLVMEnsureMultithreaded {
  85. public:
  86.    LLVMEnsureMultithreaded()
  87.    {
  88. #if HAVE_LLVM < 0x0303
  89.       if (!llvm::llvm_is_multithreaded()) {
  90.          llvm::llvm_start_multithreaded();
  91.       }
  92. #else
  93.       if (!LLVMIsMultithreaded()) {
  94.          LLVMStartMultithreaded();
  95.       }
  96. #endif
  97.    }
  98. };
  99.  
  100. static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
  101.  
  102. }
  103.  
  104. extern "C" void
  105. lp_set_target_options(void)
  106. {
  107. #if HAVE_LLVM <= 0x0300
  108. #if defined(DEBUG)
  109. #if HAVE_LLVM >= 0x0207
  110.    llvm::JITEmitDebugInfo = true;
  111. #endif
  112. #endif
  113.  
  114.    /*
  115.     * LLVM revision 123367 switched the default stack alignment to 16 bytes on
  116.     * Linux (and several other Unices in later revisions), to match recent gcc
  117.     * versions.
  118.     *
  119.     * However our drivers can be loaded by old binary applications, still
  120.     * maintaining a 4 bytes stack alignment.  Therefore we must tell LLVM here
  121.     * to only assume a 4 bytes alignment for backwards compatibility.
  122.     */
  123. #if defined(PIPE_ARCH_X86)
  124. #if HAVE_LLVM == 0x0300
  125.    llvm::StackAlignmentOverride = 4;
  126. #else
  127.    llvm::StackAlignment = 4;
  128. #endif
  129. #endif
  130.  
  131. #if defined(DEBUG) || defined(PROFILE)
  132.    llvm::NoFramePointerElim = true;
  133. #if HAVE_LLVM >= 0x0208
  134.    llvm::NoFramePointerElimNonLeaf = true;
  135. #endif
  136. #endif
  137.  
  138.    llvm::NoExcessFPPrecision = false;
  139.  
  140.    /* XXX: Investigate this */
  141. #if 0
  142.    llvm::UnsafeFPMath = true;
  143. #endif
  144. #endif  /* HAVE_LLVM <= 0x0300 */
  145.  
  146. #if HAVE_LLVM < 0x0209
  147.    /*
  148.     * LLVM will generate MMX instructions for vectors <= 64 bits, leading to
  149.     * innefficient code, and in 32bit systems, to the corruption of the FPU
  150.     * stack given that it expects the user to generate the EMMS instructions.
  151.     *
  152.     * See also:
  153.     * - http://llvm.org/bugs/show_bug.cgi?id=3287
  154.     * - http://l4.me.uk/post/2009/06/07/llvm-wrinkle-3-configuration-what-configuration/
  155.     *
  156.     * The -disable-mmx global option can be specified only once  since we
  157.     * dynamically link against LLVM it will reside in a separate shared object,
  158.     * which may or not be delete when this shared object is, so we use the
  159.     * llvm::DisablePrettyStackTrace variable (which we set below and should
  160.     * reside in the same shared library) to determine whether the -disable-mmx
  161.     * option has been set or not.
  162.     *
  163.     * Thankfully this ugly hack is not necessary on LLVM 2.9 onwards.
  164.     */
  165.    if (!llvm::DisablePrettyStackTrace) {
  166.       static boolean first = TRUE;
  167.       static const char* options[] = {
  168.          "prog",
  169.          "-disable-mmx"
  170.       };
  171.       assert(first);
  172.       llvm::cl::ParseCommandLineOptions(2, const_cast<char**>(options));
  173.       first = FALSE;
  174.    }
  175. #endif
  176.  
  177.    /*
  178.     * By default LLVM adds a signal handler to output a pretty stack trace.
  179.     * This signal handler is never removed, causing problems when unloading the
  180.     * shared object where the gallium driver resides.
  181.     */
  182.    llvm::DisablePrettyStackTrace = true;
  183.  
  184.    // If we have a native target, initialize it to ensure it is linked in and
  185.    // usable by the JIT.
  186.    llvm::InitializeNativeTarget();
  187.  
  188. #if HAVE_LLVM >= 0x0208
  189.    llvm::InitializeNativeTargetAsmPrinter();
  190. #elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
  191.    LLVMInitializeX86AsmPrinter();
  192. #elif defined(PIPE_ARCH_ARM)
  193.    LLVMInitializeARMAsmPrinter();
  194. #elif defined(PIPE_ARCH_PPC)
  195.    LLVMInitializePowerPCAsmPrinter();
  196. #endif
  197.  
  198. #if HAVE_LLVM >= 0x0207
  199. #  if HAVE_LLVM >= 0x0301
  200.    llvm::InitializeNativeTargetDisassembler();
  201. #  elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
  202.    LLVMInitializeX86Disassembler();
  203. #  elif defined(PIPE_ARCH_ARM)
  204.    LLVMInitializeARMDisassembler();
  205. #  endif
  206. #endif
  207. }
  208.  
  209.  
  210. extern "C" void
  211. lp_func_delete_body(LLVMValueRef FF)
  212. {
  213.    llvm::Function *func = llvm::unwrap<llvm::Function>(FF);
  214.    func->deleteBody();
  215. }
  216.  
  217.  
  218. extern "C"
  219. LLVMValueRef
  220. lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal,
  221.                        const char *Name)
  222. {
  223.    return llvm::wrap(llvm::unwrap(B)->CreateLoad(llvm::unwrap(PointerVal), true, Name));
  224. }
  225.  
  226.  
  227. extern "C"
  228. void
  229. lp_set_load_alignment(LLVMValueRef Inst,
  230.                        unsigned Align)
  231. {
  232.    llvm::unwrap<llvm::LoadInst>(Inst)->setAlignment(Align);
  233. }
  234.  
  235. extern "C"
  236. void
  237. lp_set_store_alignment(LLVMValueRef Inst,
  238.                        unsigned Align)
  239. {
  240.    llvm::unwrap<llvm::StoreInst>(Inst)->setAlignment(Align);
  241. }
  242.  
  243.  
  244. #if HAVE_LLVM >= 0x301
  245.  
  246. /**
  247.  * Same as LLVMCreateJITCompilerForModule, but:
  248.  * - allows using MCJIT and enabling AVX feature where available.
  249.  * - set target options
  250.  *
  251.  * See also:
  252.  * - llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
  253.  * - llvm/tools/lli/lli.cpp
  254.  * - http://markmail.org/message/ttkuhvgj4cxxy2on#query:+page:1+mid:aju2dggerju3ivd3+state:results
  255.  */
  256. extern "C"
  257. LLVMBool
  258. lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
  259.                                         LLVMModuleRef M,
  260.                                         unsigned OptLevel,
  261.                                         int useMCJIT,
  262.                                         char **OutError)
  263. {
  264.    using namespace llvm;
  265.  
  266.    std::string Error;
  267.    EngineBuilder builder(unwrap(M));
  268.  
  269.    /**
  270.     * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and
  271.     * friends for configuring code generation options, like stack alignment.
  272.     */
  273.    TargetOptions options;
  274. #if defined(PIPE_ARCH_X86)
  275.    options.StackAlignmentOverride = 4;
  276.    options.RealignStack = true;
  277. #endif
  278.  
  279. #if defined(DEBUG)
  280.    options.JITEmitDebugInfo = true;
  281. #endif
  282.  
  283. #if defined(DEBUG) || defined(PROFILE)
  284.    options.NoFramePointerElimNonLeaf = true;
  285.    options.NoFramePointerElim = true;
  286. #endif
  287.  
  288.    builder.setEngineKind(EngineKind::JIT)
  289.           .setErrorStr(&Error)
  290.           .setTargetOptions(options)
  291.           .setOptLevel((CodeGenOpt::Level)OptLevel);
  292.  
  293.    if (useMCJIT) {
  294.        builder.setUseMCJIT(true);
  295.    }
  296.  
  297.    llvm::SmallVector<std::string, 1> MAttrs;
  298.    if (util_cpu_caps.has_avx) {
  299.       /*
  300.        * AVX feature is not automatically detected from CPUID by the X86 target
  301.        * yet, because the old (yet default) JIT engine is not capable of
  302.        * emitting the opcodes.  But as we're using MCJIT here, it is safe to
  303.        * add set this attribute.
  304.        */
  305.       MAttrs.push_back("+avx");
  306.       if (util_cpu_caps.has_f16c) {
  307.          MAttrs.push_back("+f16c");
  308.       }
  309.       builder.setMAttrs(MAttrs);
  310.    }
  311.    builder.setJITMemoryManager(JITMemoryManager::CreateDefaultMemManager());
  312.  
  313.    ExecutionEngine *JIT;
  314. #if 0
  315.    JIT = builder.create();
  316. #else
  317.    /*
  318.     * Workaround http://llvm.org/bugs/show_bug.cgi?id=12833
  319.     */
  320.    StringRef MArch = "";
  321.    StringRef MCPU = "";
  322.    Triple TT(unwrap(M)->getTargetTriple());
  323.    JIT = builder.create(builder.selectTarget(TT, MArch, MCPU, MAttrs));
  324. #endif
  325.    if (JIT) {
  326.       *OutJIT = wrap(JIT);
  327.       return 0;
  328.    }
  329.    *OutError = strdup(Error.c_str());
  330.    return 1;
  331. }
  332.  
  333. #endif /* HAVE_LLVM >= 0x301 */
  334.