2 * Copyright 2014 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 * The above copyright notice and this permission notice (including the
21 * next paragraph) shall be included in all copies or substantial portions
25 /* based on pieces from si_pipe.c and radeon_llvm_emit.c */
26 #include "ac_llvm_util.h"
28 #include <llvm-c/Core.h>
30 #include "c11/threads.h"
36 static void ac_init_llvm_target()
38 #if HAVE_LLVM < 0x0307
39 LLVMInitializeR600TargetInfo();
40 LLVMInitializeR600Target();
41 LLVMInitializeR600TargetMC();
42 LLVMInitializeR600AsmPrinter();
44 LLVMInitializeAMDGPUTargetInfo();
45 LLVMInitializeAMDGPUTarget();
46 LLVMInitializeAMDGPUTargetMC();
47 LLVMInitializeAMDGPUAsmPrinter();
51 static once_flag ac_init_llvm_target_once_flag
= ONCE_FLAG_INIT
;
53 static LLVMTargetRef
ac_get_llvm_target(const char *triple
)
55 LLVMTargetRef target
= NULL
;
56 char *err_message
= NULL
;
58 call_once(&ac_init_llvm_target_once_flag
, ac_init_llvm_target
);
60 if (LLVMGetTargetFromTriple(triple
, &target
, &err_message
)) {
61 fprintf(stderr
, "Cannot find target for triple %s ", triple
);
63 fprintf(stderr
, "%s\n", err_message
);
65 LLVMDisposeMessage(err_message
);
71 static const char *ac_get_llvm_processor_name(enum radeon_family family
)
100 #if HAVE_LLVM <= 0x0307
111 #if HAVE_LLVM <= 0x0308
127 LLVMTargetMachineRef
ac_create_target_machine(enum radeon_family family
, bool supports_spill
)
129 assert(family
>= CHIP_TAHITI
);
131 const char *triple
= supports_spill
? "amdgcn-mesa-mesa3d" : "amdgcn--";
132 LLVMTargetRef target
= ac_get_llvm_target(triple
);
133 LLVMTargetMachineRef tm
= LLVMCreateTargetMachine(
136 ac_get_llvm_processor_name(family
),
137 "+DumpCode,+vgpr-spilling",
138 LLVMCodeGenLevelDefault
,
140 LLVMCodeModelDefault
);
146 #if HAVE_LLVM < 0x0400
147 static LLVMAttribute
ac_attr_to_llvm_attr(enum ac_func_attr attr
)
150 case AC_FUNC_ATTR_ALWAYSINLINE
: return LLVMAlwaysInlineAttribute
;
151 case AC_FUNC_ATTR_BYVAL
: return LLVMByValAttribute
;
152 case AC_FUNC_ATTR_INREG
: return LLVMInRegAttribute
;
153 case AC_FUNC_ATTR_NOALIAS
: return LLVMNoAliasAttribute
;
154 case AC_FUNC_ATTR_NOUNWIND
: return LLVMNoUnwindAttribute
;
155 case AC_FUNC_ATTR_READNONE
: return LLVMReadNoneAttribute
;
156 case AC_FUNC_ATTR_READONLY
: return LLVMReadOnlyAttribute
;
158 fprintf(stderr
, "Unhandled function attribute: %x\n", attr
);
165 static const char *attr_to_str(enum ac_func_attr attr
)
168 case AC_FUNC_ATTR_ALWAYSINLINE
: return "alwaysinline";
169 case AC_FUNC_ATTR_BYVAL
: return "byval";
170 case AC_FUNC_ATTR_INREG
: return "inreg";
171 case AC_FUNC_ATTR_NOALIAS
: return "noalias";
172 case AC_FUNC_ATTR_NOUNWIND
: return "nounwind";
173 case AC_FUNC_ATTR_READNONE
: return "readnone";
174 case AC_FUNC_ATTR_READONLY
: return "readonly";
176 fprintf(stderr
, "Unhandled function attribute: %x\n", attr
);
184 ac_add_function_attr(LLVMValueRef function
,
186 enum ac_func_attr attr
)
189 #if HAVE_LLVM < 0x0400
190 LLVMAttribute llvm_attr
= ac_attr_to_llvm_attr(attr
);
191 if (attr_idx
== -1) {
192 LLVMAddFunctionAttr(function
, llvm_attr
);
194 LLVMAddAttribute(LLVMGetParam(function
, attr_idx
- 1), llvm_attr
);
197 LLVMContextRef context
= LLVMGetModuleContext(LLVMGetGlobalParent(function
));
198 const char *attr_name
= attr_to_str(attr
);
199 unsigned kind_id
= LLVMGetEnumAttributeKindForName(attr_name
,
201 LLVMAttributeRef llvm_attr
= LLVMCreateEnumAttribute(context
, kind_id
, 0);
202 LLVMAddAttributeAtIndex(function
, attr_idx
, llvm_attr
);
207 ac_dump_module(LLVMModuleRef module
)
209 char *str
= LLVMPrintModuleToString(module
);
210 fprintf(stderr
, "%s", str
);
211 LLVMDisposeMessage(str
);