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 0 : RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
17 : } JITRegistrator;
18 :
19 : }
20 :
21 0 : extern "C" void LLVMLinkInOrcMCJITReplacement() {}
22 :
23 : namespace llvm {
24 : namespace orc {
25 :
26 : GenericValue
27 129 : OrcMCJITReplacement::runFunction(Function *F,
28 : ArrayRef<GenericValue> ArgValues) {
29 : assert(F && "Function *F was null at entry to run()");
30 :
31 129 : void *FPtr = getPointerToFunction(F);
32 : assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
33 : FunctionType *FTy = F->getFunctionType();
34 129 : 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 129 : if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
45 129 : switch (ArgValues.size()) {
46 1 : case 3:
47 3 : if (FTy->getParamType(0)->isIntegerTy(32) &&
48 1 : FTy->getParamType(1)->isPointerTy() &&
49 : 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 1 : GenericValue rv;
55 2 : rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
56 1 : (char **)GVTOP(ArgValues[1]),
57 1 : (const char **)GVTOP(ArgValues[2])));
58 : return rv;
59 : }
60 : break;
61 5 : case 2:
62 10 : if (FTy->getParamType(0)->isIntegerTy(32) &&
63 5 : FTy->getParamType(1)->isPointerTy()) {
64 5 : int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
65 :
66 : // Call the function.
67 5 : GenericValue rv;
68 10 : rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
69 5 : (char **)GVTOP(ArgValues[1])));
70 : return rv;
71 : }
72 : break;
73 66 : case 1:
74 66 : if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
75 2 : GenericValue rv;
76 66 : int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
77 68 : 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 57 : if (ArgValues.empty()) {
86 56 : GenericValue rv;
87 57 : switch (RetTy->getTypeID()) {
88 0 : default:
89 0 : llvm_unreachable("Unknown return type for function call!");
90 : case Type::IntegerTyID: {
91 : 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 113 : 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 0 : case Type::VoidTyID:
107 0 : 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 : case Type::X86_FP80TyID:
116 : case Type::FP128TyID:
117 : case Type::PPC_FP128TyID:
118 : 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 129 : auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors;
129 :
130 278 : for (auto &KV : CtorDtorsMap)
131 298 : cantFail(LegacyCtorDtorRunner<LazyEmitLayerT>(std::move(KV.second), KV.first)
132 298 : .runViaLayer(LazyEmitLayer));
133 :
134 : CtorDtorsMap.clear();
135 129 : }
136 :
137 : } // End namespace orc.
138 : } // End namespace llvm.
|