~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/auxiliary/gallivm/lp_bld_misc.cpp

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
// Undef these vars just to silence warnings
36
 
#undef PACKAGE_BUGREPORT
37
 
#undef PACKAGE_NAME
38
 
#undef PACKAGE_STRING
39
 
#undef PACKAGE_TARNAME
40
 
#undef PACKAGE_VERSION
41
 
 
42
 
 
43
 
#include <stddef.h>
44
 
 
45
 
#include <llvm/Config/llvm-config.h>
46
 
 
47
 
#if LLVM_VERSION_MAJOR < 7
48
 
// Workaround http://llvm.org/PR23628
49
 
#pragma push_macro("DEBUG")
50
 
#undef DEBUG
51
 
#endif
52
 
 
53
 
#include <llvm/Config/llvm-config.h>
54
 
#include <llvm-c/Core.h>
55
 
#include <llvm-c/Support.h>
56
 
#include <llvm-c/ExecutionEngine.h>
57
 
#include <llvm/Target/TargetOptions.h>
58
 
#include <llvm/ExecutionEngine/ExecutionEngine.h>
59
 
#include <llvm/ADT/Triple.h>
60
 
#include <llvm/Analysis/TargetLibraryInfo.h>
61
 
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
62
 
#include <llvm/Support/CommandLine.h>
63
 
#include <llvm/Support/Host.h>
64
 
#include <llvm/Support/PrettyStackTrace.h>
65
 
#include <llvm/ExecutionEngine/ObjectCache.h>
66
 
#include <llvm/Support/TargetSelect.h>
67
 
#if LLVM_VERSION_MAJOR >= 15
68
 
#include <llvm/Support/MemoryBuffer.h>
69
 
#endif
70
 
 
71
 
#if LLVM_VERSION_MAJOR < 11
72
 
#include <llvm/IR/CallSite.h>
73
 
#endif
74
 
#include <llvm/IR/IRBuilder.h>
75
 
#include <llvm/IR/Module.h>
76
 
#include <llvm/Support/CBindingWrapping.h>
77
 
 
78
 
#include <llvm/Config/llvm-config.h>
79
 
#if LLVM_USE_INTEL_JITEVENTS
80
 
#include <llvm/ExecutionEngine/JITEventListener.h>
81
 
#endif
82
 
 
83
 
#if LLVM_VERSION_MAJOR < 7
84
 
// Workaround http://llvm.org/PR23628
85
 
#pragma pop_macro("DEBUG")
86
 
#endif
87
 
 
88
 
#include "c11/threads.h"
89
 
#include "os/os_thread.h"
90
 
#include "pipe/p_config.h"
91
 
#include "util/u_debug.h"
92
 
#include "util/u_cpu_detect.h"
93
 
 
94
 
#include "lp_bld_misc.h"
95
 
#include "lp_bld_debug.h"
96
 
 
97
 
namespace {
98
 
 
99
 
class LLVMEnsureMultithreaded {
100
 
public:
101
 
   LLVMEnsureMultithreaded()
102
 
   {
103
 
      if (!LLVMIsMultithreaded()) {
104
 
         LLVMStartMultithreaded();
105
 
      }
106
 
   }
107
 
};
108
 
 
109
 
static LLVMEnsureMultithreaded lLVMEnsureMultithreaded;
110
 
 
111
 
}
112
 
 
113
 
static once_flag init_native_targets_once_flag = ONCE_FLAG_INIT;
114
 
 
115
 
static void init_native_targets()
116
 
