[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