/// 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); }