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