DwarfWriter reading basic type information from llvm-gcc4 code.
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index 68b685e7fcb45724a622f39195a69b6a733f5362..0bd55c915123f93e82b62868287b34f251f82a53 100644 (file)
@@ -132,6 +132,52 @@ void PHINode::resizeOperands(unsigned NumOps) {
   OperandList = NewOps;
 }
 
+/// hasConstantValue - If the specified PHI node always merges together the same
+/// value, return the value, otherwise return null.
+///
+Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
+  // If the PHI node only has one incoming value, eliminate the PHI node...
+  if (getNumIncomingValues() == 1)
+    if (getIncomingValue(0) != this)   // not  X = phi X
+      return getIncomingValue(0);
+    else
+      return UndefValue::get(getType());  // Self cycle is dead.
+      
+  // Otherwise if all of the incoming values are the same for the PHI, replace
+  // the PHI node with the incoming value.
+  //
+  Value *InVal = 0;
+  bool HasUndefInput = false;
+  for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i)
+    if (isa<UndefValue>(getIncomingValue(i)))
+      HasUndefInput = true;
+    else if (getIncomingValue(i) != this)  // Not the PHI node itself...
+      if (InVal && getIncomingValue(i) != InVal)
+        return 0;  // Not the same, bail out.
+      else
+        InVal = getIncomingValue(i);
+  
+  // The only case that could cause InVal to be null is if we have a PHI node
+  // that only has entries for itself.  In this case, there is no entry into the
+  // loop, so kill the PHI.
+  //
+  if (InVal == 0) InVal = UndefValue::get(getType());
+  
+  // If we have a PHI node like phi(X, undef, X), where X is defined by some
+  // instruction, we cannot always return X as the result of the PHI node.  Only
+  // do this if X is not an instruction (thus it must dominate the PHI block),
+  // or if the client is prepared to deal with this possibility.
+  if (HasUndefInput && !AllowNonDominatingInstruction)
+    if (Instruction *IV = dyn_cast<Instruction>(InVal))
+      // If it's in the entry block, it dominates everything.
+      if (IV->getParent() != &IV->getParent()->getParent()->front() ||
+          isa<InvokeInst>(IV))
+        return 0;   // Cannot guarantee that InVal dominates this PHINode.
+
+  // All of the incoming values are the same, return the value now.
+  return InVal;
+}
+
 
 //===----------------------------------------------------------------------===//
 //                        CallInst Implementation
@@ -448,18 +494,20 @@ static Value *getAISize(Value *Amt) {
 }
 
 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
-                               const std::string &Name,
+                               unsigned Align, const std::string &Name,
                                Instruction *InsertBefore)
   : UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize),
-                     Name, InsertBefore) {
+                     Name, InsertBefore), Alignment(Align) {
+  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
 }
 
 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
-                               const std::string &Name,
+                               unsigned Align, const std::string &Name,
                                BasicBlock *InsertAtEnd)
   : UnaryInstruction(PointerType::get(Ty), iTy, getAISize(ArraySize),
-                     Name, InsertAtEnd) {
+                     Name, InsertAtEnd), Alignment(Align) {
+  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
 }
 
@@ -475,12 +523,12 @@ const Type *AllocationInst::getAllocatedType() const {
 
 AllocaInst::AllocaInst(const AllocaInst &AI)
   : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0),
-                   Instruction::Alloca) {
+                   Instruction::Alloca, AI.getAlignment()) {
 }
 
 MallocInst::MallocInst(const MallocInst &MI)
   : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
-                   Instruction::Malloc) {
+                   Instruction::Malloc, MI.getAlignment()) {
 }
 
 //===----------------------------------------------------------------------===//
@@ -747,6 +795,46 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
   return PTy->getElementType();
 }
 
+//===----------------------------------------------------------------------===//
+//                           ExtractElementInst Implementation
+//===----------------------------------------------------------------------===//
+
+ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
+                                       const std::string &Name, Instruction *InsertBef)
+  : Instruction(cast<PackedType>(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<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
 //===----------------------------------------------------------------------===//
@@ -763,16 +851,17 @@ void BinaryOperator::init(BinaryOps iType)
   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<PackedType>(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() ||
+            (isa<PackedType>(getType()) && 
+             cast<PackedType>(getType())->getElementType()->isIntegral())) &&
            "Tried to create a logical operation on a non-integral type!");
     break;
   case SetLT: case SetGT: case SetLE:
@@ -841,8 +930,17 @@ BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
 
 BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
                                           BasicBlock *InsertAtEnd) {
-  return new BinaryOperator(Instruction::Xor, Op,
-                            ConstantIntegral::getAllOnesValue(Op->getType()),
+  Constant *AllOnes;
+  if (const PackedType *PTy = dyn_cast<PackedType>(Op->getType())) {
+    // Create a vector of all ones values.
+    Constant *Elt = ConstantIntegral::getAllOnesValue(PTy->getElementType());
+    AllOnes = 
+      ConstantPacked::get(std::vector<Constant*>(PTy->getNumElements(), Elt));
+  } else {
+    AllOnes = ConstantIntegral::getAllOnesValue(Op->getType());
+  }
+  
+  return new BinaryOperator(Instruction::Xor, Op, AllOnes,
                             Op->getType(), Name, InsertAtEnd);
 }
 
@@ -1097,6 +1195,8 @@ CallInst   *CallInst::clone()   const { return new CallInst(*this); }
 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); }