LLVM  4.0.0
OrcMCJITReplacement.cpp
Go to the documentation of this file.
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"
12 
13 namespace {
14 
15 static struct RegisterJIT {
16  RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
17 } JITRegistrator;
18 
19 }
20 
21 extern "C" void LLVMLinkInOrcMCJITReplacement() {}
22 
23 namespace llvm {
24 namespace orc {
25 
26 GenericValue
28  ArrayRef<GenericValue> ArgValues) {
29  assert(F && "Function *F was null at entry to run()");
30 
31  void *FPtr = getPointerToFunction(F);
32  assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
33  FunctionType *FTy = F->getFunctionType();
34  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  if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
45  switch (ArgValues.size()) {
46  case 3:
47  if (FTy->getParamType(0)->isIntegerTy(32) &&
48  FTy->getParamType(1)->isPointerTy() &&
49  FTy->getParamType(2)->isPointerTy()) {
50  int (*PF)(int, char **, const char **) =
51  (int (*)(int, char **, const char **))(intptr_t)FPtr;
52 
53  // Call the function.
54  GenericValue rv;
55  rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
56  (char **)GVTOP(ArgValues[1]),
57  (const char **)GVTOP(ArgValues[2])));
58  return rv;
59  }
60  break;
61  case 2:
62  if (FTy->getParamType(0)->isIntegerTy(32) &&
63  FTy->getParamType(1)->isPointerTy()) {
64  int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
65 
66  // Call the function.
67  GenericValue rv;
68  rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
69  (char **)GVTOP(ArgValues[1])));
70  return rv;
71  }
72  break;
73  case 1:
74  if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
75  GenericValue rv;
76  int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
77  rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
78  return rv;
79  }
80  break;
81  }
82  }
83 
84  // Handle cases where no arguments are passed first.
85  if (ArgValues.empty()) {
86  GenericValue rv;
87  switch (RetTy->getTypeID()) {
88  default:
89  llvm_unreachable("Unknown return type for function call!");
90  case Type::IntegerTyID: {
91  unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
92  if (BitWidth == 1)
93  rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
94  else if (BitWidth <= 8)
95  rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
96  else if (BitWidth <= 16)
97  rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
98  else if (BitWidth <= 32)
99  rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
100  else if (BitWidth <= 64)
101  rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
102  else
103  llvm_unreachable("Integer types > 64 bits not supported");
104  return rv;
105  }
106  case Type::VoidTyID:
107  rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
108  return rv;
109  case Type::FloatTyID:
110  rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
111  return rv;
112  case Type::DoubleTyID:
113  rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
114  return rv;
115  case Type::X86_FP80TyID:
116  case Type::FP128TyID:
117  case Type::PPC_FP128TyID:
118  llvm_unreachable("long double not supported yet");
119  case Type::PointerTyID:
120  return PTOGV(((void *(*)())(intptr_t)FPtr)());
121  }
122  }
123 
124  llvm_unreachable("Full-featured argument passing not supported yet!");
125 }
126 
127 } // End namespace orc.
128 } // End namespace llvm.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type (if unknown returns 0).
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:137
2: 32-bit floating point type
Definition: Type.h:58
4: 80-bit floating point type (X87)
Definition: Type.h:60
15: Pointers
Definition: Type.h:74
Class to represent function types.
Definition: DerivedTypes.h:102
#define F(x, y, z)
Definition: MD5.cpp:51
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:136
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
11: Arbitrary bit width integers
Definition: Type.h:70
GenericValue runFunction(Function *F, ArrayRef< GenericValue > ArgValues) override
runFunction - Execute the specified function with the specified arguments, and return the result...
0: type with no size
Definition: Type.h:56
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:133
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void LLVMLinkInOrcMCJITReplacement()
6: 128-bit floating point type (two 64-bits, PowerPC)
Definition: Type.h:62
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:136
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:213
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void * getPointerToFunction(Function *F) override
getPointerToFunction - The different EE's represent function bodies in different ways.
void * GVTOP(const GenericValue &GV)
Definition: GenericValue.h:51
GenericValue PTOGV(void *P)
Definition: GenericValue.h:50
Class for arbitrary precision integers.
Definition: APInt.h:77
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:195
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.cpp:230
bool isVarArg() const
Definition: DerivedTypes.h:122
3: 64-bit floating point type
Definition: Type.h:59
Type * getReturnType() const
Definition: DerivedTypes.h:123
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
5: 128-bit floating point type (112-bit mantissa)
Definition: Type.h:61