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