{
117
 
   // If we have a native target, initialize it to ensure it is linked in and
118
 
   // usable by the JIT.
119
 
   llvm::InitializeNativeTarget();
120
 
 
121
 
   llvm::InitializeNativeTargetAsmPrinter();
122
 
 
123
 
   llvm::InitializeNativeTargetDisassembler();
124
 
#if DEBUG
125
 
   {
126
 
      char *env_llc_options = getenv("GALLIVM_LLC_OPTIONS");
127
 
      if (env_llc_options) {
128
 
         char *option;
129
 
         char *options[64] = {(char *) "llc"};      // Warning without cast
130
 
         int   n;
131
 
         for (n = 0, option = strtok(env_llc_options, " "); option; n++, option = strtok(NULL, " ")) {
132
 
            options[n + 1] = option;
133
 
         }
134
 
         if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
135
 
            debug_printf("llc additional options (%d):\n", n);
136
 
            for (int i = 1; i <= n; i++)
137
 
               debug_printf("\t%s\n", options[i]);
138
 
            debug_printf("\n");
139
 
         }
140
 
         LLVMParseCommandLineOptions(n + 1, options, NULL);
141
 
      }
142
 
   }
143
 
#endif
144
 
}
145
 
 
146
 
extern "C" void
147
 
lp_set_target_options(void)
148
 
{
149
 
   /* The llvm target registry is not thread-safe, so drivers and gallium frontends
150
 
    * that want to initialize targets should use the lp_set_target_options()
151
 
    * function to safely initialize targets.
152
 
    *
153
 
    * LLVM targets should be initialized before the driver or gallium frontend tries
154
 
    * to access the registry.
155
 
    */
156
 
   call_once(&init_native_targets_once_flag, init_native_targets);
157
 
}
158
 
 
159
 
extern "C"
160
 
LLVMTargetLibraryInfoRef
161
 
gallivm_create_target_library_info(const char *triple)
162
 
{
163
 
   return reinterpret_cast<LLVMTargetLibraryInfoRef>(
164
 
   new llvm::TargetLibraryInfoImpl(
165
 
   llvm::Triple(triple)));
166
 
}
167
 
 
168
 
extern "C"
169
 
void
170
 
gallivm_dispose_target_library_info(LLVMTargetLibraryInfoRef library_info)
171
 
{
172
 
   delete reinterpret_cast<
173
 
   llvm::TargetLibraryInfoImpl
174
 
   *>(library_info);
175
 
}
176
 
 
177
 
 
178
 
typedef llvm::RTDyldMemoryManager BaseMemoryManager;
179
 
 
180
 
 
181
 
/*
182
 
 * Delegating is tedious but the default manager class is hidden in an
183
 
 * anonymous namespace in LLVM, so we cannot just derive from it to change
184
 
 * its behavior.
185
 
 */
186
 
class DelegatingJITMemoryManager : public BaseMemoryManager {
187
 
 
188
 
   protected:
189
 
      virtual BaseMemoryManager *mgr() const = 0;
190
 
 
191
 
   public:
192
 
      /*
193
 
       * From RTDyldMemoryManager
194
 
       */
195
 
      virtual uint8_t *allocateCodeSection(uintptr_t Size,
196
 
                                           unsigned Alignment,
197
 
                                           unsigned SectionID,
198
 
                                           llvm::StringRef SectionName) {
199
 
         return mgr()->allocateCodeSection(Size, Alignment, SectionID,
200
 
                                           SectionName);
201
 
      }
202
 
      virtual uint8_t *allocateDataSection(uintptr_t Size,
203
 
                                           unsigned Alignment,
204
 
                                           unsigned SectionID,
205
 
                                           llvm::StringRef SectionName,
206
 
                                           bool IsReadOnly) {
207
 
         return mgr()->allocateDataSection(Size, Alignment, SectionID,
208
 
                                           SectionName,
209
 
                                           IsReadOnly);
210
 
      }
211
 
      virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
212
 
         mgr()->registerEHFrames(Addr, LoadAddr, Size);
213
 
      }
214
 
#if LLVM_VERSION_MAJOR >= 5
215
 
      virtual void deregisterEHFrames() {
216
 
         mgr()->deregisterEHFrames();
217
 
      }
218
 
#else
219
 
      virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {
220
 
         mgr()->deregisterEHFrames(Addr, LoadAddr, Size);
221
 
      }
