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