Change references to the Method class to be references to the Function
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrSelection.cpp
index c1b8aa38c87969ac62c7a66e987ec889933da531..2094f6ec41c8ecbf804ac0eb03e9af54775855bf 100644 (file)
 
 #include "SparcInternals.h"
 #include "SparcInstrSelectionSupport.h"
+#include "SparcRegClassInfo.h"
 #include "llvm/CodeGen/InstrSelectionSupport.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/InstrForest.h"
 #include "llvm/CodeGen/InstrSelection.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/CodeGen/MachineCodeForMethod.h"
+#include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iMemory.h"
 #include "llvm/iOther.h"
 #include "llvm/BasicBlock.h"
-#include "llvm/Method.h"
-#include "llvm/ConstPoolVals.h"
+#include "llvm/Function.h"
+#include "llvm/ConstantVals.h"
+#include "Support/MathExtras.h"
 #include <math.h>
-
-//******************** Internal Data Declarations ************************/
-
+using std::vector;
 
 //************************* Forward Declarations ***************************/
 
 
-static void SetMemOperands_Internal     (MachineInstr* minstr,
+static void SetMemOperands_Internal     (vector<MachineInstr*>& mvec,
+                                         vector<MachineInstr*>::iterator mvecI,
                                          const InstructionNode* vmInstrNode,
                                          Value* ptrVal,
-                                         Value* arrayOffsetVal,
-                                         const vector<ConstPoolVal*>& idxVec,
+                                         std::vector<Value*>& idxVec,
                                          const TargetMachine& target);
 
 
@@ -140,20 +141,20 @@ ChooseBFpccInstruction(const InstructionNode* instrNode,
 // Eventually the entire BURG instruction selection should be put
 // into a separate class that can hold such information.
 // The static cache is not too bad because the memory for these
-// TmpInstructions will be freed along with the rest of the Method anyway.
+// TmpInstructions will be freed along with the rest of the Function anyway.
 // 
 static TmpInstruction*
-GetTmpForCC(Value* boolVal, const Method* method, const Type* ccType)
+GetTmpForCC(Value* boolVal, const Function *F, const Type* ccType)
 {
-  typedef  hash_map<const Value*, TmpInstruction*> BoolTmpCache;
+  typedef std::hash_map<const Value*, TmpInstruction*> BoolTmpCache;
   static BoolTmpCache boolToTmpCache;     // Map boolVal -> TmpInstruction*
-  static const Method* lastMethod = NULL; // Use to flush cache between methods
+  static const Function *lastFunction = 0;// Use to flush cache between funcs
   
   assert(boolVal->getType() == Type::BoolTy && "Weird but ok! Delete assert");
   
-  if (lastMethod != method)
+  if (lastFunction != F)
     {
-      lastMethod = method;
+      lastFunction = F;
       boolToTmpCache.clear();
     }
   
@@ -161,7 +162,7 @@ GetTmpForCC(Value* boolVal, const Method* method, const Type* ccType)
   // directly written to map using the ref returned by operator[].
   TmpInstruction*& tmpI = boolToTmpCache[boolVal];
   if (tmpI == NULL)
-    tmpI = new TmpInstruction(TMP_INSTRUCTION_OPCODE, ccType, boolVal, NULL);
+    tmpI = new TmpInstruction(ccType, boolVal);
   
   return tmpI;
 }
@@ -259,12 +260,14 @@ ChooseConvertToFloatInstr(const InstructionNode* instrNode,
       break;
       
     case ToDoubleTy: 
-      // Use FXTOD for all integer-to-double conversions.  This has to be
-      // consistent with the code in CreateCodeToCopyIntToFloat() since
-      // that will be used to load the integer into an FP register.
-      // 
-      if (opType == Type::SByteTy || opType == Type::ShortTy ||
-          opType == Type::IntTy || opType == Type::LongTy)
+      // This is usually used in conjunction with CreateCodeToCopyIntToFloat().
+      // Both functions should treat the integer as a 32-bit value for types
+      // of 4 bytes or less, and as a 64-bit value otherwise.
+      if (opType == Type::SByteTy || opType == Type::UByteTy ||
+          opType == Type::ShortTy || opType == Type::UShortTy ||
+          opType == Type::IntTy   || opType == Type::UIntTy)
+        opCode = FITOD;
+      else if (opType == Type::LongTy || opType == Type::ULongTy)
         opCode = FXTOD;
       else if (opType == Type::FloatTy)
         opCode = FSTOD;
@@ -324,9 +327,9 @@ ChooseAddInstructionByType(const Type* resultType)
   MachineOpCode opCode = INVALID_OPCODE;
   
   if (resultType->isIntegral() ||
-      resultType->isPointerType() ||
-      resultType->isLabelType() ||
-      isa<MethodType>(resultType) ||
+      isa<PointerType>(resultType) ||
+      isa<FunctionType>(resultType) ||
+      resultType == Type::LabelTy ||
       resultType == Type::BoolTy)
     {
       opCode = ADD;
@@ -356,10 +359,10 @@ CreateMovFloatInstruction(const InstructionNode* instrNode,
 {
   MachineInstr* minstr = new MachineInstr((resultType == Type::FloatTy)
                                           ? FMOVS : FMOVD);
-  minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                            instrNode->leftChild()->getValue());
-  minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                            instrNode->getValue());
+  minstr->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                               instrNode->leftChild()->getValue());
+  minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+                               instrNode->getValue());
   return minstr;
 }
 
@@ -369,7 +372,7 @@ CreateAddConstInstruction(const InstructionNode* instrNode)
   MachineInstr* minstr = NULL;
   
   Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
-  assert(isa<ConstPoolVal>(constOp));
+  assert(isa<Constant>(constOp));
   
   // Cases worth optimizing are:
   // (1) Add with 0 for float or double: use an FMOV of appropriate type,
@@ -380,7 +383,7 @@ CreateAddConstInstruction(const InstructionNode* instrNode)
   if (resultType == Type::FloatTy ||
       resultType == Type::DoubleTy)
     {
-      double dval = ((ConstPoolFP*) constOp)->getValue();
+      double dval = cast<ConstantFP>(constOp)->getValue();
       if (dval == 0.0)
         minstr = CreateMovFloatInstruction(instrNode, resultType);
     }
@@ -417,7 +420,7 @@ CreateSubConstInstruction(const InstructionNode* instrNode)
   MachineInstr* minstr = NULL;
   
   Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
-  assert(isa<ConstPoolVal>(constOp));
+  assert(isa<Constant>(constOp));
   
   // Cases worth optimizing are:
   // (1) Sub with 0 for float or double: use an FMOV of appropriate type,
@@ -428,7 +431,7 @@ CreateSubConstInstruction(const InstructionNode* instrNode)
   if (resultType == Type::FloatTy ||
       resultType == Type::DoubleTy)
     {
-      double dval = ((ConstPoolFP*) constOp)->getValue();
+      double dval = cast<ConstantFP>(constOp)->getValue();
       if (dval == 0.0)
         minstr = CreateMovFloatInstruction(instrNode, resultType);
     }
@@ -490,47 +493,42 @@ ChooseMulInstructionByType(const Type* resultType)
 }
 
 
-static inline MachineOpCode 
-ChooseMulInstruction(const InstructionNode* instrNode,
-                     bool checkCasts)
-{
-  if (checkCasts && BothFloatToDouble(instrNode))
-    return FSMULD;
-  
-  // else use the regular multiply instructions
-  return ChooseMulInstructionByType(instrNode->getInstruction()->getType());
-}
-
 
 static inline MachineInstr*
-CreateIntNegInstruction(TargetMachine& target,
+CreateIntNegInstruction(const TargetMachine& target,
                         Value* vreg)
 {
   MachineInstr* minstr = new MachineInstr(SUB);
-  minstr->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
-  minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, vreg);
-  minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, vreg);
+  minstr->SetMachineOperandReg(0, target.getRegInfo().getZeroRegNum());
+  minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, vreg);
+  minstr->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, vreg);
   return minstr;
 }
 
 
-static inline MachineInstr* 
-CreateMulConstInstruction(TargetMachine &target,
-                          const InstructionNode* instrNode,
-                          MachineInstr*& getMinstr2)
+// Does not create any instructions if we cannot exploit constant to
+// create a cheaper instruction.
+// This returns the approximate cost of the instructions generated,
+// which is used to pick the cheapest when both operands are constant.
+static inline unsigned int
+CreateMulConstInstruction(const TargetMachine &target,
+                          Value* lval, Value* rval, Value* destVal,
+                          vector<MachineInstr*>& mvec)
 {
-  MachineInstr* minstr = NULL; // return NULL if we cannot exploit constant
-  getMinstr2 = NULL;           // to create a cheaper instruction
-  bool needNeg = false;
-
-  Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
-  assert(isa<ConstPoolVal>(constOp));
+  /* An integer multiply is generally more costly than FP multiply */ 
+  unsigned int cost = target.getInstrInfo().minLatency(MULX);
+  MachineInstr* minstr1 = NULL;
+  MachineInstr* minstr2 = NULL;
+  
+  Value* constOp = rval;
+  if (! isa<Constant>(constOp))
+    return cost;
   
   // Cases worth optimizing are:
   // (1) Multiply by 0 or 1 for any type: replace with copy (ADD or FMOV)
   // (2) Multiply by 2^x for integer types: replace with Shift
   // 
-  const Type* resultType = instrNode->getInstruction()->getType();
+  const Type* resultType = destVal->getType();
   
   if (resultType->isIntegral() || resultType->isPointerType())
     {
@@ -548,30 +546,31 @@ CreateMulConstInstruction(TargetMachine &target,
           
           if (C == 0 || C == 1)
             {
-              minstr = new MachineInstr(ADD);
-              
+              cost = target.getInstrInfo().minLatency(ADD);
+              minstr1 = new MachineInstr(ADD);
               if (C == 0)
-                minstr->SetMachineOperand(0,
-                                          target.getRegInfo().getZeroRegNum());
+                minstr1->SetMachineOperandReg(0,
+                              target.getRegInfo().getZeroRegNum());
               else
-                minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
-                                          instrNode->leftChild()->getValue());
-              minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
+                minstr1->SetMachineOperandVal(0,
+                              MachineOperand::MO_VirtualRegister, lval);
+              minstr1->SetMachineOperandReg(1,
+                                        target.getRegInfo().getZeroRegNum());
             }
           else if (IsPowerOf2(C, pow))
             {
-              minstr = new MachineInstr((resultType == Type::LongTy)
-                                        ? SLLX : SLL);
-              minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                           instrNode->leftChild()->getValue());
-              minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
-                                           pow);
+              minstr1 = new MachineInstr((resultType == Type::LongTy)
+                                         ? SLLX : SLL);
+              minstr1->SetMachineOperandVal(0,
+                                MachineOperand::MO_VirtualRegister, lval);
+              minstr1->SetMachineOperandConst(1,
+                                MachineOperand::MO_UnextendedImmed, pow);
             }
           
