merge of use-diet branch to trunk
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index 6f04ba7bd80bae2031e75f26925734059960c427..78e7b17a66930d72104b3161cc78162df3e9a4c4 100644 (file)
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
-#include "llvm/ParameterAttributes.h"
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/Support/MathExtras.h"
 using namespace llvm;
 
+//===----------------------------------------------------------------------===//
+//                            CallSite Class
+//===----------------------------------------------------------------------===//
+
+CallSite::CallSite(Instruction *C) {
+  assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
+  I = C;
+}
 unsigned CallSite::getCallingConv() const {
   if (CallInst *CI = dyn_cast<CallInst>(I))
     return CI->getCallingConv();
@@ -35,13 +42,13 @@ void CallSite::setCallingConv(unsigned CC) {
   else
     cast<InvokeInst>(I)->setCallingConv(CC);
 }
-const ParamAttrsList* CallSite::getParamAttrs() const {
+const PAListPtr &CallSite::getParamAttrs() const {
   if (CallInst *CI = dyn_cast<CallInst>(I))
     return CI->getParamAttrs();
   else
     return cast<InvokeInst>(I)->getParamAttrs();
 }
-void CallSite::setParamAttrs(const ParamAttrsList *PAL) {
+void CallSite::setParamAttrs(const PAListPtr &PAL) {
   if (CallInst *CI = dyn_cast<CallInst>(I))
     CI->setParamAttrs(PAL);
   else
@@ -53,6 +60,13 @@ bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
   else
     return cast<InvokeInst>(I)->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);
+}
+
 bool CallSite::doesNotAccessMemory() const {
   if (CallInst *CI = dyn_cast<CallInst>(I))
     return CI->doesNotAccessMemory();
@@ -86,18 +100,21 @@ void CallSite::setDoesNotThrow(bool doesNotThrow) {
 TerminatorInst::~TerminatorInst() {
 }
 
+//===----------------------------------------------------------------------===//
+//                           UnaryInstruction Class
+//===----------------------------------------------------------------------===//
+
 // Out of line virtual method, so the vtable, etc has a home.
 UnaryInstruction::~UnaryInstruction() {
 }
 
-
 //===----------------------------------------------------------------------===//
 //                               PHINode Class
 //===----------------------------------------------------------------------===//
 
 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) {
@@ -107,7 +124,7 @@ PHINode::PHINode(const PHINode &PN)
 }
 
 PHINode::~PHINode() {
-  delete [] OperandList;
+  dropHungoffUses(OperandList);
 }
 
 // removeIncomingValue - Remove an incoming value.  This is useful if a
@@ -150,8 +167,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.
@@ -163,14 +181,13 @@ void PHINode::resizeOperands(unsigned NumOps) {
   }
 
   ReservedSpace = NumOps;
-  Use *NewOps = new Use[NumOps];
   Use *OldOps = OperandList;
-  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+  Use *NewOps = allocHungoffUses(NumOps);
+  for (unsigned i = 0; i != e; ++i) {
       NewOps[i].init(OldOps[i], this);
-      OldOps[i].set(0);
   }
-  delete [] OldOps;
   OperandList = NewOps;
+  if (OldOps) Use::zap(OldOps, OldOps + e, true);
 }
 
 /// hasConstantValue - If the specified PHI node always merges together the same
@@ -178,11 +195,12 @@ void PHINode::resizeOperands(unsigned NumOps) {
 ///
 Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
   // If the PHI node only has one incoming value, eliminate the PHI node...
-  if (getNumIncomingValues() == 1)
+  if (getNumIncomingValues() == 1) {
     if (getIncomingValue(0) != this)   // not  X = phi X
       return getIncomingValue(0);
     else
       return UndefValue::get(getType());  // Self cycle is dead.
+  }
       
   // Otherwise if all of the incoming values are the same for the PHI, replace
   // the PHI node with the incoming value.
@@ -190,13 +208,14 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
   Value *InVal = 0;
   bool HasUndefInput = false;
   for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i)
-    if (isa<UndefValue>(getIncomingValue(i)))
+    if (isa<UndefValue>(getIncomingValue(i))) {
       HasUndefInput = true;
-    else if (getIncomingValue(i) != this)  // Not the PHI node itself...
+    } else if (getIncomingValue(i) != this) { // Not the PHI node itself...
       if (InVal && getIncomingValue(i) != InVal)
         return 0;  // Not the same, bail out.
       else
         InVal = getIncomingValue(i);
+    }
   
   // The only case that could cause InVal to be null is if we have a PHI node
   // that only has entries for itself.  In this case, there is no entry into the
@@ -225,15 +244,11 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
 //===----------------------------------------------------------------------===//
 
 CallInst::~CallInst() {
-  delete [] OperandList;
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
 }
 
 void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
-  ParamAttrs = 0;
-  NumOperands = NumParams+1;
-  Use *OL = OperandList = new Use[NumParams+1];
+  assert(NumOperands == NumParams+1 && "NumOperands not set up?");
+  Use *OL = OperandList;
   OL[0].init(Func, this);
 
   const FunctionType *FTy =
@@ -252,9 +267,8 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
 }
 
 void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
-  ParamAttrs = 0;
-  NumOperands = 3;
-  Use *OL = OperandList = new Use[3];
+  assert(NumOperands == 3 && "NumOperands not set up?");
+  Use *OL = OperandList;
   OL[0].init(Func, this);
   OL[1].init(Actual1, this);
   OL[2].init(Actual2, this);
@@ -275,9 +289,8 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
 }
 
 void CallInst::init(Value *Func, Value *Actual) {
-  ParamAttrs = 0;
-  NumOperands = 2;
-  Use *OL = OperandList = new Use[2];
+  assert(NumOperands == 2 && "NumOperands not set up?");
+  Use *OL = OperandList;
   OL[0].init(Func, this);
   OL[1].init(Actual, this);
 
@@ -294,9 +307,8 @@ void CallInst::init(Value *Func, Value *Actual) {
 }
 
 void CallInst::init(Value *Func) {
-  ParamAttrs = 0;
-  NumOperands = 1;
-  Use *OL = OperandList = new Use[1];
+  assert(NumOperands == 1 && "NumOperands not set up?");
+  Use *OL = OperandList;
   OL[0].init(Func, this);
 
   const FunctionType *FTy =
@@ -306,48 +318,13 @@ void CallInst::init(Value *Func) {
   assert(FTy->getNumParams() == 0 && "Calling a function with bad signature");
 }
 
-#if 0
-// Leave for llvm-gcc
-CallInst::CallInst(Value *Func, Value* const *Args, unsigned NumArgs,
-                   const std::string &Name, BasicBlock *InsertAtEnd)
-  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
-                                     ->getElementType())->getReturnType(),
-                Instruction::Call, 0, 0, InsertAtEnd) {
-  init(Func, Args, NumArgs);
-  setName(Name);
-}
-CallInst::CallInst(Value *Func, Value* const *Args, unsigned NumArgs,
-                   const std::string &Name, Instruction *InsertBefore)
-    : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
-                                     ->getElementType())->getReturnType(),
-                  Instruction::Call, 0, 0, InsertBefore) {
-  init(Func, Args, NumArgs);
-  setName(Name);
-}
-
-CallInst::CallInst(Value *Func, Value *Actual1, Value *Actual2,
-                   const std::string &Name, Instruction  *InsertBefore)
-  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
-                                   ->getElementType())->getReturnType(),
-                Instruction::Call, 0, 0, InsertBefore) {
-  init(Func, Actual1, Actual2);
-  setName(Name);
-}
-
-CallInst::CallInst(Value *Func, Value *Actual1, Value *Actual2,
-                   const std::string &Name, BasicBlock  *InsertAtEnd)
-  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
-                                   ->getElementType())->getReturnType(),
-                Instruction::Call, 0, 0, InsertAtEnd) {
-  init(Func, Actual1, Actual2);
-  setName(Name);
-}
-#endif
 CallInst::CallInst(Value *Func, Value* Actual, const std::string &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);
 }
