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