Move types back to the 2.5 API.
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index 56bc8167c3c54d8d97386df13109169ecc717d67..08b439630749547da07e72a520b5ede7549c6331 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/BasicBlock.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
+#include "llvm/Operator.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/Support/MathExtras.h"
@@ -26,72 +27,77 @@ using namespace llvm;
 //                            CallSite Class
 //===----------------------------------------------------------------------===//
 
+#define CALLSITE_DELEGATE_GETTER(METHOD) \
+  Instruction *II(getInstruction());     \
+  return isCall()                        \
+    ? cast<CallInst>(II)->METHOD         \
+    : cast<InvokeInst>(II)->METHOD
+
+#define CALLSITE_DELEGATE_SETTER(METHOD) \
+  Instruction *II(getInstruction());     \
+  if (isCall())                          \
+    cast<CallInst>(II)->METHOD;          \
+  else                                   \
+    cast<InvokeInst>(II)->METHOD
+
 CallSite::CallSite(Instruction *C) {
   assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
-  I = C;
+  I.setPointer(C);
+  I.setInt(isa<CallInst>(C));
 }
 unsigned CallSite::getCallingConv() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->getCallingConv();
-  else
-    return cast<InvokeInst>(I)->getCallingConv();
+  CALLSITE_DELEGATE_GETTER(getCallingConv());
 }
 void CallSite::setCallingConv(unsigned CC) {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    CI->setCallingConv(CC);
-  else
-    cast<InvokeInst>(I)->setCallingConv(CC);
+  CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
 }
-const PAListPtr &CallSite::getParamAttrs() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->getParamAttrs();
-  else
-    return cast<InvokeInst>(I)->getParamAttrs();
+const AttrListPtr &CallSite::getAttributes() const {
+  CALLSITE_DELEGATE_GETTER(getAttributes());
 }
-void CallSite::setParamAttrs(const PAListPtr &PAL) {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    CI->setParamAttrs(PAL);
-  else
-    cast<InvokeInst>(I)->setParamAttrs(PAL);
+void CallSite::setAttributes(const AttrListPtr &PAL) {
+  CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
 }
-bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->paramHasAttr(i, attr);
-  else
-    return cast<InvokeInst>(I)->paramHasAttr(i, attr);
+bool CallSite::paramHasAttr(uint16_t i, Attributes attr) const {
+  CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
 }
 uint16_t CallSite::getParamAlignment(uint16_t i) const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->getParamAlignment(i);
-  else
-    return cast<InvokeInst>(I)->getParamAlignment(i);
+  CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
 }
-
 bool CallSite::doesNotAccessMemory() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->doesNotAccessMemory();
-  else
-    return cast<InvokeInst>(I)->doesNotAccessMemory();
+  CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
+}
+void CallSite::setDoesNotAccessMemory(bool doesNotAccessMemory) {
+  CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
 }
 bool CallSite::onlyReadsMemory() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->onlyReadsMemory();
-  else
-    return cast<InvokeInst>(I)->onlyReadsMemory();
+  CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
+}
+void CallSite::setOnlyReadsMemory(bool onlyReadsMemory) {
+  CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
+}
+bool CallSite::doesNotReturn() const {
+ CALLSITE_DELEGATE_GETTER(doesNotReturn());
+}
+void CallSite::setDoesNotReturn(bool doesNotReturn) {
+  CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
 }
 bool CallSite::doesNotThrow() const {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    return CI->doesNotThrow();
-  else
-    return cast<InvokeInst>(I)->doesNotThrow();
+  CALLSITE_DELEGATE_GETTER(doesNotThrow());
 }
 void CallSite::setDoesNotThrow(bool doesNotThrow) {
-  if (CallInst *CI = dyn_cast<CallInst>(I))
-    CI->setDoesNotThrow(doesNotThrow);
-  else
-    cast<InvokeInst>(I)->setDoesNotThrow(doesNotThrow);
+  CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
 }
 
+bool CallSite::hasArgument(const Value *Arg) const {
+  for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; ++AI)
+    if (AI->get() == Arg)
+      return true;
+  return false;
+}
+
+#undef CALLSITE_DELEGATE_GETTER
+#undef CALLSITE_DELEGATE_SETTER
+
 //===----------------------------------------------------------------------===//
 //                            TerminatorInst Class
 //===----------------------------------------------------------------------===//
@@ -100,10 +106,40 @@ void CallSite::setDoesNotThrow(bool doesNotThrow) {
 TerminatorInst::~TerminatorInst() {
 }
 
+//===----------------------------------------------------------------------===//
+//                           UnaryInstruction Class
+//===----------------------------------------------------------------------===//
+
 // Out of line virtual method, so the vtable, etc has a home.
 UnaryInstruction::~UnaryInstruction() {
 }
 
+//===----------------------------------------------------------------------===//
+//                              SelectInst Class
+//===----------------------------------------------------------------------===//
+
+/// areInvalidOperands - Return a string if the specified operands are invalid
+/// for a select operation, otherwise return null.
+const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
+  if (Op1->getType() != Op2->getType())
+    return "both values to select must have same type";
+  
+  if (const VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
+    // Vector select.
+    if (VT->getElementType() != Type::Int1Ty)
+      return "vector select condition element type must be i1";
+    const VectorType *ET = dyn_cast<VectorType>(Op1->getType());
+    if (ET == 0)
+      return "selected values for vector select must be vectors";
+    if (ET->getNumElements() != VT->getNumElements())
+      return "vector select requires selected vectors to have "
+                   "the same vector length as select condition";
+  } else if (Op0->getType() != Type::Int1Ty) {
+    return "select condition must be i1 or <n x i1>";
+  }
+  return 0;
+}
+
 
 //===----------------------------------------------------------------------===//
 //                               PHINode Class
@@ -111,17 +147,18 @@ UnaryInstruction::~UnaryInstruction() {
 
 PHINode::PHINode(const PHINode &PN)
   : Instruction(PN.getType(), Instruction::PHI,
-                new Use[PN.getNumOperands()], PN.getNumOperands()),
+                allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()),
     ReservedSpace(PN.getNumOperands()) {
   Use *OL = OperandList;
   for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
-    OL[i].init(PN.getOperand(i), this);
-    OL[i+1].init(PN.getOperand(i+1), this);
+    OL[i] = PN.getOperand(i);
+    OL[i+1] = PN.getOperand(i+1);
   }
 }
 
 PHINode::~PHINode() {
-  delete [] OperandList;
+  if (OperandList)
+    dropHungoffUses(OperandList);
 }
 
 // removeIncomingValue - Remove an incoming value.  This is useful if a
@@ -150,7 +187,7 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
   // If the PHI node is dead, because it has zero entries, nuke it now.
   if (NumOps == 2 && DeletePHIIfEmpty) {
     // If anyone is using this PHI, make them use a dummy value instead...
-    replaceAllUsesWith(UndefValue::get(getType()));
+    replaceAllUsesWith(getType()->getContext().getUndef(getType()));
     eraseFromParent();
   }
   return Removed;
@@ -164,8 +201,9 @@ Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
 ///   3. If NumOps == NumOperands, trim the reserved space.
 ///
 void PHINode::resizeOperands(unsigned NumOps) {
+  unsigned e = getNumOperands();
   if (NumOps == 0) {
-    NumOps = (getNumOperands())*3/2;
+    NumOps = e*3/2;
     if (NumOps < 4) NumOps = 4;      // 4 op PHI nodes are VERY common.
   } else if (NumOps*2 > NumOperands) {
     // No resize needed.
@@ -177,14 +215,11 @@ void PHINode::resizeOperands(unsigned NumOps) {
   }
 
   ReservedSpace = NumOps;
-  Use *NewOps = new Use[NumOps];
   Use *OldOps = OperandList;
-  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
-      NewOps[i].init(OldOps[i], this);
-      OldOps[i].set(0);
-  }
-  delete [] OldOps;
+  Use *NewOps = allocHungoffUses(NumOps);
+  std::copy(OldOps, OldOps + e, NewOps);
   OperandList = NewOps;
+  if (OldOps) Use::zap(OldOps, OldOps + e, true);
 }
 
 /// hasConstantValue - If the specified PHI node always merges together the same
@@ -196,7 +231,8 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
     if (getIncomingValue(0) != this)   // not  X = phi X
       return getIncomingValue(0);
     else
-      return UndefValue::get(getType());  // Self cycle is dead.
+      return
+        getType()->getContext().getUndef(getType());  // Self cycle is dead.
   }
       
   // Otherwise if all of the incoming values are the same for the PHI, replace
@@ -218,7 +254,7 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
   // 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 (InVal == 0) InVal = getType()->getContext().getUndef(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
@@ -241,13 +277,12 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
 //===----------------------------------------------------------------------===//
 
 CallInst::~CallInst() {
-  delete [] OperandList;
 }
 
 void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
-  NumOperands = NumParams+1;
-  Use *OL = OperandList = new Use[NumParams+1];
-  OL[0].init(Func, this);
+  assert(NumOperands == NumParams+1 && "NumOperands not set up?");
+  Use *OL = OperandList;
+  OL[0] = Func;
 
   const FunctionType *FTy =
     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
@@ -260,16 +295,16 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
     assert((i >= FTy->getNumParams() || 
             FTy->getParamType(i) == Params[i]->getType()) &&
            "Calling a function with a bad signature!");
-    OL[i+1].init(Params[i], this);
+    OL[i+1] = Params[i];
   }
 }
 
 void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
-  NumOperands = 3;
-  Use *OL = OperandList = new Use[3];
-  OL[0].init(Func, this);
-  OL[1].init(Actual1, this);
-  OL[2].init(Actual2, this);
+  assert(NumOperands == 3 && "NumOperands not set up?");
+  Use *OL = OperandList;
+  OL[0] = Func;
+  OL[1] = Actual1;
+  OL[2] = Actual2;
 
   const FunctionType *FTy =
     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
@@ -287,10 +322,10 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
 }
 
 void CallInst::init(Value *Func, Value *Actual) {
-  NumOperands = 2;
-  Use *OL = OperandList = new Use[2];
-  OL[0].init(Func, this);
-  OL[1].init(Actual, this);
+  assert(NumOperands == 2 && "NumOperands not set up?");
+  Use *OL = OperandList;
+  OL[0] = Func;
+  OL[1] = Actual;
 
   const FunctionType *FTy =
     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
@@ -305,9 +340,9 @@ void CallInst::init(Value *Func, Value *Actual) {
 }
 
 void CallInst::init(Value *Func) {
-  NumOperands = 1;
-  Use *OL = OperandList = new Use[1];
-  OL[0].init(Func, this);
+  assert(NumOperands == 1 && "NumOperands not set up?");
+  Use *OL = OperandList;
+  OL[0] = Func;
 
   const FunctionType *FTy =
     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
@@ -316,85 +351,93 @@ void CallInst::init(Value *Func) {
   assert(FTy->getNumParams() == 0 && "Calling a function with bad signature");
 }
 
-CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
+CallInst::CallInst(Value *Func, Value* Actual, const Twine &Name,
                    Instruction *InsertBefore)
   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
                                    ->getElementType())->getReturnType(),
-                Instruction::Call, 0, 0, InsertBefore) {
+                Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - 2,
+                2, InsertBefore) {
   init(Func, Actual);
   setName(Name);
 }
 
-CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
+CallInst::CallInst(Value *Func, Value* Actual, const Twine &Name,
                    BasicBlock  *InsertAtEnd)
   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
                                    ->getElementType())->getReturnType(),
-                Instruction::Call, 0, 0, InsertAtEnd) {
+                Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - 2,
+                2, InsertAtEnd) {
   init(Func, Actual);
   setName(Name);
 }
-CallInst::CallInst(Value *Func, const std::string &Name,
+CallInst::CallInst(Value *Func, const Twine &Name,
                    Instruction *InsertBefore)
   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
                                    ->getElementType())->getReturnType(),
-                Instruction::Call, 0, 0, InsertBefore) {
+                Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - 1,
+                1, InsertBefore) {
   init(Func);
   setName(Name);
 }
 
-CallInst::CallInst(Value *Func, const std::string &Name,
+CallInst::CallInst(Value *Func, const Twine &Name,
                    BasicBlock *InsertAtEnd)
   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
                                    ->getElementType())->getReturnType(),
-                Instruction::Call, 0, 0, InsertAtEnd) {
+                Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - 1,
+                1, InsertAtEnd) {
   init(Func);
   setName(Name);
 }
 
 CallInst::CallInst(const CallInst &CI)
-  : Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
+  : Instruction(CI.getType(), Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
                 CI.getNumOperands()) {
-  setParamAttrs(CI.getParamAttrs());
+  setAttributes(CI.getAttributes());
   SubclassData = CI.SubclassData;
   Use *OL = OperandList;
   Use *InOL = CI.OperandList;
   for (unsigned i = 0, e = CI.getNumOperands(); i != e; ++i)
-    OL[i].init(InOL[i], this);
+    OL[i] = InOL[i];
+}
+
+void CallInst::addAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
+  PAL = PAL.addAttr(i, attr);
+  setAttributes(PAL);
 }
 
-bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
-  if (ParamAttrs.paramHasAttr(i, attr))
+void CallInst::removeAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
+  PAL = PAL.removeAttr(i, attr);
+  setAttributes(PAL);
+}
+
+bool CallInst::paramHasAttr(unsigned i, Attributes attr) const {
+  if (AttributeList.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
   return false;
 }
 
-void CallInst::setDoesNotThrow(bool doesNotThrow) {
-  PAListPtr PAL = getParamAttrs();
-  if (doesNotThrow)
-    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
-  else
-    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
-  setParamAttrs(PAL);
-}
-
 
 //===----------------------------------------------------------------------===//
 //                        InvokeInst Implementation
 //===----------------------------------------------------------------------===//
 
-InvokeInst::~InvokeInst() {
-  delete [] OperandList;
-}
-
 void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
                       Value* const *Args, unsigned NumArgs) {
-  NumOperands = 3+NumArgs;
-  Use *OL = OperandList = new Use[3+NumArgs];
-  OL[0].init(Fn, this);
-  OL[1].init(IfNormal, this);
-  OL[2].init(IfException, this);
+  assert(NumOperands == 3+NumArgs && "NumOperands not set up?");
+  Use *OL = OperandList;
+  OL[0] = Fn;
+  OL[1] = IfNormal;
+  OL[2] = IfException;
   const FunctionType *FTy =
     cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
   FTy = FTy;  // silence warning.
@@ -408,18 +451,20 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
             FTy->getParamType(i) == Args[i]->getType()) &&
            "Invoking a function with a bad signature!");
     
-    OL[i+3].init(Args[i], this);
+    OL[i+3] = Args[i];
   }
 }
 
 InvokeInst::InvokeInst(const InvokeInst &II)
   : TerminatorInst(II.getType(), Instruction::Invoke,
-                   new Use[II.getNumOperands()], II.getNumOperands()) {
-  setParamAttrs(II.getParamAttrs());
+                   OperandTraits<InvokeInst>::op_end(this)
+                   - II.getNumOperands(),
+                   II.getNumOperands()) {
+  setAttributes(II.getAttributes());
   SubclassData = II.SubclassData;
   Use *OL = OperandList, *InOL = II.OperandList;
   for (unsigned i = 0, e = II.getNumOperands(); i != e; ++i)
-    OL[i].init(InOL[i], this);
+    OL[i] = InOL[i];
 }
 
 BasicBlock *InvokeInst::getSuccessorV(unsigned idx) const {
@@ -432,21 +477,24 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   return setSuccessor(idx, B);
 }
 
-bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
-  if (ParamAttrs.paramHasAttr(i, attr))
+bool InvokeInst::paramHasAttr(unsigned i, Attributes attr) const {
+  if (AttributeList.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
   return false;
 }
 
-void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
-  PAListPtr PAL = getParamAttrs();
-  if (doesNotThrow)
-    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
-  else
-    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
-  setParamAttrs(PAL);
+void InvokeInst::addAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
+  PAL = PAL.addAttr(i, attr);
+  setAttributes(PAL);
+}
+
+void InvokeInst::removeAttribute(unsigned i, Attributes attr) {
+  AttrListPtr PAL = getAttributes();
+  PAL = PAL.removeAttr(i, attr);
+  setAttributes(PAL);
 }
 
 
@@ -456,68 +504,30 @@ void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
 
 ReturnInst::ReturnInst(const ReturnInst &RI)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   &RetVal, RI.getNumOperands()) {
-  unsigned N = RI.getNumOperands();
-  if (N == 1) 
-    RetVal.init(RI.RetVal, this);
-  else if (N) {
-    Use *OL = OperandList = new Use[N];
-    for (unsigned i = 0; i < N; ++i)
-      OL[i].init(RI.getOperand(i), this);
-  }
+                   OperandTraits<ReturnInst>::op_end(this) -
+                     RI.getNumOperands(),
+                   RI.getNumOperands()) {
+  if (RI.getNumOperands())
+    Op<0>() = RI.Op<0>();
 }
 
 ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+                   InsertBefore) {
   if (retVal)
-    init(&retVal, 1);
+    Op<0>() = retVal;
 }
 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+                   InsertAtEnd) {
   if (retVal)
-    init(&retVal, 1);
+    Op<0>() = retVal;
 }
 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
-}
-
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
-                       Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertBefore) {
-  if (N != 0)
-    init(retVals, N);
-}
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
-                       BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertAtEnd) {
-  if (N != 0)
-    init(retVals, N);
-}
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N) {
-  if (N != 0)
-    init(retVals, N);
-}
-
-void ReturnInst::init(Value * const* retVals, unsigned N) {
-  assert (N > 0 && "Invalid operands numbers in ReturnInst init");
-
-  NumOperands = N;
-  if (NumOperands == 1) {
-    Value *V = *retVals;
-    if (V->getType() == Type::VoidTy)
-      return;
-    RetVal.init(V, this);
-    return;
-  }
-
-  Use *OL = OperandList = new Use[NumOperands];
-  for (unsigned i = 0; i < NumOperands; ++i) {
-    Value *V = *retVals++;
-    assert(!isa<BasicBlock>(V) &&
-           "Cannot return basic block.  Probably using the incorrect ctor");
-    OL[i].init(V, this);
-  }
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this), 0, InsertAtEnd) {
 }
 
 unsigned ReturnInst::getNumSuccessorsV() const {
@@ -527,18 +537,15 @@ unsigned ReturnInst::getNumSuccessorsV() const {
 /// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
 /// emit the vtable for the class in this translation unit.
 void ReturnInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
-  assert(0 && "ReturnInst has no successors!");
+  llvm_unreachable("ReturnInst has no successors!");
 }
 
 BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
-  assert(0 && "ReturnInst has no successors!");
-  abort();
+  llvm_unreachable("ReturnInst has no successors!");
   return 0;
 }
 
 ReturnInst::~ReturnInst() {
-  if (NumOperands > 1)
-    delete [] OperandList;
 }
 
 //===----------------------------------------------------------------------===//
@@ -558,12 +565,11 @@ unsigned UnwindInst::getNumSuccessorsV() const {
 }
 
 void UnwindInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
-  assert(0 && "UnwindInst has no successors!");
+  llvm_unreachable("UnwindInst has no successors!");
 }
 
 BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const {
-  assert(0 && "UnwindInst has no successors!");
-  abort();
+  llvm_unreachable("UnwindInst has no successors!");
   return 0;
 }
 
@@ -583,12 +589,11 @@ unsigned UnreachableInst::getNumSuccessorsV() const {
 }
 
 void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
-  assert(0 && "UnwindInst has no successors!");
+  llvm_unreachable("UnwindInst has no successors!");
 }
 
 BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const {
-  assert(0 && "UnwindInst has no successors!");
-  abort();
+  llvm_unreachable("UnwindInst has no successors!");
   return 0;
 }
 
@@ -603,33 +608,41 @@ void BranchInst::AssertOK() {
 }
 
 BranchInst::BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 1, InsertBefore) {
+  : TerminatorInst(Type::VoidTy, Instruction::Br,
+                   OperandTraits<BranchInst>::op_end(this) - 1,
+                   1, InsertBefore) {
   assert(IfTrue != 0 && "Branch destination may not be null!");
-  Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
+  Op<-1>() = IfTrue;
 }
 BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
                        Instruction *InsertBefore)
-: TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 3, InsertBefore) {
-  Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
-  Ops[1].init(reinterpret_cast<Value*>(IfFalse), this);
-  Ops[2].init(Cond, this);
+  : TerminatorInst(Type::VoidTy, Instruction::Br,
+                   OperandTraits<BranchInst>::op_end(this) - 3,
+                   3, InsertBefore) {
+  Op<-1>() = IfTrue;
+  Op<-2>() = IfFalse;
+  Op<-3>() = Cond;
 #ifndef NDEBUG
   AssertOK();
 #endif
 }
 
 BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 1, InsertAtEnd) {
+  : TerminatorInst(Type::VoidTy, Instruction::Br,
+                   OperandTraits<BranchInst>::op_end(this) - 1,
+                   1, InsertAtEnd) {
   assert(IfTrue != 0 && "Branch destination may not be null!");
-  Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
+  Op<-1>() = IfTrue;
 }
 
 BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
            BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Br, Ops, 3, InsertAtEnd) {
-  Ops[0].init(reinterpret_cast<Value*>(IfTrue), this);
-  Ops[1].init(reinterpret_cast<Value*>(IfFalse), this);
-  Ops[2].init(Cond, this);
+  : TerminatorInst(Type::VoidTy, Instruction::Br,
+                   OperandTraits<BranchInst>::op_end(this) - 3,
+                   3, InsertAtEnd) {
+  Op<-1>() = IfTrue;
+  Op<-2>() = IfFalse;
+  Op<-3>() = Cond;
 #ifndef NDEBUG
   AssertOK();
 #endif
@@ -637,15 +650,42 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
 
 
 BranchInst::BranchInst(const BranchInst &BI) :
-  TerminatorInst(Type::VoidTy, Instruction::Br, Ops, BI.getNumOperands()) {
-  OperandList[0].init(BI.getOperand(0), this);
+  TerminatorInst(Type::VoidTy, Instruction::Br,
+                 OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
+                 BI.getNumOperands()) {
+  Op<-1>() = BI.Op<-1>();
   if (BI.getNumOperands() != 1) {
     assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
-    OperandList[1].init(BI.getOperand(1), this);
-    OperandList[2].init(BI.getOperand(2), this);
+    Op<-3>() = BI.Op<-3>();
+    Op<-2>() = BI.Op<-2>();
+  }
+}
+
+
+Use* Use::getPrefix() {
+  PointerIntPair<Use**, 2, PrevPtrTag> &PotentialPrefix(this[-1].Prev);
+  if (PotentialPrefix.getOpaqueValue())
+    return 0;
+
+  return reinterpret_cast<Use*>((char*)&PotentialPrefix + 1);
+}
+
+BranchInst::~BranchInst() {
+  if (NumOperands == 1) {
+    if (Use *Prefix = OperandList->getPrefix()) {
+      Op<-1>() = 0;
+      //
+      // mark OperandList to have a special value for scrutiny
+      // by baseclass destructors and operator delete
+      OperandList = Prefix;
+    } else {
+      NumOperands = 3;
+      OperandList = op_begin();
+    }
   }
 }
 
+
 BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {
   return getSuccessor(idx);
 }
@@ -661,7 +701,7 @@ void BranchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
 //                        AllocationInst Implementation
 //===----------------------------------------------------------------------===//
 
-static Value *getAISize(Value *Amt) {
+static Value *getAISize(LLVMContext &Context, Value *Amt) {
   if (!Amt)
     Amt = ConstantInt::get(Type::Int32Ty, 1);
   else {
@@ -674,20 +714,20 @@ static Value *getAISize(Value *Amt) {
 }
 
 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
-                               unsigned Align, const std::string &Name,
+                               unsigned Align, const Twine &Name,
                                Instruction *InsertBefore)
-  : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
-                     InsertBefore) {
+  : UnaryInstruction(PointerType::getUnqual(Ty), iTy,
+                     getAISize(Ty->getContext(), ArraySize), InsertBefore) {
   setAlignment(Align);
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
   setName(Name);
 }
 
 AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
-                               unsigned Align, const std::string &Name,
+                               unsigned Align, const Twine &Name,
                                BasicBlock *InsertAtEnd)
-  : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
-                     InsertAtEnd) {
+  : UnaryInstruction(PointerType::getUnqual(Ty), iTy,
+                     getAISize(Ty->getContext(), ArraySize), InsertAtEnd) {
   setAlignment(Align);
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
   setName(Name);
@@ -714,13 +754,27 @@ const Type *AllocationInst::getAllocatedType() const {
 }
 
 AllocaInst::AllocaInst(const AllocaInst &AI)
-  : AllocationInst(AI.getType()->getElementType(), (Value*)AI.getOperand(0),
-                   Instruction::Alloca, AI.getAlignment()) {
+  : AllocationInst(AI.getType()->getElementType(),    
+                   (Value*)AI.getOperand(0), Instruction::Alloca,
+                   AI.getAlignment()) {
+}
+
+/// isStaticAlloca - Return true if this alloca is in the entry block of the
+/// function and is a constant size.  If so, the code generator will fold it
+/// into the prolog/epilog code, so it is basically free.
+bool AllocaInst::isStaticAlloca() const {
+  // Must be constant size.
+  if (!isa<ConstantInt>(getArraySize())) return false;
+  
+  // Must be in the entry block.
+  const BasicBlock *Parent = getParent();
+  return Parent == &Parent->getParent()->front();
 }
 
 MallocInst::MallocInst(const MallocInst &MI)
-  : AllocationInst(MI.getType()->getElementType(), (Value*)MI.getOperand(0),
-                   Instruction::Malloc, MI.getAlignment()) {
+  : AllocationInst(MI.getType()->getElementType(), 
+                   (Value*)MI.getOperand(0), Instruction::Malloc,
+                   MI.getAlignment()) {
 }
 
 //===----------------------------------------------------------------------===//
@@ -752,7 +806,7 @@ void LoadInst::AssertOK() {
          "Ptr must have pointer type.");
 }
 
-LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef)
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, Instruction *InsertBef)
   : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
                      Load, Ptr, InsertBef) {
   setVolatile(false);
@@ -761,7 +815,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef)
   setName(Name);
 }
 
-LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE)
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, BasicBlock *InsertAE)
   : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
                      Load, Ptr, InsertAE) {
   setVolatile(false);
@@ -770,7 +824,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE)
   setName(Name);
 }
 
-LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
                    Instruction *InsertBef)
   : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
                      Load, Ptr, InsertBef) {
@@ -780,7 +834,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
   setName(Name);
 }
 
-LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, 
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, 
                    unsigned Align, Instruction *InsertBef)
   : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
                      Load, Ptr, InsertBef) {
@@ -790,7 +844,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
   setName(Name);
 }
 
-LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, 
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile, 
                    unsigned Align, BasicBlock *InsertAE)
   : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
                      Load, Ptr, InsertAE) {
@@ -800,7 +854,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
   setName(Name);
 }
 
-LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
+LoadInst::LoadInst(Value *Ptr, const Twine &Name, bool isVolatile,
                    BasicBlock *InsertAE)
   : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
                      Load, Ptr, InsertAE) {
@@ -860,6 +914,7 @@ void LoadInst::setAlignment(unsigned Align) {
 //===----------------------------------------------------------------------===//
 
 void StoreInst::AssertOK() {
+  assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
   assert(isa<PointerType>(getOperand(1)->getType()) &&
          "Ptr must have pointer type!");
   assert(getOperand(0)->getType() ==
@@ -869,18 +924,24 @@ void StoreInst::AssertOK() {
 
 
 StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore)
-  : Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
-  Ops[0].init(val, this);
-  Ops[1].init(addr, this);
+  : Instruction(Type::VoidTy, Store,
+                OperandTraits<StoreInst>::op_begin(this),
+                OperandTraits<StoreInst>::operands(this),
+                InsertBefore) {
+  Op<0>() = val;
+  Op<1>() = addr;
   setVolatile(false);
   setAlignment(0);
   AssertOK();
 }
 
 StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
-  : Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
-  Ops[0].init(val, this);
-  Ops[1].init(addr, this);
+  : Instruction(Type::VoidTy, Store,
+                OperandTraits<StoreInst>::op_begin(this),
+                OperandTraits<StoreInst>::operands(this),
+                InsertAtEnd) {
+  Op<0>() = val;
+  Op<1>() = addr;
   setVolatile(false);
   setAlignment(0);
   AssertOK();
@@ -888,9 +949,12 @@ StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
 
 StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
                      Instruction *InsertBefore)
-  : Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
-  Ops[0].init(val, this);
-  Ops[1].init(addr, this);
+  : Instruction(Type::VoidTy, Store,
+                OperandTraits<StoreInst>::op_begin(this),
+                OperandTraits<StoreInst>::operands(this),
+                InsertBefore) {
+  Op<0>() = val;
+  Op<1>() = addr;
   setVolatile(isVolatile);
   setAlignment(0);
   AssertOK();
@@ -898,9 +962,12 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
 
 StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
                      unsigned Align, Instruction *InsertBefore)
-  : Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
-  Ops[0].init(val, this);
-  Ops[1].init(addr, this);
+  : Instruction(Type::VoidTy, Store,
+                OperandTraits<StoreInst>::op_begin(this),
+                OperandTraits<StoreInst>::operands(this),
+                InsertBefore) {
+  Op<0>() = val;
+  Op<1>() = addr;
   setVolatile(isVolatile);
   setAlignment(Align);
   AssertOK();
@@ -908,9 +975,12 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
 
 StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
                      unsigned Align, BasicBlock *InsertAtEnd)
-  : Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
-  Ops[0].init(val, this);
-  Ops[1].init(addr, this);
+  : Instruction(Type::VoidTy, Store,
+                OperandTraits<StoreInst>::op_begin(this),
+                OperandTraits<StoreInst>::operands(this),
+                InsertAtEnd) {
+  Op<0>() = val;
+  Op<1>() = addr;
   setVolatile(isVolatile);
   setAlignment(Align);
   AssertOK();
@@ -918,9 +988,12 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
 
 StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
                      BasicBlock *InsertAtEnd)
-  : Instruction(Type::VoidTy, Store, Ops, 2, InsertAtEnd) {
-  Ops[0].init(val, this);
-  Ops[1].init(addr, this);
+  : Instruction(Type::VoidTy, Store,
+                OperandTraits<StoreInst>::op_begin(this),
+                OperandTraits<StoreInst>::operands(this),
+                InsertAtEnd) {
+  Op<0>() = val;
+  Op<1>() = addr;
   setVolatile(isVolatile);
   setAlignment(0);
   AssertOK();
@@ -939,87 +1012,114 @@ static unsigned retrieveAddrSpace(const Value *Val) {
   return cast<PointerType>(Val->getType())->getAddressSpace();
 }
 
-void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx) {
-  NumOperands = 1+NumIdx;
-  Use *OL = OperandList = new Use[NumOperands];
-  OL[0].init(Ptr, this);
+void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx,
+                             const Twine &Name) {
+  assert(NumOperands == 1+NumIdx && "NumOperands not initialized?");
+  Use *OL = OperandList;
+  OL[0] = Ptr;
 
   for (unsigned i = 0; i != NumIdx; ++i)
-    OL[i+1].init(Idx[i], this);
-}
+    OL[i+1] = Idx[i];
 
-void GetElementPtrInst::init(Value *Ptr, Value *Idx) {
-  NumOperands = 2;
-  Use *OL = OperandList = new Use[2];
-  OL[0].init(Ptr, this);
-  OL[1].init(Idx, this);
-}
-
-GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
-                                     const std::string &Name, Instruction *InBe)
-  : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
-                                 retrieveAddrSpace(Ptr)),
-                GetElementPtr, 0, 0, InBe) {
-  init(Ptr, Idx);
   setName(Name);
 }
 
-GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
-                                     const std::string &Name, BasicBlock *IAE)
-  : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),Idx)),
-                                 retrieveAddrSpace(Ptr)),
-                GetElementPtr, 0, 0, IAE) {
-  init(Ptr, Idx);
+void GetElementPtrInst::init(Value *Ptr, Value *Idx, const Twine &Name) {
+  assert(NumOperands == 2 && "NumOperands not initialized?");
+  Use *OL = OperandList;
+  OL[0] = Ptr;
+  OL[1] = Idx;
+
   setName(Name);
 }
 
-GetElementPtrInst::~GetElementPtrInst() {
-  delete[] OperandList;
+GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI)
+  : Instruction(GEPI.getType(), GetElementPtr,
+                OperandTraits<GetElementPtrInst>::op_end(this)
+                - GEPI.getNumOperands(),
+                GEPI.getNumOperands()) {
+  Use *OL = OperandList;
+  Use *GEPIOL = GEPI.OperandList;
+  for (unsigned i = 0, E = NumOperands; i != E; ++i)
+    OL[i] = GEPIOL[i];
 }
 
-// getIndexedType - Returns the type of the element that would be loaded with
-// a load instruction with the specified parameters.
-//
-// A null type is returned if the indices are invalid for the specified
-// pointer type.
-//
-const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
-                                              Value* const *Idxs,
-                                              unsigned NumIdx,
-                                              bool AllowCompositeLeaf) {
-  if (!isa<PointerType>(Ptr)) return 0;   // Type isn't a pointer type!
-
-  // Handle the special case of the empty set index set...
-  if (NumIdx == 0) {
-    if (AllowCompositeLeaf ||
-        cast<PointerType>(Ptr)->getElementType()->isFirstClassType())
-      return cast<PointerType>(Ptr)->getElementType();
-    else
-      return 0;
-  }
+GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
+                                     const Twine &Name, Instruction *InBe)
+  : Instruction(PointerType::get(
+      checkType(getIndexedType(Ptr->getType(),Idx)), retrieveAddrSpace(Ptr)),
+                GetElementPtr,
+                OperandTraits<GetElementPtrInst>::op_end(this) - 2,
+                2, InBe) {
+  init(Ptr, Idx, Name);
+}
 
-  unsigned CurIdx = 0;
-  while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
-    if (NumIdx == CurIdx) {
-      if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr;
-      return 0;   // Can't load a whole structure or array!?!?
-    }
+GetElementPtrInst::GetElementPtrInst(Value *Ptr, Value *Idx,
+                                     const Twine &Name, BasicBlock *IAE)
+  : Instruction(PointerType::get(
+            checkType(getIndexedType(Ptr->getType(),Idx)),  
+                retrieveAddrSpace(Ptr)),
+                GetElementPtr,
+                OperandTraits<GetElementPtrInst>::op_end(this) - 2,
+                2, IAE) {
+  init(Ptr, Idx, Name);
+}
+
+/// getIndexedType - Returns the type of the element that would be accessed with
+/// a gep instruction with the specified parameters.
+///
+/// The Idxs pointer should point to a continuous piece of memory containing the
+/// indices, either as Value* or uint64_t.
+///
+/// A null type is returned if the indices are invalid for the specified
+/// pointer type.
+///
+template <typename IndexTy>
+static const Type* getIndexedTypeInternal(const Type *Ptr, IndexTy const *Idxs,
+                                          unsigned NumIdx) {
+  const PointerType *PTy = dyn_cast<PointerType>(Ptr);
+  if (!PTy) return 0;   // Type isn't a pointer type!
+  const Type *Agg = PTy->getElementType();
 
-    Value *Index = Idxs[CurIdx++];
-    if (isa<PointerType>(CT) && CurIdx != 1)
-      return 0;  // Can only index into pointer types at the first index!
+  // Handle the special case of the empty set index set, which is always valid.
+  if (NumIdx == 0)
+    return Agg;
+  
+  // If there is at least one index, the top level type must be sized, otherwise
+  // it cannot be 'stepped over'.  We explicitly allow abstract types (those
+  // that contain opaque types) under the assumption that it will be resolved to
+  // a sane type later.
+  if (!Agg->isSized() && !Agg->isAbstract())
+    return 0;
+
+  unsigned CurIdx = 1;
+  for (; CurIdx != NumIdx; ++CurIdx) {
+    const CompositeType *CT = dyn_cast<CompositeType>(Agg);
+    if (!CT || isa<PointerType>(CT)) return 0;
+    IndexTy Index = Idxs[CurIdx];
     if (!CT->indexValid(Index)) return 0;
-    Ptr = CT->getTypeAtIndex(Index);
+    Agg = CT->getTypeAtIndex(Index);
 
     // If the new type forwards to another type, then it is in the middle
     // of being refined to another type (and hence, may have dropped all
     // references to what it was using before).  So, use the new forwarded
     // type.
-    if (const Type * Ty = Ptr->getForwardedType()) {
-      Ptr = Ty;
-    }
+    if (const Type *Ty = Agg->getForwardedType())
+      Agg = Ty;
   }
-  return CurIdx == NumIdx ? Ptr : 0;
+  return CurIdx == NumIdx ? Agg : 0;
+}
+
+const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
+                                              Value* const *Idxs,
+                                              unsigned NumIdx) {
+  return getIndexedTypeInternal(Ptr, Idxs, NumIdx);
+}
+
+const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
+                                              uint64_t const *Idxs,
+                                              unsigned NumIdx) {
+  return getIndexedTypeInternal(Ptr, Idxs, NumIdx);
 }
 
 const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
@@ -1064,55 +1164,31 @@ bool GetElementPtrInst::hasAllConstantIndices() const {
 //===----------------------------------------------------------------------===//
 
 ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
-                                       const std::string &Name,
+                                       const Twine &Name,
                                        Instruction *InsertBef)
   : Instruction(cast<VectorType>(Val->getType())->getElementType(),
-                ExtractElement, Ops, 2, InsertBef) {
+                ExtractElement,
+                OperandTraits<ExtractElementInst>::op_begin(this),
+                2, InsertBef) {
   assert(isValidOperands(Val, Index) &&
          "Invalid extractelement instruction operands!");
-  Ops[0].init(Val, this);
-  Ops[1].init(Index, this);
+  Op<0>() = Val;
+  Op<1>() = Index;
   setName(Name);
 }
 
-ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
-                                       const std::string &Name,
-                                       Instruction *InsertBef)
-  : Instruction(cast<VectorType>(Val->getType())->getElementType(),
-                ExtractElement, Ops, 2, InsertBef) {
-  Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
-  assert(isValidOperands(Val, Index) &&
-         "Invalid extractelement instruction operands!");
-  Ops[0].init(Val, this);
-  Ops[1].init(Index, this);
-  setName(Name);
-}
-
-
 ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
-                                       const std::string &Name,
+                                       const Twine &Name,
                                        BasicBlock *InsertAE)
   : Instruction(cast<VectorType>(Val->getType())->getElementType(),
-                ExtractElement, Ops, 2, InsertAE) {
+                ExtractElement,
+                OperandTraits<ExtractElementInst>::op_begin(this),
+                2, InsertAE) {
   assert(isValidOperands(Val, Index) &&
          "Invalid extractelement instruction operands!");
 
-  Ops[0].init(Val, this);
-  Ops[1].init(Index, this);
-  setName(Name);
-}
-
-ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
-                                       const std::string &Name,
-                                       BasicBlock *InsertAE)
-  : Instruction(cast<VectorType>(Val->getType())->getElementType(),
-                ExtractElement, Ops, 2, InsertAE) {
-  Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
-  assert(isValidOperands(Val, Index) &&
-         "Invalid extractelement instruction operands!");
-  
-  Ops[0].init(Val, this);
-  Ops[1].init(Index, this);
+  Op<0>() = Val;
+  Op<1>() = Index;
   setName(Name);
 }
 
