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/Host.h" 23 #include "llvm/Support/TargetRegistry.h" 24 #include "llvm/Support/raw_ostream.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 Mod->setDataLayout(td); 216 pass.add(new DataLayoutPass(Mod)); 217 218 TargetMachine::CodeGenFileType ft; 219 switch (codegen) { 220 case LLVMAssemblyFile: 221 ft = TargetMachine::CGFT_AssemblyFile; 222 break; 223 default: 224 ft = TargetMachine::CGFT_ObjectFile; 225 break; 226 } 227 if (TM->addPassesToEmitFile(pass, OS, ft)) { 228 error = "TargetMachine can't emit a file of this type"; 229 *ErrorMessage = strdup(error.c_str()); 230 return true; 231 } 232 233 pass.run(*Mod); 234 235 OS.flush(); 236 return false; 237 } 238 239 LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, 240 char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { 241 std::string error; 242 raw_fd_ostream dest(Filename, error, sys::fs::F_None); 243 if (!error.empty()) { 244 *ErrorMessage = strdup(error.c_str()); 245 return true; 246 } 247 formatted_raw_ostream destf(dest); 248 bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage); 249 dest.flush(); 250 return Result; 251 } 252 253 LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, 254 LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage, 255 LLVMMemoryBufferRef *OutMemBuf) { 256 std::string CodeString; 257 raw_string_ostream OStream(CodeString); 258 formatted_raw_ostream Out(OStream); 259 bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage); 260 OStream.flush(); 261 262 std::string &Data = OStream.str(); 263 *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(), 264 Data.length(), ""); 265 return Result; 266 } 267 268 char *LLVMGetDefaultTargetTriple(void) { 269 return strdup(sys::getDefaultTargetTriple().c_str()); 270 } 271 272 void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) { 273 unwrap(T)->addAnalysisPasses(*unwrap(PM)); 274 } 275