/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/

#include "exp_ovfl_ptal.h"
#include "exp_ieee.h"
#include "BigNumHelper.h"
#include "ExpPCodeOptimizations.h"

//
// Perform constant propogation across all blocks.
//
NABoolean PCodeCfg::constantPropagation(NABoolean doPeeling)
{
  NABoolean notAllVisited, restart=FALSE;

  CollIndex i;

  // Mark all blocks as unvisited
  clearVisitedFlags();

  // Algorithm:
  //
  // Visit each block after all predecesors of that block have been visited.
  // For each block, merge constants from all pred blocks coming into the block.
  // 
  do
  {
    notAllVisited = FALSE;

    FOREACH_BLOCK_REV_DFO(block, firstInst, lastInst, index)
    {
      // If the block has already been processed, continue to the next block.
      if (block->getVisitedFlag())
        continue;

      const BLOCKLIST& preds = block->getPreds();

      // The constant propagation algorithm could result in dead blocks.  If
      // we process those dead blocks, it could result in incorrect propagation
      // information.
      if ((preds.entries() == 0) && (block != entryBlock_)) {
        deleteBlock(block);
        continue;
      }

      // Declare constant vectors used for this block.
      NABitVector zeroes(heap_), ones(heap_), neg1(heap_);

      // Visit each predecessor and merge in their constants.
      for (i=0; i < preds.entries(); i++)
      {
        if (preds[i]->getVisitedFlag() == FALSE) {
          notAllVisited = TRUE;
          break;
        }

        // Declare temp constant vectors used for merging purposes.
        NABitVector tempZeroes(heap_), tempOnes(heap_), tempNeg1(heap_);

        // Initialize the temp vectors with the predecessor's constant vectors.
        tempZeroes = preds[i]->zeroesVector;
        tempOnes = preds[i]->onesVector;
        tempNeg1 = preds[i]->neg1Vector;

        // Set implicit constants derived from knowing which target a branch 
        // took. 
        preds[i]->fixupConstantVectors(block, tempZeroes, tempOnes, tempNeg1);

        // If this is the first pred, initialize the block's constant vectors
        // to that of the preds.

        if (i == 0) {
          zeroes = tempZeroes;
          ones = tempOnes;
          neg1 = tempNeg1;
          continue;
        }

        // Merge the preds constants into that of this blocks.
        PCodeConstants::mergeConstantVectors(zeroes, ones, neg1,
                                             tempZeroes, tempOnes, tempNeg1);
      }

      // Bail out if not all preds are ready..
      if (i != preds.entries())
        continue;

      // If this is the entry block, initialize this block's constant vectors
      // with the known constant's vectors of the cfg.
      if (block == entryBlock_) {
        zeroes += *zeroes_;
        ones += *ones_;
        neg1 += *neg1_;
      }

      restart = localConstantPropagation(block, zeroes, ones, neg1) || restart;

      block->setVisitedFlag(TRUE);

      // Set the block's constant vectors to the local ones used here.
      block->zeroesVector = zeroes;
      block->onesVector = ones;
      block->neg1Vector = neg1;

      if (doPeeling && block->doesBlockQualifyForShortCircuit()) {
        PCodeBlock *t1, *t2;

        CollIndex entries = zeroes.entries();

#if 0
        CollIndex j;

        printf("Block %d:\n", block->getBlockNum());

        printf("  Zeroes: ");
        j = zeroes.getLastStaleBit();
        for (; (j = zeroes.prevUsed(j)) != NULL_COLL_INDEX; j--)
        {
          PCodeOperand* operand = getMap()->getFirstValue(&j);
          operand->print();
          printf ("(%d) ", j);
        }
        printf("\n");

        printf("  Ones: ");
        j = ones.getLastStaleBit();
        for (; (j = ones.prevUsed(j)) != NULL_COLL_INDEX; j--)
        {
          PCodeOperand* operand = getMap()->getFirstValue(&j);
          operand->print();
          printf ("(%d) ", j);
        }
        printf("\n");

        printf("  Neg1: ");
        j = neg1.getLastStaleBit();
        for (; (j = neg1.prevUsed(j)) != NULL_COLL_INDEX; j--)
        {
          PCodeOperand* operand = getMap()->getFirstValue(&j);
          operand->print();
          printf ("(%d) ", j);
        }
        printf("\n");
#endif

        t1 = shortCircuitOptForBlock(block, TRUE, TRUE, zeroes, ones, neg1);

        assert (zeroes.entries() == entries);

        // If peeled block was generated, mark visited flag since known
        // constants were updated (and set) in target block.
        if (t1)
          t1->setVisitedFlag(TRUE);

        t2 = shortCircuitOptForBlock(block, FALSE, TRUE, zeroes, ones, neg1);

        // If peeled block was generated, mark visited flag since known
        // constants were updated (and set) in target block.
        if (t2)
          t2->setVisitedFlag(TRUE);

        assert (zeroes.entries() == entries);

        restart = restart || (t1 != NULL) || (t2 != NULL);
      }

    } ENDFE_BLOCK_REV_DFO
  } while (notAllVisited);

  return restart;
}



NABoolean PCodeCfg::localConstantPropagation(PCodeBlock* block,
                                             NABitVector& zeroes,
                                             NABitVector& ones,
                                             NABitVector& neg1)
{
  CollIndex i;
  PCodeOperand *operand1, *operand2;
  CollIndex bvIndex1, bvIndex2;
  PCodeInst* returnInst = NULL;
  Int32 returnValue = PCodeConstants::UNKNOWN_CONSTANT;
  Int32 constant, constant2;

  NABoolean isZero, isOne, isNeg1;
  NABoolean graphChanged = FALSE;

  // Use zeroes, ones, and neg1 to start constant propagating and optimizing
  // this basic block
  FOREACH_INST_IN_BLOCK(block, inst)
  {
    PCIT::Instruction opc = (PCIT::Instruction) inst->getOpcode();
    PCodeBinary* code = inst->code;
    NABoolean restart = TRUE;

    switch (inst->getOpcode()) {
      case PCIT::MOVE_MBIN16U_IBIN16U:
      case PCIT::MOVE_MBIN32S_IBIN32S:
      case PCIT::MOVE_MBIN8_MBIN8:
      case PCIT::MOVE_MBIN16U_MBIN16U:
      case PCIT::MOVE_MBIN32U_MBIN32U:
      case PCIT::MOVE_MBIN64S_MBIN64S:
        // These cases actually use const info regarding the write operands
        // in order to optimize.  Let them clear out the write operands
        // themselves.
        break;

      default:
      {
        // Clear out constant assumptions for all writes
        for (i=0; i < inst->getWOps().entries(); i++) {
          CollIndex bvIndex = inst->getWOps()[i]->getBvIndex();
#if 0
          // TODO: May need to fix this so that source operands not cleared
          // as well
          for (j=0; j < inst->getROps().entries(); j++) {
            if ((bvIndex == inst->getROps()[j]->getBvIndex()) &&
               (PCodeConstants::getConstantValue(bvIndex, zeroes, ones, neg1) !=
                PCodeConstants::UNKNOWN_CONSTANT))
              assert(FALSE);
          }
#endif
          // Special logical branches are created for the purposes of predicate
          // reordering.  Ignore these cases.
          if (inst->isLogicalBranch())
            if (bvIndex == inst->getROps()[0]->getBvIndex())
              continue;

          PCodeConstants::clearConstantVectors(bvIndex, zeroes, ones, neg1);
        }
      }
    }

    switch (opc)
    {
      case PCIT::MOVE_MBIN16U_IBIN16U:
      case PCIT::MOVE_MBIN32S_IBIN32S:
      {
        operand1 = inst->getWOps()[0];
        bvIndex1 = operand1->getBvIndex();
        constant = inst->code[3];

        constant2 = PCodeConstants::getConstantValue(bvIndex1, zeroes,
                                                     ones, neg1);

        // Delete moves whose constants are already known.
        if ((constant2 != PCodeConstants::UNKNOWN_CONSTANT) &&
            (constant == constant2))
        {
          block->deleteInst(inst);
          break;
        }

        // Clear out vector first since it's not done initially before switch
        PCodeConstants::clearConstantVectors(bvIndex1, zeroes, ones, neg1);

        PCodeConstants::setConstantInVectors(constant, bvIndex1,
                                             zeroes, ones, neg1);

        // Use constant operand instead for potential copy prop
        if (constant == 0) {
          PCodeInst* mv;
          if (opc == PCIT::MOVE_MBIN16U_IBIN16U)
            mv = block->insertNewInstAfter(inst, PCIT::MOVE_MBIN16U_MBIN16U);
          else
            mv = block->insertNewInstAfter(inst, PCIT::MOVE_MBIN32U_MBIN32U);

          mv->code[1] = inst->code[1];
          mv->code[2] = inst->code[2];
          mv->code[3] = 1;
          mv->code[4] = zeroOffset_;

          mv->reloadOperands(this);

          // Don't need the old NULL instruction any more.
          block->deleteInst(inst);
        }

        break;
      }

      case PCIT::NULL_VIOLATION_MBIN16U:
        operand1 = inst->getROps()[0];
        zeroes += operand1->getBvIndex();
        break;

      case PCIT::NULL_VIOLATION_MPTR32_MPTR32_IPTR_IPTR:
      case PCIT::NULL_VIOLATION_MBIN16U_MBIN16U:
      {
        operand1 = inst->getROps()[0];
        zeroes += operand1->getBvIndex();

        if ((opc != PCIT::NULL_VIOLATION_MPTR32_MPTR32_IPTR_IPTR) ||
            (GetPCodeBinaryAsPtr(inst->code, 5 + PCODEBINARIES_PER_PTR) != 0))
        {
          operand2 = inst->getROps()[1];
          zeroes += operand2->getBvIndex();
        }
        break;
      }

      case PCIT::REPLACE_NULL_MATTR3_MBIN32S:
      case PCIT::REPLACE_NULL_MATTR3_MBIN32U:
      case PCIT::REPLACE_NULL_MATTR3_MBIN16S:
      case PCIT::REPLACE_NULL_MATTR3_MBIN16U:
      {
        bvIndex2 = inst->getROps()[0]->getBvIndex();
        constant = PCodeConstants::getConstantValue(bvIndex2,zeroes,ones,neg1);
        if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
          inst->code[0] = (inst->getWOps()[0]->getLen() == 2)
                             ? PCIT::MOVE_MBIN16U_MBIN16U
                             : PCIT::MOVE_MBIN32U_MBIN32U;

          if (constant == 0) {
            inst->code[3] = inst->code[6];
            inst->code[4] = inst->code[7];
          }
          else {
            inst->code[3] = inst->code[8];
            inst->code[4] = inst->code[9];
          }

          inst->reloadOperands(this);

          // For some reason the src types are MASCII - change it.
          if (inst->code[0] == PCIT::MOVE_MBIN16U_MBIN16U) {
            inst->getWOps()[0]->setType(PCIT::MBIN16U);
            inst->getROps()[0]->setType(PCIT::MBIN16U);
          }
          else {
            inst->getWOps()[0]->setType(PCIT::MBIN32U);
            inst->getROps()[0]->setType(PCIT::MBIN32U);
          }

          RESTART_INST_IN_BLOCK;
        }
        break;
      }

      case PCIT::NULL_MBIN16U:
      {
        PCodeInst* mv;

        // Propagate the known zero constant
        bvIndex1 = inst->getWOps()[0]->getBvIndex();
        PCodeConstants::setConstantInVectors(0, bvIndex1, zeroes, ones, neg1);

        // Convert NULL into MOVE of the zero constant - good for copy prop
        mv = block->insertNewInstBefore(inst, PCIT::MOVE_MBIN16U_MBIN16U);
        mv->code[1] = inst->code[1];
        mv->code[2] = inst->code[2];
        mv->code[3] = 1;
        mv->code[4] = zeroOffset_;

        mv->reloadOperands(this);

        // Don't need the old NULL instruction any more.
        block->deleteInst(inst);

        break;
      }

      case PCIT::NULL_BITMAP:
        bvIndex1 = inst->getWOps()[0]->getBvIndex();
        if (inst->code[3] == PCIT::NULL_BITMAP_SET) {
          constant = (inst->code[5]) ? -1 : 0;
          PCodeConstants::setConstantInVectors(constant, bvIndex1,
                                               zeroes, ones, neg1);
        }
        break;


      case PCIT::MOVE_MBIN32S:
        bvIndex1 = inst->getROps()[0]->getBvIndex();
        constant = PCodeConstants::getConstantValue(bvIndex1,zeroes,ones,neg1);
        if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
          returnInst = inst;
          returnValue = constant;
        }
        break;

      case PCIT::RETURN:
        if (returnInst) {
          PCodeInst* ret;
          ret = block->insertNewInstBefore(inst, PCIT::RETURN_IBIN32S);
          ret->code[1] = returnValue;

          block->deleteInst(returnInst);
          block->deleteInst(inst);
        }
        break;

      case PCIT::MOVE_MBIN8_MBIN8_IBIN32S:
      {
        operand1 = inst->getROps()[0];

        switch (operand1->getLen()) {
          case 1:
            inst->code[0] = PCIT::MOVE_MBIN8_MBIN8;
            break;
          case 2:
            inst->code[0] = PCIT::MOVE_MBIN16U_MBIN16U;
            break;
          case 4:
            inst->code[0] = PCIT::MOVE_MBIN32U_MBIN32U;
            break;
          case 8:
            inst->code[0] = PCIT::MOVE_MBIN64S_MBIN64S;
            break;
        }

        if (inst->code[0] != PCIT::MOVE_MBIN8_MBIN8_IBIN32S) {
          inst->reloadOperands(this);
          RESTART_INST_IN_BLOCK;
        }
        else {
          // Just propagate the constants over
          operand2 = inst->getWOps()[0];
          PCodeConstants::copyConstantVectors(operand1->getBvIndex(),
                                              operand2->getBvIndex(),
                                              zeroes, ones, neg1);
        }

        break;
      }

      case PCIT::MOVE_MBIN8_MBIN8:
      case PCIT::MOVE_MBIN16U_MBIN16U:
      case PCIT::MOVE_MBIN32U_MBIN32U:
      case PCIT::MOVE_MBIN64S_MBIN64S:
      {
        operand1 = inst->getROps()[0];
        operand2 = inst->getWOps()[0];

        bvIndex1 = operand1->getBvIndex();
        bvIndex2 = operand2->getBvIndex();

        constant = PCodeConstants::getConstantValue(bvIndex2, zeroes,
                                                    ones, neg1);

        // Delete moves whose constants are already known.
        if ((constant != PCodeConstants::UNKNOWN_CONSTANT) &&
            (constant ==
             PCodeConstants::getConstantValue(bvIndex1, zeroes, ones, neg1)))
        {
          block->deleteInst(inst);
          break;
        }

        // Clear out vector first since it's not done initially before switch
        PCodeConstants::clearConstantVectors(bvIndex2, zeroes, ones, neg1);

        constant = PCodeConstants::copyConstantVectors(bvIndex1, bvIndex2,
                                                       zeroes, ones, neg1);

        // Let peephole take care of the rest of this.  This will allow copy
        // propagation to proceed, which may be better.
        if (operand1->isConst())
          break;

        if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
          // If constant is zero, use the constant operand in order to try and
          // promote copy propagation later on
          if (constant == 0) {
            inst->code[3] = 1;
            inst->code[4] = zeroOffset_;
            inst->reloadOperands(this);
          }
          else {
            switch (opc) {
              case PCIT::MOVE_MBIN16U_MBIN16U:
                inst->code[0] = PCIT::MOVE_MBIN16U_IBIN16U;
                break;

              case PCIT::MOVE_MBIN32U_MBIN32U:
                inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
                break;

              case PCIT::MOVE_MBIN8_MBIN8:
              case PCIT::MOVE_MBIN64S_MBIN64S:
                // TODO: No IBIN equivalent yet
                break;
            }

            // If the opcode changed, update operands
            if (opc != inst->code[0]) {
              inst->code[3] = constant;
              inst->getROps().clear();
            }
          }
        }
           
        break;
      }


      case PCIT::OR_MBIN32S_MBIN32S_MBIN32S:

