1bb8507e6SMatthias Braun //===-- TargetMachine.cpp -------------------------------------------------===// 2bb8507e6SMatthias Braun // 3bb8507e6SMatthias Braun // The LLVM Compiler Infrastructure 4bb8507e6SMatthias Braun // 5bb8507e6SMatthias Braun // This file is distributed under the University of Illinois Open Source 6bb8507e6SMatthias Braun // License. See LICENSE.TXT for details. 7bb8507e6SMatthias Braun // 8bb8507e6SMatthias Braun //===----------------------------------------------------------------------===// 9bb8507e6SMatthias Braun // 10bb8507e6SMatthias Braun // This file implements the LLVM-C part of TargetMachine.h 11bb8507e6SMatthias Braun // 12bb8507e6SMatthias Braun //===----------------------------------------------------------------------===// 13bb8507e6SMatthias Braun 14bb8507e6SMatthias Braun #include "llvm-c/Core.h" 15bb8507e6SMatthias Braun #include "llvm-c/Target.h" 16bb8507e6SMatthias Braun #include "llvm-c/TargetMachine.h" 17bb8507e6SMatthias Braun #include "llvm/Analysis/TargetTransformInfo.h" 18bb8507e6SMatthias Braun #include "llvm/IR/DataLayout.h" 19bb8507e6SMatthias Braun #include "llvm/IR/LegacyPassManager.h" 20bb8507e6SMatthias Braun #include "llvm/IR/Module.h" 21bb8507e6SMatthias Braun #include "llvm/Support/FileSystem.h" 22bb8507e6SMatthias Braun #include "llvm/Support/FormattedStream.h" 23bb8507e6SMatthias Braun #include "llvm/Support/Host.h" 24bb8507e6SMatthias Braun #include "llvm/Support/TargetRegistry.h" 25bb8507e6SMatthias Braun #include "llvm/Support/raw_ostream.h" 26*bf121cf4SDavid Blaikie #include "llvm/Target/CodeGenCWrappers.h" 27bb8507e6SMatthias Braun #include "llvm/Target/TargetMachine.h" 28bb8507e6SMatthias Braun #include <cassert> 29bb8507e6SMatthias Braun #include <cstdlib> 30bb8507e6SMatthias Braun #include <cstring> 31bb8507e6SMatthias Braun 32bb8507e6SMatthias Braun using namespace llvm; 33bb8507e6SMatthias Braun 34bb8507e6SMatthias Braun static TargetMachine *unwrap(LLVMTargetMachineRef P) { 35bb8507e6SMatthias Braun return reinterpret_cast<TargetMachine *>(P); 36bb8507e6SMatthias Braun } 37bb8507e6SMatthias Braun static Target *unwrap(LLVMTargetRef P) { 38bb8507e6SMatthias Braun return reinterpret_cast<Target*>(P); 39bb8507e6SMatthias Braun } 40bb8507e6SMatthias Braun static LLVMTargetMachineRef wrap(const TargetMachine *P) { 41bb8507e6SMatthias Braun return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P)); 42bb8507e6SMatthias Braun } 43bb8507e6SMatthias Braun static LLVMTargetRef wrap(const Target * P) { 44bb8507e6SMatthias Braun return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P)); 45bb8507e6SMatthias Braun } 46bb8507e6SMatthias Braun 47bb8507e6SMatthias Braun LLVMTargetRef LLVMGetFirstTarget() { 48bb8507e6SMatthias Braun if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) { 49bb8507e6SMatthias Braun return nullptr; 50bb8507e6SMatthias Braun } 51bb8507e6SMatthias Braun 52bb8507e6SMatthias Braun const Target *target = &*TargetRegistry::targets().begin(); 53bb8507e6SMatthias Braun return wrap(target); 54bb8507e6SMatthias Braun } 55bb8507e6SMatthias Braun LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) { 56bb8507e6SMatthias Braun return wrap(unwrap(T)->getNext()); 57bb8507e6SMatthias Braun } 58bb8507e6SMatthias Braun 59bb8507e6SMatthias Braun LLVMTargetRef LLVMGetTargetFromName(const char *Name) { 60bb8507e6SMatthias Braun StringRef NameRef = Name; 61bb8507e6SMatthias Braun auto I = find_if(TargetRegistry::targets(), 62bb8507e6SMatthias Braun [&](const Target &T) { return T.getName() == NameRef; }); 63bb8507e6SMatthias Braun return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr; 64bb8507e6SMatthias Braun } 65bb8507e6SMatthias Braun 66bb8507e6SMatthias Braun LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T, 67bb8507e6SMatthias Braun char **ErrorMessage) { 68bb8507e6SMatthias Braun std::string Error; 69bb8507e6SMatthias Braun 70bb8507e6SMatthias Braun *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error)); 71bb8507e6SMatthias Braun 72bb8507e6SMatthias Braun if (!*T) { 73bb8507e6SMatthias Braun if (ErrorMessage) 74bb8507e6SMatthias Braun *ErrorMessage = strdup(Error.c_str()); 75bb8507e6SMatthias Braun 76bb8507e6SMatthias Braun return 1; 77bb8507e6SMatthias Braun } 78bb8507e6SMatthias Braun 79bb8507e6SMatthias Braun return 0; 80bb8507e6SMatthias Braun } 81bb8507e6SMatthias Braun 82bb8507e6SMatthias Braun const char * LLVMGetTargetName(LLVMTargetRef T) { 83bb8507e6SMatthias Braun return unwrap(T)->getName(); 84bb8507e6SMatthias Braun } 85bb8507e6SMatthias Braun 86bb8507e6SMatthias Braun const char * LLVMGetTargetDescription(LLVMTargetRef T) { 87bb8507e6SMatthias Braun return unwrap(T)->getShortDescription(); 88bb8507e6SMatthias Braun } 89bb8507e6SMatthias Braun 90bb8507e6SMatthias Braun LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) { 91bb8507e6SMatthias Braun return unwrap(T)->hasJIT(); 92bb8507e6SMatthias Braun } 93bb8507e6SMatthias Braun 94bb8507e6SMatthias Braun LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) { 95bb8507e6SMatthias Braun return unwrap(T)->hasTargetMachine(); 96bb8507e6SMatthias Braun } 97bb8507e6SMatthias Braun 98bb8507e6SMatthias Braun LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) { 99bb8507e6SMatthias Braun return unwrap(T)->hasMCAsmBackend(); 100bb8507e6SMatthias Braun } 101bb8507e6SMatthias Braun 102bb8507e6SMatthias Braun LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, 103bb8507e6SMatthias Braun const char *Triple, const char *CPU, const char *Features, 104bb8507e6SMatthias Braun LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, 105bb8507e6SMatthias Braun LLVMCodeModel CodeModel) { 106bb8507e6SMatthias Braun Optional<Reloc::Model> RM; 107bb8507e6SMatthias Braun switch (Reloc){ 108bb8507e6SMatthias Braun case LLVMRelocStatic: 109bb8507e6SMatthias Braun RM = Reloc::Static; 110bb8507e6SMatthias Braun break; 111bb8507e6SMatthias Braun case LLVMRelocPIC: 112bb8507e6SMatthias Braun RM = Reloc::PIC_; 113bb8507e6SMatthias Braun break; 114bb8507e6SMatthias Braun case LLVMRelocDynamicNoPic: 115bb8507e6SMatthias Braun RM = Reloc::DynamicNoPIC; 116bb8507e6SMatthias Braun break; 117bb8507e6SMatthias Braun default: 118bb8507e6SMatthias Braun break; 119bb8507e6SMatthias Braun } 120bb8507e6SMatthias Braun 121bb8507e6SMatthias Braun bool JIT; 122bb8507e6SMatthias Braun Optional<CodeModel::Model> CM = unwrap(CodeModel, JIT); 123bb8507e6SMatthias Braun 124bb8507e6SMatthias Braun CodeGenOpt::Level OL; 125bb8507e6SMatthias Braun switch (Level) { 126bb8507e6SMatthias Braun case LLVMCodeGenLevelNone: 127bb8507e6SMatthias Braun OL = CodeGenOpt::None; 128bb8507e6SMatthias Braun break; 129bb8507e6SMatthias Braun case LLVMCodeGenLevelLess: 130bb8507e6SMatthias Braun OL = CodeGenOpt::Less; 131bb8507e6SMatthias Braun break; 132bb8507e6SMatthias Braun case LLVMCodeGenLevelAggressive: 133bb8507e6SMatthias Braun OL = CodeGenOpt::Aggressive; 134bb8507e6SMatthias Braun break; 135bb8507e6SMatthias Braun default: 136bb8507e6SMatthias Braun OL = CodeGenOpt::Default; 137bb8507e6SMatthias Braun break; 138bb8507e6SMatthias Braun } 139bb8507e6SMatthias Braun 140bb8507e6SMatthias Braun TargetOptions opt; 141bb8507e6SMatthias Braun return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM, 142bb8507e6SMatthias Braun OL, JIT)); 143bb8507e6SMatthias Braun } 144bb8507e6SMatthias Braun 145bb8507e6SMatthias Braun void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); } 146bb8507e6SMatthias Braun 147bb8507e6SMatthias Braun LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) { 148bb8507e6SMatthias Braun const Target* target = &(unwrap(T)->getTarget()); 149bb8507e6SMatthias Braun return wrap(target); 150bb8507e6SMatthias Braun } 151bb8507e6SMatthias Braun 152bb8507e6SMatthias Braun char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) { 153bb8507e6SMatthias Braun std::string StringRep = unwrap(T)->getTargetTriple().str(); 154bb8507e6SMatthias Braun return strdup(StringRep.c_str()); 155bb8507e6SMatthias Braun } 156bb8507e6SMatthias Braun 157bb8507e6SMatthias Braun char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) { 158bb8507e6SMatthias Braun std::string StringRep = unwrap(T)->getTargetCPU(); 159bb8507e6SMatthias Braun return strdup(StringRep.c_str()); 160bb8507e6SMatthias Braun } 161bb8507e6SMatthias Braun 162bb8507e6SMatthias Braun char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) { 163bb8507e6SMatthias Braun std::string StringRep = unwrap(T)->getTargetFeatureString(); 164bb8507e6SMatthias Braun return strdup(StringRep.c_str()); 165bb8507e6SMatthias Braun } 166bb8507e6SMatthias Braun 167bb8507e6SMatthias Braun void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T, 168bb8507e6SMatthias Braun LLVMBool VerboseAsm) { 169bb8507e6SMatthias Braun unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm; 170bb8507e6SMatthias Braun } 171bb8507e6SMatthias Braun 172bb8507e6SMatthias Braun LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) { 173bb8507e6SMatthias Braun return wrap(new DataLayout(unwrap(T)->createDataLayout())); 174bb8507e6SMatthias Braun } 175bb8507e6SMatthias Braun 176bb8507e6SMatthias Braun static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, 177bb8507e6SMatthias Braun raw_pwrite_stream &OS, 178bb8507e6SMatthias Braun LLVMCodeGenFileType codegen, 179bb8507e6SMatthias Braun char **ErrorMessage) { 180bb8507e6SMatthias Braun TargetMachine* TM = unwrap(T); 181bb8507e6SMatthias Braun Module* Mod = unwrap(M); 182bb8507e6SMatthias Braun 183bb8507e6SMatthias Braun legacy::PassManager pass; 184bb8507e6SMatthias Braun 185bb8507e6SMatthias Braun std::string error; 186bb8507e6SMatthias Braun 187bb8507e6SMatthias Braun Mod->setDataLayout(TM->createDataLayout()); 188bb8507e6SMatthias Braun 189bb8507e6SMatthias Braun TargetMachine::CodeGenFileType ft; 190bb8507e6SMatthias Braun switch (codegen) { 191bb8507e6SMatthias Braun case LLVMAssemblyFile: 192bb8507e6SMatthias Braun ft = TargetMachine::CGFT_AssemblyFile; 193bb8507e6SMatthias Braun break; 194bb8507e6SMatthias Braun default: 195bb8507e6SMatthias Braun ft = TargetMachine::CGFT_ObjectFile; 196bb8507e6SMatthias Braun break; 197bb8507e6SMatthias Braun } 198bb8507e6SMatthias Braun if (TM->addPassesToEmitFile(pass, OS, ft)) { 199bb8507e6SMatthias Braun error = "TargetMachine can't emit a file of this type"; 200bb8507e6SMatthias Braun *ErrorMessage = strdup(error.c_str()); 201bb8507e6SMatthias Braun return true; 202bb8507e6SMatthias Braun } 203bb8507e6SMatthias Braun 204bb8507e6SMatthias Braun pass.run(*Mod); 205bb8507e6SMatthias Braun 206bb8507e6SMatthias Braun OS.flush(); 207bb8507e6SMatthias Braun return false; 208bb8507e6SMatthias Braun } 209bb8507e6SMatthias Braun 210bb8507e6SMatthias Braun LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, 211bb8507e6SMatthias Braun char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { 212bb8507e6SMatthias Braun std::error_code EC; 213bb8507e6SMatthias Braun raw_fd_ostream dest(Filename, EC, sys::fs::F_None); 214bb8507e6SMatthias Braun if (EC) { 215bb8507e6SMatthias Braun *ErrorMessage = strdup(EC.message().c_str()); 216bb8507e6SMatthias Braun return true; 217bb8507e6SMatthias Braun } 218bb8507e6SMatthias Braun bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage); 219bb8507e6SMatthias Braun dest.flush(); 220bb8507e6SMatthias Braun return Result; 221bb8507e6SMatthias Braun } 222bb8507e6SMatthias Braun 223bb8507e6SMatthias Braun LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, 224bb8507e6SMatthias Braun LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage, 225bb8507e6SMatthias Braun LLVMMemoryBufferRef *OutMemBuf) { 226bb8507e6SMatthias Braun SmallString<0> CodeString; 227bb8507e6SMatthias Braun raw_svector_ostream OStream(CodeString); 228bb8507e6SMatthias Braun bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage); 229bb8507e6SMatthias Braun 230bb8507e6SMatthias Braun StringRef Data = OStream.str(); 231bb8507e6SMatthias Braun *OutMemBuf = 232bb8507e6SMatthias Braun LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), ""); 233bb8507e6SMatthias Braun return Result; 234bb8507e6SMatthias Braun } 235bb8507e6SMatthias Braun 236bb8507e6SMatthias Braun char *LLVMGetDefaultTargetTriple(void) { 237bb8507e6SMatthias Braun return strdup(sys::getDefaultTargetTriple().c_str()); 238bb8507e6SMatthias Braun } 239bb8507e6SMatthias Braun 240bb8507e6SMatthias Braun void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) { 241bb8507e6SMatthias Braun unwrap(PM)->add( 242bb8507e6SMatthias Braun createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis())); 243bb8507e6SMatthias Braun } 244