@@ -1129,61 +1205,38 @@ bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
 //===----------------------------------------------------------------------===//
 
 InsertElementInst::InsertElementInst(const InsertElementInst &IE)
-    : Instruction(IE.getType(), InsertElement, Ops, 3) {
-  Ops[0].init(IE.Ops[0], this);
-  Ops[1].init(IE.Ops[1], this);
-  Ops[2].init(IE.Ops[2], this);
+    : Instruction(IE.getType(), InsertElement,
+                  OperandTraits<InsertElementInst>::op_begin(this), 3) {
+  Op<0>() = IE.Op<0>();
+  Op<1>() = IE.Op<1>();
+  Op<2>() = IE.Op<2>();
 }
 InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
-                                     const std::string &Name,
-                                     Instruction *InsertBef)
-  : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertBef) {
-  assert(isValidOperands(Vec, Elt, Index) &&
-         "Invalid insertelement instruction operands!");
-  Ops[0].init(Vec, this);
-  Ops[1].init(Elt, this);
-  Ops[2].init(Index, this);
-  setName(Name);
-}
-
-InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
-                                     const std::string &Name,
+                                     const Twine &Name,
                                      Instruction *InsertBef)
-  : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertBef) {
-  Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
+  : Instruction(Vec->getType(), InsertElement,
+                OperandTraits<InsertElementInst>::op_begin(this),
+                3, InsertBef) {
   assert(isValidOperands(Vec, Elt, Index) &&
          "Invalid insertelement instruction operands!");
-  Ops[0].init(Vec, this);
-  Ops[1].init(Elt, this);
-  Ops[2].init(Index, this);
+  Op<0>() = Vec;
+  Op<1>() = Elt;
+  Op<2>() = Index;
   setName(Name);
 }
 
-
 InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
-                                     const std::string &Name,
+                                     const Twine &Name,
                                      BasicBlock *InsertAE)
-  : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertAE) {
+  : Instruction(Vec->getType(), InsertElement,
+                OperandTraits<InsertElementInst>::op_begin(this),
+                3, InsertAE) {
   assert(isValidOperands(Vec, Elt, Index) &&
          "Invalid insertelement instruction operands!");
 
-  Ops[0].init(Vec, this);
-  Ops[1].init(Elt, this);
-  Ops[2].init(Index, this);
-  setName(Name);
-}
-
-InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
-                                     const std::string &Name,
-                                     BasicBlock *InsertAE)
-: Instruction(Vec->getType(), InsertElement, Ops, 3, InsertAE) {
-  Constant *Index = ConstantInt::get(Type::Int32Ty, IndexV);
-  assert(isValidOperands(Vec, Elt, Index) &&
-         "Invalid insertelement instruction operands!");
-  
-  Ops[0].init(Vec, this);
-  Ops[1].init(Elt, this);
-  Ops[2].init(Index, this);
+  Op<0>() = Vec;
+  Op<1>() = Elt;
+  Op<2>() = Index;
   setName(Name);
 }
 
@@ -1196,7 +1249,7 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt,
     return false;// Second operand of insertelement must be vector element type.
     
   if (Index->getType() != Type::Int32Ty)
-    return false;  // Third operand of insertelement must be uint.
+    return false;  // Third operand of insertelement must be i32.
   return true;
 }
 
@@ -1206,48 +1259,55 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt,
 //===----------------------------------------------------------------------===//
 
 ShuffleVectorInst::ShuffleVectorInst(const ShuffleVectorInst &SV) 
-    : Instruction(SV.getType(), ShuffleVector, Ops, 3) {
-  Ops[0].init(SV.Ops[0], this);
-  Ops[1].init(SV.Ops[1], this);
-  Ops[2].init(SV.Ops[2], this);
+  : Instruction(SV.getType(), ShuffleVector,
+                OperandTraits<ShuffleVectorInst>::op_begin(this),
+                OperandTraits<ShuffleVectorInst>::operands(this)) {
+  Op<0>() = SV.Op<0>();
+  Op<1>() = SV.Op<1>();
+  Op<2>() = SV.Op<2>();
 }
 
 ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
-                                     const std::string &Name,
+                                     const Twine &Name,
                                      Instruction *InsertBefore)
-  : Instruction(V1->getType(), ShuffleVector, Ops, 3, InsertBefore) {
+: Instruction(VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
+                cast<VectorType>(Mask->getType())->getNumElements()),
+              ShuffleVector,
+              OperandTraits<ShuffleVectorInst>::op_begin(this),
+              OperandTraits<ShuffleVectorInst>::operands(this),
+              InsertBefore) {
   assert(isValidOperands(V1, V2, Mask) &&
          "Invalid shuffle vector instruction operands!");
-  Ops[0].init(V1, this);
-  Ops[1].init(V2, this);
-  Ops[2].init(Mask, this);
+  Op<0>() = V1;
+  Op<1>() = V2;
+  Op<2>() = Mask;
   setName(Name);
 }
 
 ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
-                                     const std::string &Name, 
+                                     const Twine &Name,
                                      BasicBlock *InsertAtEnd)
-  : Instruction(V1->getType(), ShuffleVector, Ops, 3, InsertAtEnd) {
+  : Instruction(V1->getType(), ShuffleVector,
+                OperandTraits<ShuffleVectorInst>::op_begin(this),
+                OperandTraits<ShuffleVectorInst>::operands(this),
+                InsertAtEnd) {
   assert(isValidOperands(V1, V2, Mask) &&
          "Invalid shuffle vector instruction operands!");
 
-  Ops[0].init(V1, this);
-  Ops[1].init(V2, this);
-  Ops[2].init(Mask, this);
+  Op<0>() = V1;
+  Op<1>() = V2;
+  Op<2>() = Mask;
   setName(Name);
 }
 
-bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, 
+bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
                                         const Value *Mask) {
-  if (!isa<VectorType>(V1->getType()) || 
-      V1->getType() != V2->getType()) 
+  if (!isa<VectorType>(V1->getType()) || V1->getType() != V2->getType())
     return false;
   
   const VectorType *MaskTy = dyn_cast<VectorType>(Mask->getType());
   if (!isa<Constant>(Mask) || MaskTy == 0 ||
-      MaskTy->getElementType() != Type::Int32Ty ||
-      MaskTy->getNumElements() != 
-      cast<VectorType>(V1->getType())->getNumElements())
+      MaskTy->getElementType() != Type::Int32Ty)
     return false;
   return true;
 }
@@ -1267,28 +1327,157 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const {
   return cast<ConstantInt>(MaskCV->getOperand(i))->getZExtValue();
 }
 
+//===----------------------------------------------------------------------===//
+//                             InsertValueInst Class
+//===----------------------------------------------------------------------===//
+
+void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx, 
+                           unsigned NumIdx, const Twine &Name) {
+  assert(NumOperands == 2 && "NumOperands not initialized?");
+  Op<0>() = Agg;
+  Op<1>() = Val;
+
+  Indices.insert(Indices.end(), Idx, Idx + NumIdx);
+  setName(Name);
+}
+
+void InsertValueInst::init(Value *Agg, Value *Val, unsigned Idx, 
+                           const Twine &Name) {
+  assert(NumOperands == 2 && "NumOperands not initialized?");
+  Op<0>() = Agg;
+  Op<1>() = Val;
+
+  Indices.push_back(Idx);
+  setName(Name);
+}
+
+InsertValueInst::InsertValueInst(const InsertValueInst &IVI)
+  : Instruction(IVI.getType(), InsertValue,
+                OperandTraits<InsertValueInst>::op_begin(this), 2),
+    Indices(IVI.Indices) {
+  Op<0>() = IVI.getOperand(0);
+  Op<1>() = IVI.getOperand(1);
+}
+
+InsertValueInst::InsertValueInst(Value *Agg,
+                                 Value *Val,
+                                 unsigned Idx, 
+                                 const Twine &Name,
+                                 Instruction *InsertBefore)
+  : Instruction(Agg->getType(), InsertValue,
+                OperandTraits<InsertValueInst>::op_begin(this),
+                2, InsertBefore) {
+  init(Agg, Val, Idx, Name);
+}
+
+InsertValueInst::InsertValueInst(Value *Agg,
+                                 Value *Val,
+                                 unsigned Idx, 
+                                 const Twine &Name,
+                                 BasicBlock *InsertAtEnd)
+  : Instruction(Agg->getType(), InsertValue,
+                OperandTraits<InsertValueInst>::op_begin(this),
+                2, InsertAtEnd) {
+  init(Agg, Val, Idx, Name);
+}
+
+//===----------------------------------------------------------------------===//
+//                             ExtractValueInst Class
+//===----------------------------------------------------------------------===//
+
+void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx,
+                            const Twine &Name) {
+  assert(NumOperands == 1 && "NumOperands not initialized?");
+
+  Indices.insert(Indices.end(), Idx, Idx + NumIdx);
+  setName(Name);
+}
+
+void ExtractValueInst::init(unsigned Idx, const Twine &Name) {
+  assert(NumOperands == 1 && "NumOperands not initialized?");
+
+  Indices.push_back(Idx);
+  setName(Name);
+}
+
+ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI)
+  : UnaryInstruction(EVI.getType(), ExtractValue, EVI.getOperand(0)),
+    Indices(EVI.Indices) {
+}
+
+// getIndexedType - Returns the type of the element that would be extracted
+// with an extractvalue instruction with the specified parameters.
+//
+// A null type is returned if the indices are invalid for the specified
+// pointer type.
+//
+const Type* ExtractValueInst::getIndexedType(const Type *Agg,
+                                             const unsigned *Idxs,
+                                             unsigned NumIdx) {
+  unsigned CurIdx = 0;
+  for (; CurIdx != NumIdx; ++CurIdx) {
+    const CompositeType *CT = dyn_cast<CompositeType>(Agg);
+    if (!CT || isa<PointerType>(CT) || isa<VectorType>(CT)) return 0;
+    unsigned Index = Idxs[CurIdx];
+    if (!CT->indexValid(Index)) return 0;
+    Agg = CT->getTypeAtIndex(Index);
+
+    // If the new type forwards to another type, then it is in the middle
+    // of being refined to another type (and hence, may have dropped all
+    // references to what it was using before).  So, use the new forwarded
+    // type.
+    if (const Type *Ty = Agg->getForwardedType())
+      Agg = Ty;
+  }
+  return CurIdx == NumIdx ? Agg : 0;
+}
+
+const Type* ExtractValueInst::getIndexedType(const Type *Agg,
+                                             unsigned Idx) {
+  return getIndexedType(Agg, &Idx, 1);
+}
 
 //===----------------------------------------------------------------------===//
 //                             BinaryOperator Class
 //===----------------------------------------------------------------------===//
 
+/// AdjustIType - Map Add, Sub, and Mul to FAdd, FSub, and FMul when the
+/// type is floating-point, to help provide compatibility with an older API.
+///
+static BinaryOperator::BinaryOps AdjustIType(BinaryOperator::BinaryOps iType,
+                                             const Type *Ty) {
+  // API compatibility: Adjust integer opcodes to floating-point opcodes.
+  if (Ty->isFPOrFPVector()) {
+    if (iType == BinaryOperator::Add) iType = BinaryOperator::FAdd;
+    else if (iType == BinaryOperator::Sub) iType = BinaryOperator::FSub;
+    else if (iType == BinaryOperator::Mul) iType = BinaryOperator::FMul;
+  }
+  return iType;
+}
+
 BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
-                               const Type *Ty, const std::string &Name,
+                               const Type *Ty, const Twine &Name,
                                Instruction *InsertBefore)
-  : Instruction(Ty, iType, Ops, 2, InsertBefore) {
-  Ops[0].init(S1, this);
-  Ops[1].init(S2, this);
-  init(iType);
+  : Instruction(Ty, AdjustIType(iType, Ty),
+                OperandTraits<BinaryOperator>::op_begin(this),
+                OperandTraits<BinaryOperator>::operands(this),
+                InsertBefore) {
+  Op<0>() = S1;
+  Op<1>() = S2;
+  init(AdjustIType(iType, Ty));
   setName(Name);
 }
 
 BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, 
-                               const Type *Ty, const std::string &Name,
+                               const Type *Ty, const Twine &Name,
                                BasicBlock *InsertAtEnd)