@@ -356,7 +333,9 @@ CallInst::CallInst(Value *Func, Value* Actual, const std::string &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);
 }
@@ -364,7 +343,9 @@ CallInst::CallInst(Value *Func, const std::string &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);
 }
@@ -373,15 +354,17 @@ CallInst::CallInst(Value *Func, const std::string &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()],
-                CI.getNumOperands()),
-    ParamAttrs(0) {
+  : Instruction(CI.getType(), Instruction::Call,
+                OperandTraits<CallInst>::op_end(this) - CI.getNumOperands(),
+                CI.getNumOperands()) {
   setParamAttrs(CI.getParamAttrs());
   SubclassData = CI.SubclassData;
   Use *OL = OperandList;
@@ -390,21 +373,8 @@ CallInst::CallInst(const CallInst &CI)
     OL[i].init(InOL[i], this);
 }
 
-void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) {
-  if (ParamAttrs == newAttrs)
-    return;
-
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
-
-  if (newAttrs)
-    newAttrs->addRef();
-
-  ParamAttrs = newAttrs; 
-}
-
-bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
-  if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
+  if (ParamAttrs.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
@@ -412,11 +382,11 @@ bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
 }
 
 void CallInst::setDoesNotThrow(bool doesNotThrow) {
-  const ParamAttrsList *PAL = getParamAttrs();
+  PAListPtr PAL = getParamAttrs();
   if (doesNotThrow)
-    PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
   else
-    PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
   setParamAttrs(PAL);
 }
 