222
 
#endif
223
 
      virtual void *getPointerToNamedFunction(const std::string &Name,
224
 
                                              bool AbortOnFailure=true) {
225
 
         return mgr()->getPointerToNamedFunction(Name, AbortOnFailure);
226
 
      }
227
 
      virtual bool finalizeMemory(std::string *ErrMsg = 0) {
228
 
         return mgr()->finalizeMemory(ErrMsg);
229
 
      }
230
 
};
231
 
 
232
 
 
233
 
/*
234
 
 * Delegate memory management to one shared manager for more efficient use
235
 
 * of memory than creating a separate pool for each LLVM engine.
236
 
 * Keep generated code until freeGeneratedCode() is called, instead of when
237
 
 * memory manager is destroyed, which happens during engine destruction.
238
 
 * This allows additional memory savings as we don't have to keep the engine
239
 
 * around in order to use the code.
240
 
 * All methods are delegated to the shared manager except destruction and
241
 
 * deallocating code.  For the latter we just remember what needs to be
242
 
 * deallocated later.  The shared manager is deleted once it is empty.
243
 
 */
244
 
class ShaderMemoryManager : public DelegatingJITMemoryManager {
245
 
 
246
 
   BaseMemoryManager *TheMM;
247
 
 
248
 
   struct GeneratedCode {
249
 
      typedef std::vector<void *> Vec;
250
 
      Vec FunctionBody, ExceptionTable;
251
 
      BaseMemoryManager *TheMM;
252
 
 
253
 
      GeneratedCode(BaseMemoryManager *MM) {
254
 
         TheMM = MM;
255
 
      }
256
 
 
257
 
      ~GeneratedCode() {
258
 
      }
259
 
   };
260
 
 
261
 
   GeneratedCode *code;
262
 
 
263
 
   BaseMemoryManager *mgr() const {
264
 
      return TheMM;
265
 
   }
266
 
 
267
 
   public:
268
 
 
269
 
      ShaderMemoryManager(BaseMemoryManager* MM) {
270
 
         TheMM = MM;
271
 
         code = new GeneratedCode(MM);
272
 
      }
273
 
 
274
 
      virtual ~ShaderMemoryManager() {
275
 
         /*
276
 
          * 'code' is purposely not deleted.  It is the user's responsibility
277
 
          * to call getGeneratedCode() and freeGeneratedCode().
278
 
          */
279
 
      }
280
 
 
281
 
      struct lp_generated_code *getGeneratedCode() {
282
 
         return (struct lp_generated_code *) code;
283
 
      }
284
 
 
285
 
      static void freeGeneratedCode(struct lp_generated_code *code) {
286
 
         delete (GeneratedCode *) code;
287
 
      }
288
 
 
289
 
      virtual void deallocateFunctionBody(void *Body) {
290
 
         // remember for later deallocation
291
 
         code->FunctionBody.push_back(Body);
292
 
      }
293
 
};
294
 
 
295
 
class LPObjectCache : public llvm::ObjectCache {
296
 
private:
297
 
   bool has_object;
298
 
   struct lp_cached_code *cache_out;
299
 
public:
300
 
   LPObjectCache(struct lp_cached_code *cache) {
301
 
      cache_out = cache;
302
 
      has_object = false;
303
 
   }
304
 
 
305
 
   ~LPObjectCache() {
306
 
   }
307
 
   void notifyObjectCompiled(const llvm::Module *M, llvm::MemoryBufferRef Obj) {
308
 
      const std::string ModuleID = M->getModuleIdentifier();
309
 
      if (has_object)
310
 
         fprintf(stderr, "CACHE ALREADY HAS MODULE OBJECT\n");
311
 
      has_object = true;
312
 
      cache_out->data_size = Obj.getBufferSize();
313
 
      cache_out->data = malloc(cache_out->data_size);
314
 
      memcpy(cache_out->data, Obj.getBufferStart(), cache_out->data_size);
315
 
   }
316
 
 
317
 