#if 0
        // First take advantage of the fact that all source operands into
        // logical boolean operators can *AND SHOULD* only have values 0, 1,
        // or -1. Therefore set this up first.  Note, we don't do this if we
        // know more about the operand's values than this fact alone.

        for (i=0; i < 2; i++) {
          operand1 = inst->getROps()[i];
          bvIndex1 = operand1->getBvIndex();

          // If this value truly is unknown, set it to what we do know.
          if (!PCodeConstants::isAnyKnownConstants(bvIndex1,zeroes,ones,neg1)) {
            zeroes += bvIndex1;
            ones += bvIndex1;
            neg1 += bvIndex1;
          }
        }
#endif

        for (i=0; i < 2; i++)
        {
          operand1 = inst->getROps()[i];
          operand2 = inst->getROps()[(i+1)%2];

          bvIndex1 = operand1->getBvIndex();
          bvIndex2 = operand2->getBvIndex();

          constant = PCodeConstants::getConstantValue(bvIndex1, zeroes,
                                                      ones, neg1);

          if (constant == 1) {
            inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
            inst->code[3] = constant;
            inst->getROps().clear();

            RESTART_INST_IN_BLOCK;
            break;
          }

          if (constant == 0)
          {
            inst->code[0] = PCIT::MOVE_MBIN32U_MBIN32U;
            inst->code[3] = operand2->getStackIndex();
            inst->code[4] = operand2->getOffset();

            inst->reloadOperands(this);

            RESTART_INST_IN_BLOCK;
            break;
          }

          if (constant == -1) {
            if (PCodeConstants::isAnyKnownConstant(bvIndex2, zeroes,
                                                   ones, neg1) &&
                !PCodeConstants::canBeOne(bvIndex2, ones))
            {
              inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
              inst->code[3] = -1;
              inst->getROps().clear();

              RESTART_INST_IN_BLOCK;
              break;
            }
          }
        }

        // If no change was made above, see if we can fine tune what the known
        // values of the target operand should be.
        if (inst->code[0] == PCIT::OR_MBIN32S_MBIN32S_MBIN32S) {
          bvIndex2 = inst->getWOps()[0]->getBvIndex();
          for (i=0; i < 2; i++) {
            bvIndex1 = inst->getROps()[i]->getBvIndex();

            // If src is 1 or -1, result is also 1 or -1
            if (PCodeConstants::isAnyKnownConstant(bvIndex1,zeroes,ones,neg1)&&
                !PCodeConstants::canBeZero(bvIndex1, zeroes))
            {
              ones += bvIndex2;
              neg1 += bvIndex2;
              break;
            }
          }
        }

        break;


      case PCIT::AND_MBIN32S_MBIN32S_MBIN32S:

#if 0
        // First take advantage of the fact that all source operands into
        // logical boolean operators can *AND SHOULD* only have values 0, 1,
        // or -1. Therefore set this up first.  Note, we don't do this if we
        // know more about the operand's values than this fact alone.

        for (i=0; i < 2; i++) {
          operand1 = inst->getROps()[i];
          bvIndex1 = operand1->getBvIndex();

          // If this value truly is unknown, set it to what we do know.
          if (!PCodeConstants::isAnyKnownConstants(bvIndex1,zeroes,ones,neg1)) {
            zeroes += bvIndex1;
            ones += bvIndex1;
            neg1 += bvIndex1;
          }
        }
