1 //===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "OrcMCJITReplacement.h"
10 #include "llvm/ExecutionEngine/GenericValue.h"
14 static struct RegisterJIT
{
15 RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
20 extern "C" void LLVMLinkInOrcMCJITReplacement() {}
26 OrcMCJITReplacement::runFunction(Function
*F
,
27 ArrayRef
<GenericValue
> ArgValues
) {
28 assert(F
&& "Function *F was null at entry to run()");
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();
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)!");
41 // Handle some common cases first. These cases correspond to common `main'
43 if (RetTy
->isIntegerTy(32) || RetTy
->isVoidTy()) {
44 switch (ArgValues
.size()) {
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
;
54 rv
.IntVal
= APInt(32, PF(ArgValues
[0].IntVal
.getZExtValue(),
55 (char **)GVTOP(ArgValues
[1]),
56 (const char **)GVTOP(ArgValues
[2])));
61 if (FTy
->getParamType(0)->isIntegerTy(32) &&
62 FTy
->getParamType(1)->isPointerTy()) {
63 int (*PF
)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr
;
67 rv
.IntVal
= APInt(32, PF(ArgValues
[0].IntVal
.getZExtValue(),
68 (char **)GVTOP(ArgValues
[1])));
73 if (FTy
->getNumParams() == 1 && FTy
->getParamType(0)->isIntegerTy(32)) {
75 int (*PF
)(int) = (int (*)(int))(intptr_t)FPtr
;
76 rv
.IntVal
= APInt(32, PF(ArgValues
[0].IntVal
.getZExtValue()));
83 // Handle cases where no arguments are passed first.
84 if (ArgValues
.empty()) {
86 switch (RetTy
->getTypeID()) {
88 llvm_unreachable("Unknown return type for function call!");
89 case Type::IntegerTyID
: {
90 unsigned BitWidth
= cast
<IntegerType
>(RetTy
)->getBitWidth();
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
)());
102 llvm_unreachable("Integer types > 64 bits not supported");
106 rv
.IntVal
= APInt(32, ((int (*)())(intptr_t)FPtr
)());
108 case Type::FloatTyID
:
109 rv
.FloatVal
= ((float (*)())(intptr_t)FPtr
)();
111 case Type::DoubleTyID
:
112 rv
.DoubleVal
= ((double (*)())(intptr_t)FPtr
)();
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
)());
123 llvm_unreachable("Full-featured argument passing not supported yet!");
126 void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors
) {
127 auto &CtorDtorsMap
= isDtors
? UnexecutedDestructors
: UnexecutedConstructors
;
129 for (auto &KV
: CtorDtorsMap
)
130 cantFail(LegacyCtorDtorRunner
<LazyEmitLayerT
>(
131 AcknowledgeORCv1Deprecation
, std::move(KV
.second
), KV
.first
)
132 .runViaLayer(LazyEmitLayer
));
134 CtorDtorsMap
.clear();
137 } // End namespace orc.
138 } // End namespace llvm.