-  : Instruction(Ty, iType, Ops, 2, InsertAtEnd) {
-  Ops[0].init(S1, this);
-  Ops[1].init(S2, this);
-  init(iType);
+  : Instruction(Ty, AdjustIType(iType, Ty),
+                OperandTraits<BinaryOperator>::op_begin(this),
+                OperandTraits<BinaryOperator>::operands(this),
+                InsertAtEnd) {
+  Op<0>() = S1;
+  Op<1>() = S2;
+  init(AdjustIType(iType, Ty));
   setName(Name);
 }
 
@@ -1301,12 +1490,19 @@ void BinaryOperator::init(BinaryOps iType) {
 #ifndef NDEBUG
   switch (iType) {
   case Add: case Sub:
-  case Mul: 
+  case Mul:
     assert(getType() == LHS->getType() &&
            "Arithmetic operation should return same type as operands!");
-    assert((getType()->isInteger() || getType()->isFloatingPoint() ||
-            isa<VectorType>(getType())) &&
-          "Tried to create an arithmetic operation on a non-arithmetic type!");
+    assert(getType()->isIntOrIntVector() &&
+           "Tried to create an integer operation on a non-integer type!");
+    break;
+  case FAdd: case FSub:
+  case FMul:
+    assert(getType() == LHS->getType() &&
+           "Arithmetic operation should return same type as operands!");
+    assert(getType()->isFPOrFPVector() &&
+           "Tried to create a floating-point operation on a "
+           "non-floating-point type!");
     break;
   case UDiv: 
   case SDiv: 
@@ -1319,9 +1515,8 @@ void BinaryOperator::init(BinaryOps iType) {
   case FDiv:
     assert(getType() == LHS->getType() &&
            "Arithmetic operation should return same type as operands!");
-    assert((getType()->isFloatingPoint() || (isa<VectorType>(getType()) &&
-            cast<VectorType>(getType())->getElementType()->isFloatingPoint())) 
-            && "Incorrect operand type (not floating point) for FDIV");
+    assert(getType()->isFPOrFPVector() &&
+           "Incorrect operand type (not floating point) for FDIV");
     break;
   case URem: 
   case SRem: 
@@ -1334,17 +1529,18 @@ void BinaryOperator::init(BinaryOps iType) {
   case FRem:
     assert(getType() == LHS->getType() &&
            "Arithmetic operation should return same type as operands!");
-    assert((getType()->isFloatingPoint() || (isa<VectorType>(getType()) &&
-            cast<VectorType>(getType())->getElementType()->isFloatingPoint())) 
-            && "Incorrect operand type (not floating point) for FREM");
+    assert(getType()->isFPOrFPVector() &&
+           "Incorrect operand type (not floating point) for FREM");
     break;
   case Shl:
   case LShr:
   case AShr:
     assert(getType() == LHS->getType() &&
            "Shift operation should return same type as operands!");
-    assert(getType()->isInteger() && 
-           "Shift operation requires integer operands");
+    assert((getType()->isInteger() ||
+            (isa<VectorType>(getType()) && 
+             cast<VectorType>(getType())->getElementType()->isInteger())) &&
+           "Tried to create a shift operation on a non-integral type!");
     break;
   case And: case Or:
   case Xor:
@@ -1361,62 +1557,85 @@ void BinaryOperator::init(BinaryOps iType) {
 #endif
 }
 
-BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
-                                       const std::string &Name,
+BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2,
+                                       const Twine &Name,
                                        Instruction *InsertBefore) {
   assert(S1->getType() == S2->getType() &&
          "Cannot create binary operator with two operands of differing type!");
   return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore);
 }
 
-BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
-                                       const std::string &Name,
+BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2,
+                                       const Twine &Name,
                                        BasicBlock *InsertAtEnd) {
-  BinaryOperator *Res = create(Op, S1, S2, Name);
+  BinaryOperator *Res = Create(Op, S1, S2, Name);
   InsertAtEnd->getInstList().push_back(Res);
   return Res;
 }
 
-BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
+BinaryOperator *BinaryOperator::CreateNeg(LLVMContext &Context,
+                                          Value *Op, const Twine &Name,
                                           Instruction *InsertBefore) {
-  Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType());
+  Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
   return new BinaryOperator(Instruction::Sub,
                             zero, Op,
                             Op->getType(), Name, InsertBefore);
 }
 
-BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
+BinaryOperator *BinaryOperator::CreateNeg(LLVMContext &Context, 
+                                          Value *Op, const Twine &Name,
                                           BasicBlock *InsertAtEnd) {
-  Value *zero = ConstantExpr::getZeroValueForNegationExpr(Op->getType());
+  Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
   return new BinaryOperator(Instruction::Sub,
                             zero, Op,
                             Op->getType(), Name, InsertAtEnd);
 }
 
-BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
+BinaryOperator *BinaryOperator::CreateFNeg(LLVMContext &Context,
+                                           Value *Op, const Twine &Name,
+                                           Instruction *InsertBefore) {
+  Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
+  return new BinaryOperator(Instruction::FSub,
+                            zero, Op,
+                            Op->getType(), Name, InsertBefore);
+}
+
+BinaryOperator *BinaryOperator::CreateFNeg(LLVMContext &Context,
+                                           Value *Op, const Twine &Name,
+                                           BasicBlock *InsertAtEnd) {
+  Value *zero = ConstantFP::getZeroValueForNegation(Op->getType());
+  return new BinaryOperator(Instruction::FSub,
+                            zero, Op,
+                            Op->getType(), Name, InsertAtEnd);
+}
+
+BinaryOperator *BinaryOperator::CreateNot(LLVMContext &Context,
+                                          Value *Op, const Twine &Name,
                                           Instruction *InsertBefore) {
   Constant *C;
   if (const VectorType *PTy = dyn_cast<VectorType>(Op->getType())) {
-    C = ConstantInt::getAllOnesValue(PTy->getElementType());
-    C = ConstantVector::get(std::vector<Constant*>(PTy->getNumElements(), C));
+    C = Context.getAllOnesValue(PTy->getElementType());
+    C = ConstantVector::get(
+                              std::vector<Constant*>(PTy->getNumElements(), C));
   } else {
-    C = ConstantInt::getAllOnesValue(Op->getType());
+    C = Context.getAllOnesValue(Op->getType());
   }
   
   return new BinaryOperator(Instruction::Xor, Op, C,
                             Op->getType(), Name, InsertBefore);
 }
 
-BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
+BinaryOperator *BinaryOperator::CreateNot(LLVMContext &Context,
+                                          Value *Op, const Twine &Name,
                                           BasicBlock *InsertAtEnd) {
   Constant *AllOnes;
   if (const VectorType *PTy = dyn_cast<VectorType>(Op->getType())) {
     // Create a vector of all ones values.
-    Constant *Elt = ConstantInt::getAllOnesValue(PTy->getElementType());
-    AllOnes = 
-      ConstantVector::get(std::vector<Constant*>(PTy->getNumElements(), Elt));
+    Constant *Elt = Context.getAllOnesValue(PTy->getElementType());
+    AllOnes = ConstantVector::get(
+                            std::vector<Constant*>(PTy->getNumElements(), Elt));
   } else {
-    AllOnes = ConstantInt::getAllOnesValue(Op->getType());
+    AllOnes = Context.getAllOnesValue(Op->getType());
   }
   
   return new BinaryOperator(Instruction::Xor, Op, AllOnes,
@@ -1436,8 +1655,16 @@ static inline bool isConstantAllOnes(const Value *V) {
 bool BinaryOperator::isNeg(const Value *V) {
   if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
     if (Bop->getOpcode() == Instruction::Sub)
-      return Bop->getOperand(0) ==
-             ConstantExpr::getZeroValueForNegationExpr(Bop->getType());
+      if (Constant* C = dyn_cast<Constant>(Bop->getOperand(0)))
+        return C->isNegativeZeroValue();
+  return false;
+}
+
+bool BinaryOperator::isFNeg(const Value *V) {
+  if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
+    if (Bop->getOpcode() == Instruction::FSub)
+      if (Constant* C = dyn_cast<Constant>(Bop->getOperand(0)))
+      return C->isNegativeZeroValue();
   return false;
 }
 
@@ -1450,7 +1677,6 @@ bool BinaryOperator::isNot(const Value *V) {
 }
 
 Value *BinaryOperator::getNegArgument(Value *BinOp) {
-  assert(isNeg(BinOp) && "getNegArgument from non-'neg' instruction!");
   return cast<BinaryOperator>(BinOp)->getOperand(1);
 }
 
@@ -1458,6 +1684,14 @@ const Value *BinaryOperator::getNegArgument(const Value *BinOp) {
   return getNegArgument(const_cast<Value*>(BinOp));
 }
 
+Value *BinaryOperator::getFNegArgument(Value *BinOp) {
+  return cast<BinaryOperator>(BinOp)->getOperand(1);
+}
+
+const Value *BinaryOperator::getFNegArgument(const Value *BinOp) {
+  return getFNegArgument(const_cast<Value*>(BinOp));
+}
+
 Value *BinaryOperator::getNotArgument(Value *BinOp) {
   assert(isNot(BinOp) && "getNotArgument on non-'not' instruction!");
   BinaryOperator *BO = cast<BinaryOperator>(BinOp);
@@ -1482,7 +1716,7 @@ const Value *BinaryOperator::getNotArgument(const Value *BinOp) {
 bool BinaryOperator::swapOperands() {
   if (!isCommutative())
     return true; // Can't commute operands
-  std::swap(Ops[0], Ops[1]);
+  Op<0>().swap(Op<1>());
   return false;
 }
 
@@ -1524,10 +1758,9 @@ bool CastInst::isLosslessCast() const {
 /// changed in order to effect the cast. Essentially, it identifies cases where
 /// no code gen is necessary for the cast, hence the name no-op cast.  For 
 /// example, the following are all no-op casts:
-/// # bitcast uint %X, int
-/// # bitcast uint* %x, sbyte*
-/// # bitcast vector< 2 x int > %x, vector< 4 x short> 
-/// # ptrtoint uint* %x, uint     ; on 32-bit plaforms only
+/// # bitcast i32* %x to i8*
+/// # bitcast <2 x i32> %x to <4 x i16> 
+/// # ptrtoint i32* %x to i32     ; on 32-bit plaforms only
 /// @brief Determine if a cast is a no-op.
 bool CastInst::isNoopCast(const Type *IntPtrTy) const {
   switch (getOpcode()) {
@@ -1546,11 +1779,11 @@ bool CastInst::isNoopCast(const Type *IntPtrTy) const {
     case Instruction::BitCast:
       return true;  // BitCast never modifies bits.
     case Instruction::PtrToInt:
-      return IntPtrTy->getPrimitiveSizeInBits() ==
-            getType()->getPrimitiveSizeInBits();
+      return IntPtrTy->getScalarSizeInBits() ==
+             getType()->getScalarSizeInBits();
     case Instruction::IntToPtr:
-      return IntPtrTy->getPrimitiveSizeInBits() ==
-             getOperand(0)->getType()->getPrimitiveSizeInBits();
+      return IntPtrTy->getScalarSizeInBits() ==
+             getOperand(0)->getType()->getScalarSizeInBits();
   }
 }
 
@@ -1589,8 +1822,8 @@ unsigned CastInst::isEliminableCastPair(
   // BITCONVERT    =       FirstClass   n/a       FirstClass    n/a   
   //
   // NOTE: some transforms are safe, but we consider them to be non-profitable.
-  // For example, we could merge "fptoui double to uint" + "zext uint to ulong",
-  // into "fptoui double to ulong", but this loses information about the range
+  // For example, we could merge "fptoui double to i32" + "zext i32 to i64",
+  // into "fptoui double to i64", but this loses information about the range
   // of the produced value (we no longer know the top-part is all zeros). 
   // Further this conversion is often much more expensive for typical hardware,
   // and causes issues when building libgcc.  We disallow fptosi+sext for the 
@@ -1655,8 +1888,10 @@ unsigned CastInst::isEliminableCastPair(
       return 0;
     case 7: { 
       // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
-      unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
-      unsigned MidSize = MidTy->getPrimitiveSizeInBits();
+      if (!IntPtrTy)
+        return 0;
+      unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
+      unsigned MidSize = MidTy->getScalarSizeInBits();
       if (MidSize >= PtrSize)
         return Instruction::BitCast;
       return 0;
@@ -1665,8 +1900,8 @@ unsigned CastInst::isEliminableCastPair(
       // ext, trunc -> bitcast,    if the SrcTy and DstTy are same size
       // ext, trunc -> ext,        if sizeof(SrcTy) < sizeof(DstTy)
       // ext, trunc -> trunc,      if sizeof(SrcTy) > sizeof(DstTy)
-      unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
-      unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+      unsigned SrcSize = SrcTy->getScalarSizeInBits();
+      unsigned DstSize = DstTy->getScalarSizeInBits();
       if (SrcSize == DstSize)
         return Instruction::BitCast;
       else if (SrcSize < DstSize)
@@ -1694,9 +1929,11 @@ unsigned CastInst::isEliminableCastPair(
       return 0;
     case 13: {
       // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
-      unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
-      unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
-      unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+      if (!IntPtrTy)
+        return 0;
+      unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
+      unsigned SrcSize = SrcTy->getScalarSizeInBits();
+      unsigned DstSize = DstTy->getScalarSizeInBits();
       if (SrcSize <= PtrSize && SrcSize == DstSize)
         return Instruction::BitCast;
       return 0;
@@ -1713,8 +1950,8 @@ unsigned CastInst::isEliminableCastPair(
   return 0;
 }
 
-CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty, 
-  const std::string &Name, Instruction *InsertBefore) {
+CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty, 
+  const Twine &Name, Instruction *InsertBefore) {
   // Construct and return the appropriate CastInst subclass
   switch (op) {
     case Trunc:    return new TruncInst    (S, Ty, Name, InsertBefore);
@@ -1735,8 +1972,8 @@ CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
   return 0;
 }
 
-CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
-  const std::string &Name, BasicBlock *InsertAtEnd) {
+CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
+  const Twine &Name, BasicBlock *InsertAtEnd) {
   // Construct and return the appropriate CastInst subclass
   switch (op) {
     case Trunc:    return new TruncInst    (S, Ty, Name, InsertAtEnd);
@@ -1757,129 +1994,130 @@ CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
   return 0;
 }
 
-CastInst *CastInst::createZExtOrBitCast(Value *S, const Type *Ty, 
-                                        const std::string &Name,
+CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, 
+                                        const Twine &Name,
                                         Instruction *InsertBefore) {
-  if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
-    return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
-  return create(Instruction::ZExt, S, Ty, Name, InsertBefore);
+  if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
+    return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+  return Create(Instruction::ZExt, S, Ty, Name, InsertBefore);
 }
 
-CastInst *CastInst::createZExtOrBitCast(Value *S, const Type *Ty, 
-                                        const std::string &Name,
+CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty, 
+                                        const Twine &Name,
                                         BasicBlock *InsertAtEnd) {
-  if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
-    return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
-  return create(Instruction::ZExt, S, Ty, Name, InsertAtEnd);
+  if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
+    return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+  return Create(Instruction::ZExt, S, Ty, Name, InsertAtEnd);
 }
 
-CastInst *CastInst::createSExtOrBitCast(Value *S, const Type *Ty, 
-                                        const std::string &Name,
+CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, 
+                                        const Twine &Name,
                                         Instruction *InsertBefore) {
-  if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
-    return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
-  return create(Instruction::SExt, S, Ty, Name, InsertBefore);
+  if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
+    return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+  return Create(Instruction::SExt, S, Ty, Name, InsertBefore);
 }
 
-CastInst *CastInst::createSExtOrBitCast(Value *S, const Type *Ty, 
-                                        const std::string &Name,
+CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty, 
+                                        const Twine &Name,
                                         BasicBlock *InsertAtEnd) {
-  if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
-    return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
-  return create(Instruction::SExt, S, Ty, Name, InsertAtEnd);
+  if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
+    return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+  return Create(Instruction::SExt, S, Ty, Name, InsertAtEnd);
 }
 
-CastInst *CastInst::createTruncOrBitCast(Value *S, const Type *Ty,
-                                         const std::string &Name,
+CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
+                                         const Twine &Name,
                                          Instruction *InsertBefore) {
-  if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
-    return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
-  return create(Instruction::Trunc, S, Ty, Name, InsertBefore);
+  if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
+    return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+  return Create(Instruction::Trunc, S, Ty, Name, InsertBefore);
 }
 
-CastInst *CastInst::createTruncOrBitCast(Value *S, const Type *Ty,
-                                         const std::string &Name, 
+CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
+                                         const Twine &Name, 
                                          BasicBlock *InsertAtEnd) {
-  if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
-    return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
-  return create(Instruction::Trunc, S, Ty, Name, InsertAtEnd);
+  if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
+    return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+  return Create(Instruction::Trunc, S, Ty, Name, InsertAtEnd);
 }
 
-CastInst *CastInst::createPointerCast(Value *S, const Type *Ty,
-                                      const std::string &Name,
+CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty,
+                                      const Twine &Name,
                                       BasicBlock *InsertAtEnd) {
   assert(isa<PointerType>(S->getType()) && "Invalid cast");
   assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
          "Invalid cast");
 
   if (Ty->isInteger())
-    return create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd);
-  return create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
+    return Create(Instruction::PtrToInt, S, Ty, Name, InsertAtEnd);
+  return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
 }
 
 /// @brief Create a BitCast or a PtrToInt cast instruction
-CastInst *CastInst::createPointerCast(Value *S, const Type *Ty, 
-                                      const std::string &Name, 
+CastInst *CastInst::CreatePointerCast(Value *S, const Type *Ty, 
+                                      const Twine &Name, 
                                       Instruction *InsertBefore) {
   assert(isa<PointerType>(S->getType()) && "Invalid cast");
   assert((Ty->isInteger() || isa<PointerType>(Ty)) &&
          "Invalid cast");
 
   if (Ty->isInteger())
-    return create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
-  return create(Instruction::BitCast, S, Ty, Name, InsertBefore);
+    return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
+  return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
 }
 
-CastInst *CastInst::createIntegerCast(Value *C, const Type *Ty, 
-                                      bool isSigned, const std::string &Name,
+CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, 
+                                      bool isSigned, const Twine &Name,
                                       Instruction *InsertBefore) {
   assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
-  unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
-  unsigned DstBits = Ty->getPrimitiveSizeInBits();
+  unsigned SrcBits = C->getType()->getScalarSizeInBits();
+  unsigned DstBits = Ty->getScalarSizeInBits();
   Instruction::CastOps opcode =
     (SrcBits == DstBits ? Instruction::BitCast :
      (SrcBits > DstBits ? Instruction::Trunc :
       (isSigned ? Instruction::SExt : Instruction::ZExt)));
-  return create(opcode, C, Ty, Name, InsertBefore);
+  return Create(opcode, C, Ty, Name, InsertBefore);
 }
 
-CastInst *CastInst::createIntegerCast(Value *C, const Type *Ty, 
-                                      bool isSigned, const std::string &Name,
+CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty, 
+                                      bool isSigned, const Twine &Name,
                                       BasicBlock *InsertAtEnd) {
-  assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
-  unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
-  unsigned DstBits = Ty->getPrimitiveSizeInBits();
+  assert(C->getType()->isIntOrIntVector() && Ty->isIntOrIntVector() &&
+         "Invalid cast");
+  unsigned SrcBits = C->getType()->getScalarSizeInBits();
+  unsigned DstBits = Ty->getScalarSizeInBits();
   Instruction::CastOps opcode =
     (SrcBits == DstBits ? Instruction::BitCast :
      (SrcBits > DstBits ? Instruction::Trunc :
       (isSigned ? Instruction::SExt : Instruction::ZExt)));
-  return create(opcode, C, Ty, Name, InsertAtEnd);
+  return Create(opcode, C, Ty, Name, InsertAtEnd);
 }
 
-CastInst *CastInst::createFPCast(Value *C, const Type *Ty, 
-                                 const std::string &Name, 
+CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty, 
+                                 const Twine &Name, 
                                  Instruction *InsertBefore) {
-  assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && 
+  assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
          "Invalid cast");
-  unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
-  unsigned DstBits = Ty->getPrimitiveSizeInBits();
+  unsigned SrcBits = C->getType()->getScalarSizeInBits();
+  unsigned DstBits = Ty->getScalarSizeInBits();
   Instruction::CastOps opcode =
     (SrcBits == DstBits ? Instruction::BitCast :
      (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
-  return create(opcode, C, Ty, Name, InsertBefore);
+  return Create(opcode, C, Ty, Name, InsertBefore);
 }
 
-CastInst *CastInst::createFPCast(Value *C, const Type *Ty, 
-                                 const std::string &Name, 
+CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty, 
+                                 const Twine &Name, 
                                  BasicBlock *InsertAtEnd) {
-  assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() && 
+  assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
          "Invalid cast");
-  unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
-  unsigned DstBits = Ty->getPrimitiveSizeInBits();
+  unsigned SrcBits = C->getType()->getScalarSizeInBits();
+  unsigned DstBits = Ty->getScalarSizeInBits();
   Instruction::CastOps opcode =
     (SrcBits == DstBits ? Instruction::BitCast :
      (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
-  return create(opcode, C, Ty, Name, InsertAtEnd);
+  return Create(opcode, C, Ty, Name, InsertAtEnd);
 }
 
 // Check whether it is valid to call getCastOpcode for these types.
@@ -1892,49 +2130,49 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
     return true;
 
   // Get the bit sizes, we'll need these
-  unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr/vector
-  unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+  unsigned SrcBits = SrcTy->getScalarSizeInBits();   // 0 for ptr
+  unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
 
   // Run through the possibilities ...
-  if (DestTy->isInteger()) {                      // Casting to integral
-    if (SrcTy->isInteger()) {                     // Casting from integral
+  if (DestTy->isInteger()) {                   // Casting to integral
+    if (SrcTy->isInteger()) {                  // Casting from integral
         return true;
-    } else if (SrcTy->isFloatingPoint()) {        // Casting from floating pt
+    } else if (SrcTy->isFloatingPoint()) {     // Casting from floating pt
       return true;
     } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
-                                                  // Casting from vector
+                                               // Casting from vector
       return DestBits == PTy->getBitWidth();
-    } else {                                      // Casting from something else
+    } else {                                   // Casting from something else
       return isa<PointerType>(SrcTy);
     }
-  } else if (DestTy->isFloatingPoint()) {         // Casting to floating pt
-    if (SrcTy->isInteger()) {                     // Casting from integral
+  } else if (DestTy->isFloatingPoint()) {      // Casting to floating pt
+    if (SrcTy->isInteger()) {                  // Casting from integral
       return true;
-    } else if (SrcTy->isFloatingPoint()) {        // Casting from floating pt
+    } else if (SrcTy->isFloatingPoint()) {     // Casting from floating pt
       return true;
     } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
-                                                  // Casting from vector
+                                               // Casting from vector
       return DestBits == PTy->getBitWidth();
-    } else {                                      // Casting from something else
+    } else {                                   // Casting from something else
       return false;
     }
   } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
-                                                   // Casting to vector
+                                                // Casting to vector
     if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
-                                                   // Casting from vector
+                                                // Casting from vector
       return DestPTy->getBitWidth() == SrcPTy->getBitWidth();
-    } else {                                       // Casting from something else
+    } else {                                    // Casting from something else
       return DestPTy->getBitWidth() == SrcBits;
     }
-  } else if (isa<PointerType>(DestTy)) {           // Casting to pointer
-    if (isa<PointerType>(SrcTy)) {                 // Casting from pointer
+  } else if (isa<PointerType>(DestTy)) {        // Casting to pointer
+    if (isa<PointerType>(SrcTy)) {              // Casting from pointer
       return true;
-    } else if (SrcTy->isInteger()) {               // Casting from integral
+    } else if (SrcTy->isInteger()) {            // Casting from integral
       return true;
-    } else {                                       // Casting from something else
+    } else {                                    // Casting from something else
       return false;
     }
-  } else {                                         // Casting to something else
+  } else {                                      // Casting to something else
     return false;
   }
 }
@@ -1951,8 +2189,8 @@ CastInst::getCastOpcode(
   const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
   // Get the bit sizes, we'll need these
   const Type *SrcTy = Src->getType();
-  unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr/vector
-  unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
+  unsigned SrcBits = SrcTy->getScalarSizeInBits();   // 0 for ptr
+  unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
 
   assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
          "Only first class types are castable!");
@@ -1978,6 +2216,7 @@ CastInst::getCastOpcode(
     } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
       assert(DestBits == PTy->getBitWidth() &&
                "Casting vector to integer of different width");
+      PTy = NULL;
       return BitCast;                             // Same size, no-op cast
     } else {
       assert(isa<PointerType>(SrcTy) &&
@@ -2001,14 +2240,16 @@ CastInst::getCastOpcode(
     } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
       assert(DestBits == PTy->getBitWidth() &&
              "Casting vector to floating point of different width");
-        return BitCast;                             // same size, no-op cast
+      PTy = NULL;
+      return BitCast;                             // same size, no-op cast
     } else {
-      assert(0 && "Casting pointer or non-first class to float");
+      llvm_unreachable("Casting pointer or non-first class to float");
     }
   } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
     if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
       assert(DestPTy->getBitWidth() == SrcPTy->getBitWidth() &&
              "Casting vector to vector of different widths");
+      SrcPTy = NULL;
       return BitCast;                             // vector -> vector
     } else if (DestPTy->getBitWidth() == SrcBits) {
       return BitCast;                               // float/int -> vector
@@ -2050,44 +2291,49 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
     return false;
 
   // Get the size of the types in bits, we'll need this later
-  unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
-  unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
+  unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
+  unsigned DstBitSize = DstTy->getScalarSizeInBits();
 
   // Switch on the opcode provided
   switch (op) {
   default: return false; // This is an input error
   case Instruction::Trunc:
-    return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize > DstBitSize;
+    return SrcTy->isIntOrIntVector() &&
+           DstTy->isIntOrIntVector()&& SrcBitSize > DstBitSize;
   case Instruction::ZExt:
-    return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize;
+    return SrcTy->isIntOrIntVector() &&
+           DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
   case Instruction::SExt: 
-    return SrcTy->isInteger() && DstTy->isInteger()&& SrcBitSize < DstBitSize;
+    return SrcTy->isIntOrIntVector() &&
+           DstTy->isIntOrIntVector()&& SrcBitSize < DstBitSize;
   case Instruction::FPTrunc:
-    return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && 
-      SrcBitSize > DstBitSize;
+    return SrcTy->isFPOrFPVector() &&
+           DstTy->isFPOrFPVector() && 
+           SrcBitSize > DstBitSize;
   case Instruction::FPExt:
-    return SrcTy->isFloatingPoint() && DstTy->isFloatingPoint() && 
-      SrcBitSize < DstBitSize;
+    return SrcTy->isFPOrFPVector() &&
+           DstTy->isFPOrFPVector() && 
+           SrcBitSize < DstBitSize;
   case Instruction::UIToFP:
   case Instruction::SIToFP:
     if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
       if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
-        return SVTy->getElementType()->isInteger() &&
-               DVTy->getElementType()->isFloatingPoint() &&
+        return SVTy->getElementType()->isIntOrIntVector() &&
+               DVTy->getElementType()->isFPOrFPVector() &&
                SVTy->getNumElements() == DVTy->getNumElements();
       }
     }
-    return SrcTy->isInteger() && DstTy->isFloatingPoint();
+    return SrcTy->isIntOrIntVector() && DstTy->isFPOrFPVector();
   case Instruction::FPToUI:
   case Instruction::FPToSI:
     if (const VectorType *SVTy = dyn_cast<VectorType>(SrcTy)) {
       if (const VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
-        return SVTy->getElementType()->isFloatingPoint() &&
-               DVTy->getElementType()->isInteger() &&
+        return SVTy->getElementType()->isFPOrFPVector() &&
+               DVTy->getElementType()->isIntOrIntVector() &&
                SVTy->getNumElements() == DVTy->getNumElements();
       }
     }
-    return SrcTy->isFloatingPoint() && DstTy->isInteger();
+    return SrcTy->isFPOrFPVector() && DstTy->isIntOrIntVector();
   case Instruction::PtrToInt:
     return isa<PointerType>(SrcTy) && DstTy->isInteger();
   case Instruction::IntToPtr:
@@ -2101,149 +2347,149 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
     // Now we know we're not dealing with a pointer/non-pointer mismatch. In all
     // these cases, the cast is okay if the source and destination bit widths
     // are identical.
-    return SrcBitSize == DstBitSize;
+    return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
   }
 }
 
 TruncInst::TruncInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, Trunc, S, Name, InsertBefore) {
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc");
 }
 
 TruncInst::TruncInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, Trunc, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc");
 }
 
 ZExtInst::ZExtInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 )  : CastInst(Ty, ZExt, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt");
 }
 
 ZExtInst::ZExtInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 )  : CastInst(Ty, ZExt, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt");
 }
 SExtInst::SExtInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, SExt, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt");
 }
 
 SExtInst::SExtInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 )  : CastInst(Ty, SExt, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt");
 }
 
 FPTruncInst::FPTruncInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, FPTrunc, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc");
 }
 
 FPTruncInst::FPTruncInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, FPTrunc, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc");
 }
 
 FPExtInst::FPExtInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, FPExt, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt");
 }
 
 FPExtInst::FPExtInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, FPExt, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt");
 }
 
 UIToFPInst::UIToFPInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, UIToFP, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP");
 }
 
 UIToFPInst::UIToFPInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, UIToFP, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP");
 }
 
 SIToFPInst::SIToFPInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, SIToFP, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP");
 }
 
 SIToFPInst::SIToFPInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, SIToFP, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP");
 }
 
 FPToUIInst::FPToUIInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, FPToUI, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI");
 }
 
 FPToUIInst::FPToUIInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, FPToUI, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI");
 }
 
 FPToSIInst::FPToSIInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, FPToSI, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI");
 }
 
 FPToSIInst::FPToSIInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, FPToSI, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI");
 }
 
 PtrToIntInst::PtrToIntInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, PtrToInt, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt");
 }
 
 PtrToIntInst::PtrToIntInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, PtrToInt, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt");
 }
 
 IntToPtrInst::IntToPtrInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, IntToPtr, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr");
 }
 
 IntToPtrInst::IntToPtrInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, IntToPtr, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr");
 }
 
 BitCastInst::BitCastInst(
-  Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
+  Value *S, const Type *Ty, const Twine &Name, Instruction *InsertBefore
 ) : CastInst(Ty, BitCast, S, Name, InsertBefore) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast");
 }
 
 BitCastInst::BitCastInst(
-  Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd
+  Value *S, const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd
 ) : CastInst(Ty, BitCast, S, Name, InsertAtEnd) { 
   assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast");
 }