#endif

        for (i=0; i < 2; i++)
        {
          operand1 = inst->getROps()[i];
          operand2 = inst->getROps()[(i+1)%2];

          bvIndex1 = operand1->getBvIndex();
          bvIndex2 = operand2->getBvIndex();

          isZero = zeroes.testBit(bvIndex1);
          isOne = ones.testBit(bvIndex1);
          isNeg1 = neg1.testBit(bvIndex1);

          if (isZero && !isOne && !isNeg1) {
            inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
            inst->code[3] = 0;

            inst->reloadOperands(this);

            RESTART_INST_IN_BLOCK;
            break;
          }

          // If this operand has a value of one, and the second operand is
          // known to have a value of 0, 1, or -1, result is the second 
          // operand.  Similarly, if this operand is -1 and the second
          // operand has value 0 or -1, then follow suit.

          if (((isOne && !isZero && !isNeg1) &&
              (zeroes.testBit(bvIndex2) || ones.testBit(bvIndex2) ||
               neg1.testBit(bvIndex2)))
              ||
              ((isNeg1 && !isZero && !isOne) &&
               (zeroes.testBit(bvIndex2) && neg1.testBit(bvIndex2) &&
                !ones.testBit(bvIndex2))))
          {
            inst->code[0] = PCIT::MOVE_MBIN32U_MBIN32U;
            inst->code[3] = operand2->getStackIndex();
            inst->code[4] = operand2->getOffset();

            inst->reloadOperands(this);

            RESTART_INST_IN_BLOCK;
            break;
          }

          // If this operand is -1, and the second operand is either -1
          // or one, the result is -1

          if ((isNeg1 && !isZero && !isOne) &&
               ((neg1.testBit(bvIndex2) || (ones.testBit(bvIndex2))) &&
                !zeroes.testBit(bvIndex2)))
          {
            inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
            inst->code[3] = -1;

            inst->reloadOperands(this);

            RESTART_INST_IN_BLOCK;
            break;
          }
        }

        // If no change was made above, see if we can fine tune what the known
        // values of the target operand should be.
        if (inst->code[0] == PCIT::AND_MBIN32S_MBIN32S_MBIN32S) {
          bvIndex2 = inst->getWOps()[0]->getBvIndex();
          for (i=0; i < 2; i++) {
            bvIndex1 = inst->getROps()[i]->getBvIndex();

            // If src is 0 or -1, result is also 0 or -1
            if (PCodeConstants::isAnyKnownConstant(bvIndex1,zeroes,ones,neg1)&&
                !PCodeConstants::canBeOne(bvIndex1, ones))
            {
              zeroes += bvIndex2;
              neg1 += bvIndex2;
              break;
            }
          }
        }

        break;

          case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIN32S_MBIN32S:
          case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIN64S_MBIN64S:
          case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIN64S_MBIN32S:
          case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MFLT64_MFLT64:
          case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIGS_MBIGS_IBIN32S:
          {
            // Look for the null indicator used in this PCODE instruction and
            // see if we know it to be NULL.  If so, then this instruction
            // doesn't get invoked, and therefore we can remove it.
            for (i=0; i < inst->getROps().entries(); i++) {
              if (((inst->getROps()[i]->getStackIndexPos() == 2) &&
                   (inst->getROps()[i]->getOffsetPos() == 3)) ||
                  ((inst->getROps()[i]->getStackIndexPos() == 3) &&
                   (inst->getROps()[i]->getOffsetPos() == 4)))
              {
                bvIndex1 = inst->getROps()[i]->getBvIndex();
                constant = PCodeConstants::getConstantValue(bvIndex1,
                                                            zeroes,ones,neg1);

                if (constant == -1)
                  block->deleteInst(inst);

                break;
              }
            }
            break;
          }

          case PCIT::CLAUSE_EVAL:
          {
            ex_clause* clause = (ex_clause*)*(Long*)&(inst->code[1]);
            if ((clause->getType() == ex_clause::FUNCTION_TYPE) &&
                (clause->getClassID() == ex_clause::FUNC_RAISE_ERROR_ID) &&
                (((ExpRaiseErrorFunction*)clause)->raiseError()))
            {
              // Create a RETURN instruction after the clause, and then fix
              // up the block so as to remove trailing instrs in the block,
              // *IF* a RETURN isn't already there.

              if (!inst->next || !(inst->next->getOpcode() == PCIT::RETURN)) {
                inst = block->insertNewInstAfter(inst, PCIT::RETURN);
                block->setLastInst(inst);
                inst->next = NULL;
                while (block->getSuccs().entries())
                  block->removeEdge(block->getSuccs()[0]);


                RESTART_INST_IN_BLOCK;
              }
            }

            if (clause->getClassID() == ex_clause::AGGR_MIN_MAX_ID) {
              // Get the previous opdata.  It represents the condition for
              // which the min/max will be performed or not.  If not, then the
              // entire CLAUSE_EVAL sequence can be deleted.
              PCodeInst* opComp = inst->prev;
              bvIndex2 = opComp->getROps()[0]->getBvIndex();

              constant = PCodeConstants::getConstantValue(bvIndex2, zeroes,
                                                          ones, neg1);
              if (constant == 0) {
                // Delete clause-eval instruction
                block->deleteInst(inst);
              }
            }
            break;
          }

          case PCIT::OPDATA_MPTR32_IBIN32S_IBIN32S:
          case PCIT::OPDATA_MPTR32_IBIN32S:
          case PCIT::OPDATA_MBIN16U_IBIN32S:
          case PCIT::OPDATA_MATTR5_IBIN32S:
            if (inst->getWOps().entries()) {
              PCodeInst* tInst = NULL;
              ex_clause* clause = NULL;

              // Use for identifying read operands
              operand1 = NULL;
              operand2 = NULL;

              // Find the clause eval associated with this opdata and set
              // read operands along the way.
              for (tInst = inst->next;
                   tInst->getOpcode() != PCIT::CLAUSE_EVAL;
                   tInst = tInst->next)
              {
                if (tInst->getROps().entries()) {
                  if (operand1 == NULL)
                    operand1 = tInst->getROps()[0];
                  else
                    operand2 = tInst->getROps()[0];
                }
              }

              assert (tInst->block == block);

              // We can determine the constants of some clauses
              clause = (ex_clause*)*(Long*)&(tInst->code[1]);
              switch (clause->getType())
              {
                case ex_clause::UN_LOGIC_TYPE:
                  // Get read and write operands
                  bvIndex1 = operand1->getBvIndex();
                  bvIndex2 = inst->getWOps()[0]->getBvIndex();

                  constant = PCodeConstants::getConstantValue(bvIndex1, zeroes,
                                                              ones, neg1);

                  if (constant != PCodeConstants::UNKNOWN_CONSTANT) {

                    constant2 = PCodeConstants::UNKNOWN_CONSTANT;

                    switch (clause->getOperType()) {
                      case ITM_IS_UNKNOWN:
                        constant2 = (constant == -1) ? 1 : 0;
                        break;

                      case ITM_IS_NOT_UNKNOWN:
                        constant2 = (constant != -1) ? 1 : 0;
                        break;

                      case ITM_IS_TRUE:
                        constant2 = (constant == 1) ? 1 : 0;
                        break;

                      case ITM_IS_FALSE:
                        constant2 = (constant == 0) ? 1 : 0;
                        break;

                      case ITM_NOT:
                        if (constant == 1)
                          constant2 = 0;
                        else if (constant == 0)
                          constant2 = 1;
                        else
                          constant2 = -1;
                        break;

                      default:
                        break;
                    }

                    if (constant2 != PCodeConstants::UNKNOWN_CONSTANT) {
                      PCodeInst* move =
                        block->insertNewInstAfter(tInst,
                                                  PCIT::MOVE_MBIN32S_IBIN32S);
                      move->code[1] = inst->getWOps()[0]->getStackIndex();
                      move->code[2] = inst->getWOps()[0]->getOffset();
                      move->code[3] = constant2;

                      move->reloadOperands(this);

                      // Delete clause-eval instruction
                      block->deleteInst(tInst);

                      //PCodeConstants::setConstantInVectors(constant2,bvIndex2,
                                                         //zeroes, ones, neg1);

                      // In order to restart inst, inst needs to be assigned
                      // new move instruction, since inst was deleted
                      inst = move;
                      RESTART_INST_IN_BLOCK;

                      break;
                    }
                  }
                  else if (clause->getOperType() == ITM_NOT) {
                    if (PCodeConstants::canBeZero(bvIndex1, zeroes) &&
                        PCodeConstants::canBeOne(bvIndex1, ones) &&
                        !PCodeConstants::canBeNeg1(bvIndex1, neg1))
                    {
                      // Clause can be replaced with simple compare inst
                      PCodeInst* cmp =
                        block->insertNewInstAfter(tInst,
                                   PCIT::EQ_MBIN32S_MBIN32S_MBIN32S);

                      cmp->code[1] = inst->getWOps()[0]->getStackIndex();
                      cmp->code[2] = inst->getWOps()[0]->getOffset();
                      cmp->code[3] = operand1->getStackIndex();
                      cmp->code[4] = operand1->getOffset();
                      cmp->code[5] = 1;
                      cmp->code[6] = zeroOffset_;

                      cmp->reloadOperands(this);

                      // Delete clause-eval instruction
                      block->deleteInst(tInst);

                      inst = cmp;
                      RESTART_INST_IN_BLOCK;

                      break;
                    }
                    else
                      // Result can be -1
                      neg1 += bvIndex2;
                  }

                  // All UN_LOGIC clauses will return 0 or 1
                  zeroes += bvIndex2;
                  ones += bvIndex2;

                  break;

                case ex_clause::LIKE_TYPE:
                case ex_clause::LIKE_CLAUSE_CHAR_ID:
                case ex_clause::COMP_TYPE:
                  bvIndex2 = inst->getWOps()[0]->getBvIndex();
                  zeroes += bvIndex2;
                  ones += bvIndex2;

                  // If this clause processes nulls, we have to assume -1 can
                  // be returned - uggh.
                  if (tInst->code[1 + PCODEBINARIES_PER_PTR] & 1)
                    neg1 += bvIndex2;
                  break;

                case ex_clause::BOOL_TYPE:
                  assert(FALSE);
                  break;

                case ex_clause::FUNCTION_TYPE:
                  switch (clause->getClassID()) {
                    case ex_clause::FUNC_GET_BIT_VALUE_AT_ID:
                      bvIndex2 = inst->getWOps()[0]->getBvIndex();
                      zeroes += bvIndex2;
                      ones += bvIndex2;
                      break;
                  }
                  break;
              }
            }

            break;

     
          case PCIT::NULL_TEST_MBIN32S_MATTR5_IBIN32S_IBIN32S:
            // TODO: Indirect varchars are not supported right now
            if (inst->code[8] == 1) {
              bvIndex1 = inst->getWOps()[0]->getBvIndex();
              zeroes += bvIndex1;
              ones += bvIndex1;
              break;
            }
            // Otherwise non-indirect varchar, so fall-through

          case PCIT::NULL_TEST_MBIN32S_MBIN16U_IBIN32S:
          {
            bvIndex2= inst->getROps()[0]->getBvIndex();
            constant = PCodeConstants::getConstantValue(bvIndex2, zeroes,
                                                        ones, neg1);

            if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
              Int32 val = 0;

              switch (opc) {
                case PCIT::NULL_TEST_MBIN32S_MBIN16U_IBIN32S:
                  val = inst->code[5];
                  break;

                case PCIT::NULL_TEST_MBIN32S_MATTR5_IBIN32S_IBIN32S:
                  val = inst->code[9];
                  break;
              }

              assert((val == 0) || (val == -1));

              inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
              inst->code[3] = (constant == val) ? 1 : 0;

              inst->getROps().clear();

              RESTART_INST_IN_BLOCK;
              break;
            }

            bvIndex1 = inst->getWOps()[0]->getBvIndex();
            zeroes += bvIndex1;
            ones += bvIndex1;

            break;
          }



          case PCIT::ZERO_MBIN32S_MBIN32U:
          case PCIT::NOTZERO_MBIN32S_MBIN32U:

          case PCIT::EQ_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::NE_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::LT_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::GT_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::LE_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::GE_MBIN32S_MBIN16S_MBIN16S:

          case PCIT::EQ_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::LT_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::GT_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::LE_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::GE_MBIN32S_MBIN16S_MBIN32S:

          case PCIT::EQ_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::LT_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::GT_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::LE_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::GE_MBIN32S_MBIN32S_MBIN32S:

          case PCIT::EQ_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::LT_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::GT_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::LE_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::GE_MBIN32S_MBIN16U_MBIN16U:

          case PCIT::EQ_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::LT_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::GT_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::LE_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::GE_MBIN32S_MBIN16U_MBIN32U:

          case PCIT::EQ_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::LT_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::GT_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::LE_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::GE_MBIN32S_MBIN32U_MBIN32U:

          case PCIT::EQ_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::LT_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::GT_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::LE_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::GE_MBIN32S_MBIN16S_MBIN32U:

          case PCIT::EQ_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::LT_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::GT_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::LE_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::GE_MBIN32S_MBIN16U_MBIN16S:

          case PCIT::NE_MBIN32S_MBIN64S_MBIN64S:
          case PCIT::EQ_MBIN32S_MBIN64S_MBIN64S:
          case PCIT::LT_MBIN32S_MBIN64S_MBIN64S:
          case PCIT::GT_MBIN32S_MBIN64S_MBIN64S:
          case PCIT::LE_MBIN32S_MBIN64S_MBIN64S:
          case PCIT::GE_MBIN32S_MBIN64S_MBIN64S:

          case PCIT::NE_MBIN32S_MASCII_MASCII:
          case PCIT::EQ_MBIN32S_MASCII_MASCII:
          case PCIT::LT_MBIN32S_MASCII_MASCII:
          case PCIT::GT_MBIN32S_MASCII_MASCII:
          case PCIT::LE_MBIN32S_MASCII_MASCII:
          case PCIT::GE_MBIN32S_MASCII_MASCII:

          case PCIT::NE_MBIN32S_MFLT64_MFLT64:
          case PCIT::EQ_MBIN32S_MFLT64_MFLT64:
          case PCIT::LT_MBIN32S_MFLT64_MFLT64:
          case PCIT::GT_MBIN32S_MFLT64_MFLT64:
          case PCIT::LE_MBIN32S_MFLT64_MFLT64:
          case PCIT::GE_MBIN32S_MFLT64_MFLT64:

          case PCIT::NE_MBIN32S_MFLT32_MFLT32:
          case PCIT::EQ_MBIN32S_MFLT32_MFLT32:
          case PCIT::LT_MBIN32S_MFLT32_MFLT32:
          case PCIT::GT_MBIN32S_MFLT32_MFLT32: 
          case PCIT::LE_MBIN32S_MFLT32_MFLT32:
          case PCIT::GE_MBIN32S_MFLT32_MFLT32:

          case PCIT::COMP_MBIN32S_MUNIV_MUNIV_IBIN32S:
          case PCIT::COMP_MBIN32S_MATTR5_MATTR5_IBIN32S:
          case PCIT::COMP_MBIN32S_MUNI_MUNI_IBIN32S_IBIN32S_IBIN32S:
          case PCIT::COMP_MBIN32S_MBIGS_MBIGS_IBIN32S_IBIN32S:
          case PCIT::COMP_MBIN32S_MASCII_MASCII_IBIN32S_IBIN32S_IBIN32S:

          case PCIT::LIKE_MBIN32S_MATTR5_MATTR5_IBIN32S_IBIN32S:
          {
            bvIndex2 = inst->getWOps()[0]->getBvIndex();
            zeroes += bvIndex2;
            ones += bvIndex2;

            break;
          }

          case PCIT::SWITCH_MBIN32S_MBIN64S_MPTR32_IBIN32S_IBIN32S:
          case PCIT::SWITCH_MBIN32S_MATTR5_MPTR32_IBIN32S_IBIN32S:
          {
            // If for IN-lists, result can only be 0 or 1.
            if (inst->isInListSwitch()) {
              bvIndex2 = inst->getWOps()[0]->getBvIndex();
              zeroes += bvIndex2;
              ones += bvIndex2;
            }
            break;
          }

      case PCIT::NNB_MBIN32S_MATTR3_IBIN32S_IBIN32S:
      {
        PCodeInst* mv;
        PCodeBlock* fallThrough = block->getSuccs()[0];

        // Add move to fall-through
        mv = fallThrough->insertNewInstBefore(NULL, PCIT::MOVE_MBIN32S_IBIN32S);
        mv->code[1] = inst->getWOps()[0]->getStackIndex();
        mv->code[2] = inst->getWOps()[0]->getOffset();
        mv->code[3] = inst->code[6];
        mv->reloadOperands(this);

        // Rewrite branch to not have write operand
        inst->code[0] = PCIT::NNB_MATTR3_IBIN32S;
        inst->code[1] = inst->getROps()[0]->getStackIndex();
        inst->code[2] = inst->getROps()[0]->getOffset();
        inst->code[3] = inst->getROps()[0]->getNullBitIndex();
        inst->reloadOperands(this);

        RESTART_INST_IN_BLOCK;
        break;
      }

      case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S_IBIN32S:
      {
        PCodeInst* mv;
        PCodeBlock* fallThrough = block->getSuccs()[0];

        // Add move to fall-through
        mv = fallThrough->insertNewInstBefore(NULL, PCIT::MOVE_MBIN32S_IBIN32S);
        mv->code[1] = inst->getWOps()[0]->getStackIndex();
        mv->code[2] = inst->getWOps()[0]->getOffset();
        mv->code[3] = inst->code[5];
        mv->reloadOperands(this);

        // Rewrite branch to not have write operand
        inst->code[0] = PCIT::NOT_NULL_BRANCH_MBIN16S_IBIN32S;
        inst->code[1] = inst->getROps()[0]->getStackIndex();
        inst->code[2] = inst->getROps()[0]->getOffset();
        inst->reloadOperands(this);

        RESTART_INST_IN_BLOCK;
        break;
      }

      case PCIT::NNB_MATTR3_IBIN32S:
      case PCIT::NOT_NULL_BRANCH_MBIN16S_IBIN32S:
      {
        bvIndex1 = inst->getROps()[0]->getBvIndex();
        constant = PCodeConstants::getConstantValue(bvIndex1, zeroes,
                                                    ones, neg1);

        if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
          if (constant == 0) {
            inst->code[0] = PCIT::BRANCH;
            inst->getROps().clear();
            block->removeEdge(block->getFallThroughBlock());
            break;
          }
          else {
            block->removeEdge(block->getTargetBlock());
            block->deleteInst(inst);
          }

          graphChanged = TRUE; // CFG was modifed
        }

        // Otherwise we can at least propagate what we do know
        zeroes += bvIndex1;
        neg1 += bvIndex1;
        break;
      }

      case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN32S_IATTR3_IBIN32S:
      {
        operand1 = inst->getWOps()[0];
        bvIndex1 = operand1->getBvIndex();
        bvIndex2 = inst->getROps()[0]->getBvIndex();
        constant = PCodeConstants::getConstantValue(bvIndex2, zeroes,
                                                    ones, neg1);

        // Constants must be known, *and* target can't be indirect varchar
        if (((constant == -1) || (constant == 0)) &&
            (operand1->getOffset() >= 0))

        {
          if (!operand1->forAlignedFormat()) {
            inst->code[0] = PCIT::MOVE_MBIN16U_IBIN16U;
            inst->code[3] = (constant == 0) ? 0 : -1;
          }
          else {
            inst->code[0] = PCIT::NULL_BITMAP;
            inst->code[3] = PCIT::NULL_BITMAP_SET;
            inst->code[4] = operand1->getNullBitIndex();
            inst->code[5] = (constant == 0) ? 0 : 1;
          }

          if (constant == 0) {
            block->insertNewInstAfter(inst, PCIT::BRANCH);
            block->removeEdge(block->getFallThroughBlock());
          }
          else {
            block->removeEdge(block->getTargetBlock());
          }

          graphChanged = TRUE; // CFG was modifed

          inst->reloadOperands(this);

          RESTART_INST_IN_BLOCK;
          break;
        }

        zeroes += bvIndex1;
        neg1 += bvIndex1;
        break;
      }

      case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN32S_MBIN32S_IATTR4_IBIN32S:
      {
        operand1 = inst->getWOps()[0];

        constant = PCodeConstants::getConstantValue(
              inst->getROps()[0]->getBvIndex(), zeroes, ones, neg1);

        constant2 = PCodeConstants::getConstantValue(
              inst->getROps()[1]->getBvIndex(), zeroes, ones, neg1);

        NABoolean isNull = ((constant == -1) || (constant2 == -1));
        NABoolean isNotNull = ((constant == 0) && (constant2 == 0));

        //TODO: add case where if either constant or constant2 is 0, then
        //reduce NNBB branch to shorter form.

        // Constants must be known, *and* target can't be indirect varchar
        if ((isNull || isNotNull) && (operand1->getOffset() >= 0))
        {
          if (!operand1->forAlignedFormat()) {
            inst->code[0] = PCIT::MOVE_MBIN16U_IBIN16U;
            inst->code[3] = (isNull) ? -1 : 0;
          }
          else {
            inst->code[0] = PCIT::NULL_BITMAP;
            inst->code[3] = PCIT::NULL_BITMAP_SET;
            inst->code[4] = operand1->getNullBitIndex();
            inst->code[5] = (isNull) ? 1 : 0;
          }

          if (isNotNull) {
            block->insertNewInstAfter(inst, PCIT::BRANCH);
            block->removeEdge(block->getFallThroughBlock());
          }
          else {
            block->removeEdge(block->getTargetBlock());
          }

          graphChanged = TRUE; // CFG was modifed

          inst->reloadOperands(this);

          RESTART_INST_IN_BLOCK;
          break;
        }
        else if ((constant == 0) || (constant2 == 0))
        {
        }

        bvIndex1 = operand1->getBvIndex();
        zeroes += bvIndex1;
        neg1 += bvIndex1;
        break;
      }

      case PCIT::NNB_SPECIAL_NULLS_MBIN32S_MATTR3_MATTR3_IBIN32S_IBIN32S:
      {
        // Go through each read operand.
        for (i=0; i < 2; i++) {
          operand2 = inst->getROps()[i];
          bvIndex2 = inst->getROps()[i]->getBvIndex();
          constant = PCodeConstants::getConstantValue(bvIndex2, zeroes,
                                                      ones, neg1);

          if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
            if (constant == 0) {
              // Get constant of second operand
              constant = PCodeConstants::getConstantValue(
                           inst->getROps()[(i+1)%2]->getBvIndex(), 
                           zeroes, ones, neg1);

              if (constant != 0)
                continue;

              // Both operands are zero
              inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
              inst->code[3] = 0;

              inst->reloadOperands(this);

              block->insertNewInstAfter(inst, PCIT::BRANCH);
              block->removeEdge(block->getFallThroughBlock());
            }
            else {
              assert (constant == -1);

              PCodeInst* newInst;
              PCodeOperand* op = (i == 0) ? inst->getROps()[1]
                                          : inst->getROps()[0];
 
              newInst = block->insertNewInstBefore(inst,
                          PCIT::NULL_TEST_MBIN32S_MATTR5_IBIN32S_IBIN32S);
              newInst->code[1] = inst->code[1];
              newInst->code[2] = inst->code[2];
              newInst->code[3] = op->getStackIndex();
              newInst->code[4] = op->getOffset();
              newInst->code[5] = -1; // voa that's unnecessary.
              newInst->code[6] = (op->forAlignedFormat())
                                   ? ExpTupleDesc::SQLMX_ALIGNED_FORMAT
                                   : ExpTupleDesc::SQLARK_EXPLODED_FORMAT;
              newInst->code[7] = op->getNullBitIndex();
              newInst->code[8] = 0;  // No voa lookup needed.
              newInst->code[9] = -1; // Test for NULL

              newInst->reloadOperands(this);

              block->deleteInst(inst);
              inst = newInst;

//              inst->code[0] = PCIT::EQ_MBIN32S_MBIN16S_MBIN16S;

              block->removeEdge(block->getTargetBlock());
            }

            graphChanged = TRUE; // CFG was modifed

            RESTART_INST_IN_BLOCK;
            break;
          }
        }

        bvIndex1 = inst->getWOps()[0]->getBvIndex();
        zeroes += bvIndex1;
        ones += bvIndex1;
        break;
      }


      case PCIT::NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_IATTR3_IBIN32S:
      case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S:
      case PCIT::NOT_NULL_BRANCH_MBIN16S_MBIN16S_IBIN32S:
      {
        operand1 = inst->getROps()[0];
        operand2 = inst->getWOps()[0];

        bvIndex1 = operand1->getBvIndex();
        bvIndex2 = operand2->getBvIndex();

        constant = PCodeConstants::getConstantValue(bvIndex1, zeroes,
                                                    ones, neg1);

        if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
          switch(opc) {
            case PCIT::NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_IATTR3_IBIN32S:
            case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S:
              inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
              break;

            case PCIT::NOT_NULL_BRANCH_MBIN16S_MBIN16S_IBIN32S:
              inst->code[0] = PCIT::MOVE_MBIN16U_IBIN16U;
              break;
          }

          inst->code[1] = operand2->getStackIndex();
          inst->code[2] = operand2->getOffset();
          inst->code[3] = constant;

          inst->reloadOperands(this);

          if (constant == 0) {
            block->insertNewInstAfter(inst, PCIT::BRANCH);
            block->removeEdge(block->getFallThroughBlock());
          }
          else {
            block->removeEdge(block->getTargetBlock());
          }

          graphChanged = TRUE; // CFG was modifed

          RESTART_INST_IN_BLOCK;
          continue;
        }

        zeroes += bvIndex1;
        neg1 += bvIndex1;

        zeroes += bvIndex2;
        neg1 += bvIndex2;
        break;
      }

      case PCIT::NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_MBIN32S_IATTR4_IBIN32S:
        operand1 = inst->getWOps()[0];
        bvIndex1 = operand1->getBvIndex();

        for (i=0; i < 2; i++) {
          operand2 = inst->getROps()[i];
          bvIndex2 = operand2->getBvIndex();
          constant = PCodeConstants::getConstantValue(bvIndex2, zeroes,
                                                      ones, neg1);

          if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
              inst->code[0] =
                PCIT::NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_IATTR3_IBIN32S;

              if (constant == -1) {
                inst->code[3] = operand2->getStackIndex();
                inst->code[4] = operand2->getOffset();
                inst->code[5] = inst->code[7];

                PCodeAttrNull * newAttr = (PCodeAttrNull *)&(inst->code[5]);
                PCodeAttrNull * oldAttr = (PCodeAttrNull *)&(inst->code[7]);

                // New size is 3 less since we're getting rid of 1 source op,
                // which is made up of index and offset, and 1 null bit index,
                // which corresponds to that source.
                newAttr->fmt_.size_ = oldAttr->fmt_.size_ - 3;
 
                // If src is second operand, need to set format correctly.
                // Otherwise it, along with target, are already set right.
                if (i == 1)
                  newAttr->fmt_.op2Fmt_ = oldAttr->fmt_.op3Fmt_;

                inst->code[6] = operand1->getNullBitIndex();
                inst->code[7] = operand2->getNullBitIndex();
                
              }
              else {
                inst->code[3] = inst->getROps()[(i+1)%2]->getStackIndex();
                inst->code[4] = inst->getROps()[(i+1)%2]->getOffset();
                inst->code[5] = inst->code[7];

                PCodeAttrNull * newAttr = (PCodeAttrNull *)&(inst->code[5]);
                PCodeAttrNull * oldAttr = (PCodeAttrNull *)&(inst->code[7]);

                // New size is 2 less since we're getting rid of 1 source op
                // which is made up of index and offset.
                newAttr->fmt_.size_ = oldAttr->fmt_.size_ - 3;
 
                // If src is first operand, need to get format of 2nd op
                // Otherwise it, along with target, are already set right.
                if (i == 0)
                  newAttr->fmt_.op2Fmt_ = oldAttr->fmt_.op3Fmt_;

                inst->code[6] = operand1->getNullBitIndex();
                inst->code[7] = inst->getROps()[(i+1)%2]->getNullBitIndex();
              }

            inst->reloadOperands(this);

            RESTART_INST_IN_BLOCK;
            break;
          }
        }

        zeroes += bvIndex1;
        neg1 += bvIndex1;

        break;


          case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_MBIN16S_IBIN32S:
          case PCIT::NOT_NULL_BRANCH_MBIN16S_MBIN16S_MBIN16S_IBIN32S:
            operand1 = inst->getWOps()[0];
            bvIndex1 = operand1->getBvIndex();

            for (i=0; i < 2; i++) {
              operand2 = inst->getROps()[i];
              bvIndex2 = operand2->getBvIndex();
              constant = PCodeConstants::getConstantValue(bvIndex2, zeroes,
                                                          ones, neg1);

              if ((constant == -1) || (constant == 0)) {
                if (opc==PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_MBIN16S_IBIN32S)
                  inst->code[0] = PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S;
                else
                  inst->code[0] = PCIT::NOT_NULL_BRANCH_MBIN16S_MBIN16S_IBIN32S;

                if (constant == 0) {
                  inst->code[3] = inst->getROps()[(i+1)%2]->getStackIndex();
                  inst->code[4] = inst->getROps()[(i+1)%2]->getOffset();
                }
                else {
                  inst->code[3] = operand2->getStackIndex();
                  inst->code[4] = operand2->getOffset();
                }
                inst->code[5] = inst->code[7];

                inst->reloadOperands(this);

                // No need to change anything else since retrying the new
                // instruction will end up removing this instruction.

                RESTART_INST_IN_BLOCK;
                break;
              }
            }

            zeroes += bvIndex1;
            neg1 += bvIndex1;

            break;

          case PCIT::NULL_BITMAP_BULK:
          case PCIT::NOT_NULL_BRANCH_BULK:
            for (i=0; i < inst->getROps().entries(); i++) {
              bvIndex2 = inst->getROps()[i]->getBvIndex();
              zeroes += bvIndex2;
              neg1 += bvIndex2;
            }
            break;

          case PCIT::BRANCH_OR:
          case PCIT::BRANCH_AND:
          {
            operand1 = inst->getROps()[0];
            operand2 = inst->getWOps()[0];

            bvIndex1 = operand1->getBvIndex();
            bvIndex2 = operand2->getBvIndex();

            constant = PCodeConstants::getConstantValue(bvIndex1, zeroes,
                                                        ones, neg1);

            if (constant != PCodeConstants::UNKNOWN_CONSTANT) {
              inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
              inst->code[1] = operand2->getStackIndex();
              inst->code[2] = operand2->getOffset();
              inst->code[3] = constant;

              inst->reloadOperands(this);

              if (((opc == PCIT::BRANCH_OR) && (constant == 1)) ||
                  ((opc == PCIT::BRANCH_AND) && (constant == 0)))
              {
                block->insertNewInstAfter(inst, PCIT::BRANCH);
                block->removeEdge(block->getFallThroughBlock());
              }
              else {
                block->removeEdge(block->getTargetBlock());
              }

              graphChanged = TRUE; // CFG was modifed

              RESTART_INST_IN_BLOCK;
              break;
            }
            else if (block->getFallThroughBlock() == block->getTargetBlock())
            {
              // Don't ask me why, but sometimes we see this: executor/TEST038
              // Change branch to move and fall-through
              inst->code[0] = PCIT::MOVE_MBIN32U_MBIN32U;
              inst->code[1] = operand2->getStackIndex();
              inst->code[2] = operand2->getOffset();
              inst->code[3] = operand1->getStackIndex();
              inst->code[4] = operand1->getOffset();

              inst->reloadOperands(this);
              block->removeEdge(block->getTargetBlock());

              graphChanged = TRUE; // CFG was modifed

              // TODO: Restart once we add constant prop support for MOVEs
              // other than constant moves.
              //RESTART_INST_IN_BLOCK;
              //break;
            }

            // The operand of a logical branch should have a boolean value.  In
            // our case, the values can be 0, 1, or -1.  If the read operand
            // is unknown, or if certain values are not possible (e.g. -1)
            // then set that up first.

            if (!PCodeConstants::isAnyKnownConstant(bvIndex1,zeroes,ones,neg1))
            {
              zeroes += bvIndex1;
              ones += bvIndex1;
              neg1 += bvIndex1;
            }

            // If a change was a made, restart without setting write constants
            if (inst->getOpcode() != opc) {
              RESTART_INST_IN_BLOCK;
              break;
            }

            // Set up write constants
            PCodeConstants::copyConstantVectors(bvIndex1, bvIndex2,
                                                zeroes, ones, neg1);

            //
            // Sometimes a logical branch targets a logic instruction
            // unnecessarily.  This is a branch optimization which could be
            // done in cfgRewiring(), but we opt to do it here instead.  An
            // example of this is:
            //
            // [1]
            // BRANCH_AND (168) 13 0 2 8 2 12  (Tgt: 4)
            // ...
            // [4]  (Preds: 2 )
            // AND_MBIN32S_MBIN32S_MBIN32S (63) 2 8 2 12 2 16
            //
            // [5]  (Preds: 1 )
            // OR_MBIN32S_MBIN32S_MBIN32S (64) 2 0 2 4 2 8
            //
            // We should just be able to branch from 1 directly to 5.
            //

            // Target block should have a single logical instruction.
            PCodeBlock* tgtBlock = block->getTargetBlock();
            if (tgtBlock->getLastInst() &&
                (tgtBlock->getLastInst() == tgtBlock->getFirstInst()))
            {
              PCodeInst* logicInst = tgtBlock->getLastInst();
              Int32 subOpc = logicInst->getOpcode();

              // ((BRANCH_OR -> OR) or (BRANCH_AND -> AND)) and both insts have
              // the same write operand.
              if ((((opc == PCIT::BRANCH_OR) &&
                   (subOpc == PCIT::OR_MBIN32S_MBIN32S_MBIN32S)) ||
                   ((opc == PCIT::BRANCH_AND) &&
                    (subOpc == PCIT::AND_MBIN32S_MBIN32S_MBIN32S))) &&
                  (logicInst->getWOps()[0]->getBvIndex() ==
                   inst->getWOps()[0]->getBvIndex()))
              {
                // The read operand of the branch must be a read operand of the
                // logic instruction.
                CollIndex branchOpIdx = inst->getROps()[0]->getBvIndex();
                if ((logicInst->getROps()[0]->getBvIndex() == branchOpIdx) ||
                    (logicInst->getROps()[1]->getBvIndex() == branchOpIdx))
                {
                  // Re-target branch to fall-through of original target block.
                  block->removeEdge(block->getTargetBlock());
                  block->addEdge(tgtBlock->getFallThroughBlock());

                  graphChanged = TRUE; // CFG was modifed
                }
              }
            }

            break;
          }
    }
  } ENDFE_INST_IN_BLOCK

  return graphChanged;
}