@@ -425,17 +395,10 @@ void CallInst::setDoesNotThrow(bool doesNotThrow) {
 //                        InvokeInst Implementation
 //===----------------------------------------------------------------------===//
 
-InvokeInst::~InvokeInst() {
-  delete [] OperandList;
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
-}
-
 void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
                       Value* const *Args, unsigned NumArgs) {
-  ParamAttrs = 0;
-  NumOperands = 3+NumArgs;
-  Use *OL = OperandList = new Use[3+NumArgs];
+  assert(NumOperands == 3+NumArgs && "NumOperands not set up?");
+  Use *OL = OperandList;
   OL[0].init(Fn, this);
   OL[1].init(IfNormal, this);
   OL[2].init(IfException, this);
@@ -443,8 +406,8 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
     cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
   FTy = FTy;  // silence warning.
 
-  assert((NumArgs == FTy->getNumParams()) ||
-         (FTy->isVarArg() && NumArgs > FTy->getNumParams()) &&
+  assert(((NumArgs == FTy->getNumParams()) ||
+          (FTy->isVarArg() && NumArgs > FTy->getNumParams())) &&
          "Calling a function with bad signature");
 
   for (unsigned i = 0, e = NumArgs; i != e; i++) {
@@ -458,8 +421,8 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
 
 InvokeInst::InvokeInst(const InvokeInst &II)
   : TerminatorInst(II.getType(), Instruction::Invoke,
-                   new Use[II.getNumOperands()], II.getNumOperands()),
-    ParamAttrs(0) {
+                   OperandTraits<InvokeInst>::op_end(this) - II.getNumOperands(),
+                   II.getNumOperands()) {
   setParamAttrs(II.getParamAttrs());
   SubclassData = II.SubclassData;
   Use *OL = OperandList, *InOL = II.OperandList;
@@ -477,21 +440,8 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   return setSuccessor(idx, B);
 }
 
-void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) {
-  if (ParamAttrs == newAttrs)
-    return;
-
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
-
-  if (newAttrs)
-    newAttrs->addRef();
-
-  ParamAttrs = newAttrs; 
-}
-
-bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
-  if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
+  if (ParamAttrs.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
@@ -499,11 +449,11 @@ bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
 }
 
 void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
-  const ParamAttrsList *PAL = getParamAttrs();
+  PAListPtr PAL = getParamAttrs();
   if (doesNotThrow)
-    PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
   else
-    PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
   setParamAttrs(PAL);
 }
 
@@ -514,31 +464,73 @@ void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
 
 ReturnInst::ReturnInst(const ReturnInst &RI)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   &RetVal, RI.getNumOperands()) {
-  if (RI.getNumOperands())
-    RetVal.init(RI.RetVal, this);
+                   OperandTraits<ReturnInst>::op_end(this) - RI.getNumOperands(),
+                   RI.getNumOperands()) {
+  unsigned N = RI.getNumOperands();
+  if (N == 1)
+    Op<0>().init(RI.Op<0>(), this);
+  else if (N) {
+    Use *OL = OperandList;
+    for (unsigned i = 0; i < N; ++i)
+      OL[i].init(RI.getOperand(i), this);
+  }
 }
 
 ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
-  init(retVal);
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
+                   retVal != 0, InsertBefore) {
+  if (retVal)
+    init(&retVal, 1);
 }
 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
-  init(retVal);
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
+                   retVal != 0, InsertAtEnd) {
+  if (retVal)
+    init(&retVal, 1);
 }
 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this),
