Interpreter.h revision d7916e988c544b2ab6af26b723b6bc340ecb78cc
192101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner//===-- Interpreter.h ------------------------------------------*- C++ -*--===// 292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// 392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// This header file defines the interpreter structure 492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// 592101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner//===----------------------------------------------------------------------===// 692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner#ifndef LLI_INTERPRETER_H 892101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner#define LLI_INTERPRETER_H 992101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 10e2409064715ac156ead333a039107b6e14548050Chris Lattner// Uncomment this line to enable profiling of structure field accesses. 11849735ce226b656af9e34193c88e70bb53f4b49cChris Lattner//#define PROFILE_STRUCTURE_FIELDS 1 12e2409064715ac156ead333a039107b6e14548050Chris Lattner 13fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner#include "../ExecutionEngine.h" 14d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner#include "../GenericValue.h" 15360e17eaf1a2abda82b02235dc57d26d8f83c937Chris Lattner#include "Support/DataTypes.h" 165af0c4803b7064938dabc4c7275dcfb231e814aeChris Lattner#include "llvm/Assembly/CachedWriter.h" 17fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner#include "llvm/Target/TargetData.h" 18fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner#include "llvm/BasicBlock.h" 19d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner#include "llvm/Support/InstVisitor.h" 205af0c4803b7064938dabc4c7275dcfb231e814aeChris Lattner 21fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattnerextern CachedWriter CW; // Object to accelerate printing of LLVM 2292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 23da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattnerstruct FunctionInfo; // Defined in ExecutionAnnotations.h 2492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 259bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner// AllocaHolder - Object to track all of the blocks of memory allocated by 269bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner// alloca. When the function returns, this object is poped off the execution 279bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner// stack, which causes the dtor to be run, which frees all the alloca'd memory. 289bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner// 299bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattnerclass AllocaHolder { 309bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner friend class AllocaHolderHandle; 319bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner std::vector<void*> Allocations; 329bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner unsigned RefCnt; 339bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattnerpublic: 349bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner AllocaHolder() : RefCnt(0) {} 359bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner void add(void *mem) { Allocations.push_back(mem); } 369bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner ~AllocaHolder() { 379bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner for (unsigned i = 0; i < Allocations.size(); ++i) 389bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner free(Allocations[i]); 399bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner } 409bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner}; 419bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner 429bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner// AllocaHolderHandle gives AllocaHolder value semantics so we can stick it into 439bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner// a vector... 449bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner// 459bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattnerclass AllocaHolderHandle { 469bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner AllocaHolder *H; 479bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattnerpublic: 489bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner AllocaHolderHandle() : H(new AllocaHolder()) { H->RefCnt++; } 499bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner AllocaHolderHandle(const AllocaHolderHandle &AH) : H(AH.H) { H->RefCnt++; } 509bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner ~AllocaHolderHandle() { if (--H->RefCnt == 0) delete H; } 519bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner 529bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner void add(void *mem) { H->add(mem); } 539bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner}; 549bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner 55697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnertypedef std::vector<GenericValue> ValuePlaneTy; 5692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 5792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// ExecutionContext struct - This struct represents one stack frame currently 5892101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// executing. 5992101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// 6092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattnerstruct ExecutionContext { 61da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner Function *CurFunction;// The currently executing function 6292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner BasicBlock *CurBB; // The currently executing BB 6392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner BasicBlock::iterator CurInst; // The next instruction to execute 64da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner FunctionInfo *FuncInfo; // The FuncInfo annotation for the function 65697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::vector<ValuePlaneTy> Values;// ValuePlanes for each type 66cdf5178f8362b0b415a4e1c1378a5b76638826beChris Lattner std::vector<GenericValue> VarArgs; // Values passed through an ellipsis 6792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 6892101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner CallInst *Caller; // Holds the call that called subframes. 6992101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // NULL if main func or debugger invoked fn 709bffa73530b3712b42f6e6bddf21f22b8aba276dChris Lattner AllocaHolderHandle Allocas; // Track memory allocated by alloca 7192101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner}; 7292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 7392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// Interpreter - This class represents the entirety of the interpreter. 7492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner// 75d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattnerclass Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> { 7692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner int ExitCode; // The exit code to be returned by the lli util 77fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner bool Debug; // Debug mode enabled? 7892101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner bool Profile; // Profiling enabled? 7943e3f7c9627d0793a31a9457d3bbbe4d8d56d331Chris Lattner bool Trace; // Tracing enabled? 8092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner int CurFrame; // The current stack frame being inspected 81fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner TargetData TD; 8292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 8392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // The runtime stack of executing code. The top of the stack is the current 842fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // function record. 85697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::vector<ExecutionContext> ECStack; 8692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 8792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattnerpublic: 88fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner Interpreter(Module *M, unsigned Config, bool DebugMode, bool TraceMode); 89fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner inline ~Interpreter() { CW.setModule(0); } 9092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 9192101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // getExitCode - return the code that should be the exit code for the lli 9292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // utility. 9392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner inline int getExitCode() const { return ExitCode; } 94fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner 95fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner /// run - Start execution with the specified function and arguments. 96fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner /// 97fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner virtual int run(const std::string &FnName, 98fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner const std::vector<std::string> &Args); 99fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner 10092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 10192101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // enableProfiling() - Turn profiling on, clear stats? 10292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void enableProfiling() { Profile = true; } 10343e3f7c9627d0793a31a9457d3bbbe4d8d56d331Chris Lattner void enableTracing() { Trace = true; } 10492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 10592101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void handleUserInput(); 10692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 10792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // User Interation Methods... 108da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner bool callFunction(const std::string &Name); // return true on failure 109697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner void setBreakpoint(const std::string &Name); 110697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner void infoValue(const std::string &Name); 111697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner void print(const std::string &Name); 1122e42d3a3060ff0c3d4c419f17493bc6a7683e9d0Chris Lattner static void print(const Type *Ty, GenericValue V); 113365a76e46e7b22ee2cd7881d0a7055fc20930fd5Chris Lattner static void printValue(const Type *Ty, GenericValue V); 11492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 115da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner bool callMainFunction(const std::string &MainName, 116da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner const std::vector<std::string> &InputFilename); 11792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 11892101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void list(); // Do the 'list' command 11992101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void printStackTrace(); // Do the 'backtrace' command 12092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 12192101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // Code execution methods... 122da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner void callFunction(Function *F, const std::vector<GenericValue> &ArgVals); 12392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner bool executeInstruction(); // Execute one instruction... 12492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 12592101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void stepInstruction(); // Do the 'step' command 12692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void nextInstruction(); // Do the 'next' command 12792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void run(); // Do the 'run' command 12892101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void finish(); // Do the 'finish' command 12992101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 13092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // Opcode Implementations 131d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitReturnInst(ReturnInst &I); 132d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitBranchInst(BranchInst &I); 133d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitSwitchInst(SwitchInst &I); 134d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner 135d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitBinaryOperator(BinaryOperator &I); 136d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitAllocationInst(AllocationInst &I); 137d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitFreeInst(FreeInst &I); 138d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitLoadInst(LoadInst &I); 139d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitStoreInst(StoreInst &I); 140d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitGetElementPtrInst(GetElementPtrInst &I); 141d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner 142d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitPHINode(PHINode &PN) { assert(0 && "PHI nodes already handled!"); } 143d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitCastInst(CastInst &I); 144d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitCallInst(CallInst &I); 145d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitShl(ShiftInst &I); 146d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitShr(ShiftInst &I); 147d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitVarArgInst(VarArgInst &I); 148d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner void visitInstruction(Instruction &I) { 149d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner std::cerr << I; 150d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner assert(0 && "Instruction not interpretable yet!"); 151d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner } 152d7916e988c544b2ab6af26b723b6bc340ecb78ccChris Lattner 153da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner GenericValue callExternalFunction(Function *F, 154da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner const std::vector<GenericValue> &ArgVals); 155e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner void exitCalled(GenericValue GV); 15692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 157da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner // getCurrentFunction - Return the currently executing function 158da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner inline Function *getCurrentFunction() const { 159da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner return CurFrame < 0 ? 0 : ECStack[CurFrame].CurFunction; 16092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner } 16192101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 16292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // isStopped - Return true if a program is stopped. Return false if no 16392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // program is running. 16492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // 16592101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner inline bool isStopped() const { return !ECStack.empty(); } 16692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 167fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner //FIXME: private: 168fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattnerpublic: 169fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner GenericValue executeGEPOperation(Value *Ptr, User::op_iterator I, 170fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner User::op_iterator E, ExecutionContext &SF); 171fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner 17292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattnerprivate: // Helper functions 17377113b627237fe2850676cccd809de1e05f03952Chris Lattner // SwitchToNewBasicBlock - Start execution in a new basic block and run any 17477113b627237fe2850676cccd809de1e05f03952Chris Lattner // PHI nodes in the top of the block. This is used for intraprocedural 17577113b627237fe2850676cccd809de1e05f03952Chris Lattner // control flow. 17677113b627237fe2850676cccd809de1e05f03952Chris Lattner // 17777113b627237fe2850676cccd809de1e05f03952Chris Lattner void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF); 17877113b627237fe2850676cccd809de1e05f03952Chris Lattner 179fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner void *getPointerToFunction(const Function *F) { return (void*)F; } 180fe11a97fcde7c63109c3ad36570657807d0cd6efChris Lattner 181e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner // getCurrentExecutablePath() - Return the directory that the lli executable 182e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner // lives in. 183e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner // 184697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::string getCurrentExecutablePath() const; 185e43db88b2d12f2aebbe62aca8465a46c92292fceChris Lattner 18692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // printCurrentInstruction - Print out the instruction that the virtual PC is 18792101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // at, or fail silently if no program is running. 18892101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // 18992101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner void printCurrentInstruction(); 19092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 191461f02fc1914d4382d6df52061220443d6b9259bChris Lattner // printStackFrame - Print information about the specified stack frame, or -1 192461f02fc1914d4382d6df52061220443d6b9259bChris Lattner // for the default one. 193461f02fc1914d4382d6df52061220443d6b9259bChris Lattner // 194461f02fc1914d4382d6df52061220443d6b9259bChris Lattner void printStackFrame(int FrameNo = -1); 195461f02fc1914d4382d6df52061220443d6b9259bChris Lattner 1962fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // LookupMatchingNames - Search the current function namespace, then the 1972fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // global namespace looking for values that match the specified name. Return 1982fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // ALL matches to that name. This is obviously slow, and should only be used 1992fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner // for user interaction. 20092101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // 201697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::vector<Value*> LookupMatchingNames(const std::string &Name); 20292101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 20392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // ChooseOneOption - Prompt the user to choose among the specified options to 20492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // pick one value. If no options are provided, emit an error. If a single 20592101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // option is provided, just return that option. 20692101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner // 207697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner Value *ChooseOneOption(const std::string &Name, 208697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner const std::vector<Value*> &Opts); 2095deea3c5c5d71acf140b0df9488126e3c67e4a0aChris Lattner 2105deea3c5c5d71acf140b0df9488126e3c67e4a0aChris Lattner 2115deea3c5c5d71acf140b0df9488126e3c67e4a0aChris Lattner void initializeExecutionEngine(); 212da82ed52ac02497d343b898cca0bb2cf303f062dChris Lattner void initializeExternalFunctions(); 21392101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner}; 21492101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner 21592101acd7fd44fd467fbeb974ae6c042289c74f9Chris Lattner#endif 216