Use the bool argument to hasConstantValue to decide whether the client is
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index 68b685e7fcb45724a622f39195a69b6a733f5362..efeb2c3766f19f27f60942bd5efd45097644448c 100644 (file)
@@ -132,6 +132,48 @@ 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)
+    return getIncomingValue(0);
+  
+  // 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())
+        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