[llvm-commits] CVS: llvm/tools/lli/Interpreter/Execution.cpp Interpreter.h

Chris Lattner lattner at cs.uiuc.edu
Sat May 10 16:23:01 PDT 2003


Changes in directory llvm/tools/lli/Interpreter:

Execution.cpp updated: 1.88 -> 1.89
Interpreter.h updated: 1.28 -> 1.29

---
Log message:

switch main LLI core execution to use an InstVisitor instead of a switch statement


---
Diffs of the changes:

Index: llvm/tools/lli/Interpreter/Execution.cpp
diff -u llvm/tools/lli/Interpreter/Execution.cpp:1.88 llvm/tools/lli/Interpreter/Execution.cpp:1.89
--- llvm/tools/lli/Interpreter/Execution.cpp:1.88	Sat May 10 15:21:16 2003
+++ llvm/tools/lli/Interpreter/Execution.cpp	Sat May 10 16:22:39 2003
@@ -486,7 +486,8 @@
   return Dest;
 }
 
-static void executeBinaryInst(BinaryOperator &I, ExecutionContext &SF) {
+void Interpreter::visitBinaryOperator(BinaryOperator &I) {
+  ExecutionContext &SF = ECStack.back();
   const Type *Ty    = I.getOperand(0)->getType();
   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
@@ -577,7 +578,8 @@
   PerformExitStuff();
 }
 
-void Interpreter::executeRetInst(ReturnInst &I, ExecutionContext &SF) {
+void Interpreter::visitReturnInst(ReturnInst &I) {
+  ExecutionContext &SF = ECStack.back();
   const Type *RetTy = 0;
   GenericValue Result;
 
@@ -631,7 +633,8 @@
   }
 }
 
-void Interpreter::executeBrInst(BranchInst &I, ExecutionContext &SF) {
+void Interpreter::visitBranchInst(BranchInst &I) {
+  ExecutionContext &SF = ECStack.back();
   BasicBlock *Dest;
 
   Dest = I.getSuccessor(0);          // Uncond branches have a fixed dest...
@@ -643,7 +646,8 @@
   SwitchToNewBasicBlock(Dest, SF);
 }
 
-void Interpreter::executeSwitchInst(SwitchInst &I, ExecutionContext &SF) {
+void Interpreter::visitSwitchInst(SwitchInst &I) {
+  ExecutionContext &SF = ECStack.back();
   GenericValue CondVal = getOperandValue(I.getOperand(0), SF);
   const Type *ElTy = I.getOperand(0)->getType();
 
@@ -681,6 +685,8 @@
   std::vector<GenericValue> ResultValues;
 
   for (; PHINode *PN = dyn_cast<PHINode>(SF.CurInst); ++SF.CurInst) {
+    if (Trace) CW << "Run:" << PN;
+
     // Search for the value corresponding to this previous bb...
     int i = PN->getBasicBlockIndex(PrevBB);
     assert(i != -1 && "PHINode doesn't contain entry for predecessor??");
@@ -702,7 +708,9 @@
 //                     Memory Instruction Implementations
 //===----------------------------------------------------------------------===//
 
-void Interpreter::executeAllocInst(AllocationInst &I, ExecutionContext &SF) {
+void Interpreter::visitAllocationInst(AllocationInst &I) {
+  ExecutionContext &SF = ECStack.back();
+
   const Type *Ty = I.getType()->getElementType();  // Type to be allocated
 
   // Get the number of elements being allocated by the array...
@@ -720,7 +728,8 @@
     ECStack.back().Allocas.add(Memory);
 }
 
-static void executeFreeInst(FreeInst &I, ExecutionContext &SF) {
+void Interpreter::visitFreeInst(FreeInst &I) {
+  ExecutionContext &SF = ECStack.back();
   assert(isa<PointerType>(I.getOperand(0)->getType()) && "Freeing nonptr?");
   GenericValue Value = getOperandValue(I.getOperand(0), SF);
   // TODO: Check to make sure memory is allocated
@@ -784,19 +793,22 @@
   return Result;
 }
 
-static void executeGEPInst(GetElementPtrInst &I, ExecutionContext &SF) {
+void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
+  ExecutionContext &SF = ECStack.back();
   SetValue(&I, TheEE->executeGEPOperation(I.getPointerOperand(),
                                    I.idx_begin(), I.idx_end(), SF), SF);
 }
 
-void Interpreter::executeLoadInst(LoadInst &I, ExecutionContext &SF) {
+void Interpreter::visitLoadInst(LoadInst &I) {
+  ExecutionContext &SF = ECStack.back();
   GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
   GenericValue *Ptr = (GenericValue*)GVTOP(SRC);
   GenericValue Result = LoadValueFromMemory(Ptr, I.getType());
   SetValue(&I, Result, SF);
 }
 
-void Interpreter::executeStoreInst(StoreInst &I, ExecutionContext &SF) {
+void Interpreter::visitStoreInst(StoreInst &I) {
+  ExecutionContext &SF = ECStack.back();
   GenericValue Val = getOperandValue(I.getOperand(0), SF);
   GenericValue SRC = getOperandValue(I.getPointerOperand(), SF);
   StoreValueToMemory(Val, (GenericValue *)GVTOP(SRC),
@@ -809,8 +821,9 @@
 //                 Miscellaneous Instruction Implementations
 //===----------------------------------------------------------------------===//
 
-void Interpreter::executeCallInst(CallInst &I, ExecutionContext &SF) {
-  ECStack.back().Caller = &I;
+void Interpreter::visitCallInst(CallInst &I) {
+  ExecutionContext &SF = ECStack.back();
+  SF.Caller = &I;
   std::vector<GenericValue> ArgVals;
   ArgVals.reserve(I.getNumOperands()-1);
   for (unsigned i = 1; i < I.getNumOperands(); ++i) {
@@ -838,15 +851,15 @@
 
   // To handle indirect calls, we must get the pointer value from the argument 
   // and treat it as a function pointer.
-  GenericValue SRC = getOperandValue(I.getCalledValue(), SF);
-  
+  GenericValue SRC = getOperandValue(I.getCalledValue(), SF);  
   callFunction((Function*)GVTOP(SRC), ArgVals);
 }
 
 #define IMPLEMENT_SHIFT(OP, TY) \
    case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.UByteVal; break
 
-static void executeShlInst(ShiftInst &I, ExecutionContext &SF) {
+void Interpreter::visitShl(ShiftInst &I) {
+  ExecutionContext &SF = ECStack.back();
   const Type *Ty    = I.getOperand(0)->getType();
   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
@@ -867,7 +880,8 @@
   SetValue(&I, Dest, SF);
 }
 
-static void executeShrInst(ShiftInst &I, ExecutionContext &SF) {
+void Interpreter::visitShr(ShiftInst &I) {
+  ExecutionContext &SF = ECStack.back();
   const Type *Ty    = I.getOperand(0)->getType();
   GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
   GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
@@ -948,11 +962,14 @@
 }
 
 
-static void executeCastInst(CastInst &I, ExecutionContext &SF) {
+void Interpreter::visitCastInst(CastInst &I) {
+  ExecutionContext &SF = ECStack.back();
   SetValue(&I, executeCastOperation(I.getOperand(0), I.getType(), SF), SF);
 }
 
-static void executeVarArgInst(VarArgInst &I, ExecutionContext &SF) {
+void Interpreter::visitVarArgInst(VarArgInst &I) {
+  ExecutionContext &SF = ECStack.back();
+
   // Get the pointer to the valist element.  LLI treats the valist in memory as
   // an integer.
   GenericValue VAListPtr = getOperandValue(I.getOperand(0), SF);
@@ -1081,8 +1098,7 @@
   ExecutionContext &SF = ECStack.back();  // Current stack frame
   Instruction &I = *SF.CurInst++;         // Increment before execute
 
-  if (Trace)
-    CW << "Run:" << I;
+  if (Trace) CW << "Run:" << I;
 
   // Track the number of dynamic instructions executed.
   ++NumDynamicInsts;
@@ -1107,37 +1123,7 @@
   }
 
   InInstruction = true;
-  if (I.isBinaryOp()) {
-    executeBinaryInst(cast<BinaryOperator>(I), SF);
-  } else {
-    switch (I.getOpcode()) {
-      // Terminators
-    case Instruction::Ret:     executeRetInst  (cast<ReturnInst>(I), SF); break;
-    case Instruction::Br:      executeBrInst   (cast<BranchInst>(I), SF); break;
-    case Instruction::Switch:  executeSwitchInst(cast<SwitchInst>(I), SF);break;
-      // Invoke not handled!
-
-      // Memory Instructions
-    case Instruction::Alloca:
-    case Instruction::Malloc:  executeAllocInst((AllocationInst&)I, SF); break;
-    case Instruction::Free:    executeFreeInst (cast<FreeInst> (I), SF); break;
-    case Instruction::Load:    executeLoadInst (cast<LoadInst> (I), SF); break;
-    case Instruction::Store:   executeStoreInst(cast<StoreInst>(I), SF); break;
-    case Instruction::GetElementPtr:
-                          executeGEPInst(cast<GetElementPtrInst>(I), SF); break;
-
-      // Miscellaneous Instructions
-    case Instruction::Call:    executeCallInst (cast<CallInst> (I), SF); break;
-    case Instruction::PHINode: assert(0 && "PHI nodes already handled!");
-    case Instruction::Cast:    executeCastInst (cast<CastInst> (I), SF); break;
-    case Instruction::Shl:     executeShlInst  (cast<ShiftInst>(I), SF); break;
-    case Instruction::Shr:     executeShrInst  (cast<ShiftInst>(I), SF); break;
-    case Instruction::VarArg:  executeVarArgInst(cast<VarArgInst>(I),SF); break;
-    default:
-      std::cout << "Don't know how to execute this instruction!\n-->" << I;
-      abort();
-    }
-  }
+  visit(I);   // Dispatch to one of the visit* methods...
   InInstruction = false;
   
   // Reset the current frame location to the top of stack


Index: llvm/tools/lli/Interpreter/Interpreter.h
diff -u llvm/tools/lli/Interpreter/Interpreter.h:1.28 llvm/tools/lli/Interpreter/Interpreter.h:1.29
--- llvm/tools/lli/Interpreter/Interpreter.h:1.28	Sat May 10 15:21:16 2003
+++ llvm/tools/lli/Interpreter/Interpreter.h	Sat May 10 16:22:39 2003
@@ -11,22 +11,16 @@
 //#define PROFILE_STRUCTURE_FIELDS 1
 
 #include "../ExecutionEngine.h"
+#include "../GenericValue.h"
 #include "Support/DataTypes.h"
 #include "llvm/Assembly/CachedWriter.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/BasicBlock.h"
-#include "../GenericValue.h"
+#include "llvm/Support/InstVisitor.h"
 
 extern CachedWriter CW;     // Object to accelerate printing of LLVM
 
 struct FunctionInfo;        // Defined in ExecutionAnnotations.h
-class CallInst;
-class ReturnInst;
-class BranchInst;
-class SwitchInst;
-class LoadInst;
-class StoreInst;
-class AllocationInst;
 
 // AllocaHolder - Object to track all of the blocks of memory allocated by
 // alloca.  When the function returns, this object is poped off the execution
@@ -78,7 +72,7 @@
 
 // Interpreter - This class represents the entirety of the interpreter.
 //
-class Interpreter : public ExecutionEngine {
+class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
   int ExitCode;                // The exit code to be returned by the lli util
   bool Debug;                  // Debug mode enabled?
   bool Profile;                // Profiling enabled?
@@ -134,11 +128,28 @@
   void finish();           // Do the 'finish' command
 
   // Opcode Implementations
-  void executeCallInst(CallInst &I, ExecutionContext &SF);
-  void executeRetInst(ReturnInst &I, ExecutionContext &SF);
-  void executeBrInst(BranchInst &I, ExecutionContext &SF);
-  void executeSwitchInst(SwitchInst &I, ExecutionContext &SF);
-  void executeAllocInst(AllocationInst &I, ExecutionContext &SF);
+  void visitReturnInst(ReturnInst &I);
+  void visitBranchInst(BranchInst &I);
+  void visitSwitchInst(SwitchInst &I);
+
+  void visitBinaryOperator(BinaryOperator &I);
+  void visitAllocationInst(AllocationInst &I);
+  void visitFreeInst(FreeInst &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 visitCallInst(CallInst &I);
+  void visitShl(ShiftInst &I);
+  void visitShr(ShiftInst &I);
+  void visitVarArgInst(VarArgInst &I);
+  void visitInstruction(Instruction &I) {
+    std::cerr << I;
+    assert(0 && "Instruction not interpretable yet!");
+  }
+
   GenericValue callExternalFunction(Function *F, 
                                     const std::vector<GenericValue> &ArgVals);
   void exitCalled(GenericValue GV);
@@ -157,9 +168,6 @@
 public:
   GenericValue executeGEPOperation(Value *Ptr, User::op_iterator I,
 				   User::op_iterator E, ExecutionContext &SF);
-  void executeLoadInst(LoadInst &I, ExecutionContext &SF);
-  void executeStoreInst(StoreInst &I, ExecutionContext &SF);
-
 
 private:  // Helper functions
   // SwitchToNewBasicBlock - Start execution in a new basic block and run any





More information about the llvm-commits mailing list