   virtual std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module *M) {
318
 
      if (cache_out->data_size) {
319
 
         return llvm::MemoryBuffer::getMemBuffer(llvm::StringRef((const char *)cache_out->data, cache_out->data_size), "", false);
320
 
      }
321
 
      return NULL;
322
 
   }
323
 
 
324
 
};
325
 
 
326
 
/**
327
 
 * Same as LLVMCreateJITCompilerForModule, but:
328
 
 * - allows using MCJIT and enabling AVX feature where available.
329
 
 * - set target options
330
 
 *
331
 
 * See also:
332
 
 * - llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
333
 
 * - llvm/tools/lli/lli.cpp
334
 
 * - http://markmail.org/message/ttkuhvgj4cxxy2on#query:+page:1+mid:aju2dggerju3ivd3+state:results
335
 
 */
336
 
extern "C"
337
 
LLVMBool
338
 
lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
339
 
                                        lp_generated_code **OutCode,
340
 
                                        struct lp_cached_code *cache_out,
341
 
                                        LLVMModuleRef M,
342
 
                                        LLVMMCJITMemoryManagerRef CMM,
343
 
                                        unsigned OptLevel,
344
 
                                        char **OutError)
345
 
{
346
 
   using namespace llvm;
347
 
 
348
 
   std::string Error;
349
 
   EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
350
 
 
351
 
   /**
352
 
    * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and
353
 
    * friends for configuring code generation options, like stack alignment.
354
 
    */
355
 
   TargetOptions options;
356
 
#if defined(PIPE_ARCH_X86) && LLVM_VERSION_MAJOR < 13
357
 
   options.StackAlignmentOverride = 4;
358
 
#endif
359
 
 
360
 
   builder.setEngineKind(EngineKind::JIT)
361
 
          .setErrorStr(&Error)
362
 
          .setTargetOptions(options)
363
 
          .setOptLevel((CodeGenOpt::Level)OptLevel);
364
 
 
365
 
#ifdef _WIN32
366
 
    /*
367
 
     * MCJIT works on Windows, but currently only through ELF object format.
368
 
     *
369
 
     * XXX: We could use `LLVM_HOST_TRIPLE "-elf"` but LLVM_HOST_TRIPLE has
370
 
     * different strings for MinGW/MSVC, so better play it safe and be
371
 
     * explicit.
372
 
     */
373
 
#  ifdef _WIN64
374
 
    LLVMSetTarget(M, "x86_64-pc-win32-elf");
375
 
#  else
376
 
    LLVMSetTarget(M, "i686-pc-win32-elf");
377
 
#  endif
378
 
#endif
379
 
 
380
 
   llvm::SmallVector<std::string, 16> MAttrs;
381
 
 
382
 
#if LLVM_VERSION_MAJOR >= 4 && (defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) || defined(PIPE_ARCH_ARM))
383
 
   /* llvm-3.3+ implements sys::getHostCPUFeatures for Arm
384
 
    * and llvm-3.7+ for x86, which allows us to enable/disable
385
 
    * code generation based on the results of cpuid on these
386
 
    * architectures.
387
 
    */
388
 
   llvm::StringMap<bool> features;
389
 
   llvm::sys::getHostCPUFeatures(features);
390
 
 
391
 
   for (StringMapIterator<bool> f = features.begin();
392
 
        f != features.end();
393
 
        ++f) {
394
 
      MAttrs.push_back(((*f).second ? "+" : "-") + (*f).first().str());
395
 
   }
396
 
#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
397
 
   /*
398
 
    * We need to unset attributes because sometimes LLVM mistakenly assumes
399
 
    * certain features are present given the processor name.
400
 
    *
401
 
    * https://bugs.freedesktop.org/show_bug.cgi?id=92214
402
 
    * http://llvm.org/PR25021
403
 
    * http://llvm.org/PR19429
404
 
    * http://llvm.org/PR16721
405
 
    */
406
 
   MAttrs.push_back(util_get_cpu_caps()->has_sse    ? "+sse"    : "-sse"   );
407
 
   MAttrs.push_back(util_get_cpu_caps()->has_sse2   ? "+sse2"   : "-sse2"  );
408
 
   MAttrs.push_back(util_get_cpu_caps()->has_sse3   ? "+sse3"   : "-sse3"  );
409
 
   MAttrs.push_back(util_get_cpu_caps()->has_ssse3  ? "+ssse3"  : "-ssse3" );
410
 
   MAttrs.push_back(util_get_cpu_caps()->has_sse4_1 ? "+sse4.1" : "-sse4.1");
411
 
   MAttrs.push_back(util_get_cpu_caps()->has_sse4_2 ? "+sse4.2" : "-sse4.2");
412
 
   /*
413
 
    * AVX feature is not automatically detected from CPUID by the X86 target
414
 
    * yet, because the old (yet default) JIT engine is not capable of
415
 
    * emitting the opcodes. On newer llvm versions it is and at least some
416
 
    * versions (tested with 3.3) will emit avx opcodes without this anyway.
417
 
    */
418
 
   MAttrs.push_back(util_get_cpu_caps()->has_avx  ? "+avx"  : "-avx");
419
 
   MAttrs.push_back(util_get_cpu_caps()->has_f16c ? "+f16c" : "-f16c");
420
 
   MAttrs.push_back(util_get_cpu_caps()->has_fma  ? "+fma"  : "-fma");
421
 
   MAttrs.push_back(util_get_cpu_caps()->has_avx2 ? "+avx2" : "-avx2");
422
 
   /* disable avx512 and all subvariants */
423
 
   MAttrs.push_back("-avx512cd");
424
 
   MAttrs.push_back("-avx512er");
425
 
   MAttrs.push_back("-avx512f");
426
 
   MAttrs.push_back("-avx512pf");
427
 
   MAttrs.push_back("-avx512bw");
428
 
   MAttrs.push_back("-avx512dq");
429
 
   MAttrs.push_back("-avx512vl");
430
 
#endif
431
 
#if defined(PIPE_ARCH_ARM)
432
 
   if (!util_get_cpu_caps()->has_neon) {
433
 
      MAttrs.push_back("-neon");
434
 
      MAttrs.push_back("-crypto");
435
 
      MAttrs.push_back("-vfp2");
436
 
   }
437
 
#endif
438
 
 
439
 
#if defined(PIPE_ARCH_PPC)
440
 
   MAttrs.push_back(util_get_cpu_caps()->has_altivec ? "+altivec" : "-altivec");
441
 
#if (LLVM_VERSION_MAJOR < 4)
442
 
   /*
443
 
    * Make sure VSX instructions are disabled
444
 
    * See LLVM bugs:
445
 
    * https://llvm.org/bugs/show_bug.cgi?id=25503#c7 (fixed in 3.8.1)
446
 
    * https://llvm.org/bugs/show_bug.cgi?id=26775 (fixed in 3.8.1)
447
 
    * https://llvm.org/bugs/show_bug.cgi?id=33531 (fixed in 4.0)
448
 
    * https://llvm.org/bugs/show_bug.cgi?id=34647 (llc performance on certain unusual shader IR; intro'd in 4.0, pending as of 5.0)
449
 
    */
450
 
   if (util_get_cpu_caps()->has_altivec) {
451
 
      MAttrs.push_back("-vsx");
452
 
   }
453
 
#else
454
 
   /*
455
 
    * Bug 25503 is fixed, by the same fix that fixed
456
 
    * bug 26775, in versions of LLVM later than 3.8 (starting with 3.8.1).
457
 
    * BZ 33531 actually comprises more than one bug, all of
458
 
    * which are fixed in LLVM 4.0.
459
 
    *
460
 
    * With LLVM 4.0 or higher:
461
 
    * Make sure VSX instructions are ENABLED (if supported), unless
462
 
    * VSX instructions are explicitly enabled/disabled via GALLIVM_VSX=1 or 0.
463
 
    */
464
 
   if (util_get_cpu_caps()->has_altivec) {
465
 
      MAttrs.push_back(util_get_cpu_caps()->has_vsx ? "+vsx" : "-vsx");
466
 
   }
467
 
#endif
468
 
#endif
469
 
 
470
 
#if defined(PIPE_ARCH_MIPS64)
471
 
   MAttrs.push_back(util_get_cpu_caps()->has_msa ? "+msa" : "-msa");
472
 
   /* MSA requires a 64-bit FPU register file */
473
 
   MAttrs.push_back("+fp64");
474
 
#endif
475
 
 
476
 
   builder.setMAttrs(MAttrs);
477
 
 
478
 
   if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
479
 
      int n = MAttrs.size();
480
 
      if (n > 0) {
481
 
         debug_printf("llc -mattr option(s): ");
482
 
         for (int i = 0; i < n; i++)
483
 
            debug_printf("%s%s", MAttrs[i].c_str(), (i < n - 1) ? "," : "");
484
 
         debug_printf("\n");
485
 
      }
486
 
   }