+                   0, InsertAtEnd) {
 }
 
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
+                       Instruction *InsertBefore)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this) - N,
+                   N, InsertBefore) {
+  if (N != 0)
+    init(retVals, N);
+}
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
+                       BasicBlock *InsertAtEnd)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret,
+                   OperandTraits<ReturnInst>::op_end(this) - N,
+                   N, InsertAtEnd) {
+  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;
+    Op<0>().init(V, this);
+    return;
+  }
 
-void ReturnInst::init(Value *retVal) {
-  if (retVal && retVal->getType() != Type::VoidTy) {
-    assert(!isa<BasicBlock>(retVal) &&
+  Use *OL = OperandList;
+  for (unsigned i = 0; i < NumOperands; ++i) {
+    Value *V = *retVals++;
+    assert(!isa<BasicBlock>(V) &&
            "Cannot return basic block.  Probably using the incorrect ctor");
-    NumOperands = 1;
-    RetVal.init(retVal, this);
+    OL[i].init(V, this);
   }
 }
 
@@ -546,8 +538,8 @@ unsigned ReturnInst::getNumSuccessorsV() const {
   return getNumSuccessors();
 }
 
-// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
-// emit the vtable for the class in this translation unit.
+/// 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!");
 }
@@ -558,6 +550,8 @@ BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
   return 0;
 }
 
+ReturnInst::~ReturnInst() {
+}
 
 //===----------------------------------------------------------------------===//
 //                        UnwindInst Implementation
@@ -621,33 +615,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<0>().init(reinterpret_cast<Value*>(IfTrue), this);
 }
 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<0>().init(reinterpret_cast<Value*>(IfTrue), this);
+  Op<1>().init(reinterpret_cast<Value*>(IfFalse), this);
+  Op<2>().init(Cond, this);
 #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<0>().init(reinterpret_cast<Value*>(IfTrue), this);
 }
 
 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<0>().init(reinterpret_cast<Value*>(IfTrue), this);
+  Op<1>().init(reinterpret_cast<Value*>(IfFalse), this);
+  Op<2>().init(Cond, this);
 #ifndef NDEBUG
   AssertOK();
 #endif
@@ -655,7 +657,9 @@ BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
 
 
 BranchInst::BranchInst(const BranchInst &BI) :
-  TerminatorInst(Type::VoidTy, Instruction::Br, Ops, BI.getNumOperands()) {
+  TerminatorInst(Type::VoidTy, Instruction::Br,
+                 OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
+                 BI.getNumOperands()) {
   OperandList[0].init(BI.getOperand(0), this);
   if (BI.getNumOperands() != 1) {
     assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
@@ -695,8 +699,8 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
                                unsigned Align, const std::string &Name,
                                Instruction *InsertBefore)
   : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
-                     InsertBefore), Alignment(Align) {
-  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+                     InsertBefore) {
+  setAlignment(Align);
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
   setName(Name);
 }
@@ -705,8 +709,8 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
                                unsigned Align, const std::string &Name,
                                BasicBlock *InsertAtEnd)
   : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
-                     InsertAtEnd), Alignment(Align) {
-  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+                     InsertAtEnd) {
+  setAlignment(Align);
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
   setName(Name);
 }
@@ -715,6 +719,12 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
 AllocationInst::~AllocationInst() {
 }
 
+void AllocationInst::setAlignment(unsigned Align) {
+  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+  SubclassData = Log2_32(Align) + 1;
+  assert(getAlignment() == Align && "Alignment representation error!");
+}
+
 bool AllocationInst::isArrayAllocation() const {
   if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0)))
     return CI->getZExtValue() != 1;
@@ -881,18 +891,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>().init(val, this);
+  Op<1>().init(addr, this);
   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>().init(val, this);
+  Op<1>().init(addr, this);
   setVolatile(false);
   setAlignment(0);
   AssertOK();
@@ -900,9 +916,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>().init(val, this);
+  Op<1>().init(addr, this);
   setVolatile(isVolatile);
   setAlignment(0);
   AssertOK();
@@ -910,9 +929,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>().init(val, this);
+  Op<1>().init(addr, this);
   setVolatile(isVolatile);
   setAlignment(Align);
   AssertOK();
@@ -920,9 +942,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>().init(val, this);
+  Op<1>().init(addr, this);
   setVolatile(isVolatile);
   setAlignment(Align);
   AssertOK();
@@ -930,9 +955,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>().init(val, this);
+  Op<1>().init(addr, this);
   setVolatile(isVolatile);
   setAlignment(0);
   AssertOK();
