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#include <stddef.h> 44 45#include <llvm-c/Core.h> 46#include <llvm-c/ExecutionEngine.h> 47#include <llvm/Target/TargetOptions.h> 48#include <llvm/ExecutionEngine/ExecutionEngine.h> 49#include <llvm/ExecutionEngine/JITEventListener.h> 50#if HAVE_LLVM >= 0x0301 51#include <llvm/ADT/Triple.h> 52#include <llvm/ExecutionEngine/JITMemoryManager.h> 53#endif 54#include <llvm/Support/CommandLine.h> 55#include <llvm/Support/PrettyStackTrace.h> 56 57#if HAVE_LLVM >= 0x0300 58#include <llvm/Support/TargetSelect.h> 59#else /* HAVE_LLVM < 0x0300 */ 60#include <llvm/Target/TargetSelect.h> 61#endif /* HAVE_LLVM < 0x0300 */ 62 63#include "pipe/p_config.h" 64#include "util/u_debug.h" 65#include "util/u_cpu_detect.h" 66 67#include "lp_bld_misc.h" 68 69 70/** 71 * Register the engine with oprofile. 72 * 73 * This allows to see the LLVM IR function names in oprofile output. 74 * 75 * To actually work LLVM needs to be built with the --with-oprofile configure 76 * option. 77 * 78 * Also a oprofile:oprofile user:group is necessary. Which is not created by 79 * default on some distributions. 80 */ 81extern "C" void 82lp_register_oprofile_jit_event_listener(LLVMExecutionEngineRef EE) 83{ 84#if HAVE_LLVM >= 0x0301 85 llvm::unwrap(EE)->RegisterJITEventListener(llvm::JITEventListener::createOProfileJITEventListener()); 86#else 87 llvm::unwrap(EE)->RegisterJITEventListener(llvm::createOProfileJITEventListener()); 88#endif 89} 90 91 92extern "C" void 93lp_set_target_options(void) 94{ 95#if HAVE_LLVM <= 0x0300 96#if defined(DEBUG) 97#if HAVE_LLVM >= 0x0207 98 llvm::JITEmitDebugInfo = true; 99#endif 100#endif 101 102 /* 103 * LLVM revision 123367 switched the default stack alignment to 16 bytes on 104 * Linux (and several other Unices in later revisions), to match recent gcc 105 * versions. 106 * 107 * However our drivers can be loaded by old binary applications, still 108 * maintaining a 4 bytes stack alignment. Therefore we must tell LLVM here 109 * to only assume a 4 bytes alignment for backwards compatibility. 110 */ 111#if defined(PIPE_ARCH_X86) 112#if HAVE_LLVM >= 0x0300 113 llvm::StackAlignmentOverride = 4; 114#else 115 llvm::StackAlignment = 4; 116#endif 117#endif 118 119#if defined(DEBUG) || defined(PROFILE) 120 llvm::NoFramePointerElim = true; 121#if HAVE_LLVM >= 0x0208 122 llvm::NoFramePointerElimNonLeaf = true; 123#endif 124#endif 125 126 llvm::NoExcessFPPrecision = false; 127 128 /* XXX: Investigate this */ 129#if 0 130 llvm::UnsafeFPMath = true; 131#endif 132#endif /* HAVE_LLVM <= 0x0300 */ 133 134#if HAVE_LLVM < 0x0209 135 /* 136 * LLVM will generate MMX instructions for vectors <= 64 bits, leading to 137 * innefficient code, and in 32bit systems, to the corruption of the FPU 138 * stack given that it expects the user to generate the EMMS instructions. 139 * 140 * See also: 141 * - http://llvm.org/bugs/show_bug.cgi?id=3287 142 * - http://l4.me.uk/post/2009/06/07/llvm-wrinkle-3-configuration-what-configuration/ 143 * 144 * The -disable-mmx global option can be specified only once since we 145 * dynamically link against LLVM it will reside in a separate shared object, 146 * which may or not be delete when this shared object is, so we use the 147 * llvm::DisablePrettyStackTrace variable (which we set below and should 148 * reside in the same shared library) to determine whether the -disable-mmx 149 * option has been set or not. 150 * 151 * Thankfully this ugly hack is not necessary on LLVM 2.9 onwards. 152 */ 153 if (!llvm::DisablePrettyStackTrace) { 154 static boolean first = TRUE; 155 static const char* options[] = { 156 "prog", 157 "-disable-mmx" 158 }; 159 assert(first); 160 llvm::cl::ParseCommandLineOptions(2, const_cast<char**>(options)); 161 first = FALSE; 162 } 163#endif 164 165 /* 166 * By default LLVM adds a signal handler to output a pretty stack trace. 167 * This signal handler is never removed, causing problems when unloading the 168 * shared object where the gallium driver resides. 169 */ 170 llvm::DisablePrettyStackTrace = true; 171 172 // If we have a native target, initialize it to ensure it is linked in and 173 // usable by the JIT. 174 llvm::InitializeNativeTarget(); 175 176#if HAVE_LLVM >= 0x0208 177 llvm::InitializeNativeTargetAsmPrinter(); 178#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) 179 LLVMInitializeX86AsmPrinter(); 180#elif defined(PIPE_ARCH_ARM) 181 LLVMInitializeARMAsmPrinter(); 182#elif defined(PIPE_ARCH_PPC) 183 LLVMInitializePowerPCAsmPrinter(); 184#endif 185 186#if HAVE_LLVM >= 0x0207 187# if HAVE_LLVM >= 0x0301 188 llvm::InitializeNativeTargetDisassembler(); 189# elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) 190 LLVMInitializeX86Disassembler(); 191# elif defined(PIPE_ARCH_ARM) 192 LLVMInitializeARMDisassembler(); 193# endif 194#endif 195} 196 197 198extern "C" void 199lp_func_delete_body(LLVMValueRef FF) 200{ 201 llvm::Function *func = llvm::unwrap<llvm::Function>(FF); 202 func->deleteBody(); 203} 204 205 206extern "C" 207LLVMValueRef 208lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal, 209 const char *Name) 210{ 211 return llvm::wrap(llvm::unwrap(B)->CreateLoad(llvm::unwrap(PointerVal), true, Name)); 212} 213 214 215extern "C" 216void 217lp_set_load_alignment(LLVMValueRef Inst, 218 unsigned Align) 219{ 220 llvm::unwrap<llvm::LoadInst>(Inst)->setAlignment(Align); 221} 222 223extern "C" 224void 225lp_set_store_alignment(LLVMValueRef Inst, 226 unsigned Align) 227{ 228 llvm::unwrap<llvm::StoreInst>(Inst)->setAlignment(Align); 229} 230 231 232#if HAVE_LLVM >= 0x301 233 234/** 235 * Same as LLVMCreateJITCompilerForModule, but using MCJIT and enabling AVX 236 * feature where available. 237 * 238 * See also: 239 * - llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp 240 * - llvm/tools/lli/lli.cpp 241 * - http://markmail.org/message/ttkuhvgj4cxxy2on#query:+page:1+mid:aju2dggerju3ivd3+state:results 242 */ 243extern "C" 244LLVMBool 245lp_build_create_mcjit_compiler_for_module(LLVMExecutionEngineRef *OutJIT, 246 LLVMModuleRef M, 247 unsigned OptLevel, 248 char **OutError) 249{ 250 using namespace llvm; 251 252 std::string Error; 253 EngineBuilder builder(unwrap(M)); 254 builder.setEngineKind(EngineKind::JIT) 255 .setErrorStr(&Error) 256 .setOptLevel((CodeGenOpt::Level)OptLevel); 257 258 builder.setUseMCJIT(true); 259 260 llvm::SmallVector<std::string, 1> MAttrs; 261 if (util_cpu_caps.has_avx) { 262 /* 263 * AVX feature is not automatically detected from CPUID by the X86 target 264 * yet, because the old (yet default) JIT engine is not capable of 265 * emitting the opcodes. But as we're using MCJIT here, it is safe to 266 * add set this attribute. 267 */ 268 MAttrs.push_back("+avx"); 269 builder.setMAttrs(MAttrs); 270 } 271 builder.setJITMemoryManager(JITMemoryManager::CreateDefaultMemManager()); 272 273 ExecutionEngine *JIT; 274#if 0 275 JIT = builder.create(); 276#else 277 /* 278 * Workaround http://llvm.org/bugs/show_bug.cgi?id=12833 279 */ 280 StringRef MArch = ""; 281 StringRef MCPU = ""; 282 Triple TT(unwrap(M)->getTargetTriple()); 283 JIT = builder.create(builder.selectTarget(TT, MArch, MCPU, MAttrs)); 284#endif 285 if (JIT) { 286 *OutJIT = wrap(JIT); 287 return 0; 288 } 289 *OutError = strdup(Error.c_str()); 290 return 1; 291} 292 293#endif /* HAVE_LLVM >= 0x301 */ 294