487
 
 
488
 
   StringRef MCPU = llvm::sys::getHostCPUName();
489
 
   /*
490
 
    * The cpu bits are no longer set automatically, so need to set mcpu manually.
491
 
    * Note that the MAttrs set above will be sort of ignored (since we should
492
 
    * not set any which would not be set by specifying the cpu anyway).
493
 
    * It ought to be safe though since getHostCPUName() should include bits
494
 
    * not only from the cpu but environment as well (for instance if it's safe
495
 
    * to use avx instructions which need OS support). According to
496
 
    * http://llvm.org/bugs/show_bug.cgi?id=19429 however if I understand this
497
 
    * right it may be necessary to specify older cpu (or disable mattrs) though
498
 
    * when not using MCJIT so no instructions are generated which the old JIT
499
 
    * can't handle. Not entirely sure if we really need to do anything yet.
500
 
    */
501
 
 
502
 
#ifdef PIPE_ARCH_PPC_64
503
 
   /*
504
 
    * Large programs, e.g. gnome-shell and firefox, may tax the addressability
505
 
    * of the Medium code model once dynamically generated JIT-compiled shader
506
 
    * programs are linked in and relocated.  Yet the default code model as of
507
 
    * LLVM 8 is Medium or even Small.
508
 
    * The cost of changing from Medium to Large is negligible:
509
 
    * - an additional 8-byte pointer stored immediately before the shader entrypoint;
510
 
    * - change an add-immediate (addis) instruction to a load (ld).
511
 
    */