@@ -2252,91 +2498,62 @@ BitCastInst::BitCastInst(
 //                               CmpInst Classes
 //===----------------------------------------------------------------------===//
 
-CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
-                 const std::string &Name, Instruction *InsertBefore)
-  : Instruction(Type::Int1Ty, op, Ops, 2, InsertBefore) {
-    Ops[0].init(LHS, this);
-    Ops[1].init(RHS, this);
+CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate,
+                 Value *LHS, Value *RHS, const Twine &Name,
+                 Instruction *InsertBefore)
+  : Instruction(ty, op,
+                OperandTraits<CmpInst>::op_begin(this),
+                OperandTraits<CmpInst>::operands(this),
+                InsertBefore) {
+    Op<0>() = LHS;
+    Op<1>() = RHS;
   SubclassData = predicate;
   setName(Name);
-  if (op == Instruction::ICmp) {
-    assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE &&
-           predicate <= ICmpInst::LAST_ICMP_PREDICATE &&
-           "Invalid ICmp predicate value");
-    const Type* Op0Ty = getOperand(0)->getType();
-    const Type* Op1Ty = getOperand(1)->getType();
-    assert(Op0Ty == Op1Ty &&
-           "Both operands to ICmp instruction are not of the same type!");
-    // Check that the operands are the right type
-    assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
-           "Invalid operand types for ICmp instruction");
-    return;
-  }
-  assert(op == Instruction::FCmp && "Invalid CmpInst opcode");
-  assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE &&
-         "Invalid FCmp predicate value");
-  const Type* Op0Ty = getOperand(0)->getType();
-  const Type* Op1Ty = getOperand(1)->getType();
-  assert(Op0Ty == Op1Ty &&
-         "Both operands to FCmp instruction are not of the same type!");
-  // Check that the operands are the right type
-  assert(Op0Ty->isFloatingPoint() &&
-         "Invalid operand types for FCmp instruction");
 }
