X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FExecutionEngine%2FInterpreter%2FInterpreter.h;h=0dc0463903d4d4606c7ef6296d126ee66cae32ac;hp=e45b4c644751cfccbdd068f270fee9637fc32d9d;hb=c16fc548515f2fd01bc2cbe4befd822a636cc154;hpb=8c9191c644cf8c3aceac8e0d1ddc72273355588c diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index e45b4c64475..0dc0463903d 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -11,20 +11,21 @@ // //===----------------------------------------------------------------------===// -#ifndef LLI_INTERPRETER_H -#define LLI_INTERPRETER_H +#ifndef LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H +#define LLVM_LIB_EXECUTIONENGINE_INTERPRETER_INTERPRETER_H -#include "llvm/Function.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/Support/InstVisitor.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Target/TargetData.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstVisitor.h" #include "llvm/Support/DataTypes.h" -#include - +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { +class IntrinsicLowering; struct FunctionInfo; template class generic_gep_type_iterator; class ConstantExpr; @@ -36,29 +37,24 @@ typedef generic_gep_type_iterator gep_type_iterator; // stack, which causes the dtor to be run, which frees all the alloca'd memory. // class AllocaHolder { - friend class AllocaHolderHandle; - std::vector Allocations; - unsigned RefCnt; + std::vector Allocations; + public: - AllocaHolder() : RefCnt(0) {} - void add(void *mem) { Allocations.push_back(mem); } - ~AllocaHolder() { - for (unsigned i = 0; i < Allocations.size(); ++i) - free(Allocations[i]); + AllocaHolder() {} + + // Make this type move-only. Define explicit move special members for MSVC. + AllocaHolder(AllocaHolder &&RHS) : Allocations(std::move(RHS.Allocations)) {} + AllocaHolder &operator=(AllocaHolder &&RHS) { + Allocations = std::move(RHS.Allocations); + return *this; } -}; -// AllocaHolderHandle gives AllocaHolder value semantics so we can stick it into -// a vector... -// -class AllocaHolderHandle { - AllocaHolder *H; -public: - AllocaHolderHandle() : H(new AllocaHolder()) { H->RefCnt++; } - AllocaHolderHandle(const AllocaHolderHandle &AH) : H(AH.H) { H->RefCnt++; } - ~AllocaHolderHandle() { if (--H->RefCnt == 0) delete H; } + ~AllocaHolder() { + for (void *Allocation : Allocations) + free(Allocation); + } - void add(void *mem) { H->add(mem); } + void add(void *Mem) { Allocations.push_back(Mem); } }; typedef std::vector ValuePlaneTy; @@ -70,18 +66,36 @@ struct ExecutionContext { Function *CurFunction;// The currently executing function BasicBlock *CurBB; // The currently executing BB BasicBlock::iterator CurInst; // The next instruction to execute - std::map Values; // LLVM values used in this invocation - std::vector VarArgs; // Values passed through an ellipsis CallSite Caller; // Holds the call that called subframes. // NULL if main func or debugger invoked fn - AllocaHolderHandle Allocas; // Track memory allocated by alloca + std::map Values; // LLVM values used in this invocation + std::vector VarArgs; // Values passed through an ellipsis + AllocaHolder Allocas; // Track memory allocated by alloca + + ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {} + + ExecutionContext(ExecutionContext &&O) + : CurFunction(O.CurFunction), CurBB(O.CurBB), CurInst(O.CurInst), + Caller(O.Caller), Values(std::move(O.Values)), + VarArgs(std::move(O.VarArgs)), Allocas(std::move(O.Allocas)) {} + + ExecutionContext &operator=(ExecutionContext &&O) { + CurFunction = O.CurFunction; + CurBB = O.CurBB; + CurInst = O.CurInst; + Caller = O.Caller; + Values = std::move(O.Values); + VarArgs = std::move(O.VarArgs); + Allocas = std::move(O.Allocas); + return *this; + } }; // Interpreter - This class represents the entirety of the interpreter. // class Interpreter : public ExecutionEngine, public InstVisitor { GenericValue ExitValue; // The return value of the called function - TargetData TD; + DataLayout TD; IntrinsicLowering *IL; // The runtime stack of executing code. The top of the stack is the current @@ -93,37 +107,34 @@ class Interpreter : public ExecutionEngine, public InstVisitor { std::vector AtExitHandlers; public: - Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, - IntrinsicLowering *IL); - ~Interpreter(); + explicit Interpreter(std::unique_ptr M); + ~Interpreter() override; /// runAtExitHandlers - Run any functions registered by the program's calls to /// atexit(3), which we intercept and store in AtExitHandlers. /// void runAtExitHandlers(); - /// create - Create an interpreter ExecutionEngine. This can never fail. The - /// specified IntrinsicLowering implementation will be deleted when the - /// Interpreter execution engine is destroyed. + static void Register() { + InterpCtor = create; + } + + /// Create an interpreter ExecutionEngine. /// - static ExecutionEngine *create(Module *M, IntrinsicLowering *IL); + static ExecutionEngine *create(std::unique_ptr M, + std::string *ErrorStr = nullptr); /// run - Start execution with the specified function and arguments. /// - virtual GenericValue runFunction(Function *F, - const std::vector &ArgValues); + GenericValue runFunction(Function *F, + const std::vector &ArgValues) override; - /// recompileAndRelinkFunction - For the interpreter, functions are always - /// up-to-date. - /// - virtual void *recompileAndRelinkFunction(Function *F) { - return getPointerToFunction(F); + void *getPointerToNamedFunction(StringRef Name, + bool AbortOnFailure = true) override { + // FIXME: not implemented. + return nullptr; } - /// freeMachineCodeForFunction - The interpreter does not generate any code. - /// - void freeMachineCodeForFunction(Function *F) { } - // Methods used to execute code: // Place a call on the stack void callFunction(Function *F, const std::vector &ArgVals); @@ -133,30 +144,53 @@ public: void visitReturnInst(ReturnInst &I); void visitBranchInst(BranchInst &I); void visitSwitchInst(SwitchInst &I); + void visitIndirectBrInst(IndirectBrInst &I); void visitBinaryOperator(BinaryOperator &I); - void visitAllocationInst(AllocationInst &I); - void visitFreeInst(FreeInst &I); + void visitICmpInst(ICmpInst &I); + void visitFCmpInst(FCmpInst &I); + void visitAllocaInst(AllocaInst &I); void visitLoadInst(LoadInst &I); void visitStoreInst(StoreInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); - void visitPHINode(PHINode &PN) { assert(0 && "PHI nodes already handled!"); } - void visitCastInst(CastInst &I); + void visitPHINode(PHINode &PN) { + llvm_unreachable("PHI nodes already handled!"); + } + void visitTruncInst(TruncInst &I); + void visitZExtInst(ZExtInst &I); + void visitSExtInst(SExtInst &I); + void visitFPTruncInst(FPTruncInst &I); + void visitFPExtInst(FPExtInst &I); + void visitUIToFPInst(UIToFPInst &I); + void visitSIToFPInst(SIToFPInst &I); + void visitFPToUIInst(FPToUIInst &I); + void visitFPToSIInst(FPToSIInst &I); + void visitPtrToIntInst(PtrToIntInst &I); + void visitIntToPtrInst(IntToPtrInst &I); + void visitBitCastInst(BitCastInst &I); void visitSelectInst(SelectInst &I); void visitCallSite(CallSite CS); void visitCallInst(CallInst &I) { visitCallSite (CallSite (&I)); } void visitInvokeInst(InvokeInst &I) { visitCallSite (CallSite (&I)); } - void visitUnwindInst(UnwindInst &I); void visitUnreachableInst(UnreachableInst &I); - void visitShl(ShiftInst &I); - void visitShr(ShiftInst &I); + void visitShl(BinaryOperator &I); + void visitLShr(BinaryOperator &I); + void visitAShr(BinaryOperator &I); + void visitVAArgInst(VAArgInst &I); + void visitExtractElementInst(ExtractElementInst &I); + void visitInsertElementInst(InsertElementInst &I); + void visitShuffleVectorInst(ShuffleVectorInst &I); + + void visitExtractValueInst(ExtractValueInst &I); + void visitInsertValueInst(InsertValueInst &I); + void visitInstruction(Instruction &I) { - std::cerr << I; - assert(0 && "Instruction not interpretable yet!"); + errs() << I << "\n"; + llvm_unreachable("Instruction not interpretable yet!"); } GenericValue callExternalFunction(Function *F, @@ -171,27 +205,50 @@ public: return &(ECStack.back ().VarArgs[0]); } - //FIXME: private: -public: +private: // Helper functions GenericValue executeGEPOperation(Value *Ptr, gep_type_iterator I, gep_type_iterator E, ExecutionContext &SF); -private: // Helper functions // SwitchToNewBasicBlock - Start execution in a new basic block and run any // PHI nodes in the top of the block. This is used for intraprocedural // control flow. // void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF); - void *getPointerToFunction(Function *F) { return (void*)F; } + void *getPointerToFunction(Function *F) override { return (void*)F; } - void initializeExecutionEngine(); + void initializeExecutionEngine() { } void initializeExternalFunctions(); GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF); GenericValue getOperandValue(Value *V, ExecutionContext &SF); - GenericValue executeCastOperation(Value *SrcVal, const Type *Ty, - ExecutionContext &SF); - void popStackAndReturnValueToCaller(const Type *RetTy, GenericValue Result); + GenericValue executeTruncInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeSExtInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeZExtInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeFPTruncInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeFPExtInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeFPToUIInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeFPToSIInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeUIToFPInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeSIToFPInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executePtrToIntInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeIntToPtrInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeBitCastInst(Value *SrcVal, Type *DstTy, + ExecutionContext &SF); + GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal, + Type *Ty, ExecutionContext &SF); + void popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result); + }; } // End llvm namespace