@@ -952,8 +980,8 @@ static unsigned retrieveAddrSpace(const Value *Val) {
 }
 
 void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx) {
-  NumOperands = 1+NumIdx;
-  Use *OL = OperandList = new Use[NumOperands];
+  assert(NumOperands == 1+NumIdx && "NumOperands not initialized?");
+  Use *OL = OperandList;
   OL[0].init(Ptr, this);
 
   for (unsigned i = 0; i != NumIdx; ++i)
@@ -961,17 +989,29 @@ void GetElementPtrInst::init(Value *Ptr, Value* const *Idx, unsigned NumIdx) {
 }
 
 void GetElementPtrInst::init(Value *Ptr, Value *Idx) {
-  NumOperands = 2;
-  Use *OL = OperandList = new Use[2];
+  assert(NumOperands == 2 && "NumOperands not initialized?");
+  Use *OL = OperandList;
   OL[0].init(Ptr, this);
   OL[1].init(Idx, this);
 }
 
+GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI)
+  : Instruction(reinterpret_cast<const Type*>(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].init(GEPIOL[i], 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) {
+                GetElementPtr,
+                OperandTraits<GetElementPtrInst>::op_end(this) - 2,
+                2, InBe) {
   init(Ptr, Idx);
   setName(Name);
 }
@@ -980,15 +1020,13 @@ 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) {
+                GetElementPtr,
+                OperandTraits<GetElementPtrInst>::op_end(this) - 2,
+                2, IAE) {
   init(Ptr, Idx);
   setName(Name);
 }
 
-GetElementPtrInst::~GetElementPtrInst() {
-  delete[] OperandList;
-}
-
 // getIndexedType - Returns the type of the element that would be loaded with
 // a load instruction with the specified parameters.
 //
@@ -1002,12 +1040,13 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
   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 (NumIdx == 0) {
     if (AllowCompositeLeaf ||
         cast<PointerType>(Ptr)->getElementType()->isFirstClassType())
       return cast<PointerType>(Ptr)->getElementType();
     else
       return 0;
+  }
 
   unsigned CurIdx = 0;
   while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
@@ -1078,11 +1117,13 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
                                        const std::string &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>().init(Val, this);
+  Op<1>().init(Index, this);
   setName(Name);
 }
 
@@ -1090,12 +1131,14 @@ ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
                                        const std::string &Name,
                                        Instruction *InsertBef)
   : Instruction(cast<VectorType>(Val->getType())->getElementType(),
-                ExtractElement, Ops, 2, InsertBef) {
+                ExtractElement,
+                OperandTraits<ExtractElementInst>::op_begin(this),
+                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);
+  Op<0>().init(Val, this);
+  Op<1>().init(Index, this);
   setName(Name);
 }
 
@@ -1104,12 +1147,14 @@ ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
                                        const std::string &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);
+  Op<0>().init(Val, this);
+  Op<1>().init(Index, this);
   setName(Name);
 }
 
@@ -1117,13 +1162,15 @@ ExtractElementInst::ExtractElementInst(Value *Val, unsigned IndexV,
                                        const std::string &Name,
                                        BasicBlock *InsertAE)
   : Instruction(cast<VectorType>(Val->getType())->getElementType(),
-                ExtractElement, Ops, 2, InsertAE) {
+                ExtractElement,
+                OperandTraits<ExtractElementInst>::op_begin(this),
+                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>().init(Val, this);
+  Op<1>().init(Index, this);
   setName(Name);
 }
 
@@ -1140,33 +1187,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>().init(IE.Op<0>(), this);
+  Op<1>().init(IE.Op<1>(), this);
+  Op<2>().init(IE.Op<2>(), this);
 }
 InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
                                      const std::string &Name,
                                      Instruction *InsertBef)
-  : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertBef) {
+  : 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>().init(Vec, this);
+  Op<1>().init(Elt, this);
+  Op<2>().init(Index, this);
   setName(Name);
 }
 
 InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
                                      const std::string &Name,
                                      Instruction *InsertBef)
-  : Instruction(Vec->getType(), InsertElement, Ops, 3, InsertBef) {
+  : Instruction(Vec->getType(), InsertElement,
+                OperandTraits<InsertElementInst>::op_begin(this),
+                3, InsertBef) {
   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>().init(Vec, this);
+  Op<1>().init(Elt, this);
+  Op<2>().init(Index, this);
   setName(Name);
 }
 
@@ -1174,27 +1226,31 @@ InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, unsigned IndexV,
 InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
                                      const std::string &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);