// 
// Change moves from constant's area to direct immediate moves.
//
void PCodeCfg::constantFolding()
{
  FOREACH_BLOCK(block, firstInst, lastInst, index) {
    FOREACH_INST_IN_BLOCK(block, inst) {
      if (inst->isMove()) {
        PCodeOperand* operand2 = inst->getROps()[0];
        if (!operand2->isConst())
          continue;

        switch(inst->getOpcode()) {
          case PCIT::MOVE_MBIN16U_MBIN8:
            inst->code[0] = PCIT::MOVE_MBIN16U_IBIN16U;
            inst->code[3] = (UInt8)getIntConstValue(operand2);
            break;

          case PCIT::MOVE_MBIN32U_MBIN16U:
          case PCIT::MOVE_MBIN32S_MBIN16U:
            inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
            inst->code[3] = (UInt16)getIntConstValue(operand2);
            break;

          case PCIT::MOVE_MBIN32S_MBIN16S:
          case PCIT::MOVE_MBIN32U_MBIN16S:
            inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
            inst->code[3] = (Int16)getIntConstValue(operand2);
            break;

          case PCIT::MOVE_MBIN16U_MBIN16U:
            inst->code[0] = PCIT::MOVE_MBIN16U_IBIN16U;
            inst->code[3] = (UInt16)getIntConstValue(operand2);
            break;

          case PCIT::MOVE_MBIN32U_MBIN32U:
            inst->code[0] = PCIT::MOVE_MBIN32S_IBIN32S;
            inst->code[3] = (UInt32)getIntConstValue(operand2);
            break;

          case PCIT::MOVE_MBIN8_MBIN8:
            continue;

          case PCIT::MOVE_MBIN64S_MBIN16U:
          case PCIT::MOVE_MBIN64S_MBIN16S:
          case PCIT::MOVE_MBIN64S_MBIN32U:
          case PCIT::MOVE_MBIN64S_MBIN32S:
            continue;

          case PCIT::MOVE_MBIN64S_MBIN64S:
            continue;

          default:
            continue;
        }

        inst->reloadOperands(this);
      }
    } ENDFE_INST_IN_BLOCK
  } ENDFE_BLOCK
}

