forked from OSchip/llvm-project
Do not depend on structure elements being of type UByteTy
llvm-svn: 10224
This commit is contained in:
parent
4d29d2d222
commit
f078808a2b
|
@ -15,16 +15,18 @@
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||||
#include "Support/Statistic.h"
|
#include "Support/Statistic.h"
|
||||||
#include <cmath> // For fmod
|
#include <cmath> // For fmod
|
||||||
|
using namespace llvm;
|
||||||
namespace llvm {
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed");
|
Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
Interpreter *TheEE = 0;
|
Interpreter *TheEE = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Value Manipulation code
|
// Value Manipulation code
|
||||||
|
@ -42,8 +44,8 @@ GenericValue Interpreter::getOperandValue(Value *V, ExecutionContext &SF) {
|
||||||
case Instruction::Cast:
|
case Instruction::Cast:
|
||||||
return executeCastOperation(CE->getOperand(0), CE->getType(), SF);
|
return executeCastOperation(CE->getOperand(0), CE->getType(), SF);
|
||||||
case Instruction::GetElementPtr:
|
case Instruction::GetElementPtr:
|
||||||
return TheEE->executeGEPOperation(CE->getOperand(0), CE->op_begin()+1,
|
return TheEE->executeGEPOperation(CE->getOperand(0), gep_type_begin(CE),
|
||||||
CE->op_end(), SF);
|
gep_type_end(CE), SF);
|
||||||
case Instruction::Add:
|
case Instruction::Add:
|
||||||
return executeAddInst(getOperandValue(CE->getOperand(0), SF),
|
return executeAddInst(getOperandValue(CE->getOperand(0), SF),
|
||||||
getOperandValue(CE->getOperand(1), SF),
|
getOperandValue(CE->getOperand(1), SF),
|
||||||
|
@ -601,33 +603,41 @@ void Interpreter::visitFreeInst(FreeInst &I) {
|
||||||
|
|
||||||
// getElementOffset - The workhorse for getelementptr.
|
// getElementOffset - The workhorse for getelementptr.
|
||||||
//
|
//
|
||||||
GenericValue Interpreter::executeGEPOperation(Value *Ptr, User::op_iterator I,
|
GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I,
|
||||||
User::op_iterator E,
|
gep_type_iterator E,
|
||||||
ExecutionContext &SF) {
|
ExecutionContext &SF) {
|
||||||
assert(isa<PointerType>(Ptr->getType()) &&
|
assert(isa<PointerType>(Ptr->getType()) &&
|
||||||
"Cannot getElementOffset of a nonpointer type!");
|
"Cannot getElementOffset of a nonpointer type!");
|
||||||
|
|
||||||
PointerTy Total = 0;
|
PointerTy Total = 0;
|
||||||
const Type *Ty = Ptr->getType();
|
|
||||||
|
|
||||||
for (; I != E; ++I) {
|
for (; I != E; ++I) {
|
||||||
if (const StructType *STy = dyn_cast<StructType>(Ty)) {
|
if (const StructType *STy = dyn_cast<StructType>(*I)) {
|
||||||
const StructLayout *SLO = TD.getStructLayout(STy);
|
const StructLayout *SLO = TD.getStructLayout(STy);
|
||||||
|
|
||||||
// Indices must be ubyte constants...
|
// Indices must be ubyte constants...
|
||||||
const ConstantUInt *CPU = cast<ConstantUInt>(*I);
|
const ConstantUInt *CPU = cast<ConstantUInt>(*I);
|
||||||
assert(CPU->getType() == Type::UByteTy);
|
|
||||||
unsigned Index = CPU->getValue();
|
unsigned Index = CPU->getValue();
|
||||||
|
|
||||||
Total += SLO->MemberOffsets[Index];
|
Total += SLO->MemberOffsets[Index];
|
||||||
Ty = STy->getElementTypes()[Index];
|
} else {
|
||||||
} else if (const SequentialType *ST = cast<SequentialType>(Ty)) {
|
const SequentialType *ST = cast<SequentialType>(*I);
|
||||||
// Get the index number for the array... which must be long type...
|
// Get the index number for the array... which must be long type...
|
||||||
assert((*I)->getType() == Type::LongTy);
|
GenericValue IdxGV = getOperandValue(I.getOperand(), SF);
|
||||||
unsigned Idx = getOperandValue(*I, SF).LongVal;
|
|
||||||
Ty = ST->getElementType();
|
uint64_t Idx;
|
||||||
unsigned Size = TD.getTypeSize(Ty);
|
switch (I.getOperand()->getType()->getPrimitiveID()) {
|
||||||
Total += Size*Idx;
|
default: assert(0 && "Illegal getelementptr index for sequential type!");
|
||||||
|
case Type::SByteTyID: Idx = IdxGV.SByteVal; break;
|
||||||
|
case Type::ShortTyID: Idx = IdxGV.ShortVal; break;
|
||||||
|
case Type::IntTyID: Idx = IdxGV.IntVal; break;
|
||||||
|
case Type::LongTyID: Idx = IdxGV.LongVal; break;
|
||||||
|
case Type::UByteTyID: Idx = IdxGV.UByteVal; break;
|
||||||
|
case Type::UShortTyID: Idx = IdxGV.UShortVal; break;
|
||||||
|
case Type::UIntTyID: Idx = IdxGV.UIntVal; break;
|
||||||
|
case Type::ULongTyID: Idx = IdxGV.ULongVal; break;
|
||||||
|
}
|
||||||
|
Total += TD.getTypeSize(ST->getElementType())*Idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +649,7 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, User::op_iterator I,
|
||||||
void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
|
void Interpreter::visitGetElementPtrInst(GetElementPtrInst &I) {
|
||||||
ExecutionContext &SF = ECStack.back();
|
ExecutionContext &SF = ECStack.back();
|
||||||
SetValue(&I, TheEE->executeGEPOperation(I.getPointerOperand(),
|
SetValue(&I, TheEE->executeGEPOperation(I.getPointerOperand(),
|
||||||
I.idx_begin(), I.idx_end(), SF), SF);
|
gep_type_begin(I), gep_type_end(I), SF), SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::visitLoadInst(LoadInst &I) {
|
void Interpreter::visitLoadInst(LoadInst &I) {
|
||||||
|
@ -912,5 +922,3 @@ void Interpreter::run() {
|
||||||
visit(I); // Dispatch to one of the visit* methods...
|
visit(I); // Dispatch to one of the visit* methods...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End llvm namespace
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
struct FunctionInfo; // Defined in ExecutionAnnotations.h
|
struct FunctionInfo; // Defined in ExecutionAnnotations.h
|
||||||
|
class gep_type_iterator;
|
||||||
|
|
||||||
// AllocaHolder - Object to track all of the blocks of memory allocated by
|
// AllocaHolder - Object to track all of the blocks of memory allocated by
|
||||||
// alloca. When the function returns, this object is poped off the execution
|
// alloca. When the function returns, this object is poped off the execution
|
||||||
|
@ -152,8 +153,8 @@ public:
|
||||||
|
|
||||||
//FIXME: private:
|
//FIXME: private:
|
||||||
public:
|
public:
|
||||||
GenericValue executeGEPOperation(Value *Ptr, User::op_iterator I,
|
GenericValue executeGEPOperation(Value *Ptr, gep_type_iterator I,
|
||||||
User::op_iterator E, ExecutionContext &SF);
|
gep_type_iterator E, ExecutionContext &SF);
|
||||||
|
|
||||||
private: // Helper functions
|
private: // Helper functions
|
||||||
// SwitchToNewBasicBlock - Start execution in a new basic block and run any
|
// SwitchToNewBasicBlock - Start execution in a new basic block and run any
|
||||||
|
|
Loading…
Reference in New Issue