+  Op<0>().init(Vec, this);
+  Op<1>().init(Elt, this);
+  Op<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) {
+: Instruction(Vec->getType(), InsertElement,
+              OperandTraits<InsertElementInst>::op_begin(this),
+              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>().init(Vec, this);
+  Op<1>().init(Elt, this);
+  Op<2>().init(Index, this);
   setName(Name);
 }
 
@@ -1217,49 +1273,75 @@ 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>().init(SV.Op<0>(), this);
+  Op<1>().init(SV.Op<1>(), this);
+  Op<2>().init(SV.Op<2>(), this);
 }
 
 ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
                                      const std::string &Name,
                                      Instruction *InsertBefore)
-  : Instruction(V1->getType(), ShuffleVector, Ops, 3, InsertBefore) {
+  : Instruction(V1->getType(), 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>().init(V1, this);
+  Op<1>().init(V2, this);
+  Op<2>().init(Mask, this);
   setName(Name);
 }
 
 ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
                                      const std::string &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>().init(V1, this);
+  Op<1>().init(V2, this);
+  Op<2>().init(Mask, this);
   setName(Name);
 }
 
 bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, 
                                         const Value *Mask) {
-  if (!isa<VectorType>(V1->getType())) return false;
-  if (V1->getType() != V2->getType()) return false;
-  if (!isa<VectorType>(Mask->getType()) ||
-         cast<VectorType>(Mask->getType())->getElementType() != Type::Int32Ty ||
-         cast<VectorType>(Mask->getType())->getNumElements() !=
-         cast<VectorType>(V1->getType())->getNumElements())
+  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())
     return false;
   return true;
 }
 
+/// getMaskValue - Return the index from the shuffle mask for the specified
+/// output result.  This is either -1 if the element is undef or a number less
+/// than 2*numelements.
+int ShuffleVectorInst::getMaskValue(unsigned i) const {
+  const Constant *Mask = cast<Constant>(getOperand(2));
+  if (isa<UndefValue>(Mask)) return -1;
+  if (isa<ConstantAggregateZero>(Mask)) return 0;
+  const ConstantVector *MaskCV = cast<ConstantVector>(Mask);
+  assert(i < MaskCV->getNumOperands() && "Index out of range");
+
+  if (isa<UndefValue>(MaskCV->getOperand(i)))
+    return -1;
+  return cast<ConstantInt>(MaskCV->getOperand(i))->getZExtValue();
+}
+
 
 //===----------------------------------------------------------------------===//
 //                             BinaryOperator Class
@@ -1268,9 +1350,12 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
 BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
                                const Type *Ty, const std::string &Name,
                                Instruction *InsertBefore)
-  : Instruction(Ty, iType, Ops, 2, InsertBefore) {
-  Ops[0].init(S1, this);
-  Ops[1].init(S2, this);
+  : Instruction(Ty, iType,
+                OperandTraits<BinaryOperator>::op_begin(this),
+                OperandTraits<BinaryOperator>::operands(this),
+                InsertBefore) {
+  Op<0>().init(S1, this);
+  Op<1>().init(S2, this);
   init(iType);
   setName(Name);
 }
@@ -1278,9 +1363,12 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
 BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, 
                                const Type *Ty, const std::string &Name,
                                BasicBlock *InsertAtEnd)
-  : Instruction(Ty, iType, Ops, 2, InsertAtEnd) {
-  Ops[0].init(S1, this);
-  Ops[1].init(S2, this);
+  : Instruction(Ty, iType,
+                OperandTraits<BinaryOperator>::op_begin(this),
+                OperandTraits<BinaryOperator>::operands(this),
+                InsertAtEnd) {
+  Op<0>().init(S1, this);
+  Op<1>().init(S2, this);
   init(iType);
   setName(Name);
 }
@@ -1475,7 +1563,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]);
+  std::swap(Op<0>(), Op<1>());
   return false;
 }
 
@@ -1875,12 +1963,70 @@ CastInst *CastInst::createFPCast(Value *C, const Type *Ty,
   return create(opcode, C, Ty, Name, InsertAtEnd);
 }
 
