138c02bc7SEugene Zelenko //===- DemandedBits.cpp - Determine demanded bits -------------------------===//
287405c7fSJames Molloy //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
687405c7fSJames Molloy //
787405c7fSJames Molloy //===----------------------------------------------------------------------===//
887405c7fSJames Molloy //
987405c7fSJames Molloy // This pass implements a demanded bits analysis. A demanded bit is one that
1087405c7fSJames Molloy // contributes to a result; bits that are not demanded can be either zero or
1187405c7fSJames Molloy // one without affecting control or data flow. For example in this sequence:
1287405c7fSJames Molloy //
1387405c7fSJames Molloy // %1 = add i32 %x, %y
1487405c7fSJames Molloy // %2 = trunc i32 %1 to i16
1587405c7fSJames Molloy //
1687405c7fSJames Molloy // Only the lowest 16 bits of %1 are demanded; the rest are removed by the
1787405c7fSJames Molloy // trunc.
1887405c7fSJames Molloy //
1987405c7fSJames Molloy //===----------------------------------------------------------------------===//
2087405c7fSJames Molloy
2187405c7fSJames Molloy #include "llvm/Analysis/DemandedBits.h"
2238c02bc7SEugene Zelenko #include "llvm/ADT/APInt.h"
235f393eb5SNikita Popov #include "llvm/ADT/SetVector.h"
24aec2fa35SDaniel Jasper #include "llvm/Analysis/AssumptionCache.h"
2587405c7fSJames Molloy #include "llvm/Analysis/ValueTracking.h"
2687405c7fSJames Molloy #include "llvm/IR/DataLayout.h"
2787405c7fSJames Molloy #include "llvm/IR/Dominators.h"
2887405c7fSJames Molloy #include "llvm/IR/InstIterator.h"
2938c02bc7SEugene Zelenko #include "llvm/IR/Instruction.h"
3087405c7fSJames Molloy #include "llvm/IR/IntrinsicInst.h"
3187405c7fSJames Molloy #include "llvm/IR/Module.h"
3287405c7fSJames Molloy #include "llvm/IR/Operator.h"
3338c02bc7SEugene Zelenko #include "llvm/IR/PassManager.h"
34110cf052SNikita Popov #include "llvm/IR/PatternMatch.h"
3538c02bc7SEugene Zelenko #include "llvm/IR/Type.h"
3638c02bc7SEugene Zelenko #include "llvm/IR/Use.h"
3705da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
3887405c7fSJames Molloy #include "llvm/Pass.h"
3938c02bc7SEugene Zelenko #include "llvm/Support/Casting.h"
4087405c7fSJames Molloy #include "llvm/Support/Debug.h"
41b45eabcfSCraig Topper #include "llvm/Support/KnownBits.h"
4287405c7fSJames Molloy #include "llvm/Support/raw_ostream.h"
4338c02bc7SEugene Zelenko #include <algorithm>
4438c02bc7SEugene Zelenko #include <cstdint>
4538c02bc7SEugene Zelenko
4687405c7fSJames Molloy using namespace llvm;
47110cf052SNikita Popov using namespace llvm::PatternMatch;
4887405c7fSJames Molloy
4987405c7fSJames Molloy #define DEBUG_TYPE "demanded-bits"
5087405c7fSJames Molloy
51de16b44fSMichael Kuperstein char DemandedBitsWrapperPass::ID = 0;
5238c02bc7SEugene Zelenko
53de16b44fSMichael Kuperstein INITIALIZE_PASS_BEGIN(DemandedBitsWrapperPass, "demanded-bits",
54de16b44fSMichael Kuperstein "Demanded bits analysis", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)55aec2fa35SDaniel Jasper INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
5687405c7fSJames Molloy INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
57de16b44fSMichael Kuperstein INITIALIZE_PASS_END(DemandedBitsWrapperPass, "demanded-bits",
58de16b44fSMichael Kuperstein "Demanded bits analysis", false, false)
5987405c7fSJames Molloy
60de16b44fSMichael Kuperstein DemandedBitsWrapperPass::DemandedBitsWrapperPass() : FunctionPass(ID) {
61de16b44fSMichael Kuperstein initializeDemandedBitsWrapperPassPass(*PassRegistry::getPassRegistry());
6287405c7fSJames Molloy }
6387405c7fSJames Molloy
getAnalysisUsage(AnalysisUsage & AU) const64de16b44fSMichael Kuperstein void DemandedBitsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
6587405c7fSJames Molloy AU.setPreservesCFG();
66aec2fa35SDaniel Jasper AU.addRequired<AssumptionCacheTracker>();
6787405c7fSJames Molloy AU.addRequired<DominatorTreeWrapperPass>();
6887405c7fSJames Molloy AU.setPreservesAll();
6987405c7fSJames Molloy }
7087405c7fSJames Molloy
print(raw_ostream & OS,const Module * M) const71de16b44fSMichael Kuperstein void DemandedBitsWrapperPass::print(raw_ostream &OS, const Module *M) const {
72de16b44fSMichael Kuperstein DB->print(OS);
73de16b44fSMichael Kuperstein }
74de16b44fSMichael Kuperstein
isAlwaysLive(Instruction * I)7587405c7fSJames Molloy static bool isAlwaysLive(Instruction *I) {
769ae926b9SChandler Carruth return I->isTerminator() || isa<DbgInfoIntrinsic>(I) || I->isEHPad() ||
7733146857SNikita Popov I->mayHaveSideEffects();
7887405c7fSJames Molloy }
7987405c7fSJames Molloy
determineLiveOperandBits(const Instruction * UserI,const Value * Val,unsigned OperandNo,const APInt & AOut,APInt & AB,KnownBits & Known,KnownBits & Known2,bool & KnownBitsComputed)800a7d0ad9SNAKAMURA Takumi void DemandedBits::determineLiveOperandBits(
816658fce4SNikita Popov const Instruction *UserI, const Value *Val, unsigned OperandNo,
826658fce4SNikita Popov const APInt &AOut, APInt &AB, KnownBits &Known, KnownBits &Known2,
836658fce4SNikita Popov bool &KnownBitsComputed) {
8487405c7fSJames Molloy unsigned BitWidth = AB.getBitWidth();
8587405c7fSJames Molloy
8687405c7fSJames Molloy // We're called once per operand, but for some instructions, we need to
8787405c7fSJames Molloy // compute known bits of both operands in order to determine the live bits of
8887405c7fSJames Molloy // either (when both operands are instructions themselves). We don't,
8987405c7fSJames Molloy // however, want to do this twice, so we cache the result in APInts that live
9087405c7fSJames Molloy // in the caller. For the two-relevant-operands case, both operand values are
9187405c7fSJames Molloy // provided here.
9287405c7fSJames Molloy auto ComputeKnownBits =
9387405c7fSJames Molloy [&](unsigned BitWidth, const Value *V1, const Value *V2) {
946658fce4SNikita Popov if (KnownBitsComputed)
956658fce4SNikita Popov return;
966658fce4SNikita Popov KnownBitsComputed = true;
976658fce4SNikita Popov
986658fce4SNikita Popov const DataLayout &DL = UserI->getModule()->getDataLayout();
99b45eabcfSCraig Topper Known = KnownBits(BitWidth);
1009fe35797SCraig Topper computeKnownBits(V1, Known, DL, 0, &AC, UserI, &DT);
10187405c7fSJames Molloy
10287405c7fSJames Molloy if (V2) {
103b45eabcfSCraig Topper Known2 = KnownBits(BitWidth);
1049fe35797SCraig Topper computeKnownBits(V2, Known2, DL, 0, &AC, UserI, &DT);
10587405c7fSJames Molloy }
10687405c7fSJames Molloy };
10787405c7fSJames Molloy
10887405c7fSJames Molloy switch (UserI->getOpcode()) {
10987405c7fSJames Molloy default: break;
11087405c7fSJames Molloy case Instruction::Call:
11187405c7fSJames Molloy case Instruction::Invoke:
11299e78cb7SNikita Popov if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(UserI)) {
11387405c7fSJames Molloy switch (II->getIntrinsicID()) {
11487405c7fSJames Molloy default: break;
11587405c7fSJames Molloy case Intrinsic::bswap:
11687405c7fSJames Molloy // The alive bits of the input are the swapped alive bits of
11787405c7fSJames Molloy // the output.
11887405c7fSJames Molloy AB = AOut.byteSwap();
11987405c7fSJames Molloy break;
1200a7894d9SBrian Gesiak case Intrinsic::bitreverse:
121bb8dbcf9SXin Tong // The alive bits of the input are the reversed alive bits of
122bb8dbcf9SXin Tong // the output.
1230a7894d9SBrian Gesiak AB = AOut.reverseBits();
1240a7894d9SBrian Gesiak break;
12587405c7fSJames Molloy case Intrinsic::ctlz:
12687405c7fSJames Molloy if (OperandNo == 0) {
12787405c7fSJames Molloy // We need some output bits, so we need all bits of the
12887405c7fSJames Molloy // input to the left of, and including, the leftmost bit
12987405c7fSJames Molloy // known to be one.
1306658fce4SNikita Popov ComputeKnownBits(BitWidth, Val, nullptr);
13187405c7fSJames Molloy AB = APInt::getHighBitsSet(BitWidth,
1328df66c60SCraig Topper std::min(BitWidth, Known.countMaxLeadingZeros()+1));
13387405c7fSJames Molloy }
13487405c7fSJames Molloy break;
13587405c7fSJames Molloy case Intrinsic::cttz:
13687405c7fSJames Molloy if (OperandNo == 0) {
13787405c7fSJames Molloy // We need some output bits, so we need all bits of the
13887405c7fSJames Molloy // input to the right of, and including, the rightmost bit
13987405c7fSJames Molloy // known to be one.
1406658fce4SNikita Popov ComputeKnownBits(BitWidth, Val, nullptr);
14187405c7fSJames Molloy AB = APInt::getLowBitsSet(BitWidth,
1428df66c60SCraig Topper std::min(BitWidth, Known.countMaxTrailingZeros()+1));
14387405c7fSJames Molloy }
14487405c7fSJames Molloy break;
145f94c8f0dSNikita Popov case Intrinsic::fshl:
146110cf052SNikita Popov case Intrinsic::fshr: {
147110cf052SNikita Popov const APInt *SA;
148f94c8f0dSNikita Popov if (OperandNo == 2) {
149f94c8f0dSNikita Popov // Shift amount is modulo the bitwidth. For powers of two we have
150f94c8f0dSNikita Popov // SA % BW == SA & (BW - 1).
151f94c8f0dSNikita Popov if (isPowerOf2_32(BitWidth))
152f94c8f0dSNikita Popov AB = BitWidth - 1;
153110cf052SNikita Popov } else if (match(II->getOperand(2), m_APInt(SA))) {
154f94c8f0dSNikita Popov // Normalize to funnel shift left. APInt shifts of BitWidth are well-
155f94c8f0dSNikita Popov // defined, so no need to special-case zero shifts here.
156110cf052SNikita Popov uint64_t ShiftAmt = SA->urem(BitWidth);
157f94c8f0dSNikita Popov if (II->getIntrinsicID() == Intrinsic::fshr)
158f94c8f0dSNikita Popov ShiftAmt = BitWidth - ShiftAmt;
159f94c8f0dSNikita Popov
160f94c8f0dSNikita Popov if (OperandNo == 0)
161f94c8f0dSNikita Popov AB = AOut.lshr(ShiftAmt);
162f94c8f0dSNikita Popov else if (OperandNo == 1)
163f94c8f0dSNikita Popov AB = AOut.shl(BitWidth - ShiftAmt);
164f94c8f0dSNikita Popov }
165f94c8f0dSNikita Popov break;
16687405c7fSJames Molloy }
167a5168bdbSNikita Popov case Intrinsic::umax:
168a5168bdbSNikita Popov case Intrinsic::umin:
169a5168bdbSNikita Popov case Intrinsic::smax:
170a5168bdbSNikita Popov case Intrinsic::smin:
171a5168bdbSNikita Popov // If low bits of result are not demanded, they are also not demanded
172a5168bdbSNikita Popov // for the min/max operands.
173a5168bdbSNikita Popov AB = APInt::getBitsSetFrom(BitWidth, AOut.countTrailingZeros());
174a5168bdbSNikita Popov break;
175110cf052SNikita Popov }
17699e78cb7SNikita Popov }
17787405c7fSJames Molloy break;
17887405c7fSJames Molloy case Instruction::Add:
179c1f6ce0cSSimon Pilgrim if (AOut.isMask()) {
180c1f6ce0cSSimon Pilgrim AB = AOut;
181c1f6ce0cSSimon Pilgrim } else {
182c1f6ce0cSSimon Pilgrim ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
183c1f6ce0cSSimon Pilgrim AB = determineLiveOperandBitsAdd(OperandNo, AOut, Known, Known2);
184c1f6ce0cSSimon Pilgrim }
185c1f6ce0cSSimon Pilgrim break;
18687405c7fSJames Molloy case Instruction::Sub:
187c1f6ce0cSSimon Pilgrim if (AOut.isMask()) {
188c1f6ce0cSSimon Pilgrim AB = AOut;
189c1f6ce0cSSimon Pilgrim } else {
190c1f6ce0cSSimon Pilgrim ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
191c1f6ce0cSSimon Pilgrim AB = determineLiveOperandBitsSub(OperandNo, AOut, Known, Known2);
192c1f6ce0cSSimon Pilgrim }
193c1f6ce0cSSimon Pilgrim break;
194bcd7f0acSJames Molloy case Instruction::Mul:
19587405c7fSJames Molloy // Find the highest live output bit. We don't need any more input
19687405c7fSJames Molloy // bits than that (adds, and thus subtracts, ripple only to the
19787405c7fSJames Molloy // left).
19887405c7fSJames Molloy AB = APInt::getLowBitsSet(BitWidth, AOut.getActiveBits());
19987405c7fSJames Molloy break;
20087405c7fSJames Molloy case Instruction::Shl:
201110cf052SNikita Popov if (OperandNo == 0) {
202110cf052SNikita Popov const APInt *ShiftAmtC;
203110cf052SNikita Popov if (match(UserI->getOperand(1), m_APInt(ShiftAmtC))) {
2041bbdf4e1SSanjay Patel uint64_t ShiftAmt = ShiftAmtC->getLimitedValue(BitWidth - 1);
20587405c7fSJames Molloy AB = AOut.lshr(ShiftAmt);
20687405c7fSJames Molloy
20787405c7fSJames Molloy // If the shift is nuw/nsw, then the high bits are not dead
20887405c7fSJames Molloy // (because we've promised that they *must* be zero).
20987405c7fSJames Molloy const ShlOperator *S = cast<ShlOperator>(UserI);
21087405c7fSJames Molloy if (S->hasNoSignedWrap())
21187405c7fSJames Molloy AB |= APInt::getHighBitsSet(BitWidth, ShiftAmt+1);
21287405c7fSJames Molloy else if (S->hasNoUnsignedWrap())
21387405c7fSJames Molloy AB |= APInt::getHighBitsSet(BitWidth, ShiftAmt);
21487405c7fSJames Molloy }
215110cf052SNikita Popov }
21687405c7fSJames Molloy break;
21787405c7fSJames Molloy case Instruction::LShr:
218110cf052SNikita Popov if (OperandNo == 0) {
219110cf052SNikita Popov const APInt *ShiftAmtC;
220110cf052SNikita Popov if (match(UserI->getOperand(1), m_APInt(ShiftAmtC))) {
2211bbdf4e1SSanjay Patel uint64_t ShiftAmt = ShiftAmtC->getLimitedValue(BitWidth - 1);
22287405c7fSJames Molloy AB = AOut.shl(ShiftAmt);
22387405c7fSJames Molloy
22487405c7fSJames Molloy // If the shift is exact, then the low bits are not dead
22587405c7fSJames Molloy // (they must be zero).
22687405c7fSJames Molloy if (cast<LShrOperator>(UserI)->isExact())
22787405c7fSJames Molloy AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
22887405c7fSJames Molloy }
229110cf052SNikita Popov }
23087405c7fSJames Molloy break;
23187405c7fSJames Molloy case Instruction::AShr:
232110cf052SNikita Popov if (OperandNo == 0) {
233110cf052SNikita Popov const APInt *ShiftAmtC;
234110cf052SNikita Popov if (match(UserI->getOperand(1), m_APInt(ShiftAmtC))) {
2351bbdf4e1SSanjay Patel uint64_t ShiftAmt = ShiftAmtC->getLimitedValue(BitWidth - 1);
23687405c7fSJames Molloy AB = AOut.shl(ShiftAmt);
23787405c7fSJames Molloy // Because the high input bit is replicated into the
23887405c7fSJames Molloy // high-order bits of the result, if we need any of those
23987405c7fSJames Molloy // bits, then we must keep the highest input bit.
24087405c7fSJames Molloy if ((AOut & APInt::getHighBitsSet(BitWidth, ShiftAmt))
24187405c7fSJames Molloy .getBoolValue())
24224db6b80SCraig Topper AB.setSignBit();
24387405c7fSJames Molloy
24487405c7fSJames Molloy // If the shift is exact, then the low bits are not dead
24587405c7fSJames Molloy // (they must be zero).
24687405c7fSJames Molloy if (cast<AShrOperator>(UserI)->isExact())
24787405c7fSJames Molloy AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
24887405c7fSJames Molloy }
249110cf052SNikita Popov }
25087405c7fSJames Molloy break;
25187405c7fSJames Molloy case Instruction::And:
25287405c7fSJames Molloy AB = AOut;
25387405c7fSJames Molloy
25487405c7fSJames Molloy // For bits that are known zero, the corresponding bits in the
25587405c7fSJames Molloy // other operand are dead (unless they're both zero, in which
25687405c7fSJames Molloy // case they can't both be dead, so just mark the LHS bits as
25787405c7fSJames Molloy // dead).
2586658fce4SNikita Popov ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
2596658fce4SNikita Popov if (OperandNo == 0)
260b45eabcfSCraig Topper AB &= ~Known2.Zero;
2616658fce4SNikita Popov else
262b45eabcfSCraig Topper AB &= ~(Known.Zero & ~Known2.Zero);
26387405c7fSJames Molloy break;
26487405c7fSJames Molloy case Instruction::Or:
26587405c7fSJames Molloy AB = AOut;
26687405c7fSJames Molloy
26787405c7fSJames Molloy // For bits that are known one, the corresponding bits in the
26887405c7fSJames Molloy // other operand are dead (unless they're both one, in which
26987405c7fSJames Molloy // case they can't both be dead, so just mark the LHS bits as
27087405c7fSJames Molloy // dead).
2716658fce4SNikita Popov ComputeKnownBits(BitWidth, UserI->getOperand(0), UserI->getOperand(1));
2726658fce4SNikita Popov if (OperandNo == 0)
273b45eabcfSCraig Topper AB &= ~Known2.One;
2746658fce4SNikita Popov else
275b45eabcfSCraig Topper AB &= ~(Known.One & ~Known2.One);
27687405c7fSJames Molloy break;
27787405c7fSJames Molloy case Instruction::Xor:
27887405c7fSJames Molloy case Instruction::PHI:
27987405c7fSJames Molloy AB = AOut;
28087405c7fSJames Molloy break;
28187405c7fSJames Molloy case Instruction::Trunc:
28287405c7fSJames Molloy AB = AOut.zext(BitWidth);
28387405c7fSJames Molloy break;
28487405c7fSJames Molloy case Instruction::ZExt:
28587405c7fSJames Molloy AB = AOut.trunc(BitWidth);
28687405c7fSJames Molloy break;
28787405c7fSJames Molloy case Instruction::SExt:
28887405c7fSJames Molloy AB = AOut.trunc(BitWidth);
28987405c7fSJames Molloy // Because the high input bit is replicated into the
29087405c7fSJames Molloy // high-order bits of the result, if we need any of those
29187405c7fSJames Molloy // bits, then we must keep the highest input bit.
29287405c7fSJames Molloy if ((AOut & APInt::getHighBitsSet(AOut.getBitWidth(),
29387405c7fSJames Molloy AOut.getBitWidth() - BitWidth))
29487405c7fSJames Molloy .getBoolValue())
29524db6b80SCraig Topper AB.setSignBit();
29687405c7fSJames Molloy break;
29787405c7fSJames Molloy case Instruction::Select:
29887405c7fSJames Molloy if (OperandNo != 0)
29987405c7fSJames Molloy AB = AOut;
30087405c7fSJames Molloy break;
301110cf052SNikita Popov case Instruction::ExtractElement:
302110cf052SNikita Popov if (OperandNo == 0)
303110cf052SNikita Popov AB = AOut;
304110cf052SNikita Popov break;
305110cf052SNikita Popov case Instruction::InsertElement:
306110cf052SNikita Popov case Instruction::ShuffleVector:
307110cf052SNikita Popov if (OperandNo == 0 || OperandNo == 1)
308110cf052SNikita Popov AB = AOut;
309110cf052SNikita Popov break;
31087405c7fSJames Molloy }
31187405c7fSJames Molloy }
31287405c7fSJames Molloy
runOnFunction(Function & F)313de16b44fSMichael Kuperstein bool DemandedBitsWrapperPass::runOnFunction(Function &F) {
314aec2fa35SDaniel Jasper auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
315de16b44fSMichael Kuperstein auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
316aec2fa35SDaniel Jasper DB.emplace(F, AC, DT);
317ab9fdb92SJames Molloy return false;
318ab9fdb92SJames Molloy }
319ab9fdb92SJames Molloy
releaseMemory()320de16b44fSMichael Kuperstein void DemandedBitsWrapperPass::releaseMemory() {
321de16b44fSMichael Kuperstein DB.reset();
322de16b44fSMichael Kuperstein }
323de16b44fSMichael Kuperstein
performAnalysis()324ab9fdb92SJames Molloy void DemandedBits::performAnalysis() {
325ab9fdb92SJames Molloy if (Analyzed)
326ab9fdb92SJames Molloy // Analysis already completed for this function.
327ab9fdb92SJames Molloy return;
328ab9fdb92SJames Molloy Analyzed = true;
32987405c7fSJames Molloy
33087405c7fSJames Molloy Visited.clear();
33187405c7fSJames Molloy AliveBits.clear();
332bc9986e9SNikita Popov DeadUses.clear();
33387405c7fSJames Molloy
3345f393eb5SNikita Popov SmallSetVector<Instruction*, 16> Worklist;
33587405c7fSJames Molloy
33687405c7fSJames Molloy // Collect the set of "root" instructions that are known live.
337de16b44fSMichael Kuperstein for (Instruction &I : instructions(F)) {
33887405c7fSJames Molloy if (!isAlwaysLive(&I))
33987405c7fSJames Molloy continue;
34087405c7fSJames Molloy
341d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "DemandedBits: Root: " << I << "\n");
34287405c7fSJames Molloy // For integer-valued instructions, set up an initial empty set of alive
34387405c7fSJames Molloy // bits and add the instruction to the work list. For other instructions
34487405c7fSJames Molloy // add their operands to the work list (for integer values operands, mark
34587405c7fSJames Molloy // all bits as live).
346110cf052SNikita Popov Type *T = I.getType();
347110cf052SNikita Popov if (T->isIntOrIntVectorTy()) {
348110cf052SNikita Popov if (AliveBits.try_emplace(&I, T->getScalarSizeInBits(), 0).second)
3495f393eb5SNikita Popov Worklist.insert(&I);
35087405c7fSJames Molloy
35187405c7fSJames Molloy continue;
35287405c7fSJames Molloy }
35387405c7fSJames Molloy
35487405c7fSJames Molloy // Non-integer-typed instructions...
35587405c7fSJames Molloy for (Use &OI : I.operands()) {
35687405c7fSJames Molloy if (Instruction *J = dyn_cast<Instruction>(OI)) {
357110cf052SNikita Popov Type *T = J->getType();
358110cf052SNikita Popov if (T->isIntOrIntVectorTy())
359*735f4671SChris Lattner AliveBits[J] = APInt::getAllOnes(T->getScalarSizeInBits());
3605fa53d15SFangrui Song else
3615fa53d15SFangrui Song Visited.insert(J);
3625f393eb5SNikita Popov Worklist.insert(J);
36387405c7fSJames Molloy }
36487405c7fSJames Molloy }
36587405c7fSJames Molloy // To save memory, we don't add I to the Visited set here. Instead, we
36687405c7fSJames Molloy // check isAlwaysLive on every instruction when searching for dead
36787405c7fSJames Molloy // instructions later (we need to check isAlwaysLive for the
36887405c7fSJames Molloy // integer-typed instructions anyway).
36987405c7fSJames Molloy }
37087405c7fSJames Molloy
37187405c7fSJames Molloy // Propagate liveness backwards to operands.
37287405c7fSJames Molloy while (!Worklist.empty()) {
37387405c7fSJames Molloy Instruction *UserI = Worklist.pop_back_val();
37487405c7fSJames Molloy
375d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "DemandedBits: Visiting: " << *UserI);
37687405c7fSJames Molloy APInt AOut;
3775fa53d15SFangrui Song bool InputIsKnownDead = false;
378110cf052SNikita Popov if (UserI->getType()->isIntOrIntVectorTy()) {
37987405c7fSJames Molloy AOut = AliveBits[UserI];
380bc9986e9SNikita Popov LLVM_DEBUG(dbgs() << " Alive Out: 0x"
381bc9986e9SNikita Popov << Twine::utohexstr(AOut.getLimitedValue()));
3825fa53d15SFangrui Song
3835fa53d15SFangrui Song // If all bits of the output are dead, then all bits of the input
3845fa53d15SFangrui Song // are also dead.
3855fa53d15SFangrui Song InputIsKnownDead = !AOut && !isAlwaysLive(UserI);
38687405c7fSJames Molloy }
387d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "\n");
38887405c7fSJames Molloy
389b45eabcfSCraig Topper KnownBits Known, Known2;
3906658fce4SNikita Popov bool KnownBitsComputed = false;
39187405c7fSJames Molloy // Compute the set of alive bits for each operand. These are anded into the
39287405c7fSJames Molloy // existing set, if any, and if that changes the set of alive bits, the
39387405c7fSJames Molloy // operand is added to the work-list.
39487405c7fSJames Molloy for (Use &OI : UserI->operands()) {
3956658fce4SNikita Popov // We also want to detect dead uses of arguments, but will only store
3966658fce4SNikita Popov // demanded bits for instructions.
3976658fce4SNikita Popov Instruction *I = dyn_cast<Instruction>(OI);
3986658fce4SNikita Popov if (!I && !isa<Argument>(OI))
3996658fce4SNikita Popov continue;
4006658fce4SNikita Popov
4016658fce4SNikita Popov Type *T = OI->getType();
402110cf052SNikita Popov if (T->isIntOrIntVectorTy()) {
403110cf052SNikita Popov unsigned BitWidth = T->getScalarSizeInBits();
404*735f4671SChris Lattner APInt AB = APInt::getAllOnes(BitWidth);
4055fa53d15SFangrui Song if (InputIsKnownDead) {
406649e1254SNikita Popov AB = APInt(BitWidth, 0);
407649e1254SNikita Popov } else {
408649e1254SNikita Popov // Bits of each operand that are used to compute alive bits of the
409649e1254SNikita Popov // output are alive, all others are dead.
4106658fce4SNikita Popov determineLiveOperandBits(UserI, OI, OI.getOperandNo(), AOut, AB,
4116658fce4SNikita Popov Known, Known2, KnownBitsComputed);
412bc9986e9SNikita Popov
413bc9986e9SNikita Popov // Keep track of uses which have no demanded bits.
414*735f4671SChris Lattner if (AB.isZero())
415bc9986e9SNikita Popov DeadUses.insert(&OI);
416bc9986e9SNikita Popov else
417bc9986e9SNikita Popov DeadUses.erase(&OI);
418649e1254SNikita Popov }
419649e1254SNikita Popov
4206658fce4SNikita Popov if (I) {
421649e1254SNikita Popov // If we've added to the set of alive bits (or the operand has not
422649e1254SNikita Popov // been previously visited), then re-queue the operand to be visited
423649e1254SNikita Popov // again.
424981f216dSFangrui Song auto Res = AliveBits.try_emplace(I);
425981f216dSFangrui Song if (Res.second || (AB |= Res.first->second) != Res.first->second) {
426981f216dSFangrui Song Res.first->second = std::move(AB);
4275f393eb5SNikita Popov Worklist.insert(I);
42887405c7fSJames Molloy }
42987405c7fSJames Molloy }
4305fa53d15SFangrui Song } else if (I && Visited.insert(I).second) {
4315f393eb5SNikita Popov Worklist.insert(I);
43287405c7fSJames Molloy }
43387405c7fSJames Molloy }
43487405c7fSJames Molloy }
43587405c7fSJames Molloy }
43687405c7fSJames Molloy
getDemandedBits(Instruction * I)43787405c7fSJames Molloy APInt DemandedBits::getDemandedBits(Instruction *I) {
438cf65b920SNikita Popov performAnalysis();
43914ca9a83SNikita Popov
440a9e477b2SBenjamin Kramer auto Found = AliveBits.find(I);
441a9e477b2SBenjamin Kramer if (Found != AliveBits.end())
442a9e477b2SBenjamin Kramer return Found->second;
443110cf052SNikita Popov
444110cf052SNikita Popov const DataLayout &DL = I->getModule()->getDataLayout();
445*735f4671SChris Lattner return APInt::getAllOnes(DL.getTypeSizeInBits(I->getType()->getScalarType()));
44687405c7fSJames Molloy }
44787405c7fSJames Molloy
getDemandedBits(Use * U)448cbde2487SQunyan Mangus APInt DemandedBits::getDemandedBits(Use *U) {
449cbde2487SQunyan Mangus Type *T = (*U)->getType();
450cbde2487SQunyan Mangus Instruction *UserI = cast<Instruction>(U->getUser());
451cbde2487SQunyan Mangus const DataLayout &DL = UserI->getModule()->getDataLayout();
452cbde2487SQunyan Mangus unsigned BitWidth = DL.getTypeSizeInBits(T->getScalarType());
453cbde2487SQunyan Mangus
454cbde2487SQunyan Mangus // We only track integer uses, everything else produces a mask with all bits
455cbde2487SQunyan Mangus // set
456cbde2487SQunyan Mangus if (!T->isIntOrIntVectorTy())
457*735f4671SChris Lattner return APInt::getAllOnes(BitWidth);
458cbde2487SQunyan Mangus
459cbde2487SQunyan Mangus if (isUseDead(U))
460cbde2487SQunyan Mangus return APInt(BitWidth, 0);
461cbde2487SQunyan Mangus
462cbde2487SQunyan Mangus performAnalysis();
463cbde2487SQunyan Mangus
464cbde2487SQunyan Mangus APInt AOut = getDemandedBits(UserI);
465*735f4671SChris Lattner APInt AB = APInt::getAllOnes(BitWidth);
466cbde2487SQunyan Mangus KnownBits Known, Known2;
467cbde2487SQunyan Mangus bool KnownBitsComputed = false;
468cbde2487SQunyan Mangus
469cbde2487SQunyan Mangus determineLiveOperandBits(UserI, *U, U->getOperandNo(), AOut, AB, Known,
470cbde2487SQunyan Mangus Known2, KnownBitsComputed);
471cbde2487SQunyan Mangus
472cbde2487SQunyan Mangus return AB;
473cbde2487SQunyan Mangus }
474cbde2487SQunyan Mangus
isInstructionDead(Instruction * I)47587405c7fSJames Molloy bool DemandedBits::isInstructionDead(Instruction *I) {
476ab9fdb92SJames Molloy performAnalysis();
477ab9fdb92SJames Molloy
47887405c7fSJames Molloy return !Visited.count(I) && AliveBits.find(I) == AliveBits.end() &&
47987405c7fSJames Molloy !isAlwaysLive(I);
48087405c7fSJames Molloy }
48187405c7fSJames Molloy
isUseDead(Use * U)482bc9986e9SNikita Popov bool DemandedBits::isUseDead(Use *U) {
483bc9986e9SNikita Popov // We only track integer uses, everything else is assumed live.
484bc9986e9SNikita Popov if (!(*U)->getType()->isIntOrIntVectorTy())
485bc9986e9SNikita Popov return false;
486bc9986e9SNikita Popov
487bc9986e9SNikita Popov // Uses by always-live instructions are never dead.
488bc9986e9SNikita Popov Instruction *UserI = cast<Instruction>(U->getUser());
489bc9986e9SNikita Popov if (isAlwaysLive(UserI))
490bc9986e9SNikita Popov return false;
491bc9986e9SNikita Popov
492bc9986e9SNikita Popov performAnalysis();
493bc9986e9SNikita Popov if (DeadUses.count(U))
494bc9986e9SNikita Popov return true;
495bc9986e9SNikita Popov
496bc9986e9SNikita Popov // If no output bits are demanded, no input bits are demanded and the use
497bc9986e9SNikita Popov // is dead. These uses might not be explicitly present in the DeadUses map.
498bc9986e9SNikita Popov if (UserI->getType()->isIntOrIntVectorTy()) {
499bc9986e9SNikita Popov auto Found = AliveBits.find(UserI);
500*735f4671SChris Lattner if (Found != AliveBits.end() && Found->second.isZero())
501bc9986e9SNikita Popov return true;
502bc9986e9SNikita Popov }
503bc9986e9SNikita Popov
504bc9986e9SNikita Popov return false;
505bc9986e9SNikita Popov }
506bc9986e9SNikita Popov
print(raw_ostream & OS)507de16b44fSMichael Kuperstein void DemandedBits::print(raw_ostream &OS) {
508cbde2487SQunyan Mangus auto PrintDB = [&](const Instruction *I, const APInt &A, Value *V = nullptr) {
509cbde2487SQunyan Mangus OS << "DemandedBits: 0x" << Twine::utohexstr(A.getLimitedValue())
510cbde2487SQunyan Mangus << " for ";
511cbde2487SQunyan Mangus if (V) {
512cbde2487SQunyan Mangus V->printAsOperand(OS, false);
513cbde2487SQunyan Mangus OS << " in ";
514cbde2487SQunyan Mangus }
515cbde2487SQunyan Mangus OS << *I << '\n';
516cbde2487SQunyan Mangus };
517cbde2487SQunyan Mangus
518de16b44fSMichael Kuperstein performAnalysis();
519bcd7f0acSJames Molloy for (auto &KV : AliveBits) {
520cbde2487SQunyan Mangus Instruction *I = KV.first;
521cbde2487SQunyan Mangus PrintDB(I, KV.second);
522cbde2487SQunyan Mangus
523cbde2487SQunyan Mangus for (Use &OI : I->operands()) {
524cbde2487SQunyan Mangus PrintDB(I, getDemandedBits(&OI), OI);
525cbde2487SQunyan Mangus }
526bcd7f0acSJames Molloy }
527bcd7f0acSJames Molloy }
528bcd7f0acSJames Molloy
determineLiveOperandBitsAddCarry(unsigned OperandNo,const APInt & AOut,const KnownBits & LHS,const KnownBits & RHS,bool CarryZero,bool CarryOne)529c1f6ce0cSSimon Pilgrim static APInt determineLiveOperandBitsAddCarry(unsigned OperandNo,
530c1f6ce0cSSimon Pilgrim const APInt &AOut,
531c1f6ce0cSSimon Pilgrim const KnownBits &LHS,
532c1f6ce0cSSimon Pilgrim const KnownBits &RHS,
533c1f6ce0cSSimon Pilgrim bool CarryZero, bool CarryOne) {
534c1f6ce0cSSimon Pilgrim assert(!(CarryZero && CarryOne) &&
535c1f6ce0cSSimon Pilgrim "Carry can't be zero and one at the same time");
536c1f6ce0cSSimon Pilgrim
537c1f6ce0cSSimon Pilgrim // The following check should be done by the caller, as it also indicates
538c1f6ce0cSSimon Pilgrim // that LHS and RHS don't need to be computed.
539c1f6ce0cSSimon Pilgrim //
540c1f6ce0cSSimon Pilgrim // if (AOut.isMask())
541c1f6ce0cSSimon Pilgrim // return AOut;
542c1f6ce0cSSimon Pilgrim
543c1f6ce0cSSimon Pilgrim // Boundary bits' carry out is unaffected by their carry in.
544c1f6ce0cSSimon Pilgrim APInt Bound = (LHS.Zero & RHS.Zero) | (LHS.One & RHS.One);
545c1f6ce0cSSimon Pilgrim
546c1f6ce0cSSimon Pilgrim // First, the alive carry bits are determined from the alive output bits:
547c1f6ce0cSSimon Pilgrim // Let demand ripple to the right but only up to any set bit in Bound.
548c1f6ce0cSSimon Pilgrim // AOut = -1----
549c1f6ce0cSSimon Pilgrim // Bound = ----1-
550c1f6ce0cSSimon Pilgrim // ACarry&~AOut = --111-
551c1f6ce0cSSimon Pilgrim APInt RBound = Bound.reverseBits();
552c1f6ce0cSSimon Pilgrim APInt RAOut = AOut.reverseBits();
553c1f6ce0cSSimon Pilgrim APInt RProp = RAOut + (RAOut | ~RBound);
554c1f6ce0cSSimon Pilgrim APInt RACarry = RProp ^ ~RBound;
555c1f6ce0cSSimon Pilgrim APInt ACarry = RACarry.reverseBits();
556c1f6ce0cSSimon Pilgrim
557c1f6ce0cSSimon Pilgrim // Then, the alive input bits are determined from the alive carry bits:
558c1f6ce0cSSimon Pilgrim APInt NeededToMaintainCarryZero;
559c1f6ce0cSSimon Pilgrim APInt NeededToMaintainCarryOne;
560c1f6ce0cSSimon Pilgrim if (OperandNo == 0) {
561c1f6ce0cSSimon Pilgrim NeededToMaintainCarryZero = LHS.Zero | ~RHS.Zero;
562c1f6ce0cSSimon Pilgrim NeededToMaintainCarryOne = LHS.One | ~RHS.One;
563c1f6ce0cSSimon Pilgrim } else {
564c1f6ce0cSSimon Pilgrim NeededToMaintainCarryZero = RHS.Zero | ~LHS.Zero;
565c1f6ce0cSSimon Pilgrim NeededToMaintainCarryOne = RHS.One | ~LHS.One;
566c1f6ce0cSSimon Pilgrim }
567c1f6ce0cSSimon Pilgrim
568c1f6ce0cSSimon Pilgrim // As in computeForAddCarry
569c1f6ce0cSSimon Pilgrim APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + !CarryZero;
570c1f6ce0cSSimon Pilgrim APInt PossibleSumOne = LHS.One + RHS.One + CarryOne;
571c1f6ce0cSSimon Pilgrim
572c1f6ce0cSSimon Pilgrim // The below is simplified from
573c1f6ce0cSSimon Pilgrim //
574c1f6ce0cSSimon Pilgrim // APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero);
575c1f6ce0cSSimon Pilgrim // APInt CarryKnownOne = PossibleSumOne ^ LHS.One ^ RHS.One;
576c1f6ce0cSSimon Pilgrim // APInt CarryUnknown = ~(CarryKnownZero | CarryKnownOne);
577c1f6ce0cSSimon Pilgrim //
578c1f6ce0cSSimon Pilgrim // APInt NeededToMaintainCarry =
579c1f6ce0cSSimon Pilgrim // (CarryKnownZero & NeededToMaintainCarryZero) |
580c1f6ce0cSSimon Pilgrim // (CarryKnownOne & NeededToMaintainCarryOne) |
581c1f6ce0cSSimon Pilgrim // CarryUnknown;
582c1f6ce0cSSimon Pilgrim
583c1f6ce0cSSimon Pilgrim APInt NeededToMaintainCarry = (~PossibleSumZero | NeededToMaintainCarryZero) &
584c1f6ce0cSSimon Pilgrim (PossibleSumOne | NeededToMaintainCarryOne);
585c1f6ce0cSSimon Pilgrim
586c1f6ce0cSSimon Pilgrim APInt AB = AOut | (ACarry & NeededToMaintainCarry);
587c1f6ce0cSSimon Pilgrim return AB;
588c1f6ce0cSSimon Pilgrim }
589c1f6ce0cSSimon Pilgrim
determineLiveOperandBitsAdd(unsigned OperandNo,const APInt & AOut,const KnownBits & LHS,const KnownBits & RHS)590c1f6ce0cSSimon Pilgrim APInt DemandedBits::determineLiveOperandBitsAdd(unsigned OperandNo,
591c1f6ce0cSSimon Pilgrim const APInt &AOut,
592c1f6ce0cSSimon Pilgrim const KnownBits &LHS,
593c1f6ce0cSSimon Pilgrim const KnownBits &RHS) {
594c1f6ce0cSSimon Pilgrim return determineLiveOperandBitsAddCarry(OperandNo, AOut, LHS, RHS, true,
595c1f6ce0cSSimon Pilgrim false);
596c1f6ce0cSSimon Pilgrim }
597c1f6ce0cSSimon Pilgrim
determineLiveOperandBitsSub(unsigned OperandNo,const APInt & AOut,const KnownBits & LHS,const KnownBits & RHS)598c1f6ce0cSSimon Pilgrim APInt DemandedBits::determineLiveOperandBitsSub(unsigned OperandNo,
599c1f6ce0cSSimon Pilgrim const APInt &AOut,
600c1f6ce0cSSimon Pilgrim const KnownBits &LHS,
601c1f6ce0cSSimon Pilgrim const KnownBits &RHS) {
602c1f6ce0cSSimon Pilgrim KnownBits NRHS;
603c1f6ce0cSSimon Pilgrim NRHS.Zero = RHS.One;
604c1f6ce0cSSimon Pilgrim NRHS.One = RHS.Zero;
605c1f6ce0cSSimon Pilgrim return determineLiveOperandBitsAddCarry(OperandNo, AOut, LHS, NRHS, false,
606c1f6ce0cSSimon Pilgrim true);
607c1f6ce0cSSimon Pilgrim }
608c1f6ce0cSSimon Pilgrim
createDemandedBitsWrapperPass()609de16b44fSMichael Kuperstein FunctionPass *llvm::createDemandedBitsWrapperPass() {
610de16b44fSMichael Kuperstein return new DemandedBitsWrapperPass();
611de16b44fSMichael Kuperstein }
612de16b44fSMichael Kuperstein
613dab4eae2SChandler Carruth AnalysisKey DemandedBitsAnalysis::Key;
614de16b44fSMichael Kuperstein
run(Function & F,FunctionAnalysisManager & AM)615de16b44fSMichael Kuperstein DemandedBits DemandedBitsAnalysis::run(Function &F,
61636e0d01eSSean Silva FunctionAnalysisManager &AM) {
617aec2fa35SDaniel Jasper auto &AC = AM.getResult<AssumptionAnalysis>(F);
618de16b44fSMichael Kuperstein auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
619aec2fa35SDaniel Jasper return DemandedBits(F, AC, DT);
620de16b44fSMichael Kuperstein }
621de16b44fSMichael Kuperstein
run(Function & F,FunctionAnalysisManager & AM)622de16b44fSMichael Kuperstein PreservedAnalyses DemandedBitsPrinterPass::run(Function &F,
623de16b44fSMichael Kuperstein FunctionAnalysisManager &AM) {
624de16b44fSMichael Kuperstein AM.getResult<DemandedBitsAnalysis>(F).print(OS);
625de16b44fSMichael Kuperstein return PreservedAnalyses::all();
62687405c7fSJames Molloy }
627