// 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); }
Value *ConstantOffsetExtractor::removeConstOffset(unsigned ChainIndex) { if (ChainIndex == 0) { assert(isa<ConstantInt>(UserChain[ChainIndex])); return ConstantInt::getNullValue(UserChain[ChainIndex]->getType()); } BinaryOperator *BO = cast<BinaryOperator>(UserChain[ChainIndex]); unsigned OpNo = (BO->getOperand(0) == UserChain[ChainIndex - 1] ? 0 : 1); assert(BO->getOperand(OpNo) == UserChain[ChainIndex - 1]); Value *NextInChain = removeConstOffset(ChainIndex - 1); Value *TheOther = BO->getOperand(1 - OpNo); // If NextInChain is 0 and not the LHS of a sub, we can simplify the // sub-expression to be just TheOther. if (ConstantInt *CI = dyn_cast<ConstantInt>(NextInChain)) { if (CI->isZero() && !(BO->getOpcode() == Instruction::Sub && OpNo == 0)) return TheOther; } if (BO->getOpcode() == Instruction::Or) { // Rebuild "or" as "add", because "or" may be invalid for the new // epxression. // // For instance, given // a | (b + 5) where a and b + 5 have no common bits, // we can extract 5 as the constant offset. // // However, reusing the "or" in the new index would give us // (a | b) + 5 // which does not equal a | (b + 5). // // Replacing the "or" with "add" is fine, because // a | (b + 5) = a + (b + 5) = (a + b) + 5 if (OpNo == 0) { return BinaryOperator::CreateAdd(NextInChain, TheOther, BO->getName(), IP); } else { return BinaryOperator::CreateAdd(TheOther, NextInChain, BO->getName(), IP); } } // We can reuse BO in this case, because the new expression shares the same // instruction type and BO is used at most once. assert(BO->getNumUses() <= 1 && "distributeExtsAndCloneChain clones each BinaryOperator in " "UserChain, so no one should be used more than " "once"); BO->setOperand(OpNo, NextInChain); BO->setHasNoSignedWrap(false); BO->setHasNoUnsignedWrap(false); // Make sure it appears after all instructions we've inserted so far. BO->moveBefore(IP); return BO; }
/// SimplifyDivRemOfSelect - Try to fold a divide or remainder of a select /// instruction. bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) { SelectInst *SI = cast<SelectInst>(I.getOperand(1)); // div/rem X, (Cond ? 0 : Y) -> div/rem X, Y int NonNullOperand = -1; if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1))) if (ST->isNullValue()) NonNullOperand = 2; // div/rem X, (Cond ? Y : 0) -> div/rem X, Y if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2))) if (ST->isNullValue()) NonNullOperand = 1; if (NonNullOperand == -1) return false; Value *SelectCond = SI->getOperand(0); // Change the div/rem to use 'Y' instead of the select. I.setOperand(1, SI->getOperand(NonNullOperand)); // Okay, we know we replace the operand of the div/rem with 'Y' with no // problem. However, the select, or the condition of the select may have // multiple uses. Based on our knowledge that the operand must be non-zero, // propagate the known value for the select into other uses of it, and // propagate a known value of the condition into its other users. // If the select and condition only have a single use, don't bother with this, // early exit. if (SI->use_empty() && SelectCond->hasOneUse()) return true; // Scan the current block backward, looking for other uses of SI. BasicBlock::iterator BBI = &I, BBFront = I.getParent()->begin(); while (BBI != BBFront) { --BBI; // If we found a call to a function, we can't assume it will return, so // information from below it cannot be propagated above it. if (isa<CallInst>(BBI) && !isa<IntrinsicInst>(BBI)) break; // Replace uses of the select or its condition with the known values. for (Instruction::op_iterator I = BBI->op_begin(), E = BBI->op_end(); I != E; ++I) { if (*I == SI) { *I = SI->getOperand(NonNullOperand); Worklist.Add(BBI); } else if (*I == SelectCond) { *I = NonNullOperand == 1 ? ConstantInt::getTrue(BBI->getContext()) : ConstantInt::getFalse(BBI->getContext()); Worklist.Add(BBI); } } // If we past the instruction, quit looking for it. if (&*BBI == SI) SI = 0; if (&*BBI == SelectCond) SelectCond = 0; // If we ran out of things to eliminate, break out of the loop. if (SelectCond == 0 && SI == 0) break; } return true; }
/// GetShiftedValue - When CanEvaluateShifted returned true for an expression, /// this value inserts the new computation that produces the shifted value. static Value *GetShiftedValue(Value *V, unsigned NumBits, bool isLeftShift, InstCombiner &IC) { // We can always evaluate constants shifted. if (Constant *C = dyn_cast<Constant>(V)) { if (isLeftShift) V = IC.Builder->CreateShl(C, NumBits); else V = IC.Builder->CreateLShr(C, NumBits); // If we got a constantexpr back, try to simplify it with TD info. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) V = ConstantFoldConstantExpression(CE, IC.getDataLayout(), IC.getTargetLibraryInfo()); return V; } Instruction *I = cast<Instruction>(V); IC.Worklist.Add(I); switch (I->getOpcode()) { default: llvm_unreachable("Inconsistency with CanEvaluateShifted"); case Instruction::And: case Instruction::Or: case Instruction::Xor: // Bitwise operators can all arbitrarily be arbitrarily evaluated shifted. I->setOperand(0, GetShiftedValue(I->getOperand(0), NumBits,isLeftShift,IC)); I->setOperand(1, GetShiftedValue(I->getOperand(1), NumBits,isLeftShift,IC)); return I; case Instruction::Shl: { BinaryOperator *BO = cast<BinaryOperator>(I); unsigned TypeWidth = BO->getType()->getScalarSizeInBits(); // We only accept shifts-by-a-constant in CanEvaluateShifted. ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1)); // We can always fold shl(c1)+shl(c2) -> shl(c1+c2). if (isLeftShift) { // If this is oversized composite shift, then unsigned shifts get 0. unsigned NewShAmt = NumBits+CI->getZExtValue(); if (NewShAmt >= TypeWidth) return Constant::getNullValue(I->getType()); BO->setOperand(1, ConstantInt::get(BO->getType(), NewShAmt)); BO->setHasNoUnsignedWrap(false); BO->setHasNoSignedWrap(false); return I; } // We turn shl(c)+lshr(c) -> and(c2) if the input doesn't already have // zeros. if (CI->getValue() == NumBits) { APInt Mask(APInt::getLowBitsSet(TypeWidth, TypeWidth - NumBits)); V = IC.Builder->CreateAnd(BO->getOperand(0), ConstantInt::get(BO->getContext(), Mask)); if (Instruction *VI = dyn_cast<Instruction>(V)) { VI->moveBefore(BO); VI->takeName(BO); } return V; } // We turn shl(c1)+shr(c2) -> shl(c3)+and(c4), but only when we know that // the and won't be needed. assert(CI->getZExtValue() > NumBits); BO->setOperand(1, ConstantInt::get(BO->getType(), CI->getZExtValue() - NumBits)); BO->setHasNoUnsignedWrap(false); BO->setHasNoSignedWrap(false); return BO; } case Instruction::LShr: { BinaryOperator *BO = cast<BinaryOperator>(I); unsigned TypeWidth = BO->getType()->getScalarSizeInBits(); // We only accept shifts-by-a-constant in CanEvaluateShifted. ConstantInt *CI = cast<ConstantInt>(BO->getOperand(1)); // We can always fold lshr(c1)+lshr(c2) -> lshr(c1+c2). if (!isLeftShift) { // If this is oversized composite shift, then unsigned shifts get 0. unsigned NewShAmt = NumBits+CI->getZExtValue(); if (NewShAmt >= TypeWidth) return Constant::getNullValue(BO->getType()); BO->setOperand(1, ConstantInt::get(BO->getType(), NewShAmt)); BO->setIsExact(false); return I; } // We turn lshr(c)+shl(c) -> and(c2) if the input doesn't already have // zeros. if (CI->getValue() == NumBits) { APInt Mask(APInt::getHighBitsSet(TypeWidth, TypeWidth - NumBits)); V = IC.Builder->CreateAnd(I->getOperand(0), ConstantInt::get(BO->getContext(), Mask)); if (Instruction *VI = dyn_cast<Instruction>(V)) { VI->moveBefore(I); VI->takeName(I); } return V; } // We turn lshr(c1)+shl(c2) -> lshr(c3)+and(c4), but only when we know that // the and won't be needed. assert(CI->getZExtValue() > NumBits); BO->setOperand(1, ConstantInt::get(BO->getType(), CI->getZExtValue() - NumBits)); BO->setIsExact(false); return BO; } case Instruction::Select: I->setOperand(1, GetShiftedValue(I->getOperand(1), NumBits,isLeftShift,IC)); I->setOperand(2, GetShiftedValue(I->getOperand(2), NumBits,isLeftShift,IC)); return I; case Instruction::PHI: { // We can change a phi if we can change all operands. Note that we never // get into trouble with cyclic PHIs here because we only consider // instructions with a single use. PHINode *PN = cast<PHINode>(I); for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) PN->setIncomingValue(i, GetShiftedValue(PN->getIncomingValue(i), NumBits, isLeftShift, IC)); return PN; } } }
/* BalanceTree(root I) worklist: set leaves: vector mark I visited Push(worklist, Ra. Rb) // find all the leaves of the tree rooted at I while worklist not empty // look backwards following def-use from use T = ’R1 <- op1, Ra1, Rb1’ = Def(Pop(worklist)) if T is a root // balance computes weight in this case if T not visited BalanceTree(T) SortedInsert(leaves, T, Weight(T)) else if op(T) == op(I) // add uses to worklist Push(worklist, Ra1, Rb1) */ BinaryOperator* balanceTree(BinaryOperator* root, std::map<Instruction*,bool>& visitMap, std::vector<BinaryOperator*>& roots) { assert(root); if(visitMap[root]) return NULL; std::list<Value*> worklist; std::set<std::pair<int,Value*>,weight_less_than> leaves; visitMap[root] = true; worklist.push_back( root->getOperand(0) ); worklist.push_back( root->getOperand(1) ); while( !worklist.empty() ) { Value* v = worklist.front(); worklist.pop_front(); assert(v); BinaryOperator* T = dynamic_cast<BinaryOperator*>(v); if( T and std::find(roots.begin(), roots.end(), T) != roots.end() ) // T is a binary operator that exists in the root list { if( !visitMap[T] ) //if we havent visited it, replace it with its balanced version { T = balanceTree(T, visitMap, roots); } if( !T ) { INTERNAL_ERROR("balanceTree(" << *root << ") failed while attempting to balance leaf node " << *v << "; balance returned NULL!\n"); } assert( T and "Balancing operation that was a root resulted in NULL being returned from balance function!" ); leaves.insert(std::pair<int,Instruction*>(calculateWeight(T, roots), T)); } else if( T and !isDifferentOperation(T, root) ) //if T isnt a root, and isnt a different operation than our root, we need to process it { worklist.push_back( T->getOperand(0) ); worklist.push_back( T->getOperand(1) ); //remove all of the signed, name, and size call uses for(Value::use_iterator UI = T->use_begin(); UI != T->use_end();) { CallInst* CI = dynamic_cast<CallInst*>(*UI); if( isROCCCFunctionCall(CI, ROCCCNames::VariableName) or isROCCCFunctionCall(CI, ROCCCNames::VariableSize) or isROCCCFunctionCall(CI, ROCCCNames::VariableSigned) ) { CI->eraseFromParent(); UI = T->use_begin(); } else ++UI; } } else //T isnt a BinaryOperator, or isn't a root, or is a different operation than our root - just add it as a single leaf { leaves.insert(std::pair<int,Value*>(1, v)); } } /* // construct a balanced tree from leaves while size(leaves) > 1 Ra1 = Dequeue(leaves) Rb1 = Dequeue(leaves) T = ’R1 <- op1, Ra1, Rb1’ insert T before I Weight(R1) = Weight(Ra1) + Weight(Rb1) SortedInsert(leaves, R1, Weight(R1)) */ while( leaves.size() > 1 ) { std::pair<int,Value*> Ra1 = *leaves.begin(); leaves.erase(leaves.begin()); std::pair<int,Value*> Rb1 = *leaves.begin(); leaves.erase(leaves.begin()); int weight = Ra1.first + Rb1.first; //workaround to create a binary instruction with different operand types; create with undefs, then replace BinaryOperator* T = BinaryOperator::create(root->getOpcode(), UndefValue::get(root->getType()), UndefValue::get(root->getType()), "tmp", root); T->setOperand(0, Ra1.second); T->setOperand(1, Rb1.second); setSizeInBits(T, getSizeInBits(root)); setValueSigned(T, isValueSigned(root)); leaves.insert(std::pair<int,Value*>(weight, T)); } BinaryOperator* last_inserted = NULL; if(leaves.begin() != leaves.end()) last_inserted = dynamic_cast<BinaryOperator*>(leaves.begin()->second); if( last_inserted ) { setValueName(last_inserted, getValueName(root)); root->uncheckedReplaceAllUsesWith(last_inserted); std::string name = root->getName(); root->eraseFromParent(); last_inserted->setName(name); roots.erase(std::find(roots.begin(), roots.end(), root)); roots.push_back(last_inserted); visitMap[last_inserted] = true; } return last_inserted; }