-          if (minstr && needNeg)
+          if (minstr1 && needNeg)
             { // insert <reg = SUB 0, reg> after the instr to flip the sign
-              getMinstr2 = CreateIntNegInstruction(target,
-                                                   instrNode->getValue());
+              minstr2 = CreateIntNegInstruction(target, destVal);
+              cost += target.getInstrInfo().minLatency(minstr2->getOpCode());
             }
         }
     }
@@ -580,7 +579,7 @@ CreateMulConstInstruction(TargetMachine &target,
       if (resultType == Type::FloatTy ||
           resultType == Type::DoubleTy)
         {
-          double dval = ((ConstPoolFP*) constOp)->getValue();
+          double dval = cast<ConstantFP>(constOp)->getValue();
           if (fabs(dval) == 1)
             {
               bool needNeg = (dval < 0);
@@ -589,19 +588,88 @@ CreateMulConstInstruction(TargetMachine &target,
                 ? (resultType == Type::FloatTy? FNEGS : FNEGD)
                 : (resultType == Type::FloatTy? FMOVS : FMOVD);
               
-              minstr = new MachineInstr(opCode);
-              minstr->SetMachineOperand(0,
-                                        MachineOperand::MO_VirtualRegister,
-                                        instrNode->leftChild()->getValue());
+              minstr1 = new MachineInstr(opCode);
+              minstr1->SetMachineOperandVal(0,
+                                            MachineOperand::MO_VirtualRegister,
+                                            lval);
             } 
         }
     }
   
-  if (minstr != NULL)
-    minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                              instrNode->getValue());   
+  if (minstr1 != NULL)
+    minstr1->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+                                  destVal);   
   
-  return minstr;
+  if (minstr1)
+    {
+      mvec.push_back(minstr1);
+      cost = target.getInstrInfo().minLatency(minstr1->getOpCode());
+    }
+  if (minstr2)
+    {
+      assert(minstr1 && "Otherwise cost needs to be initialized to 0");
+      cost += target.getInstrInfo().minLatency(minstr2->getOpCode());
+      mvec.push_back(minstr2);
+    }
+  
+  return cost;
+}
+
+
+// Does not create any instructions if we cannot exploit constant to
+// create a cheaper instruction.
+// 
+static inline void
+CreateCheapestMulConstInstruction(const TargetMachine &target,
+                                  Value* lval, Value* rval, Value* destVal,
+                                  vector<MachineInstr*>& mvec)
+{
+  Value* constOp;
+  if (isa<Constant>(lval) && isa<Constant>(rval))
+    { // both operands are constant: try both orders!
+      vector<MachineInstr*> mvec1, mvec2;
+      unsigned int lcost = CreateMulConstInstruction(target, lval, rval,
+                                                     destVal, mvec1);
+      unsigned int rcost = CreateMulConstInstruction(target, rval, lval,
+                                                     destVal, mvec2);
+      vector<MachineInstr*>& mincostMvec =  (lcost <= rcost)? mvec1 : mvec2;
+      vector<MachineInstr*>& maxcostMvec =  (lcost <= rcost)? mvec2 : mvec1;
+      mvec.insert(mvec.end(), mincostMvec.begin(), mincostMvec.end()); 
+
+      for (unsigned int i=0; i < maxcostMvec.size(); ++i)
+        delete maxcostMvec[i];
+    }
+  else if (isa<Constant>(rval))         // rval is constant, but not lval
+    CreateMulConstInstruction(target, lval, rval, destVal, mvec);
+  else if (isa<Constant>(lval))         // lval is constant, but not rval
+    CreateMulConstInstruction(target, lval, rval, destVal, mvec);
+  
+  // else neither is constant
+  return;
+}
+
+// Return NULL if we cannot exploit constant to create a cheaper instruction
+static inline void
+CreateMulInstruction(const TargetMachine &target,
+                     Value* lval, Value* rval, Value* destVal,
+                     vector<MachineInstr*>& mvec,
+                     MachineOpCode forceMulOp = INVALID_MACHINE_OPCODE)
+{
+  unsigned int L = mvec.size();
+  CreateCheapestMulConstInstruction(target, lval, rval, destVal, mvec);
+  if (mvec.size() == L)
+    { // no instructions were added so create MUL reg, reg, reg.
+      // Use FSMULD if both operands are actually floats cast to doubles.
+      // Otherwise, use the default opcode for the appropriate type.
+      MachineOpCode mulOp = ((forceMulOp != INVALID_MACHINE_OPCODE)
+                             ? forceMulOp 
+                             : ChooseMulInstructionByType(destVal->getType()));
+      MachineInstr* M = new MachineInstr(mulOp);
+      M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, lval);
+      M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, rval);
+      M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, destVal);
+      mvec.push_back(M);
+    }
 }
 
 
@@ -631,16 +699,18 @@ ChooseDivInstruction(TargetMachine &target,
 }
 
 
-static inline MachineInstr* 
+// Return NULL if we cannot exploit constant to create a cheaper instruction
+static inline void
 CreateDivConstInstruction(TargetMachine &target,
                           const InstructionNode* instrNode,
-                          MachineInstr*& getMinstr2)
+                          vector<MachineInstr*>& mvec)
 {
-  MachineInstr* minstr = NULL;
-  getMinstr2 = NULL;
+  MachineInstr* minstr1 = NULL;
+  MachineInstr* minstr2 = NULL;
   
   Value* constOp = ((InstrTreeNode*) instrNode->rightChild())->getValue();
-  assert(isa<ConstPoolVal>(constOp));
+  if (! isa<Constant>(constOp))
+    return;
   
   // Cases worth optimizing are:
   // (1) Divide by 1 for any type: replace with copy (ADD or FMOV)
@@ -664,26 +734,30 @@ CreateDivConstInstruction(TargetMachine &target,
           
           if (C == 1)
             {
-              minstr = new MachineInstr(ADD);
-              minstr->SetMachineOperand(0,MachineOperand::MO_VirtualRegister,
-                                          instrNode->leftChild()->getValue());
-              minstr->SetMachineOperand(1,target.getRegInfo().getZeroRegNum());
+              minstr1 = new MachineInstr(ADD);
+              minstr1->SetMachineOperandVal(0,
+                                           MachineOperand::MO_VirtualRegister,
+                                           instrNode->leftChild()->getValue());
+              minstr1->SetMachineOperandReg(1,
+                                        target.getRegInfo().getZeroRegNum());
             }
           else if (IsPowerOf2(C, pow))
             {
               MachineOpCode opCode= ((resultType->isSigned())
                                      ? (resultType==Type::LongTy)? SRAX : SRA
                                      : (resultType==Type::LongTy)? SRLX : SRL);
-              minstr = new MachineInstr(opCode);
-              minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+              minstr1 = new MachineInstr(opCode);
+              minstr1->SetMachineOperandVal(0,
+                                           MachineOperand::MO_VirtualRegister,
                                            instrNode->leftChild()->getValue());
-              minstr->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
-                                           pow);
+              minstr1->SetMachineOperandConst(1,
+                                          MachineOperand::MO_UnextendedImmed,
+                                          pow);
             }
           
-          if (minstr && needNeg)
+          if (minstr1 && needNeg)
             { // insert <reg = SUB 0, reg> after the instr to flip the sign
-              getMinstr2 = CreateIntNegInstruction(target,
+              minstr2 = CreateIntNegInstruction(target,
                                                    instrNode->getValue());
             }
         }
@@ -693,7 +767,7 @@ CreateDivConstInstruction(TargetMachine &target,
       if (resultType == Type::FloatTy ||
           resultType == Type::DoubleTy)
         {
-          double dval = ((ConstPoolFP*) constOp)->getValue();
+          double dval = cast<ConstantFP>(constOp)->getValue();
           if (fabs(dval) == 1)
             {
               bool needNeg = (dval < 0);
@@ -702,21 +776,121 @@ CreateDivConstInstruction(TargetMachine &target,
                 ? (resultType == Type::FloatTy? FNEGS : FNEGD)
                 : (resultType == Type::FloatTy? FMOVS : FMOVD);
               
-              minstr = new MachineInstr(opCode);
-              minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+              minstr1 = new MachineInstr(opCode);
+              minstr1->SetMachineOperandVal(0,
+                                           MachineOperand::MO_VirtualRegister,
                                            instrNode->leftChild()->getValue());
             } 
         }
     }
   
-  if (minstr != NULL)
-    minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                              instrNode->getValue());   
+  if (minstr1 != NULL)
+    minstr1->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+                                 instrNode->getValue());   
   
-  return minstr;
+  if (minstr1)
+    mvec.push_back(minstr1);
+  if (minstr2)
+    mvec.push_back(minstr2);
 }
 
 
+static void
+CreateCodeForVariableSizeAlloca(const TargetMachine& target,
+                                Instruction* result,
+                                unsigned int tsize,
+                                Value* numElementsVal,
+                                vector<MachineInstr*>& getMvec)
+{
+  MachineInstr* M;
+  
+  // Create a Value to hold the (constant) element size
+  Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
+
+  // Get the constant offset from SP for dynamically allocated storage
+  // and create a temporary Value to hold it.
+  assert(result && result->getParent() && "Result value is not part of a fn?");
+  Function *F = result->getParent()->getParent();
+  MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(F);
+  bool growUp;
+  ConstantSInt* dynamicAreaOffset =
+    ConstantSInt::get(Type::IntTy,
+                      target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
+  assert(! growUp && "Has SPARC v9 stack frame convention changed?");
+
+  // Create a temporary value to hold the result of MUL
+  TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
+  MachineCodeForInstruction::get(result).addTemp(tmpProd);
+  
+  // Instruction 1: mul numElements, typeSize -> tmpProd
+  M = new MachineInstr(MULX);
+  M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, numElementsVal);
+  M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tsizeVal);
+  M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, tmpProd);
+  getMvec.push_back(M);
+        
+  // Instruction 2: sub %sp, tmpProd -> %sp
+  M = new MachineInstr(SUB);
+  M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+  M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpProd);
+  M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+  getMvec.push_back(M);
+  
+  // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
+  M = new MachineInstr(ADD);
+  M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+  M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, dynamicAreaOffset);
+  M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
+  getMvec.push_back(M);
+}        
+
+
+static void
+CreateCodeForFixedSizeAlloca(const TargetMachine& target,
+                             Instruction* result,
+                             unsigned int tsize,
+                             unsigned int numElements,
+                             vector<MachineInstr*>& getMvec)
+{
+  assert(result && result->getParent() &&
+         "Result value is not part of a function?");
+  Function *F = result->getParent()->getParent();
+  MachineCodeForMethod &mcInfo = MachineCodeForMethod::get(F);
+
+  // Check if the offset would small enough to use as an immediate in
+  // load/stores (check LDX because all load/stores have the same-size immediate
+  // field).  If not, put the variable in the dynamically sized area of the
+  // frame.
+  unsigned int paddedSizeIgnored;
+  int offsetFromFP = mcInfo.computeOffsetforLocalVar(target, result,
+                                                     paddedSizeIgnored,
+                                                     tsize * numElements);
+  if (! target.getInstrInfo().constantFitsInImmedField(LDX, offsetFromFP))
+    {
+      CreateCodeForVariableSizeAlloca(target, result, tsize, 
+                                      ConstantSInt::get(Type::IntTy,numElements),
+                                      getMvec);
+      return;
+    }
+  
+  // else offset fits in immediate field so go ahead and allocate it.
+  offsetFromFP = mcInfo.allocateLocalVar(target, result, tsize * numElements);
+  
+  // Create a temporary Value to hold the constant offset.
+  // This is needed because it may not fit in the immediate field.
+  ConstantSInt* offsetVal = ConstantSInt::get(Type::IntTy, offsetFromFP);
+  
+  // Instruction 1: add %fp, offsetFromFP -> result
+  MachineInstr* M = new MachineInstr(ADD);
+  M->SetMachineOperandReg(0, target.getRegInfo().getFramePointer());
+  M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, offsetVal); 
+  M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, result);
+  
+  getMvec.push_back(M);
+}
+
+
+
 //------------------------------------------------------------------------ 
 // Function SetOperandsForMemInstr
 //
