LLVM  8.0.1
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
27 OrcMCJITReplacement::runFunction(Function *F,
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 void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) {
128  auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors;
129 
130  for (auto &KV : CtorDtorsMap)
131  cantFail(LegacyCtorDtorRunner<LazyEmitLayerT>(std::move(KV.second), KV.first)
132  .runViaLayer(LazyEmitLayer));
133 
134  CtorDtorsMap.clear();
135 }
136 
137 } // End namespace orc.
138 } // End namespace llvm.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:704
This class represents lattice values for constants.
Definition: AllocatorList.h:24
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:135
Convenience class for recording constructor/destructor names for later execution. ...
F(f)
TypeID getTypeID() const
Return the type id for the type.
Definition: Type.h:138
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:197
Class to represent function types.
Definition: DerivedTypes.h:103
const Type::TypeID FloatTyID
bool isVarArg() const
Definition: DerivedTypes.h:123
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:141
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
void LLVMLinkInOrcMCJITReplacement()
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:224
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:139
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void * GVTOP(const GenericValue &GV)
Definition: GenericValue.h:51
Type * getReturnType() const
Definition: DerivedTypes.h:124
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:164
GenericValue PTOGV(void *P)
Definition: GenericValue.h:50
Class for arbitrary precision integers.
Definition: APInt.h:70
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const Type::TypeID DoubleTyID
Error runViaLayer(JITLayerT &JITLayer) const
Run the recorded constructors/destructors through the given JIT layer.
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144