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