Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
35271 views
1
//===-- Interpreter.h ------------------------------------------*- C++ -*--===//
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
// This header file defines the interpreter structure
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H
14
#define LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H
15
16
#include "llvm/ExecutionEngine/ExecutionEngine.h"
17
#include "llvm/ExecutionEngine/GenericValue.h"
18
#include "llvm/IR/DataLayout.h"
19
#include "llvm/IR/Function.h"
20
#include "llvm/IR/InstVisitor.h"
21
#include "llvm/Support/DataTypes.h"
22
#include "llvm/Support/ErrorHandling.h"
23
#include "llvm/Support/raw_ostream.h"
24
namespace llvm {
25
26
class IntrinsicLowering;
27
template<typename T> class generic_gep_type_iterator;
28
class ConstantExpr;
29
typedef generic_gep_type_iterator<User::const_op_iterator> gep_type_iterator;
30
31
32
// AllocaHolder - Object to track all of the blocks of memory allocated by
33
// alloca. When the function returns, this object is popped off the execution
34
// stack, which causes the dtor to be run, which frees all the alloca'd memory.
35
//
36
class AllocaHolder {
37
std::vector<void *> Allocations;
38
39
public:
40
AllocaHolder() = default;
41
42
// Make this type move-only.
43
AllocaHolder(AllocaHolder &&) = default;
44
AllocaHolder &operator=(AllocaHolder &&RHS) = default;
45
46
~AllocaHolder() {
47
for (void *Allocation : Allocations)
48
free(Allocation);
49
}
50
51
void add(void *Mem) { Allocations.push_back(Mem); }
52
};
53
54
typedef std::vector<GenericValue> ValuePlaneTy;
55
56
// ExecutionContext struct - This struct represents one stack frame currently
57
// executing.
58
//
59
struct ExecutionContext {
60
Function *CurFunction;// The currently executing function
61
BasicBlock *CurBB; // The currently executing BB
62
BasicBlock::iterator CurInst; // The next instruction to execute
63
CallBase *Caller; // Holds the call that called subframes.
64
// NULL if main func or debugger invoked fn
65
std::map<Value *, GenericValue> Values; // LLVM values used in this invocation
66
std::vector<GenericValue> VarArgs; // Values passed through an ellipsis
67
AllocaHolder Allocas; // Track memory allocated by alloca
68
69
ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {}
70
};
71
72
// Interpreter - This class represents the entirety of the interpreter.
73
//
74
class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
75
GenericValue ExitValue; // The return value of the called function
76
IntrinsicLowering *IL;
77
78
// The runtime stack of executing code. The top of the stack is the current
79
// function record.
80
std::vector<ExecutionContext> ECStack;
81
82
// AtExitHandlers - List of functions to call when the program exits,
83
// registered with the atexit() library function.
84
std::vector<Function*> AtExitHandlers;
85
86
public:
87
explicit Interpreter(std::unique_ptr<Module> M);
88
~Interpreter() override;
89
90
/// runAtExitHandlers - Run any functions registered by the program's calls to
91
/// atexit(3), which we intercept and store in AtExitHandlers.
92
///
93
void runAtExitHandlers();
94
95
static void Register() {
96
InterpCtor = create;
97
}
98
99
/// Create an interpreter ExecutionEngine.
100
///
101
static ExecutionEngine *create(std::unique_ptr<Module> M,
102
std::string *ErrorStr = nullptr);
103
104
/// run - Start execution with the specified function and arguments.
105
///
106
GenericValue runFunction(Function *F,
107
ArrayRef<GenericValue> ArgValues) override;
108
109
void *getPointerToNamedFunction(StringRef Name,
110
bool AbortOnFailure = true) override {
111
// FIXME: not implemented.
112
return nullptr;
113
}
114
115
// Methods used to execute code:
116
// Place a call on the stack
117
void callFunction(Function *F, ArrayRef<GenericValue> ArgVals);
118
void run(); // Execute instructions until nothing left to do
119
120
// Opcode Implementations
121
void visitReturnInst(ReturnInst &I);
122
void visitBranchInst(BranchInst &I);
123
void visitSwitchInst(SwitchInst &I);
124
void visitIndirectBrInst(IndirectBrInst &I);
125
126
void visitUnaryOperator(UnaryOperator &I);
127
void visitBinaryOperator(BinaryOperator &I);
128
void visitICmpInst(ICmpInst &I);
129
void visitFCmpInst(FCmpInst &I);
130
void visitAllocaInst(AllocaInst &I);
131
void visitLoadInst(LoadInst &I);
132
void visitStoreInst(StoreInst &I);
133
void visitGetElementPtrInst(GetElementPtrInst &I);
134
void visitPHINode(PHINode &PN) {
135
llvm_unreachable("PHI nodes already handled!");
136
}
137
void visitTruncInst(TruncInst &I);
138
void visitZExtInst(ZExtInst &I);
139
void visitSExtInst(SExtInst &I);
140
void visitFPTruncInst(FPTruncInst &I);
141
void visitFPExtInst(FPExtInst &I);
142
void visitUIToFPInst(UIToFPInst &I);
143
void visitSIToFPInst(SIToFPInst &I);
144
void visitFPToUIInst(FPToUIInst &I);
145
void visitFPToSIInst(FPToSIInst &I);
146
void visitPtrToIntInst(PtrToIntInst &I);
147
void visitIntToPtrInst(IntToPtrInst &I);
148
void visitBitCastInst(BitCastInst &I);
149
void visitSelectInst(SelectInst &I);
150
151
void visitVAStartInst(VAStartInst &I);
152
void visitVAEndInst(VAEndInst &I);
153
void visitVACopyInst(VACopyInst &I);
154
void visitIntrinsicInst(IntrinsicInst &I);
155
void visitCallBase(CallBase &I);
156
void visitUnreachableInst(UnreachableInst &I);
157
158
void visitShl(BinaryOperator &I);
159
void visitLShr(BinaryOperator &I);
160
void visitAShr(BinaryOperator &I);
161
162
void visitVAArgInst(VAArgInst &I);
163
void visitExtractElementInst(ExtractElementInst &I);
164
void visitInsertElementInst(InsertElementInst &I);
165
void visitShuffleVectorInst(ShuffleVectorInst &I);
166
167
void visitExtractValueInst(ExtractValueInst &I);
168
void visitInsertValueInst(InsertValueInst &I);
169
170
void visitInstruction(Instruction &I) {
171
errs() << I << "\n";
172
llvm_unreachable("Instruction not interpretable yet!");
173
}
174
175
GenericValue callExternalFunction(Function *F,
176
ArrayRef<GenericValue> ArgVals);
177
void exitCalled(GenericValue GV);
178
179
void addAtExitHandler(Function *F) {
180
AtExitHandlers.push_back(F);
181
}
182
183
GenericValue *getFirstVarArg () {
184
return &(ECStack.back ().VarArgs[0]);
185
}
186
187
private: // Helper functions
188
GenericValue executeGEPOperation(Value *Ptr, gep_type_iterator I,
189
gep_type_iterator E, ExecutionContext &SF);
190
191
// SwitchToNewBasicBlock - Start execution in a new basic block and run any
192
// PHI nodes in the top of the block. This is used for intraprocedural
193
// control flow.
194
//
195
void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF);
196
197
void *getPointerToFunction(Function *F) override { return (void*)F; }
198
199
void initializeExecutionEngine() { }
200
void initializeExternalFunctions();
201
GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF);
202
GenericValue getOperandValue(Value *V, ExecutionContext &SF);
203
GenericValue executeTruncInst(Value *SrcVal, Type *DstTy,
204
ExecutionContext &SF);
205
GenericValue executeSExtInst(Value *SrcVal, Type *DstTy,
206
ExecutionContext &SF);
207
GenericValue executeZExtInst(Value *SrcVal, Type *DstTy,
208
ExecutionContext &SF);
209
GenericValue executeFPTruncInst(Value *SrcVal, Type *DstTy,
210
ExecutionContext &SF);
211
GenericValue executeFPExtInst(Value *SrcVal, Type *DstTy,
212
ExecutionContext &SF);
213
GenericValue executeFPToUIInst(Value *SrcVal, Type *DstTy,
214
ExecutionContext &SF);
215
GenericValue executeFPToSIInst(Value *SrcVal, Type *DstTy,
216
ExecutionContext &SF);
217
GenericValue executeUIToFPInst(Value *SrcVal, Type *DstTy,
218
ExecutionContext &SF);
219
GenericValue executeSIToFPInst(Value *SrcVal, Type *DstTy,
220
ExecutionContext &SF);
221
GenericValue executePtrToIntInst(Value *SrcVal, Type *DstTy,
222
ExecutionContext &SF);
223
GenericValue executeIntToPtrInst(Value *SrcVal, Type *DstTy,
224
ExecutionContext &SF);
225
GenericValue executeBitCastInst(Value *SrcVal, Type *DstTy,
226
ExecutionContext &SF);
227
void popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result);
228
229
};
230
231
} // End llvm namespace
232
233
#endif
234
235