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