+// Check whether it is valid to call getCastOpcode for these types.
+// This routine must be kept in sync with getCastOpcode.
+bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
+  if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType())
+    return false;
+
+  if (SrcTy == 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
+
+  // Run through the possibilities ...
+  if (DestTy->isInteger()) {                      // Casting to integral
+    if (SrcTy->isInteger()) {                     // Casting from integral
+        return true;
+    } else if (SrcTy->isFloatingPoint()) {        // Casting from floating pt
+      return true;
+    } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
+                                                  // Casting from vector
+      return DestBits == PTy->getBitWidth();
+    } else {                                      // Casting from something else
+      return isa<PointerType>(SrcTy);
+    }
+  } else if (DestTy->isFloatingPoint()) {         // Casting to floating pt
+    if (SrcTy->isInteger()) {                     // Casting from integral
+      return true;
+    } else if (SrcTy->isFloatingPoint()) {        // Casting from floating pt
+      return true;
+    } else if (const VectorType *PTy = dyn_cast<VectorType>(SrcTy)) {
+                                                  // Casting from vector
+      return DestBits == PTy->getBitWidth();
+    } else {                                      // Casting from something else
+      return false;
+    }
+  } else if (const VectorType *DestPTy = dyn_cast<VectorType>(DestTy)) {
+                                                   // Casting to vector
+    if (const VectorType *SrcPTy = dyn_cast<VectorType>(SrcTy)) {
+                                                   // Casting from vector
+      return DestPTy->getBitWidth() == SrcPTy->getBitWidth();
+    } else {                                       // Casting from something else
+      return DestPTy->getBitWidth() == SrcBits;
+    }
+  } else if (isa<PointerType>(DestTy)) {           // Casting to pointer
+    if (isa<PointerType>(SrcTy)) {                 // Casting from pointer
+      return true;
+    } else if (SrcTy->isInteger()) {               // Casting from integral
+      return true;
+    } else {                                       // Casting from something else
+      return false;
+    }
+  } else {                                         // Casting to something else
+    return false;
+  }
+}
+
 // Provide a way to get a "cast" where the cast opcode is inferred from the 
 // types and size of the operand. This, basically, is a parallel of the 
 // logic in the castIsValid function below.  This axiom should hold:
 //   castIsValid( getCastOpcode(Val, Ty), Val, Ty)
 // should not assert in castIsValid. In other words, this produces a "correct"
 // casting opcode for the arguments passed to it.
+// This routine must be kept in sync with isCastable.
 Instruction::CastOps
 CastInst::getCastOpcode(
   const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
@@ -1889,6 +2035,9 @@ CastInst::getCastOpcode(
   unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr/vector
   unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
 
+  assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
+         "Only first class types are castable!");
+
   // Run through the possibilities ...
   if (DestTy->isInteger()) {                       // Casting to integral
     if (SrcTy->isInteger()) {                      // Casting from integral
@@ -2030,7 +2179,7 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
     if (isa<PointerType>(SrcTy) != isa<PointerType>(DstTy))
       return false;
 
-    // Now we know we're not dealing with a pointer/non-poiner mismatch. In all
+    // 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;
@@ -2186,9 +2335,12 @@ BitCastInst::BitCastInst(
 
 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);
+  : Instruction(Type::Int1Ty, op,
+                OperandTraits<CmpInst>::op_begin(this),
+                OperandTraits<CmpInst>::operands(this),
+                InsertBefore) {
+    Op<0>().init(LHS, this);
+    Op<1>().init(RHS, this);
   SubclassData = predicate;
   setName(Name);
   if (op == Instruction::ICmp) {
@@ -2215,12 +2367,15 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
   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);
+  : Instruction(Type::Int1Ty, op,
+                OperandTraits<CmpInst>::op_begin(this),
+                OperandTraits<CmpInst>::operands(this),
+                InsertAtEnd) {
+  Op<0>().init(LHS, this);
+  Op<1>().init(RHS, this);
   SubclassData = predicate;
   setName(Name);
   if (op == Instruction::ICmp) {
@@ -2233,7 +2388,7 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
     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) &&
+    assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
            "Invalid operand types for ICmp instruction");
     return;
   }
@@ -2337,6 +2492,19 @@ ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) {
   }
 }
 
+ICmpInst::Predicate ICmpInst::getUnsignedPredicate(Predicate pred) {
+  switch (pred) {
+    default: assert(! "Unknown icmp predicate!");
+    case ICMP_EQ: case ICMP_NE: 
+    case ICMP_UGT: case ICMP_ULT: case ICMP_UGE: case ICMP_ULE: 
+       return pred;
+    case ICMP_SGT: return ICMP_UGT;
+    case ICMP_SLT: return ICMP_ULT;
+    case ICMP_SGE: return ICMP_UGE;
+    case ICMP_SLE: return ICMP_ULE;
+  }
+}
+
 bool ICmpInst::isSignedPredicate(Predicate pred) {
   switch (pred) {
     default: assert(! "Unknown icmp predicate!");
@@ -2467,7 +2635,7 @@ 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);
@@ -2495,7 +2663,7 @@ 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);
@@ -2504,7 +2672,7 @@ SwitchInst::SwitchInst(const SwitchInst &SI)
 }
 
 SwitchInst::~SwitchInst() {
-  delete [] OperandList;
+  dropHungoffUses(OperandList);
 }
 
 
