Changes in directory llvm/lib/VMCore:
AsmWriter.cpp updated: 1.196 -> 1.197 ConstantFolding.cpp updated: 1.86 -> 1.87 ConstantFolding.h updated: 1.47 -> 1.48 Constants.cpp updated: 1.148 -> 1.149 Instruction.cpp updated: 1.50 -> 1.51 Instructions.cpp updated: 1.32 -> 1.33 Verifier.cpp updated: 1.152 -> 1.153 --- Log message: Add shufflevector support, todo, implement better constant folding. --- Diffs of the changes: (+134 -8) AsmWriter.cpp | 3 +- ConstantFolding.cpp | 8 ++++++ ConstantFolding.h | 3 ++ Constants.cpp | 40 ++++++++++++++++++++++++++++++++- Instruction.cpp | 1 Instructions.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++----- Verifier.cpp | 24 +++++++++++++++++++ 7 files changed, 134 insertions(+), 8 deletions(-) Index: llvm/lib/VMCore/AsmWriter.cpp diff -u llvm/lib/VMCore/AsmWriter.cpp:1.196 llvm/lib/VMCore/AsmWriter.cpp:1.197 --- llvm/lib/VMCore/AsmWriter.cpp:1.196 Wed Mar 1 16:17:00 2006 +++ llvm/lib/VMCore/AsmWriter.cpp Fri Apr 7 20:18:18 2006 @@ -1237,7 +1237,8 @@ // Shift Left & Right print both types even for Ubyte LHS, and select prints // types even if all operands are bools. - if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I)) { + if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I) || + isa<ShuffleVectorInst>(I)) { PrintAllTypes = true; } else { for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) { Index: llvm/lib/VMCore/ConstantFolding.cpp diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.86 llvm/lib/VMCore/ConstantFolding.cpp:1.87 --- llvm/lib/VMCore/ConstantFolding.cpp:1.86 Thu Apr 6 23:44:06 2006 +++ llvm/lib/VMCore/ConstantFolding.cpp Fri Apr 7 20:18:18 2006 @@ -908,6 +908,14 @@ return 0; } +Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, + const Constant *V2, + const Constant *Mask) { + // TODO: + 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.47 llvm/lib/VMCore/ConstantFolding.h:1.48 --- llvm/lib/VMCore/ConstantFolding.h:1.47 Tue Jan 17 14:07:22 2006 +++ llvm/lib/VMCore/ConstantFolding.h Fri Apr 7 20:18:18 2006 @@ -36,6 +36,9 @@ Constant *ConstantFoldInsertElementInstruction(const Constant *Val, const Constant *Elt, const Constant *Idx); + Constant *ConstantFoldShuffleVectorInstruction(const Constant *V1, + const Constant *V2, + const Constant *Mask); 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.148 llvm/lib/VMCore/Constants.cpp:1.149 --- llvm/lib/VMCore/Constants.cpp:1.148 Fri Mar 10 18:13:10 2006 +++ llvm/lib/VMCore/Constants.cpp Fri Apr 7 20:18:18 2006 @@ -376,6 +376,21 @@ } }; +/// ShuffleVectorConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// shufflevector constant exprs. +class ShuffleVectorConstantExpr : public ConstantExpr { + Use Ops[3]; +public: + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::ShuffleVector, + 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 { @@ -1175,7 +1190,10 @@ if (V.first == Instruction::InsertElement) return new InsertElementConstantExpr(V.second[0], V.second[1], V.second[2]); - + if (V.first == Instruction::ShuffleVector) + return new ShuffleVectorConstantExpr(V.second[0], V.second[1], + V.second[2]); + assert(V.first == Instruction::GetElementPtr && "Invalid ConstantExpr!"); std::vector<Constant*> IdxList(V.second.begin()+1, V.second.end()); @@ -1464,6 +1482,26 @@ Val, Elt, Idx); } +Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1, + Constant *V2, Constant *Mask) { + if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask)) + return FC; // Fold a few common cases... + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec(1, V1); + ArgVec.push_back(V2); + ArgVec.push_back(Mask); + const ExprMapKeyType &Key = std::make_pair(Instruction::ShuffleVector,ArgVec); + return ExprConstants.getOrCreate(ReqTy, Key); +} + +Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, + Constant *Mask) { + assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) && + "Invalid shuffle vector constant expr operands!"); + return getShuffleVectorTy(V1->getType(), V1, V2, Mask); +} + + // destroyConstant - Remove the constant from the constant table... // void ConstantExpr::destroyConstant() { Index: llvm/lib/VMCore/Instruction.cpp diff -u llvm/lib/VMCore/Instruction.cpp:1.50 llvm/lib/VMCore/Instruction.cpp:1.51 --- llvm/lib/VMCore/Instruction.cpp:1.50 Tue Jan 17 14:07:22 2006 +++ llvm/lib/VMCore/Instruction.cpp Fri Apr 7 20:18:18 2006 @@ -122,6 +122,7 @@ case VAArg: return "va_arg"; case ExtractElement: return "extractelement"; case InsertElement: return "insertelement"; + case ShuffleVector: return "shufflevector"; default: return "<Invalid operator> "; } Index: llvm/lib/VMCore/Instructions.cpp diff -u llvm/lib/VMCore/Instructions.cpp:1.32 llvm/lib/VMCore/Instructions.cpp:1.33 --- llvm/lib/VMCore/Instructions.cpp:1.32 Sat Mar 25 15:54:21 2006 +++ llvm/lib/VMCore/Instructions.cpp Fri Apr 7 20:18:18 2006 @@ -800,7 +800,8 @@ //===----------------------------------------------------------------------===// 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 +809,8 @@ } 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); @@ -820,7 +822,8 @@ //===----------------------------------------------------------------------===// InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index, - const std::string &Name, Instruction *InsertBef) + const std::string &Name, + Instruction *InsertBef) : Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertBef) { Ops[0].init(Val, this); Ops[1].init(Elt, this); @@ -828,7 +831,8 @@ } InsertElementInst::InsertElementInst(Value *Val, Value *Elt, Value *Index, - const std::string &Name, BasicBlock *InsertAE) + const std::string &Name, + BasicBlock *InsertAE) : Instruction(Val->getType(), InsertElement, Ops, 3, Name, InsertAE) { Ops[0].init(Val, this); Ops[1].init(Elt, this); @@ -836,6 +840,46 @@ } //===----------------------------------------------------------------------===// +// ShuffleVectorInst Implementation +//===----------------------------------------------------------------------===// + +ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, + const std::string &Name, + Instruction *InsertBefore) + : Instruction(V1->getType(), ShuffleVector, Ops, 3, Name, InsertBefore) { + assert(isValidOperands(V1, V2, Mask) && + "Invalid shuffle vector instruction operands!"); + Ops[0].init(V1, this); + Ops[1].init(V2, this); + Ops[2].init(Mask, this); +} + +ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, + const std::string &Name, + BasicBlock *InsertAtEnd) + : Instruction(V1->getType(), ShuffleVector, Ops, 3, Name, InsertAtEnd) { + assert(isValidOperands(V1, V2, Mask) && + "Invalid shuffle vector instruction operands!"); + + Ops[0].init(V1, this); + Ops[1].init(V2, this); + Ops[2].init(Mask, this); +} + +bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, + const Value *Mask) { + if (!isa<PackedType>(V1->getType())) return false; + if (V1->getType() != V2->getType()) return false; + if (!isa<PackedType>(Mask->getType()) || + cast<PackedType>(Mask->getType())->getElementType() != Type::UIntTy || + cast<PackedType>(Mask->getType())->getNumElements() != + cast<PackedType>(V1->getType())->getNumElements()) + return false; + return true; +} + + +//===----------------------------------------------------------------------===// // BinaryOperator Class //===----------------------------------------------------------------------===// @@ -1202,8 +1246,15 @@ 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); } -InsertElementInst *InsertElementInst::clone() const {return new InsertElementInst(*this); } +ExtractElementInst *ExtractElementInst::clone() const { + return new ExtractElementInst(*this); +} +InsertElementInst *InsertElementInst::clone() const { + return new InsertElementInst(*this); +} +ShuffleVectorInst *ShuffleVectorInst::clone() const { + return new ShuffleVectorInst(*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.152 llvm/lib/VMCore/Verifier.cpp:1.153 --- llvm/lib/VMCore/Verifier.cpp:1.152 Fri Mar 31 01:22:05 2006 +++ llvm/lib/VMCore/Verifier.cpp Fri Apr 7 20:18:18 2006 @@ -184,6 +184,7 @@ void visitShiftInst(ShiftInst &SI); void visitExtractElementInst(ExtractElementInst &EI); void visitInsertElementInst(InsertElementInst &EI); + void visitShuffleVectorInst(ShuffleVectorInst &EI); void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } void visitCallInst(CallInst &CI); void visitGetElementPtrInst(GetElementPtrInst &GEP); @@ -562,6 +563,29 @@ visitInstruction(IE); } +void Verifier::visitShuffleVectorInst(ShuffleVectorInst &SV) { + Assert1(ShuffleVectorInst::isValidOperands(SV.getOperand(0), SV.getOperand(1), + SV.getOperand(2)), + "Invalid shufflevector operands!", &SV); + Assert1(SV.getType() == SV.getOperand(0)->getType(), + "Result of shufflevector must match first operand type!", &SV); + + // Check to see if Mask is valid. + if (const ConstantPacked *MV = dyn_cast<ConstantPacked>(SV.getOperand(2))) { + for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) { + Assert1(isa<ConstantUInt>(MV->getOperand(i)) || + isa<UndefValue>(MV->getOperand(i)), + "Invalid shufflevector shuffle mask!", &SV); + } + } else { + Assert1(isa<UndefValue>(SV.getOperand(2)) || + isa<ConstantAggregateZero>(SV.getOperand(2)), + "Invalid shufflevector shuffle mask!", &SV); + } + + visitInstruction(SV); +} + void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { const Type *ElTy = GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(), _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits