/// 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; } } }
void Lint::visitShl(BinaryOperator &I) { if (ConstantInt *CI = dyn_cast<ConstantInt>(findValue(I.getOperand(1), /*OffsetOk=*/false))) Assert(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()), "Undefined result: Shift count out of range", &I); }
bool AlignmentFromAssumptionsPass::extractAlignmentInfo(CallInst *I, Value *&AAPtr, const SCEV *&AlignSCEV, const SCEV *&OffSCEV) { // An alignment assume must be a statement about the least-significant // bits of the pointer being zero, possibly with some offset. ICmpInst *ICI = dyn_cast<ICmpInst>(I->getArgOperand(0)); if (!ICI) return false; // This must be an expression of the form: x & m == 0. if (ICI->getPredicate() != ICmpInst::ICMP_EQ) return false; // Swap things around so that the RHS is 0. Value *CmpLHS = ICI->getOperand(0); Value *CmpRHS = ICI->getOperand(1); const SCEV *CmpLHSSCEV = SE->getSCEV(CmpLHS); const SCEV *CmpRHSSCEV = SE->getSCEV(CmpRHS); if (CmpLHSSCEV->isZero()) std::swap(CmpLHS, CmpRHS); else if (!CmpRHSSCEV->isZero()) return false; BinaryOperator *CmpBO = dyn_cast<BinaryOperator>(CmpLHS); if (!CmpBO || CmpBO->getOpcode() != Instruction::And) return false; // Swap things around so that the right operand of the and is a constant // (the mask); we cannot deal with variable masks. Value *AndLHS = CmpBO->getOperand(0); Value *AndRHS = CmpBO->getOperand(1); const SCEV *AndLHSSCEV = SE->getSCEV(AndLHS); const SCEV *AndRHSSCEV = SE->getSCEV(AndRHS); if (isa<SCEVConstant>(AndLHSSCEV)) { std::swap(AndLHS, AndRHS); std::swap(AndLHSSCEV, AndRHSSCEV); } const SCEVConstant *MaskSCEV = dyn_cast<SCEVConstant>(AndRHSSCEV); if (!MaskSCEV) return false; // The mask must have some trailing ones (otherwise the condition is // trivial and tells us nothing about the alignment of the left operand). unsigned TrailingOnes = MaskSCEV->getAPInt().countTrailingOnes(); if (!TrailingOnes) return false; // Cap the alignment at the maximum with which LLVM can deal (and make sure // we don't overflow the shift). uint64_t Alignment; TrailingOnes = std::min(TrailingOnes, unsigned(sizeof(unsigned) * CHAR_BIT - 1)); Alignment = std::min(1u << TrailingOnes, +Value::MaximumAlignment); Type *Int64Ty = Type::getInt64Ty(I->getParent()->getParent()->getContext()); AlignSCEV = SE->getConstant(Int64Ty, Alignment); // The LHS might be a ptrtoint instruction, or it might be the pointer // with an offset. AAPtr = nullptr; OffSCEV = nullptr; if (PtrToIntInst *PToI = dyn_cast<PtrToIntInst>(AndLHS)) { AAPtr = PToI->getPointerOperand(); OffSCEV = SE->getZero(Int64Ty); } else if (const SCEVAddExpr* AndLHSAddSCEV = dyn_cast<SCEVAddExpr>(AndLHSSCEV)) { // Try to find the ptrtoint; subtract it and the rest is the offset. for (SCEVAddExpr::op_iterator J = AndLHSAddSCEV->op_begin(), JE = AndLHSAddSCEV->op_end(); J != JE; ++J) if (const SCEVUnknown *OpUnk = dyn_cast<SCEVUnknown>(*J)) if (PtrToIntInst *PToI = dyn_cast<PtrToIntInst>(OpUnk->getValue())) { AAPtr = PToI->getPointerOperand(); OffSCEV = SE->getMinusSCEV(AndLHSAddSCEV, *J); break; } } if (!AAPtr) return false; // Sign extend the offset to 64 bits (so that it is like all of the other // expressions). unsigned OffSCEVBits = OffSCEV->getType()->getPrimitiveSizeInBits(); if (OffSCEVBits < 64) OffSCEV = SE->getSignExtendExpr(OffSCEV, Int64Ty); else if (OffSCEVBits > 64) return false; AAPtr = AAPtr->stripPointerCasts(); return true; }
bool LazyValueInfoCache::solveBlockValue(Value *Val, BasicBlock *BB) { if (isa<Constant>(Val)) return true; ValueCacheEntryTy &Cache = lookup(Val); SeenBlocks.insert(BB); LVILatticeVal &BBLV = Cache[BB]; // OverDefinedCacheUpdater is a helper object that will update // the OverDefinedCache for us when this method exits. Make sure to // call markResult on it as we exist, passing a bool to indicate if the // cache needs updating, i.e. if we have solve a new value or not. OverDefinedCacheUpdater ODCacheUpdater(Val, BB, BBLV, this); // If we've already computed this block's value, return it. if (!BBLV.isUndefined()) { DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << BBLV <<'\n'); // Since we're reusing a cached value here, we don't need to update the // OverDefinedCahce. The cache will have been properly updated // whenever the cached value was inserted. ODCacheUpdater.markResult(false); return true; } // Otherwise, this is the first time we're seeing this block. Reset the // lattice value to overdefined, so that cycles will terminate and be // conservatively correct. BBLV.markOverdefined(); Instruction *BBI = dyn_cast<Instruction>(Val); if (BBI == 0 || BBI->getParent() != BB) { return ODCacheUpdater.markResult(solveBlockValueNonLocal(BBLV, Val, BB)); } if (PHINode *PN = dyn_cast<PHINode>(BBI)) { return ODCacheUpdater.markResult(solveBlockValuePHINode(BBLV, PN, BB)); } if (AllocaInst *AI = dyn_cast<AllocaInst>(BBI)) { BBLV = LVILatticeVal::getNot(ConstantPointerNull::get(AI->getType())); return ODCacheUpdater.markResult(true); } // We can only analyze the definitions of certain classes of instructions // (integral binops and casts at the moment), so bail if this isn't one. LVILatticeVal Result; if ((!isa<BinaryOperator>(BBI) && !isa<CastInst>(BBI)) || !BBI->getType()->isIntegerTy()) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); BBLV.markOverdefined(); return ODCacheUpdater.markResult(true); } // FIXME: We're currently limited to binops with a constant RHS. This should // be improved. BinaryOperator *BO = dyn_cast<BinaryOperator>(BBI); if (BO && !isa<ConstantInt>(BO->getOperand(1))) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); BBLV.markOverdefined(); return ODCacheUpdater.markResult(true); } return ODCacheUpdater.markResult(solveBlockValueConstantRange(BBLV, BBI, BB)); }
static bool matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot, unsigned &Opcode, Type *&Ty) { if (!EnableReduxCost) return false; // Need to extract the first element. ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1)); unsigned Idx = ~0u; if (CI) Idx = CI->getZExtValue(); if (Idx != 0) return false; BinaryOperator *RdxStart = dyn_cast<BinaryOperator>(ReduxRoot->getOperand(0)); if (!RdxStart) return false; unsigned RdxOpcode = RdxStart->getOpcode(); Type *VecTy = ReduxRoot->getOperand(0)->getType(); unsigned NumVecElems = VecTy->getVectorNumElements(); if (!isPowerOf2_32(NumVecElems)) return false; // We look for a sequence of shuffles and adds like the following matching one // fadd, shuffle vector pair at a time. // // %rdx.shuf = shufflevector <4 x float> %rdx, <4 x float> undef, // <4 x i32> <i32 2, i32 3, i32 undef, i32 undef> // %bin.rdx = fadd <4 x float> %rdx, %rdx.shuf // %rdx.shuf7 = shufflevector <4 x float> %bin.rdx, <4 x float> undef, // <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> // %bin.rdx8 = fadd <4 x float> %bin.rdx, %rdx.shuf7 // %r = extractelement <4 x float> %bin.rdx8, i32 0 unsigned MaskStart = 1; Value *RdxOp = RdxStart; SmallVector<int, 32> ShuffleMask(NumVecElems, 0); unsigned NumVecElemsRemain = NumVecElems; while (NumVecElemsRemain - 1) { // Check for the right reduction operation. BinaryOperator *BinOp; if (!(BinOp = dyn_cast<BinaryOperator>(RdxOp))) return false; if (BinOp->getOpcode() != RdxOpcode) return false; Value *NextRdxOp; ShuffleVectorInst *Shuffle; std::tie(NextRdxOp, Shuffle) = getShuffleAndOtherOprd(BinOp); // Check the current reduction operation and the shuffle use the same value. if (Shuffle == nullptr) return false; if (Shuffle->getOperand(0) != NextRdxOp) return false; // Check that shuffle masks matches. for (unsigned j = 0; j != MaskStart; ++j) ShuffleMask[j] = MaskStart + j; // Fill the rest of the mask with -1 for undef. std::fill(&ShuffleMask[MaskStart], ShuffleMask.end(), -1); SmallVector<int, 16> Mask = Shuffle->getShuffleMask(); if (ShuffleMask != Mask) return false; RdxOp = NextRdxOp; NumVecElemsRemain /= 2; MaskStart *= 2; } Opcode = RdxOpcode; Ty = VecTy; return true; }
Instruction *InstCombiner::visitAdd(BinaryOperator &I) { bool Changed = SimplifyAssociativeOrCommutative(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); if (Value *V = SimplifyAddInst(LHS, RHS, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), TD)) return ReplaceInstUsesWith(I, V); // (A*B)+(A*C) -> A*(B+C) etc if (Value *V = SimplifyUsingDistributiveLaws(I)) return ReplaceInstUsesWith(I, V); if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) { // X + (signbit) --> X ^ signbit const APInt &Val = CI->getValue(); if (Val.isSignBit()) return BinaryOperator::CreateXor(LHS, RHS); // See if SimplifyDemandedBits can simplify this. This handles stuff like // (X & 254)+1 -> (X&254)|1 if (SimplifyDemandedInstructionBits(I)) return &I; // zext(bool) + C -> bool ? C + 1 : C if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS)) if (ZI->getSrcTy()->isIntegerTy(1)) return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI); Value *XorLHS = 0; ConstantInt *XorRHS = 0; if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { uint32_t TySizeBits = I.getType()->getScalarSizeInBits(); const APInt &RHSVal = CI->getValue(); unsigned ExtendAmt = 0; // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext. if (XorRHS->getValue() == -RHSVal) { if (RHSVal.isPowerOf2()) ExtendAmt = TySizeBits - RHSVal.logBase2() - 1; else if (XorRHS->getValue().isPowerOf2()) ExtendAmt = TySizeBits - XorRHS->getValue().logBase2() - 1; } if (ExtendAmt) { APInt Mask = APInt::getHighBitsSet(TySizeBits, ExtendAmt); if (!MaskedValueIsZero(XorLHS, Mask)) ExtendAmt = 0; } if (ExtendAmt) { Constant *ShAmt = ConstantInt::get(I.getType(), ExtendAmt); Value *NewShl = Builder->CreateShl(XorLHS, ShAmt, "sext"); return BinaryOperator::CreateAShr(NewShl, ShAmt); } } } if (isa<Constant>(RHS) && isa<PHINode>(LHS)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; if (I.getType()->isIntegerTy(1)) return BinaryOperator::CreateXor(LHS, RHS); // X + X --> X << 1 if (LHS == RHS) { BinaryOperator *New = BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1)); New->setHasNoSignedWrap(I.hasNoSignedWrap()); New->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); return New; } // -A + B --> B - A // -A + -B --> -(A + B) if (Value *LHSV = dyn_castNegVal(LHS)) { if (Value *RHSV = dyn_castNegVal(RHS)) { Value *NewAdd = Builder->CreateAdd(LHSV, RHSV, "sum"); return BinaryOperator::CreateNeg(NewAdd); } return BinaryOperator::CreateSub(RHS, LHSV); } // A + -B --> A - B if (!isa<Constant>(RHS)) if (Value *V = dyn_castNegVal(RHS)) return BinaryOperator::CreateSub(LHS, V); ConstantInt *C2; if (Value *X = dyn_castFoldableMul(LHS, C2)) { if (X == RHS) // X*C + X --> X * (C+1) return BinaryOperator::CreateMul(RHS, AddOne(C2)); // X*C1 + X*C2 --> X * (C1+C2) ConstantInt *C1; if (X == dyn_castFoldableMul(RHS, C1)) return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, C2)); } // X + X*C --> X * (C+1) if (dyn_castFoldableMul(RHS, C2) == LHS) return BinaryOperator::CreateMul(LHS, AddOne(C2)); // A+B --> A|B iff A and B have no bits set in common. if (const IntegerType *IT = dyn_cast<IntegerType>(I.getType())) { APInt Mask = APInt::getAllOnesValue(IT->getBitWidth()); APInt LHSKnownOne(IT->getBitWidth(), 0); APInt LHSKnownZero(IT->getBitWidth(), 0); ComputeMaskedBits(LHS, Mask, LHSKnownZero, LHSKnownOne); if (LHSKnownZero != 0) { APInt RHSKnownOne(IT->getBitWidth(), 0); APInt RHSKnownZero(IT->getBitWidth(), 0); ComputeMaskedBits(RHS, Mask, RHSKnownZero, RHSKnownOne); // No bits in common -> bitwise or. if ((LHSKnownZero|RHSKnownZero).isAllOnesValue()) return BinaryOperator::CreateOr(LHS, RHS); } } // W*X + Y*Z --> W * (X+Z) iff W == Y { Value *W, *X, *Y, *Z; if (match(LHS, m_Mul(m_Value(W), m_Value(X))) && match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) { if (W != Y) { if (W == Z) { std::swap(Y, Z); } else if (Y == X) { std::swap(W, X); } else if (X == Z) { std::swap(Y, Z); std::swap(W, X); } } if (W == Y) { Value *NewAdd = Builder->CreateAdd(X, Z, LHS->getName()); return BinaryOperator::CreateMul(W, NewAdd); } } } if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) { Value *X = 0; if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X return BinaryOperator::CreateSub(SubOne(CRHS), X); // (X & FF00) + xx00 -> (X+xx00) & FF00 if (LHS->hasOneUse() && match(LHS, m_And(m_Value(X), m_ConstantInt(C2))) && CRHS->getValue() == (CRHS->getValue() & C2->getValue())) { // See if all bits from the first bit set in the Add RHS up are included // in the mask. First, get the rightmost bit. const APInt &AddRHSV = CRHS->getValue(); // Form a mask of all bits from the lowest bit added through the top. APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1)); // See if the and mask includes all of these bits. APInt AddRHSHighBitsAnd(AddRHSHighBits & C2->getValue()); if (AddRHSHighBits == AddRHSHighBitsAnd) { // Okay, the xform is safe. Insert the new add pronto. Value *NewAdd = Builder->CreateAdd(X, CRHS, LHS->getName()); return BinaryOperator::CreateAnd(NewAdd, C2); } } // Try to fold constant add into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(LHS)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; } // add (select X 0 (sub n A)) A --> select X A n { SelectInst *SI = dyn_cast<SelectInst>(LHS); Value *A = RHS; if (!SI) { SI = dyn_cast<SelectInst>(RHS); A = LHS; } if (SI && SI->hasOneUse()) { Value *TV = SI->getTrueValue(); Value *FV = SI->getFalseValue(); Value *N; // Can we fold the add into the argument of the select? // We check both true and false select arguments for a matching subtract. if (match(FV, m_Zero()) && match(TV, m_Sub(m_Value(N), m_Specific(A)))) // Fold the add into the true select value. return SelectInst::Create(SI->getCondition(), N, A); if (match(TV, m_Zero()) && match(FV, m_Sub(m_Value(N), m_Specific(A)))) // Fold the add into the false select value. return SelectInst::Create(SI->getCondition(), A, N); } } // Check for (add (sext x), y), see if we can merge this into an // integer add followed by a sext. if (SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) { // (add (sext x), cst) --> (sext (add x, cst')) if (ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) { Constant *CI = ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType()); if (LHSConv->hasOneUse() && ConstantExpr::getSExt(CI, I.getType()) == RHSC && WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI)) { // Insert the new, smaller add. Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), CI, "addconv"); return new SExtInst(NewAdd, I.getType()); } } // (add (sext x), (sext y)) --> (sext (add int x, y)) if (SExtInst *RHSConv = dyn_cast<SExtInst>(RHS)) { // Only do this if x/y have the same type, if at last one of them has a // single use (so we don't increase the number of sexts), and if the // integer add will not overflow. if (LHSConv->getOperand(0)->getType()==RHSConv->getOperand(0)->getType()&& (LHSConv->hasOneUse() || RHSConv->hasOneUse()) && WillNotOverflowSignedAdd(LHSConv->getOperand(0), RHSConv->getOperand(0))) { // Insert the new integer add. Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0), RHSConv->getOperand(0), "addconv"); return new SExtInst(NewAdd, I.getType()); } } } return Changed ? &I : 0; }
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; }
Instruction *InstCombiner::visitUDiv(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (Value *V = SimplifyUDivInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); // Handle the integer div common cases if (Instruction *Common = commonIDivTransforms(I)) return Common; { // X udiv 2^C -> X >> C // Check to see if this is an unsigned division with an exact power of 2, // if so, convert to a right shift. const APInt *C; if (match(Op1, m_Power2(C))) { BinaryOperator *LShr = BinaryOperator::CreateLShr(Op0, ConstantInt::get(Op0->getType(), C->logBase2())); if (I.isExact()) LShr->setIsExact(); return LShr; } } if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) { // X udiv C, where C >= signbit if (C->getValue().isNegative()) { Value *IC = Builder->CreateICmpULT(Op0, C); return SelectInst::Create(IC, Constant::getNullValue(I.getType()), ConstantInt::get(I.getType(), 1)); } } // X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2) { const APInt *CI; Value *N; if (match(Op1, m_Shl(m_Power2(CI), m_Value(N)))) { if (*CI != 1) N = Builder->CreateAdd(N, ConstantInt::get(I.getType(),CI->logBase2())); if (I.isExact()) return BinaryOperator::CreateExactLShr(Op0, N); return BinaryOperator::CreateLShr(Op0, N); } } // udiv X, (Select Cond, C1, C2) --> Select Cond, (shr X, C1), (shr X, C2) // where C1&C2 are powers of two. { Value *Cond; const APInt *C1, *C2; if (match(Op1, m_Select(m_Value(Cond), m_Power2(C1), m_Power2(C2)))) { // Construct the "on true" case of the select Value *TSI = Builder->CreateLShr(Op0, C1->logBase2(), Op1->getName()+".t", I.isExact()); // Construct the "on false" case of the select Value *FSI = Builder->CreateLShr(Op0, C2->logBase2(), Op1->getName()+".f", I.isExact()); // construct the select instruction and return it. return SelectInst::Create(Cond, TSI, FSI); } } // (zext A) udiv (zext B) --> zext (A udiv B) if (ZExtInst *ZOp0 = dyn_cast<ZExtInst>(Op0)) if (Value *ZOp1 = dyn_castZExtVal(Op1, ZOp0->getSrcTy())) return new ZExtInst(Builder->CreateUDiv(ZOp0->getOperand(0), ZOp1, "div", I.isExact()), I.getType()); return 0; }
void IndVarSimplify::EliminateIVRemainders() { SmallVector<WeakVH, 16> DeadInsts; // Look for SRem and URem users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; BinaryOperator *Rem = dyn_cast<BinaryOperator>(UI.getUser()); if (!Rem) continue; bool isSigned = Rem->getOpcode() == Instruction::SRem; if (!isSigned && Rem->getOpcode() != Instruction::URem) continue; // We're only interested in the case where we know something about // the numerator. if (UI.getOperandValToReplace() != Rem->getOperand(0)) continue; // Get the SCEVs for the ICmp operands. const SCEV *S = SE->getSCEV(Rem->getOperand(0)); const SCEV *X = SE->getSCEV(Rem->getOperand(1)); // Simplify unnecessary loops away. const Loop *ICmpLoop = LI->getLoopFor(Rem->getParent()); S = SE->getSCEVAtScope(S, ICmpLoop); X = SE->getSCEVAtScope(X, ICmpLoop); // i % n --> i if i is in [0,n). if ((!isSigned || SE->isKnownNonNegative(S)) && SE->isKnownPredicate(isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, S, X)) Rem->replaceAllUsesWith(Rem->getOperand(0)); else { // (i+1) % n --> (i+1)==n?0:(i+1) if i is in [0,n). const SCEV *LessOne = SE->getMinusSCEV(S, SE->getConstant(S->getType(), 1)); if ((!isSigned || SE->isKnownNonNegative(LessOne)) && SE->isKnownPredicate(isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, LessOne, X)) { ICmpInst *ICmp = new ICmpInst(Rem, ICmpInst::ICMP_EQ, Rem->getOperand(0), Rem->getOperand(1), "tmp"); SelectInst *Sel = SelectInst::Create(ICmp, ConstantInt::get(Rem->getType(), 0), Rem->getOperand(0), "tmp", Rem); Rem->replaceAllUsesWith(Sel); } else continue; } // Inform IVUsers about the new users. if (Instruction *I = dyn_cast<Instruction>(Rem->getOperand(0))) IU->AddUsersIfInteresting(I); DEBUG(dbgs() << "INDVARS: Simplified rem: " << *Rem << '\n'); DeadInsts.push_back(Rem); } // Now that we're done iterating through lists, clean up any instructions // which are now dead. while (!DeadInsts.empty()) if (Instruction *Inst = dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val())) RecursivelyDeleteTriviallyDeadInstructions(Inst); }
/// HandleFloatingPointIV - If the loop has floating induction variable /// then insert corresponding integer induction variable if possible. /// For example, /// for(double i = 0; i < 10000; ++i) /// bar(i) /// is converted into /// for(int i = 0; i < 10000; ++i) /// bar((double)i); /// void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) { unsigned IncomingEdge = L->contains(PN->getIncomingBlock(0)); unsigned BackEdge = IncomingEdge^1; // Check incoming value. ConstantFP *InitValueVal = dyn_cast<ConstantFP>(PN->getIncomingValue(IncomingEdge)); int64_t InitValue; if (!InitValueVal || !ConvertToSInt(InitValueVal->getValueAPF(), InitValue)) return; // Check IV increment. Reject this PN if increment operation is not // an add or increment value can not be represented by an integer. BinaryOperator *Incr = dyn_cast<BinaryOperator>(PN->getIncomingValue(BackEdge)); if (Incr == 0 || Incr->getOpcode() != Instruction::FAdd) return; // If this is not an add of the PHI with a constantfp, or if the constant fp // is not an integer, bail out. ConstantFP *IncValueVal = dyn_cast<ConstantFP>(Incr->getOperand(1)); int64_t IncValue; if (IncValueVal == 0 || Incr->getOperand(0) != PN || !ConvertToSInt(IncValueVal->getValueAPF(), IncValue)) return; // Check Incr uses. One user is PN and the other user is an exit condition // used by the conditional terminator. Value::use_iterator IncrUse = Incr->use_begin(); Instruction *U1 = cast<Instruction>(*IncrUse++); if (IncrUse == Incr->use_end()) return; Instruction *U2 = cast<Instruction>(*IncrUse++); if (IncrUse != Incr->use_end()) return; // Find exit condition, which is an fcmp. If it doesn't exist, or if it isn't // only used by a branch, we can't transform it. FCmpInst *Compare = dyn_cast<FCmpInst>(U1); if (!Compare) Compare = dyn_cast<FCmpInst>(U2); if (Compare == 0 || !Compare->hasOneUse() || !isa<BranchInst>(Compare->use_back())) return; BranchInst *TheBr = cast<BranchInst>(Compare->use_back()); // We need to verify that the branch actually controls the iteration count // of the loop. If not, the new IV can overflow and no one will notice. // The branch block must be in the loop and one of the successors must be out // of the loop. assert(TheBr->isConditional() && "Can't use fcmp if not conditional"); if (!L->contains(TheBr->getParent()) || (L->contains(TheBr->getSuccessor(0)) && L->contains(TheBr->getSuccessor(1)))) return; // If it isn't a comparison with an integer-as-fp (the exit value), we can't // transform it. ConstantFP *ExitValueVal = dyn_cast<ConstantFP>(Compare->getOperand(1)); int64_t ExitValue; if (ExitValueVal == 0 || !ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue)) return; // Find new predicate for integer comparison. CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; switch (Compare->getPredicate()) { default: return; // Unknown comparison. case CmpInst::FCMP_OEQ: case CmpInst::FCMP_UEQ: NewPred = CmpInst::ICMP_EQ; break; case CmpInst::FCMP_ONE: case CmpInst::FCMP_UNE: NewPred = CmpInst::ICMP_NE; break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: NewPred = CmpInst::ICMP_SGT; break; case CmpInst::FCMP_OGE: case CmpInst::FCMP_UGE: NewPred = CmpInst::ICMP_SGE; break; case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: NewPred = CmpInst::ICMP_SLT; break; case CmpInst::FCMP_OLE: case CmpInst::FCMP_ULE: NewPred = CmpInst::ICMP_SLE; break; } // We convert the floating point induction variable to a signed i32 value if // we can. This is only safe if the comparison will not overflow in a way // that won't be trapped by the integer equivalent operations. Check for this // now. // TODO: We could use i64 if it is native and the range requires it. // The start/stride/exit values must all fit in signed i32. if (!isInt<32>(InitValue) || !isInt<32>(IncValue) || !isInt<32>(ExitValue)) return; // If not actually striding (add x, 0.0), avoid touching the code. if (IncValue == 0) return; // Positive and negative strides have different safety conditions. if (IncValue > 0) { // If we have a positive stride, we require the init to be less than the // exit value and an equality or less than comparison. if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SGT || NewPred == CmpInst::ICMP_SGE) return; uint32_t Range = uint32_t(ExitValue-InitValue); if (NewPred == CmpInst::ICMP_SLE) { // Normalize SLE -> SLT, check for infinite loop. if (++Range == 0) return; // Range overflows. } unsigned Leftover = Range % uint32_t(IncValue); // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) < ExitValue) return; } else { // If we have a negative stride, we require the init to be greater than the // exit value and an equality or greater than comparison. if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SLT || NewPred == CmpInst::ICMP_SLE) return; uint32_t Range = uint32_t(InitValue-ExitValue); if (NewPred == CmpInst::ICMP_SGE) { // Normalize SGE -> SGT, check for infinite loop. if (++Range == 0) return; // Range overflows. } unsigned Leftover = Range % uint32_t(-IncValue); // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) > ExitValue) return; } const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext()); // Insert new integer induction variable. PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN); NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue), PN->getIncomingBlock(IncomingEdge)); Value *NewAdd = BinaryOperator::CreateAdd(NewPHI, ConstantInt::get(Int32Ty, IncValue), Incr->getName()+".int", Incr); NewPHI->addIncoming(NewAdd, PN->getIncomingBlock(BackEdge)); ICmpInst *NewCompare = new ICmpInst(TheBr, NewPred, NewAdd, ConstantInt::get(Int32Ty, ExitValue), Compare->getName()); // In the following deletions, PN may become dead and may be deleted. // Use a WeakVH to observe whether this happens. WeakVH WeakPH = PN; // Delete the old floating point exit comparison. The branch starts using the // new comparison. NewCompare->takeName(Compare); Compare->replaceAllUsesWith(NewCompare); RecursivelyDeleteTriviallyDeadInstructions(Compare); // Delete the old floating point increment. Incr->replaceAllUsesWith(UndefValue::get(Incr->getType())); RecursivelyDeleteTriviallyDeadInstructions(Incr); // If the FP induction variable still has uses, this is because something else // in the loop uses its value. In order to canonicalize the induction // variable, we chose to eliminate the IV and rewrite it in terms of an // int->fp cast. // // We give preference to sitofp over uitofp because it is faster on most // platforms. if (WeakPH) { Value *Conv = new SIToFPInst(NewPHI, PN->getType(), "indvar.conv", PN->getParent()->getFirstNonPHI()); PN->replaceAllUsesWith(Conv); RecursivelyDeleteTriviallyDeadInstructions(PN); } // Add a new IVUsers entry for the newly-created integer PHI. IU->AddUsersIfInteresting(NewPHI); }
/// Insert code in the prolog code when unrolling a loop with a /// run-time trip-count. /// /// This method assumes that the loop unroll factor is total number /// of loop bodes in the loop after unrolling. (Some folks refer /// to the unroll factor as the number of *extra* copies added). /// We assume also that the loop unroll factor is a power-of-two. So, after /// unrolling the loop, the number of loop bodies executed is 2, /// 4, 8, etc. Note - LLVM converts the if-then-sequence to a switch /// instruction in SimplifyCFG.cpp. Then, the backend decides how code for /// the switch instruction is generated. /// /// extraiters = tripcount % loopfactor /// if (extraiters == 0) jump Loop: /// if (extraiters == loopfactor) jump L1 /// if (extraiters == loopfactor-1) jump L2 /// ... /// L1: LoopBody; /// L2: LoopBody; /// ... /// if tripcount < loopfactor jump End /// Loop: /// ... /// End: /// bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, LoopInfo *LI, LPPassManager *LPM) { // for now, only unroll loops that contain a single exit if (!L->getExitingBlock()) return false; // Make sure the loop is in canonical form, and there is a single // exit block only. if (!L->isLoopSimplifyForm() || L->getUniqueExitBlock() == 0) return false; // Use Scalar Evolution to compute the trip count. This allows more // loops to be unrolled than relying on induction var simplification ScalarEvolution *SE = LPM->getAnalysisIfAvailable<ScalarEvolution>(); if (SE == 0) return false; // Only unroll loops with a computable trip count and the trip count needs // to be an int value (allowing a pointer type is a TODO item) const SCEV *BECount = SE->getBackedgeTakenCount(L); if (isa<SCEVCouldNotCompute>(BECount) || !BECount->getType()->isIntegerTy()) return false; // Add 1 since the backedge count doesn't include the first loop iteration const SCEV *TripCountSC = SE->getAddExpr(BECount, SE->getConstant(BECount->getType(), 1)); if (isa<SCEVCouldNotCompute>(TripCountSC)) return false; // We only handle cases when the unroll factor is a power of 2. // Count is the loop unroll factor, the number of extra copies added + 1. if ((Count & (Count-1)) != 0) return false; // If this loop is nested, then the loop unroller changes the code in // parent loop, so the Scalar Evolution pass needs to be run again if (Loop *ParentLoop = L->getParentLoop()) SE->forgetLoop(ParentLoop); BasicBlock *PH = L->getLoopPreheader(); BasicBlock *Header = L->getHeader(); BasicBlock *Latch = L->getLoopLatch(); // It helps to splits the original preheader twice, one for the end of the // prolog code and one for a new loop preheader BasicBlock *PEnd = SplitEdge(PH, Header, LPM->getAsPass()); BasicBlock *NewPH = SplitBlock(PEnd, PEnd->getTerminator(), LPM->getAsPass()); BranchInst *PreHeaderBR = cast<BranchInst>(PH->getTerminator()); // Compute the number of extra iterations required, which is: // extra iterations = run-time trip count % (loop unroll factor + 1) SCEVExpander Expander(*SE, "loop-unroll"); Value *TripCount = Expander.expandCodeFor(TripCountSC, TripCountSC->getType(), PreHeaderBR); Type *CountTy = TripCount->getType(); BinaryOperator *ModVal = BinaryOperator::CreateURem(TripCount, ConstantInt::get(CountTy, Count), "xtraiter"); ModVal->insertBefore(PreHeaderBR); // Check if for no extra iterations, then jump to unrolled loop Value *BranchVal = new ICmpInst(PreHeaderBR, ICmpInst::ICMP_NE, ModVal, ConstantInt::get(CountTy, 0), "lcmp"); // Branch to either the extra iterations or the unrolled loop // We will fix up the true branch label when adding loop body copies BranchInst::Create(PEnd, PEnd, BranchVal, PreHeaderBR); assert(PreHeaderBR->isUnconditional() && PreHeaderBR->getSuccessor(0) == PEnd && "CFG edges in Preheader are not correct"); PreHeaderBR->eraseFromParent(); ValueToValueMapTy LVMap; Function *F = Header->getParent(); // These variables are used to update the CFG links in each iteration BasicBlock *CompareBB = 0; BasicBlock *LastLoopBB = PH; // Get an ordered list of blocks in the loop to help with the ordering of the // cloned blocks in the prolog code LoopBlocksDFS LoopBlocks(L); LoopBlocks.perform(LI); // // For each extra loop iteration, create a copy of the loop's basic blocks // and generate a condition that branches to the copy depending on the // number of 'left over' iterations. // for (unsigned leftOverIters = Count-1; leftOverIters > 0; --leftOverIters) { std::vector<BasicBlock*> NewBlocks; ValueToValueMapTy VMap; // Clone all the basic blocks in the loop, but we don't clone the loop // This function adds the appropriate CFG connections. CloneLoopBlocks(L, (leftOverIters == Count-1), LastLoopBB, PEnd, NewBlocks, LoopBlocks, VMap, LVMap, LI); LastLoopBB = cast<BasicBlock>(VMap[Latch]); // Insert the cloned blocks into function just before the original loop F->getBasicBlockList().splice(PEnd, F->getBasicBlockList(), NewBlocks[0], F->end()); // Generate the code for the comparison which determines if the loop // prolog code needs to be executed. if (leftOverIters == Count-1) { // There is no compare block for the fall-thru case when for the last // left over iteration CompareBB = NewBlocks[0]; } else { // Create a new block for the comparison BasicBlock *NewBB = BasicBlock::Create(CompareBB->getContext(), "unr.cmp", F, CompareBB); if (Loop *ParentLoop = L->getParentLoop()) { // Add the new block to the parent loop, if needed ParentLoop->addBasicBlockToLoop(NewBB, LI->getBase()); } // The comparison w/ the extra iteration value and branch Value *BranchVal = new ICmpInst(*NewBB, ICmpInst::ICMP_EQ, ModVal, ConstantInt::get(CountTy, leftOverIters), "un.tmp"); // Branch to either the extra iterations or the unrolled loop BranchInst::Create(NewBlocks[0], CompareBB, BranchVal, NewBB); CompareBB = NewBB; PH->getTerminator()->setSuccessor(0, NewBB); VMap[NewPH] = CompareBB; } // Rewrite the cloned instruction operands to use the values // created when the clone is created. for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) { for (BasicBlock::iterator I = NewBlocks[i]->begin(), E = NewBlocks[i]->end(); I != E; ++I) { RemapInstruction(I, VMap, RF_NoModuleLevelChanges|RF_IgnoreMissingEntries); } } } // Connect the prolog code to the original loop and update the // PHI functions. ConnectProlog(L, TripCount, Count, LastLoopBB, PEnd, PH, NewPH, LVMap, LPM->getAsPass()); NumRuntimeUnrolled++; return true; }
static Value *genVal(int &Budget, unsigned Width, bool ConstOK, bool ArgOK) { if (Budget > 0 && Choose(2)) { if (Verbose) errs() << "adding a phi, budget = " << Budget << "\n"; --Budget; Value *V = Builder->CreatePHI(Type::getIntNTy(*C, Width), N); Vals.push_back(V); return V; } if (Budget > 0 && Budget != N && Choose(2)) { if (Verbose) errs() << "adding a branch, budget = " << Budget << "\n"; --Budget; BranchInst *Br; if (0 && Builder->GetInsertBlock()->size() > 0 && Choose(2)) { Br = Builder->CreateBr(BBs[0]); } else { Value *C = genVal(Budget, 1, false, ArgOK); Br = Builder->CreateCondBr(C, BBs[0], BBs[0]); } Branches.push_back(Br); BasicBlock *BB = BasicBlock::Create(*C, "", F); BBs.push_back(BB); Builder->SetInsertPoint(BB); return genVal(Budget, Width, ConstOK, ArgOK); } if (Budget > 0 && Width == W && Choose(2)) { if (Verbose) errs() << "adding a select with width = " << Width << " and budget = " << Budget << "\n"; --Budget; Value *L, *R; genLR(L, R, Budget, Width); Value *C = genVal(Budget, 1, false); Value *V = Builder->CreateSelect(C, L, R); Vals.push_back(V); return V; } if (Budget > 0 && Width == 1 && Choose(2)) { if (Verbose) errs() << "adding an icmp with width = " << Width << " and budget = " << Budget << "\n"; --Budget; Value *L, *R; genLR(L, R, Budget, Width); CmpInst::Predicate P; switch (OneICmp ? 0 : Choose(10)) { case 0: P = CmpInst::ICMP_EQ; break; case 1: P = CmpInst::ICMP_NE; break; case 2: P = CmpInst::ICMP_UGT; break; case 3: P = CmpInst::ICMP_UGE; break; case 4: P = CmpInst::ICMP_ULT; break; case 5: P = CmpInst::ICMP_ULE; break; case 6: P = CmpInst::ICMP_SGT; break; case 7: P = CmpInst::ICMP_SGE; break; case 8: P = CmpInst::ICMP_SLT; break; case 9: P = CmpInst::ICMP_SLE; break; } Value *V = Builder->CreateICmp(P, L, R); Vals.push_back(V); return V; } if (Budget > 0 && Width == W && Choose(2)) { unsigned OldW = Width * 2; if (Verbose) errs() << "adding a trunc from " << OldW << " to " << Width << " and budget = " << Budget << "\n"; --Budget; Value *V = Builder->CreateTrunc(genVal(Budget, OldW, false), Type::getIntNTy(*C, Width)); Vals.push_back(V); return V; } if (Budget > 0 && Width == W && Choose(2)) { unsigned OldW = Width / 2; if (OldW > 1 && Choose(2)) OldW = 1; if (Verbose) errs() << "adding a zext from " << OldW << " to " << Width << " and budget = " << Budget << "\n"; --Budget; Value *V; if (Choose(2)) V = Builder->CreateZExt(genVal(Budget, OldW, false), Type::getIntNTy(*C, Width)); else V = Builder->CreateSExt(genVal(Budget, OldW, false), Type::getIntNTy(*C, Width)); Vals.push_back(V); return V; } if (Budget > 0 && Width == W && Choose(2)) { if (Verbose) errs() << "adding a binop with width = " << Width << " and budget = " << Budget << "\n"; --Budget; Instruction::BinaryOps Op; switch (OneBinop ? 0 : Choose(10)) { case 0: Op = Instruction::Add; break; case 1: Op = Instruction::Sub; break; case 2: Op = Instruction::Mul; break; case 3: Op = Instruction::SDiv; break; case 4: Op = Instruction::UDiv; break; case 5: Op = Instruction::SRem; break; case 6: Op = Instruction::URem; break; case 7: Op = Instruction::And; break; case 8: Op = Instruction::Or; break; case 9: Op = Instruction::Xor; break; } Value *L, *R; genLR(L, R, Budget, Width); Value *V = Builder->CreateBinOp(Op, L, R); if (!NoUB) { if ((Op == Instruction::Add || Op == Instruction::Sub || Op == Instruction::Mul || Op == Instruction::Shl) && Choose(2)) { BinaryOperator *B = cast<BinaryOperator>(V); B->setHasNoSignedWrap(true); } if ((Op == Instruction::Add || Op == Instruction::Sub || Op == Instruction::Mul || Op == Instruction::Shl) && Choose(2)) { BinaryOperator *B = cast<BinaryOperator>(V); B->setHasNoUnsignedWrap(true); } if ((Op == Instruction::UDiv || Op == Instruction::SDiv || Op == Instruction::LShr || Op == Instruction::AShr) && Choose(2)) { BinaryOperator *B = cast<BinaryOperator>(V); B->setIsExact(true); } } Vals.push_back(V); return V; } if (ConstOK && Choose(2)) { if (Verbose) errs() << "adding a const with width = " << Width << " and budget = " << Budget << "\n"; if (OneConst) { return ConstantInt::get(*C, APInt(Width, 1)); } else { int n = Choose((1 << Width) + 1); if (n == (1 << Width)) return UndefValue::get(Type::getIntNTy(*C, Width)); else return ConstantInt::get(*C, APInt(Width, n)); } } if (Verbose) errs() << "using existing val with width = " << Width << " and budget = " << Budget << " and ArgOK = " << ArgOK << "\n"; std::vector<Value *> Vs; for (auto &it : Vals) if (it->getType()->getPrimitiveSizeInBits() == Width) Vs.push_back(it); unsigned choices = Vs.size() + (ArgOK ? 1 : 0); if (choices == 0) exit(0); unsigned which = Choose(choices); if (which == Vs.size()) { Value *V = 0; for (auto it = F->arg_begin(); it != F->arg_end(); ++it) { if (UsedArgs.find(it) == UsedArgs.end() && it->getType()->getPrimitiveSizeInBits() == Width) { UsedArgs.insert(it); V = it; Vals.push_back(V); break; } } ensure(V); return V; } else { return Vs.at(which); } }
Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1, BinaryOperator &I) { bool isLeftShift = I.getOpcode() == Instruction::Shl; ConstantInt *COp1 = nullptr; if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(Op1)) COp1 = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()); else if (ConstantVector *CV = dyn_cast<ConstantVector>(Op1)) COp1 = dyn_cast_or_null<ConstantInt>(CV->getSplatValue()); else COp1 = dyn_cast<ConstantInt>(Op1); if (!COp1) return nullptr; // See if we can propagate this shift into the input, this covers the trivial // cast of lshr(shl(x,c1),c2) as well as other more complex cases. if (I.getOpcode() != Instruction::AShr && CanEvaluateShifted(Op0, COp1->getZExtValue(), isLeftShift, *this)) { DEBUG(dbgs() << "ICE: GetShiftedValue propagating shift through expression" " to eliminate shift:\n IN: " << *Op0 << "\n SH: " << I <<"\n"); return ReplaceInstUsesWith(I, GetShiftedValue(Op0, COp1->getZExtValue(), isLeftShift, *this)); } // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. uint32_t TypeBits = Op0->getType()->getScalarSizeInBits(); assert(!COp1->uge(TypeBits) && "Shift over the type width should have been removed already"); // ((X*C1) << C2) == (X * (C1 << C2)) if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0)) if (BO->getOpcode() == Instruction::Mul && isLeftShift) if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1))) return BinaryOperator::CreateMul(BO->getOperand(0), ConstantExpr::getShl(BOOp, Op1)); // Try to fold constant and into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; if (isa<PHINode>(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; // Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2)) if (TruncInst *TI = dyn_cast<TruncInst>(Op0)) { Instruction *TrOp = dyn_cast<Instruction>(TI->getOperand(0)); // If 'shift2' is an ashr, we would have to get the sign bit into a funny // place. Don't try to do this transformation in this case. Also, we // require that the input operand is a shift-by-constant so that we have // confidence that the shifts will get folded together. We could do this // xform in more cases, but it is unlikely to be profitable. if (TrOp && I.isLogicalShift() && TrOp->isShift() && isa<ConstantInt>(TrOp->getOperand(1))) { // Okay, we'll do this xform. Make the shift of shift. Constant *ShAmt = ConstantExpr::getZExt(COp1, TrOp->getType()); // (shift2 (shift1 & 0x00FF), c2) Value *NSh = Builder->CreateBinOp(I.getOpcode(), TrOp, ShAmt,I.getName()); // For logical shifts, the truncation has the effect of making the high // part of the register be zeros. Emulate this by inserting an AND to // clear the top bits as needed. This 'and' will usually be zapped by // other xforms later if dead. unsigned SrcSize = TrOp->getType()->getScalarSizeInBits(); unsigned DstSize = TI->getType()->getScalarSizeInBits(); APInt MaskV(APInt::getLowBitsSet(SrcSize, DstSize)); // The mask we constructed says what the trunc would do if occurring // between the shifts. We want to know the effect *after* the second // shift. We know that it is a logical shift by a constant, so adjust the // mask as appropriate. if (I.getOpcode() == Instruction::Shl) MaskV <<= COp1->getZExtValue(); else { assert(I.getOpcode() == Instruction::LShr && "Unknown logical shift"); MaskV = MaskV.lshr(COp1->getZExtValue()); } // shift1 & 0x00FF Value *And = Builder->CreateAnd(NSh, ConstantInt::get(I.getContext(), MaskV), TI->getName()); // Return the value truncated to the interesting size. return new TruncInst(And, I.getType()); } } if (Op0->hasOneUse()) { if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0)) { // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C) Value *V1, *V2; ConstantInt *CC; switch (Op0BO->getOpcode()) { default: break; case Instruction::Add: case Instruction::And: case Instruction::Or: case Instruction::Xor: { // These operators commute. // Turn (Y + (X >> C)) << C -> (X + (Y << C)) & (~0 << C) if (isLeftShift && Op0BO->getOperand(1)->hasOneUse() && match(Op0BO->getOperand(1), m_Shr(m_Value(V1), m_Specific(Op1)))) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName()); // (X + (Y << C)) Value *X = Builder->CreateBinOp(Op0BO->getOpcode(), YS, V1, Op0BO->getOperand(1)->getName()); uint32_t Op1Val = COp1->getLimitedValue(TypeBits); APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val); Constant *Mask = ConstantInt::get(I.getContext(), Bits); if (VectorType *VT = dyn_cast<VectorType>(X->getType())) Mask = ConstantVector::getSplat(VT->getNumElements(), Mask); return BinaryOperator::CreateAnd(X, Mask); } // Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C)) Value *Op0BOOp1 = Op0BO->getOperand(1); if (isLeftShift && Op0BOOp1->hasOneUse() && match(Op0BOOp1, m_And(m_OneUse(m_Shr(m_Value(V1), m_Specific(Op1))), m_ConstantInt(CC)))) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(0), Op1, Op0BO->getName()); // X & (CC << C) Value *XM = Builder->CreateAnd(V1, ConstantExpr::getShl(CC, Op1), V1->getName()+".mask"); return BinaryOperator::Create(Op0BO->getOpcode(), YS, XM); } } // FALL THROUGH. case Instruction::Sub: { // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C) if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() && match(Op0BO->getOperand(0), m_Shr(m_Value(V1), m_Specific(Op1)))) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName()); // (X + (Y << C)) Value *X = Builder->CreateBinOp(Op0BO->getOpcode(), V1, YS, Op0BO->getOperand(0)->getName()); uint32_t Op1Val = COp1->getLimitedValue(TypeBits); APInt Bits = APInt::getHighBitsSet(TypeBits, TypeBits - Op1Val); Constant *Mask = ConstantInt::get(I.getContext(), Bits); if (VectorType *VT = dyn_cast<VectorType>(X->getType())) Mask = ConstantVector::getSplat(VT->getNumElements(), Mask); return BinaryOperator::CreateAnd(X, Mask); } // Turn (((X >> C)&CC) + Y) << C -> (X + (Y << C)) & (CC << C) if (isLeftShift && Op0BO->getOperand(0)->hasOneUse() && match(Op0BO->getOperand(0), m_And(m_OneUse(m_Shr(m_Value(V1), m_Value(V2))), m_ConstantInt(CC))) && V2 == Op1) { Value *YS = // (Y << C) Builder->CreateShl(Op0BO->getOperand(1), Op1, Op0BO->getName()); // X & (CC << C) Value *XM = Builder->CreateAnd(V1, ConstantExpr::getShl(CC, Op1), V1->getName()+".mask"); return BinaryOperator::Create(Op0BO->getOpcode(), XM, YS); } break; } } // If the operand is an bitwise operator with a constant RHS, and the // shift is the only use, we can pull it out of the shift. if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) { bool isValid = true; // Valid only for And, Or, Xor bool highBitSet = false; // Transform if high bit of constant set? switch (Op0BO->getOpcode()) { default: isValid = false; break; // Do not perform transform! case Instruction::Add: isValid = isLeftShift; break; case Instruction::Or: case Instruction::Xor: highBitSet = false; break; case Instruction::And: highBitSet = true; break; } // If this is a signed shift right, and the high bit is modified // by the logical operation, do not perform the transformation. // The highBitSet boolean indicates the value of the high bit of // the constant which would cause it to be modified for this // operation. // if (isValid && I.getOpcode() == Instruction::AShr) isValid = Op0C->getValue()[TypeBits-1] == highBitSet; if (isValid) { Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, Op1); Value *NewShift = Builder->CreateBinOp(I.getOpcode(), Op0BO->getOperand(0), Op1); NewShift->takeName(Op0BO); return BinaryOperator::Create(Op0BO->getOpcode(), NewShift, NewRHS); } } } } // Find out if this is a shift of a shift by a constant. BinaryOperator *ShiftOp = dyn_cast<BinaryOperator>(Op0); if (ShiftOp && !ShiftOp->isShift()) ShiftOp = nullptr; if (ShiftOp && isa<ConstantInt>(ShiftOp->getOperand(1))) { // This is a constant shift of a constant shift. Be careful about hiding // shl instructions behind bit masks. They are used to represent multiplies // by a constant, and it is important that simple arithmetic expressions // are still recognizable by scalar evolution. // // The transforms applied to shl are very similar to the transforms applied // to mul by constant. We can be more aggressive about optimizing right // shifts. // // Combinations of right and left shifts will still be optimized in // DAGCombine where scalar evolution no longer applies. ConstantInt *ShiftAmt1C = cast<ConstantInt>(ShiftOp->getOperand(1)); uint32_t ShiftAmt1 = ShiftAmt1C->getLimitedValue(TypeBits); uint32_t ShiftAmt2 = COp1->getLimitedValue(TypeBits); assert(ShiftAmt2 != 0 && "Should have been simplified earlier"); if (ShiftAmt1 == 0) return nullptr; // Will be simplified in the future. Value *X = ShiftOp->getOperand(0); IntegerType *Ty = cast<IntegerType>(I.getType()); // Check for (X << c1) << c2 and (X >> c1) >> c2 if (I.getOpcode() == ShiftOp->getOpcode()) { uint32_t AmtSum = ShiftAmt1+ShiftAmt2; // Fold into one big shift. // If this is oversized composite shift, then unsigned shifts get 0, ashr // saturates. if (AmtSum >= TypeBits) { if (I.getOpcode() != Instruction::AShr) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); AmtSum = TypeBits-1; // Saturate to 31 for i32 ashr. } return BinaryOperator::Create(I.getOpcode(), X, ConstantInt::get(Ty, AmtSum)); } if (ShiftAmt1 == ShiftAmt2) { // If we have ((X << C) >>u C), turn this into X & (-1 >>u C). if (I.getOpcode() == Instruction::LShr && ShiftOp->getOpcode() == Instruction::Shl) { APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt1)); return BinaryOperator::CreateAnd(X, ConstantInt::get(I.getContext(), Mask)); } } else if (ShiftAmt1 < ShiftAmt2) { uint32_t ShiftDiff = ShiftAmt2-ShiftAmt1; // (X >>?,exact C1) << C2 --> X << (C2-C1) // The inexact version is deferred to DAGCombine so we don't hide shl // behind a bit mask. if (I.getOpcode() == Instruction::Shl && ShiftOp->getOpcode() != Instruction::Shl && ShiftOp->isExact()) { assert(ShiftOp->getOpcode() == Instruction::LShr || ShiftOp->getOpcode() == Instruction::AShr); ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewShl = BinaryOperator::Create(Instruction::Shl, X, ShiftDiffCst); NewShl->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); NewShl->setHasNoSignedWrap(I.hasNoSignedWrap()); return NewShl; } // (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2) if (I.getOpcode() == Instruction::LShr && ShiftOp->getOpcode() == Instruction::Shl) { ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); // (X <<nuw C1) >>u C2 --> X >>u (C2-C1) if (ShiftOp->hasNoUnsignedWrap()) { BinaryOperator *NewLShr = BinaryOperator::Create(Instruction::LShr, X, ShiftDiffCst); NewLShr->setIsExact(I.isExact()); return NewLShr; } Value *Shift = Builder->CreateLShr(X, ShiftDiffCst); APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt2)); return BinaryOperator::CreateAnd(Shift, ConstantInt::get(I.getContext(),Mask)); } // We can't handle (X << C1) >>s C2, it shifts arbitrary bits in. However, // we can handle (X <<nsw C1) >>s C2 since it only shifts in sign bits. if (I.getOpcode() == Instruction::AShr && ShiftOp->getOpcode() == Instruction::Shl) { if (ShiftOp->hasNoSignedWrap()) { // (X <<nsw C1) >>s C2 --> X >>s (C2-C1) ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewAShr = BinaryOperator::Create(Instruction::AShr, X, ShiftDiffCst); NewAShr->setIsExact(I.isExact()); return NewAShr; } } } else { assert(ShiftAmt2 < ShiftAmt1); uint32_t ShiftDiff = ShiftAmt1-ShiftAmt2; // (X >>?exact C1) << C2 --> X >>?exact (C1-C2) // The inexact version is deferred to DAGCombine so we don't hide shl // behind a bit mask. if (I.getOpcode() == Instruction::Shl && ShiftOp->getOpcode() != Instruction::Shl && ShiftOp->isExact()) { ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewShr = BinaryOperator::Create(ShiftOp->getOpcode(), X, ShiftDiffCst); NewShr->setIsExact(true); return NewShr; } // (X << C1) >>u C2 --> X << (C1-C2) & (-1 >> C2) if (I.getOpcode() == Instruction::LShr && ShiftOp->getOpcode() == Instruction::Shl) { ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); if (ShiftOp->hasNoUnsignedWrap()) { // (X <<nuw C1) >>u C2 --> X <<nuw (C1-C2) BinaryOperator *NewShl = BinaryOperator::Create(Instruction::Shl, X, ShiftDiffCst); NewShl->setHasNoUnsignedWrap(true); return NewShl; } Value *Shift = Builder->CreateShl(X, ShiftDiffCst); APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt2)); return BinaryOperator::CreateAnd(Shift, ConstantInt::get(I.getContext(),Mask)); } // We can't handle (X << C1) >>s C2, it shifts arbitrary bits in. However, // we can handle (X <<nsw C1) >>s C2 since it only shifts in sign bits. if (I.getOpcode() == Instruction::AShr && ShiftOp->getOpcode() == Instruction::Shl) { if (ShiftOp->hasNoSignedWrap()) { // (X <<nsw C1) >>s C2 --> X <<nsw (C1-C2) ConstantInt *ShiftDiffCst = ConstantInt::get(Ty, ShiftDiff); BinaryOperator *NewShl = BinaryOperator::Create(Instruction::Shl, X, ShiftDiffCst); NewShl->setHasNoSignedWrap(true); return NewShl; } } } } return nullptr; }
void Lint::visitURem(BinaryOperator &I) { Assert1(!isZero(I.getOperand(1), TD), "Undefined behavior: Division by zero", &I); }
Instruction *InstCombiner::visitMul(BinaryOperator &I) { bool Changed = SimplifyAssociativeOrCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (Value *V = SimplifyMulInst(Op0, Op1, TD)) return ReplaceInstUsesWith(I, V); if (Value *V = SimplifyUsingDistributiveLaws(I)) return ReplaceInstUsesWith(I, V); if (match(Op1, m_AllOnes())) // X * -1 == 0 - X return BinaryOperator::CreateNeg(Op0, I.getName()); if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) { // ((X << C1)*C2) == (X * (C2 << C1)) if (BinaryOperator *SI = dyn_cast<BinaryOperator>(Op0)) if (SI->getOpcode() == Instruction::Shl) if (Constant *ShOp = dyn_cast<Constant>(SI->getOperand(1))) return BinaryOperator::CreateMul(SI->getOperand(0), ConstantExpr::getShl(CI, ShOp)); const APInt &Val = CI->getValue(); if (Val.isPowerOf2()) { // Replace X*(2^C) with X << C Constant *NewCst = ConstantInt::get(Op0->getType(), Val.logBase2()); BinaryOperator *Shl = BinaryOperator::CreateShl(Op0, NewCst); if (I.hasNoSignedWrap()) Shl->setHasNoSignedWrap(); if (I.hasNoUnsignedWrap()) Shl->setHasNoUnsignedWrap(); return Shl; } // Canonicalize (X+C1)*CI -> X*CI+C1*CI. { Value *X; ConstantInt *C1; if (Op0->hasOneUse() && match(Op0, m_Add(m_Value(X), m_ConstantInt(C1)))) { Value *Add = Builder->CreateMul(X, CI); return BinaryOperator::CreateAdd(Add, Builder->CreateMul(C1, CI)); } } // (Y - X) * (-(2**n)) -> (X - Y) * (2**n), for positive nonzero n // (Y + const) * (-(2**n)) -> (-constY) * (2**n), for positive nonzero n // The "* (2**n)" thus becomes a potential shifting opportunity. { const APInt & Val = CI->getValue(); const APInt &PosVal = Val.abs(); if (Val.isNegative() && PosVal.isPowerOf2()) { Value *X = 0, *Y = 0; if (Op0->hasOneUse()) { ConstantInt *C1; Value *Sub = 0; if (match(Op0, m_Sub(m_Value(Y), m_Value(X)))) Sub = Builder->CreateSub(X, Y, "suba"); else if (match(Op0, m_Add(m_Value(Y), m_ConstantInt(C1)))) Sub = Builder->CreateSub(Builder->CreateNeg(C1), Y, "subc"); if (Sub) return BinaryOperator::CreateMul(Sub, ConstantInt::get(Y->getType(), PosVal)); } } } } // Simplify mul instructions with a constant RHS. if (isa<Constant>(Op1)) { // Try to fold constant mul into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; if (isa<PHINode>(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; } if (Value *Op0v = dyn_castNegVal(Op0)) // -X * -Y = X*Y if (Value *Op1v = dyn_castNegVal(Op1)) return BinaryOperator::CreateMul(Op0v, Op1v); // (X / Y) * Y = X - (X % Y) // (X / Y) * -Y = (X % Y) - X { Value *Op1C = Op1; BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0); if (!BO || (BO->getOpcode() != Instruction::UDiv && BO->getOpcode() != Instruction::SDiv)) { Op1C = Op0; BO = dyn_cast<BinaryOperator>(Op1); } Value *Neg = dyn_castNegVal(Op1C); if (BO && BO->hasOneUse() && (BO->getOperand(1) == Op1C || BO->getOperand(1) == Neg) && (BO->getOpcode() == Instruction::UDiv || BO->getOpcode() == Instruction::SDiv)) { Value *Op0BO = BO->getOperand(0), *Op1BO = BO->getOperand(1); // If the division is exact, X % Y is zero, so we end up with X or -X. if (PossiblyExactOperator *SDiv = dyn_cast<PossiblyExactOperator>(BO)) if (SDiv->isExact()) { if (Op1BO == Op1C) return ReplaceInstUsesWith(I, Op0BO); return BinaryOperator::CreateNeg(Op0BO); } Value *Rem; if (BO->getOpcode() == Instruction::UDiv) Rem = Builder->CreateURem(Op0BO, Op1BO); else Rem = Builder->CreateSRem(Op0BO, Op1BO); Rem->takeName(BO); if (Op1BO == Op1C) return BinaryOperator::CreateSub(Op0BO, Rem); return BinaryOperator::CreateSub(Rem, Op0BO); } } /// i1 mul -> i1 and. if (I.getType()->isIntegerTy(1)) return BinaryOperator::CreateAnd(Op0, Op1); // X*(1 << Y) --> X << Y // (1 << Y)*X --> X << Y { Value *Y; if (match(Op0, m_Shl(m_One(), m_Value(Y)))) return BinaryOperator::CreateShl(Op1, Y); if (match(Op1, m_Shl(m_One(), m_Value(Y)))) return BinaryOperator::CreateShl(Op0, Y); } // If one of the operands of the multiply is a cast from a boolean value, then // we know the bool is either zero or one, so this is a 'masking' multiply. // X * Y (where Y is 0 or 1) -> X & (0-Y) if (!I.getType()->isVectorTy()) { // -2 is "-1 << 1" so it is all bits set except the low one. APInt Negative2(I.getType()->getPrimitiveSizeInBits(), (uint64_t)-2, true); Value *BoolCast = 0, *OtherOp = 0; if (MaskedValueIsZero(Op0, Negative2)) BoolCast = Op0, OtherOp = Op1; else if (MaskedValueIsZero(Op1, Negative2)) BoolCast = Op1, OtherOp = Op0; if (BoolCast) { Value *V = Builder->CreateSub(Constant::getNullValue(I.getType()), BoolCast); return BinaryOperator::CreateAnd(V, OtherOp); } } return Changed ? &I : 0; }
Instruction *InstCombiner::visitSub(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (Value *V = SimplifySubInst(Op0, Op1, I.hasNoSignedWrap(), I.hasNoUnsignedWrap(), TD)) return ReplaceInstUsesWith(I, V); // (A*B)-(A*C) -> A*(B-C) etc if (Value *V = SimplifyUsingDistributiveLaws(I)) return ReplaceInstUsesWith(I, V); // If this is a 'B = x-(-A)', change to B = x+A. This preserves NSW/NUW. if (Value *V = dyn_castNegVal(Op1)) { BinaryOperator *Res = BinaryOperator::CreateAdd(Op0, V); Res->setHasNoSignedWrap(I.hasNoSignedWrap()); Res->setHasNoUnsignedWrap(I.hasNoUnsignedWrap()); return Res; } if (I.getType()->isIntegerTy(1)) return BinaryOperator::CreateXor(Op0, Op1); // Replace (-1 - A) with (~A). if (match(Op0, m_AllOnes())) return BinaryOperator::CreateNot(Op1); if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) { // C - ~X == X + (1+C) Value *X = 0; if (match(Op1, m_Not(m_Value(X)))) return BinaryOperator::CreateAdd(X, AddOne(C)); // -(X >>u 31) -> (X >>s 31) // -(X >>s 31) -> (X >>u 31) if (C->isZero()) { Value *X; ConstantInt *CI; if (match(Op1, m_LShr(m_Value(X), m_ConstantInt(CI))) && // Verify we are shifting out everything but the sign bit. CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1) return BinaryOperator::CreateAShr(X, CI); if (match(Op1, m_AShr(m_Value(X), m_ConstantInt(CI))) && // Verify we are shifting out everything but the sign bit. CI->getValue() == I.getType()->getPrimitiveSizeInBits()-1) return BinaryOperator::CreateLShr(X, CI); } // Try to fold constant sub into select arguments. if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) if (Instruction *R = FoldOpIntoSelect(I, SI)) return R; // C - zext(bool) -> bool ? C - 1 : C if (ZExtInst *ZI = dyn_cast<ZExtInst>(Op1)) if (ZI->getSrcTy()->isIntegerTy(1)) return SelectInst::Create(ZI->getOperand(0), SubOne(C), C); // C-(X+C2) --> (C-C2)-X ConstantInt *C2; if (match(Op1, m_Add(m_Value(X), m_ConstantInt(C2)))) return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X); } { Value *Y; // X-(X+Y) == -Y X-(Y+X) == -Y if (match(Op1, m_Add(m_Specific(Op0), m_Value(Y))) || match(Op1, m_Add(m_Value(Y), m_Specific(Op0)))) return BinaryOperator::CreateNeg(Y); // (X-Y)-X == -Y if (match(Op0, m_Sub(m_Specific(Op1), m_Value(Y)))) return BinaryOperator::CreateNeg(Y); } if (Op1->hasOneUse()) { Value *X = 0, *Y = 0, *Z = 0; Constant *C = 0; ConstantInt *CI = 0; // (X - (Y - Z)) --> (X + (Z - Y)). if (match(Op1, m_Sub(m_Value(Y), m_Value(Z)))) return BinaryOperator::CreateAdd(Op0, Builder->CreateSub(Z, Y, Op1->getName())); // (X - (X & Y)) --> (X & ~Y) // if (match(Op1, m_And(m_Value(Y), m_Specific(Op0))) || match(Op1, m_And(m_Specific(Op0), m_Value(Y)))) return BinaryOperator::CreateAnd(Op0, Builder->CreateNot(Y, Y->getName() + ".not")); // 0 - (X sdiv C) -> (X sdiv -C) if (match(Op1, m_SDiv(m_Value(X), m_Constant(C))) && match(Op0, m_Zero())) return BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(C)); // 0 - (X << Y) -> (-X << Y) when X is freely negatable. if (match(Op1, m_Shl(m_Value(X), m_Value(Y))) && match(Op0, m_Zero())) if (Value *XNeg = dyn_castNegVal(X)) return BinaryOperator::CreateShl(XNeg, Y); // X - X*C --> X * (1-C) if (match(Op1, m_Mul(m_Specific(Op0), m_ConstantInt(CI)))) { Constant *CP1 = ConstantExpr::getSub(ConstantInt::get(I.getType(),1), CI); return BinaryOperator::CreateMul(Op0, CP1); } // X - X<<C --> X * (1-(1<<C)) if (match(Op1, m_Shl(m_Specific(Op0), m_ConstantInt(CI)))) { Constant *One = ConstantInt::get(I.getType(), 1); C = ConstantExpr::getSub(One, ConstantExpr::getShl(One, CI)); return BinaryOperator::CreateMul(Op0, C); } // X - A*-B -> X + A*B // X - -A*B -> X + A*B Value *A, *B; if (match(Op1, m_Mul(m_Value(A), m_Neg(m_Value(B)))) || match(Op1, m_Mul(m_Neg(m_Value(A)), m_Value(B)))) return BinaryOperator::CreateAdd(Op0, Builder->CreateMul(A, B)); // X - A*CI -> X + A*-CI // X - CI*A -> X + A*-CI if (match(Op1, m_Mul(m_Value(A), m_ConstantInt(CI))) || match(Op1, m_Mul(m_ConstantInt(CI), m_Value(A)))) { Value *NewMul = Builder->CreateMul(A, ConstantExpr::getNeg(CI)); return BinaryOperator::CreateAdd(Op0, NewMul); } } ConstantInt *C1; if (Value *X = dyn_castFoldableMul(Op0, C1)) { if (X == Op1) // X*C - X --> X * (C-1) return BinaryOperator::CreateMul(Op1, SubOne(C1)); ConstantInt *C2; // X*C1 - X*C2 -> X * (C1-C2) if (X == dyn_castFoldableMul(Op1, C2)) return BinaryOperator::CreateMul(X, ConstantExpr::getSub(C1, C2)); } // Optimize pointer differences into the same array into a size. Consider: // &A[10] - &A[0]: we should compile this to "10". if (TD) { Value *LHSOp, *RHSOp; if (match(Op0, m_PtrToInt(m_Value(LHSOp))) && match(Op1, m_PtrToInt(m_Value(RHSOp)))) if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType())) return ReplaceInstUsesWith(I, Res); // trunc(p)-trunc(q) -> trunc(p-q) if (match(Op0, m_Trunc(m_PtrToInt(m_Value(LHSOp)))) && match(Op1, m_Trunc(m_PtrToInt(m_Value(RHSOp))))) if (Value *Res = OptimizePointerDifference(LHSOp, RHSOp, I.getType())) return ReplaceInstUsesWith(I, Res); } return 0; }
bool LazyValueInfoCache::solveBlockValue(Value *Val, BasicBlock *BB) { if (isa<Constant>(Val)) return true; if (lookup(Val).count(BB)) { // If we have a cached value, use that. DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << lookup(Val)[BB] << '\n'); // Since we're reusing a cached value, we don't need to update the // OverDefinedCache. The cache will have been properly updated whenever the // cached value was inserted. return true; } // Hold off inserting this value into the Cache in case we have to return // false and come back later. LVILatticeVal Res; Instruction *BBI = dyn_cast<Instruction>(Val); if (!BBI || BBI->getParent() != BB) { if (!solveBlockValueNonLocal(Res, Val, BB)) return false; insertResult(Val, BB, Res); return true; } if (PHINode *PN = dyn_cast<PHINode>(BBI)) { if (!solveBlockValuePHINode(Res, PN, BB)) return false; insertResult(Val, BB, Res); return true; } if (AllocaInst *AI = dyn_cast<AllocaInst>(BBI)) { Res = LVILatticeVal::getNot(ConstantPointerNull::get(AI->getType())); insertResult(Val, BB, Res); return true; } // We can only analyze the definitions of certain classes of instructions // (integral binops and casts at the moment), so bail if this isn't one. LVILatticeVal Result; if ((!isa<BinaryOperator>(BBI) && !isa<CastInst>(BBI)) || !BBI->getType()->isIntegerTy()) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Res.markOverdefined(); insertResult(Val, BB, Res); return true; } // FIXME: We're currently limited to binops with a constant RHS. This should // be improved. BinaryOperator *BO = dyn_cast<BinaryOperator>(BBI); if (BO && !isa<ConstantInt>(BO->getOperand(1))) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Res.markOverdefined(); insertResult(Val, BB, Res); return true; } if (!solveBlockValueConstantRange(Res, BBI, BB)) return false; insertResult(Val, BB, Res); return true; }
Value *BoUpSLP::vectorizeTree(ValueList &VL, int VF) { Type *ScalarTy = VL[0]->getType(); if (StoreInst *SI = dyn_cast<StoreInst>(VL[0])) ScalarTy = SI->getValueOperand()->getType(); VectorType *VecTy = VectorType::get(ScalarTy, VF); // Check if all of the operands are constants or identical. bool AllConst = true; bool AllSameScalar = true; for (unsigned i = 0, e = VF; i < e; ++i) { AllConst &= !!dyn_cast<Constant>(VL[i]); AllSameScalar &= (VL[0] == VL[i]); // Must have a single use. Instruction *I = dyn_cast<Instruction>(VL[i]); if (I && (I->getNumUses() > 1 || I->getParent() != BB)) return Scalarize(VL, VecTy); } // Is this a simple vector constant. if (AllConst || AllSameScalar) return Scalarize(VL, VecTy); // Scalarize unknown structures. Instruction *VL0 = dyn_cast<Instruction>(VL[0]); if (!VL0) return Scalarize(VL, VecTy); unsigned Opcode = VL0->getOpcode(); for (unsigned i = 0, e = VF; i < e; ++i) { Instruction *I = dyn_cast<Instruction>(VL[i]); // If not all of the instructions are identical then we have to scalarize. if (!I || Opcode != I->getOpcode()) return Scalarize(VL, VecTy); } switch (Opcode) { case Instruction::Add: case Instruction::FAdd: case Instruction::Sub: case Instruction::FSub: case Instruction::Mul: case Instruction::FMul: case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: case Instruction::URem: case Instruction::SRem: case Instruction::FRem: case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: case Instruction::And: case Instruction::Or: case Instruction::Xor: { ValueList LHSVL, RHSVL; for (int i = 0; i < VF; ++i) { RHSVL.push_back(cast<Instruction>(VL[i])->getOperand(0)); LHSVL.push_back(cast<Instruction>(VL[i])->getOperand(1)); } Value *RHS = vectorizeTree(RHSVL, VF); Value *LHS = vectorizeTree(LHSVL, VF); IRBuilder<> Builder(GetLastInstr(VL, VF)); BinaryOperator *BinOp = dyn_cast<BinaryOperator>(VL0); return Builder.CreateBinOp(BinOp->getOpcode(), RHS,LHS); } case Instruction::Load: { LoadInst *LI = dyn_cast<LoadInst>(VL0); unsigned Alignment = LI->getAlignment(); // Check if all of the loads are consecutive. for (unsigned i = 1, e = VF; i < e; ++i) if (!isConsecutiveAccess(VL[i-1], VL[i])) return Scalarize(VL, VecTy); IRBuilder<> Builder(GetLastInstr(VL, VF)); Value *VecPtr = Builder.CreateBitCast(LI->getPointerOperand(), VecTy->getPointerTo()); LI = Builder.CreateLoad(VecPtr); LI->setAlignment(Alignment); return LI; } case Instruction::Store: { StoreInst *SI = dyn_cast<StoreInst>(VL0); unsigned Alignment = SI->getAlignment(); ValueList ValueOp; for (int i = 0; i < VF; ++i) ValueOp.push_back(cast<StoreInst>(VL[i])->getValueOperand()); Value *VecValue = vectorizeTree(ValueOp, VF); IRBuilder<> Builder(GetLastInstr(VL, VF)); Value *VecPtr = Builder.CreateBitCast(SI->getPointerOperand(), VecTy->getPointerTo()); Builder.CreateStore(VecValue, VecPtr)->setAlignment(Alignment); for (int i = 0; i < VF; ++i) cast<Instruction>(VL[i])->eraseFromParent(); return 0; } default: return Scalarize(VL, VecTy); } }
/// FoldSelectIntoOp - Try fold the select into one of the operands to /// facilitate further optimization. Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal, Value *FalseVal) { // See the comment above GetSelectFoldableOperands for a description of the // transformation we are doing here. if (Instruction *TVI = dyn_cast<Instruction>(TrueVal)) { if (TVI->hasOneUse() && TVI->getNumOperands() == 2 && !isa<Constant>(FalseVal)) { if (unsigned SFO = GetSelectFoldableOperands(TVI)) { unsigned OpToFold = 0; if ((SFO & 1) && FalseVal == TVI->getOperand(0)) { OpToFold = 1; } else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) { OpToFold = 2; } if (OpToFold) { Constant *C = GetSelectFoldableConstant(TVI); Value *OOp = TVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting // between 0, 1 and -1. if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) { Value *NewSel = Builder->CreateSelect(SI.getCondition(), OOp, C); NewSel->takeName(TVI); BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI); BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(), FalseVal, NewSel); if (isa<PossiblyExactOperator>(BO)) BO->setIsExact(TVI_BO->isExact()); if (isa<OverflowingBinaryOperator>(BO)) { BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap()); BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap()); } return BO; } } } } } if (Instruction *FVI = dyn_cast<Instruction>(FalseVal)) { if (FVI->hasOneUse() && FVI->getNumOperands() == 2 && !isa<Constant>(TrueVal)) { if (unsigned SFO = GetSelectFoldableOperands(FVI)) { unsigned OpToFold = 0; if ((SFO & 1) && TrueVal == FVI->getOperand(0)) { OpToFold = 1; } else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) { OpToFold = 2; } if (OpToFold) { Constant *C = GetSelectFoldableConstant(FVI); Value *OOp = FVI->getOperand(2-OpToFold); // Avoid creating select between 2 constants unless it's selecting // between 0, 1 and -1. if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) { Value *NewSel = Builder->CreateSelect(SI.getCondition(), C, OOp); NewSel->takeName(FVI); BinaryOperator *FVI_BO = cast<BinaryOperator>(FVI); BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(), TrueVal, NewSel); if (isa<PossiblyExactOperator>(BO)) BO->setIsExact(FVI_BO->isExact()); if (isa<OverflowingBinaryOperator>(BO)) { BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap()); BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap()); } return BO; } } } } } return 0; }
bool isRemainderWhenDevidingByTwo(Expr *expr) { BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(expr); return binaryOperator && binaryOperator->getOpcode() == BO_Rem && isIntegerLiteral(binaryOperator->getRHS(), 2); }
TEST(CloneInstruction, OverflowBits) { LLVMContext context; Value *V = new Argument(Type::getInt32Ty(context)); BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V); BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V); BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(); Sub->setHasNoUnsignedWrap(); Mul->setHasNoUnsignedWrap(); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); Add->setHasNoSignedWrap(); Sub->setHasNoSignedWrap(); Mul->setHasNoSignedWrap(); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); Add->setHasNoUnsignedWrap(false); Sub->setHasNoUnsignedWrap(false); Mul->setHasNoUnsignedWrap(false); EXPECT_FALSE(cast<BinaryOperator>(Add->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Add->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Sub->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Sub->clone())->hasNoSignedWrap()); EXPECT_FALSE(cast<BinaryOperator>(Mul->clone())->hasNoUnsignedWrap()); EXPECT_TRUE(cast<BinaryOperator>(Mul->clone())->hasNoSignedWrap()); }
static bool matchPairwiseReductionAtLevel(const BinaryOperator *BinOp, unsigned Level, unsigned NumLevels) { // Match one level of pairwise operations. // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef, // <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef> // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef, // <4 x i32> <i32 1, i32 3, i32 undef, i32 undef> // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1 if (BinOp == nullptr) return false; assert(BinOp->getType()->isVectorTy() && "Expecting a vector type"); unsigned Opcode = BinOp->getOpcode(); Value *L = BinOp->getOperand(0); Value *R = BinOp->getOperand(1); ShuffleVectorInst *LS = dyn_cast<ShuffleVectorInst>(L); if (!LS && Level) return false; ShuffleVectorInst *RS = dyn_cast<ShuffleVectorInst>(R); if (!RS && Level) return false; // On level 0 we can omit one shufflevector instruction. if (!Level && !RS && !LS) return false; // Shuffle inputs must match. Value *NextLevelOpL = LS ? LS->getOperand(0) : nullptr; Value *NextLevelOpR = RS ? RS->getOperand(0) : nullptr; Value *NextLevelOp = nullptr; if (NextLevelOpR && NextLevelOpL) { // If we have two shuffles their operands must match. if (NextLevelOpL != NextLevelOpR) return false; NextLevelOp = NextLevelOpL; } else if (Level == 0 && (NextLevelOpR || NextLevelOpL)) { // On the first level we can omit the shufflevector <0, undef,...>. So the // input to the other shufflevector <1, undef> must match with one of the // inputs to the current binary operation. // Example: // %NextLevelOpL = shufflevector %R, <1, undef ...> // %BinOp = fadd %NextLevelOpL, %R if (NextLevelOpL && NextLevelOpL != R) return false; else if (NextLevelOpR && NextLevelOpR != L) return false; NextLevelOp = NextLevelOpL ? R : L; } else return false; // Check that the next levels binary operation exists and matches with the // current one. BinaryOperator *NextLevelBinOp = nullptr; if (Level + 1 != NumLevels) { if (!(NextLevelBinOp = dyn_cast<BinaryOperator>(NextLevelOp))) return false; else if (NextLevelBinOp->getOpcode() != Opcode) return false; } // Shuffle mask for pairwise operation must match. if (matchPairwiseShuffleMask(LS, true, Level)) { if (!matchPairwiseShuffleMask(RS, false, Level)) return false; } else if (matchPairwiseShuffleMask(RS, true, Level)) { if (!matchPairwiseShuffleMask(LS, false, Level)) return false; } else return false; if (++Level == NumLevels) return true; // Match next level. return matchPairwiseReductionAtLevel(NextLevelBinOp, Level, NumLevels); }
// Peephole optimize the following instructions: // %t1 = cast ? to x * // %t2 = add x * %SP, %t1 ;; Constant must be 2nd operand // // Into: %t3 = getelementptr {<...>} * %SP, <element indices> // %t2 = cast <eltype> * %t3 to {<...>}* // static bool HandleCastToPointer(BasicBlock::iterator BI, const PointerType *DestPTy, const TargetData &TD) { CastInst &CI = cast<CastInst>(*BI); if (CI.use_empty()) return false; // Scan all of the uses, looking for any uses that are not add or sub // instructions. If we have non-adds, do not make this transformation. // bool HasSubUse = false; // Keep track of any subtracts... for (Value::use_iterator I = CI.use_begin(), E = CI.use_end(); I != E; ++I) if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*I)) { if ((BO->getOpcode() != Instruction::Add && BO->getOpcode() != Instruction::Sub) || // Avoid add sbyte* %X, %X cases... BO->getOperand(0) == BO->getOperand(1)) return false; else HasSubUse |= BO->getOpcode() == Instruction::Sub; } else { return false; } std::vector<Value*> Indices; Value *Src = CI.getOperand(0); const Type *Result = ConvertibleToGEP(DestPTy, Src, Indices, TD, &BI); if (Result == 0) return false; // Not convertible... // Cannot handle subtracts if there is more than one index required... if (HasSubUse && Indices.size() != 1) return false; PRINT_PEEPHOLE2("cast-add-to-gep:in", *Src, CI); // If we have a getelementptr capability... transform all of the // add instruction uses into getelementptr's. while (!CI.use_empty()) { BinaryOperator *I = cast<BinaryOperator>(*CI.use_begin()); assert((I->getOpcode() == Instruction::Add || I->getOpcode() == Instruction::Sub) && "Use is not a valid add instruction!"); // Get the value added to the cast result pointer... Value *OtherPtr = I->getOperand((I->getOperand(0) == &CI) ? 1 : 0); Instruction *GEP = new GetElementPtrInst(OtherPtr, Indices, I->getName()); PRINT_PEEPHOLE1("cast-add-to-gep:i", *I); // If the instruction is actually a subtract, we are guaranteed to only have // one index (from code above), so we just need to negate the pointer index // long value. if (I->getOpcode() == Instruction::Sub) { Instruction *Neg = BinaryOperator::createNeg(GEP->getOperand(1), GEP->getOperand(1)->getName()+".neg", I); GEP->setOperand(1, Neg); } if (GEP->getType() == I->getType()) { // Replace the old add instruction with the shiny new GEP inst ReplaceInstWithInst(I, GEP); } else { // If the type produced by the gep instruction differs from the original // add instruction type, insert a cast now. // // Insert the GEP instruction before the old add instruction... I->getParent()->getInstList().insert(I, GEP); PRINT_PEEPHOLE1("cast-add-to-gep:o", *GEP); GEP = new CastInst(GEP, I->getType()); // Replace the old add instruction with the shiny new GEP inst ReplaceInstWithInst(I, GEP); } PRINT_PEEPHOLE1("cast-add-to-gep:o", *GEP); } return true; }
void Lint::visitSub(BinaryOperator &I) { Assert(!isa<UndefValue>(I.getOperand(0)) || !isa<UndefValue>(I.getOperand(1)), "Undefined result: sub(undef, undef)", &I); }
bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) { Module &M = *F.getParent(); LLVMContext &C = F.getContext(); IRBuilder<> IRB(C); SmallVector<Instruction *, 64> ToErase; // Vector of %setjmpTable values std::vector<Instruction *> SetjmpTableInsts; // Vector of %setjmpTableSize values std::vector<Instruction *> SetjmpTableSizeInsts; // Setjmp preparation // This instruction effectively means %setjmpTableSize = 4. // We create this as an instruction intentionally, and we don't want to fold // this instruction to a constant 4, because this value will be used in // SSAUpdater.AddAvailableValue(...) later. BasicBlock &EntryBB = F.getEntryBlock(); BinaryOperator *SetjmpTableSize = BinaryOperator::Create( Instruction::Add, IRB.getInt32(4), IRB.getInt32(0), "setjmpTableSize", &*EntryBB.getFirstInsertionPt()); // setjmpTable = (int *) malloc(40); Instruction *SetjmpTable = CallInst::CreateMalloc( SetjmpTableSize, IRB.getInt32Ty(), IRB.getInt32Ty(), IRB.getInt32(40), nullptr, nullptr, "setjmpTable"); // setjmpTable[0] = 0; IRB.SetInsertPoint(SetjmpTableSize); IRB.CreateStore(IRB.getInt32(0), SetjmpTable); SetjmpTableInsts.push_back(SetjmpTable); SetjmpTableSizeInsts.push_back(SetjmpTableSize); // Setjmp transformation std::vector<PHINode *> SetjmpRetPHIs; Function *SetjmpF = M.getFunction("setjmp"); for (User *U : SetjmpF->users()) { auto *CI = dyn_cast<CallInst>(U); if (!CI) report_fatal_error("Does not support indirect calls to setjmp"); BasicBlock *BB = CI->getParent(); if (BB->getParent() != &F) // in other function continue; // The tail is everything right after the call, and will be reached once // when setjmp is called, and later when longjmp returns to the setjmp BasicBlock *Tail = SplitBlock(BB, CI->getNextNode()); // Add a phi to the tail, which will be the output of setjmp, which // indicates if this is the first call or a longjmp back. The phi directly // uses the right value based on where we arrive from IRB.SetInsertPoint(Tail->getFirstNonPHI()); PHINode *SetjmpRet = IRB.CreatePHI(IRB.getInt32Ty(), 2, "setjmp.ret"); // setjmp initial call returns 0 SetjmpRet->addIncoming(IRB.getInt32(0), BB); // The proper output is now this, not the setjmp call itself CI->replaceAllUsesWith(SetjmpRet); // longjmp returns to the setjmp will add themselves to this phi SetjmpRetPHIs.push_back(SetjmpRet); // Fix call target // Our index in the function is our place in the array + 1 to avoid index // 0, because index 0 means the longjmp is not ours to handle. IRB.SetInsertPoint(CI); Value *Args[] = {CI->getArgOperand(0), IRB.getInt32(SetjmpRetPHIs.size()), SetjmpTable, SetjmpTableSize}; Instruction *NewSetjmpTable = IRB.CreateCall(SaveSetjmpF, Args, "setjmpTable"); Instruction *NewSetjmpTableSize = IRB.CreateLoad(TempRet0GV, "setjmpTableSize"); SetjmpTableInsts.push_back(NewSetjmpTable); SetjmpTableSizeInsts.push_back(NewSetjmpTableSize); ToErase.push_back(CI); } // Update each call that can longjmp so it can return to a setjmp where // relevant. // Because we are creating new BBs while processing and don't want to make // all these newly created BBs candidates again for longjmp processing, we // first make the vector of candidate BBs. std::vector<BasicBlock *> BBs; for (BasicBlock &BB : F) BBs.push_back(&BB); // BBs.size() will change within the loop, so we query it every time for (unsigned i = 0; i < BBs.size(); i++) { BasicBlock *BB = BBs[i]; for (Instruction &I : *BB) { assert(!isa<InvokeInst>(&I)); auto *CI = dyn_cast<CallInst>(&I); if (!CI) continue; const Value *Callee = CI->getCalledValue(); if (!canLongjmp(M, Callee)) continue; Value *Threw = nullptr; BasicBlock *Tail; if (Callee->getName().startswith(InvokePrefix)) { // If invoke wrapper has already been generated for this call in // previous EH phase, search for the load instruction // %__THREW__.val = __THREW__; // in postamble after the invoke wrapper call LoadInst *ThrewLI = nullptr; StoreInst *ThrewResetSI = nullptr; for (auto I = std::next(BasicBlock::iterator(CI)), IE = BB->end(); I != IE; ++I) { if (auto *LI = dyn_cast<LoadInst>(I)) if (auto *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand())) if (GV == ThrewGV) { Threw = ThrewLI = LI; break; } } // Search for the store instruction after the load above // __THREW__ = 0; for (auto I = std::next(BasicBlock::iterator(ThrewLI)), IE = BB->end(); I != IE; ++I) { if (auto *SI = dyn_cast<StoreInst>(I)) if (auto *GV = dyn_cast<GlobalVariable>(SI->getPointerOperand())) if (GV == ThrewGV && SI->getValueOperand() == IRB.getInt32(0)) { ThrewResetSI = SI; break; } } assert(Threw && ThrewLI && "Cannot find __THREW__ load after invoke"); assert(ThrewResetSI && "Cannot find __THREW__ store after invoke"); Tail = SplitBlock(BB, ThrewResetSI->getNextNode()); } else { // Wrap call with invoke wrapper and generate preamble/postamble Threw = wrapInvoke(CI); ToErase.push_back(CI); Tail = SplitBlock(BB, CI->getNextNode()); } // We need to replace the terminator in Tail - SplitBlock makes BB go // straight to Tail, we need to check if a longjmp occurred, and go to the // right setjmp-tail if so ToErase.push_back(BB->getTerminator()); // Generate a function call to testSetjmp function and preamble/postamble // code to figure out (1) whether longjmp occurred (2) if longjmp // occurred, which setjmp it corresponds to Value *Label = nullptr; Value *LongjmpResult = nullptr; BasicBlock *EndBB = nullptr; wrapTestSetjmp(BB, CI, Threw, SetjmpTable, SetjmpTableSize, Label, LongjmpResult, EndBB); assert(Label && LongjmpResult && EndBB); // Create switch instruction IRB.SetInsertPoint(EndBB); SwitchInst *SI = IRB.CreateSwitch(Label, Tail, SetjmpRetPHIs.size()); // -1 means no longjmp happened, continue normally (will hit the default // switch case). 0 means a longjmp that is not ours to handle, needs a // rethrow. Otherwise the index is the same as the index in P+1 (to avoid // 0). for (unsigned i = 0; i < SetjmpRetPHIs.size(); i++) { SI->addCase(IRB.getInt32(i + 1), SetjmpRetPHIs[i]->getParent()); SetjmpRetPHIs[i]->addIncoming(LongjmpResult, EndBB); } // We are splitting the block here, and must continue to find other calls // in the block - which is now split. so continue to traverse in the Tail BBs.push_back(Tail); } } // Erase everything we no longer need in this function for (Instruction *I : ToErase) I->eraseFromParent(); // Free setjmpTable buffer before each return instruction for (BasicBlock &BB : F) { TerminatorInst *TI = BB.getTerminator(); if (isa<ReturnInst>(TI)) CallInst::CreateFree(SetjmpTable, TI); } // Every call to saveSetjmp can change setjmpTable and setjmpTableSize // (when buffer reallocation occurs) // entry: // setjmpTableSize = 4; // setjmpTable = (int *) malloc(40); // setjmpTable[0] = 0; // ... // somebb: // setjmpTable = saveSetjmp(buf, label, setjmpTable, setjmpTableSize); // setjmpTableSize = __tempRet0; // So we need to make sure the SSA for these variables is valid so that every // saveSetjmp and testSetjmp calls have the correct arguments. SSAUpdater SetjmpTableSSA; SSAUpdater SetjmpTableSizeSSA; SetjmpTableSSA.Initialize(Type::getInt32PtrTy(C), "setjmpTable"); SetjmpTableSizeSSA.Initialize(Type::getInt32Ty(C), "setjmpTableSize"); for (Instruction *I : SetjmpTableInsts) SetjmpTableSSA.AddAvailableValue(I->getParent(), I); for (Instruction *I : SetjmpTableSizeInsts) SetjmpTableSizeSSA.AddAvailableValue(I->getParent(), I); for (auto UI = SetjmpTable->use_begin(), UE = SetjmpTable->use_end(); UI != UE;) { // Grab the use before incrementing the iterator. Use &U = *UI; // Increment the iterator before removing the use from the list. ++UI; if (Instruction *I = dyn_cast<Instruction>(U.getUser())) if (I->getParent() != &EntryBB) SetjmpTableSSA.RewriteUse(U); } for (auto UI = SetjmpTableSize->use_begin(), UE = SetjmpTableSize->use_end(); UI != UE;) { Use &U = *UI; ++UI; if (Instruction *I = dyn_cast<Instruction>(U.getUser())) if (I->getParent() != &EntryBB) SetjmpTableSizeSSA.RewriteUse(U); } // Finally, our modifications to the cfg can break dominance of SSA variables. // For example, in this code, // if (x()) { .. setjmp() .. } // if (y()) { .. longjmp() .. } // We must split the longjmp block, and it can jump into the block splitted // from setjmp one. But that means that when we split the setjmp block, it's // first part no longer dominates its second part - there is a theoretically // possible control flow path where x() is false, then y() is true and we // reach the second part of the setjmp block, without ever reaching the first // part. So, we rebuild SSA form here. rebuildSSA(F); return true; }
void Lint::visitURem(BinaryOperator &I) { Assert(!isZero(I.getOperand(1), I.getModule()->getDataLayout(), DT, AC), "Undefined behavior: Division by zero", &I); }
void Lint::visitShl(BinaryOperator &I) { if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)->stripPointerCasts())) Assert1(CI->getValue().ult(cast<IntegerType>(I.getType())->getBitWidth()), "Undefined result: Shift count out of range", &I); }
/// InsertPHITranslatedPointer - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. /// This returns null on failure. /// Value *PHITransAddr:: InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, SmallVectorImpl<Instruction*> &NewInsts) { // See if we have a version of this value already available and dominating // PredBB. If so, there is no need to insert a new instance of it. PHITransAddr Tmp(InVal, TD); if (!Tmp.PHITranslateValue(CurBB, PredBB, &DT)) return Tmp.getAddr(); // If we don't have an available version of this value, it must be an // instruction. Instruction *Inst = cast<Instruction>(InVal); // Handle cast of PHI translatable value. if (CastInst *Cast = dyn_cast<CastInst>(Inst)) { if (!Cast->isSafeToSpeculativelyExecute()) return 0; Value *OpVal = InsertPHITranslatedSubExpr(Cast->getOperand(0), CurBB, PredBB, DT, NewInsts); if (OpVal == 0) return 0; // Otherwise insert a cast at the end of PredBB. CastInst *New = CastInst::Create(Cast->getOpcode(), OpVal, InVal->getType(), InVal->getName()+".phi.trans.insert", PredBB->getTerminator()); NewInsts.push_back(New); return New; } // Handle getelementptr with at least one PHI operand. if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) { SmallVector<Value*, 8> GEPOps; BasicBlock *CurBB = GEP->getParent(); for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i), CurBB, PredBB, DT, NewInsts); if (OpVal == 0) return 0; GEPOps.push_back(OpVal); } GetElementPtrInst *Result = GetElementPtrInst::Create(GEPOps[0], makeArrayRef(GEPOps).slice(1), InVal->getName()+".phi.trans.insert", PredBB->getTerminator()); Result->setIsInBounds(GEP->isInBounds()); NewInsts.push_back(Result); return Result; } #if 0 // FIXME: This code works, but it is unclear that we actually want to insert // a big chain of computation in order to make a value available in a block. // This needs to be evaluated carefully to consider its cost trade offs. // Handle add with a constant RHS. if (Inst->getOpcode() == Instruction::Add && isa<ConstantInt>(Inst->getOperand(1))) { // PHI translate the LHS. Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0), CurBB, PredBB, DT, NewInsts); if (OpVal == 0) return 0; BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1), InVal->getName()+".phi.trans.insert", PredBB->getTerminator()); Res->setHasNoSignedWrap(cast<BinaryOperator>(Inst)->hasNoSignedWrap()); Res->setHasNoUnsignedWrap(cast<BinaryOperator>(Inst)->hasNoUnsignedWrap()); NewInsts.push_back(Res); return Res; } #endif return 0; }
/* this helper function is called when the traversal reaches a node of type Stmt */ void StmtHelper(Stmt *x){ //variable used for <cond> </cond> //bool condition = false; bool isElse = false; if(x != NULL){ string output = ""; //find current level and next level int intLevel = getLevelStmt(x); int intNextLevel = intLevel+1; //convert them both to strings to use for output string level; string nextLevel; stringstream ss; ss << intLevel; level = ss.str(); stringstream ss2; ss2 << intNextLevel; nextLevel = ss2.str(); const Stmt* parent = getStmtParent(x, Context); //PROBLEM if(x->getStmtClassName() != std::string("ForStmt") && isFlowControl(x, Context)){ //return; } //if the parent is calling any type of funciton then this node should be enclosed in <args> </args> string filename; if(callStackDebug && !callStack.empty()){ cerr << "stmt: call stack top: " << callStack.top()->getStmtClassName() << endl; } while(!callStack.empty() && numClosingArgsNeeded > 0 && !isParentStmt(parent, callStack.top()->getStmtClassName())){ if(debugPrint){ cerr << "adding args" << endl; } numClosingArgsNeeded--; output += "</args,1>\n"; callStack.pop(); if(callStackDebug){ cerr << "popping" << endl; printCallStack(); } } if(isParentStmtInCurFile(x,"CXXConstructExpr") && isParentStmt(x, "CXXConstructExpr")){ if(debugPrint){ cerr << "setting previousConstructorCall to true" << endl; } }else if(isParentStmtInCurFile(x,"CXXTemporaryObjectExpr") && isParentStmt(x, "CXXTemporaryObjectExpr")){ if(debugPrint){ cerr << "setting previousTempConstructorCallArg" << endl; } }else if(isParentStmt(x, "CallExpr")){ if(debugPrint){ cerr << "setting previousCallArgs to true" << endl; } }else if(isParentStmt(x, "CXXMemberCallExpr")){ if(debugPrint){ cerr << "setting previousMemberCallArgs to true" << endl; } } //if the parent is a variable declaration then this node should be encolsed in <decl> </decl> if(isParentStmt(x, "Var")){ previousRhsDecl = true; if(debugPrint){ cout << "setting prev var to true" << endl; } }else if(previousRhsDecl && numClosingVarsNeeded > 0){ //if the current node is not a child of a variable declaration //but the previous node was a child of a variable declation //then we know to print a </decl> output +="</variableDecl,1>\n"; numClosingVarsNeeded--; previousRhsDecl = false; } if(parent != NULL && strcmp(parent->getStmtClassName(), "IfStmt") == 0){ if(debugPrint){ cerr << "possibly an if statement" << endl; } //find the first child of the if statemt const Stmt* firstChild = NULL; auto children = parent->children(); for(const Stmt* child : children){ if(child != NULL){ firstChild = child; break; } } //if the first child is the current node, then we know it is part of the condition if(firstChild != NULL && x->getLocStart() == firstChild->getLocStart()){ if(debugPrint){ cerr << "part of the condition" << endl; } prevCondition = true; }else if(prevCondition){ output +="</cond,1>\n"; prevCondition = false; } //find if else const IfStmt* ifstmt = (IfStmt*) parent; const Stmt* elseStmt = ifstmt->getElse(); if(elseStmt != NULL){ if(debugPrint){ cout << "checking if " << x->getLocStart().printToString(Context->getSourceManager()); cout << " == " << elseStmt->getLocStart().printToString(Context->getSourceManager()); cout << " : " << (x->getLocStart() == elseStmt->getLocStart()) << endl; } if(x->getLocStart() == elseStmt->getLocStart()){ isElse = true; } } } string node = x->getStmtClassName(); if(node == "ReturnStmt"){ output += "<return"; }else if(node == "ForStmt"){ output += "<forLoop"; }else if(node == "WhileStmt"){ output += "<whileLoop"; }else if(node == "DoStmt"){ output += "<do"; }else if(node == "IfStmt"){ if(parent->getStmtClassName() != std::string("IfStmt")){ stringstream ssminus; ssminus << (intLevel-1); output += "<ifBlock," + ssminus.str() + ">\n"; intLevel += 1; stringstream ssif; ssif << intLevel; level = ssif.str(); } output += "<ifStatement"; }else if(node == "SwitchStmt"){ output += "<switch"; }else if(node == "CaseStmt"){ output += "<case"; }else if(node == "CXXMemberCallExpr"){ CXXMemberCallExpr* ce = (CXXMemberCallExpr*) x; Expr* obj = ce->getImplicitObjectArgument(); CallExpr* expr = (CallExpr*) x; output += "<object: "; QualType qt = obj->getType(); output += qt.getBaseTypeIdentifier()->getName().str(); output += "; calling func: "; output += expr->getDirectCallee()->getNameInfo().getAsString(); output += ", " + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } }else if(node == "CallExpr"){ CallExpr* expr = (CallExpr*) x; output += "<calling func: "; output += expr->getDirectCallee()->getNameInfo().getAsString(); output += ", " + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } }else if(node == "CXXConstructExpr"){ CXXConstructExpr* ce = (CXXConstructExpr*) x; //Decl* CD = ce->getConstructor(); string filename; //if(isInCurFile(Context, CD, filename)){ CXXMethodDecl* MD = ce->getConstructor(); output += "<calling func: "; output += MD->getNameInfo().getAsString(); output += "," + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } //} }else if(node == "BinaryOperator"){ BinaryOperator* binaryOp = (BinaryOperator*) x; if(binaryOp->isAssignmentOp()){ output += "<assignment"; }else if(binaryOp->isComparisonOp()){ output += "<comparison"; }else{ output += "<binaryOp"; } }else if(node == "UnaryOperator"){ UnaryOperator* uo = (UnaryOperator*) x; string op = uo->getOpcodeStr(uo->getOpcode()).str(); if(op != "-"){ output += "<unaryOp"; } }else if(node == "CompoundAssignOperator"){ output += "<augAssign"; }else if(node == "CompoundStmt"){ if(isElse){ output += "<elseStatement"; }else{ output += "<compoundStmt"; } }else if(node == "CXXThrowExpr"){ output += "<raisingException"; }else if(node == "CXXTryStmt"){ output += "<try"; }else if(node == "CXXCatchStmt"){ output += "<except"; }else if(node == "CXXOperatorCallExpr"){ CXXOperatorCallExpr* ce = (CXXOperatorCallExpr*) x; if(ce->isAssignmentOp()){ output += "<assignment"; } }else if(node == "CXXTemporaryObjectExpr"){ CXXTemporaryObjectExpr* ce = (CXXTemporaryObjectExpr*) x; Decl* CD = ce->getConstructor(); string filename; if(isInCurFile(Context, CD, filename)){ CXXMethodDecl* MD = ce->getConstructor(); output += "<calling func: "; output += MD->getNameInfo().getAsString(); output += "," + level + ">\n"; output += "<args"; numClosingArgsNeeded++; callStack.push(x); if(callStackDebug){ cerr << "pushing" << endl; printCallStack(); } } }else if(node == "DeclRefExpr"){ if(parent != NULL && parent->getStmtClassName() == std::string("ImplicitCastExpr")){ DeclRefExpr* dr = (DeclRefExpr*) x; ValueDecl* d = (ValueDecl*) dr->getDecl(); //cout << d->getQualType().getAsString() << endl; if(d != NULL){ QualType qt = d->getType(); //cout << qt.getAsString() << endl; if(qt.getAsString() == "std::vector<int, class std::allocator<int> >::const_reference (std::vector::size_type) const noexcept"){ //string type = io->getName().str(); //cout << type << endl; //if(type == "vector"){ output += "<expr"; //} } } } }else{ if(allNodes){ output += "<"; output += node; output += ">"; } } if(output.size() != 0 && !endsIn(output, "</cond,1>\n") && !endsIn(output,"</variableDecl,1>\n") && !endsIn(output,"</args,1>\n") && !endsIn(output,">") && !endsIn(output, ">\n")){ output += ", " + level + ">"; cout << output << endl; output = ""; }else if(output.size() != 0){ cout << output << endl; output = ""; if(debugPrint){ cerr << "printing output" << endl; } } } }