Home | History | Annotate | Download | only in jitter
      1 /****************************************************************************
      2 * Copyright (C) 2014-2015 Intel Corporation.   All Rights Reserved.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice (including the next
     12 * paragraph) shall be included in all copies or substantial portions of the
     13 * Software.
     14 *
     15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21 * IN THE SOFTWARE.
     22 *
     23 * @file JitManager.h
     24 *
     25 * @brief JitManager contains the LLVM data structures used for JIT generation
     26 *
     27 * Notes:
     28 *
     29 ******************************************************************************/
     30 #pragma once
     31 
     32 #include "common/os.h"
     33 #include "common/isa.hpp"
     34 
     35 #if defined(_WIN32)
     36 #pragma warning(disable : 4146 4244 4267 4800 4996)
     37 #endif
     38 
     39 // llvm 3.7+ reuses "DEBUG" as an enum value
     40 #pragma push_macro("DEBUG")
     41 #undef DEBUG
     42 
     43 #include "llvm/IR/DataLayout.h"
     44 #include "llvm/IR/Instructions.h"
     45 #include "llvm/IR/LLVMContext.h"
     46 #include "llvm/IR/Module.h"
     47 #include "llvm/IR/Type.h"
     48 #include "llvm/IR/IRBuilder.h"
     49 #include "llvm/IR/IntrinsicInst.h"
     50 
     51 #include "llvm/Config/llvm-config.h"
     52 #ifndef LLVM_VERSION_MAJOR
     53 #include "llvm/Config/config.h"
     54 #endif
     55 
     56 #ifndef HAVE_LLVM
     57 #define HAVE_LLVM ((LLVM_VERSION_MAJOR << 8) | LLVM_VERSION_MINOR)
     58 #endif
     59 
     60 #include "llvm/IR/Verifier.h"
     61 #include "llvm/ExecutionEngine/MCJIT.h"
     62 #include "llvm/Support/FileSystem.h"
     63 #define LLVM_F_NONE sys::fs::F_None
     64 
     65 #include "llvm/Analysis/Passes.h"
     66 
     67 #if HAVE_LLVM == 0x306
     68 #include "llvm/PassManager.h"
     69 using FunctionPassManager = llvm::FunctionPassManager;
     70 using PassManager = llvm::PassManager;
     71 #else
     72 #include "llvm/IR/LegacyPassManager.h"
     73 using FunctionPassManager = llvm::legacy::FunctionPassManager;
     74 using PassManager = llvm::legacy::PassManager;
     75 #endif
     76 
     77 #include "llvm/CodeGen/Passes.h"
     78 #include "llvm/ExecutionEngine/ExecutionEngine.h"
     79 #include "llvm/Support/raw_ostream.h"
     80 #include "llvm/Support/TargetSelect.h"
     81 #include "llvm/Transforms/IPO.h"
     82 #include "llvm/Transforms/Scalar.h"
     83 #include "llvm/Support/Host.h"
     84 #include "llvm/Support/DynamicLibrary.h"
     85 
     86 
     87 #pragma pop_macro("DEBUG")
     88 
     89 //////////////////////////////////////////////////////////////////////////
     90 /// JitInstructionSet
     91 /// @brief Subclass of InstructionSet that allows users to override
     92 /// the reporting of support for certain ISA features.  This allows capping
     93 /// the jitted code to a certain feature level, e.g. jit AVX level code on
     94 /// a platform that supports AVX2.
     95 //////////////////////////////////////////////////////////////////////////
     96 class JitInstructionSet : public InstructionSet
     97 {
     98 public:
     99     JitInstructionSet(const char* requestedIsa) : isaRequest(requestedIsa)
    100     {
    101         std::transform(isaRequest.begin(), isaRequest.end(), isaRequest.begin(), ::tolower);
    102 
    103         if(isaRequest == "avx")
    104         {
    105             bForceAVX = true;
    106             bForceAVX2 = false;
    107             bForceAVX512 = false;
    108         }
    109         else if(isaRequest == "avx2")
    110         {
    111             bForceAVX = false;
    112             bForceAVX2 = true;
    113             bForceAVX512 = false;
    114         }
    115         #if 0
    116         else if(isaRequest == "avx512")
    117         {
    118             bForceAVX = false;
    119             bForceAVX2 = false;
    120             bForceAVX512 = true;
    121         }
    122         #endif
    123     };
    124 
    125     bool AVX2(void) { return bForceAVX ? 0 : InstructionSet::AVX2(); }
    126     bool AVX512F(void) { return (bForceAVX | bForceAVX2) ? 0 : InstructionSet::AVX512F(); }
    127     bool BMI2(void) { return bForceAVX ? 0 : InstructionSet::BMI2(); }
    128 
    129 private:
    130     bool bForceAVX = false;
    131     bool bForceAVX2 = false;
    132     bool bForceAVX512 = false;
    133     std::string isaRequest;
    134 };
    135 
    136 
    137 
    138 struct JitLLVMContext : llvm::LLVMContext
    139 {
    140 };
    141 
    142 
    143 //////////////////////////////////////////////////////////////////////////
    144 /// JitManager
    145 //////////////////////////////////////////////////////////////////////////
    146 struct JitManager
    147 {
    148     JitManager(uint32_t w, const char* arch, const char* core);
    149     ~JitManager(){};
    150 
    151     JitLLVMContext          mContext;   ///< LLVM compiler
    152     llvm::IRBuilder<>       mBuilder;   ///< LLVM IR Builder
    153     llvm::ExecutionEngine*  mpExec;
    154 
    155     // Need to be rebuilt after a JIT and before building new IR
    156     llvm::Module* mpCurrentModule;
    157     bool mIsModuleFinalized;
    158     uint32_t mJitNumber;
    159 
    160     uint32_t                 mVWidth;
    161 
    162     // Built in types.
    163     llvm::Type*                mInt8Ty;
    164     llvm::Type*                mInt32Ty;
    165     llvm::Type*                mInt64Ty;
    166     llvm::Type*                mFP32Ty;
    167     llvm::StructType*          mV4FP32Ty;
    168     llvm::StructType*          mV4Int32Ty;
    169 
    170     llvm::Type* mSimtFP32Ty;
    171     llvm::Type* mSimtInt32Ty;
    172 
    173     llvm::Type* mSimdVectorInt32Ty;
    174     llvm::Type* mSimdVectorTy;
    175 
    176     // fetch shader types
    177     llvm::FunctionType*        mFetchShaderTy;
    178 
    179     JitInstructionSet mArch;
    180     std::string mCore;
    181 
    182     void SetupNewModule();
    183     bool SetupModuleFromIR(const uint8_t *pIR);
    184 
    185     void DumpAsm(llvm::Function* pFunction, const char* fileName);
    186     static void DumpToFile(llvm::Function *f, const char *fileName);
    187 };
    188