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