//
// Given an operand known to be a constant, lookup it's value as a string and
// return it (and its length via an incoming parameter).
//
char* PCodeCfg::getStringConstValue(PCodeOperand* op, Int32* len)
{
  CollIndex off = op->getOffset();

  if (op->isVarchar()) {
    off = off - op->getVcIndicatorLen() - op->getVcNullIndicatorLen();
  }

  PCodeConstants* constPtr = offsetToConstMap_->getFirstValue(&off);

  assert(constPtr != NULL);

  switch (op->getType()) {
    case PCIT::MASCII:
      *len = op->getLen();
      return (char*)(constPtr->getData());

    case PCIT::MATTR5:
      if (op->isVarchar()) {
        *len = ((op->getVcIndicatorLen() == 2)
          ? (Int32)(*((Int16*)((char*)constPtr->getData() +
              op->getVcNullIndicatorLen())))
          : (Int32)(*((Int32*)((char*)constPtr->getData() +
              op->getVcNullIndicatorLen()))));

        return ((char*)constPtr->getData() + op->getVcIndicatorLen() +
                       op->getVcNullIndicatorLen());
      }

      // Otherwise we have a fixed-length string.
      *len = op->getLen();
      return (char*)(constPtr->getData());

    default:
      assert(FALSE);
      break;
  }

  return NULL;
}

//
// Given any pointer operand, return the pointer to it.
//
void* PCodeCfg::getPtrConstValue(PCodeOperand* op)
{
  CollIndex off = op->getOffset();

  // This routine can be called before PCodeConstant objects are initialized.
  // As such, the offset must come directly from the constants area of the expr.
  if (offsetToConstMap_ == NULL) {
    char * stk = expr_->getConstantsArea();
    Int32 len = expr_->getConstsLength();

    assert (off < (CollIndex)len);

    return (void*)(stk + off);
  }

  // Otherwise constant should be recorded in constants map.
  PCodeConstants* constPtr = offsetToConstMap_->getFirstValue(&off);
  if (constPtr == NULL)
    return NULL;

  return (void*)(constPtr->getData());
}


//
// Given an operand known to be an integer, find its value and return it.
//
Int64 PCodeCfg::getIntConstValue(PCodeOperand* op)
{
  CollIndex off = op->getOffset();

  // TODO: move this calculation to getStringValue()
  if (op->isVarchar()) {
    off = off - op->getVcIndicatorLen() - op->getVcNullIndicatorLen();
  }

  PCodeConstants* constPtr = offsetToConstMap_->getFirstValue(&off);

  //
  // All integer constant operands should be found in constants hash table.  If
  // not, then they must be constants defined prior to optimizations.  An
  // example on how this can happen is a MOVE_MBIN8_MBIN8_IBIN32S which has a
  // constant read operand with type MPTR32.  Operands with type MPTR32 are not
  // currently tracked.  If this instruction is converted into a normal (known
  // sized) move, then constant folding may be called and it may be further
  // converted into an immediate move.
  //
  // TODO: Keep the assert for now (change made in ::getAlign() to recognize
  // PCIT::MPTR32 operand (giving it worst-case 8-byte alignment).
  //

  assert(constPtr != NULL);

  Int64 value = 0;

  switch (op->getType()) {
    case PCIT::MBIN8:
      value = (Int64)*((UInt8*)(constPtr->getData()));
      break;
    case PCIT::MBIN8S:
      value = (Int64)*((Int8*)(constPtr->getData()));
      break;
    case PCIT::MBIN8U:
      value = (Int64)*((UInt8*)(constPtr->getData()));
      break;
    case PCIT::MBIN16S:
      value = (Int64)*((Int16*)(constPtr->getData()));
      break;
    case PCIT::MBIN16U:
      value = (Int64)*((UInt16*)(constPtr->getData()));
      break;
    case PCIT::MBIN32S:
      value = (Int64)*((Int32*)(constPtr->getData()));
      break;
    case PCIT::MBIN32U:
      value = (Int64)*((UInt32*)(constPtr->getData()));
      break;
    case PCIT::MBIN64S:
      value = (Int64)*((Int64*)(constPtr->getData()));
      break;
    case PCIT::MPTR32:
      switch (constPtr->getLen()) {
        case 1:
          value = (Int64)*((UInt8*)(constPtr->getData()));
          break;
        case 2:
          value = (Int64)*((Int16*)(constPtr->getData()));
          break;
        case 4:
          value = (Int64)*((Int32*)(constPtr->getData()));
          break;
        case 8:
          value = (Int64)*((Int64*)(constPtr->getData()));
          break;
        default:
          assert(FALSE);
      }
      break;

    default:
      assert(FALSE);
      break;
  }

  return value;
}

//
// Given an operand known to be a float, find its value and return it.
//
double PCodeCfg::getFloatConstValue(PCodeOperand* op)
{
  CollIndex off = op->getOffset();

  // TODO: move this calculation to getStringValue()
  if (op->isVarchar()) {
    off = off - op->getVcIndicatorLen() - op->getVcNullIndicatorLen();
  }

  PCodeConstants* constPtr = offsetToConstMap_->getFirstValue(&off);

  // All integer constant operands should be found in constants hash table.
  assert(constPtr != NULL);

  double value = 0;

  switch (op->getType()) {
    case PCIT::MFLT64:
      value = *((double*)(constPtr->getData()));
      break;

    case PCIT::MFLT32:
      value = *((float*)(constPtr->getData()));
      break;

    default:
      assert(FALSE);
      break;
  }

  return value;
}

//
// Add a new integer constant.  The alignment param is used to indicate the
// size of the datum as well as it's alignment.
//
Int32 PCodeCfg::addNewIntConstant(Int64 value, Int32 alignment)
{
  // Quickly return the zero offset if it exists and we're looking to add 0.
  if ((value == 0) && (zeroOffset_ != -1))
    return zeroOffset_;

  switch (alignment) {
    case 1:
    {
      UInt8 val = (UInt8)value;
      return *(addConstant(&val, alignment, alignment));
    }

    case 2:
    {
      UInt16 val = (UInt16)value;
      return *(addConstant(&val, alignment, alignment));
    }

    case 4:
    {
      UInt32 val = (UInt32)value;
      return *(addConstant(&val, alignment, alignment));
    }

    case 8:
    {
      return *(addConstant(&value, alignment, alignment));
    }

    default:
      assert(FALSE);
  }

  return -1;
}

//
// Add a new float constant.  The alignment param is used to indicate the
// size of the datum as well as it's alignment.
//
Int32 PCodeCfg::addNewFloatConstant(double value, Int32 alignment)
{
  switch (alignment) {
    case 4:
    {
      float val = (float)value;
      return *(addConstant(&val, alignment, alignment));
    }

    case 8:
    {
      return *(addConstant(&value, alignment, alignment));
    }

    default:
      assert(FALSE);
  }

  return -1;
}

//
// Constant fold instructions with input operands known to be constant.  It's
// important to update the reaching defs information if the new instruction
// being added is generated from scratch - see updateReachingDefs().
//
PCodeInst* PCodeCfg::constantFold(PCodeInst* inst, NABoolean rDefsAvailable)
{
  CollIndex i;
  PCodeOperand *op1, *op2;
  Int16 ov; // overflow indicator

  Int32 opc = inst->getOpcode();

  switch (opc) {
#if 0
    case PCIT::CLAUSE_EVAL:
    {
      ex_expr::exp_return_type retCode;
      char *opData[3 * ex_clause::MAX_OPERANDS];
      char **opDataData = &opData[2 * ex_clause::MAX_OPERANDS];

      clause = inst->code[1];

      if (inst->mustProcessNulls() ||
          !inst->clauseInitOperandsForConstFold(opData, heap_))
        return;

      retCode = clause->eval(opDataData, heap_, diagsArea)

      if (retCode == ex_expr::EXPR_ERROR)
        return;

      break;
    }
#endif

    case PCIT::MOVE_MASCII_MASCII_IBIN32S_IBIN32S:
    case PCIT::MOVE_MASCII_MATTR5_IBIN32S:
    {
      Int32 len, tgtLen;
      CollIndex* off;

      // Folding inst into same-sized moves is useful for copy propagation, and
      // that being only if the write operand is a temp.
      if (!inst->getWOps()[0]->isTemp())
        break;

      op2 = inst->getROps()[0];
      if (op2->isConst()) {
        assert(!op2->isIndirectVarchar());

        op1 = inst->getWOps()[0];
        tgtLen = op1->getLen();

        char* str = getStringConstValue(op2, &len);
        Int32 padLen = tgtLen - len;

        char* newStr = (char*)new(heap_) char[tgtLen];
        if (padLen > 0) {
          str_cpy_all(newStr, str, len);
          str_pad(newStr + len, padLen, ' ');
        }
        else {
          str_cpy_all(newStr, str, tgtLen);
        }

        off = addConstant((void*)newStr, tgtLen, 1);

        inst->code[0] = PCIT::MOVE_MBIN8_MBIN8_IBIN32S;
        inst->code[3] = 1;
        inst->code[4] = *off;
        inst->code[5] = tgtLen;

        NADELETEBASIC(newStr, heap_);
        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::MOVE_MATTR5_MASCII_IBIN32S:
    {
      Int32 len, tgtLen;
      CollIndex* off;

      op1 = inst->getWOps()[0];

      // Folding inst into same-sized moves is useful for copy propagation, and
      // that being only if the write operand is a temp.
      if (!op1->isTemp())
        break;

      op2 = inst->getROps()[0];
      if (op2->isConst()) {
        // Get source string
        char* str = getStringConstValue(op2, &len);

        // Since char is being stored in varchar, if the length is too big to
        // be represented by a varchar (in terms of a 2-byte vc length field),
        // then skip this transformation.
        if (len >= SHRT_MAX)
          break;

        // Target length that should be stored.
        tgtLen = (op1->getVcMaxLen() >= len) ? len : op1->getVcMaxLen();

        // Allocate new varchar string with 2 bytes for vc len
        char* newStr = (char*) new(heap_) char[2 + tgtLen];
        *((Int16*)(newStr)) = (Int16)tgtLen;  
        str_cpy_all(newStr + 2, str, tgtLen);

        off = addConstant((void*)newStr, tgtLen + 2, 2);

        Int32 comboLen = 0;
        char* comboPtr = (char*)(&comboLen);
        comboPtr[0] = 0; // no null
        comboPtr[1] = 2; // vc length is 2 bytes

        PCodeInst* newInst;
        PCodeBlock* block = inst->block;

        newInst = block->insertNewInstAfter(inst, PCIT::MOVE_MATTR5_MATTR5);

        newInst->code[1] = inst->code[1];
        newInst->code[2] = inst->code[2];
        newInst->code[3] = inst->code[3];
        newInst->code[4] = inst->code[4];
        newInst->code[5] = inst->code[5];

        newInst->code[6] = 1;
        newInst->code[7] = *off + 2;            // Up 2 to get to str itself
        newInst->code[8] = -1;                  // voa
        newInst->code[9] = op1->getVcMaxLen();  // tgt/src share max vc length
        newInst->code[10] = comboLen;

        newInst->reloadOperands(this);

        // Attempt to update reaching defs info.
        if (rDefsAvailable)
          updateReachingDefs(block, op1->getBvIndex(), inst, newInst);

        block->deleteInst(inst);
        inst = newInst;

        NADELETEBASIC(newStr, heap_);
      }

      break;
    }

    case PCIT::MOVE_MBIGS_MBIN16S_IBIN32S:
    case PCIT::MOVE_MBIGS_MBIN32S_IBIN32S:
    case PCIT::MOVE_MBIGS_MBIN64S_IBIN32S:
    {
      op1 = inst->getWOps()[0];

      // Folding inst into same-sized moves is useful for copy propagation, and
      // that being only if the write operand is a temp.
      if (!op1->isTemp())
        break;

      op2 = inst->getROps()[0];
      if (op2->isConst()) {
        CollIndex* off;
        Int64 value = getIntConstValue(op2);
        Int32 tgtLen = inst->getWOps()[0]->getLen();
        char* result = (char*) new(heap_) char[tgtLen];
        BigNumHelper::ConvInt64ToBigNumWithSignHelper(tgtLen, value, result, FALSE);

        off = addConstant((void*)result, tgtLen,inst->getWOps()[0]->getAlign());

        PCodeInst* newInst;
        PCodeBlock* block = inst->block;

        newInst = block->insertNewInstAfter(inst,
                    PCIT::MOVE_MBIGS_MBIGS_IBIN32S_IBIN32S);
        newInst->code[1] = inst->code[1];
        newInst->code[2] = inst->code[2];
        newInst->code[3] = 1;
        newInst->code[4] = *off;
        newInst->code[5] = tgtLen;
        newInst->code[6] = tgtLen;

        newInst->reloadOperands(this);

        // Attempt to update reaching defs info.
        if (rDefsAvailable)
          updateReachingDefs(block, op1->getBvIndex(), inst, newInst);

        block->deleteInst(inst);
        inst = newInst;
      }

      break;
    }

    case PCIT::MOVE_MBIN32S_IBIN32S:
    {
      PCodeInst* newInst;
      PCodeBlock* block = inst->block;

      op1 = inst->getWOps()[0];

      // Folding inst into same-sized moves is useful for copy propagation, and
      // that being only if the write operand is a temp.
      if (!op1->isTemp())
        break;

      newInst = block->insertNewInstAfter(inst, PCIT::MOVE_MBIN32U_MBIN32U);
      newInst->code[1] = inst->code[1];
      newInst->code[2] = inst->code[2];
      newInst->code[3] = 1;
      newInst->code[4] = addNewIntConstant(inst->code[3], 4);

      newInst->reloadOperands(this);

      // Attempt to update reaching defs info.
      if (rDefsAvailable)
        updateReachingDefs(block, op1->getBvIndex(), inst, newInst);

      block->deleteInst(inst);
      inst = newInst;

      break;
    }

    case PCIT::MOVE_MBIN64S_MBIN16U:
    case PCIT::MOVE_MBIN64S_MBIN16S:
    case PCIT::MOVE_MBIN64S_MBIN32S:
    case PCIT::MOVE_MBIN64S_MBIN32U:

    case PCIT::MOVE_MBIN32U_MBIN16U:
    case PCIT::MOVE_MBIN32S_MBIN16U:
    case PCIT::MOVE_MBIN32U_MBIN16S:
    case PCIT::MOVE_MBIN32S_MBIN16S:

    case PCIT::MOVE_MBIN16U_MBIN8:
    {
      // Folding inst into same-sized moves is useful for copy propagation, and
      // that being only if the write operand is a temp.
      if (!inst->getWOps()[0]->isTemp())
        break;

      op1 = inst->getROps()[0];
      if (op1->isConst()) {
        Int64 value = getIntConstValue(op1);

        // Re-define the instruction and reload operands
        switch (inst->getWOps()[0]->getType()) {
          case PCIT::MBIN64S:
            inst->code[0] = PCIT::MOVE_MBIN64S_MBIN64S;
            inst->code[4] = addNewIntConstant(value, 8);
            break;

          case PCIT::MBIN32U:
          case PCIT::MBIN32S:
            inst->code[0] = PCIT::MOVE_MBIN32U_MBIN32U;
            inst->code[4] = addNewIntConstant(value, 4);
            break;

          case PCIT::MBIN16U:
            inst->code[0] = PCIT::MOVE_MBIN16U_MBIN16U;
            inst->code[4] = addNewIntConstant(value, 2);
            break;
        }

        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::MOVE_MFLT64_MBIN16S:
    case PCIT::MOVE_MFLT64_MBIN32S:
    case PCIT::MOVE_MFLT64_MBIN64S:
    case PCIT::MOVE_MFLT64_MFLT32:
    {
      // Folding inst into same-sized moves is useful for copy propagation, and
      // that being only if the write operand is a temp.
      if (!inst->getWOps()[0]->isTemp())
        break;

      op1 = inst->getROps()[0];
      if (op1->isConst()) {
        double fvalue =
          (inst->getROps()[0]->getType() == PCIT::MFLT32)
            ? (double)(getFloatConstValue(op1))
            : (double)(getIntConstValue(op1));

        // Re-define the instruction and reload operands
        inst->code[0] = PCIT::MOVE_MBIN64S_MBIN64S;
        inst->code[4] = addNewFloatConstant(fvalue, 8);

        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::MUL_MBIN16S_MBIN16S_MBIN16S:
    case PCIT::MUL_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::MUL_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::MUL_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::MUL_MBIN64S_MBIN16S_MBIN32S:
    case PCIT::MUL_MBIN64S_MBIN32S_MBIN32S:
    case PCIT::MUL_MBIN64S_MBIN64S_MBIN64S:
      for (i=0; i < inst->getROps().entries(); i++) {
        op1 = inst->getROps()[i];
        if (op1->isConst() && (getIntConstValue(op1) == 1)) {
          switch (opc) {
            case PCIT::MUL_MBIN64S_MBIN16S_MBIN32S:
              inst->code[0] = (i == 0) ? PCIT::MOVE_MBIN64S_MBIN32S :
                                         PCIT::MOVE_MBIN64S_MBIN16S;
              break;

            case PCIT::MUL_MBIN32S_MBIN16S_MBIN32S:
              inst->code[0] = (i == 0) ? PCIT::MOVE_MBIN32U_MBIN32U :
                                         PCIT::MOVE_MBIN32S_MBIN16S;
              break;

            case PCIT::MUL_MBIN16S_MBIN16S_MBIN16S:
              inst->code[0] = PCIT::MOVE_MBIN16U_MBIN16U;
              break;

            case PCIT::MUL_MBIN32S_MBIN32S_MBIN32S:
              inst->code[0] = PCIT::MOVE_MBIN32U_MBIN32U;
              break;

            case PCIT::MUL_MBIN32S_MBIN16S_MBIN16S:
              inst->code[0] = PCIT::MOVE_MBIN32S_MBIN16S;
              break;

            case PCIT::MUL_MBIN64S_MBIN32S_MBIN32S:
              inst->code[0] = PCIT::MOVE_MBIN64S_MBIN32S;
              break;

            case PCIT::MUL_MBIN64S_MBIN64S_MBIN64S:
              inst->code[0] = PCIT::MOVE_MBIN64S_MBIN64S;
              break;
          }

          inst->code[3] = inst->getROps()[(i+1)%2]->getStackIndex();
          inst->code[4] = inst->getROps()[(i+1)%2]->getOffset();

          inst->reloadOperands(this);

          // Try to fold the move even further
          return constantFold(inst, rDefsAvailable);
        }
      }

      op1 = inst->getROps()[0];
      op2 = inst->getROps()[1];

      if (op1->isConst() && op2->isConst())
      {
        Int64 x = getIntConstValue(op1);
        Int64 y = getIntConstValue(op2);

        Int64 value = EXP_FIXED_OV_MUL(x, y, &ov);

        if (ov)
          return inst;

        Int32 offset = addNewIntConstant(value, inst->getWOps()[0]->getLen());
        inst->code[0] = inst->generateCopyMoveOpc(
                          inst->getWOps()[0]->getType());
        inst->code[3] = 1;
        inst->code[4] = offset;

        inst->reloadOperands(this);
      }

      break;

    case PCIT::EQ_MBIN32S_MASCII_MASCII:
    case PCIT::LT_MBIN32S_MASCII_MASCII:
    case PCIT::LE_MBIN32S_MASCII_MASCII:
    case PCIT::GT_MBIN32S_MASCII_MASCII:
    case PCIT::GE_MBIN32S_MASCII_MASCII:
    {
      op1 = inst->getROps()[0];
      op2 = inst->getROps()[1];

      if (op1->isConst() && op2->isConst())
      {
        Int32 z, len;

        char* x = getStringConstValue(op1, &len);
        char* y = getStringConstValue(op2, &len);

        z = memcmp(x, y, op1->getLen());

        switch (opc) {
          case PCIT::EQ_MBIN32S_MASCII_MASCII:
            z = (z == 0);
            break;

          case PCIT::LT_MBIN32S_MASCII_MASCII:
            z = (z < 0);
            break;

          case PCIT::LE_MBIN32S_MASCII_MASCII:
            z = (z <= 0);
            break;

          case PCIT::GT_MBIN32S_MASCII_MASCII:
            z = (z > 0);
            break;

          case PCIT::GE_MBIN32S_MASCII_MASCII:
            z = (z >= 0);
            break;
        }

        Int32 offset = addNewIntConstant(z, 4);
        inst->code[0] = inst->generateCopyMoveOpc(PCIT::MBIN32S);
        inst->code[3] = 1;
        inst->code[4] = offset;

        inst->reloadOperands(this);
      }

      break;
    }


    case PCIT::LE_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::LE_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::LE_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::LE_MBIN32S_MBIN16U_MBIN16U:
    case PCIT::LE_MBIN32S_MBIN16U_MBIN32U:
    case PCIT::LE_MBIN32S_MBIN32U_MBIN32U:
    case PCIT::LE_MBIN32S_MBIN16S_MBIN32U:
    case PCIT::LE_MBIN32S_MBIN16U_MBIN16S:
    case PCIT::LE_MBIN32S_MBIN64S_MBIN64S:

    case PCIT::GE_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::GE_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::GE_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::GE_MBIN32S_MBIN16U_MBIN16U:
    case PCIT::GE_MBIN32S_MBIN16U_MBIN32U:
    case PCIT::GE_MBIN32S_MBIN32U_MBIN32U:
    case PCIT::GE_MBIN32S_MBIN16S_MBIN32U:
    case PCIT::GE_MBIN32S_MBIN16U_MBIN16S:
    case PCIT::GE_MBIN32S_MBIN64S_MBIN64S:

    case PCIT::LT_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::LT_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::LT_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::LT_MBIN32S_MBIN16U_MBIN16U:
    case PCIT::LT_MBIN32S_MBIN16U_MBIN32U:
    case PCIT::LT_MBIN32S_MBIN32U_MBIN32U:
    case PCIT::LT_MBIN32S_MBIN16S_MBIN32U:
    case PCIT::LT_MBIN32S_MBIN16U_MBIN16S:
    case PCIT::LT_MBIN32S_MBIN64S_MBIN64S:

    case PCIT::GT_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::GT_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::GT_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::GT_MBIN32S_MBIN16U_MBIN16U:
    case PCIT::GT_MBIN32S_MBIN16U_MBIN32U:
    case PCIT::GT_MBIN32S_MBIN32U_MBIN32U:
    case PCIT::GT_MBIN32S_MBIN16S_MBIN32U:
    case PCIT::GT_MBIN32S_MBIN16U_MBIN16S:
    case PCIT::GT_MBIN32S_MBIN64S_MBIN64S:

    case PCIT::EQ_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::EQ_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::EQ_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::EQ_MBIN32S_MBIN16U_MBIN16U:
    case PCIT::EQ_MBIN32S_MBIN16U_MBIN32U:
    case PCIT::EQ_MBIN32S_MBIN32U_MBIN32U:
    case PCIT::EQ_MBIN32S_MBIN16S_MBIN32U:
    case PCIT::EQ_MBIN32S_MBIN16U_MBIN16S:
    case PCIT::EQ_MBIN32S_MBIN64S_MBIN64S:

    case PCIT::NE_MBIN32S_MBIN64S_MBIN64S:
    case PCIT::NE_MBIN32S_MBIN16S_MBIN16S:
    {
      op1 = inst->getROps()[0];
      op2 = inst->getROps()[1];

      if (op1->isConst() && op2->isConst())
      {
        Int32 z = 0;

        Int64 x = getIntConstValue(op1);
        Int64 y = getIntConstValue(op2);

        switch (opc) {
          case PCIT::LE_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::LE_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::LE_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::LE_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::LE_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::LE_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::LE_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::LE_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::LE_MBIN32S_MBIN64S_MBIN64S:
            z = (x <= y) ? 1 : 0;
            break;

          case PCIT::GE_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::GE_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::GE_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::GE_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::GE_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::GE_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::GE_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::GE_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::GE_MBIN32S_MBIN64S_MBIN64S:
            z = (x >= y) ? 1 : 0;
            break;

          case PCIT::LT_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::LT_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::LT_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::LT_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::LT_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::LT_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::LT_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::LT_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::LT_MBIN32S_MBIN64S_MBIN64S:
            z = (x < y) ? 1 : 0;
            break;

          case PCIT::GT_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::GT_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::GT_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::GT_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::GT_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::GT_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::GT_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::GT_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::GT_MBIN32S_MBIN64S_MBIN64S:
            z = (x > y) ? 1 : 0;
            break;

          case PCIT::EQ_MBIN32S_MBIN16S_MBIN16S:
          case PCIT::EQ_MBIN32S_MBIN16S_MBIN32S:
          case PCIT::EQ_MBIN32S_MBIN32S_MBIN32S:
          case PCIT::EQ_MBIN32S_MBIN16U_MBIN16U:
          case PCIT::EQ_MBIN32S_MBIN16U_MBIN32U:
          case PCIT::EQ_MBIN32S_MBIN32U_MBIN32U:
          case PCIT::EQ_MBIN32S_MBIN16S_MBIN32U:
          case PCIT::EQ_MBIN32S_MBIN16U_MBIN16S:
          case PCIT::EQ_MBIN32S_MBIN64S_MBIN64S:
            z = (x == y) ? 1 : 0;
            break;

          case PCIT::NE_MBIN32S_MBIN64S_MBIN64S:
          case PCIT::NE_MBIN32S_MBIN16S_MBIN16S:
            z = (x != y) ? 1 : 0;
            break;
        }

        Int32 offset = addNewIntConstant(z, 4);
        inst->code[0] = inst->generateCopyMoveOpc(PCIT::MBIN32S);
        inst->code[3] = 1;
        inst->code[4] = offset;

        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::ADD_MBIN16S_MBIN16S_MBIN16S:
    case PCIT::ADD_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::ADD_MBIN64S_MBIN64S_MBIN64S:
    case PCIT::ADD_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::ADD_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::ADD_MBIN64S_MBIN32S_MBIN64S:
    {
      op1 = inst->getROps()[0];
      op2 = inst->getROps()[1];

      if (op1->isConst() && op2->isConst())
      {
        Int64 x = getIntConstValue(op1);
        Int64 y = getIntConstValue(op2);

        Int64 value = EXP_FIXED_OV_ADD(x, y, &ov);

        if (ov)
          return inst;

        Int32 offset = addNewIntConstant(value, inst->getWOps()[0]->getLen());
        inst->code[0] = inst->generateCopyMoveOpc(
                          inst->getWOps()[0]->getType());
        inst->code[3] = 1;
        inst->code[4] = offset;

        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::SUB_MBIN16S_MBIN16S_MBIN16S:
    case PCIT::SUB_MBIN32S_MBIN32S_MBIN32S:
    case PCIT::SUB_MBIN64S_MBIN64S_MBIN64S:
    case PCIT::SUB_MBIN32S_MBIN16S_MBIN16S:
    case PCIT::SUB_MBIN32S_MBIN16S_MBIN32S:
    case PCIT::SUB_MBIN32S_MBIN32S_MBIN16S:
    {
      op1 = inst->getROps()[0];
      op2 = inst->getROps()[1];

      if (op1->isConst() && op2->isConst())
      {
        Int64 x = getIntConstValue(op1);
        Int64 y = getIntConstValue(op2);

        Int64 value = EXP_FIXED_OV_SUB(x, y, &ov);

        if (ov)
          return inst;

        Int32 offset = addNewIntConstant(value, inst->getWOps()[0]->getLen());
        inst->code[0] = inst->generateCopyMoveOpc(
                          inst->getWOps()[0]->getType());
        inst->code[3] = 1;
        inst->code[4] = offset;

        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::MUL_MFLT64_MFLT64_MFLT64:
    case PCIT::ADD_MFLT64_MFLT64_MFLT64:
    case PCIT::SUB_MFLT64_MFLT64_MFLT64:
    case PCIT::DIV_MFLT64_MFLT64_MFLT64:
    {
      op1 = inst->getROps()[0];
      op2 = inst->getROps()[1];

      if (op1->isConst() && op2->isConst()) {
        double x = getFloatConstValue(op1);
        double y = getFloatConstValue(op2);

        double res = 0.0;
        Int16 ov = 0;

        switch (opc) {
          case PCIT::MUL_MFLT64_MFLT64_MFLT64:
            res = MathReal64Mul(x, y, &ov);
            break;
          case PCIT::ADD_MFLT64_MFLT64_MFLT64:
            res = MathReal64Add(x, y, &ov);
            break;
          case PCIT::SUB_MFLT64_MFLT64_MFLT64:
            res = MathReal64Sub(x, y, &ov);
            break;
          case PCIT::DIV_MFLT64_MFLT64_MFLT64:
            res = MathReal64Div(x, y, &ov);
            break;
        }

        if (ov)
          return inst;

        // FIXME: I think we need to appropriately support a MOVE_MFLT64_MFLT64
        // instruction so that Native Expressions doesn't get confused.

        Int32 offset = addNewFloatConstant(res, 8);
        inst->code[0] = PCIT::MOVE_MBIN64S_MBIN64S;
        inst->code[3] = 1;
        inst->code[4] = offset;

        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::HASH_MBIN32U_MATTR5:
    case PCIT::HASH_MBIN32U_MPTR32_IBIN32S_IBIN32S:
    case PCIT::HASH_MBIN32U_MBIN16_IBIN32S_IBIN32S:
    case PCIT::HASH_MBIN32U_MBIN32_IBIN32S_IBIN32S:
    case PCIT::HASH_MBIN32U_MBIN64_IBIN32S_IBIN32S:
    {
      op1 = inst->getROps()[0];

      if (op1->isConst()) {
        Int32 len;
        char* x;
        UInt32 flags = ExHDPHash::NO_FLAGS;

        if (opc == PCIT::HASH_MBIN32U_MATTR5) {
          x = getStringConstValue(op1, &len);

          // Reduce length if padding exists.
          while ((len > 0) && (x[len-1] == ' '))
            len--;
        }
        else {
          len = op1->getLen();
          x = (char*)getPtrConstValue(op1);
          flags = inst->code[5];
        }

        UInt32 res = ExHDPHash::hash(x, flags, len);

        Int32 offset = addNewIntConstant(res, 4);
        inst->code[0] = inst->generateCopyMoveOpc(PCIT::MBIN32S);
        inst->code[3] = 1;
        inst->code[4] = offset;

        inst->reloadOperands(this);
      }

      break;
    }

    case PCIT::RANGE_LOW_S32S64:
    case PCIT::RANGE_HIGH_S32S64:
    case PCIT::RANGE_LOW_U32S64:
    case PCIT::RANGE_HIGH_U32S64:
    case PCIT::RANGE_LOW_S64S64:
    case PCIT::RANGE_HIGH_S64S64:
    case PCIT::RANGE_LOW_S16S64:
    case PCIT::RANGE_HIGH_S16S64:
    case PCIT::RANGE_MFLT64:
    {
      Int64 x, y;
      NABoolean error = TRUE; // Assume range instruction is needed

      PCodeOperand* op = inst->getROps()[0];

      // Only range instructions with const operands can be removed
      if (!op->isConst())
        break;

      if (opc != PCIT::RANGE_MFLT64) {
        x = getIntConstValue(op);
        y = (*(Int64*)&inst->code[3]);
      }

      switch (opc) {
        case PCIT::RANGE_LOW_S32S64:
        case PCIT::RANGE_LOW_U32S64:
        case PCIT::RANGE_LOW_S64S64:
        case PCIT::RANGE_LOW_S16S64:
          error = (x < y);
          break;

        case PCIT::RANGE_HIGH_S32S64:
        case PCIT::RANGE_HIGH_U32S64:
        case PCIT::RANGE_HIGH_S64S64:
        case PCIT::RANGE_HIGH_S16S64:
          error = (x > y);
          break;

        case PCIT::RANGE_MFLT64:
          error = FALSE;
          break;
      }

      if (!error) {
        PCodeBlock* block = inst->block;
        block->deleteInst(inst);
        inst = NULL;
      }
      break;
    }

    case PCIT::COMP_MBIN32S_MATTR5_MATTR5_IBIN32S:
    {
      op1 = inst->getROps()[0];
      op2 = inst->getROps()[1];
      if (!op1->isConst() || !op2->isConst())
        break;

      Int32 len1, len2;

      char* str1 = getStringConstValue(op1, &len1);
      char* str2 = getStringConstValue(op2, &len2);

      Int32 compTable[6][3] = {
        /* ITM_EQUAL */      {0, 1, 0},
        /* ITM_NOT_EQUAL */  {1, 0, 1},
        /* ITM_LESS */       {1, 0, 0},
        /* ITM_LESS_EQ */    {1, 1, 0},
        /* ITM_GREATER */    {0, 0, 1},
        /* ITM_GREATER_EQ */ {0, 1, 1}
      };

      // Set table pointer to appropriate position based on operation
      Int32* table = &(compTable[inst->code[13] - ITM_EQUAL][1]);

      Int32 compCode = charStringCompareWithPad(str1, len1, str2, len2, ' ');
      Int32 res = table[compCode];

      Int32 offset = addNewIntConstant(res, 4);
      inst->code[0] = inst->generateCopyMoveOpc(PCIT::MBIN32S);
      inst->code[3] = 1;
      inst->code[4] = offset;

      inst->reloadOperands(this);

      break;
    }

    case PCIT::GENFUNC_MATTR5_MATTR5_IBIN32S:
    {
      Int32 len;
      Int32 subOpc = inst->code[11];

      // Get source operand and check if constant.
      op2 = inst->getROps()[0];
      if (!op2->isConst())
        break;

      // Get tgt operand.
      op1 = inst->getWOps()[0];

      switch (subOpc) {
        case ITM_TRIM:
        case ITM_LTRIM:
        case ITM_RTRIM:
        case ITM_UPPER:
        case ITM_LOWER:
        {
          Int32 startIdx = 0;
          char* fromStr = NULL;
          NABoolean fromStrAllocated = FALSE;
          PCodeInst* newInst;

          PCodeBlock* block = inst->block;

          // Get source string and len (initial target length)
          char* str = getStringConstValue(op2, &len);
          CollIndex tgtLen = len;

          if ((subOpc == ITM_LOWER) || (subOpc == ITM_UPPER))
          {
            fromStr = (char*) new(heap_) char[tgtLen];
            for (i=0; i < tgtLen; i++)
              fromStr[i] = (subOpc == ITM_UPPER)
                ? TOUPPER(str[i]) : TOLOWER(str[i]);

            fromStrAllocated = TRUE;
          }
          else {
            // Set string up to first non-space
            if ((subOpc == ITM_TRIM) || (subOpc == ITM_LTRIM)) {
              for (i=0; i < (CollIndex)len; i++, startIdx++, tgtLen--)
                if (str[i] != ' ')
                  break;
            }

            // Set string up to last non-space
            if ((subOpc == ITM_TRIM) || (subOpc == ITM_RTRIM)) {

              if ( len > 0 ) // Protect against 0-length strings
              {
                for (i=len-1; i > (CollIndex)startIdx; i--, tgtLen--)
                  if (str[i] != ' ')
                    break;
              }
            }

            // Set "fromStr" to be "str" so that code below works for all cases.
            fromStr = str;
          }

          if (op1->isVarchar()) {
            // Allocate new varchar string with 2 bytes for vc len
            char* newStr = (char*) new(heap_) char[2 + tgtLen];
            *((Int16*)(newStr)) = (Int16)tgtLen;  

            if (tgtLen > 0)
              str_cpy_all(newStr + 2, &fromStr[startIdx], tgtLen);

            CollIndex* off = addConstant((void*)newStr, tgtLen + 2, 2);

            Int32 comboLen = 0;
            char* comboPtr = (char*)(&comboLen);
            comboPtr[0] = 0; // no null
            comboPtr[1] = 2; // vc length is 2 bytes

            newInst = block->insertNewInstAfter(inst, PCIT::MOVE_MATTR5_MATTR5);

            newInst->code[1] = inst->code[1];
            newInst->code[2] = inst->code[2];
            newInst->code[3] = inst->code[3];
            newInst->code[4] = inst->code[4];
            newInst->code[5] = inst->code[5];

            newInst->code[6] = 1;
            newInst->code[7] = *off + 2;            // Up 2 to get to str itself
            newInst->code[8] = -1;                  // voa
            newInst->code[9] = op1->getVcMaxLen();  // tgt/src share max vc len
            newInst->code[10] = comboLen;
 
            NADELETEBASIC(newStr, heap_);
          }
          else {
            CollIndex* off = addConstant((void*)fromStr, tgtLen, 1);

            newInst =
              block->insertNewInstAfter(inst, PCIT::MOVE_MBIN8_MBIN8_IBIN32S);

            newInst->code[1] = inst->code[1];
            newInst->code[2] = inst->code[2];
            newInst->code[3] = 1;
            newInst->code[4] = *off;
            newInst->code[5] = tgtLen;
          }

          newInst->reloadOperands(this);

          // Attempt to update reaching defs info.
          if (rDefsAvailable)
            updateReachingDefs(block, op1->getBvIndex(), inst, newInst);

          block->deleteInst(inst);
          inst = newInst;

          // Cleanup if needed.
          if (fromStrAllocated)
            NADELETEBASIC(fromStr, heap_);

          break;
        }

        default:
          break;
      }
    }

    default:
      break;
  }

  return inst;
}