512
 
   builder.setCodeModel(CodeModel::Large);
513
 
 
514
 
#if UTIL_ARCH_LITTLE_ENDIAN
515
 
   /*
516
 
    * Versions of LLVM prior to 4.0 lacked a table entry for "POWER8NVL",
517
 
    * resulting in (big-endian) "generic" being returned on
518
 
    * little-endian Power8NVL systems.  The result was that code that
519
 
    * attempted to load the least significant 32 bits of a 64-bit quantity
520
 
    * from memory loaded the wrong half.  This resulted in failures in some
521
 
    * Piglit tests, e.g.
522
 
    * .../arb_gpu_shader_fp64/execution/conversion/frag-conversion-explicit-double-uint
523
 
    */
524
 
   if (MCPU == "generic")
525
 
      MCPU = "pwr8";
526
 
#endif
527
 
#endif
528
 
 
529
 
#if defined(PIPE_ARCH_MIPS64)
530
 
      /*
531
 
       * ls3a4000 CPU and ls2k1000 SoC is a mips64r5 compatible with MSA SIMD
532
 
       * instruction set implemented, while ls3a3000 is mips64r2 compatible
533
 
       * only. getHostCPUName() return "generic" on all loongson
534
 
       * mips CPU currently. So we override the MCPU to mips64r5 if MSA is
535
 
       * implemented, feedback to mips64r2 for all other ordinary mips64 cpu.
536
 
       */
