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