diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Utils/Local.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 38 | ||||
-rw-r--r-- | lib/VMCore/Instruction.cpp | 1 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 21 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 13 |
5 files changed, 75 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 49b871a983..8f0f7e86cd 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -102,6 +102,8 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I) { if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(2))) return ConstantExpr::getSelect(Op0, Op1, Op2); return 0; + case Instruction::ExtractElement: + return ConstantExpr::getExtractElement(Op0, Op1); case Instruction::GetElementPtr: std::vector<Constant*> IdxList; IdxList.reserve(I->getNumOperands()-1); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 63e71435df..610ed784c8 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -347,6 +347,19 @@ public: } }; +/// ExtractElementConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement extractelement constant exprs. +class ExtractElementConstantExpr : public ConstantExpr { + Use Ops[2]; +public: + ExtractElementConstantExpr(Constant *C1, Constant *C2) + : ConstantExpr(cast<PackedType>(C1->getType())->getElementType(), + Instruction::ExtractElement, Ops, 2) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + } +}; + /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. struct GetElementPtrConstantExpr : public ConstantExpr { @@ -1141,6 +1154,8 @@ namespace llvm { return new BinaryConstantExpr(V.first, V.second[0], V.second[1]); if (V.first == Instruction::Select) return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]); + if (V.first == Instruction::ExtractElement) + return new ExtractElementConstantExpr(V.second[0], V.second[1]); assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!"); @@ -1386,6 +1401,23 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, return getGetElementPtrTy(PointerType::get(Ty), C, IdxList); } +Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val, + Constant *Idx) { + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec(1, Val); + ArgVec.push_back(Idx); + const ExprMapKeyType &Key = std::make_pair(Instruction::ExtractElement,ArgVec); + return ExprConstants.getOrCreate(ReqTy, Key); +} + +Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) { + assert(isa<PackedType>(Val->getType()) && + "Tried to create extractelement operation on non-packed type!"); + assert(Idx->getType() == Type::UIntTy && + "Index must be uint type!"); + return getExtractElementTy(cast<PackedType>(Val->getType())->getElementType(), + Val, Idx); +} // destroyConstant - Remove the constant from the constant table... // @@ -1581,6 +1613,12 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, if (C2 == From) C2 = To; if (C3 == From) C3 = To; Replacement = ConstantExpr::getSelect(C1, C2, C3); + } else if (getOpcode() == Instruction::ExtractElement) { + Constant *C1 = getOperand(0); + Constant *C2 = getOperand(1); + if (C1 == From) C1 = To; + if (C2 == From) C2 = To; + Replacement = ConstantExpr::getExtractElement(C1, C2); } else if (getNumOperands() == 2) { Constant *C1 = getOperand(0); Constant *C2 = getOperand(1); diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 342614ef47..8b13e6e75b 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -120,6 +120,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case Shl: return "shl"; case Shr: return "shr"; case VAArg: return "va_arg"; + case ExtractElement: return "extractelement"; default: return "<Invalid operator> "; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 1b8d0387cf..06fbcf712c 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -796,6 +796,26 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) { } //===----------------------------------------------------------------------===// +// ExtractElementInst Implementation +//===----------------------------------------------------------------------===// + +ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, + const std::string &Name, Instruction *InsertBef) + : Instruction(cast<PackedType>(Val->getType())->getElementType(), + ExtractElement, Ops, 2, Name, InsertBef) { + Ops[0].init(Val, this); + Ops[1].init(Index, this); +} + +ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, + const std::string &Name, BasicBlock *InsertAE) + : Instruction(cast<PackedType>(Val->getType())->getElementType(), + ExtractElement, Ops, 2, Name, InsertAE) { + Ops[0].init(Val, this); + Ops[1].init(Index, this); +} + +//===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// @@ -1155,6 +1175,7 @@ CallInst *CallInst::clone() const { return new CallInst(*this); } ShiftInst *ShiftInst::clone() const { return new ShiftInst(*this); } SelectInst *SelectInst::clone() const { return new SelectInst(*this); } VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); } +ExtractElementInst *ExtractElementInst::clone() const {return new ExtractElementInst(*this); } PHINode *PHINode::clone() const { return new PHINode(*this); } ReturnInst *ReturnInst::clone() const { return new ReturnInst(*this); } BranchInst *BranchInst::clone() const { return new BranchInst(*this); } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 8b371f95b4..4b13a6b86a 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -178,6 +178,7 @@ namespace { // Anonymous namespace for class void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); void visitShiftInst(ShiftInst &SI); + void visitExtractElementInst(ExtractElementInst &EI); void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } void visitCallInst(CallInst &CI); void visitGetElementPtrInst(GetElementPtrInst &GEP); @@ -532,6 +533,18 @@ void Verifier::visitShiftInst(ShiftInst &SI) { visitInstruction(SI); } +void Verifier::visitExtractElementInst(ExtractElementInst &EI) { + Assert1(isa<PackedType>(EI.getOperand(0)->getType()), + "First operand to extractelement must be packed type!", &EI); + Assert1(EI.getOperand(1)->getType() == Type::UIntTy, + "Second operand to extractelement must be uint type!", &EI); + Assert1(EI.getType() == + cast<PackedType>(EI.getOperand(0)->getType())->getElementType(), + "Extractelement return type must be same as " + "first operand element type!", &EI); + visitInstruction(EI); +} + void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { const Type *ElTy = GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(), |