[llvm-commits] [vector_llvm] CVS: llvm/lib/VMCore/AsmWriter.cpp Constants.cpp Instruction.cpp Instructions.cpp Type.cpp Verifier.cpp
Robert Bocchino
bocchino at cs.uiuc.edu
Tue Oct 18 12:22:22 PDT 2005
Changes in directory llvm/lib/VMCore:
AsmWriter.cpp updated: 1.181 -> 1.181.2.1
Constants.cpp updated: 1.139 -> 1.139.2.1
Instruction.cpp updated: 1.48 -> 1.48.2.1
Instructions.cpp updated: 1.26 -> 1.26.2.1
Type.cpp updated: 1.129 -> 1.129.2.1
Verifier.cpp updated: 1.134 -> 1.134.2.1
---
Log message:
Initial commit of Vector LLVM.
---
Diffs of the changes: (+594 -80)
AsmWriter.cpp | 25 ++--
Constants.cpp | 52 ++++----
Instruction.cpp | 18 ++
Instructions.cpp | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Type.cpp | 214 +++++++++++++++++++++++++++++-----
Verifier.cpp | 25 ++--
6 files changed, 594 insertions(+), 80 deletions(-)
Index: llvm/lib/VMCore/AsmWriter.cpp
diff -u llvm/lib/VMCore/AsmWriter.cpp:1.181 llvm/lib/VMCore/AsmWriter.cpp:1.181.2.1
--- llvm/lib/VMCore/AsmWriter.cpp:1.181 Wed Aug 17 14:33:31 2005
+++ llvm/lib/VMCore/AsmWriter.cpp Tue Oct 18 14:21:57 2005
@@ -332,16 +332,23 @@
Result += "]";
break;
}
- case Type::PackedTyID: {
- const PackedType *PTy = cast<PackedType>(Ty);
- Result += "<" + utostr(PTy->getNumElements()) + " x ";
+ case Type::FixedVectorTyID: {
+ const FixedVectorType *PTy = cast<FixedVectorType>(Ty);
+ Result += "[vector of " + utostr(PTy->getNumElements()) + " ";
calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result);
- Result += ">";
+ Result += "]";
break;
}
case Type::OpaqueTyID:
Result += "opaque";
break;
+ case Type::VectorTyID: {
+ const VectorType *VTy = cast<VectorType>(Ty);
+ Result += "[vector of ";
+ calcTypeName(VTy->getElementType(), TypeStack, TypeNames, Result);
+ Result += "]";
+ break;
+ }
default:
Result += "<unrecognized-type>";
}
@@ -503,10 +510,10 @@
}
Out << " }";
- } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
+ } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
const Type *ETy = CP->getType()->getElementType();
- assert(CP->getNumOperands() > 0 &&
- "Number of operands for a PackedConst must be > 0");
+ assert(CP->getNumOperands() > 0 &&
+ "Number of operands for a FixedVectorConst must be > 0");
Out << '<';
Out << ' ';
printTypeInt(Out, ETy, TypeTable);
@@ -734,7 +741,7 @@
} else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
Out << '[' << ATy->getNumElements() << " x ";
printType(ATy->getElementType()) << ']';
- } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
+ } else if (const FixedVectorType *PTy = dyn_cast<FixedVectorType>(Ty)) {
Out << '<' << PTy->getNumElements() << " x ";
printType(PTy->getElementType()) << '>';
}
@@ -1054,6 +1061,8 @@
} else if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall()) {
// If this is a call, check if it's a tail call.
Out << "tail ";
+ } else if (isa<VImmInst>(I) && isa<FixedVectorType>(I.getType())) {
+ Out << "fixed ";
}
// Print out the opcode...
Index: llvm/lib/VMCore/Constants.cpp
diff -u llvm/lib/VMCore/Constants.cpp:1.139 llvm/lib/VMCore/Constants.cpp:1.139.2.1
--- llvm/lib/VMCore/Constants.cpp:1.139 Fri Oct 7 00:23:36 2005
+++ llvm/lib/VMCore/Constants.cpp Tue Oct 18 14:21:57 2005
@@ -112,9 +112,15 @@
case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
+ //case Type::VectorTyID: {
+ //const VectorType *VT = cast<VectorType>(Ty);
+ //return ConstantExpr::getCast(Constant::getNullValue(VT->getElementType()), Ty);
+ //}
+
case Type::StructTyID:
case Type::ArrayTyID:
- case Type::PackedTyID:
+ case Type::FixedVectorTyID:
+ case Type::VectorTyID:
return ConstantAggregateZero::get(Ty);
default:
// Function, Label, or Opaque type?
@@ -287,7 +293,7 @@
}
-ConstantPacked::ConstantPacked(const PackedType *T,
+ConstantVector::ConstantVector(const FixedVectorType *T,
const std::vector<Constant*> &V)
: Constant(T, ConstantPackedVal, new Use[V.size()], V.size()) {
Use *OL = OperandList;
@@ -297,12 +303,12 @@
assert((C->getType() == T->getElementType() ||
(T->isAbstract() &&
C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
- "Initializer for packed element doesn't match packed element type!");
+ "Initializer for vector element doesn't match vector element type!");
OL->init(C, this);
}
}
-ConstantPacked::~ConstantPacked() {
+ConstantVector::~ConstantVector() {
delete [] OperandList;
}
@@ -483,10 +489,12 @@
// TODO: Figure out how to test if a double can be cast to a float!
case Type::FloatTyID:
case Type::DoubleTyID:
+ case Type::VectorTyID: // Added this for vector type!
return true; // This is the largest type...
}
};
+
//===----------------------------------------------------------------------===//
// Factory Function Implementation
@@ -982,17 +990,17 @@
destroyConstantImpl();
}
-//---- ConstantPacked::get() implementation...
+//---- ConstantVector::get() implementation...
//
namespace llvm {
template<>
- struct ConvertConstantType<ConstantPacked, PackedType> {
- static void convert(ConstantPacked *OldC, const PackedType *NewTy) {
+ struct ConvertConstantType<ConstantVector, FixedVectorType> {
+ static void convert(ConstantVector *OldC, const FixedVectorType *NewTy) {
// Make everyone now use a constant of the new type...
std::vector<Constant*> C;
for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i)
C.push_back(cast<Constant>(OldC->getOperand(i)));
- Constant *New = ConstantPacked::get(NewTy, C);
+ Constant *New = ConstantVector::get(NewTy, C);
assert(New != OldC && "Didn't replace constant??");
OldC->uncheckedReplaceAllUsesWith(New);
OldC->destroyConstant(); // This constant is now dead, destroy it.
@@ -1000,7 +1008,7 @@
};
}
-static std::vector<Constant*> getValType(ConstantPacked *CP) {
+static std::vector<Constant*> getValType(ConstantVector *CP) {
std::vector<Constant*> Elements;
Elements.reserve(CP->getNumOperands());
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
@@ -1008,32 +1016,32 @@
return Elements;
}
-static ValueMap<std::vector<Constant*>, PackedType,
- ConstantPacked> PackedConstants;
+static ValueMap<std::vector<Constant*>, FixedVectorType,
+ ConstantVector> FixedVectorConstants;
-Constant *ConstantPacked::get(const PackedType *Ty,
+Constant *ConstantVector::get(const FixedVectorType *Ty,
const std::vector<Constant*> &V) {
- // If this is an all-zero packed, return a ConstantAggregateZero object
+ // If this is an all-zero vector, return a ConstantAggregateZero object
if (!V.empty()) {
Constant *C = V[0];
if (!C->isNullValue())
- return PackedConstants.getOrCreate(Ty, V);
+ return FixedVectorConstants.getOrCreate(Ty, V);
for (unsigned i = 1, e = V.size(); i != e; ++i)
if (V[i] != C)
- return PackedConstants.getOrCreate(Ty, V);
+ return FixedVectorConstants.getOrCreate(Ty, V);
}
return ConstantAggregateZero::get(Ty);
}
-Constant *ConstantPacked::get(const std::vector<Constant*> &V) {
+Constant *ConstantVector::get(const std::vector<Constant*> &V) {
assert(!V.empty() && "Cannot infer type if V is empty");
- return get(PackedType::get(V.front()->getType(),V.size()), V);
+ return get(FixedVectorType::get(V.front()->getType(),V.size()), V);
}
// destroyConstant - Remove the constant from the constant table...
//
-void ConstantPacked::destroyConstant() {
- PackedConstants.remove(this);
+void ConstantVector::destroyConstant() {
+ FixedVectorConstants.remove(this);
destroyConstantImpl();
}
@@ -1529,7 +1537,7 @@
destroyConstant();
}
-void ConstantPacked::replaceUsesOfWithOnConstant(Value *From, Value *To,
+void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
@@ -1541,7 +1549,7 @@
Values.push_back(Val);
}
- Constant *Replacement = ConstantPacked::get(getType(), Values);
+ Constant *Replacement = ConstantVector::get(getType(), Values);
assert(Replacement != this && "I didn't contain From!");
// Everyone using this now uses the replacement.
@@ -1615,7 +1623,7 @@
AggZeroConstants.clear(Constants);
ArrayConstants.clear(Constants);
StructConstants.clear(Constants);
- PackedConstants.clear(Constants);
+ FixedVectorConstants.clear(Constants);
NullPtrConstants.clear(Constants);
UndefValueConstants.clear(Constants);
ExprConstants.clear(Constants);
Index: llvm/lib/VMCore/Instruction.cpp
diff -u llvm/lib/VMCore/Instruction.cpp:1.48 llvm/lib/VMCore/Instruction.cpp:1.48.2.1
--- llvm/lib/VMCore/Instruction.cpp:1.48 Mon Aug 8 00:21:50 2005
+++ llvm/lib/VMCore/Instruction.cpp Tue Oct 18 14:21:57 2005
@@ -104,6 +104,14 @@
case SetEQ: return "seteq";
case SetNE: return "setne";
+ // VSetCC operators...
+ case VSetLE: return "vsetle";
+ case VSetGE: return "vsetge";
+ case VSetLT: return "vsetlt";
+ case VSetGT: return "vsetgt";
+ case VSetEQ: return "vseteq";
+ case VSetNE: return "vsetne";
+
// Memory instructions...
case Malloc: return "malloc";
case Free: return "free";
@@ -116,10 +124,18 @@
case PHI: return "phi";
case Cast: return "cast";
case Select: return "select";
+ case VSelect: return "vselect";
case Call: return "call";
case Shl: return "shl";
case Shr: return "shr";
- case VAArg: return "va_arg";
+ case VAArg: return "vaarg";
+ case VImm: return "vimm";
+ case VGather: return "vgather";
+ case VScatter: return "vscatter";
+ case Extract: return "extract";
+ case ExtractElement: return "extractelement";
+ case Combine: return "combine";
+ case CombineElement: return "combineelement";
default: return "<Invalid operator> ";
}
Index: llvm/lib/VMCore/Instructions.cpp
diff -u llvm/lib/VMCore/Instructions.cpp:1.26 llvm/lib/VMCore/Instructions.cpp:1.26.2.1
--- llvm/lib/VMCore/Instructions.cpp:1.26 Fri Aug 5 10:37:31 2005
+++ llvm/lib/VMCore/Instructions.cpp Tue Oct 18 14:21:57 2005
@@ -18,6 +18,7 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Support/CallSite.h"
+
using namespace llvm;
unsigned CallSite::getCallingConv() const {
@@ -809,21 +810,27 @@
case Rem:
assert(getType() == LHS->getType() &&
"Arithmetic operation should return same type as operands!");
- assert((getType()->isInteger() ||
- getType()->isFloatingPoint() ||
- isa<PackedType>(getType()) ) &&
+ assert((getType()->isInteger() ||
+ getType()->isFloatingPoint() ||
+ isa<VectorType>(getType())) &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case And: case Or:
case Xor:
assert(getType() == LHS->getType() &&
"Logical operation should return same type as operands!");
- assert(getType()->isIntegral() &&
+ assert(getType()->isIntegral() ||
+ getType()->isIntegralVector() &&
"Tried to create a logical operation on a non-integral type!");
break;
case SetLT: case SetGT: case SetLE:
case SetGE: case SetEQ: case SetNE:
assert(getType() == Type::BoolTy && "Setcc must return bool!");
+ break;
+ case VSetLT: case VSetGT: case VSetLE:
+ case VSetGE: case VSetEQ: case VSetNE:
+ assert(getType()->isBooleanVector() && "VSetcc must return bool vector!");
+ break;
default:
break;
}
@@ -839,6 +846,8 @@
// Binary comparison operators...
case SetLT: case SetGT: case SetLE:
case SetGE: case SetEQ: case SetNE:
+ case VSetLT: case VSetGT: case VSetLE:
+ case VSetGE: case VSetEQ: case VSetNE:
return new SetCondInst(Op, S1, S2, Name, InsertBefore);
default:
@@ -964,9 +973,18 @@
// SetCondInst Class
//===----------------------------------------------------------------------===//
+static Type *condType(Value *S) {
+ const Type *T = S->getType();
+ if (const FixedVectorType *VT = dyn_cast<FixedVectorType>(T))
+ return FixedVectorType::get(Type::BoolTy, VT->getNumElements());
+ if (const VectorType *VT = dyn_cast<VectorType>(T))
+ return VectorType::get(Type::BoolTy);
+ return Type::BoolTy;
+}
+
SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2,
const std::string &Name, Instruction *InsertBefore)
- : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertBefore) {
+ : BinaryOperator(Opcode, S1, S2, condType(S1), Name, InsertBefore) {
// Make sure it's a valid type... getInverseCondition will assert out if not.
assert(getInverseCondition(Opcode));
@@ -974,7 +992,7 @@
SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2,
const std::string &Name, BasicBlock *InsertAtEnd)
- : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertAtEnd) {
+ : BinaryOperator(Opcode, S1, S2, condType(S1), Name, InsertAtEnd) {
// Make sure it's a valid type... getInverseCondition will assert out if not.
assert(getInverseCondition(Opcode));
@@ -993,6 +1011,12 @@
case SetLT: return SetGE;
case SetGE: return SetLT;
case SetLE: return SetGT;
+ case VSetEQ: return VSetNE;
+ case VSetNE: return VSetEQ;
+ case VSetGT: return VSetLE;
+ case VSetLT: return VSetGE;
+ case VSetGE: return VSetLT;
+ case VSetLE: return VSetGT;
}
}
@@ -1008,6 +1032,54 @@
case SetLT: return SetGT;
case SetGE: return SetLE;
case SetLE: return SetGE;
+ case VSetGT: return VSetLT;
+ case VSetLT: return VSetGT;
+ case VSetGE: return VSetLE;
+ case VSetLE: return VSetGE;
+ }
+}
+
+// getScalarOpcode - Return the scalar version of this opcode.
+// For example seteq -> seteq, vseteq -> seteq, etc.
+//
+Instruction::BinaryOps SetCondInst::getScalarOpcode(BinaryOps Opcode) {
+ switch (Opcode) {
+ default:
+ assert(0 && "Unknown setcc opcode!");
+ case SetEQ: case VSetEQ:
+ return SetEQ;
+ case SetNE: case VSetNE:
+ return SetNE;
+ case SetGT: case VSetGT:
+ return SetGT;
+ case SetLT: case VSetLT:
+ return SetLT;
+ case SetGE: case VSetGE:
+ return SetGE;
+ case SetLE: case VSetLE:
+ return SetLE;
+ }
+}
+
+// getVectorOpcode - Return the vector version of this opcode.
+// For example seteq -> vseteq, vseteq -> vseteq, etc.
+//
+Instruction::BinaryOps SetCondInst::getVectorOpcode(BinaryOps Opcode) {
+ switch (Opcode) {
+ default:
+ assert(0 && "Unknown setcc opcode!");
+ case SetEQ: case VSetEQ:
+ return VSetEQ;
+ case SetNE: case VSetNE:
+ return VSetNE;
+ case SetGT: case VSetGT:
+ return VSetGT;
+ case SetLT: case VSetLT:
+ return VSetLT;
+ case SetGE: case VSetGE:
+ return VSetGE;
+ case SetLE: case VSetLE:
+ return VSetLE;
}
}
@@ -1122,6 +1194,252 @@
}
+//===----------------------------------------------------------------------===//
+// VMemoryInst Implementation
+//===----------------------------------------------------------------------===//
+
+VMemoryInst::VMemoryInst(const Type *Ty, unsigned iType,
+ Use *Ops, unsigned NumOps,
+ const std::string &Name, Instruction *InsertBef)
+ : Instruction(Ty, iType, Ops, NumOps, Name, InsertBef) {}
+
+VMemoryInst::VMemoryInst(const Type* Ty, unsigned iType,
+ Use *Ops, unsigned NumOps,
+ const std::string &Name, BasicBlock *InsertAE)
+
+ : Instruction(Ty, iType, Ops, NumOps, Name, InsertAE) {}
+
+VMemoryInst::~VMemoryInst() {
+ delete [] OperandList;
+}
+
+bool VMemoryInst::checkIndexType(const std::vector<Value*> &Idx) {
+ unsigned i;
+ for (i = 0; i < Idx.size(); ++i)
+ if (Idx[i]->getType() != Type::LongTy)
+ return false;
+ return true;
+}
+
+const Type *VMemoryInst::getElementType() const {
+ const VectorType *VT = dyn_cast<VectorType>(getType());
+ assert(VT && "Vector instruction not of vector type!");
+ return VT->getElementType();
+}
+
+
+//===----------------------------------------------------------------------===//
+// VGatherInst Implementation
+//===----------------------------------------------------------------------===//
+
+void VGatherInst::init(Value *Ptr, const std::vector<Value*> &Idx)
+{
+ assert(isa<PointerType>(Ptr->getType()) && "Ptr must be of pointer type!");
+ assert(cast<PointerType>(Ptr->getType())->getElementType()->isPrimitiveType() &&
+ "Ptr must be pointer to primitive type!");
+ assert(checkNumIndices(Idx) && "vgather must have four indices for each array dimension!");
+ assert(checkIndexType(Idx) && "vgather indices must be of type long!");
+
+ NumOperands = 1+Idx.size();
+ Use *OL = OperandList = new Use[NumOperands];
+ OL[0].init(Ptr, this);
+
+ for (unsigned i = 0, e = Idx.size(); i != e; ++i)
+ OL[i+1].init(Idx[i], this);
+}
+
+VGatherInst::VGatherInst(Value *Ptr, const std::vector<Value*> &Idx,
+ const std::string &Name, Instruction *InsertBef)
+ : VMemoryInst(VectorType::get(cast<PointerType>(Ptr->getType())->getElementType()),
+ VGather, 0, 0, Name, InsertBef) {
+ init(Ptr, Idx);
+}
+
+VGatherInst::VGatherInst(Value *Ptr, const std::vector<Value*> &Idx,
+ const std::string &Name, BasicBlock *InsertAE)
+ : VMemoryInst(VectorType::get(cast<PointerType>(Ptr->getType())->getElementType()),
+ VGather, 0, 0, Name, InsertAE) {
+ init(Ptr, Idx);
+}
+
+
+//===----------------------------------------------------------------------===//
+// VScatterInst Implementation
+//===----------------------------------------------------------------------===//
+
+void VScatterInst::init(Value *Val, Value *Ptr, const std::vector<Value*> &Idx) {
+ assert(isa<VectorType>(Val->getType()) && "Val must be of vector type!");
+ assert(isa<PointerType>(Ptr->getType()) && "Ptr must be of pointer type!");
+ assert(cast<PointerType>(Ptr->getType())->getElementType()->isPrimitiveType() &&
+ "Ptr must be pointer to primitive type!");
+ //assert(Val->getType() == VectorType::get(cast<PointerType>(Ptr->getType())->getElementType())
+ // && "Ptr must be a pointer to Val type!");
+ assert(cast<VectorType>(Val->getType())->getElementType() ==
+ cast<PointerType>(Ptr->getType())->getElementType()
+ && "Ptr must be a pointer to Val type!");
+ assert(checkNumIndices(Idx) && "vscatter must have four indices for each array dimension!");
+ assert(checkIndexType(Idx) && "vscatter indices must be of type long!");
+
+ NumOperands = 2+Idx.size();
+ Use *OL = OperandList = new Use[NumOperands];
+ OL[0].init(Val, this);
+ OL[1].init(Ptr, this);
+
+ for (unsigned i = 0, e = Idx.size(); i != e; ++i)
+ OL[i+2].init(Idx[i], this);
+
+}
+
+VScatterInst::VScatterInst(Value *Val, Value *Ptr, const std::vector<Value*> &Idx,
+ Instruction *InsertBefore)
+ : VMemoryInst(Type::VoidTy, VScatter, 0, 0, "", InsertBefore) {
+ init(Val, Ptr, Idx);
+}
+
+VScatterInst::VScatterInst(Value *Val, Value *Ptr, const std::vector<Value*> &Idx,
+ BasicBlock *InsertAtEnd)
+ : VMemoryInst(Type::VoidTy, VScatter, 0, 0, "", InsertAtEnd) {
+ init(Val, Ptr, Idx);
+}
+
+//===----------------------------------------------------------------------===//
+// VImmInst Implementation
+//===----------------------------------------------------------------------===//
+
+static const VectorType *VImmType(const Type* Ty, Value *Len, bool isFixed) {
+ if (!isFixed)
+ return VectorType::get(Ty);
+ ConstantUInt *C = dyn_cast<ConstantUInt>(Len);
+ assert(C && "Length operand of fixed vimm must be constant uint!");
+ return FixedVectorType::get(Ty, C->getValue());
+}
+
+VImmInst::VImmInst(Value *Val, Value *Len, bool isFixed,
+ const std::string &Name,
+ Instruction *InsertBef)
+ : Instruction(VImmType(Val->getType(), Len, isFixed),
+ VImm, Ops, 2, Name, InsertBef) {
+ Ops[0].init(Val, this);
+ Ops[1].init(Len, this);
+}
+
+VImmInst::VImmInst(Value *Val, Value *Len, bool isFixed,
+ const std::string &Name,
+ BasicBlock *InsertAE)
+ : Instruction(VImmType(Val->getType(), Len, isFixed),
+ VImm, Ops, 2, Name, InsertAE) {
+ Ops[0].init(Val, this);
+ Ops[1].init(Len, this);
+}
+
+//===----------------------------------------------------------------------===//
+// ExtractInst Implementation
+//===----------------------------------------------------------------------===//
+
+static const Type *getExtractType(const Type *Ty, Value *len) {
+ const VectorType *VTy = dyn_cast<VectorType>(Ty);
+ assert(VTy && "Extract inst must have vector type!");
+ // FIXME: Add a fixed attribute that says whether the result should
+ // be a fixed or variable vector (this is what vimm currently does).
+ // OR, we could explicitly encode the type in the assembly form. I
+ // haven't decided which is better.
+ //
+ if (isa<FixedVectorType>(Ty))
+ if (ConstantUInt *C = dyn_cast<ConstantUInt>(len))
+ return FixedVectorType::get(VTy->getElementType(), C->getValue());
+ return Ty;
+}
+
+ExtractInst::ExtractInst(Value *Val, Value *Start,
+ Value *Stride, Value *Len,
+ const std::string &Name, Instruction *InsertBef)
+ : Instruction(getExtractType(Val->getType(), Len),//Val->getType(),
+ Extract, Ops, 4, Name, InsertBef) {
+ Ops[0].init(Val, this);
+ Ops[1].init(Start, this);
+ Ops[2].init(Stride, this);
+ Ops[3].init(Len, this);
+}
+
+ExtractInst::ExtractInst(Value *Val, Value *Start,
+ Value *Stride, Value *Len,
+ const std::string &Name, BasicBlock *InsertAE)
+ : Instruction(getExtractType(Val->getType(), Len),//Val->getType(),
+ Extract, Ops, 4, Name, InsertAE) {
+ Ops[0].init(Val, this);
+ Ops[1].init(Start, this);
+ Ops[2].init(Stride, this);
+ Ops[3].init(Len, this);
+}
+
+//===----------------------------------------------------------------------===//
+// ExtractElementInst Implementation
+//===----------------------------------------------------------------------===//
+
+ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
+ const std::string &Name, Instruction *InsertBef)
+ : Instruction(cast<VectorType>(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<VectorType>(Val->getType())->getElementType(),
+ ExtractElement, Ops, 2, Name, InsertAE) {
+ Ops[0].init(Val, this);
+ Ops[1].init(Index, this);
+}
+
+//===----------------------------------------------------------------------===//
+// CombineInst Implementation
+//===----------------------------------------------------------------------===//
+
+CombineInst::CombineInst(Value *V1, Value *V2,
+ Value *Start, Value *Stride,
+ const std::string &Name, Instruction *InsertBef)
+ : Instruction(V1->getType(),
+ Combine, Ops, 4, Name, InsertBef) {
+ Ops[0].init(V1, this);
+ Ops[1].init(V2, this);
+ Ops[2].init(Start, this);
+ Ops[3].init(Stride, this);
+}
+
+CombineInst::CombineInst(Value *V1, Value *V2,
+ Value *Start, Value *Stride,
+ const std::string &Name, BasicBlock *InsertAE)
+ : Instruction(V1->getType(),
+ Combine, Ops, 4, Name, InsertAE) {
+ Ops[0].init(V1, this);
+ Ops[1].init(V2, this);
+ Ops[2].init(Start, this);
+ Ops[3].init(Stride, this);
+}
+
+//===----------------------------------------------------------------------===//
+// CombineElementInst Implementation
+//===----------------------------------------------------------------------===//
+
+CombineElementInst::CombineElementInst(Value *Vector, Value *Element, Value *Index,
+ const std::string &Name, Instruction *InsertBef)
+ : Instruction(Vector->getType(),
+ CombineElement, Ops, 3, Name, InsertBef) {
+ Ops[0].init(Vector, this);
+ Ops[1].init(Element, this);
+ Ops[2].init(Index, this);
+}
+
+CombineElementInst::CombineElementInst(Value *Vector, Value *Element, Value *Index,
+ const std::string &Name, BasicBlock *InsertAE)
+ : Instruction(Vector->getType(),
+ CombineElement, Ops, 3, Name, InsertAE) {
+ Ops[0].init(Vector, this);
+ Ops[1].init(Element, this);
+ Ops[2].init(Index, this);
+}
+
// Define these methods here so vtables don't get emitted into every translation
// unit that uses these classes.
@@ -1133,6 +1451,14 @@
return create(getOpcode(), Ops[0], Ops[1]);
}
+VGatherInst *VGatherInst::clone() const { return new VGatherInst(*this); }
+VScatterInst *VScatterInst::clone() const { return new VScatterInst(*this); }
+VImmInst *VImmInst::clone() const { return new VImmInst(*this); }
+ExtractInst *ExtractInst::clone() const { return new ExtractInst(*this); }
+ExtractElementInst *ExtractElementInst::clone() const { return new ExtractElementInst(*this); }
+CombineInst *CombineInst::clone() const { return new CombineInst(*this); }
+CombineElementInst *CombineElementInst::clone() const { return new CombineElementInst(*this); }
+
MallocInst *MallocInst::clone() const { return new MallocInst(*this); }
AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); }
FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); }
@@ -1142,6 +1468,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); }
+VSelectInst *VSelectInst::clone() const { return new VSelectInst(*this); }
VAArgInst *VAArgInst::clone() const { return new VAArgInst(*this); }
PHINode *PHINode::clone() const { return new PHINode(*this); }
ReturnInst *ReturnInst::clone() const { return new ReturnInst(*this); }
@@ -1150,3 +1477,4 @@
InvokeInst *InvokeInst::clone() const { return new InvokeInst(*this); }
UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
+
Index: llvm/lib/VMCore/Type.cpp
diff -u llvm/lib/VMCore/Type.cpp:1.129 llvm/lib/VMCore/Type.cpp:1.129.2.1
--- llvm/lib/VMCore/Type.cpp:1.129 Wed Jul 27 01:12:34 2005
+++ llvm/lib/VMCore/Type.cpp Tue Oct 18 14:21:58 2005
@@ -177,7 +177,7 @@
if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
return ATy->getElementType()->isSized();
- if (const PackedType *PTy = dyn_cast<PackedType>(this))
+ if (const FixedVectorType *PTy = dyn_cast<FixedVectorType>(this))
return PTy->getElementType()->isSized();
if (!isa<StructType>(this)) return false;
@@ -291,12 +291,24 @@
Result += getTypeDescription(ATy->getElementType(), TypeStack) + "]";
break;
}
- case Type::PackedTyID: {
- const PackedType *PTy = cast<PackedType>(Ty);
+ case Type::StreamTyID: {
+ const StreamType *STy = cast<StreamType>(Ty);
+ Result = "[stream of ";
+ Result += getTypeDescription(STy->getElementType(), TypeStack) + "]";
+ break;
+ }
+ case Type::VectorTyID: {
+ const VectorType *VTy = cast<VectorType>(Ty);
+ Result = "[vector of ";
+ Result += getTypeDescription(VTy->getElementType(), TypeStack) + "]";
+ break;
+ }
+ case Type::FixedVectorTyID: {
+ const FixedVectorType *PTy = cast<FixedVectorType>(Ty);
unsigned NumElements = PTy->getNumElements();
- Result = "<";
- Result += utostr(NumElements) + " x ";
- Result += getTypeDescription(PTy->getElementType(), TypeStack) + ">";
+ Result = "[vector of ";
+ Result += utostr(NumElements) + " ";
+ Result += getTypeDescription(PTy->getElementType(), TypeStack) + "]";
break;
}
default:
@@ -436,19 +448,27 @@
setAbstract(ElType->isAbstract());
}
-PackedType::PackedType(const Type *ElType, unsigned NumEl)
- : SequentialType(PackedTyID, ElType) {
- NumElements = NumEl;
+PointerType::PointerType(const Type *E) : SequentialType(PointerTyID, E) {
+ // Calculate whether or not this type is abstract
+ setAbstract(E->isAbstract());
+}
- assert(NumEl > 0 && "NumEl of a PackedType must be greater than 0");
- assert((ElType->isIntegral() || ElType->isFloatingPoint()) &&
- "Elements of a PackedType must be a primitive type");
+StreamType::StreamType(const Type *E)
+ : SequentialType(StreamTyID, E) {
+ assert((E->isIntegral() || E->isFloatingPoint() || isa<FixedVectorType>(E)) &&
+ "Elements of a StreamType must be a primitive or fixed vector type!");
}
+VectorType::VectorType(const Type *E, bool fixed)
+ : SequentialType(fixed ? FixedVectorTyID : VectorTyID, E) {
+ assert((E->isIntegral() || E->isFloatingPoint()) &&
+ "Elements of a VectorType must be a primitive type!");
+}
-PointerType::PointerType(const Type *E) : SequentialType(PointerTyID, E) {
- // Calculate whether or not this type is abstract
- setAbstract(E->isAbstract());
+FixedVectorType::FixedVectorType(const Type *ElType, unsigned NumEl)
+ : VectorType(ElType, true) {
+ NumElements = NumEl;
+ assert(NumEl > 0 && "NumEl of a FixedVectorType must be greater than 0!");
}
OpaqueType::OpaqueType() : DerivedType(OpaqueTyID) {
@@ -595,8 +615,8 @@
const ArrayType *ATy2 = cast<ArrayType>(Ty2);
return ATy->getNumElements() == ATy2->getNumElements() &&
TypesEqual(ATy->getElementType(), ATy2->getElementType(), EqTypes);
- } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
- const PackedType *PTy2 = cast<PackedType>(Ty2);
+ } else if (const FixedVectorType *PTy = dyn_cast<FixedVectorType>(Ty)) {
+ const FixedVectorType *PTy2 = cast<FixedVectorType>(Ty2);
return PTy->getNumElements() == PTy2->getNumElements() &&
TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes);
} else if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
@@ -971,20 +991,20 @@
//===----------------------------------------------------------------------===//
-// Packed Type Factory...
+// FixedVector Type Factory...
//
namespace llvm {
-class PackedValType {
+class FixedVectorValType {
const Type *ValTy;
unsigned Size;
public:
- PackedValType(const Type *val, int sz) : ValTy(val), Size(sz) {}
+ FixedVectorValType(const Type *val, int sz) : ValTy(val), Size(sz) {}
- static PackedValType get(const PackedType *PT) {
- return PackedValType(PT->getElementType(), PT->getNumElements());
+ static FixedVectorValType get(const FixedVectorType *PT) {
+ return FixedVectorValType(PT->getElementType(), PT->getNumElements());
}
- static unsigned hashTypeStructure(const PackedType *PT) {
+ static unsigned hashTypeStructure(const FixedVectorType *PT) {
return PT->getNumElements();
}
@@ -994,24 +1014,24 @@
ValTy = NewType;
}
- inline bool operator<(const PackedValType &MTV) const {
+ inline bool operator<(const FixedVectorValType &MTV) const {
if (Size < MTV.Size) return true;
return Size == MTV.Size && ValTy < MTV.ValTy;
}
};
}
-static TypeMap<PackedValType, PackedType> PackedTypes;
+static TypeMap<FixedVectorValType, FixedVectorType> FixedVectorTypes;
-PackedType *PackedType::get(const Type *ElementType, unsigned NumElements) {
- assert(ElementType && "Can't get packed of null types!");
+FixedVectorType *FixedVectorType::get(const Type *ElementType, unsigned NumElements) {
+ assert(ElementType && "Can't get fixed-length vector of null types!");
- PackedValType PVT(ElementType, NumElements);
- PackedType *PT = PackedTypes.get(PVT);
+ FixedVectorValType PVT(ElementType, NumElements);
+ FixedVectorType *PT = FixedVectorTypes.get(PVT);
if (PT) return PT; // Found a match, return it!
// Value not found. Derive a new type!
- PackedTypes.add(PVT, PT = new PackedType(ElementType, NumElements));
+ FixedVectorTypes.add(PVT, PT = new FixedVectorType(ElementType, NumElements));
#ifdef DEBUG_MERGE_TYPES
std::cerr << "Derived new type: " << *PT << "\n";
@@ -1130,6 +1150,102 @@
//===----------------------------------------------------------------------===//
+// Vector Type Factory...
+//
+namespace llvm {
+class VectorValType {
+ const Type *ValTy;
+public:
+ VectorValType(const Type *val) : ValTy(val) {}
+
+ static VectorValType get(const VectorType *AT) {
+ return VectorValType(AT->getElementType());
+ }
+
+ static unsigned hashTypeStructure(const VectorType *AT) {
+ return AT->getElementType()->getTypeID(); // ???
+ }
+
+ // Subclass should override this... to update self as usual
+ void doRefinement(const DerivedType *OldType, const Type *NewType) {
+ assert(ValTy == OldType);
+ ValTy = NewType;
+ }
+
+ inline bool operator<(const VectorValType &MTV) const {
+ return ValTy < MTV.ValTy;
+ }
+};
+}
+
+static TypeMap<VectorValType, VectorType> VectorTypes;
+
+VectorType *VectorType::get(const Type *ElementType) {
+ assert(ElementType && "Can't get vector of null types!");
+
+ VectorValType AVT(ElementType);
+ VectorType *AT = VectorTypes.get(AVT);
+ if (AT) return AT; // Found a match, return it!
+
+ // Value not found. Derive a new type!
+ VectorTypes.add(AVT, AT = new VectorType(ElementType));
+
+#ifdef DEBUG_MERGE_TYPES
+ std::cerr << "Derived new type: " << *AT << "\n";
+#endif
+ return AT;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Stream Type Factory...
+//
+namespace llvm {
+class StreamValType {
+ const Type *ValTy;
+public:
+ StreamValType(const Type *val) : ValTy(val) {}
+
+ static StreamValType get(const StreamType *AT) {
+ return StreamValType(AT->getElementType());
+ }
+
+ static unsigned hashTypeStructure(const StreamType *AT) {
+ return AT->getElementType()->getTypeID(); // ???
+ }
+
+ // Subclass should override this... to update self as usual
+ void doRefinement(const DerivedType *OldType, const Type *NewType) {
+ assert(ValTy == OldType);
+ ValTy = NewType;
+ }
+
+ inline bool operator<(const StreamValType &MTV) const {
+ return ValTy < MTV.ValTy;
+ }
+};
+}
+
+static TypeMap<StreamValType, StreamType> StreamTypes;
+
+StreamType *StreamType::get(const Type *ElementType) {
+ assert(ElementType && "Can't get vector of null types!");
+
+ StreamValType AVT(ElementType);
+ StreamType *AT = StreamTypes.get(AVT);
+ if (AT) return AT; // Found a match, return it!
+
+ // Value not found. Derive a new type!
+ StreamTypes.add(AVT, AT = new StreamType(ElementType));
+
+#ifdef DEBUG_MERGE_TYPES
+ std::cerr << "Derived new type: " << *AT << "\n";
+#endif
+ return AT;
+}
+
+
+//===----------------------------------------------------------------------===//
// Derived Type Refinement Functions
//===----------------------------------------------------------------------===//
@@ -1288,12 +1404,12 @@
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
-void PackedType::refineAbstractType(const DerivedType *OldType,
+void FixedVectorType::refineAbstractType(const DerivedType *OldType,
const Type *NewType) {
- PackedTypes.finishRefinement(this, OldType, NewType);
+ FixedVectorTypes.finishRefinement(this, OldType, NewType);
}
-void PackedType::typeBecameConcrete(const DerivedType *AbsTy) {
+void FixedVectorType::typeBecameConcrete(const DerivedType *AbsTy) {
refineAbstractType(AbsTy, AbsTy);
}
@@ -1323,6 +1439,34 @@
refineAbstractType(AbsTy, AbsTy);
}
+// refineAbstractType - Called when a contained type is found to be more
+// concrete - this could potentially change us from an abstract type to a
+// concrete type.
+//
+void VectorType::refineAbstractType(const DerivedType *OldType,
+ const Type *NewType) {
+ VectorTypes.finishRefinement(this, OldType, NewType);
+}
+
+void VectorType::typeBecameConcrete(const DerivedType *AbsTy) {
+ refineAbstractType(AbsTy, AbsTy);
+}
+
+
+// refineAbstractType - Called when a contained type is found to be more
+// concrete - this could potentially change us from an abstract type to a
+// concrete type.
+//
+void StreamType::refineAbstractType(const DerivedType *OldType,
+ const Type *NewType) {
+ StreamTypes.finishRefinement(this, OldType, NewType);
+}
+
+void StreamType::typeBecameConcrete(const DerivedType *AbsTy) {
+ refineAbstractType(AbsTy, AbsTy);
+}
+
+
bool SequentialType::indexValid(const Value *V) const {
const Type *Ty = V->getType();
switch (Ty->getTypeID()) {
@@ -1361,7 +1505,9 @@
PointerTypes.clear(DerivedTypes);
StructTypes.clear(DerivedTypes);
ArrayTypes.clear(DerivedTypes);
- PackedTypes.clear(DerivedTypes);
+ StreamTypes.clear(DerivedTypes);
+ VectorTypes.clear(DerivedTypes);
+ FixedVectorTypes.clear(DerivedTypes);
for(std::vector<Type *>::iterator I = DerivedTypes.begin(),
E = DerivedTypes.end(); I != E; ++I)
Index: llvm/lib/VMCore/Verifier.cpp
diff -u llvm/lib/VMCore/Verifier.cpp:1.134 llvm/lib/VMCore/Verifier.cpp:1.134.2.1
--- llvm/lib/VMCore/Verifier.cpp:1.134 Sat Jun 18 13:34:52 2005
+++ llvm/lib/VMCore/Verifier.cpp Tue Oct 18 14:21:58 2005
@@ -418,7 +418,8 @@
}
void Verifier::visitSelectInst(SelectInst &SI) {
- Assert1(SI.getCondition()->getType() == Type::BoolTy,
+ Assert1(SI.getCondition()->getType() == Type::BoolTy ||
+ SI.getCondition()->getType()->isBooleanVector(),
"Select condition type must be bool!", &SI);
Assert1(SI.getTrueValue()->getType() == SI.getFalseValue()->getType(),
"Select values must have identical types!", &SI);
@@ -498,30 +499,36 @@
// Check that logical operators are only used with integral operands.
if (B.getOpcode() == Instruction::And || B.getOpcode() == Instruction::Or ||
B.getOpcode() == Instruction::Xor) {
- Assert1(B.getType()->isIntegral(),
+ Assert1(B.getType()->isIntegral() ||
+ B.getType()->isIntegralVector(),
"Logical operators only work with integral types!", &B);
Assert1(B.getType() == B.getOperand(0)->getType(),
"Logical operators must have same type for operands and result!",
&B);
} else if (isa<SetCondInst>(B)) {
- // Check that setcc instructions return bool
- Assert1(B.getType() == Type::BoolTy,
- "setcc instructions must return boolean values!", &B);
+ // Check that setcc instructions return bool or bool vectors
+ if (B.getOpcode() < Instruction::VSetEQ)
+ Assert1(B.getType() == Type::BoolTy,
+ "setcc instructions must return boolean values!", &B);
+ else
+ Assert1(B.getType()->isBooleanVector(),
+ "vsetcc instructions must return boolean vector values!", &B);
} else {
// Arithmetic operators only work on integer or fp values
Assert1(B.getType() == B.getOperand(0)->getType(),
"Arithmetic operators must have same type for operands and result!",
&B);
- Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint() ||
- isa<PackedType>(B.getType()),
- "Arithmetic operators must have integer, fp, or packed type!", &B);
+ Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint() ||
+ isa<VectorType>(B.getType()),
+ "Arithmetic operators must have integer, fp, or vector type!", &B);
}
visitInstruction(B);
}
void Verifier::visitShiftInst(ShiftInst &SI) {
- Assert1(SI.getType()->isInteger(),
+ Assert1(SI.getType()->isInteger() ||
+ SI.getType()->isIntegerVector(),
"Shift must return an integer result!", &SI);
Assert1(SI.getType() == SI.getOperand(0)->getType(),
"Shift return type must be same as first operand!", &SI);
More information about the llvm-commits
mailing list