示例#1
0
/// OptimizeAdd - Optimize a series of operands to an 'add' instruction.  This
/// optimizes based on identities.  If it can be reduced to a single Value, it
/// is returned, otherwise the Ops list is mutated as necessary.
Value *Reassociate::OptimizeAdd(Instruction *I,
                                SmallVectorImpl<ValueEntry> &Ops) {
  // Scan the operand lists looking for X and -X pairs.  If we find any, we
  // can simplify the expression. X+-X == 0.  While we're at it, scan for any
  // duplicates.  We want to canonicalize Y+Y+Y+Z -> 3*Y+Z.
  //
  // TODO: We could handle "X + ~X" -> "-1" if we wanted, since "-X = ~X+1".
  //
  for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
    Value *TheOp = Ops[i].Op;
    // Check to see if we've seen this operand before.  If so, we factor all
    // instances of the operand together.  Due to our sorting criteria, we know
    // that these need to be next to each other in the vector.
    if (i+1 != Ops.size() && Ops[i+1].Op == TheOp) {
      // Rescan the list, remove all instances of this operand from the expr.
      unsigned NumFound = 0;
      do {
        Ops.erase(Ops.begin()+i);
        ++NumFound;
      } while (i != Ops.size() && Ops[i].Op == TheOp);
      
      DEBUG(errs() << "\nFACTORING [" << NumFound << "]: " << *TheOp << '\n');
      ++NumFactor;
      
      // Insert a new multiply.
      Value *Mul = ConstantInt::get(cast<IntegerType>(I->getType()), NumFound);
      Mul = BinaryOperator::CreateMul(TheOp, Mul, "factor", I);
      
      // Now that we have inserted a multiply, optimize it. This allows us to
      // handle cases that require multiple factoring steps, such as this:
      // (X*2) + (X*2) + (X*2) -> (X*2)*3 -> X*6
      RedoInsts.push_back(Mul);
      
      // If every add operand was a duplicate, return the multiply.
      if (Ops.empty())
        return Mul;
      
      // Otherwise, we had some input that didn't have the dupe, such as
      // "A + A + B" -> "A*2 + B".  Add the new multiply to the list of
      // things being added by this operation.
      Ops.insert(Ops.begin(), ValueEntry(getRank(Mul), Mul));
      
      --i;
      e = Ops.size();
      continue;
    }
    
    // Check for X and -X in the operand list.
    if (!BinaryOperator::isNeg(TheOp))
      continue;
    
    Value *X = BinaryOperator::getNegArgument(TheOp);
    unsigned FoundX = FindInOperandList(Ops, i, X);
    if (FoundX == i)
      continue;
    
    // Remove X and -X from the operand list.
    if (Ops.size() == 2)
      return Constant::getNullValue(X->getType());
    
    Ops.erase(Ops.begin()+i);
    if (i < FoundX)
      --FoundX;
    else
      --i;   // Need to back up an extra one.
    Ops.erase(Ops.begin()+FoundX);
    ++NumAnnihil;
    --i;     // Revisit element.
    e -= 2;  // Removed two elements.
  }
  
  // Scan the operand list, checking to see if there are any common factors
  // between operands.  Consider something like A*A+A*B*C+D.  We would like to
  // reassociate this to A*(A+B*C)+D, which reduces the number of multiplies.
  // To efficiently find this, we count the number of times a factor occurs
  // for any ADD operands that are MULs.
  DenseMap<Value*, unsigned> FactorOccurrences;
  
  // Keep track of each multiply we see, to avoid triggering on (X*4)+(X*4)
  // where they are actually the same multiply.
  unsigned MaxOcc = 0;
  Value *MaxOccVal = 0;
  for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
    BinaryOperator *BOp = dyn_cast<BinaryOperator>(Ops[i].Op);
    if (BOp == 0 || BOp->getOpcode() != Instruction::Mul || !BOp->use_empty())
      continue;
    
    // Compute all of the factors of this added value.
    SmallVector<Value*, 8> Factors;
    FindSingleUseMultiplyFactors(BOp, Factors, Ops, true);
    assert(Factors.size() > 1 && "Bad linearize!");
    
    // Add one to FactorOccurrences for each unique factor in this op.
    SmallPtrSet<Value*, 8> Duplicates;
    for (unsigned i = 0, e = Factors.size(); i != e; ++i) {
      Value *Factor = Factors[i];
      if (!Duplicates.insert(Factor)) continue;
      
      unsigned Occ = ++FactorOccurrences[Factor];
      if (Occ > MaxOcc) { MaxOcc = Occ; MaxOccVal = Factor; }
      
      // If Factor is a negative constant, add the negated value as a factor
      // because we can percolate the negate out.  Watch for minint, which
      // cannot be positivified.
      if (ConstantInt *CI = dyn_cast<ConstantInt>(Factor))
        if (CI->isNegative() && !CI->isMinValue(true)) {
          Factor = ConstantInt::get(CI->getContext(), -CI->getValue());
          assert(!Duplicates.count(Factor) &&
                 "Shouldn't have two constant factors, missed a canonicalize");
          
          unsigned Occ = ++FactorOccurrences[Factor];
          if (Occ > MaxOcc) { MaxOcc = Occ; MaxOccVal = Factor; }
        }
    }
  }
  
  // If any factor occurred more than one time, we can pull it out.
  if (MaxOcc > 1) {
    DEBUG(errs() << "\nFACTORING [" << MaxOcc << "]: " << *MaxOccVal << '\n');
    ++NumFactor;

    // Create a new instruction that uses the MaxOccVal twice.  If we don't do
    // this, we could otherwise run into situations where removing a factor
    // from an expression will drop a use of maxocc, and this can cause 
    // RemoveFactorFromExpression on successive values to behave differently.
    Instruction *DummyInst = BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal);
    SmallVector<WeakVH, 4> NewMulOps;
    for (unsigned i = 0; i != Ops.size(); ++i) {
      // Only try to remove factors from expressions we're allowed to.
      BinaryOperator *BOp = dyn_cast<BinaryOperator>(Ops[i].Op);
      if (BOp == 0 || BOp->getOpcode() != Instruction::Mul || !BOp->use_empty())
        continue;
      
      if (Value *V = RemoveFactorFromExpression(Ops[i].Op, MaxOccVal)) {
        // The factorized operand may occur several times.  Convert them all in
        // one fell swoop.
        for (unsigned j = Ops.size(); j != i;) {
          --j;
          if (Ops[j].Op == Ops[i].Op) {
            NewMulOps.push_back(V);
            Ops.erase(Ops.begin()+j);
          }
        }
        --i;
      }
    }
    
    // No need for extra uses anymore.
    delete DummyInst;

    unsigned NumAddedValues = NewMulOps.size();
    Value *V = EmitAddTreeOfValues(I, NewMulOps);

    // Now that we have inserted the add tree, optimize it. This allows us to
    // handle cases that require multiple factoring steps, such as this:
    // A*A*B + A*A*C   -->   A*(A*B+A*C)   -->   A*(A*(B+C))
    assert(NumAddedValues > 1 && "Each occurrence should contribute a value");
    (void)NumAddedValues;
    V = ReassociateExpression(cast<BinaryOperator>(V));

    // Create the multiply.
    Value *V2 = BinaryOperator::CreateMul(V, MaxOccVal, "tmp", I);

    // Rerun associate on the multiply in case the inner expression turned into
    // a multiply.  We want to make sure that we keep things in canonical form.
    V2 = ReassociateExpression(cast<BinaryOperator>(V2));
    
    // If every add operand included the factor (e.g. "A*B + A*C"), then the
    // entire result expression is just the multiply "A*(B+C)".
    if (Ops.empty())
      return V2;
    
    // Otherwise, we had some input that didn't have the factor, such as
    // "A*B + A*C + D" -> "A*(B+C) + D".  Add the new multiply to the list of
    // things being added by this operation.
    Ops.insert(Ops.begin(), ValueEntry(getRank(V2), V2));
  }
  
  return 0;
}