TargetMachineC.cpp revision fa74752298602e0b74fb60ce3f0e76d0c461d3d8
1//===-- TargetMachine.cpp -------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the LLVM-C part of TargetMachine.h 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm-c/TargetMachine.h" 15#include "llvm-c/Core.h" 16#include "llvm-c/Target.h" 17#include "llvm/IR/DataLayout.h" 18#include "llvm/IR/Module.h" 19#include "llvm/PassManager.h" 20#include "llvm/Support/CodeGen.h" 21#include "llvm/Support/FormattedStream.h" 22#include "llvm/Support/TargetRegistry.h" 23#include "llvm/Support/raw_ostream.h" 24#include "llvm/Support/Host.h" 25#include "llvm/Target/TargetMachine.h" 26#include <cassert> 27#include <cstdlib> 28#include <cstring> 29 30using namespace llvm; 31 32inline DataLayout *unwrap(LLVMTargetDataRef P) { 33 return reinterpret_cast<DataLayout*>(P); 34} 35 36inline LLVMTargetDataRef wrap(const DataLayout *P) { 37 return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P)); 38} 39 40inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) { 41 return reinterpret_cast<TargetLibraryInfo*>(P); 42} 43 44inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) { 45 TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P); 46 return reinterpret_cast<LLVMTargetLibraryInfoRef>(X); 47} 48 49inline TargetMachine *unwrap(LLVMTargetMachineRef P) { 50 return reinterpret_cast<TargetMachine*>(P); 51} 52inline Target *unwrap(LLVMTargetRef P) { 53 return reinterpret_cast<Target*>(P); 54} 55inline LLVMTargetMachineRef wrap(const TargetMachine *P) { 56 return 57 reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P)); 58} 59inline LLVMTargetRef wrap(const Target * P) { 60 return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P)); 61} 62 63LLVMTargetRef LLVMGetFirstTarget() { 64 if(TargetRegistry::begin() == TargetRegistry::end()) { 65 return NULL; 66 } 67 68 const Target* target = &*TargetRegistry::begin(); 69 return wrap(target); 70} 71LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) { 72 return wrap(unwrap(T)->getNext()); 73} 74 75LLVMTargetRef LLVMGetTargetFromName(const char *Name) { 76 for (TargetRegistry::iterator IT = TargetRegistry::begin(), 77 IE = TargetRegistry::end(); IT != IE; ++IT) { 78 if (IT->getName() == Name) 79 return wrap(&*IT); 80 } 81 82 return NULL; 83} 84 85LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T, 86 char **ErrorMessage) { 87 std::string Error; 88 89 *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error)); 90 91 if (!*T) { 92 if (ErrorMessage) 93 *ErrorMessage = strdup(Error.c_str()); 94 95 return 1; 96 } 97 98 return 0; 99} 100 101const char * LLVMGetTargetName(LLVMTargetRef T) { 102 return unwrap(T)->getName(); 103} 104 105const char * LLVMGetTargetDescription(LLVMTargetRef T) { 106 return unwrap(T)->getShortDescription(); 107} 108 109LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) { 110 return unwrap(T)->hasJIT(); 111} 112 113LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) { 114 return unwrap(T)->hasTargetMachine(); 115} 116 117LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) { 118 return unwrap(T)->hasMCAsmBackend(); 119} 120 121LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, 122 const char* Triple, const char* CPU, const char* Features, 123 LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, 124 LLVMCodeModel CodeModel) { 125 Reloc::Model RM; 126 switch (Reloc){ 127 case LLVMRelocStatic: 128 RM = Reloc::Static; 129 break; 130 case LLVMRelocPIC: 131 RM = Reloc::PIC_; 132 break; 133 case LLVMRelocDynamicNoPic: 134 RM = Reloc::DynamicNoPIC; 135 break; 136 default: 137 RM = Reloc::Default; 138 break; 139 } 140 141 CodeModel::Model CM = unwrap(CodeModel); 142 143 CodeGenOpt::Level OL; 144 switch (Level) { 145 case LLVMCodeGenLevelNone: 146 OL = CodeGenOpt::None; 147 break; 148 case LLVMCodeGenLevelLess: 149 OL = CodeGenOpt::Less; 150 break; 151 case LLVMCodeGenLevelAggressive: 152 OL = CodeGenOpt::Aggressive; 153 break; 154 default: 155 OL = CodeGenOpt::Default; 156 break; 157 } 158 159 TargetOptions opt; 160 return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, 161 CM, OL)); 162} 163 164 165void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { 166 delete unwrap(T); 167} 168 169LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) { 170 const Target* target = &(unwrap(T)->getTarget()); 171 return wrap(target); 172} 173 174char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) { 175 std::string StringRep = unwrap(T)->getTargetTriple(); 176 return strdup(StringRep.c_str()); 177} 178 179char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) { 180 std::string StringRep = unwrap(T)->getTargetCPU(); 181 return strdup(StringRep.c_str()); 182} 183 184char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) { 185 std::string StringRep = unwrap(T)->getTargetFeatureString(); 186 return strdup(StringRep.c_str()); 187} 188 189LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) { 190 return wrap(unwrap(T)->getDataLayout()); 191} 192 193void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T, 194 LLVMBool VerboseAsm) { 195 unwrap(T)->setAsmVerbosityDefault(VerboseAsm); 196} 197 198static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, 199 formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) { 200 TargetMachine* TM = unwrap(T); 201 Module* Mod = unwrap(M); 202 203 PassManager pass; 204 205 std::string error; 206 207 const DataLayout* td = TM->getDataLayout(); 208 209 if (!td) { 210 error = "No DataLayout in TargetMachine"; 211 *ErrorMessage = strdup(error.c_str()); 212 return true; 213 } 214 pass.add(new DataLayout(*td)); 215 216 TargetMachine::CodeGenFileType ft; 217 switch (codegen) { 218 case LLVMAssemblyFile: 219 ft = TargetMachine::CGFT_AssemblyFile; 220 break; 221 default: 222 ft = TargetMachine::CGFT_ObjectFile; 223 break; 224 } 225 if (TM->addPassesToEmitFile(pass, OS, ft)) { 226 error = "TargetMachine can't emit a file of this type"; 227 *ErrorMessage = strdup(error.c_str()); 228 return true; 229 } 230 231 pass.run(*Mod); 232 233 OS.flush(); 234 return false; 235} 236 237LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, 238 char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { 239 std::string error; 240 raw_fd_ostream dest(Filename, error, sys::fs::F_Binary); 241 if (!error.empty()) { 242 *ErrorMessage = strdup(error.c_str()); 243 return true; 244 } 245 formatted_raw_ostream destf(dest); 246 bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage); 247 dest.flush(); 248 return Result; 249} 250 251LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, 252 LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage, 253 LLVMMemoryBufferRef *OutMemBuf) { 254 std::string CodeString; 255 raw_string_ostream OStream(CodeString); 256 formatted_raw_ostream Out(OStream); 257 bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage); 258 OStream.flush(); 259 260 std::string &Data = OStream.str(); 261 *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(), 262 Data.length(), ""); 263 return Result; 264} 265 266char *LLVMGetDefaultTargetTriple(void) { 267 return strdup(sys::getDefaultTargetTriple().c_str()); 268} 269