Subversion Repositories Kolibri OS

Rev

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. #include <llvm/ADT/Triple.h>
  58. #if HAVE_LLVM < 0x0306
  59. #include <llvm/ExecutionEngine/JITMemoryManager.h>
  60. #else
  61. #include <llvm/ExecutionEngine/SectionMemoryManager.h>
  62. #endif
  63. #include <llvm/Support/CommandLine.h>
  64. #include <llvm/Support/Host.h>
  65. #include <llvm/Support/PrettyStackTrace.h>
  66.  
  67. #include <llvm/Support/TargetSelect.h>
  68.  
  69. #include <llvm/IR/IRBuilder.h>
  70. #include <llvm/IR/Module.h>
  71. #include <llvm/Support/CBindingWrapping.h>
  72.  
  73. #include "pipe/p_config.h"
  74. #include "util/u_debug.h"
  75. #include "util/u_cpu_detect.h"
  76.  
  77. #include "lp_bld_misc.h"
  78.  
  79. namespace {
  80.  
  81. class LLVMEnsureMultithreaded {
  82. public:
  83.    LLVMEnsureMultithreaded()
  84.    {
  85.       if (!LLVMIsMultithreaded()) {
  86.          LLVMStartMultithreaded();
  87.       }
  88.    }
  89. };
  90.  
  91. static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
  92.  
  93. }
  94.  
  95. extern "C" void
  96. lp_set_target_options(void)
  97. {
  98. #if HAVE_LLVM < 0x0304
  99.    /*
  100.     * By default LLVM adds a signal handler to output a pretty stack trace.
  101.     * This signal handler is never removed, causing problems when unloading the
  102.     * shared object where the gallium driver resides.
  103.     */
  104.    llvm::DisablePrettyStackTrace = true;
  105. #endif
  106.  
  107.    // If we have a native target, initialize it to ensure it is linked in and
  108.    // usable by the JIT.
  109.    llvm::InitializeNativeTarget();
  110.  
  111.    llvm::InitializeNativeTargetAsmPrinter();
  112.  
  113.    llvm::InitializeNativeTargetDisassembler();
  114. }
  115.  
  116.  
  117. extern "C"
  118. LLVMValueRef
  119. lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal,
  120.                        const char *Name)
  121. {
  122.    return llvm::wrap(llvm::unwrap(B)->CreateLoad(llvm::unwrap(PointerVal), true, Name));
  123. }
  124.  
  125.  
  126. extern "C"
  127. void
  128. lp_set_load_alignment(LLVMValueRef Inst,
  129.                        unsigned Align)
  130. {
  131.    llvm::unwrap<llvm::LoadInst>(Inst)->setAlignment(Align);
  132. }
  133.  
  134. extern "C"
  135. void
  136. lp_set_store_alignment(LLVMValueRef Inst,
  137.                        unsigned Align)
  138. {
  139.    llvm::unwrap<llvm::StoreInst>(Inst)->setAlignment(Align);
  140. }
  141.  
  142.  
  143. #if HAVE_LLVM < 0x0306
  144. typedef llvm::JITMemoryManager BaseMemoryManager;
  145. #else
  146. typedef llvm::RTDyldMemoryManager BaseMemoryManager;
  147. #endif
  148.  
  149.  
  150. /*
  151.  * Delegating is tedious but the default manager class is hidden in an
  152.  * anonymous namespace in LLVM, so we cannot just derive from it to change
  153.  * its behavior.
  154.  */
  155. class DelegatingJITMemoryManager : public BaseMemoryManager {
  156.  
  157.    protected:
  158.       virtual BaseMemoryManager *mgr() const = 0;
  159.  
  160.    public:
  161. #if HAVE_LLVM < 0x0306
  162.       /*
  163.        * From JITMemoryManager
  164.        */
  165.       virtual void setMemoryWritable() {
  166.          mgr()->setMemoryWritable();
  167.       }
  168.       virtual void setMemoryExecutable() {
  169.          mgr()->setMemoryExecutable();
  170.       }
  171.       virtual void setPoisonMemory(bool poison) {
  172.          mgr()->setPoisonMemory(poison);
  173.       }
  174.       virtual void AllocateGOT() {
  175.          mgr()->AllocateGOT();
  176.          /*
  177.           * isManagingGOT() is not virtual in base class so we can't delegate.
  178.           * Instead we mirror the value of HasGOT in our instance.
  179.           */
  180.          HasGOT = mgr()->isManagingGOT();
  181.       }
  182.       virtual uint8_t *getGOTBase() const {
  183.          return mgr()->getGOTBase();
  184.       }
  185.       virtual uint8_t *startFunctionBody(const llvm::Function *F,
  186.                                          uintptr_t &ActualSize) {
  187.          return mgr()->startFunctionBody(F, ActualSize);
  188.       }
  189.       virtual uint8_t *allocateStub(const llvm::GlobalValue *F,
  190.                                     unsigned StubSize,
  191.                                     unsigned Alignment) {
  192.          return mgr()->allocateStub(F, StubSize, Alignment);
  193.       }
  194.       virtual void endFunctionBody(const llvm::Function *F,
  195.                                    uint8_t *FunctionStart,
  196.                                    uint8_t *FunctionEnd) {
  197.          mgr()->endFunctionBody(F, FunctionStart, FunctionEnd);
  198.       }
  199.       virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
  200.          return mgr()->allocateSpace(Size, Alignment);
  201.       }
  202.       virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
  203.          return mgr()->allocateGlobal(Size, Alignment);
  204.       }
  205.       virtual void deallocateFunctionBody(void *Body) {
  206.          mgr()->deallocateFunctionBody(Body);
  207.       }
  208. #if HAVE_LLVM < 0x0304
  209.       virtual uint8_t *startExceptionTable(const llvm::Function *F,
  210.                                            uintptr_t &ActualSize) {
  211.          return mgr()->startExceptionTable(F, ActualSize);
  212.       }
  213.       virtual void endExceptionTable(const llvm::Function *F,
  214.                                      uint8_t *TableStart,
  215.                                      uint8_t *TableEnd,
  216.                                      uint8_t *FrameRegister) {
  217.          mgr()->endExceptionTable(F, TableStart, TableEnd,
  218.                                   FrameRegister);
  219.       }
  220.       virtual void deallocateExceptionTable(void *ET) {
  221.          mgr()->deallocateExceptionTable(ET);
  222.       }
  223. #endif
  224.       virtual bool CheckInvariants(std::string &s) {
  225.          return mgr()->CheckInvariants(s);
  226.       }
  227.       virtual size_t GetDefaultCodeSlabSize() {
  228.          return mgr()->GetDefaultCodeSlabSize();
  229.       }
  230.       virtual size_t GetDefaultDataSlabSize() {
  231.          return mgr()->GetDefaultDataSlabSize();
  232.       }
  233.       virtual size_t GetDefaultStubSlabSize() {
  234.          return mgr()->GetDefaultStubSlabSize();
  235.       }
  236.       virtual unsigned GetNumCodeSlabs() {
  237.          return mgr()->GetNumCodeSlabs();
  238.       }
  239.       virtual unsigned GetNumDataSlabs() {
  240.          return mgr()->GetNumDataSlabs();
  241.       }
  242.       virtual unsigned GetNumStubSlabs() {
  243.          return mgr()->GetNumStubSlabs();
  244.       }
  245. #endif
  246.  
  247.       /*
  248.        * From RTDyldMemoryManager
  249.        */
  250. #if HAVE_LLVM >= 0x0304
  251.       virtual uint8_t *allocateCodeSection(uintptr_t Size,
  252.                                            unsigned Alignment,
  253.                                            unsigned SectionID,
  254.                                            llvm::StringRef SectionName) {
  255.          return mgr()->allocateCodeSection(Size, Alignment, SectionID,
  256.                                            SectionName);
  257.       }
  258. #else
  259.       virtual uint8_t *allocateCodeSection(uintptr_t Size,
  260.                                            unsigned Alignment,
  261.                                            unsigned SectionID) {
  262.          return mgr()->allocateCodeSection(Size, Alignment, SectionID);
  263.       }
  264. #endif
  265.       virtual uint8_t *allocateDataSection(uintptr_t Size,
  266.                                            unsigned Alignment,
  267.                                            unsigned SectionID,
  268. #if HAVE_LLVM >= 0x0304
  269.                                            llvm::StringRef SectionName,
  270. #endif
  271.                                            bool IsReadOnly) {
  272.          return mgr()->allocateDataSection(Size, Alignment, SectionID,
  273. #if HAVE_LLVM >= 0x0304
  274.                                            SectionName,
  275. #endif
  276.                                            IsReadOnly);
  277.       }
  278. #if HAVE_LLVM >= 0x0304
  279.       virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
  280.          mgr()->registerEHFrames(Addr, LoadAddr, Size);
  281.       }
  282.       virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
  283.          mgr()->deregisterEHFrames(Addr, LoadAddr, Size);
  284.       }
  285. #else
  286.       virtual void registerEHFrames(llvm::StringRef SectionData) {
  287.          mgr()->registerEHFrames(SectionData);
  288.       }
  289. #endif
  290.       virtual void *getPointerToNamedFunction(const std::string &Name,
  291.                                               bool AbortOnFailure=true) {
  292.          return mgr()->getPointerToNamedFunction(Name, AbortOnFailure);
  293.       }
  294. #if HAVE_LLVM <= 0x0303
  295.       virtual bool applyPermissions(std::string *ErrMsg = 0) {
  296.          return mgr()->applyPermissions(ErrMsg);
  297.       }
  298. #else
  299.       virtual bool finalizeMemory(std::string *ErrMsg = 0) {
  300.          return mgr()->finalizeMemory(ErrMsg);
  301.       }
  302. #endif
  303. };
  304.  
  305.  
  306. /*
  307.  * Delegate memory management to one shared manager for more efficient use
  308.  * of memory than creating a separate pool for each LLVM engine.
  309.  * Keep generated code until freeGeneratedCode() is called, instead of when
  310.  * memory manager is destroyed, which happens during engine destruction.
  311.  * This allows additional memory savings as we don't have to keep the engine
  312.  * around in order to use the code.
  313.  * All methods are delegated to the shared manager except destruction and
  314.  * deallocating code.  For the latter we just remember what needs to be
  315.  * deallocated later.  The shared manager is deleted once it is empty.
  316.  */
  317. class ShaderMemoryManager : public DelegatingJITMemoryManager {
  318.  
  319.    BaseMemoryManager *TheMM;
  320.  
  321.    struct GeneratedCode {
  322.       typedef std::vector<void *> Vec;
  323.       Vec FunctionBody, ExceptionTable;
  324.       BaseMemoryManager *TheMM;
  325.  
  326.       GeneratedCode(BaseMemoryManager *MM) {
  327.          TheMM = MM;
  328.       }
  329.  
  330.       ~GeneratedCode() {
  331.          /*
  332.           * Deallocate things as previously requested and
  333.           * free shared manager when no longer used.
  334.           */
  335. #if HAVE_LLVM < 0x0306
  336.          Vec::iterator i;
  337.  
  338.          assert(TheMM);
  339.          for ( i = FunctionBody.begin(); i != FunctionBody.end(); ++i )
  340.             TheMM->deallocateFunctionBody(*i);
  341. #if HAVE_LLVM < 0x0304
  342.          for ( i = ExceptionTable.begin(); i != ExceptionTable.end(); ++i )
  343.             TheMM->deallocateExceptionTable(*i);
  344. #endif /* HAVE_LLVM < 0x0304 */
  345. #endif /* HAVE_LLVM < 0x0306 */
  346.       }
  347.    };
  348.  
  349.    GeneratedCode *code;
  350.  
  351.    BaseMemoryManager *mgr() const {
  352.       return TheMM;
  353.    }
  354.  
  355.    public:
  356.  
  357.       ShaderMemoryManager(BaseMemoryManager* MM) {
  358.          TheMM = MM;
  359.          code = new GeneratedCode(MM);
  360.       }
  361.  
  362.       virtual ~ShaderMemoryManager() {
  363.          /*
  364.           * 'code' is purposely not deleted.  It is the user's responsibility
  365.           * to call getGeneratedCode() and freeGeneratedCode().
  366.           */
  367.       }
  368.  
  369.       struct lp_generated_code *getGeneratedCode() {
  370.          return (struct lp_generated_code *) code;
  371.       }
  372.  
  373.       static void freeGeneratedCode(struct lp_generated_code *code) {
  374.          delete (GeneratedCode *) code;
  375.       }
  376.  
  377. #if HAVE_LLVM < 0x0304
  378.       virtual void deallocateExceptionTable(void *ET) {
  379.          // remember for later deallocation
  380.          code->ExceptionTable.push_back(ET);
  381.       }
  382. #endif
  383.  
  384.       virtual void deallocateFunctionBody(void *Body) {
  385.          // remember for later deallocation
  386.          code->FunctionBody.push_back(Body);
  387.       }
  388. };
  389.  
  390.  
  391. /**
  392.  * Same as LLVMCreateJITCompilerForModule, but:
  393.  * - allows using MCJIT and enabling AVX feature where available.
  394.  * - set target options
  395.  *
  396.  * See also:
  397.  * - llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
  398.  * - llvm/tools/lli/lli.cpp
  399.  * - http://markmail.org/message/ttkuhvgj4cxxy2on#query:+page:1+mid:aju2dggerju3ivd3+state:results
  400.  */
  401. extern "C"
  402. LLVMBool
  403. lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
  404.                                         lp_generated_code **OutCode,
  405.                                         LLVMModuleRef M,
  406.                                         LLVMMCJITMemoryManagerRef CMM,
  407.                                         unsigned OptLevel,
  408.                                         int useMCJIT,
  409.                                         char **OutError)
  410. {
  411.    using namespace llvm;
  412.  
  413.    std::string Error;
  414. #if HAVE_LLVM >= 0x0306
  415.    EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
  416. #else
  417.    EngineBuilder builder(unwrap(M));
  418. #endif
  419.  
  420.    /**
  421.     * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and
  422.     * friends for configuring code generation options, like stack alignment.
  423.     */
  424.    TargetOptions options;
  425. #if defined(PIPE_ARCH_X86)
  426.    options.StackAlignmentOverride = 4;
  427. #if HAVE_LLVM < 0x0304
  428.    options.RealignStack = true;
  429. #endif
  430. #endif
  431.  
  432. #if defined(DEBUG) && HAVE_LLVM < 0x0307
  433.    options.JITEmitDebugInfo = true;
  434. #endif
  435.  
  436.    /* XXX: Workaround http://llvm.org/PR21435 */
  437. #if defined(DEBUG) || defined(PROFILE) || \
  438.     (HAVE_LLVM >= 0x0303 && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)))
  439. #if HAVE_LLVM < 0x0304
  440.    options.NoFramePointerElimNonLeaf = true;
  441. #endif
  442.    options.NoFramePointerElim = true;
  443. #endif
  444.  
  445.    builder.setEngineKind(EngineKind::JIT)
  446.           .setErrorStr(&Error)
  447.           .setTargetOptions(options)
  448.           .setOptLevel((CodeGenOpt::Level)OptLevel);
  449.  
  450.    if (useMCJIT) {
  451. #if HAVE_LLVM < 0x0306
  452.        builder.setUseMCJIT(true);
  453. #endif
  454. #ifdef _WIN32
  455.        /*
  456.         * MCJIT works on Windows, but currently only through ELF object format.
  457.         */
  458.        std::string targetTriple = llvm::sys::getProcessTriple();
  459.        targetTriple.append("-elf");
  460.        unwrap(M)->setTargetTriple(targetTriple);
  461. #endif
  462.    }
  463.  
  464.    llvm::SmallVector<std::string, 1> MAttrs;
  465.    if (util_cpu_caps.has_avx) {
  466.       /*
  467.        * AVX feature is not automatically detected from CPUID by the X86 target
  468.        * yet, because the old (yet default) JIT engine is not capable of
  469.        * emitting the opcodes. On newer llvm versions it is and at least some
  470.        * versions (tested with 3.3) will emit avx opcodes without this anyway.
  471.        */
  472.       MAttrs.push_back("+avx");
  473.       if (util_cpu_caps.has_f16c) {
  474.          MAttrs.push_back("+f16c");
  475.       }
  476.       builder.setMAttrs(MAttrs);
  477.    }
  478.  
  479. #if HAVE_LLVM >= 0x0305
  480.    StringRef MCPU = llvm::sys::getHostCPUName();
  481.    /*
  482.     * The cpu bits are no longer set automatically, so need to set mcpu manually.
  483.     * Note that the MAttrs set above will be sort of ignored (since we should
  484.     * not set any which would not be set by specifying the cpu anyway).
  485.     * It ought to be safe though since getHostCPUName() should include bits
  486.     * not only from the cpu but environment as well (for instance if it's safe
  487.     * to use avx instructions which need OS support). According to
  488.     * http://llvm.org/bugs/show_bug.cgi?id=19429 however if I understand this
  489.     * right it may be necessary to specify older cpu (or disable mattrs) though
  490.     * when not using MCJIT so no instructions are generated which the old JIT
  491.     * can't handle. Not entirely sure if we really need to do anything yet.
  492.     */
  493.    builder.setMCPU(MCPU);
  494. #endif
  495.  
  496.    ShaderMemoryManager *MM = NULL;
  497.    if (useMCJIT) {
  498. #if HAVE_LLVM > 0x0303
  499.        BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
  500.        MM = new ShaderMemoryManager(JMM);
  501.        *OutCode = MM->getGeneratedCode();
  502.  
  503. #if HAVE_LLVM >= 0x0306
  504.        builder.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(MM));
  505.        MM = NULL; // ownership taken by std::unique_ptr
  506. #else
  507.        builder.setMCJITMemoryManager(MM);
  508. #endif
  509. #endif
  510.    } else {
  511. #if HAVE_LLVM < 0x0306
  512.        BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
  513.        MM = new ShaderMemoryManager(JMM);
  514.        *OutCode = MM->getGeneratedCode();
  515.  
  516.        builder.setJITMemoryManager(MM);
  517. #else
  518.        assert(0);
  519. #endif
  520.    }
  521.  
  522.    ExecutionEngine *JIT;
  523.  
  524.    JIT = builder.create();
  525.    if (JIT) {
  526.       *OutJIT = wrap(JIT);
  527.       return 0;
  528.    }
  529.    lp_free_generated_code(*OutCode);
  530.    *OutCode = 0;
  531.    delete MM;
  532.    *OutError = strdup(Error.c_str());
  533.    return 1;
  534. }
  535.  
  536.  
  537. extern "C"
  538. void
  539. lp_free_generated_code(struct lp_generated_code *code)
  540. {
  541.    ShaderMemoryManager::freeGeneratedCode(code);
  542. }
  543.  
  544. extern "C"
  545. LLVMMCJITMemoryManagerRef
  546. lp_get_default_memory_manager()
  547. {
  548.    BaseMemoryManager *mm;
  549. #if HAVE_LLVM < 0x0306
  550.    mm = llvm::JITMemoryManager::CreateDefaultMemManager();
  551. #else
  552.    mm = new llvm::SectionMemoryManager();
  553. #endif
  554.    return reinterpret_cast<LLVMMCJITMemoryManagerRef>(mm);
  555. }
  556.  
  557. extern "C"
  558. void
  559. lp_free_memory_manager(LLVMMCJITMemoryManagerRef memorymgr)
  560. {
  561.    delete reinterpret_cast<BaseMemoryManager*>(memorymgr);
  562. }
  563.