-  
-CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
-                 const std::string &Name, BasicBlock *InsertAtEnd)
-  : Instruction(Type::Int1Ty, op, Ops, 2, InsertAtEnd) {
-  Ops[0].init(LHS, this);
-  Ops[1].init(RHS, this);
+
+CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate,
+                 Value *LHS, Value *RHS, const Twine &Name,
+                 BasicBlock *InsertAtEnd)
+  : Instruction(ty, op,
+                OperandTraits<CmpInst>::op_begin(this),
+                OperandTraits<CmpInst>::operands(this),
+                InsertAtEnd) {
+  Op<0>() = LHS;
+  Op<1>() = RHS;
   SubclassData = predicate;
   setName(Name);
-  if (op == Instruction::ICmp) {
-    assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE &&
-           predicate <= ICmpInst::LAST_ICMP_PREDICATE &&
-           "Invalid ICmp predicate value");
-
-    const Type* Op0Ty = getOperand(0)->getType();
-    const Type* Op1Ty = getOperand(1)->getType();
-    assert(Op0Ty == Op1Ty &&
-          "Both operands to ICmp instruction are not of the same type!");
-    // Check that the operands are the right type
-    assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
-           "Invalid operand types for ICmp instruction");
-    return;
-  }
-  assert(op == Instruction::FCmp && "Invalid CmpInst opcode");
-  assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE &&
-         "Invalid FCmp predicate value");
-  const Type* Op0Ty = getOperand(0)->getType();
-  const Type* Op1Ty = getOperand(1)->getType();
-  assert(Op0Ty == Op1Ty &&
-          "Both operands to FCmp instruction are not of the same type!");
-  // Check that the operands are the right type
-  assert(Op0Ty->isFloatingPoint() &&
-        "Invalid operand types for FCmp instruction");
 }
 
 CmpInst *
-CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, 
-                const std::string &Name, Instruction *InsertBefore) {
+CmpInst::Create(LLVMContext &Context, OtherOps Op, unsigned short predicate,
+                Value *S1, Value *S2, 
+                const Twine &Name, Instruction *InsertBefore) {
   if (Op == Instruction::ICmp) {
-    return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, 
-                        InsertBefore);
+    if (InsertBefore)
+      return new ICmpInst(InsertBefore, CmpInst::Predicate(predicate),
+                          S1, S2, Name);
+    else
+      return new ICmpInst(Context, CmpInst::Predicate(predicate),
+                          S1, S2, Name);
   }
-  return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, 
-                      InsertBefore);
+  
+  if (InsertBefore)
+    return new FCmpInst(InsertBefore, CmpInst::Predicate(predicate),
+                        S1, S2, Name);
+  else
+    return new FCmpInst(Context, CmpInst::Predicate(predicate),
+                        S1, S2, Name);
 }
 
 CmpInst *
-CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, 
-                const std::string &Name, BasicBlock *InsertAtEnd) {
+CmpInst::Create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, 
+                const Twine &Name, BasicBlock *InsertAtEnd) {
   if (Op == Instruction::ICmp) {
-    return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, 
-                        InsertAtEnd);
+    return new ICmpInst(*InsertAtEnd, CmpInst::Predicate(predicate),
+                        S1, S2, Name);
   }
