VMCore support for the insertelement operation.
authorRobert Bocchino <bocchino@illinois.edu>
Tue, 17 Jan 2006 20:07:22 +0000 (20:07 +0000)
committerRobert Bocchino <bocchino@illinois.edu>
Tue, 17 Jan 2006 20:07:22 +0000 (20:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25408 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/ConstantFold.cpp
lib/VMCore/ConstantFold.h
lib/VMCore/ConstantFolding.h
lib/VMCore/Constants.cpp
lib/VMCore/Instruction.cpp
lib/VMCore/Instructions.cpp
lib/VMCore/Verifier.cpp

index 3f7bc7db33a9be871c2f9dbdb77c0be4a6e4640f..a6fbf42fa24a4aa59784f0c9a9fe1a11767a2075 100644 (file)
@@ -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) {
index e8580c429051a5c94cfd0910852bdec44afb873d..7914a1cbfdae05e60d8a5d8d9812dba63225bfce 100644 (file)
@@ -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,
index e8580c429051a5c94cfd0910852bdec44afb873d..7914a1cbfdae05e60d8a5d8d9812dba63225bfce 100644 (file)
@@ -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,
index f4ff31f24f21213076c1eab023d13dbd555ed7ef..c8a5f356bc032d91cf36a09461feb2bd4fe37061 100644 (file)
@@ -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() {
index 8b13e6e75b79951a3fbba946c0f9b13be82361d3..a44b5e4b11ae410e338c5493c6b98fddcd64cacc 100644 (file)
@@ -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> ";
   }
index 06fbcf712cda1fbef8484bf1b5e2f1e58f39a939..0bd55c915123f93e82b62868287b34f251f82a53 100644 (file)
@@ -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,13 +808,33 @@ 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);
   Ops[1].init(Index, this);
 }
 
+//===----------------------------------------------------------------------===//
+//                           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); }
index ed73341e25ecf8d3de298c9dbacc175d1da0280a..9f4a6c894d922a0d83498dd44489530f94c42ee3 100644 (file)
@@ -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(),