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