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