@@ -734,7 +908,8 @@ CreateDivConstInstruction(TargetMachine &target,
 //------------------------------------------------------------------------ 
 
 static void
-SetOperandsForMemInstr(MachineInstr* minstr,
+SetOperandsForMemInstr(vector<MachineInstr*>& mvec,
+                       vector<MachineInstr*>::iterator mvecI,
                        const InstructionNode* vmInstrNode,
                        const TargetMachine& target)
 {
@@ -744,71 +919,42 @@ SetOperandsForMemInstr(MachineInstr* minstr,
   // The major work here is to extract these for all 3 instruction types
   // and then call the common function SetMemOperands_Internal().
   // 
-  const vector<ConstPoolVal*> OLDIDXVEC = memInst->getIndicesBROKEN();
-  const vector<ConstPoolVal*>* idxVec = &OLDIDXVEC;  //FIXME
-  vector<ConstPoolVal*>* newIdxVec = NULL;
-  Value* ptrVal;
-  Value* arrayOffsetVal = NULL;
-  
-  // Test if a GetElemPtr instruction is being folded into this mem instrn.
-  // If so, it will be in the left child for Load and GetElemPtr,
-  // and in the right child for Store instructions.
-  // 
+  Value* ptrVal = memInst->getPointerOperand();
+  
+  // Start with the index vector of this instruction, if any.
+  vector<Value*> idxVec;
+  idxVec.insert(idxVec.end(), memInst->idx_begin(), memInst->idx_end());
+  
+  // If there is a GetElemPtr instruction to fold in to this instr,
+  // it must be in the left child for Load and GetElemPtr, and in the
+  // right child for Store instructions.
   InstrTreeNode* ptrChild = (vmInstrNode->getOpLabel() == Instruction::Store
                              ? vmInstrNode->rightChild()
                              : vmInstrNode->leftChild()); 
   
-  if (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
-      ptrChild->getOpLabel() == GetElemPtrIdx)
+  // Fold chains of GetElemPtr instructions for structure references.
+  if (isa<StructType>(cast<PointerType>(ptrVal->getType())->getElementType())
+      && (ptrChild->getOpLabel() == Instruction::GetElementPtr ||
+          ptrChild->getOpLabel() == GetElemPtrIdx))
     {
-      // There is a GetElemPtr instruction and there may be a chain of
-      // more than one.  Use the pointer value of the last one in the chain.
-      // Fold the index vectors from the entire chain and from the mem
-      // instruction into one single index vector.
-      // Finally, we never fold for an array instruction so make that NULL.
-      
-      newIdxVec = new vector<ConstPoolVal*>;
-      ptrVal = FoldGetElemChain((InstructionNode*) ptrChild, *newIdxVec);
-      
-      newIdxVec->insert(newIdxVec->end(), idxVec->begin(), idxVec->end());
-      idxVec = newIdxVec;
-      
-      assert(! ((PointerType*)ptrVal->getType())->getValueType()->isArrayType()
-             && "GetElemPtr cannot be folded into array refs in selection");
+      Value* newPtr = FoldGetElemChain((InstructionNode*) ptrChild, idxVec);
+      if (newPtr)
+        ptrVal = newPtr;
     }
-  else
-    {
-      // There is no GetElemPtr instruction.
-      // Use the pointer value and the index vector from the Mem instruction.
-      // If it is an array reference, get the array offset value.
-      // 
-      ptrVal = memInst->getPointerOperand();
-
-      const Type* opType = cast<PointerType>(ptrVal->getType())->getValueType();
-      if (opType->isArrayType())
-        {
-          assert((memInst->getNumOperands()
-                  == (unsigned) 1 + memInst->getFirstIndexOperandNumber())
-                 && "Array refs must be lowered before Instruction Selection");
-          
-          arrayOffsetVal = memInst->getOperand(memInst->getFirstIndexOperandNumber());
-        }
-    }
-  
-  SetMemOperands_Internal(minstr, vmInstrNode, ptrVal, arrayOffsetVal,
-                          *idxVec, target);
   
-  if (newIdxVec != NULL)
-    delete newIdxVec;
+  SetMemOperands_Internal(mvec, mvecI, vmInstrNode, ptrVal, idxVec, target);
 }
 
 
+// Generate the correct operands (and additional instructions if needed)
+// for the given pointer and given index vector.
+//
 static void
-SetMemOperands_Internal(MachineInstr* minstr,
+SetMemOperands_Internal(vector<MachineInstr*>& mvec,
+                        vector<MachineInstr*>::iterator mvecI,
                         const InstructionNode* vmInstrNode,
                         Value* ptrVal,
-                        Value* arrayOffsetVal,
-                        const vector<ConstPoolVal*>& idxVec,
+                        vector<Value*>& idxVec,
                         const TargetMachine& target)
 {
   MemAccessInst* memInst = (MemAccessInst*) vmInstrNode->getInstruction();
@@ -818,52 +964,77 @@ SetMemOperands_Internal(MachineInstr* minstr,
   Value* valueForRegOffset = NULL;
   MachineOperand::MachineOperandType offsetOpType =MachineOperand::MO_VirtualRegister;
 
-  // Check if there is an index vector and if so, if it translates to
-  // a small enough constant to fit in the immediate-offset field.
+  // Check if there is an index vector and if so, compute the
+  // right offset for structures and for arrays 
   // 
   if (idxVec.size() > 0)
     {
-      bool isConstantOffset = false;
       unsigned offset = 0;
       
-      const PointerType* ptrType = (PointerType*) ptrVal->getType();
+      const PointerType* ptrType = cast<PointerType>(ptrVal->getType());
       
-      if (ptrType->getValueType()->isStructType())
+      // Handle special common case of leading [0] index.
+      bool firstIndexIsZero =
+        bool(isa<ConstantUInt>(idxVec.front()) &&
+             cast<ConstantUInt>(idxVec.front())->getValue() == 0);
+      
+      // This is a real structure reference if the ptr target is a
+      // structure type, and the first offset is [0] (eliminate that offset).
+      if (firstIndexIsZero && ptrType->getElementType()->isStructType())
         {
-          // the offset is always constant for structs
-          isConstantOffset = true;
-          
-          // Compute the offset value using the index vector
-          offset = target.DataLayout.getIndexedOffset(ptrType, idxVec);
+          // Compute the offset value using the index vector. Create a
+          // virtual reg. for it since it may not fit in the immed field.
+          assert(idxVec.size() >= 2);
+          idxVec.erase(idxVec.begin());
+          unsigned offset = target.DataLayout.getIndexedOffset(ptrType,idxVec);
+          valueForRegOffset = ConstantSInt::get(Type::IntTy, offset);
         }
       else
         {
-          // It must be an array ref.  Check if the offset is a constant,
-          // and that the indexing has been lowered to a single offset.
-          // 
-          assert(ptrType->getValueType()->isArrayType());
-          assert(arrayOffsetVal != NULL
-                 && "Expect to be given Value* for array offsets");
+          // It is an array ref, and must have been lowered to a single offset.
+          assert((memInst->getNumOperands()
+                  == (unsigned) 1 + memInst->getFirstIndexOperandNumber())
+                 && "Array refs must be lowered before Instruction Selection");
           
-          if (ConstPoolVal *CPV = dyn_cast<ConstPoolVal>(arrayOffsetVal))
+          Value* arrayOffsetVal =  * memInst->idx_begin();
+          
+          // If index is 0, the offset value is just 0.  Otherwise, 
+          // generate a MUL instruction to compute address from index.
+          // The call to getTypeSize() will fail if size is not constant.
+          // CreateMulInstruction() folds constants intelligently enough.
+          // 
+          if (firstIndexIsZero)
             {
-              isConstantOffset = true;  // always constant for structs
-              assert(arrayOffsetVal->getType()->isIntegral());
-              offset = (CPV->getType()->isSigned()
-                        ? ((ConstPoolSInt*)CPV)->getValue()
-                        : (int64_t) ((ConstPoolUInt*)CPV)->getValue());
+              offsetOpType = MachineOperand::MO_SignExtendedImmed;
+              smallConstOffset = 0;
             }
           else
             {
-              valueForRegOffset = arrayOffsetVal;
+              vector<MachineInstr*> mulVec;
+              Instruction* addr = new TmpInstruction(Type::UIntTy, memInst);
+              MachineCodeForInstruction::get(memInst).addTemp(addr);
+              
+              unsigned int eltSize =
+                target.DataLayout.getTypeSize(ptrType->getElementType());
+              assert(eltSize > 0 && "Invalid or non-const array element size");
+              ConstantUInt* eltVal = ConstantUInt::get(Type::UIntTy, eltSize);
+              
+              CreateMulInstruction(target,
+                                   arrayOffsetVal, /* lval, not likely const */
+                                   eltVal,         /* rval, likely constant */
+                                   addr,           /* result*/
+                                   mulVec, INVALID_MACHINE_OPCODE);
+              assert(mulVec.size() > 0 && "No multiply instruction created?");
+              for (vector<MachineInstr*>::const_iterator I = mulVec.begin();
+                   I != mulVec.end(); ++I)
+                {
+                  mvecI = mvec.insert(mvecI, *I);   // ptr to inserted value
+                  ++mvecI;                          // ptr to mem. instr.
+                }
+              
+              valueForRegOffset = addr;
             }
         }
-      
-      if (isConstantOffset)
-        {
-          // create a virtual register for the constant
-          valueForRegOffset = ConstPoolSInt::get(Type::IntTy, offset);
-        }
     }
   else
     {
@@ -871,28 +1042,39 @@ SetMemOperands_Internal(MachineInstr* minstr,
       smallConstOffset = 0;
     }
   
-  // Operand 0 is value for STORE, ptr for LOAD or GET_ELEMENT_PTR
-  // It is the left child in the instruction tree in all cases.
-  Value* leftVal = vmInstrNode->leftChild()->getValue();
-  minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, leftVal);
+  // For STORE:
+  //   Operand 0 is value, operand 1 is ptr, operand 2 is offset
+  // For LOAD or GET_ELEMENT_PTR,
+  //   Operand 0 is ptr, operand 1 is offset, operand 2 is result.
+  // 
+  unsigned offsetOpNum, ptrOpNum;
+  if (memInst->getOpcode() == Instruction::Store)
+    {
+      (*mvecI)->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                     vmInstrNode->leftChild()->getValue());
+      ptrOpNum = 1;
+      offsetOpNum = 2;
+    }
+  else
+    {
+      ptrOpNum = 0;
+      offsetOpNum = 1;
+      (*mvecI)->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+                                     memInst);
+    }
+  
+  (*mvecI)->SetMachineOperandVal(ptrOpNum, MachineOperand::MO_VirtualRegister,
+                                 ptrVal);
   
-  // Operand 1 is ptr for STORE, offset for LOAD or GET_ELEMENT_PTR
-  // Operand 2 is offset for STORE, result reg for LOAD or GET_ELEMENT_PTR
-  //
-  unsigned offsetOpNum = (memInst->getOpcode() == Instruction::Store)? 2 : 1;
   if (offsetOpType == MachineOperand::MO_VirtualRegister)
     {
       assert(valueForRegOffset != NULL);
-      minstr->SetMachineOperand(offsetOpNum, offsetOpType, valueForRegOffset); 
+      (*mvecI)->SetMachineOperandVal(offsetOpNum, offsetOpType,
+                                     valueForRegOffset); 
     }
   else
-    minstr->SetMachineOperand(offsetOpNum, offsetOpType, smallConstOffset);
-  
-  if (memInst->getOpcode() == Instruction::Store)
-    minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, ptrVal);
-  else
-    minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                 vmInstrNode->getValue());
+    (*mvecI)->SetMachineOperandConst(offsetOpNum, offsetOpType,
+                                     smallConstOffset);
 }
 
 
@@ -900,6 +1082,9 @@ SetMemOperands_Internal(MachineInstr* minstr,
 // Substitute operand `operandNum' of the instruction in node `treeNode'
 // in place of the use(s) of that instruction in node `parent'.
 // Check both explicit and implicit operands!
+// Also make sure to skip over a parent who:
+// (1) is a list node in the Burg tree, or
+// (2) itself had its results forwarded to its parent
 // 
 static void
 ForwardOperand(InstructionNode* treeNode,
@@ -920,32 +1105,51 @@ ForwardOperand(InstructionNode* treeNode,
   InstructionNode* parentInstrNode = (InstructionNode*) parent;
   
   Instruction* userInstr = parentInstrNode->getInstruction();
-  MachineCodeForVMInstr& mvec = userInstr->getMachineInstrVec();
-  for (unsigned i=0, N=mvec.size(); i < N; i++)
+  MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(userInstr);
+
+  // The parent's mvec would be empty if it was itself forwarded.
+  // Recursively call ForwardOperand in that case...
+  //
+  if (mvec.size() == 0)
     {
-      MachineInstr* minstr = mvec[i];
-      
-      for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
+      assert(parent->parent() != NULL &&
+             "Parent could not have been forwarded, yet has no instructions?");
+      ForwardOperand(treeNode, parent->parent(), operandNum);
+    }
+  else
+    {
+      bool fwdSuccessful = false;
+      for (unsigned i=0, N=mvec.size(); i < N; i++)
         {
-          const MachineOperand& mop = minstr->getOperand(i);
-          if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
-              mop.getVRegValue() == unusedOp)
+          MachineInstr* minstr = mvec[i];
+          for (unsigned i=0, numOps=minstr->getNumOperands(); i < numOps; ++i)
             {
-              minstr->SetMachineOperand(i, MachineOperand::MO_VirtualRegister,
-                                           fwdOp);
+              const MachineOperand& mop = minstr->getOperand(i);
+              if (mop.getOperandType() == MachineOperand::MO_VirtualRegister &&
+                  mop.getVRegValue() == unusedOp)
+                {
+                  minstr->SetMachineOperandVal(i,
+                                MachineOperand::MO_VirtualRegister, fwdOp);
+                  fwdSuccessful = true;
+                }
             }
+          
+          for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); i<numOps; ++i)
+            if (minstr->getImplicitRef(i) == unusedOp)
+              {
+                minstr->setImplicitRef(i, fwdOp,
+                                       minstr->implicitRefIsDefined(i));
+                fwdSuccessful = true;
+              }
         }
-      
-      for (unsigned i=0, numOps=minstr->getNumImplicitRefs(); i < numOps; ++i)
-        if (minstr->getImplicitRef(i) == unusedOp)
-          minstr->setImplicitRef(i, fwdOp, minstr->implicitRefIsDefined(i));
+      assert(fwdSuccessful && "Value to be forwarded is never used!");
     }
 }
 
 
-
 void UltraSparcInstrInfo::
 CreateCopyInstructionsByType(const TargetMachine& target,
+                             Function *F,
                              Value* src,
                              Instruction* dest,
                              vector<MachineInstr*>& minstrVec) const
@@ -965,7 +1169,7 @@ CreateCopyInstructionsByType(const TargetMachine& target,
   // a global variable (i.e., a constant address), generate a load
   // instruction instead of an add
   // 
-  if (isa<ConstPoolVal>(src))
+  if (isa<Constant>(src))
     {
       unsigned int machineRegNum;
       int64_t immedValue;
@@ -983,23 +1187,24 @@ CreateCopyInstructionsByType(const TargetMachine& target,
     { // `src' is constant and cannot fit in immed field for the ADD
       // Insert instructions to "load" the constant into a register
       vector<TmpInstruction*> tempVec;
-      target.getInstrInfo().CreateCodeToLoadConst(src,dest,minstrVec,tempVec);
+      target.getInstrInfo().CreateCodeToLoadConst(F, src, dest,
+                                                  minstrVec, tempVec);
       for (unsigned i=0; i < tempVec.size(); i++)
-        dest->getMachineInstrVec().addTempValue(tempVec[i]);
+        MachineCodeForInstruction::get(dest).addTemp(tempVec[i]);
     }
   else
-    { // Create the appropriate add instruction.
+    { // Create an add-with-0 instruction of the appropriate type.
       // Make `src' the second operand, in case it is a constant
       // Use (unsigned long) 0 for a NULL pointer value.
       // 
-      const Type* nullValueType =
+      const Type* zeroValueType =
         (resultType->getPrimitiveID() == Type::PointerTyID)? Type::ULongTy
                                                            : resultType;
       MachineInstr* minstr = new MachineInstr(opCode);
-      minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                ConstPoolVal::getNullConstant(nullValueType));
-      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, src);
-      minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
+      minstr->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                   Constant::getNullConstant(zeroValueType));
+      minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, src);
+      minstr->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,dest);
       minstrVec.push_back(minstr);
     }
 }
@@ -1022,16 +1227,17 @@ GetInstructionsForProlog(BasicBlock* entryBB,
                          TargetMachine &target,
                          MachineInstr** mvec)
 {
-  int64_t s0=0;                // used to avoid overloading ambiguity below
-  
+  MachineInstr* M;
   const MachineFrameInfo& frameInfo = target.getFrameInfo();
+  unsigned int N = 0;
   
   // The second operand is the stack size. If it does not fit in the
-  // immediate field, we either have to find an unused register in the
-  // caller's window or move some elements to the dynamically allocated
-  // area of the stack frame (just above save area and method args).
-  Method* method = entryBB->getParent();
-  MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
+  // immediate field, we have to use a free register to hold the size.
+  // We will assume that local register `l0' is unused since the SAVE
+  // instruction must be the first instruction in each procedure.
+  // 
+  Function *F = entryBB->getParent();
+  MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(F);
   unsigned int staticStackSize = mcInfo.getStaticStackSize();
   
   if (staticStackSize < (unsigned) frameInfo.getMinStackFrameSize())
@@ -1041,16 +1247,37 @@ GetInstructionsForProlog(BasicBlock* entryBB,
                         (unsigned) frameInfo.getStackFrameSizeAlignment()))
     staticStackSize += frameInfo.getStackFrameSizeAlignment() - padsz;
   
-  assert(target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize)
-         && "Stack size too large for immediate field of SAVE instruction. Need additional work as described in the comment above");
-  
-  mvec[0] = new MachineInstr(SAVE);
-  mvec[0]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
-  mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+  if (target.getInstrInfo().constantFitsInImmedField(SAVE, staticStackSize))
+    {
+      M = new MachineInstr(SAVE);
+      M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+      M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
+                                   - (int) staticStackSize);
+      M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+      mvec[N++] = M;
+    }
+  else
+    {
+      M = new MachineInstr(SETSW);
+      M->SetMachineOperandConst(0, MachineOperand::MO_SignExtendedImmed,
                                 - (int) staticStackSize);
-  mvec[0]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
+      M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
+                                 target.getRegInfo().getUnifiedRegNum(
+                                  target.getRegInfo().getRegClassIDOfType(Type::IntTy),
+                                  SparcIntRegOrder::l0));
+      mvec[N++] = M;
+      
+      M = new MachineInstr(SAVE);
+      M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
+      M->SetMachineOperandReg(1, MachineOperand::MO_MachineRegister,
+                                 target.getRegInfo().getUnifiedRegNum(
+                                  target.getRegInfo().getRegClassIDOfType(Type::IntTy),
+                                  SparcIntRegOrder::l0));
+      M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
+      mvec[N++] = M;
+    }
   
-  return 1;
+  return N;
 }
 
 
@@ -1059,12 +1286,11 @@ GetInstructionsForEpilog(BasicBlock* anExitBB,
                          TargetMachine &target,
                          MachineInstr** mvec)
 {
-  int64_t s0=0;                // used to avoid overloading ambiguity below
-  
   mvec[0] = new MachineInstr(RESTORE);
-  mvec[0]->SetMachineOperand(0, target.getRegInfo().getZeroRegNum());
-  mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, s0);
-  mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
+  mvec[0]->SetMachineOperandReg(0, target.getRegInfo().getZeroRegNum());
+  mvec[0]->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
+                             (int64_t)0);
+  mvec[0]->SetMachineOperandReg(2, target.getRegInfo().getZeroRegNum());
   
   return 1;
 }
@@ -1102,6 +1328,7 @@ ThisIsAChainRule(int eruleno)
     case 242:
     case 243:
     case 244:
+    case 321:
       return true; break;
       
     default:
@@ -1118,22 +1345,26 @@ ThisIsAChainRule(int eruleno)
 //   patterns chosen by the BURG-generated parser.
 //------------------------------------------------------------------------ 
 
-unsigned
+void
 GetInstructionsByRule(InstructionNode* subtreeRoot,
                       int ruleForNode,
                       short* nts,
                       TargetMachine &target,
-                      MachineInstr** mvec)
+                      vector<MachineInstr*>& mvec)
 {
-  int numInstr = 1;                    // initialize for common case
   bool checkCast = false;              // initialize here to use fall-through
   int nextRule;
   int forwardOperandNum = -1;
-  int64_t s0=0, s8=8;                  // variables holding constants to avoid
-  uint64_t u0=0;                       // overloading ambiguities below
+  unsigned int allocaSize = 0;
+  MachineInstr* M, *M2;
+  unsigned int L;
+
+  mvec.clear(); 
   
-  for (unsigned i=0; i < MAX_INSTR_PER_VMINSTR; i++)
-    mvec[i] = NULL;
+  // If the code for this instruction was folded into the parent (user),
+  // then do nothing!
+  if (subtreeRoot->isFoldedIntoParent())
+    return;
   
   // 
   // Let's check for chain rules outside the switch so that we don't have
@@ -1148,7 +1379,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
              && "A chain rule should have only one RHS non-terminal!");
       nextRule = burm_rule(subtreeRoot->state, nts[0]);
       nts = burm_nts[nextRule];
-      numInstr = GetInstructionsByRule(subtreeRoot, nextRule, nts,target,mvec);
+      GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec);
     }
   else
     {
@@ -1161,46 +1392,47 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                 // Mark the return value   register as an implicit ref of
                 // the machine instruction.
                // Finally put a NOP in the delay slot.
-        ReturnInst* returnInstr = (ReturnInst*) subtreeRoot->getInstruction();
+        ReturnInst *returnInstr =
+          cast<ReturnInst>(subtreeRoot->getInstruction());
         assert(returnInstr->getOpcode() == Instruction::Ret);
-        Method* method = returnInstr->getParent()->getParent();
         
-        Instruction* returnReg = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
-                                                    returnInstr, NULL);
-        returnInstr->getMachineInstrVec().addTempValue(returnReg);
+        Instruction* returnReg = new TmpInstruction(returnInstr);
+        MachineCodeForInstruction::get(returnInstr).addTemp(returnReg);
         
-        mvec[0] = new MachineInstr(JMPLRET);
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+        M = new MachineInstr(JMPLRET);
+        M->SetMachineOperandReg(0, MachineOperand::MO_VirtualRegister,
                                       returnReg);
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,s8);
-        mvec[0]->SetMachineOperand(2, target.getRegInfo().getZeroRegNum());
+        M->SetMachineOperandConst(1,MachineOperand::MO_SignExtendedImmed,
+                                   (int64_t)8);
+        M->SetMachineOperandReg(2, target.getRegInfo().getZeroRegNum());
         
         if (returnInstr->getReturnValue() != NULL)
-          mvec[0]->addImplicitRef(returnInstr->getReturnValue());
+          M->addImplicitRef(returnInstr->getReturnValue());
         
-        unsigned n = numInstr++; // delay slot
-        mvec[n] = new MachineInstr(NOP);
+        mvec.push_back(M);
+        mvec.push_back(new MachineInstr(NOP));
         
         break;
       }  
         
       case 3:  // stmt:   Store(reg,reg)
       case 4:  // stmt:   Store(reg,ptrreg)
-        mvec[0] = new MachineInstr(
-                       ChooseStoreInstruction(
-                            subtreeRoot->leftChild()->getValue()->getType()));
-        SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(
+                         ChooseStoreInstruction(
+                            subtreeRoot->leftChild()->getValue()->getType())));
+        SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
         break;
 
       case 5:  // stmt:   BrUncond
-        mvec[0] = new MachineInstr(BA);
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
+        M = new MachineInstr(BA);
+        M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
                                       (Value*)NULL);
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
-              ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
+        M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+             cast<BranchInst>(subtreeRoot->getInstruction())->getSuccessor(0));
+        mvec.push_back(M);
         
         // delay slot
-        mvec[numInstr++] = new MachineInstr(NOP);
+        mvec.push_back(new MachineInstr(NOP));
         break;
 
       case 206:        // stmt:   BrCond(setCCconst)
@@ -1212,37 +1444,44 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         InstrTreeNode* constNode = subtreeRoot->leftChild()->rightChild();
         assert(constNode &&
                constNode->getNodeType() ==InstrTreeNode::NTConstNode);
-        ConstPoolVal* constVal = (ConstPoolVal*) constNode->getValue();
+        Constant *constVal = cast<Constant>(constNode->getValue());
         bool isValidConst;
-
+        
         if ((constVal->getType()->isIntegral()
              || constVal->getType()->isPointerType())
             && GetConstantValueAsSignedInt(constVal, isValidConst) == 0
             && isValidConst)
           {
-            BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction());
-            
             // That constant is a zero after all...
             // Use the left child of setCC as the first argument!
-            mvec[0] = new MachineInstr(ChooseBprInstruction(subtreeRoot));
-            mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                          subtreeRoot->leftChild()->leftChild()->getValue());
-            mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
-                                          brInst->getSuccessor(0));
-
+            // Mark the setCC node so that no code is generated for it.
+            InstructionNode* setCCNode = (InstructionNode*)
+                                         subtreeRoot->leftChild();
+            assert(setCCNode->getOpLabel() == SetCCOp);
+            setCCNode->markFoldedIntoParent();
+            
+            BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction());
+            
+            M = new MachineInstr(ChooseBprInstruction(subtreeRoot));
+            M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                    setCCNode->leftChild()->getValue());
+            M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+                                    brInst->getSuccessor(0));
+            mvec.push_back(M);
+            
             // delay slot
-            mvec[numInstr++] = new MachineInstr(NOP);
+            mvec.push_back(new MachineInstr(NOP));
 
             // false branch
-            int n = numInstr++; 
-            mvec[n] = new MachineInstr(BA);
-            mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
-                                          (Value*) NULL);
-            mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
-                                          brInst->getSuccessor(1));
+            M = new MachineInstr(BA);
+            M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+                                    (Value*) NULL);
+            M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+                                    brInst->getSuccessor(1));
+            mvec.push_back(M);
             
             // delay slot
-            mvec[numInstr++] = new MachineInstr(NOP);
+            mvec.push_back(new MachineInstr(NOP));
             
             break;
           }
@@ -1259,48 +1498,49 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         // 
         BranchInst* brInst = cast<BranchInst>(subtreeRoot->getInstruction());
         bool isFPBranch;
-        mvec[0] = new MachineInstr(ChooseBccInstruction(subtreeRoot,
-                                                        isFPBranch));
+        M = new MachineInstr(ChooseBccInstruction(subtreeRoot, isFPBranch));
         
         Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
                                      brInst->getParent()->getParent(),
                                      isFPBranch? Type::FloatTy : Type::IntTy);
         
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister, ccValue);
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
-                                      brInst->getSuccessor(0));
+        M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister, ccValue);
+        M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+                                   brInst->getSuccessor(0));
+        mvec.push_back(M);
         
         // delay slot
-        mvec[numInstr++] = new MachineInstr(NOP);
+        mvec.push_back(new MachineInstr(NOP));
         
         // false branch
-        int n = numInstr++;
-        mvec[n] = new MachineInstr(BA);
-        mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
-                                      (Value*) NULL);
-        mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
-                                      brInst->getSuccessor(1));
+        M = new MachineInstr(BA);
+        M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+                                   (Value*) NULL);
+        M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
+                                   brInst->getSuccessor(1));
+        mvec.push_back(M);
         
         // delay slot
-        mvec[numInstr++] = new MachineInstr(NOP);
+        mvec.push_back(new MachineInstr(NOP));
         break;
       }
         
       case 208:        // stmt:   BrCond(boolconst)
       {
         // boolconst => boolean is a constant; use BA to first or second label
-        ConstPoolVal* constVal = 
-          cast<ConstPoolVal>(subtreeRoot->leftChild()->getValue());
-        unsigned dest = ((ConstPoolBool*) constVal)->getValue()? 0 : 1;
+        Constant* constVal = 
+          cast<Constant>(subtreeRoot->leftChild()->getValue());
+        unsigned dest = cast<ConstantBool>(constVal)->getValue()? 0 : 1;
         
-        mvec[0] = new MachineInstr(BA);
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
-                                      (Value*) NULL);
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+        M = new MachineInstr(BA);
+        M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+                                (Value*) NULL);
+        M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
           ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(dest));
+        mvec.push_back(M);
         
         // delay slot
-        mvec[numInstr++] = new MachineInstr(NOP);
+        mvec.push_back(new MachineInstr(NOP));
         break;
       }
         
@@ -1308,31 +1548,31 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
       { // boolreg   => boolean is stored in an existing register.
         // Just use the branch-on-integer-register instruction!
         // 
-        mvec[0] = new MachineInstr(BRNZ);
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+        M = new MachineInstr(BRNZ);
+        M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
                                       subtreeRoot->leftChild()->getValue());
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+        M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(0));
+        mvec.push_back(M);
 
         // delay slot
-        mvec[numInstr++] = new MachineInstr(NOP); // delay slot
+        mvec.push_back(new MachineInstr(NOP));
 
         // false branch
-        int n = numInstr++;
-        mvec[n] = new MachineInstr(BA);
-        mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
-                                      (Value*) NULL);
-        mvec[n]->SetMachineOperand(1, MachineOperand::MO_PCRelativeDisp,
+        M = new MachineInstr(BA);
+        M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+                                (Value*) NULL);
+        M->SetMachineOperandVal(1, MachineOperand::MO_PCRelativeDisp,
               ((BranchInst*) subtreeRoot->getInstruction())->getSuccessor(1));
+        mvec.push_back(M);
         
         // delay slot
-        mvec[numInstr++] = new MachineInstr(NOP);
+        mvec.push_back(new MachineInstr(NOP));
         break;
       }  
       
       case 9:  // stmt:   Switch(reg)
         assert(0 && "*** SWITCH instruction is not implemented yet.");
-        numInstr = 0;
         break;
 
       case 10: // reg:   VRegList(reg, reg)
@@ -1340,13 +1580,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         break;
 
       case 21: // bool:  Not(bool):    Both these are implemented as:
-      case 321:        // reg:   BNot(reg) :        reg = reg XOR-NOT 0
-        mvec[0] = new MachineInstr(XNOR);
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                      subtreeRoot->leftChild()->getValue());
-        mvec[0]->SetMachineOperand(1, target.getRegInfo().getZeroRegNum());
-        mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                     subtreeRoot->getValue());
+      case 421:        // reg:   BNot(reg) :        reg = reg XOR-NOT 0
+        M = new MachineInstr(XNOR);
+        M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                subtreeRoot->leftChild()->getValue());
+        M->SetMachineOperandReg(1, target.getRegInfo().getZeroRegNum());
+        M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+                                subtreeRoot->getValue());
+        mvec.push_back(M);
         break;
 
       case 322:        // reg:   ToBoolTy(bool):
@@ -1355,8 +1596,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
         assert(opType->isIntegral() || opType->isPointerType()
                || opType == Type::BoolTy);
-        numInstr = 0;
-        forwardOperandNum = 0;
+        forwardOperandNum = 0;          // forward first operand to user
         break;
       }
       
@@ -1369,8 +1609,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         assert(opType->isIntegral() ||
                opType->isPointerType() ||
                opType == Type::BoolTy && "Cast is illegal for other types");
-        numInstr = 0;
-        forwardOperandNum = 0;
+        forwardOperandNum = 0;          // forward first operand to user
         break;
       }
       
@@ -1384,8 +1623,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
             || opType->isPointerType()
             || opType == Type::BoolTy)
           {
-            numInstr = 0;
-            forwardOperandNum = 0;
+            forwardOperandNum = 0;          // forward first operand to user
           }
         else
           {
@@ -1407,9 +1645,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                 const Type* destTypeToUse =
                   (dest->getType() == Type::LongTy)? Type::DoubleTy
                                                    : Type::FloatTy;
-                destForCast = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
-                                                 destTypeToUse, leftVal, NULL);
-                dest->getMachineInstrVec().addTempValue(destForCast);
+                destForCast = new TmpInstruction(destTypeToUse, leftVal);
+                MachineCodeForInstruction &MCFI = 
+                  MachineCodeForInstruction::get(dest);
+                MCFI.addTemp(destForCast);
                 
                 vector<TmpInstruction*> tempVec;
                 target.getInstrInfo().CreateCodeToCopyFloatToInt(
@@ -1418,7 +1657,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                     minstrVec, tempVec, target);
                 
                 for (unsigned i=0; i < tempVec.size(); ++i)
-                  dest->getMachineInstrVec().addTempValue(tempVec[i]);
+                  MCFI.addTemp(tempVec[i]);
               }
             else
               destForCast = leftVal;
@@ -1426,15 +1665,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
             MachineOpCode opCode=ChooseConvertToIntInstr(subtreeRoot, opType);
             assert(opCode != INVALID_OPCODE && "Expected to need conversion!");
             
-            mvec[0] = new MachineInstr(opCode);
-            mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                          leftVal);
-            mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                          destForCast);
-
-            assert(numInstr == 1 && "Should be initialized to 1 at the top");
-            for (unsigned i=0; i < minstrVec.size(); ++i)
-              mvec[numInstr++] = minstrVec[i];
+            M = new MachineInstr(opCode);
+            M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                    leftVal);
+            M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+                                    destForCast);
+            mvec.push_back(M);
+
+            // Append the copy code, if any, after the conversion instr.
+            mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
           }
         break;
       }  
@@ -1450,10 +1689,9 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         // so do the check here instead of only for ToFloatTy(reg).
         // 
         if (subtreeRoot->parent() != NULL &&
-            ((InstructionNode*) subtreeRoot->parent())->getInstruction()->getMachineInstrVec()[0]->getOpCode() == FSMULD)
+            MachineCodeForInstruction::get(((InstructionNode*)subtreeRoot->parent())->getInstruction())[0]->getOpCode() == FSMULD)
           {
-            numInstr = 0;
-            forwardOperandNum = 0;
+            forwardOperandNum = 0;          // forward first operand to user
           }
         else
           {
@@ -1462,8 +1700,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
             MachineOpCode opCode=ChooseConvertToFloatInstr(subtreeRoot,opType);
             if (opCode == INVALID_OPCODE)      // no conversion needed
               {
-                numInstr = 0;
-                forwardOperandNum = 0;
+                forwardOperandNum = 0;      // forward first operand to user
               }
             else
               {
@@ -1484,9 +1721,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                       (leftVal->getType() == Type::LongTy)? Type::DoubleTy
                                                           : Type::FloatTy;
                     
-                    srcForCast = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
-                                                    srcTypeToUse, dest, NULL);
-                    dest->getMachineInstrVec().addTempValue(srcForCast);
+                    srcForCast = new TmpInstruction(srcTypeToUse, dest);
+                    MachineCodeForInstruction &DestMCFI = 
+                      MachineCodeForInstruction::get(dest);
+                    DestMCFI.addTemp(srcForCast);
                     
                     vector<MachineInstr*> minstrVec;
                     vector<TmpInstruction*> tempVec;
@@ -1495,53 +1733,56 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
                          leftVal, (TmpInstruction*) srcForCast,
                          minstrVec, tempVec, target);
                     
-                    for (unsigned i=0; i < minstrVec.size(); ++i)
-                      mvec[n++] = minstrVec[i];
-
+                    mvec.insert(mvec.end(), minstrVec.begin(),minstrVec.end());
+                    
                     for (unsigned i=0; i < tempVec.size(); ++i)
-                       dest->getMachineInstrVec().addTempValue(tempVec[i]);
+                       DestMCFI.addTemp(tempVec[i]);
                   }
                 else
                   srcForCast = leftVal;
                 
-                MachineInstr* castI = new MachineInstr(opCode);
-                castI->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                            srcForCast);
-                castI->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                            dest);
-                mvec[n++] = castI;
-                numInstr = n;
+                M = new MachineInstr(opCode);
+                M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                           srcForCast);
+                M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+                                           dest);
+                mvec.push_back(M);
               }
           }
         break;
 
       case 19: // reg:   ToArrayTy(reg):
       case 20: // reg:   ToPointerTy(reg):
-        numInstr = 0;
-        forwardOperandNum = 0;
+        forwardOperandNum = 0;          // forward first operand to user
         break;
 
       case 233:        // reg:   Add(reg, Constant)
-        mvec[0] = CreateAddConstInstruction(subtreeRoot);
-        if (mvec[0] != NULL)
-          break;
+        M = CreateAddConstInstruction(subtreeRoot);
+        if (M != NULL)
+          {
+            mvec.push_back(M);
+            break;
+          }
         // ELSE FALL THROUGH
-
+        
       case 33: // reg:   Add(reg, reg)
-        mvec[0] = new MachineInstr(ChooseAddInstruction(subtreeRoot));
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(ChooseAddInstruction(subtreeRoot)));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case 234:        // reg:   Sub(reg, Constant)
-        mvec[0] = CreateSubConstInstruction(subtreeRoot);
-        if (mvec[0] != NULL)
-          break;
+        M = CreateSubConstInstruction(subtreeRoot);
+        if (M != NULL)
+          {
+            mvec.push_back(M);
+            break;
+          }
         // ELSE FALL THROUGH
-
+        
       case 34: // reg:   Sub(reg, reg)
-        mvec[0] = new MachineInstr(ChooseSubInstructionByType(
-                                   subtreeRoot->getInstruction()->getType()));
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(ChooseSubInstructionByType(
+                                   subtreeRoot->getInstruction()->getType())));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case 135:        // reg:   Mul(todouble, todouble)
@@ -1549,40 +1790,43 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         // FALL THROUGH 
 
       case 35: // reg:   Mul(reg, reg)
-        mvec[0] =new MachineInstr(ChooseMulInstruction(subtreeRoot,checkCast));
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+      {
+        MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
+                                 ? FSMULD
+                                 : INVALID_MACHINE_OPCODE);
+        CreateMulInstruction(target,
+                             subtreeRoot->leftChild()->getValue(),
+                             subtreeRoot->rightChild()->getValue(),
+                             subtreeRoot->getInstruction(),
+                             mvec, forceOp);
         break;
-
+      }
       case 335:        // reg:   Mul(todouble, todoubleConst)
         checkCast = true;
         // FALL THROUGH 
 
       case 235:        // reg:   Mul(reg, Constant)
-        mvec[0] = CreateMulConstInstruction(target, subtreeRoot, mvec[1]);
-        if (mvec[0] == NULL)
-          {
-            mvec[0] = new MachineInstr(ChooseMulInstruction(subtreeRoot,
-                                                            checkCast));
-            Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
-          }
-        else
-          if (mvec[1] != NULL)
-            ++numInstr;
+      {
+        MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
+                                 ? FSMULD
+                                 : INVALID_MACHINE_OPCODE);
+        CreateMulInstruction(target,
+                             subtreeRoot->leftChild()->getValue(),
+                             subtreeRoot->rightChild()->getValue(),
+                             subtreeRoot->getInstruction(),
+                             mvec, forceOp);
         break;
-
+      }
       case 236:        // reg:   Div(reg, Constant)
-        mvec[0] = CreateDivConstInstruction(target, subtreeRoot, mvec[1]);
-        if (mvec[0] != NULL)
-          {
-            if (mvec[1] != NULL)
-              ++numInstr;
-          }
-        else
+        L = mvec.size();
+        CreateDivConstInstruction(target, subtreeRoot, mvec);
+        if (mvec.size() > L)
+          break;
         // ELSE FALL THROUGH
-
+      
       case 36: // reg:   Div(reg, reg)
-        mvec[0] = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(ChooseDivInstruction(target, subtreeRoot)));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case  37:        // reg:   Rem(reg, reg)
@@ -1590,32 +1834,32 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
       {
         Instruction* remInstr = subtreeRoot->getInstruction();
         
-        TmpInstruction* quot = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
+        TmpInstruction* quot = new TmpInstruction(
                                         subtreeRoot->leftChild()->getValue(),
                                         subtreeRoot->rightChild()->getValue());
-        TmpInstruction* prod = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
+        TmpInstruction* prod = new TmpInstruction(
                                         quot,
                                         subtreeRoot->rightChild()->getValue());
-        remInstr->getMachineInstrVec().addTempValue(quot); 
-        remInstr->getMachineInstrVec().addTempValue(prod); 
+        MachineCodeForInstruction::get(remInstr).addTemp(quot).addTemp(prod); 
         
-        mvec[0] = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
-        mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,quot);
+        M = new MachineInstr(ChooseDivInstruction(target, subtreeRoot));
+        Set3OperandsFromInstr(M, subtreeRoot, target);
+        M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,quot);
+        mvec.push_back(M);
         
-        int n = numInstr++;
-        mvec[n] = new MachineInstr(ChooseMulInstructionByType(
+        M = new MachineInstr(ChooseMulInstructionByType(
                                    subtreeRoot->getInstruction()->getType()));
-        mvec[n]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,quot);
-        mvec[n]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
+        M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,quot);
+        M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
                                       subtreeRoot->rightChild()->getValue());
-        mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,prod);
+        M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,prod);
+        mvec.push_back(M);
         
-        n = numInstr++;
-        mvec[n] = new MachineInstr(ChooseSubInstructionByType(
+        M = new MachineInstr(ChooseSubInstructionByType(
                                    subtreeRoot->getInstruction()->getType()));
-        Set3OperandsFromInstr(mvec[n], subtreeRoot, target);
-        mvec[n]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,prod);
+        Set3OperandsFromInstr(M, subtreeRoot, target);
+        M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,prod);
+        mvec.push_back(M);
         
         break;
       }
@@ -1624,74 +1868,50 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
       case 238:        // bool:   And(bool, boolconst)
       case 338:        // reg :   BAnd(reg, reg)
       case 538:        // reg :   BAnd(reg, Constant)
-        mvec[0] = new MachineInstr(AND);
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(AND));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case 138:        // bool:   And(bool, not)
       case 438:        // bool:   BAnd(bool, not)
-        mvec[0] = new MachineInstr(ANDN);
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(ANDN));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case  39:        // bool:   Or(bool, bool)
       case 239:        // bool:   Or(bool, boolconst)
       case 339:        // reg :   BOr(reg, reg)
       case 539:        // reg :   BOr(reg, Constant)
-        mvec[0] = new MachineInstr(ORN);
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(ORN));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case 139:        // bool:   Or(bool, not)
       case 439:        // bool:   BOr(bool, not)
-        mvec[0] = new MachineInstr(ORN);
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(ORN));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case  40:        // bool:   Xor(bool, bool)
       case 240:        // bool:   Xor(bool, boolconst)
       case 340:        // reg :   BXor(reg, reg)
       case 540:        // reg :   BXor(reg, Constant)
-        mvec[0] = new MachineInstr(XOR);
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(XOR));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case 140:        // bool:   Xor(bool, not)
       case 440:        // bool:   BXor(bool, not)
-        mvec[0] = new MachineInstr(XNOR);
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(XNOR));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
 
       case 41: // boolconst:   SetCC(reg, Constant)
-        // Check if this is an integer comparison, and
-        // there is a parent, and the parent decided to use
-        // a branch-on-integer-register instead of branch-on-condition-code.
-        // If so, the SUBcc instruction is not required.
-        // (However, we must still check for constants to be loaded from
-        // the constant pool so that such a load can be associated with
-        // this instruction.)
         // 
-        // Otherwise this is just the same as case 42, so just fall through.
+        // If the SetCC was folded into the user (parent), it will be
+        // caught above.  All other cases are the same as case 42,
+        // so just fall through.
         // 
-        if ((subtreeRoot->leftChild()->getValue()->getType()->isIntegral() ||
-             subtreeRoot->leftChild()->getValue()->getType()->isPointerType())
-            && subtreeRoot->parent() != NULL)
-          {
-            InstructionNode* parent = (InstructionNode*) subtreeRoot->parent();
-            assert(parent->getNodeType() == InstrTreeNode::NTInstructionNode);
-            const vector<MachineInstr*>&
-              minstrVec = parent->getInstruction()->getMachineInstrVec();
-            MachineOpCode parentOpCode;
-            if (parent->getInstruction()->getOpcode() == Instruction::Br &&
-                (parentOpCode = minstrVec[0]->getOpCode()) >= BRZ &&
-                parentOpCode <= BRGEZ)
-              {
-                numInstr = 0;          // don't forward the operand!
-                break;
-              }
-          }
-        // ELSE FALL THROUGH
-
       case 42: // bool:   SetCC(reg, reg):
       {
         // This generates a SUBCC instruction, putting the difference in
@@ -1738,7 +1958,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         TmpInstruction* tmpForCC = GetTmpForCC(setCCInstr,
                                      setCCInstr->getParent()->getParent(),
                                      isFPCompare? Type::FloatTy : Type::IntTy);
-        setCCInstr->getMachineInstrVec().addTempValue(tmpForCC);
+        MachineCodeForInstruction::get(setCCInstr).addTemp(tmpForCC);
         
         if (! isFPCompare)
           {
@@ -1747,11 +1967,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
             // a separate instruction to compute the bool result, so discard
             // result of SUBcc instruction anyway.
             // 
-            mvec[0] = new MachineInstr(SUBcc);
-            Set3OperandsFromInstr(mvec[0], subtreeRoot, target, ! keepSubVal);
-            
-            mvec[0]->SetMachineOperand(3, MachineOperand::MO_CCRegister,
-                                          tmpForCC, /*def*/true);
+            M = new MachineInstr(SUBcc);
+            Set3OperandsFromInstr(M, subtreeRoot, target, ! keepSubVal);
+            M->SetMachineOperandVal(3, MachineOperand::MO_CCRegister,
+                                    tmpForCC, /*def*/true);
+            mvec.push_back(M);
             
             if (computeBoolVal)
               { // recompute bool using the integer condition codes
@@ -1762,13 +1982,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         else
           {
             // FP condition: dest of FCMP should be some FCCn register
-            mvec[0] = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
-            mvec[0]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
+            M = new MachineInstr(ChooseFcmpInstruction(subtreeRoot));
+            M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
                                           tmpForCC);
-            mvec[0]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
+            M->SetMachineOperandVal(1,MachineOperand::MO_VirtualRegister,
                                          subtreeRoot->leftChild()->getValue());
-            mvec[0]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,
+            M->SetMachineOperandVal(2,MachineOperand::MO_VirtualRegister,
                                         subtreeRoot->rightChild()->getValue());
+            mvec.push_back(M);
             
             if (computeBoolVal)
               {// recompute bool using the FP condition codes
@@ -1782,156 +2003,86 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
           {
             if (mustClearReg)
               {// Unconditionally set register to 0
-               int n = numInstr++;
-               mvec[n] = new MachineInstr(SETHI);
-               mvec[n]->SetMachineOperand(0,MachineOperand::MO_UnextendedImmed,
-                                            s0);
-               mvec[n]->SetMachineOperand(1,MachineOperand::MO_VirtualRegister,
-                                            setCCInstr);
+                M = new MachineInstr(SETHI);
+                M->SetMachineOperandConst(0,MachineOperand::MO_UnextendedImmed,
+                                          (int64_t)0);
+                M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,
+                                        setCCInstr);
+                mvec.push_back(M);
               }
             
             // Now conditionally move `valueToMove' (0 or 1) into the register
-            int n = numInstr++;
-            mvec[n] = new MachineInstr(movOpCode);
-            mvec[n]->SetMachineOperand(0, MachineOperand::MO_CCRegister,
-                                          tmpForCC);
-            mvec[n]->SetMachineOperand(1, MachineOperand::MO_UnextendedImmed,
-                                          valueToMove);
-            mvec[n]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                          setCCInstr);
+            M = new MachineInstr(movOpCode);
+            M->SetMachineOperandVal(0, MachineOperand::MO_CCRegister,
+                                    tmpForCC);
+            M->SetMachineOperandConst(1, MachineOperand::MO_UnextendedImmed,
+                                      valueToMove);
+            M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+                                    setCCInstr);
+            mvec.push_back(M);
           }
         break;
       }    
 
       case 43: // boolreg: VReg
       case 44: // boolreg: Constant
-        numInstr = 0;
         break;
 
       case 51: // reg:   Load(reg)
       case 52: // reg:   Load(ptrreg)
       case 53: // reg:   LoadIdx(reg,reg)
       case 54: // reg:   LoadIdx(ptrreg,reg)
-        mvec[0] = new MachineInstr(ChooseLoadInstruction(
-                                     subtreeRoot->getValue()->getType()));
-        SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr(ChooseLoadInstruction(
+                                     subtreeRoot->getValue()->getType())));
+        SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
         break;
 
       case 55: // reg:   GetElemPtr(reg)
       case 56: // reg:   GetElemPtrIdx(reg,reg)
-        if (subtreeRoot->parent() != NULL)
-          {
-            // If the parent was a memory operation and not an array access,
-            // the parent will fold this instruction in so generate nothing.
-            // 
-            Instruction* parent =
-              cast<Instruction>(subtreeRoot->parent()->getValue());
-            if (parent->getOpcode() == Instruction::Load ||
-                parent->getOpcode() == Instruction::Store ||
-                parent->getOpcode() == Instruction::GetElementPtr)
-              {
-                // Check if the parent is an array access,
-                // If so, we still need to generate this instruction.
-                GetElementPtrInst* getElemInst =
-                  cast<GetElementPtrInst>(subtreeRoot->getInstruction());
-                const PointerType* ptrType =
-                  cast<PointerType>(getElemInst->getPointerOperand()->getType());
-                if (! ptrType->getValueType()->isArrayType())
-                  {// we don't need a separate instr
-                    numInstr = 0;              // don't forward operand!
-                    break;
-                  }
-              }
-          }
-        // else in all other cases we need to a separate ADD instruction
-        mvec[0] = new MachineInstr(ADD);
-        SetOperandsForMemInstr(mvec[0], subtreeRoot, target);
+        // If the GetElemPtr was folded into the user (parent), it will be
+        // caught above.  For other cases, we have to compute the address.
+        mvec.push_back(new MachineInstr(ADD));
+        SetOperandsForMemInstr(mvec, mvec.end()-1, subtreeRoot, target);
         break;
-
+        
       case 57: // reg:  Alloca: Implement as 1 instruction:
       {         //         add %fp, offsetFromFP -> result
-        Instruction* instr = subtreeRoot->getInstruction();
-        const PointerType* instrType = (const PointerType*) instr->getType();
-        assert(instrType->isPointerType());
-        int tsize = (int)
-          target.findOptimalStorageSize(instrType->getValueType());
-        assert(tsize != 0 && "Just to check when this can happen");
-        
-        Method* method = instr->getParent()->getParent();
-        MachineCodeForMethod& mcInfo = MachineCodeForMethod::get(method);
-        int offsetFromFP = mcInfo.allocateLocalVar(target, instr, (unsigned int) tsize);
-        
-        // Create a temporary Value to hold the constant offset.
-        // This is needed because it may not fit in the immediate field.
-        ConstPoolSInt* offsetVal=ConstPoolSInt::get(Type::IntTy, offsetFromFP);
-        
-        // Instruction 1: add %fp, offsetFromFP -> result
-        mvec[0] = new MachineInstr(ADD);
-        mvec[0]->SetMachineOperand(0, target.getRegInfo().getFramePointer());
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                      offsetVal); 
-        mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                      instr);
+        AllocationInst* instr =
+          cast<AllocationInst>(subtreeRoot->getInstruction());
+        unsigned int tsize =
+          target.findOptimalStorageSize(instr->getAllocatedType());
+        assert(tsize != 0);
+        CreateCodeForFixedSizeAlloca(target, instr, tsize, 1, mvec);
         break;
       }