537
 
   if (MCPU == "generic")
538
 
      MCPU = util_get_cpu_caps()->has_msa ? "mips64r5" : "mips64r2";
539
 
#endif
540
 
 
541
 
   builder.setMCPU(MCPU);
542
 
   if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) {
543
 
      debug_printf("llc -mcpu option: %s\n", MCPU.str().c_str());
544
 
   }
545
 
 
546
 
   ShaderMemoryManager *MM = NULL;
547
 
   BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
548
 
   MM = new ShaderMemoryManager(JMM);
549
 
   *OutCode = MM->getGeneratedCode();
550
 
 
551
 
   builder.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(MM));
552
 
   MM = NULL; // ownership taken by std::unique_ptr
553
 
 
554
 
   ExecutionEngine *JIT;
555
 
 
556
 
   JIT = builder.create();
557
 
 
558
 
   if (cache_out) {
559
 
      LPObjectCache *objcache = new LPObjectCache(cache_out);
560
 
      JIT->setObjectCache(objcache);
561
 
      cache_out->jit_obj_cache = (void *)objcache;
562
 
   }
563
 
 
564
 
#if LLVM_USE_INTEL_JITEVENTS
565
 
   JITEventListener *JEL = JITEventListener::createIntelJITEventListener();
566
 
   JIT->RegisterJITEventListener(JEL);
567
 
#endif
568
 
   if (JIT) {
569
 
      *OutJIT = wrap(JIT);
570
 
      return 0;
571
 
   }
572
 
   lp_free_generated_code(*OutCode);
573
 
   *OutCode = 0;
574
 
   delete MM;
575
 
   *OutError = strdup(Error.c_str());
576
 
   return 1;
577
 
}
578
 
 
579
 
 
580
 
extern "C"
581
 
void
582
 
lp_free_generated_code(struct lp_generated_code *code)
583
 
{
584
 
   ShaderMemoryManager::freeGeneratedCode(code);
585
 
}
586
 
 
587
 
extern "C"
588
 
LLVMMCJITMemoryManagerRef
589
 
lp_get_default_memory_manager()
590
 
{
591
 
   BaseMemoryManager *mm;
592
 
   mm = new llvm::SectionMemoryManager();
593
 
   return reinterpret_cast<LLVMMCJITMemoryManagerRef>(mm);
594
 
}
595
 
 
596
 
extern "C"
597
 
void
598
 
lp_free_memory_manager(LLVMMCJITMemoryManagerRef memorymgr)
599
 
{
600
 
   delete reinterpret_cast<BaseMemoryManager*>(memorymgr);
601
 
}
602
 
 
603
 
extern "C" void
604
 
lp_free_objcache(void *objcache_ptr)
605
 
{
606
 
   LPObjectCache *objcache = (LPObjectCache *)objcache_ptr;
607
 
   delete objcache;
608
 
}
609
 
 
610
 
extern "C" LLVMValueRef
611
 
lp_get_called_value(LLVMValueRef call)
612
 
{
613
 
        return LLVMGetCalledValue(call);
614
 
}
615
 
 
616
 
extern "C" bool
617
 
lp_is_function(LLVMValueRef v)
618
 
{
619
 
        return LLVMGetValueKind(v) == LLVMFunctionValueKind;
620
 
}
621
 
 
622
 
extern "C" void
623
 
lp_set_module_stack_alignment_override(LLVMModuleRef MRef, unsigned align)
624
 
{
625
 
#if LLVM_VERSION_MAJOR >= 13
626
 
   llvm::Module *M = llvm::unwrap(MRef);
627
 
   M->setOverrideStackAlignment(align);
628
 
#endif
629
 
}