2 * Copyright 2011 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 "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:
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
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 FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * Authors: Tom Stellard <thomas.stellard@amd.com>
26 #include "radeon_llvm_emit.h"
28 #include <llvm/LLVMContext.h>
29 #include <llvm/Module.h>
30 #include <llvm/PassManager.h>
31 #include <llvm/ADT/Triple.h>
32 #include <llvm/Support/FormattedStream.h>
33 #include <llvm/Support/Host.h>
34 #include <llvm/Support/IRReader.h>
35 #include <llvm/Support/SourceMgr.h>
36 #include <llvm/Support/TargetRegistry.h>
37 #include <llvm/Support/TargetSelect.h>
38 #include <llvm/Target/TargetData.h>
39 #include <llvm/Target/TargetMachine.h>
41 #include <llvm/Transforms/Scalar.h>
43 #include <llvm-c/Target.h>
54 void LLVMInitializeAMDILTargetMC(void);
55 void LLVMInitializeAMDILTarget(void);
56 void LLVMInitializeAMDILTargetInfo(void);
61 * Compile an LLVM module to machine code.
63 * @param bytes This function allocates memory for the byte stream, it is the
64 * caller's responsibility to free it.
67 radeon_llvm_compile(LLVMModuleRef M
, unsigned char ** bytes
,
68 unsigned * byte_count
, const char * gpu_family
,
71 Triple
AMDGPUTriple(sys::getDefaultTargetTriple());
74 /* XXX: Can we just initialize the AMDGPU target here? */
75 InitializeAllTargets();
76 InitializeAllTargetMCs();
78 LLVMInitializeAMDILTargetInfo();
79 LLVMInitializeAMDILTarget();
80 LLVMInitializeAMDILTargetMC();
83 const Target
* AMDGPUTarget
= TargetRegistry::lookupTarget("r600", err
);
85 fprintf(stderr
, "Can't find target: %s\n", err
.c_str());
89 Triple::ArchType Arch
= Triple::getArchTypeForLLVMName("r600");
90 if (Arch
== Triple::UnknownArch
) {
91 fprintf(stderr
, "Unknown Arch\n");
93 AMDGPUTriple
.setArch(Arch
);
95 Module
* mod
= unwrap(M
);
96 std::string FS
= gpu_family
;
99 std::auto_ptr
<TargetMachine
> tm(AMDGPUTarget
->createTargetMachine(
100 AMDGPUTriple
.getTriple(), gpu_family
, "" /* Features */,
101 TO
, Reloc::Default
, CodeModel::Default
,
104 TargetMachine
&AMDGPUTargetMachine
= *tm
.get();
105 /* XXX: Use TargetMachine.Options in 3.0 */
110 PM
.add(new TargetData(*AMDGPUTargetMachine
.getTargetData()));
111 PM
.add(createPromoteMemoryToRegisterPass());
112 AMDGPUTargetMachine
.setAsmVerbosityDefault(true);
114 std::string CodeString
;
115 raw_string_ostream
oStream(CodeString
);
116 formatted_raw_ostream
out(oStream
);
118 /* Optional extra paramater true / false to disable verify */
119 if (AMDGPUTargetMachine
.addPassesToEmitFile(PM
, out
, TargetMachine::CGFT_AssemblyFile
,
121 fprintf(stderr
, "AddingPasses failed.\n");
127 std::string
&data
= oStream
.str();
129 *bytes
= (unsigned char*)malloc(data
.length() * sizeof(unsigned char));
130 memcpy(*bytes
, data
.c_str(), data
.length() * sizeof(unsigned char));
131 *byte_count
= data
.length();