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