示例#1
0
/// ReassociateInst - Inspect and reassociate the instruction at the
/// given position, post-incrementing the position.
void Reassociate::ReassociateInst(BasicBlock::iterator &BBI) {
  Instruction *BI = BBI++;
  if (BI->getOpcode() == Instruction::Shl &&
      isa<ConstantInt>(BI->getOperand(1)))
    if (Instruction *NI = ConvertShiftToMul(BI, ValueRankMap)) {
      MadeChange = true;
      BI = NI;
    }

  // Reject cases where it is pointless to do this.
  if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPointTy() || 
      BI->getType()->isVectorTy())
    return;  // Floating point ops are not associative.

  // Do not reassociate boolean (i1) expressions.  We want to preserve the
  // original order of evaluation for short-circuited comparisons that
  // SimplifyCFG has folded to AND/OR expressions.  If the expression
  // is not further optimized, it is likely to be transformed back to a
  // short-circuited form for code gen, and the source order may have been
  // optimized for the most likely conditions.
  if (BI->getType()->isIntegerTy(1))
    return;

  // If this is a subtract instruction which is not already in negate form,
  // see if we can convert it to X+-Y.
  if (BI->getOpcode() == Instruction::Sub) {
    if (ShouldBreakUpSubtract(BI)) {
      BI = BreakUpSubtract(BI, ValueRankMap);
      // Reset the BBI iterator in case BreakUpSubtract changed the
      // instruction it points to.
      BBI = BI;
      ++BBI;
      MadeChange = true;
    } else if (BinaryOperator::isNeg(BI)) {
      // Otherwise, this is a negation.  See if the operand is a multiply tree
      // and if this is not an inner node of a multiply tree.
      if (isReassociableOp(BI->getOperand(1), Instruction::Mul) &&
          (!BI->hasOneUse() ||
           !isReassociableOp(BI->use_back(), Instruction::Mul))) {
        BI = LowerNegateToMultiply(BI, ValueRankMap);
        MadeChange = true;
      }
    }
  }

  // If this instruction is a commutative binary operator, process it.
  if (!BI->isAssociative()) return;
  BinaryOperator *I = cast<BinaryOperator>(BI);

  // If this is an interior node of a reassociable tree, ignore it until we
  // get to the root of the tree, to avoid N^2 analysis.
  if (I->hasOneUse() && isReassociableOp(I->use_back(), I->getOpcode()))
    return;

  // If this is an add tree that is used by a sub instruction, ignore it 
  // until we process the subtract.
  if (I->hasOneUse() && I->getOpcode() == Instruction::Add &&
      cast<Instruction>(I->use_back())->getOpcode() == Instruction::Sub)
    return;

  ReassociateExpression(I);
}