// reassociate the expression from ((? op A) op B) to (? op (A op B))
if (ShouldApply) {
BasicBlock *BB = Root.getParent();
- // All of the instructions have a single use and have no side-effects,
- // because of this, we can pull them all into the current basic block.
- if (LHSI->getParent() != BB) {
- // Move all of the instructions from root to LHSI into the current
- // block.
- Instruction *TmpLHSI = cast<Instruction>(Root.getOperand(0));
- Instruction *LastUse = &Root;
- while (TmpLHSI->getParent() == BB) {
- LastUse = TmpLHSI;
- TmpLHSI = cast<Instruction>(TmpLHSI->getOperand(0));
- }
-
- // Loop over all of the instructions in other blocks, moving them into
- // the current one.
- Value *TmpLHS = TmpLHSI;
- do {
- TmpLHSI = cast<Instruction>(TmpLHS);
- // Remove from current block...
- TmpLHSI->getParent()->getInstList().remove(TmpLHSI);
- // Insert before the last instruction...
- BB->getInstList().insert(LastUse, TmpLHSI);
- TmpLHS = TmpLHSI->getOperand(0);
- } while (TmpLHSI != LHSI);
- }
// Now all of the instructions are in the current basic block, go ahead
// and perform the reassociation.
// Make what used to be the LHS of the root be the user of the root...
Value *ExtraOperand = TmpLHSI->getOperand(1);
- if (&Root != TmpLHSI)
- Root.replaceAllUsesWith(TmpLHSI); // Users now use TmpLHSI
- else {
+ if (&Root == TmpLHSI) {
Root.replaceAllUsesWith(Constant::getNullValue(TmpLHSI->getType()));
return 0;
}
+ Root.replaceAllUsesWith(TmpLHSI); // Users now use TmpLHSI
TmpLHSI->setOperand(1, &Root); // TmpLHSI now uses the root
- BB->getInstList().remove(&Root); // Remove root from the BB
- BB->getInstList().insert(TmpLHSI, &Root); // Insert root before TmpLHSI
+ TmpLHSI->getParent()->getInstList().remove(TmpLHSI);
+ BasicBlock::iterator ARI = &Root; ++ARI;
+ BB->getInstList().insert(ARI, TmpLHSI); // Move TmpLHSI to after Root
+ ARI = Root;
// Now propagate the ExtraOperand down the chain of instructions until we
// get to LHSI.
while (TmpLHSI != LHSI) {
Instruction *NextLHSI = cast<Instruction>(TmpLHSI->getOperand(0));
+ // Move the instruction to immediately before the chain we are
+ // constructing to avoid breaking dominance properties.
+ NextLHSI->getParent()->getInstList().remove(NextLHSI);
+ BB->getInstList().insert(ARI, NextLHSI);
+ ARI = NextLHSI;
+
Value *NextOp = NextLHSI->getOperand(1);
NextLHSI->setOperand(1, ExtraOperand);
TmpLHSI = NextLHSI;
}
Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
- // div X, 1 == X
if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
+ // div X, 1 == X
if (RHS->equalsInt(1))
return ReplaceInstUsesWith(I, I.getOperand(0));
+ // div X, -1 == -X
+ if (RHS->isAllOnesValue())
+ return BinaryOperator::createNeg(I.getOperand(0));
+
// Check to see if this is an unsigned division with an exact power of 2,
// if so, convert to a right shift.
if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
// obvious.
Value *Op = GEP.getOperand(i);
if (Op->getType()->getPrimitiveSize() > TD->getPointerSize())
- if (!isa<Constant>(Op)) {
+ if (Constant *C = dyn_cast<Constant>(Op)) {
+ GEP.setOperand(i, ConstantExpr::getCast(C, TD->getIntPtrType()));
+ MadeChange = true;
+ } else {
Op = InsertNewInstBefore(new CastInst(Op, TD->getIntPtrType(),
Op->getName()), GEP);
GEP.setOperand(i, Op);
bool Changed = false;
TD = &getAnalysis<TargetData>();
- WorkList.insert(WorkList.end(), inst_begin(F), inst_end(F));
+ for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
+ WorkList.push_back(&*i);
+ }
+
while (!WorkList.empty()) {
Instruction *I = WorkList.back(); // Get an instruction from the worklist