-        
+      
       case 58: // reg:   Alloca(reg): Implement as 3 instructions:
                 //     mul num, typeSz -> tmp
                 //     sub %sp, tmp    -> %sp
       {         //     add %sp, frameSizeBelowDynamicArea -> result
-        Instruction* instr = subtreeRoot->getInstruction();
-        const PointerType* instrType = (const PointerType*) instr->getType();
-        assert(instrType->isPointerType() &&
-               instrType->getValueType()->isArrayType());
-        const Type* eltType =
-          ((ArrayType*) instrType->getValueType())->getElementType();
-        int tsize = (int) target.findOptimalStorageSize(eltType);
-        
-        assert(tsize != 0 && "Just to check when this can happen");
+        AllocationInst* instr =
+          cast<AllocationInst>(subtreeRoot->getInstruction());
+        const Type* eltType = instr->getAllocatedType();
         
-        // Create a temporary Value to hold the constant type-size
-        ConstPoolSInt* tsizeVal = ConstPoolSInt::get(Type::IntTy, tsize);
-        
-        // Create a temporary Value to hold the constant offset from SP
-        Method* method = instr->getParent()->getParent();
-        bool ignore;                    // we don't need this 
-        ConstPoolSInt* dynamicAreaOffset = ConstPoolSInt::get(Type::IntTy,
-          target.getFrameInfo().getDynamicAreaOffset(MachineCodeForMethod::get(method),
-                                                     ignore));
-        
-        // Create a temporary value to hold `tmp'
-        Instruction* tmpInstr = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
-                                          subtreeRoot->leftChild()->getValue(),
-                                          NULL /*could insert tsize here*/);
-        subtreeRoot->getInstruction()->getMachineInstrVec().addTempValue(tmpInstr);
-        
-        // Instruction 1: mul numElements, typeSize -> tmp
-        mvec[0] = new MachineInstr(MULX);
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                      subtreeRoot->leftChild()->getValue());
-        mvec[0]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                      tsizeVal);
-        mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                      tmpInstr);
-        
-        // Instruction 2: sub %sp, tmp -> %sp
-        numInstr++;
-        mvec[1] = new MachineInstr(SUB);
-        mvec[1]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
-        mvec[1]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                      tmpInstr);
-        mvec[1]->SetMachineOperand(2, target.getRegInfo().getStackPointer());
+        // If #elements is constant, use simpler code for fixed-size allocas
+        int tsize = (int) target.findOptimalStorageSize(eltType);
+        Value* numElementsVal = NULL;
+        bool isArray = instr->isArrayAllocation();
         
-        // Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
-        numInstr++;
-        mvec[2] = new MachineInstr(ADD);
-        mvec[2]->SetMachineOperand(0, target.getRegInfo().getStackPointer());
-        mvec[2]->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,
-                                      dynamicAreaOffset);
-        mvec[2]->SetMachineOperand(2,MachineOperand::MO_VirtualRegister,instr);
+        if (!isArray ||
+            isa<Constant>(numElementsVal = instr->getArraySize()))
+          { // total size is constant: generate code for fixed-size alloca
+            unsigned int numElements = isArray? 
+              cast<ConstantUInt>(numElementsVal)->getValue() : 1;
+            CreateCodeForFixedSizeAlloca(target, instr, tsize,
+                                         numElements, mvec);
+          }
+        else // total size is not constant.
+          CreateCodeForVariableSizeAlloca(target, instr, tsize,
+                                          numElementsVal, mvec);
         break;
       }
-
+      
       case 61: // reg:   Call
       {         // Generate a call-indirect (i.e., jmpl) for now to expose
                 // the potential need for registers.  If an absolute address
@@ -1944,53 +2095,53 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         CallInst *callInstr = cast<CallInst>(subtreeRoot->getInstruction());
         Value *callee = callInstr->getCalledValue();
         
-        Instruction* retAddrReg = new TmpInstruction(TMP_INSTRUCTION_OPCODE,
-                                                     callInstr, NULL);
-        
-        // Note temporary values in the machineInstrVec for the VM instr.
-        //
-        // WARNING: Operands 0..N-1 must go in slots 0..N-1 of implicitUses.
-        //          The result value must go in slot N.  This is assumed
-        //          in register allocation.
-        // 
-        callInstr->getMachineInstrVec().addTempValue(retAddrReg);
-        
+        // Create hidden virtual register for return address, with type void*. 
+        Instruction* retAddrReg =
+          new TmpInstruction(PointerType::get(Type::VoidTy), callInstr);
+        MachineCodeForInstruction::get(callInstr).addTemp(retAddrReg);
         
         // Generate the machine instruction and its operands.
         // Use CALL for direct function calls; this optimistically assumes
         // the PC-relative address fits in the CALL address field (22 bits).
         // Use JMPL for indirect calls.
         // 
-        if (callee->getValueType() == Value::MethodVal)
+        if (isa<Function>(callee))
           { // direct function call
-            mvec[0] = new MachineInstr(CALL);
-            mvec[0]->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp,
-                                          callee);
+            M = new MachineInstr(CALL);
+            M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp,
+                                    callee);
           } 
         else
           { // indirect function call
-            mvec[0] = new MachineInstr(JMPLCALL);
-            mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
-                                          callee);
-            mvec[0]->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
-                                          (int64_t) 0);
-            mvec[0]->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
-                                          retAddrReg);
+            M = new MachineInstr(JMPLCALL);
+            M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
+                                    callee);
+            M->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,
+                                      (int64_t) 0);
+            M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,
+                                    retAddrReg);
           }
         
+        mvec.push_back(M);
+
+        // WARNING: Operands 0..N-1 must go in slots 0..N-1 of implicitUses.
+        //          The result value must go in slot N.  This is assumed
+        //          in register allocation.
+        // 
         // Add the call operands and return value as implicit refs
         for (unsigned i=0, N=callInstr->getNumOperands(); i < N; ++i)
           if (callInstr->getOperand(i) != callee)
-            mvec[0]->addImplicitRef(callInstr->getOperand(i));
+            mvec.back()->addImplicitRef(callInstr->getOperand(i));
         
         if (callInstr->getType() != Type::VoidTy)
-          mvec[0]->addImplicitRef(callInstr, /*isDef*/ true);
+          mvec.back()->addImplicitRef(callInstr, /*isDef*/ true);
         
         // For the CALL instruction, the ret. addr. reg. is also implicit
-        if (callee->getValueType() == Value::MethodVal)
-          mvec[0]->addImplicitRef(retAddrReg, /*isDef*/ true);
+        if (isa<Function>(callee))
+          mvec.back()->addImplicitRef(retAddrReg, /*isDef*/ true);
         
-        mvec[numInstr++] = new MachineInstr(NOP); // delay slot
+        // delay slot
+        mvec.push_back(new MachineInstr(NOP));
         break;
       }
 
@@ -1999,8 +2150,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         assert(opType->isIntegral()
                || opType == Type::BoolTy
                || opType->isPointerType()&& "Shl unsupported for other types");
-        mvec[0] = new MachineInstr((opType == Type::LongTy)? SLLX : SLL);
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr((opType == Type::LongTy)? SLLX : SLL));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
       }
       
@@ -2009,38 +2160,38 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         assert(opType->isIntegral()
                || opType == Type::BoolTy
                || opType->isPointerType() &&"Shr unsupported for other types");
-        mvec[0] = new MachineInstr((opType->isSigned()
-                                    ? ((opType == Type::LongTy)? SRAX : SRA)
-                                    : ((opType == Type::LongTy)? SRLX : SRL)));
-        Set3OperandsFromInstr(mvec[0], subtreeRoot, target);
+        mvec.push_back(new MachineInstr((opType->isSigned()
+                                   ? ((opType == Type::LongTy)? SRAX : SRA)
+                                   : ((opType == Type::LongTy)? SRLX : SRL))));
+        Set3OperandsFromInstr(mvec.back(), subtreeRoot, target);
         break;
       }
       
       case 64: // reg:   Phi(reg,reg)
-        numInstr = 0;                  // don't forward the value
-        break;
+        break;                          // don't forward the value
+
 #undef NEED_PHI_MACHINE_INSTRS
 #ifdef NEED_PHI_MACHINE_INSTRS
       {                // This instruction has variable #operands, so resultPos is 0.
         Instruction* phi = subtreeRoot->getInstruction();
-        mvec[0] = new MachineInstr(PHI, 1 + phi->getNumOperands());
-        mvec[0]->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+        M = new MachineInstr(PHI, 1 + phi->getNumOperands());
+        M->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister,
                                       subtreeRoot->getValue());
         for (unsigned i=0, N=phi->getNumOperands(); i < N; i++)
-          mvec[0]->SetMachineOperand(i+1, MachineOperand::MO_VirtualRegister,
-                                          phi->getOperand(i));
+          M->SetMachineOperandVal(i+1, MachineOperand::MO_VirtualRegister,
+                                  phi->getOperand(i));
+        mvec.push_back(M);
         break;
       }  
-#endif NEED_PHI_MACHINE_INSTRS
+#endif // NEED_PHI_MACHINE_INSTRS
+      
       
       case 71: // reg:     VReg
       case 72: // reg:     Constant
-        numInstr = 0;                  // don't forward the value
-        break;
+        break;                          // don't forward the value
 
       default:
         assert(0 && "Unrecognized BURG rule");
-        numInstr = 0;
         break;
       }
     }
@@ -2055,16 +2206,14 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
       else
         {
           vector<MachineInstr*> minstrVec;
-          target.getInstrInfo().CreateCopyInstructionsByType(target,
+          target.getInstrInfo().CreateCopyInstructionsByType(target, 
+                subtreeRoot->getInstruction()->getParent()->getParent(),
                 subtreeRoot->getInstruction()->getOperand(forwardOperandNum),
                 subtreeRoot->getInstruction(), minstrVec);
           assert(minstrVec.size() > 0);
-          for (unsigned i=0; i < minstrVec.size(); ++i)
-            mvec[numInstr++] = minstrVec[i];
+          mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end());
         }
     }
-  
-  return numInstr;
 }