-  return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, 
-                      InsertAtEnd);
+  return new FCmpInst(*InsertAtEnd, CmpInst::Predicate(predicate),
+                      S1, S2, Name);
 }
 
 void CmpInst::swapOperands() {
@@ -2359,10 +2576,9 @@ bool CmpInst::isEquality() {
 }
 
 
-ICmpInst::Predicate ICmpInst::getInversePredicate(Predicate pred) {
+CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) {
   switch (pred) {
-    default:
-      assert(!"Unknown icmp predicate!");
+    default: assert(!"Unknown cmp predicate!");
     case ICMP_EQ: return ICMP_NE;
     case ICMP_NE: return ICMP_EQ;
     case ICMP_UGT: return ICMP_ULE;
@@ -2373,22 +2589,23 @@ ICmpInst::Predicate ICmpInst::getInversePredicate(Predicate pred) {
     case ICMP_SLT: return ICMP_SGE;
     case ICMP_SGE: return ICMP_SLT;
     case ICMP_SLE: return ICMP_SGT;
-  }
-}
 
-ICmpInst::Predicate ICmpInst::getSwappedPredicate(Predicate pred) {
-  switch (pred) {
-    default: assert(! "Unknown icmp predicate!");
-    case ICMP_EQ: case ICMP_NE:
-      return pred;
-    case ICMP_SGT: return ICMP_SLT;
-    case ICMP_SLT: return ICMP_SGT;
-    case ICMP_SGE: return ICMP_SLE;
-    case ICMP_SLE: return ICMP_SGE;
-    case ICMP_UGT: return ICMP_ULT;
-    case ICMP_ULT: return ICMP_UGT;
-    case ICMP_UGE: return ICMP_ULE;
-    case ICMP_ULE: return ICMP_UGE;
+    case FCMP_OEQ: return FCMP_UNE;
+    case FCMP_ONE: return FCMP_UEQ;
+    case FCMP_OGT: return FCMP_ULE;
+    case FCMP_OLT: return FCMP_UGE;
+    case FCMP_OGE: return FCMP_ULT;
+    case FCMP_OLE: return FCMP_UGT;
+    case FCMP_UEQ: return FCMP_ONE;
+    case FCMP_UNE: return FCMP_OEQ;
+    case FCMP_UGT: return FCMP_OLE;
+    case FCMP_ULT: return FCMP_OGE;
+    case FCMP_UGE: return FCMP_OLT;
+    case FCMP_ULE: return FCMP_OGT;
+    case FCMP_ORD: return FCMP_UNO;
+    case FCMP_UNO: return FCMP_ORD;
+    case FCMP_TRUE: return FCMP_FALSE;
+    case FCMP_FALSE: return FCMP_TRUE;
   }
 }
 
@@ -2437,7 +2654,7 @@ ICmpInst::makeConstantRange(Predicate pred, const APInt &C) {
   APInt Upper(C);
   uint32_t BitWidth = C.getBitWidth();
   switch (pred) {
-  default: assert(0 && "Invalid ICmp opcode to ConstantRange ctor!");
+  default: llvm_unreachable("Invalid ICmp opcode to ConstantRange ctor!");
   case ICmpInst::ICMP_EQ: Upper++; break;
   case ICmpInst::ICMP_NE: Lower++; break;
   case ICmpInst::ICMP_ULT: Lower = APInt::getMinValue(BitWidth); break;
@@ -2464,32 +2681,20 @@ ICmpInst::makeConstantRange(Predicate pred, const APInt &C) {
   return ConstantRange(Lower, Upper);
 }
 
-FCmpInst::Predicate FCmpInst::getInversePredicate(Predicate pred) {
-  switch (pred) {
-    default:
-      assert(!"Unknown icmp predicate!");
-    case FCMP_OEQ: return FCMP_UNE;
-    case FCMP_ONE: return FCMP_UEQ;
-    case FCMP_OGT: return FCMP_ULE;
-    case FCMP_OLT: return FCMP_UGE;
-    case FCMP_OGE: return FCMP_ULT;
-    case FCMP_OLE: return FCMP_UGT;
-    case FCMP_UEQ: return FCMP_ONE;
-    case FCMP_UNE: return FCMP_OEQ;
-    case FCMP_UGT: return FCMP_OLE;
-    case FCMP_ULT: return FCMP_OGE;
-    case FCMP_UGE: return FCMP_OLT;
-    case FCMP_ULE: return FCMP_OGT;
-    case FCMP_ORD: return FCMP_UNO;
-    case FCMP_UNO: return FCMP_ORD;
-    case FCMP_TRUE: return FCMP_FALSE;
-    case FCMP_FALSE: return FCMP_TRUE;
-  }
-}
-
-FCmpInst::Predicate FCmpInst::getSwappedPredicate(Predicate pred) {
+CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) {
   switch (pred) {
-    default: assert(!"Unknown fcmp predicate!");
+    default: assert(!"Unknown cmp predicate!");
+    case ICMP_EQ: case ICMP_NE:
+      return pred;
+    case ICMP_SGT: return ICMP_SLT;
+    case ICMP_SLT: return ICMP_SGT;
+    case ICMP_SGE: return ICMP_SLE;
+    case ICMP_SLE: return ICMP_SGE;
+    case ICMP_UGT: return ICMP_ULT;
+    case ICMP_ULT: return ICMP_UGT;
+    case ICMP_UGE: return ICMP_ULE;
+    case ICMP_ULE: return ICMP_UGE;
+  
     case FCMP_FALSE: case FCMP_TRUE:
     case FCMP_OEQ: case FCMP_ONE:
     case FCMP_UEQ: case FCMP_UNE:
@@ -2548,10 +2753,10 @@ void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumCases) {
   assert(Value && Default);
   ReservedSpace = 2+NumCases*2;
   NumOperands = 2;
-  OperandList = new Use[ReservedSpace];
+  OperandList = allocHungoffUses(ReservedSpace);
 
-  OperandList[0].init(Value, this);
-  OperandList[1].init(Default, this);
+  OperandList[0] = Value;
+  OperandList[1] = Default;
 }
 
 /// SwitchInst ctor - Create a new switch instruction, specifying a value to
@@ -2576,16 +2781,16 @@ SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
 
 SwitchInst::SwitchInst(const SwitchInst &SI)
   : TerminatorInst(Type::VoidTy, Instruction::Switch,
-                   new Use[SI.getNumOperands()], SI.getNumOperands()) {
+                   allocHungoffUses(SI.getNumOperands()), SI.getNumOperands()) {
   Use *OL = OperandList, *InOL = SI.OperandList;
   for (unsigned i = 0, E = SI.getNumOperands(); i != E; i+=2) {
-    OL[i].init(InOL[i], this);
-    OL[i+1].init(InOL[i+1], this);
+    OL[i] = InOL[i];
+    OL[i+1] = InOL[i+1];
   }
 }
 
 SwitchInst::~SwitchInst() {
-  delete [] OperandList;
+  dropHungoffUses(OperandList);
 }
 
 
@@ -2598,8 +2803,8 @@ void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
   // Initialize some new operands.
   assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
   NumOperands = OpNo+2;
-  OperandList[OpNo].init(OnVal, this);
-  OperandList[OpNo+1].init(Dest, this);
+  OperandList[OpNo] = OnVal;
+  OperandList[OpNo+1] = Dest;
 }
 
 /// removeCase - This method removes the specified successor from the switch
@@ -2632,13 +2837,14 @@ void SwitchInst::removeCase(unsigned idx) {
 /// resizeOperands - resize operands - This adjusts the length of the operands
 /// list according to the following behavior:
 ///   1. If NumOps == 0, grow the operand list in response to a push_back style
-///      of operation.  This grows the number of ops by 1.5 times.
+///      of operation.  This grows the number of ops by 3 times.
 ///   2. If NumOps > NumOperands, reserve space for NumOps operands.
 ///   3. If NumOps == NumOperands, trim the reserved space.
 ///
 void SwitchInst::resizeOperands(unsigned NumOps) {
+  unsigned e = getNumOperands();
   if (NumOps == 0) {
-    NumOps = getNumOperands()/2*6;
+    NumOps = e*3;
   } else if (NumOps*2 > NumOperands) {
     // No resize needed.
     if (ReservedSpace >= NumOps) return;
@@ -2649,14 +2855,13 @@ void SwitchInst::resizeOperands(unsigned NumOps) {
   }
 
   ReservedSpace = NumOps;
-  Use *NewOps = new Use[NumOps];
+  Use *NewOps = allocHungoffUses(NumOps);
   Use *OldOps = OperandList;
-  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
-      NewOps[i].init(OldOps[i], this);
-      OldOps[i].set(0);
+  for (unsigned i = 0; i != e; ++i) {
+      NewOps[i] = OldOps[i];
   }
-  delete [] OldOps;
   OperandList = NewOps;
+  if (OldOps) Use::zap(OldOps, OldOps + e, true);
 }
 
 
@@ -2670,95 +2875,148 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   setSuccessor(idx, B);
 }
 
-//===----------------------------------------------------------------------===//
-//                           GetResultInst Implementation
-//===----------------------------------------------------------------------===//
+// Define these methods here so vtables don't get emitted into every translation
+// unit that uses these classes.
 
-GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
-                             const std::string &Name,
-                             Instruction *InsertBef)
-  : Instruction(cast<StructType>(Aggregate->getType())->getElementType(Index),
-                GetResult, &Aggr, 1, InsertBef) {
-  assert(isValidOperands(Aggregate, Index) && "Invalid GetResultInst operands!");
-  Aggr.init(Aggregate, this);
-  Idx = Index;
-  setName(Name);
+GetElementPtrInst *GetElementPtrInst::clone(LLVMContext&) const {
+  return new(getNumOperands()) GetElementPtrInst(*this);
 }
 
-bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
-  if (!Aggregate)
-    return false;
+BinaryOperator *BinaryOperator::clone(LLVMContext&) const {
+  return Create(getOpcode(), Op<0>(), Op<1>());
+}
 
-  if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
-    unsigned NumElements = STy->getNumElements();
-    if (Index >= NumElements || NumElements == 0)
-      return false;
+FCmpInst* FCmpInst::clone(LLVMContext &Context) const {
+  return new FCmpInst(Context, getPredicate(), Op<0>(), Op<1>());
+}
+ICmpInst* ICmpInst::clone(LLVMContext &Context) const {
+  return new ICmpInst(Context, getPredicate(), Op<0>(), Op<1>());
+}
 
-    // getresult aggregate value's element types are restricted to
-    // avoid nested aggregates.
-    for (unsigned i = 0; i < NumElements; ++i)
-      if (!STy->getElementType(i)->isFirstClassType())
-        return false;
+ExtractValueInst *ExtractValueInst::clone(LLVMContext&) const {
+  return new ExtractValueInst(*this);
+}
+InsertValueInst *InsertValueInst::clone(LLVMContext&) const {
+  return new InsertValueInst(*this);
+}
 
-    // Otherwise, Aggregate is valid.
-    return true;
-  }
-  return false;
+MallocInst *MallocInst::clone(LLVMContext&) const {
+  return new MallocInst(*this);
 }
 
-// Define these methods here so vtables don't get emitted into every translation
-// unit that uses these classes.
+AllocaInst *AllocaInst::clone(LLVMContext&) const {
+  return new AllocaInst(*this);
+}
 
-GetElementPtrInst *GetElementPtrInst::clone() const {
-  return new(getNumOperands()) GetElementPtrInst(*this);
+FreeInst *FreeInst::clone(LLVMContext&) const {
+  return new FreeInst(getOperand(0));
+}
+
+LoadInst *LoadInst::clone(LLVMContext&) const {
+  return new LoadInst(*this);
+}
+
+StoreInst *StoreInst::clone(LLVMContext&) const {
+  return new StoreInst(*this);
+}
+
+CastInst *TruncInst::clone(LLVMContext&) const {
+  return new TruncInst(*this);
+}
+
+CastInst *ZExtInst::clone(LLVMContext&) const {
+  return new ZExtInst(*this);
 }
 
-BinaryOperator *BinaryOperator::clone() const {
-  return create(getOpcode(), Ops[0], Ops[1]);
+CastInst *SExtInst::clone(LLVMContext&) const {
+  return new SExtInst(*this);
 }
 
-FCmpInst* FCmpInst::clone() const {
-  return new FCmpInst(getPredicate(), Ops[0], Ops[1]);
+CastInst *FPTruncInst::clone(LLVMContext&) const {
+  return new FPTruncInst(*this);
 }
-ICmpInst* ICmpInst::clone() const {
-  return new ICmpInst(getPredicate(), Ops[0], Ops[1]);
+
+CastInst *FPExtInst::clone(LLVMContext&) const {
+  return new FPExtInst(*this);
+}
+
+CastInst *UIToFPInst::clone(LLVMContext&) const {
+  return new UIToFPInst(*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)); }
-LoadInst   *LoadInst::clone()     const { return new LoadInst(*this); }
-StoreInst  *StoreInst::clone()    const { return new StoreInst(*this); }
-CastInst   *TruncInst::clone()    const { return new TruncInst(*this); }
-CastInst   *ZExtInst::clone()     const { return new ZExtInst(*this); }
-CastInst   *SExtInst::clone()     const { return new SExtInst(*this); }
-CastInst   *FPTruncInst::clone()  const { return new FPTruncInst(*this); }
-CastInst   *FPExtInst::clone()    const { return new FPExtInst(*this); }
-CastInst   *UIToFPInst::clone()   const { return new UIToFPInst(*this); }
-CastInst   *SIToFPInst::clone()   const { return new SIToFPInst(*this); }
-CastInst   *FPToUIInst::clone()   const { return new FPToUIInst(*this); }
-CastInst   *FPToSIInst::clone()   const { return new FPToSIInst(*this); }
-CastInst   *PtrToIntInst::clone() const { return new PtrToIntInst(*this); }
-CastInst   *IntToPtrInst::clone() const { return new IntToPtrInst(*this); }
-CastInst   *BitCastInst::clone()  const { return new BitCastInst(*this); }
-CallInst   *CallInst::clone()     const { return new(getNumOperands()) CallInst(*this); }
-SelectInst *SelectInst::clone()   const { return new(getNumOperands()) SelectInst(*this); }
-VAArgInst  *VAArgInst::clone()    const { return new VAArgInst(*this); }
+CastInst *SIToFPInst::clone(LLVMContext&) const {
+  return new SIToFPInst(*this);
+}
+
+CastInst *FPToUIInst::clone(LLVMContext&) const {
+  return new FPToUIInst(*this);
+}
+
+CastInst *FPToSIInst::clone(LLVMContext&) const {
+  return new FPToSIInst(*this);
+}
+
+CastInst *PtrToIntInst::clone(LLVMContext&) const {
+  return new PtrToIntInst(*this);
+}
+
+CastInst *IntToPtrInst::clone(LLVMContext&) const {
+  return new IntToPtrInst(*this);
+}
+
+CastInst *BitCastInst::clone(LLVMContext&) const {
+  return new BitCastInst(*this);
+}
 
-ExtractElementInst *ExtractElementInst::clone() const {
-  return new ExtractElementInst(*this);
+CallInst *CallInst::clone(LLVMContext&) const {
+  return new(getNumOperands()) CallInst(*this);
 }
-InsertElementInst *InsertElementInst::clone() const {
+
+SelectInst *SelectInst::clone(LLVMContext&)   const {
+  return new(getNumOperands()) SelectInst(*this);
+}
+
+VAArgInst *VAArgInst::clone(LLVMContext&) const {
+  return new VAArgInst(*this);
+}
+
+ExtractElementInst *ExtractElementInst::clone(LLVMContext&) const {
+  return ExtractElementInst::Create(*this);
+}
+
+InsertElementInst *InsertElementInst::clone(LLVMContext&) const {
   return InsertElementInst::Create(*this);
 }
-ShuffleVectorInst *ShuffleVectorInst::clone() const {
+
+ShuffleVectorInst *ShuffleVectorInst::clone(LLVMContext&) const {
   return new ShuffleVectorInst(*this);
 }
-PHINode    *PHINode::clone()    const { return new PHINode(*this); }
-ReturnInst *ReturnInst::clone() const { return new(getNumOperands()) ReturnInst(*this); }
-BranchInst *BranchInst::clone() const { return new(getNumOperands()) BranchInst(*this); }
-SwitchInst *SwitchInst::clone() const { return new(getNumOperands()) SwitchInst(*this); }
-InvokeInst *InvokeInst::clone() const { return new(getNumOperands()) InvokeInst(*this); }
-UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
-UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
-GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }
+
+PHINode *PHINode::clone(LLVMContext&) const {
+  return new PHINode(*this);
+}
+
+ReturnInst *ReturnInst::clone(LLVMContext&) const {
+  return new(getNumOperands()) ReturnInst(*this);
+}
+
+BranchInst *BranchInst::clone(LLVMContext&) const {
+  unsigned Ops(getNumOperands());
+  return new(Ops, Ops == 1) BranchInst(*this);
+}
+
+SwitchInst *SwitchInst::clone(LLVMContext&) const {
+  return new SwitchInst(*this);
+}
+
+InvokeInst *InvokeInst::clone(LLVMContext&) const {
+  return new(getNumOperands()) InvokeInst(*this);
+}
+
+UnwindInst *UnwindInst::clone(LLVMContext&) const {
+  return new UnwindInst();
+}
+
+UnreachableInst *UnreachableInst::clone(LLVMContext&) const {
+  return new UnreachableInst();
+}