17ec681f3Smrg/*
27ec681f3Smrg * Copyright 2016 Bas Nieuwenhuizen
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the
67ec681f3Smrg * "Software"), to deal in the Software without restriction, including
77ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish,
87ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to
97ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to
107ec681f3Smrg * the following conditions:
117ec681f3Smrg *
127ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
137ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
147ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
157ec681f3Smrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
167ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
177ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
187ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
197ec681f3Smrg *
207ec681f3Smrg * The above copyright notice and this permission notice (including the
217ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions
227ec681f3Smrg * of the Software.
237ec681f3Smrg *
247ec681f3Smrg */
257ec681f3Smrg
267ec681f3Smrg#ifndef AC_LLVM_UTIL_H
277ec681f3Smrg#define AC_LLVM_UTIL_H
287ec681f3Smrg
297ec681f3Smrg#include "amd_family.h"
307ec681f3Smrg#include "util/macros.h"
317ec681f3Smrg#include <llvm-c/TargetMachine.h>
327ec681f3Smrg#include <llvm/Config/llvm-config.h>
337ec681f3Smrg
347ec681f3Smrg#include <stdbool.h>
357ec681f3Smrg
367ec681f3Smrg#ifdef __cplusplus
377ec681f3Smrgextern "C" {
387ec681f3Smrg#endif
397ec681f3Smrg
407ec681f3Smrgstruct ac_compiler_passes;
417ec681f3Smrgstruct ac_llvm_context;
427ec681f3Smrg
437ec681f3Smrgenum ac_func_attr
447ec681f3Smrg{
457ec681f3Smrg   AC_FUNC_ATTR_ALWAYSINLINE = (1 << 0),
467ec681f3Smrg   AC_FUNC_ATTR_INREG = (1 << 2),
477ec681f3Smrg   AC_FUNC_ATTR_NOALIAS = (1 << 3),
487ec681f3Smrg   AC_FUNC_ATTR_NOUNWIND = (1 << 4),
497ec681f3Smrg   AC_FUNC_ATTR_READNONE = (1 << 5),
507ec681f3Smrg   AC_FUNC_ATTR_READONLY = (1 << 6),
517ec681f3Smrg   AC_FUNC_ATTR_WRITEONLY = (1 << 7),
527ec681f3Smrg   AC_FUNC_ATTR_INACCESSIBLE_MEM_ONLY = (1 << 8),
537ec681f3Smrg   AC_FUNC_ATTR_CONVERGENT = (1 << 9),
547ec681f3Smrg
557ec681f3Smrg   /* Legacy intrinsic that needs attributes on function declarations
567ec681f3Smrg    * and they must match the internal LLVM definition exactly, otherwise
577ec681f3Smrg    * intrinsic selection fails.
587ec681f3Smrg    */
597ec681f3Smrg   AC_FUNC_ATTR_LEGACY = (1u << 31),
607ec681f3Smrg};
617ec681f3Smrg
627ec681f3Smrgenum ac_target_machine_options
637ec681f3Smrg{
647ec681f3Smrg   AC_TM_SUPPORTS_SPILL       = 1 << 0,
657ec681f3Smrg   AC_TM_CHECK_IR             = 1 << 1,
667ec681f3Smrg   AC_TM_ENABLE_GLOBAL_ISEL   = 1 << 2,
677ec681f3Smrg   AC_TM_CREATE_LOW_OPT       = 1 << 3,
687ec681f3Smrg};
697ec681f3Smrg
707ec681f3Smrgenum ac_float_mode
717ec681f3Smrg{
727ec681f3Smrg   AC_FLOAT_MODE_DEFAULT,
737ec681f3Smrg   AC_FLOAT_MODE_DEFAULT_OPENGL,
747ec681f3Smrg   AC_FLOAT_MODE_DENORM_FLUSH_TO_ZERO,
757ec681f3Smrg};
767ec681f3Smrg
777ec681f3Smrg/* Per-thread persistent LLVM objects. */
787ec681f3Smrgstruct ac_llvm_compiler {
797ec681f3Smrg   LLVMTargetLibraryInfoRef target_library_info;
807ec681f3Smrg   LLVMPassManagerRef passmgr;
817ec681f3Smrg
827ec681f3Smrg   /* Default compiler. */
837ec681f3Smrg   LLVMTargetMachineRef tm;
847ec681f3Smrg   struct ac_compiler_passes *passes;
857ec681f3Smrg
867ec681f3Smrg   /* Optional compiler for faster compilation with fewer optimizations.
877ec681f3Smrg    * LLVM modules can be created with "tm" too. There is no difference.
887ec681f3Smrg    */
897ec681f3Smrg   LLVMTargetMachineRef low_opt_tm; /* uses -O1 instead of -O2 */
907ec681f3Smrg   struct ac_compiler_passes *low_opt_passes;
917ec681f3Smrg};
927ec681f3Smrg
937ec681f3Smrgconst char *ac_get_llvm_processor_name(enum radeon_family family);
947ec681f3Smrgvoid ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes);
957ec681f3Smrgvoid ac_add_attr_alignment(LLVMValueRef val, uint64_t bytes);
967ec681f3Smrgbool ac_is_sgpr_param(LLVMValueRef param);
977ec681f3Smrgvoid ac_add_function_attr(LLVMContextRef ctx, LLVMValueRef function, int attr_idx,
987ec681f3Smrg                          enum ac_func_attr attr);
997ec681f3Smrgvoid ac_add_func_attributes(LLVMContextRef ctx, LLVMValueRef function, unsigned attrib_mask);
1007ec681f3Smrgvoid ac_dump_module(LLVMModuleRef module);
1017ec681f3Smrg
1027ec681f3SmrgLLVMValueRef ac_llvm_get_called_value(LLVMValueRef call);
1037ec681f3Smrgbool ac_llvm_is_function(LLVMValueRef v);
1047ec681f3SmrgLLVMModuleRef ac_create_module(LLVMTargetMachineRef tm, LLVMContextRef ctx);
1057ec681f3Smrg
1067ec681f3SmrgLLVMBuilderRef ac_create_builder(LLVMContextRef ctx, enum ac_float_mode float_mode);
1077ec681f3Smrgvoid ac_enable_signed_zeros(struct ac_llvm_context *ctx);
1087ec681f3Smrgvoid ac_disable_signed_zeros(struct ac_llvm_context *ctx);
1097ec681f3Smrg
1107ec681f3Smrgvoid ac_llvm_add_target_dep_function_attr(LLVMValueRef F, const char *name, unsigned value);
1117ec681f3Smrgvoid ac_llvm_set_workgroup_size(LLVMValueRef F, unsigned size);
1127ec681f3Smrgvoid ac_llvm_set_target_features(LLVMValueRef F, struct ac_llvm_context *ctx);
1137ec681f3Smrg
1147ec681f3Smrgstatic inline unsigned ac_get_load_intr_attribs(bool can_speculate)
1157ec681f3Smrg{
1167ec681f3Smrg   /* READNONE means writes can't affect it, while READONLY means that
1177ec681f3Smrg    * writes can affect it. */
1187ec681f3Smrg   return can_speculate ? AC_FUNC_ATTR_READNONE : AC_FUNC_ATTR_READONLY;
1197ec681f3Smrg}
1207ec681f3Smrg
1217ec681f3Smrgunsigned ac_count_scratch_private_memory(LLVMValueRef function);
1227ec681f3Smrg
1237ec681f3SmrgLLVMTargetLibraryInfoRef ac_create_target_library_info(const char *triple);
1247ec681f3Smrgvoid ac_dispose_target_library_info(LLVMTargetLibraryInfoRef library_info);
1257ec681f3SmrgPUBLIC void ac_init_shared_llvm_once(void); /* Do not use directly, use ac_init_llvm_once */
1267ec681f3Smrgvoid ac_init_llvm_once(void);
1277ec681f3Smrg
1287ec681f3Smrgbool ac_init_llvm_compiler(struct ac_llvm_compiler *compiler, enum radeon_family family,
1297ec681f3Smrg                           enum ac_target_machine_options tm_options);
1307ec681f3Smrgvoid ac_destroy_llvm_compiler(struct ac_llvm_compiler *compiler);
1317ec681f3Smrg
1327ec681f3Smrgstruct ac_compiler_passes *ac_create_llvm_passes(LLVMTargetMachineRef tm);
1337ec681f3Smrgvoid ac_destroy_llvm_passes(struct ac_compiler_passes *p);
1347ec681f3Smrgbool ac_compile_module_to_elf(struct ac_compiler_passes *p, LLVMModuleRef module,
1357ec681f3Smrg                              char **pelf_buffer, size_t *pelf_size);
1367ec681f3Smrgvoid ac_llvm_add_barrier_noop_pass(LLVMPassManagerRef passmgr);
1377ec681f3Smrgvoid ac_enable_global_isel(LLVMTargetMachineRef tm);
1387ec681f3Smrg
1397ec681f3Smrgstatic inline bool ac_has_vec3_support(enum chip_class chip, bool use_format)
1407ec681f3Smrg{
1417ec681f3Smrg   /* GFX6 only supports vec3 with load/store format. */
1427ec681f3Smrg   return chip != GFX6 || use_format;
1437ec681f3Smrg}
1447ec681f3Smrg
1457ec681f3Smrg#ifdef __cplusplus
1467ec681f3Smrg}
1477ec681f3Smrg#endif
1487ec681f3Smrg
1497ec681f3Smrg#endif /* AC_LLVM_UTIL_H */
150