@@ -2551,13 +2719,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;
@@ -2568,14 +2737,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) {
+  for (unsigned i = 0; i != e; ++i) {
       NewOps[i].init(OldOps[i], this);
-      OldOps[i].set(0);
   }
-  delete [] OldOps;
   OperandList = NewOps;
+  if (OldOps) Use::zap(OldOps, OldOps + e, true);
 }
 
 
@@ -2589,23 +2757,61 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   setSuccessor(idx, B);
 }
 
+//===----------------------------------------------------------------------===//
+//                           GetResultInst Implementation
+//===----------------------------------------------------------------------===//
+
+GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
+                             const std::string &Name,
+                             Instruction *InsertBef)
+  : Instruction(cast<StructType>(Aggregate->getType())->getElementType(Index),
+                GetResult,
+                OperandTraits<GetResultInst>::op_begin(this),
+                OperandTraits<GetResultInst>::operands(this),
+                InsertBef) {
+  assert(isValidOperands(Aggregate, Index) && "Invalid GetResultInst operands!");
+  Op<0>().init(Aggregate, this);
+  Idx = Index;
+  setName(Name);
+}
+
+bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
+  if (!Aggregate)
+    return false;
+
+  if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
+    unsigned NumElements = STy->getNumElements();
+    if (Index >= NumElements || NumElements == 0)
+      return false;
+
+    // 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;
+
+    // Otherwise, Aggregate is valid.
+    return true;
+  }
+  return false;
+}
 
 // Define these methods here so vtables don't get emitted into every translation
 // unit that uses these classes.
 
 GetElementPtrInst *GetElementPtrInst::clone() const {
-  return new GetElementPtrInst(*this);
+  return new(getNumOperands()) GetElementPtrInst(*this);
 }
 
 BinaryOperator *BinaryOperator::clone() const {
-  return create(getOpcode(), Ops[0], Ops[1]);
+  return create(getOpcode(), Op<0>(), Op<1>());
 }
 
 FCmpInst* FCmpInst::clone() const {
-  return new FCmpInst(getPredicate(), Ops[0], Ops[1]);
+  return new FCmpInst(getPredicate(), Op<0>(), Op<1>());
 }
 ICmpInst* ICmpInst::clone() const {
-  return new ICmpInst(getPredicate(), Ops[0], Ops[1]);
+  return new ICmpInst(getPredicate(), Op<0>(), Op<1>());
 }
 
 MallocInst *MallocInst::clone()   const { return new MallocInst(*this); }
@@ -2625,23 +2831,24 @@ 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 CallInst(*this); }
-SelectInst *SelectInst::clone()   const { return new SelectInst(*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); }
 
 ExtractElementInst *ExtractElementInst::clone() const {
   return new ExtractElementInst(*this);
 }
 InsertElementInst *InsertElementInst::clone() const {
-  return new InsertElementInst(*this);
+  return InsertElementInst::Create(*this);
 }
 ShuffleVectorInst *ShuffleVectorInst::clone() const {
   return new ShuffleVectorInst(*this);
 }
 PHINode    *PHINode::clone()    const { return new PHINode(*this); }
-ReturnInst *ReturnInst::clone() const { return new ReturnInst(*this); }
-BranchInst *BranchInst::clone() const { return new BranchInst(*this); }
+ReturnInst *ReturnInst::clone() const { return new(getNumOperands()) ReturnInst(*this); }
+BranchInst *BranchInst::clone() const { return new(getNumOperands()) BranchInst(*this); }
 SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
-InvokeInst *InvokeInst::clone() const { return new InvokeInst(*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); }