Changes in directory llvm/lib/VMCore:
ConstantFolding.cpp updated: 1.82 -> 1.83 ConstantFolding.h updated: 1.46 -> 1.47 Constants.cpp updated: 1.144 -> 1.145 Instruction.cpp updated: 1.49 -> 1.50 Instructions.cpp updated: 1.30 -> 1.31 Verifier.cpp updated: 1.143 -> 1.144 --- Log message: VMCore support for the insertelement operation. --- Diffs of the changes: (+147 -9) ConstantFolding.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ConstantFolding.h | 3 ++ Constants.cpp | 49 +++++++++++++++++++++++++++++++++++++++++--- Instruction.cpp | 1 Instructions.cpp | 25 ++++++++++++++++++++-- Verifier.cpp | 21 +++++++++++++++---- 6 files changed, 147 insertions(+), 9 deletions(-) Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.82 llvm/lib/VMCore/ConstantFolding.cpp:1.83 --- llvm/lib/VMCore/ConstantFolding.cpp:1.82 Tue Jan 10 14:03:46 2006 +++ llvm/lib/VMCore/ConstantFolding.cpp Tue Jan 17 14:07:22 2006 @@ -734,6 +734,63 @@ return 0; } +Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, + const Constant *Elt, + const Constant *Idx) { + const ConstantUInt *CIdx = dyn_cast<ConstantUInt>(Idx); + if (!CIdx) return 0; + unsigned idxVal = CIdx->getValue(); + if (const UndefValue *UVal = dyn_cast<UndefValue>(Val)) { + // Insertion of scalar constant into packed undef + // Optimize away insertion of undef + if (isa<UndefValue>(Elt)) + return const_cast<Constant*>(Val); + // Otherwise break the aggregate undef into multiple undefs and do + // the insertion + unsigned numOps = + cast<PackedType>(Val->getType())->getNumElements(); + std::vector<Constant*> Ops; + Ops.reserve(numOps); + for (unsigned i = 0; i < numOps; ++i) { + const Constant *Op = + (i == idxVal) ? Elt : UndefValue::get(Elt->getType()); + Ops.push_back(const_cast<Constant*>(Op)); + } + return ConstantPacked::get(Ops); + } + if (const ConstantAggregateZero *CVal = + dyn_cast<ConstantAggregateZero>(Val)) { + // Insertion of scalar constant into packed aggregate zero + // Optimize away insertion of zero + if (Elt->isNullValue()) + return const_cast<Constant*>(Val); + // Otherwise break the aggregate zero into multiple zeros and do + // the insertion + unsigned numOps = + cast<PackedType>(Val->getType())->getNumElements(); + std::vector<Constant*> Ops; + Ops.reserve(numOps); + for (unsigned i = 0; i < numOps; ++i) { + const Constant *Op = + (i == idxVal) ? Elt : Constant::getNullValue(Elt->getType()); + Ops.push_back(const_cast<Constant*>(Op)); + } + return ConstantPacked::get(Ops); + } + if (const ConstantPacked *CVal = dyn_cast<ConstantPacked>(Val)) { + // Insertion of scalar constant into packed constant + std::vector<Constant*> Ops; + Ops.reserve(CVal->getNumOperands()); + for (unsigned i = 0; i < CVal->getNumOperands(); ++i) { + const Constant *Op = + (i == idxVal) ? Elt : cast<Constant>(CVal->getOperand(i)); + Ops.push_back(const_cast<Constant*>(Op)); + } + return ConstantPacked::get(Ops); + } + return 0; +} + /// isZeroSizedType - This type is zero sized if its an array or structure of /// zero sized types. The only leaf zero sized type is an empty structure. static bool isMaybeZeroSizedType(const Type *Ty) { Index: llvm/lib/VMCore/ConstantFolding.h diff -u llvm/lib/VMCore/ConstantFolding.h:1.46 llvm/lib/VMCore/ConstantFolding.h:1.47 --- llvm/lib/VMCore/ConstantFolding.h:1.46 Tue Jan 10 14:03:46 2006 +++ llvm/lib/VMCore/ConstantFolding.h Tue Jan 17 14:07:22 2006 @@ -33,6 +33,9 @@ const Constant *V2); Constant *ConstantFoldExtractElementInstruction(const Constant *Val, const Constant *Idx); + Constant *ConstantFoldInsertElementInstruction(const Constant *Val, + const Constant *Elt, + const Constant *Idx); Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, const Constant *V2); Constant *ConstantFoldGetElementPtr(const Constant *C, Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.144 llvm/lib/VMCore/Constants.cpp:1.145 --- llvm/lib/VMCore/Constants.cpp:1.144 Tue Jan 10 14:03:46 2006 +++ llvm/lib/VMCore/Constants.cpp Tue Jan 17 14:07:22 2006 @@ -347,8 +347,9 @@ } }; -/// ExtractElementConstantExpr - This class is private to Constants.cpp, and is used -/// behind the scenes to implement extractelement constant exprs. +/// 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: @@ -360,6 +361,21 @@ } }; +/// InsertElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertelement constant exprs. +class InsertElementConstantExpr : public ConstantExpr { + Use Ops[3]; +public: + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, + Ops, 3) { + Ops[0].init(C1, this); + Ops[1].init(C2, this); + Ops[2].init(C3, this); + } +}; + /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. struct GetElementPtrConstantExpr : public ConstantExpr { @@ -1156,6 +1172,9 @@ 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]); + if (V.first == Instruction::InsertElement) + return new InsertElementConstantExpr(V.second[0], V.second[1], + V.second[2]); assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!"); @@ -1416,9 +1435,33 @@ assert(isa<PackedType>(Val->getType()) && "Tried to create extractelement operation on non-packed type!"); assert(Idx->getType() == Type::UIntTy && - "Index must be uint type!"); + "Extractelement index must be uint type!"); return getExtractElementTy(cast<PackedType>(Val->getType())->getElementType(), Val, Idx); +} + +Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val, + Constant *Elt, Constant *Idx) { + if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx)) + return FC; // Fold a few common cases... + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec(1, Val); + ArgVec.push_back(Elt); + ArgVec.push_back(Idx); + const ExprMapKeyType &Key = std::make_pair(Instruction::InsertElement,ArgVec); + return ExprConstants.getOrCreate(ReqTy, Key); +} + +Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, + Constant *Idx) { + assert(isa<PackedType>(Val->getType()) && + "Tried to create insertelement operation on non-packed type!"); + assert(Elt->getType() == cast<PackedType>(Val->getType())->getElementType() + && "Insertelement types must match!"); + assert(Idx->getType() == Type::UIntTy && + "Insertelement index must be uint type!"); + return getInsertElementTy(cast<PackedType>(Val->getType())->getElementType(), + Val, Elt, Idx); } // destroyConstant - Remove the constant from the constant table... Index: llvm/lib/VMCore/Instruction.cpp diff -u llvm/lib/VMCore/Instruction.cpp:1.49 llvm/lib/VMCore/Instruction.cpp:1.50 --- llvm/lib/VMCore/Instruction.cpp:1.49 Tue Jan 10 13:05:24 2006 +++ llvm/lib/VMCore/Instruction.cpp Tue Jan 17 14:07:22 2006 @@ -121,6 +121,7 @@ case Shr: return "shr"; case VAArg: return "va_arg"; case ExtractElement: return "extractelement"; + case InsertElement: return "insertelement"; default: return "<Invalid operator> "; } Index: llvm/lib/VMCore/Instructions.cpp diff -u llvm/lib/VMCore/Instructions.cpp:1.30 llvm/lib/VMCore/Instructions.cpp:1.31 --- llvm/lib/VMCore/Instructions.cpp:1.30 Tue Jan 10 13:05:24 2006 +++ llvm/lib/VMCore/Instructions.cpp Tue Jan 17 14:07:22 2006 @@ -800,7 +800,7 @@ //===----------------------------------------------------------------------===// ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, - const std::string &Name, Instruction *InsertBef) + const std::string &Name, Instruction *InsertBef) : Instruction(cast<PackedType>(Val->getType())->getElementType(), ExtractElement, Ops, 2, Name, InsertBef) { Ops[0].init(Val, this); @@ -808,7 +808,7 @@ } ExtractElementInst::ExtractElementInst(Value *Val, Value *Index, - const std::string &Name, BasicBlock *InsertAE) + const std::string &Name, BasicBlock *InsertAE) : Instruction(cast<PackedType>(Val->getType())->getElementType(), ExtractElement, Ops, 2, Name, InsertAE) { Ops[0].init(Val, this); @@ -816,6 +816,26 @@ } //===----------------------------------------------------------------------===// +// InsertElementInst Implementation +//===----------------------------------------------------------------------===// + +InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index, + const std::string &Name, Instruction *InsertBef) + : Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertBef) { + Ops[0].init(Val, this); + Ops[1].init(Elt, this); + Ops[2].init(Index, this); +} + +InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index, + const std::string &Name, BasicBlock *InsertAE) + : Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertAE) { + Ops[0].init(Val, this); + Ops[1].init(Elt, this); + Ops[2].init(Index, this); +} + +//===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// @@ -1176,6 +1196,7 @@ SelectInst *SelectInst::clone() const { return new SelectInst(*this); } VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); } ExtractElementInst *ExtractElementInst::clone() const {return new ExtractElementInst(*this); } +InsertElementInst *InsertElementInst::clone() const {return new InsertElementInst(*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); } Index: llvm/lib/VMCore/Verifier.cpp diff -u llvm/lib/VMCore/Verifier.cpp:1.143 llvm/lib/VMCore/Verifier.cpp:1.144 --- llvm/lib/VMCore/Verifier.cpp:1.143 Mon Jan 16 15:12:35 2006 +++ llvm/lib/VMCore/Verifier.cpp Tue Jan 17 14:07:22 2006 @@ -140,7 +140,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); if (RealPass) - AU.addRequired<ETForest>(); + AU.addRequired<ETForest>(); } /// abortIfBroken - If the module is broken and we are supposed to abort on @@ -180,6 +180,7 @@ void visitBinaryOperator(BinaryOperator &B); void visitShiftInst(ShiftInst &SI); void visitExtractElementInst(ExtractElementInst &EI); + void visitInsertElementInst(InsertElementInst &EI); void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } void visitCallInst(CallInst &CI); void visitGetElementPtrInst(GetElementPtrInst &GEP); @@ -540,10 +541,22 @@ 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); + cast<PackedType>(EI.getOperand(0)->getType())->getElementType(), + "Extractelement return type must match " + "first operand element type!", &EI); visitInstruction(EI); +} + +void Verifier::visitInsertElementInst(InsertElementInst &IE) { + Assert1(isa<PackedType>(IE.getOperand(0)->getType()), + "First operand to insertelement must be packed type!", &IE); + Assert1(IE.getOperand(1)->getType() == + cast<PackedType>(IE.getOperand(0)->getType())->getElementType(), + "Second operand to insertelement must match " + "first operand element type!", &IE); + Assert1(IE.getOperand(2)->getType() == Type::UIntTy, + "Third operand to insertelement must be uint type!", &IE); + visitInstruction(IE); } void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits