LLVM  9.0.0svn
OrcMCJITReplacement.cpp
Go to the documentation of this file.
1 //===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "OrcMCJITReplacement.h"
11 
12 namespace {
13 
14 static struct RegisterJIT {
15  RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
16 } JITRegistrator;
17 
18 }
19 
20 extern "C" void LLVMLinkInOrcMCJITReplacement() {}
21 
22 namespace llvm {
23 namespace orc {
24 
25 GenericValue
26 OrcMCJITReplacement::runFunction(Function *F,
27  ArrayRef<GenericValue> ArgValues) {
28  assert(F && "Function *F was null at entry to run()");
29 
30  void *FPtr = getPointerToFunction(F);
31  assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
32  FunctionType *FTy = F->getFunctionType();
33  Type *RetTy = FTy->getReturnType();
34 
35  assert((FTy->getNumParams() == ArgValues.size() ||
36  (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
37  "Wrong number of arguments passed into function!");
38  assert(FTy->getNumParams() == ArgValues.size() &&
39  "This doesn't support passing arguments through varargs (yet)!");
40 
41  // Handle some common cases first. These cases correspond to common `main'
42  // prototypes.
43  if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
44  switch (ArgValues.size()) {
45  case 3:
46  if (FTy->getParamType(0)->isIntegerTy(32) &&
47  FTy->getParamType(1)->isPointerTy() &&
48  FTy->getParamType(2)->isPointerTy()) {
49  int (*PF)(int, char **, const char **) =
50  (int (*)(int, char **, const char **))(intptr_t)FPtr;
51 
52  // Call the function.
53  GenericValue rv;
54  rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
55  (char **)GVTOP(ArgValues[1]),
56  (const char **)GVTOP(ArgValues[2])));
57  return rv;
58  }
59  break;
60  case 2:
61  if (FTy->getParamType(0)->isIntegerTy(32) &&
62  FTy->getParamType(1)->isPointerTy()) {
63  int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
64 
65  // Call the function.
66  GenericValue rv;
67  rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
68  (char **)GVTOP(ArgValues[1])));
69  return rv;
70  }
71  break;
72  case 1:
73  if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
74  GenericValue rv;
75  int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
76  rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
77  return rv;
78  }
79  break;
80  }
81  }
82 
83  // Handle cases where no arguments are passed first.
84  if (ArgValues.empty()) {
85  GenericValue rv;
86  switch (RetTy->getTypeID()) {
87  default:
88  llvm_unreachable("Unknown return type for function call!");
89  case Type::IntegerTyID: {
90  unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
91  if (BitWidth == 1)
92  rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
93  else if (BitWidth <= 8)
94  rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
95  else if (BitWidth <= 16)
96  rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
97  else if (BitWidth <= 32)
98  rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
99  else if (BitWidth <= 64)
100  rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
101  else
102  llvm_unreachable("Integer types > 64 bits not supported");
103  return rv;
104  }
105  case Type::VoidTyID:
106  rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
107  return rv;
108  case Type::FloatTyID:
109  rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
110  return rv;
111  case Type::DoubleTyID:
112  rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
113  return rv;
114  case Type::X86_FP80TyID:
115  case Type::FP128TyID:
116  case Type::PPC_FP128TyID:
117  llvm_unreachable("long double not supported yet");
118  case Type::PointerTyID:
119  return PTOGV(((void *(*)())(intptr_t)FPtr)());
120  }
121  }
122 
123  llvm_unreachable("Full-featured argument passing not supported yet!");
124 }
125 
126 void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) {
127  auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors;
128 
129  for (auto &KV : CtorDtorsMap)
130  cantFail(LegacyCtorDtorRunner<LazyEmitLayerT>(std::move(KV.second), KV.first)
131  .runViaLayer(LazyEmitLayer));
132 
133  CtorDtorsMap.clear();
134 }
135 
136 } // End namespace orc.
137 } // 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:703
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:134
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:137
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:196
Class to represent function types.
Definition: DerivedTypes.h:102
const Type::TypeID FloatTyID
bool isVarArg() const
Definition: DerivedTypes.h:122
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:140
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void LLVMLinkInOrcMCJITReplacement()
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:223
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:138
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void * GVTOP(const GenericValue &GV)
Definition: GenericValue.h:50
Type * getReturnType() const
Definition: DerivedTypes.h:123
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:163
GenericValue PTOGV(void *P)
Definition: GenericValue.h:49
Class for arbitrary precision integers.
Definition: APInt.h:69
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:143