X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FInstructionCombining.cpp;h=92b7f1a39bc719a7c367ff8fadc1463d8f10dc2e;hb=6ffe551f657c948d6a473a198ecbd1188bf9ce45;hp=23d0f5ffcc78f78f4f9b6431cbadd085fc2a9dd1;hpb=66331a4e3312af6cc07b8c583565cc53d5b1516a;p=oota-llvm.git diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 23d0f5ffcc7..92b7f1a39bc 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -397,30 +397,6 @@ Instruction *AssociativeOpt(BinaryOperator &Root, const Functor &F) { // 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(Root.getOperand(0)); - Instruction *LastUse = &Root; - while (TmpLHSI->getParent() == BB) { - LastUse = TmpLHSI; - TmpLHSI = cast(TmpLHSI->getOperand(0)); - } - - // Loop over all of the instructions in other blocks, moving them into - // the current one. - Value *TmpLHS = TmpLHSI; - do { - TmpLHSI = cast(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. @@ -431,20 +407,27 @@ Instruction *AssociativeOpt(BinaryOperator &Root, const Functor &F) { // 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(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; @@ -866,11 +849,15 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { } Instruction *InstCombiner::visitDiv(BinaryOperator &I) { - // div X, 1 == X if (ConstantInt *RHS = dyn_cast(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(RHS)) @@ -2209,6 +2196,28 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { return new CastInst(NotCond, SI.getType()); } } + + // See if we are selecting two values based on a comparison of the two values. + if (SetCondInst *SCI = dyn_cast(CondVal)) { + if (SCI->getOperand(0) == TrueVal && SCI->getOperand(1) == FalseVal) { + // Transform (X == Y) ? X : Y -> Y + if (SCI->getOpcode() == Instruction::SetEQ) + return ReplaceInstUsesWith(SI, FalseVal); + // Transform (X != Y) ? X : Y -> X + if (SCI->getOpcode() == Instruction::SetNE) + return ReplaceInstUsesWith(SI, TrueVal); + // NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc. + + } else if (SCI->getOperand(0) == FalseVal && SCI->getOperand(1) == TrueVal){ + // Transform (X == Y) ? Y : X -> X + if (SCI->getOpcode() == Instruction::SetEQ) + return ReplaceInstUsesWith(SI, FalseVal); + // Transform (X != Y) ? Y : X -> Y + if (SCI->getOpcode() == Instruction::SetNE) + return ReplaceInstUsesWith(SI, TrueVal); + // NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc. + } + } // See if we can fold the select into one of our operands. if (SI.getType()->isInteger()) { @@ -2575,7 +2584,10 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { // obvious. Value *Op = GEP.getOperand(i); if (Op->getType()->getPrimitiveSize() > TD->getPointerSize()) - if (!isa(Op)) { + if (Constant *C = dyn_cast(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); @@ -2831,8 +2843,11 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { Value *Op = LI.getOperand(0); if (LI.isVolatile()) return 0; - if (ConstantPointerRef *CPR = dyn_cast(Op)) - Op = CPR->getValue(); + if (Constant *C = dyn_cast(Op)) + if (C->isNullValue()) // load null -> 0 + return ReplaceInstUsesWith(LI, Constant::getNullValue(LI.getType())); + else if (ConstantPointerRef *CPR = dyn_cast(C)) + Op = CPR->getValue(); // Instcombine load (constant global) into the value loaded... if (GlobalVariable *GV = dyn_cast(Op)) @@ -2919,7 +2934,10 @@ bool InstCombiner::runOnFunction(Function &F) { bool Changed = false; TD = &getAnalysis(); - 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