// Given an expression of the form '(A+B)+(D+C)', turn it into '(((A+B)+C)+D)'. // Note that if D is also part of the expression tree that we recurse to // linearize it as well. Besides that case, this does not recurse into A,B, or // C. void Reassociate::LinearizeExpr(BinaryOperator *I) { BinaryOperator *LHS = cast<BinaryOperator>(I->getOperand(0)); BinaryOperator *RHS = cast<BinaryOperator>(I->getOperand(1)); assert(isReassociableOp(LHS, I->getOpcode()) && isReassociableOp(RHS, I->getOpcode()) && "Not an expression that needs linearization?"); DEBUG(dbgs() << "Linear" << *LHS << '\n' << *RHS << '\n' << *I << '\n'); // Move the RHS instruction to live immediately before I, avoiding breaking // dominator properties. RHS->moveBefore(I); // Move operands around to do the linearization. I->setOperand(1, RHS->getOperand(0)); RHS->setOperand(0, LHS); I->setOperand(0, RHS); // Conservatively clear all the optional flags, which may not hold // after the reassociation. I->clearSubclassOptionalData(); LHS->clearSubclassOptionalData(); RHS->clearSubclassOptionalData(); ++NumLinear; MadeChange = true; DEBUG(dbgs() << "Linearized: " << *I << '\n'); // If D is part of this expression tree, tail recurse. if (isReassociableOp(I->getOperand(1), I->getOpcode())) LinearizeExpr(I); }