LCOV - code coverage report
Current view: top level - lib/ExecutionEngine/Orc - OrcMCJITReplacement.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 48 66 72.7 %
Date: 2017-09-14 15:23:50 Functions: 3 4 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
       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             : #include "OrcMCJITReplacement.h"
      11             : #include "llvm/ExecutionEngine/GenericValue.h"
      12             : 
      13             : namespace {
      14             : 
      15             : static struct RegisterJIT {
      16             :   RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
      17       72306 : } JITRegistrator;
      18             : 
      19             : }
      20             : 
      21           0 : extern "C" void LLVMLinkInOrcMCJITReplacement() {}
      22             : 
      23             : namespace llvm {
      24             : namespace orc {
      25             : 
      26             : GenericValue
      27         131 : OrcMCJITReplacement::runFunction(Function *F,
      28             :                                  ArrayRef<GenericValue> ArgValues) {
      29             :   assert(F && "Function *F was null at entry to run()");
      30             : 
      31         131 :   void *FPtr = getPointerToFunction(F);
      32             :   assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
      33         131 :   FunctionType *FTy = F->getFunctionType();
      34         131 :   Type *RetTy = FTy->getReturnType();
      35             : 
      36             :   assert((FTy->getNumParams() == ArgValues.size() ||
      37             :           (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
      38             :          "Wrong number of arguments passed into function!");
      39             :   assert(FTy->getNumParams() == ArgValues.size() &&
      40             :          "This doesn't support passing arguments through varargs (yet)!");
      41             : 
      42             :   // Handle some common cases first.  These cases correspond to common `main'
      43             :   // prototypes.
      44         197 :   if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
      45         131 :     switch (ArgValues.size()) {
      46           1 :     case 3:
      47           3 :       if (FTy->getParamType(0)->isIntegerTy(32) &&
      48           4 :           FTy->getParamType(1)->isPointerTy() &&
      49           3 :           FTy->getParamType(2)->isPointerTy()) {
      50           1 :         int (*PF)(int, char **, const char **) =
      51             :             (int (*)(int, char **, const char **))(intptr_t)FPtr;
      52             : 
      53             :         // Call the function.
      54           2 :         GenericValue rv;
      55           5 :         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
      56           1 :                                  (char **)GVTOP(ArgValues[1]),
      57           1 :                                  (const char **)GVTOP(ArgValues[2])));
      58           1 :         return rv;
      59             :       }
      60             :       break;
      61           5 :     case 2:
      62          15 :       if (FTy->getParamType(0)->isIntegerTy(32) &&
      63          15 :           FTy->getParamType(1)->isPointerTy()) {
      64           5 :         int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
      65             : 
      66             :         // Call the function.
      67          10 :         GenericValue rv;
      68          25 :         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
      69           5 :                                  (char **)GVTOP(ArgValues[1])));
      70           5 :         return rv;
      71             :       }
      72             :       break;
      73          66 :     case 1:
      74         132 :       if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
      75          68 :         GenericValue rv;
      76          66 :         int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
      77         138 :         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
      78           2 :         return rv;
      79             :       }
      80             :       break;
      81             :     }
      82             :   }
      83             : 
      84             :   // Handle cases where no arguments are passed first.
      85          59 :   if (ArgValues.empty()) {
      86         117 :     GenericValue rv;
      87          59 :     switch (RetTy->getTypeID()) {
      88           0 :     default:
      89           0 :       llvm_unreachable("Unknown return type for function call!");
      90          57 :     case Type::IntegerTyID: {
      91         114 :       unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
      92          57 :       if (BitWidth == 1)
      93           0 :         rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
      94          57 :       else if (BitWidth <= 8)
      95           0 :         rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
      96          57 :       else if (BitWidth <= 16)
      97           0 :         rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
      98          57 :       else if (BitWidth <= 32)
      99         225 :         rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
     100           0 :       else if (BitWidth <= 64)
     101           0 :         rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
     102             :       else
     103           0 :         llvm_unreachable("Integer types > 64 bits not supported");
     104             :       return rv;
     105             :     }
     106           2 :     case Type::VoidTyID:
     107           8 :       rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
     108             :       return rv;
     109           0 :     case Type::FloatTyID:
     110           0 :       rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
     111             :       return rv;
     112           0 :     case Type::DoubleTyID:
     113           0 :       rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
     114             :       return rv;
     115           0 :     case Type::X86_FP80TyID:
     116             :     case Type::FP128TyID:
     117             :     case Type::PPC_FP128TyID:
     118           0 :       llvm_unreachable("long double not supported yet");
     119           0 :     case Type::PointerTyID:
     120           0 :       return PTOGV(((void *(*)())(intptr_t)FPtr)());
     121             :     }
     122             :   }
     123             : 
     124           0 :   llvm_unreachable("Full-featured argument passing not supported yet!");
     125             : }
     126             : 
     127         129 : void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) {
     128         665 :   for (auto &M : LocalModules)
     129         298 :     ExecutionEngine::runStaticConstructorsDestructors(*M, isDtors);
     130         129 : }
     131             : 
     132             : } // End namespace orc.
     133      144612 : } // End namespace llvm.

Generated by: LCOV version 1.13