TargetMachineC.cpp revision 263508
1101100Ssos//===-- TargetMachine.cpp -------------------------------------------------===// 2101100Ssos// 3101100Ssos// The LLVM Compiler Infrastructure 4101100Ssos// 5101100Ssos// This file is distributed under the University of Illinois Open Source 6101100Ssos// License. See LICENSE.TXT for details. 7101100Ssos// 8101100Ssos//===----------------------------------------------------------------------===// 9101100Ssos// 10101100Ssos// This file implements the LLVM-C part of TargetMachine.h 11101100Ssos// 12101100Ssos//===----------------------------------------------------------------------===// 13101100Ssos 14101100Ssos#include "llvm-c/TargetMachine.h" 15101100Ssos#include "llvm-c/Core.h" 16101100Ssos#include "llvm-c/Target.h" 17101100Ssos#include "llvm/IR/DataLayout.h" 18101100Ssos#include "llvm/IR/Module.h" 19101100Ssos#include "llvm/PassManager.h" 20101100Ssos#include "llvm/Support/CodeGen.h" 21101100Ssos#include "llvm/Support/FormattedStream.h" 22101100Ssos#include "llvm/Support/TargetRegistry.h" 23101100Ssos#include "llvm/Support/raw_ostream.h" 24101100Ssos#include "llvm/Support/Host.h" 25101100Ssos#include "llvm/Target/TargetMachine.h" 26101100Ssos#include <cassert> 27101100Ssos#include <cstdlib> 28101100Ssos#include <cstring> 29101100Ssos 30101100Ssosusing namespace llvm; 31101100Ssos 32101100Ssosinline DataLayout *unwrap(LLVMTargetDataRef P) { 33101100Ssos return reinterpret_cast<DataLayout*>(P); 34101100Ssos} 35101100Ssos 36101100Ssosinline LLVMTargetDataRef wrap(const DataLayout *P) { 37101100Ssos return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P)); 38101100Ssos} 39101100Ssos 40101100Ssosinline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) { 41101100Ssos return reinterpret_cast<TargetLibraryInfo*>(P); 42101100Ssos} 43101100Ssos 44101100Ssosinline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) { 45101100Ssos TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P); 46101100Ssos return reinterpret_cast<LLVMTargetLibraryInfoRef>(X); 47101100Ssos} 48101100Ssos 49101100Ssosinline TargetMachine *unwrap(LLVMTargetMachineRef P) { 50101100Ssos return reinterpret_cast<TargetMachine*>(P); 51101100Ssos} 52101100Ssosinline Target *unwrap(LLVMTargetRef P) { 53101100Ssos return reinterpret_cast<Target*>(P); 54101100Ssos} 55102058Ssosinline LLVMTargetMachineRef wrap(const TargetMachine *P) { 56102058Ssos return 57102058Ssos reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P)); 58102058Ssos} 59102058Ssosinline LLVMTargetRef wrap(const Target * P) { 60102058Ssos return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P)); 61102058Ssos} 62101100Ssos 63101100SsosLLVMTargetRef LLVMGetFirstTarget() { 64101100Ssos if(TargetRegistry::begin() == TargetRegistry::end()) { 65101100Ssos return NULL; 66101100Ssos } 67101100Ssos 68101100Ssos const Target* target = &*TargetRegistry::begin(); 69101100Ssos return wrap(target); 70101100Ssos} 71101100SsosLLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) { 72111472Sphk return wrap(unwrap(T)->getNext()); 73101100Ssos} 74101100Ssos 75101100SsosLLVMTargetRef LLVMGetTargetFromName(const char *Name) { 76101100Ssos StringRef NameRef = Name; 77101100Ssos for (TargetRegistry::iterator IT = TargetRegistry::begin(), 78101100Ssos IE = TargetRegistry::end(); IT != IE; ++IT) { 79101100Ssos if (IT->getName() == NameRef) 80101100Ssos return wrap(&*IT); 81101100Ssos } 82101100Ssos 83101100Ssos return NULL; 84101100Ssos} 85101100Ssos 86101100SsosLLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T, 87101100Ssos char **ErrorMessage) { 88101100Ssos std::string Error; 89101100Ssos 90101100Ssos *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error)); 91101100Ssos 92101100Ssos if (!*T) { 93111472Sphk if (ErrorMessage) 94111472Sphk *ErrorMessage = strdup(Error.c_str()); 95111472Sphk 96111472Sphk return 1; 97111472Sphk } 98101100Ssos 99101100Ssos return 0; 100101100Ssos} 101101100Ssos 102101100Ssosconst char * LLVMGetTargetName(LLVMTargetRef T) { 103101100Ssos return unwrap(T)->getName(); 104101100Ssos} 105101100Ssos 106101100Ssosconst char * LLVMGetTargetDescription(LLVMTargetRef T) { 107101100Ssos return unwrap(T)->getShortDescription(); 108101100Ssos} 109101100Ssos 110101100SsosLLVMBool LLVMTargetHasJIT(LLVMTargetRef T) { 111101100Ssos return unwrap(T)->hasJIT(); 112101100Ssos} 113101100Ssos 114101100SsosLLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) { 115101100Ssos return unwrap(T)->hasTargetMachine(); 116101100Ssos} 117101100Ssos 118101100SsosLLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) { 119101100Ssos return unwrap(T)->hasMCAsmBackend(); 120101100Ssos} 121101100Ssos 122101100SsosLLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T, 123101100Ssos const char* Triple, const char* CPU, const char* Features, 124101100Ssos LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc, 125101100Ssos LLVMCodeModel CodeModel) { 126101100Ssos Reloc::Model RM; 127101100Ssos switch (Reloc){ 128101100Ssos case LLVMRelocStatic: 129101100Ssos RM = Reloc::Static; 130101100Ssos break; 131101100Ssos case LLVMRelocPIC: 132101100Ssos RM = Reloc::PIC_; 133101100Ssos break; 134101100Ssos case LLVMRelocDynamicNoPic: 135101100Ssos RM = Reloc::DynamicNoPIC; 136101100Ssos break; 137101100Ssos default: 138101100Ssos RM = Reloc::Default; 139101100Ssos break; 140101100Ssos } 141101100Ssos 142101100Ssos CodeModel::Model CM = unwrap(CodeModel); 143101100Ssos 144101100Ssos CodeGenOpt::Level OL; 145101100Ssos switch (Level) { 146101100Ssos case LLVMCodeGenLevelNone: 147101100Ssos OL = CodeGenOpt::None; 148101100Ssos break; 149101100Ssos case LLVMCodeGenLevelLess: 150101100Ssos OL = CodeGenOpt::Less; 151101100Ssos break; 152101100Ssos case LLVMCodeGenLevelAggressive: 153101100Ssos OL = CodeGenOpt::Aggressive; 154111472Sphk break; 155111472Sphk default: 156111472Sphk OL = CodeGenOpt::Default; 157111472Sphk break; 158111472Sphk } 159101100Ssos 160103714Sphk TargetOptions opt; 161103714Sphk return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, 162104066Ssos CM, OL)); 163104066Ssos} 164101100Ssos 165104066Ssos 166104066Ssosvoid LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { 167104066Ssos delete unwrap(T); 168101100Ssos} 169101100Ssos 170101100SsosLLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) { 171101100Ssos const Target* target = &(unwrap(T)->getTarget()); 172101100Ssos return wrap(target); 173101100Ssos} 174101100Ssos 175101100Ssoschar* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) { 176101100Ssos std::string StringRep = unwrap(T)->getTargetTriple(); 177101100Ssos return strdup(StringRep.c_str()); 178101100Ssos} 179101100Ssos 180101100Ssoschar* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) { 181101100Ssos std::string StringRep = unwrap(T)->getTargetCPU(); 182101100Ssos return strdup(StringRep.c_str()); 183101100Ssos} 184101100Ssos 185101100Ssoschar* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) { 186101100Ssos std::string StringRep = unwrap(T)->getTargetFeatureString(); 187101100Ssos return strdup(StringRep.c_str()); 188101100Ssos} 189101100Ssos 190101100SsosLLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) { 191101100Ssos return wrap(unwrap(T)->getDataLayout()); 192101100Ssos} 193101100Ssos 194101100Ssosvoid LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T, 195101100Ssos LLVMBool VerboseAsm) { 196101100Ssos unwrap(T)->setAsmVerbosityDefault(VerboseAsm); 197101100Ssos} 198101100Ssos 199101100Ssosstatic LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, 200111472Sphk formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) { 201101100Ssos TargetMachine* TM = unwrap(T); 202101100Ssos Module* Mod = unwrap(M); 203101100Ssos 204101100Ssos PassManager pass; 205101100Ssos 206101100Ssos std::string error; 207101100Ssos 208101100Ssos const DataLayout* td = TM->getDataLayout(); 209101100Ssos 210101100Ssos if (!td) { 211101100Ssos error = "No DataLayout in TargetMachine"; 212101100Ssos *ErrorMessage = strdup(error.c_str()); 213101100Ssos return true; 214101100Ssos } 215101100Ssos pass.add(new DataLayout(*td)); 216101100Ssos 217101100Ssos TargetMachine::CodeGenFileType ft; 218101100Ssos switch (codegen) { 219101100Ssos case LLVMAssemblyFile: 220101100Ssos ft = TargetMachine::CGFT_AssemblyFile; 221101100Ssos break; 222101100Ssos default: 223101100Ssos ft = TargetMachine::CGFT_ObjectFile; 224101100Ssos break; 225101100Ssos } 226101100Ssos if (TM->addPassesToEmitFile(pass, OS, ft)) { 227101100Ssos error = "TargetMachine can't emit a file of this type"; 228101100Ssos *ErrorMessage = strdup(error.c_str()); 229101100Ssos return true; 230101100Ssos } 231101100Ssos 232102058Ssos pass.run(*Mod); 233101100Ssos 234101100Ssos OS.flush(); 235111979Sphk return false; 236101100Ssos} 237101100Ssos 238101100SsosLLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M, 239101100Ssos char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) { 240101100Ssos std::string error; 241101100Ssos raw_fd_ostream dest(Filename, error, sys::fs::F_Binary); 242101100Ssos if (!error.empty()) { 243101100Ssos *ErrorMessage = strdup(error.c_str()); 244101100Ssos return true; 245101100Ssos } 246101100Ssos formatted_raw_ostream destf(dest); 247101100Ssos bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage); 248101100Ssos dest.flush(); 249101100Ssos return Result; 250101100Ssos} 251101100Ssos 252101100SsosLLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, 253111979Sphk LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage, 254101100Ssos LLVMMemoryBufferRef *OutMemBuf) { 255101100Ssos std::string CodeString; 256101100Ssos raw_string_ostream OStream(CodeString); 257101100Ssos formatted_raw_ostream Out(OStream); 258101100Ssos bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage); 259101100Ssos OStream.flush(); 260101100Ssos 261101100Ssos std::string &Data = OStream.str(); 262101100Ssos *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(), 263101100Ssos Data.length(), ""); 264101100Ssos return Result; 265101100Ssos} 266101100Ssos 267101100Ssoschar *LLVMGetDefaultTargetTriple(void) { 268101100Ssos return strdup(sys::getDefaultTargetTriple().c_str()); 269101100Ssos} 270101100Ssos