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