10b57cec5SDimitry Andric //===-- Interpreter.h ------------------------------------------*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This header file defines the interpreter structure 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H 140b57cec5SDimitry Andric #define LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ExecutionEngine/ExecutionEngine.h" 170b57cec5SDimitry Andric #include "llvm/ExecutionEngine/GenericValue.h" 180b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 190b57cec5SDimitry Andric #include "llvm/IR/Function.h" 200b57cec5SDimitry Andric #include "llvm/IR/InstVisitor.h" 210b57cec5SDimitry Andric #include "llvm/Support/DataTypes.h" 220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 230b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 240b57cec5SDimitry Andric namespace llvm { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class IntrinsicLowering; 270b57cec5SDimitry Andric template<typename T> class generic_gep_type_iterator; 280b57cec5SDimitry Andric class ConstantExpr; 290b57cec5SDimitry Andric typedef generic_gep_type_iterator<User::const_op_iterator> gep_type_iterator; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric // AllocaHolder - Object to track all of the blocks of memory allocated by 330b57cec5SDimitry Andric // alloca. When the function returns, this object is popped off the execution 340b57cec5SDimitry Andric // stack, which causes the dtor to be run, which frees all the alloca'd memory. 350b57cec5SDimitry Andric // 360b57cec5SDimitry Andric class AllocaHolder { 370b57cec5SDimitry Andric std::vector<void *> Allocations; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric public: 40*81ad6265SDimitry Andric AllocaHolder() = default; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric // Make this type move-only. 430b57cec5SDimitry Andric AllocaHolder(AllocaHolder &&) = default; 440b57cec5SDimitry Andric AllocaHolder &operator=(AllocaHolder &&RHS) = default; 450b57cec5SDimitry Andric ~AllocaHolder()460b57cec5SDimitry Andric ~AllocaHolder() { 470b57cec5SDimitry Andric for (void *Allocation : Allocations) 480b57cec5SDimitry Andric free(Allocation); 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric add(void * Mem)510b57cec5SDimitry Andric void add(void *Mem) { Allocations.push_back(Mem); } 520b57cec5SDimitry Andric }; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric typedef std::vector<GenericValue> ValuePlaneTy; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric // ExecutionContext struct - This struct represents one stack frame currently 570b57cec5SDimitry Andric // executing. 580b57cec5SDimitry Andric // 590b57cec5SDimitry Andric struct ExecutionContext { 600b57cec5SDimitry Andric Function *CurFunction;// The currently executing function 610b57cec5SDimitry Andric BasicBlock *CurBB; // The currently executing BB 620b57cec5SDimitry Andric BasicBlock::iterator CurInst; // The next instruction to execute 635ffd83dbSDimitry Andric CallBase *Caller; // Holds the call that called subframes. 640b57cec5SDimitry Andric // NULL if main func or debugger invoked fn 650b57cec5SDimitry Andric std::map<Value *, GenericValue> Values; // LLVM values used in this invocation 660b57cec5SDimitry Andric std::vector<GenericValue> VarArgs; // Values passed through an ellipsis 670b57cec5SDimitry Andric AllocaHolder Allocas; // Track memory allocated by alloca 680b57cec5SDimitry Andric ExecutionContextExecutionContext690b57cec5SDimitry Andric ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {} 700b57cec5SDimitry Andric }; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // Interpreter - This class represents the entirety of the interpreter. 730b57cec5SDimitry Andric // 740b57cec5SDimitry Andric class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> { 750b57cec5SDimitry Andric GenericValue ExitValue; // The return value of the called function 760b57cec5SDimitry Andric IntrinsicLowering *IL; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric // The runtime stack of executing code. The top of the stack is the current 790b57cec5SDimitry Andric // function record. 800b57cec5SDimitry Andric std::vector<ExecutionContext> ECStack; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric // AtExitHandlers - List of functions to call when the program exits, 830b57cec5SDimitry Andric // registered with the atexit() library function. 840b57cec5SDimitry Andric std::vector<Function*> AtExitHandlers; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric public: 870b57cec5SDimitry Andric explicit Interpreter(std::unique_ptr<Module> M); 880b57cec5SDimitry Andric ~Interpreter() override; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric /// runAtExitHandlers - Run any functions registered by the program's calls to 910b57cec5SDimitry Andric /// atexit(3), which we intercept and store in AtExitHandlers. 920b57cec5SDimitry Andric /// 930b57cec5SDimitry Andric void runAtExitHandlers(); 940b57cec5SDimitry Andric Register()950b57cec5SDimitry Andric static void Register() { 960b57cec5SDimitry Andric InterpCtor = create; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric /// Create an interpreter ExecutionEngine. 1000b57cec5SDimitry Andric /// 1010b57cec5SDimitry Andric static ExecutionEngine *create(std::unique_ptr<Module> M, 1020b57cec5SDimitry Andric std::string *ErrorStr = nullptr); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric /// run - Start execution with the specified function and arguments. 1050b57cec5SDimitry Andric /// 1060b57cec5SDimitry Andric GenericValue runFunction(Function *F, 1070b57cec5SDimitry Andric ArrayRef<GenericValue> ArgValues) override; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric void *getPointerToNamedFunction(StringRef Name, 1100b57cec5SDimitry Andric bool AbortOnFailure = true) override { 1110b57cec5SDimitry Andric // FIXME: not implemented. 1120b57cec5SDimitry Andric return nullptr; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric // Methods used to execute code: 1160b57cec5SDimitry Andric // Place a call on the stack 1170b57cec5SDimitry Andric void callFunction(Function *F, ArrayRef<GenericValue> ArgVals); 1180b57cec5SDimitry Andric void run(); // Execute instructions until nothing left to do 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric // Opcode Implementations 1210b57cec5SDimitry Andric void visitReturnInst(ReturnInst &I); 1220b57cec5SDimitry Andric void visitBranchInst(BranchInst &I); 1230b57cec5SDimitry Andric void visitSwitchInst(SwitchInst &I); 1240b57cec5SDimitry Andric void visitIndirectBrInst(IndirectBrInst &I); 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric void visitUnaryOperator(UnaryOperator &I); 1270b57cec5SDimitry Andric void visitBinaryOperator(BinaryOperator &I); 1280b57cec5SDimitry Andric void visitICmpInst(ICmpInst &I); 1290b57cec5SDimitry Andric void visitFCmpInst(FCmpInst &I); 1300b57cec5SDimitry Andric void visitAllocaInst(AllocaInst &I); 1310b57cec5SDimitry Andric void visitLoadInst(LoadInst &I); 1320b57cec5SDimitry Andric void visitStoreInst(StoreInst &I); 1330b57cec5SDimitry Andric void visitGetElementPtrInst(GetElementPtrInst &I); visitPHINode(PHINode & PN)1340b57cec5SDimitry Andric void visitPHINode(PHINode &PN) { 1350b57cec5SDimitry Andric llvm_unreachable("PHI nodes already handled!"); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric void visitTruncInst(TruncInst &I); 1380b57cec5SDimitry Andric void visitZExtInst(ZExtInst &I); 1390b57cec5SDimitry Andric void visitSExtInst(SExtInst &I); 1400b57cec5SDimitry Andric void visitFPTruncInst(FPTruncInst &I); 1410b57cec5SDimitry Andric void visitFPExtInst(FPExtInst &I); 1420b57cec5SDimitry Andric void visitUIToFPInst(UIToFPInst &I); 1430b57cec5SDimitry Andric void visitSIToFPInst(SIToFPInst &I); 1440b57cec5SDimitry Andric void visitFPToUIInst(FPToUIInst &I); 1450b57cec5SDimitry Andric void visitFPToSIInst(FPToSIInst &I); 1460b57cec5SDimitry Andric void visitPtrToIntInst(PtrToIntInst &I); 1470b57cec5SDimitry Andric void visitIntToPtrInst(IntToPtrInst &I); 1480b57cec5SDimitry Andric void visitBitCastInst(BitCastInst &I); 1490b57cec5SDimitry Andric void visitSelectInst(SelectInst &I); 1500b57cec5SDimitry Andric 1515ffd83dbSDimitry Andric void visitVAStartInst(VAStartInst &I); 1525ffd83dbSDimitry Andric void visitVAEndInst(VAEndInst &I); 1535ffd83dbSDimitry Andric void visitVACopyInst(VACopyInst &I); 1545ffd83dbSDimitry Andric void visitIntrinsicInst(IntrinsicInst &I); 1555ffd83dbSDimitry Andric void visitCallBase(CallBase &I); 1560b57cec5SDimitry Andric void visitUnreachableInst(UnreachableInst &I); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric void visitShl(BinaryOperator &I); 1590b57cec5SDimitry Andric void visitLShr(BinaryOperator &I); 1600b57cec5SDimitry Andric void visitAShr(BinaryOperator &I); 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric void visitVAArgInst(VAArgInst &I); 1630b57cec5SDimitry Andric void visitExtractElementInst(ExtractElementInst &I); 1640b57cec5SDimitry Andric void visitInsertElementInst(InsertElementInst &I); 1650b57cec5SDimitry Andric void visitShuffleVectorInst(ShuffleVectorInst &I); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric void visitExtractValueInst(ExtractValueInst &I); 1680b57cec5SDimitry Andric void visitInsertValueInst(InsertValueInst &I); 1690b57cec5SDimitry Andric visitInstruction(Instruction & I)1700b57cec5SDimitry Andric void visitInstruction(Instruction &I) { 1710b57cec5SDimitry Andric errs() << I << "\n"; 1720b57cec5SDimitry Andric llvm_unreachable("Instruction not interpretable yet!"); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric GenericValue callExternalFunction(Function *F, 1760b57cec5SDimitry Andric ArrayRef<GenericValue> ArgVals); 1770b57cec5SDimitry Andric void exitCalled(GenericValue GV); 1780b57cec5SDimitry Andric addAtExitHandler(Function * F)1790b57cec5SDimitry Andric void addAtExitHandler(Function *F) { 1800b57cec5SDimitry Andric AtExitHandlers.push_back(F); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric getFirstVarArg()1830b57cec5SDimitry Andric GenericValue *getFirstVarArg () { 1840b57cec5SDimitry Andric return &(ECStack.back ().VarArgs[0]); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric private: // Helper functions 1880b57cec5SDimitry Andric GenericValue executeGEPOperation(Value *Ptr, gep_type_iterator I, 1890b57cec5SDimitry Andric gep_type_iterator E, ExecutionContext &SF); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric // SwitchToNewBasicBlock - Start execution in a new basic block and run any 1920b57cec5SDimitry Andric // PHI nodes in the top of the block. This is used for intraprocedural 1930b57cec5SDimitry Andric // control flow. 1940b57cec5SDimitry Andric // 1950b57cec5SDimitry Andric void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF); 1960b57cec5SDimitry Andric getPointerToFunction(Function * F)1970b57cec5SDimitry Andric void *getPointerToFunction(Function *F) override { return (void*)F; } 1980b57cec5SDimitry Andric initializeExecutionEngine()1990b57cec5SDimitry Andric void initializeExecutionEngine() { } 2000b57cec5SDimitry Andric void initializeExternalFunctions(); 2010b57cec5SDimitry Andric GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF); 2020b57cec5SDimitry Andric GenericValue getOperandValue(Value *V, ExecutionContext &SF); 2030b57cec5SDimitry Andric GenericValue executeTruncInst(Value *SrcVal, Type *DstTy, 2040b57cec5SDimitry Andric ExecutionContext &SF); 2050b57cec5SDimitry Andric GenericValue executeSExtInst(Value *SrcVal, Type *DstTy, 2060b57cec5SDimitry Andric ExecutionContext &SF); 2070b57cec5SDimitry Andric GenericValue executeZExtInst(Value *SrcVal, Type *DstTy, 2080b57cec5SDimitry Andric ExecutionContext &SF); 2090b57cec5SDimitry Andric GenericValue executeFPTruncInst(Value *SrcVal, Type *DstTy, 2100b57cec5SDimitry Andric ExecutionContext &SF); 2110b57cec5SDimitry Andric GenericValue executeFPExtInst(Value *SrcVal, Type *DstTy, 2120b57cec5SDimitry Andric ExecutionContext &SF); 2130b57cec5SDimitry Andric GenericValue executeFPToUIInst(Value *SrcVal, Type *DstTy, 2140b57cec5SDimitry Andric ExecutionContext &SF); 2150b57cec5SDimitry Andric GenericValue executeFPToSIInst(Value *SrcVal, Type *DstTy, 2160b57cec5SDimitry Andric ExecutionContext &SF); 2170b57cec5SDimitry Andric GenericValue executeUIToFPInst(Value *SrcVal, Type *DstTy, 2180b57cec5SDimitry Andric ExecutionContext &SF); 2190b57cec5SDimitry Andric GenericValue executeSIToFPInst(Value *SrcVal, Type *DstTy, 2200b57cec5SDimitry Andric ExecutionContext &SF); 2210b57cec5SDimitry Andric GenericValue executePtrToIntInst(Value *SrcVal, Type *DstTy, 2220b57cec5SDimitry Andric ExecutionContext &SF); 2230b57cec5SDimitry Andric GenericValue executeIntToPtrInst(Value *SrcVal, Type *DstTy, 2240b57cec5SDimitry Andric ExecutionContext &SF); 2250b57cec5SDimitry Andric GenericValue executeBitCastInst(Value *SrcVal, Type *DstTy, 2260b57cec5SDimitry Andric ExecutionContext &SF); 2270b57cec5SDimitry Andric void popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result); 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric }; 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric } // End llvm namespace 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric #endif 234