aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bocchino <bocchino@illinois.edu>2006-01-17 20:07:22 +0000
committerRobert Bocchino <bocchino@illinois.edu>2006-01-17 20:07:22 +0000
commitc152f9cd26e7cb32352c513389a18ffd892ecaec (patch)
treeb584bdb434f8a0cca75c8606eb3d151239aa04fa
parent956fd7254f976581a27ba0ee73d7707ff484d2c3 (diff)
VMCore support for the insertelement operation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25408 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/VMCore/ConstantFold.cpp57
-rw-r--r--lib/VMCore/ConstantFold.h3
-rw-r--r--lib/VMCore/ConstantFolding.h3
-rw-r--r--lib/VMCore/Constants.cpp49
-rw-r--r--lib/VMCore/Instruction.cpp1
-rw-r--r--lib/VMCore/Instructions.cpp25
-rw-r--r--lib/VMCore/Verifier.cpp21
7 files changed, 150 insertions, 9 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 3f7bc7db33..a6fbf42fa2 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -734,6 +734,63 @@ Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val,
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) {
diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h
index e8580c4290..7914a1cbfd 100644
--- a/lib/VMCore/ConstantFold.h
+++ b/lib/VMCore/ConstantFold.h
@@ -33,6 +33,9 @@ namespace llvm {
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,
diff --git a/lib/VMCore/ConstantFolding.h b/lib/VMCore/ConstantFolding.h
index e8580c4290..7914a1cbfd 100644
--- a/lib/VMCore/ConstantFolding.h
+++ b/lib/VMCore/ConstantFolding.h
@@ -33,6 +33,9 @@ namespace llvm {
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,
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index f4ff31f24f..c8a5f356bc 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -347,8 +347,9 @@ public:
}
};
-/// 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 @@ public:
}
};
+/// 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 @@ namespace llvm {
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,11 +1435,35 @@ 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!");
+ "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...
//
void ConstantExpr::destroyConstant() {
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp
index 8b13e6e75b..a44b5e4b11 100644
--- a/lib/VMCore/Instruction.cpp
+++ b/lib/VMCore/Instruction.cpp
@@ -121,6 +121,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case Shr: return "shr";
case VAArg: return "va_arg";
case ExtractElement: return "extractelement";
+ case InsertElement: return "insertelement";
default: return "<Invalid operator> ";
}
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 06fbcf712c..0bd55c9151 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -800,7 +800,7 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
//===----------------------------------------------------------------------===//
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,
}
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 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
}
//===----------------------------------------------------------------------===//
+// 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 @@ 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); }
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 ed73341e25..9f4a6c894d 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -140,7 +140,7 @@ namespace { // Anonymous namespace for class
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 @@ namespace { // Anonymous namespace for class
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,12 +541,24 @@ void Verifier::visitExtractElementInst(ExtractElementInst &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);
+ 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) {
const Type *ElTy =
GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(),