summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/DemandedBits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/DemandedBits.cpp')
-rw-r--r--llvm/lib/Analysis/DemandedBits.cpp65
1 files changed, 44 insertions, 21 deletions
diff --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp
index 6bef77176cb..0382787fbef 100644
--- a/llvm/lib/Analysis/DemandedBits.cpp
+++ b/llvm/lib/Analysis/DemandedBits.cpp
@@ -39,6 +39,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/Pass.h"
@@ -50,6 +51,7 @@
#include <cstdint>
using namespace llvm;
+using namespace llvm::PatternMatch;
#define DEBUG_TYPE "demanded-bits"
@@ -143,17 +145,17 @@ void DemandedBits::determineLiveOperandBits(
}
break;
case Intrinsic::fshl:
- case Intrinsic::fshr:
+ case Intrinsic::fshr: {
+ const APInt *SA;
if (OperandNo == 2) {
// Shift amount is modulo the bitwidth. For powers of two we have
// SA % BW == SA & (BW - 1).
if (isPowerOf2_32(BitWidth))
AB = BitWidth - 1;
- } else if (auto *SA = dyn_cast<ConstantInt>(II->getOperand(2))) {
- // TODO: Support vectors.
+ } else if (match(II->getOperand(2), m_APInt(SA))) {
// Normalize to funnel shift left. APInt shifts of BitWidth are well-
// defined, so no need to special-case zero shifts here.
- uint64_t ShiftAmt = SA->getValue().urem(BitWidth);
+ uint64_t ShiftAmt = SA->urem(BitWidth);
if (II->getIntrinsicID() == Intrinsic::fshr)
ShiftAmt = BitWidth - ShiftAmt;
@@ -164,6 +166,7 @@ void DemandedBits::determineLiveOperandBits(
}
break;
}
+ }
break;
case Instruction::Add:
case Instruction::Sub:
@@ -174,8 +177,9 @@ void DemandedBits::determineLiveOperandBits(
AB = APInt::getLowBitsSet(BitWidth, AOut.getActiveBits());
break;
case Instruction::Shl:
- if (OperandNo == 0)
- if (auto *ShiftAmtC = dyn_cast<ConstantInt>(UserI->getOperand(1))) {
+ if (OperandNo == 0) {
+ const APInt *ShiftAmtC;
+ if (match(UserI->getOperand(1), m_APInt(ShiftAmtC))) {
uint64_t ShiftAmt = ShiftAmtC->getLimitedValue(BitWidth - 1);
AB = AOut.lshr(ShiftAmt);
@@ -187,10 +191,12 @@ void DemandedBits::determineLiveOperandBits(
else if (S->hasNoUnsignedWrap())
AB |= APInt::getHighBitsSet(BitWidth, ShiftAmt);
}
+ }
break;
case Instruction::LShr:
- if (OperandNo == 0)
- if (auto *ShiftAmtC = dyn_cast<ConstantInt>(UserI->getOperand(1))) {
+ if (OperandNo == 0) {
+ const APInt *ShiftAmtC;
+ if (match(UserI->getOperand(1), m_APInt(ShiftAmtC))) {
uint64_t ShiftAmt = ShiftAmtC->getLimitedValue(BitWidth - 1);
AB = AOut.shl(ShiftAmt);
@@ -199,10 +205,12 @@ void DemandedBits::determineLiveOperandBits(
if (cast<LShrOperator>(UserI)->isExact())
AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
}
+ }
break;
case Instruction::AShr:
- if (OperandNo == 0)
- if (auto *ShiftAmtC = dyn_cast<ConstantInt>(UserI->getOperand(1))) {
+ if (OperandNo == 0) {
+ const APInt *ShiftAmtC;
+ if (match(UserI->getOperand(1), m_APInt(ShiftAmtC))) {
uint64_t ShiftAmt = ShiftAmtC->getLimitedValue(BitWidth - 1);
AB = AOut.shl(ShiftAmt);
// Because the high input bit is replicated into the
@@ -217,6 +225,7 @@ void DemandedBits::determineLiveOperandBits(
if (cast<AShrOperator>(UserI)->isExact())
AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt);
}
+ }
break;
case Instruction::And:
AB = AOut;
@@ -274,6 +283,15 @@ void DemandedBits::determineLiveOperandBits(
if (OperandNo != 0)
AB = AOut;
break;
+ case Instruction::ExtractElement:
+ if (OperandNo == 0)
+ AB = AOut;
+ break;
+ case Instruction::InsertElement:
+ case Instruction::ShuffleVector:
+ if (OperandNo == 0 || OperandNo == 1)
+ AB = AOut;
+ break;
}
}
@@ -309,8 +327,9 @@ void DemandedBits::performAnalysis() {
// bits and add the instruction to the work list. For other instructions
// add their operands to the work list (for integer values operands, mark
// all bits as live).
- if (IntegerType *IT = dyn_cast<IntegerType>(I.getType())) {
- if (AliveBits.try_emplace(&I, IT->getBitWidth(), 0).second)
+ Type *T = I.getType();
+ if (T->isIntOrIntVectorTy()) {
+ if (AliveBits.try_emplace(&I, T->getScalarSizeInBits(), 0).second)
Worklist.push_back(&I);
continue;
@@ -319,8 +338,9 @@ void DemandedBits::performAnalysis() {
// Non-integer-typed instructions...
for (Use &OI : I.operands()) {
if (Instruction *J = dyn_cast<Instruction>(OI)) {
- if (IntegerType *IT = dyn_cast<IntegerType>(J->getType()))
- AliveBits[J] = APInt::getAllOnesValue(IT->getBitWidth());
+ Type *T = J->getType();
+ if (T->isIntOrIntVectorTy())
+ AliveBits[J] = APInt::getAllOnesValue(T->getScalarSizeInBits());
Worklist.push_back(J);
}
}
@@ -336,13 +356,13 @@ void DemandedBits::performAnalysis() {
LLVM_DEBUG(dbgs() << "DemandedBits: Visiting: " << *UserI);
APInt AOut;
- if (UserI->getType()->isIntegerTy()) {
+ if (UserI->getType()->isIntOrIntVectorTy()) {
AOut = AliveBits[UserI];
LLVM_DEBUG(dbgs() << " Alive Out: " << AOut);
}
LLVM_DEBUG(dbgs() << "\n");
- if (!UserI->getType()->isIntegerTy())
+ if (!UserI->getType()->isIntOrIntVectorTy())
Visited.insert(UserI);
KnownBits Known, Known2;
@@ -351,10 +371,11 @@ void DemandedBits::performAnalysis() {
// operand is added to the work-list.
for (Use &OI : UserI->operands()) {
if (Instruction *I = dyn_cast<Instruction>(OI)) {
- if (IntegerType *IT = dyn_cast<IntegerType>(I->getType())) {
- unsigned BitWidth = IT->getBitWidth();
+ Type *T = I->getType();
+ if (T->isIntOrIntVectorTy()) {
+ unsigned BitWidth = T->getScalarSizeInBits();
APInt AB = APInt::getAllOnesValue(BitWidth);
- if (UserI->getType()->isIntegerTy() && !AOut &&
+ if (UserI->getType()->isIntOrIntVectorTy() && !AOut &&
!isAlwaysLive(UserI)) {
AB = APInt(BitWidth, 0);
} else {
@@ -389,11 +410,13 @@ void DemandedBits::performAnalysis() {
APInt DemandedBits::getDemandedBits(Instruction *I) {
performAnalysis();
- const DataLayout &DL = I->getModule()->getDataLayout();
auto Found = AliveBits.find(I);
if (Found != AliveBits.end())
return Found->second;
- return APInt::getAllOnesValue(DL.getTypeSizeInBits(I->getType()));
+
+ const DataLayout &DL = I->getModule()->getDataLayout();
+ return APInt::getAllOnesValue(
+ DL.getTypeSizeInBits(I->getType()->getScalarType()));
}
bool DemandedBits::isInstructionDead(Instruction *I) {
OpenPOWER on IntegriCloud