LLVM Interpreter: implementation of "insertvalue" and "extractvalue";

undef constatnt for structure and test for these functions.

done by Yuri Veselov (mailto:Yuri.Veselov@intel.com)

llvm-svn: 190599
This commit is contained in:
Elena Demikhovsky 2013-09-12 10:48:23 +00:00
parent fccb3bcae3
commit f5a643e2c5
3 changed files with 111 additions and 1 deletions

View File

@ -556,6 +556,24 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
// with the correct bit width.
Result.IntVal = APInt(C->getType()->getPrimitiveSizeInBits(), 0);
break;
case Type::StructTyID: {
// if the whole struct is 'undef' just reserve memory for the value.
if(StructType *STy = dyn_cast<StructType>(C->getType())) {
unsigned int elemNum = STy->getNumElements();
Result.AggregateVal.resize(elemNum);
for (unsigned int i = 0; i < elemNum; ++i) {
Type *ElemTy = STy->getElementType(i);
if (ElemTy->isIntegerTy())
Result.AggregateVal[i].IntVal =
APInt(ElemTy->getPrimitiveSizeInBits(), 0);
else if (ElemTy->isAggregateType()) {
const Constant *ElemUndef = UndefValue::get(ElemTy);
Result.AggregateVal[i] = getConstantValue(ElemUndef);
}
}
}
}
break;
case Type::VectorTyID:
// if the whole vector is 'undef' just reserve memory for the value.
const VectorType* VTy = dyn_cast<VectorType>(C->getType());
@ -564,7 +582,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
Result.AggregateVal.resize(elemNum);
if (ElemTy->isIntegerTy())
for (unsigned int i = 0; i < elemNum; ++i)
Result.AggregateVal[i].IntVal =
Result.AggregateVal[i].IntVal =
APInt(ElemTy->getPrimitiveSizeInBits(), 0);
break;
}

View File

@ -1880,6 +1880,95 @@ void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){
SetValue(&I, Dest, SF);
}
void Interpreter::visitExtractValueInst(ExtractValueInst &I) {
ExecutionContext &SF = ECStack.back();
Value *Agg = I.getAggregateOperand();
GenericValue Dest;
GenericValue Src = getOperandValue(Agg, SF);
ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
unsigned Num = I.getNumIndices();
GenericValue *pSrc = &Src;
for (unsigned i = 0 ; i < Num; ++i) {
pSrc = &pSrc->AggregateVal[*IdxBegin];
++IdxBegin;
}
Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
switch (IndexedType->getTypeID()) {
default:
llvm_unreachable("Unhandled dest type for extractelement instruction");
break;
case Type::IntegerTyID:
Dest.IntVal = pSrc->IntVal;
break;
case Type::FloatTyID:
Dest.FloatVal = pSrc->FloatVal;
break;
case Type::DoubleTyID:
Dest.DoubleVal = pSrc->DoubleVal;
break;
case Type::ArrayTyID:
case Type::StructTyID:
case Type::VectorTyID:
Dest.AggregateVal = pSrc->AggregateVal;
break;
case Type::PointerTyID:
Dest.PointerVal = pSrc->PointerVal;
break;
}
SetValue(&I, Dest, SF);
}
void Interpreter::visitInsertValueInst(InsertValueInst &I) {
ExecutionContext &SF = ECStack.back();
Value *Agg = I.getAggregateOperand();
GenericValue Src1 = getOperandValue(Agg, SF);
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
GenericValue Dest = Src1; // Dest is a slightly changed Src1
ExtractValueInst::idx_iterator IdxBegin = I.idx_begin();
unsigned Num = I.getNumIndices();
GenericValue *pDest = &Dest;
for (unsigned i = 0 ; i < Num; ++i) {
pDest = &pDest->AggregateVal[*IdxBegin];
++IdxBegin;
}
// pDest points to the target value in the Dest now
Type *IndexedType = ExtractValueInst::getIndexedType(Agg->getType(), I.getIndices());
switch (IndexedType->getTypeID()) {
default:
llvm_unreachable("Unhandled dest type for insertelement instruction");
break;
case Type::IntegerTyID:
pDest->IntVal = Src2.IntVal;
break;
case Type::FloatTyID:
pDest->FloatVal = Src2.FloatVal;
break;
case Type::DoubleTyID:
pDest->DoubleVal = Src2.DoubleVal;
break;
case Type::ArrayTyID:
case Type::StructTyID:
case Type::VectorTyID:
pDest->AggregateVal = Src2.AggregateVal;
break;
case Type::PointerTyID:
pDest->PointerVal = Src2.PointerVal;
break;
}
SetValue(&I, Dest, SF);
}
GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
ExecutionContext &SF) {
switch (CE->getOpcode()) {

View File

@ -182,6 +182,9 @@ public:
void visitInsertElementInst(InsertElementInst &I);
void visitShuffleVectorInst(ShuffleVectorInst &I);
void visitExtractValueInst(ExtractValueInst &I);
void visitInsertValueInst(InsertValueInst &I);
void visitInstruction(Instruction &I) {
errs() << I << "\n";
llvm_unreachable("Instruction not interpretable yet!");