Port DemandedBits to the new pass manager.
Differential Revision: http://reviews.llvm.org/D18679 llvm-svn: 266699
This commit is contained in:
parent
2526fca8d8
commit
de16b44f74
|
@ -26,6 +26,7 @@
|
|||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
|
@ -35,31 +36,31 @@ class Instruction;
|
|||
class DominatorTree;
|
||||
class AssumptionCache;
|
||||
|
||||
struct DemandedBits : public FunctionPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
DemandedBits();
|
||||
class DemandedBits {
|
||||
public:
|
||||
DemandedBits(Function &F, AssumptionCache &AC, DominatorTree &DT) :
|
||||
F(F), AC(AC), DT(DT), Analyzed(false) {}
|
||||
|
||||
bool runOnFunction(Function& F) override;
|
||||
void getAnalysisUsage(AnalysisUsage& AU) const override;
|
||||
void print(raw_ostream &OS, const Module *M) const override;
|
||||
|
||||
/// Return the bits demanded from instruction I.
|
||||
APInt getDemandedBits(Instruction *I);
|
||||
|
||||
/// Return true if, during analysis, I could not be reached.
|
||||
bool isInstructionDead(Instruction *I);
|
||||
|
||||
void print(raw_ostream &OS);
|
||||
|
||||
private:
|
||||
Function &F;
|
||||
AssumptionCache ∾
|
||||
DominatorTree &DT;
|
||||
|
||||
void performAnalysis();
|
||||
void determineLiveOperandBits(const Instruction *UserI,
|
||||
const Instruction *I, unsigned OperandNo,
|
||||
const APInt &AOut, APInt &AB,
|
||||
APInt &KnownZero, APInt &KnownOne,
|
||||
APInt &KnownZero2, APInt &KnownOne2);
|
||||
const Instruction *I, unsigned OperandNo,
|
||||
const APInt &AOut, APInt &AB,
|
||||
APInt &KnownZero, APInt &KnownOne,
|
||||
APInt &KnownZero2, APInt &KnownOne2);
|
||||
|
||||
AssumptionCache *AC;
|
||||
DominatorTree *DT;
|
||||
Function *F;
|
||||
bool Analyzed;
|
||||
|
||||
// The set of visited instructions (non-integer-typed only).
|
||||
|
@ -67,8 +68,49 @@ private:
|
|||
DenseMap<Instruction *, APInt> AliveBits;
|
||||
};
|
||||
|
||||
class DemandedBitsWrapperPass : public FunctionPass {
|
||||
private:
|
||||
mutable Optional<DemandedBits> DB;
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
DemandedBitsWrapperPass();
|
||||
|
||||
bool runOnFunction(Function &F) override;
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||
|
||||
/// Clean up memory in between runs
|
||||
void releaseMemory() override;
|
||||
|
||||
DemandedBits &getDemandedBits() { return *DB; }
|
||||
|
||||
void print(raw_ostream &OS, const Module *M) const override;
|
||||
};
|
||||
|
||||
/// An analysis that produces \c DemandedBits for a function.
|
||||
class DemandedBitsAnalysis : public AnalysisInfoMixin<DemandedBitsAnalysis> {
|
||||
friend AnalysisInfoMixin<DemandedBitsAnalysis>;
|
||||
static char PassID;
|
||||
|
||||
public:
|
||||
/// \brief Provide the result typedef for this analysis pass.
|
||||
typedef DemandedBits Result;
|
||||
|
||||
/// \brief Run the analysis pass over a function and produce demanded bits
|
||||
/// information.
|
||||
DemandedBits run(Function &F, AnalysisManager<Function> &AM);
|
||||
};
|
||||
|
||||
/// \brief Printer pass for DemandedBits
|
||||
class DemandedBitsPrinterPass : public PassInfoMixin<DemandedBitsPrinterPass> {
|
||||
raw_ostream &OS;
|
||||
|
||||
public:
|
||||
explicit DemandedBitsPrinterPass(raw_ostream &OS) : OS(OS) {}
|
||||
PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM);
|
||||
};
|
||||
|
||||
/// Create a demanded bits analysis pass.
|
||||
FunctionPass *createDemandedBitsPass();
|
||||
FunctionPass *createDemandedBitsWrapperPass();
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
namespace llvm {
|
||||
|
||||
template <typename T> class ArrayRef;
|
||||
struct DemandedBits;
|
||||
class DemandedBits;
|
||||
class GetElementPtrInst;
|
||||
class Loop;
|
||||
class ScalarEvolution;
|
||||
|
|
|
@ -323,7 +323,7 @@ void initializeDwarfEHPreparePass(PassRegistry&);
|
|||
void initializeFloat2IntPass(PassRegistry&);
|
||||
void initializeLoopDistributePass(PassRegistry&);
|
||||
void initializeSjLjEHPreparePass(PassRegistry&);
|
||||
void initializeDemandedBitsPass(PassRegistry&);
|
||||
void initializeDemandedBitsWrapperPassPass(PassRegistry&);
|
||||
void initializeFuncletLayoutPass(PassRegistry &);
|
||||
void initializeLoopLoadEliminationPass(PassRegistry&);
|
||||
void initializeFunctionImportPassPass(PassRegistry &);
|
||||
|
|
|
@ -37,7 +37,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
|
|||
initializeCFLAAWrapperPassPass(Registry);
|
||||
initializeDependenceAnalysisPass(Registry);
|
||||
initializeDelinearizationPass(Registry);
|
||||
initializeDemandedBitsPass(Registry);
|
||||
initializeDemandedBitsWrapperPassPass(Registry);
|
||||
initializeDivergenceAnalysisPass(Registry);
|
||||
initializeDominanceFrontierWrapperPassPass(Registry);
|
||||
initializeDomViewerPass(Registry);
|
||||
|
|
|
@ -42,25 +42,29 @@ using namespace llvm;
|
|||
|
||||
#define DEBUG_TYPE "demanded-bits"
|
||||
|
||||
char DemandedBits::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(DemandedBits, "demanded-bits", "Demanded bits analysis",
|
||||
false, false)
|
||||
char DemandedBitsWrapperPass::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(DemandedBitsWrapperPass, "demanded-bits",
|
||||
"Demanded bits analysis", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
INITIALIZE_PASS_END(DemandedBits, "demanded-bits", "Demanded bits analysis",
|
||||
false, false)
|
||||
INITIALIZE_PASS_END(DemandedBitsWrapperPass, "demanded-bits",
|
||||
"Demanded bits analysis", false, false)
|
||||
|
||||
DemandedBits::DemandedBits() : FunctionPass(ID), F(nullptr), Analyzed(false) {
|
||||
initializeDemandedBitsPass(*PassRegistry::getPassRegistry());
|
||||
DemandedBitsWrapperPass::DemandedBitsWrapperPass() : FunctionPass(ID) {
|
||||
initializeDemandedBitsWrapperPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
void DemandedBits::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
void DemandedBitsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AssumptionCacheTracker>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
void DemandedBitsWrapperPass::print(raw_ostream &OS, const Module *M) const {
|
||||
DB->print(OS);
|
||||
}
|
||||
|
||||
static bool isAlwaysLive(Instruction *I) {
|
||||
return isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) ||
|
||||
I->isEHPad() || I->mayHaveSideEffects();
|
||||
|
@ -84,13 +88,13 @@ void DemandedBits::determineLiveOperandBits(
|
|||
KnownZero = APInt(BitWidth, 0);
|
||||
KnownOne = APInt(BitWidth, 0);
|
||||
computeKnownBits(const_cast<Value *>(V1), KnownZero, KnownOne, DL, 0,
|
||||
AC, UserI, DT);
|
||||
&AC, UserI, &DT);
|
||||
|
||||
if (V2) {
|
||||
KnownZero2 = APInt(BitWidth, 0);
|
||||
KnownOne2 = APInt(BitWidth, 0);
|
||||
computeKnownBits(const_cast<Value *>(V2), KnownZero2, KnownOne2, DL,
|
||||
0, AC, UserI, DT);
|
||||
0, &AC, UserI, &DT);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -243,19 +247,22 @@ void DemandedBits::determineLiveOperandBits(
|
|||
}
|
||||
}
|
||||
|
||||
bool DemandedBits::runOnFunction(Function& Fn) {
|
||||
F = &Fn;
|
||||
Analyzed = false;
|
||||
bool DemandedBitsWrapperPass::runOnFunction(Function &F) {
|
||||
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
DB.emplace(F, AC, DT);
|
||||
return false;
|
||||
}
|
||||
|
||||
void DemandedBitsWrapperPass::releaseMemory() {
|
||||
DB.reset();
|
||||
}
|
||||
|
||||
void DemandedBits::performAnalysis() {
|
||||
if (Analyzed)
|
||||
// Analysis already completed for this function.
|
||||
return;
|
||||
Analyzed = true;
|
||||
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*F);
|
||||
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
|
||||
Visited.clear();
|
||||
AliveBits.clear();
|
||||
|
@ -263,7 +270,7 @@ void DemandedBits::performAnalysis() {
|
|||
SmallVector<Instruction*, 128> Worklist;
|
||||
|
||||
// Collect the set of "root" instructions that are known live.
|
||||
for (Instruction &I : instructions(*F)) {
|
||||
for (Instruction &I : instructions(F)) {
|
||||
if (!isAlwaysLive(&I))
|
||||
continue;
|
||||
|
||||
|
@ -368,16 +375,29 @@ bool DemandedBits::isInstructionDead(Instruction *I) {
|
|||
!isAlwaysLive(I);
|
||||
}
|
||||
|
||||
void DemandedBits::print(raw_ostream &OS, const Module *M) const {
|
||||
// This is gross. But the alternative is making all the state mutable
|
||||
// just because of this one debugging method.
|
||||
const_cast<DemandedBits*>(this)->performAnalysis();
|
||||
void DemandedBits::print(raw_ostream &OS) {
|
||||
performAnalysis();
|
||||
for (auto &KV : AliveBits) {
|
||||
OS << "DemandedBits: 0x" << utohexstr(KV.second.getLimitedValue()) << " for "
|
||||
<< *KV.first << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
FunctionPass *llvm::createDemandedBitsPass() {
|
||||
return new DemandedBits();
|
||||
FunctionPass *llvm::createDemandedBitsWrapperPass() {
|
||||
return new DemandedBitsWrapperPass();
|
||||
}
|
||||
|
||||
char DemandedBitsAnalysis::PassID;
|
||||
|
||||
DemandedBits DemandedBitsAnalysis::run(Function &F,
|
||||
AnalysisManager<Function> &AM) {
|
||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
||||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
return DemandedBits(F, AC, DT);
|
||||
}
|
||||
|
||||
PreservedAnalyses DemandedBitsPrinterPass::run(Function &F,
|
||||
FunctionAnalysisManager &AM) {
|
||||
AM.getResult<DemandedBitsAnalysis>(F).print(OS);
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "llvm/Analysis/CFLAliasAnalysis.h"
|
||||
#include "llvm/Analysis/CGSCCPassManager.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/DemandedBits.h"
|
||||
#include "llvm/Analysis/DominanceFrontier.h"
|
||||
#include "llvm/Analysis/GlobalsModRef.h"
|
||||
#include "llvm/Analysis/LazyCallGraph.h"
|
||||
|
|
|
@ -68,6 +68,7 @@ FUNCTION_ANALYSIS("aa", AAManager())
|
|||
FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis())
|
||||
FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
|
||||
FUNCTION_ANALYSIS("postdomtree", PostDominatorTreeAnalysis())
|
||||
FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis())
|
||||
FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis())
|
||||
FUNCTION_ANALYSIS("loops", LoopAnalysis())
|
||||
FUNCTION_ANALYSIS("memdep", MemoryDependenceAnalysis())
|
||||
|
@ -105,6 +106,7 @@ FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
|
|||
FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))
|
||||
FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(dbgs()))
|
||||
|
|
|
@ -45,7 +45,7 @@ struct BDCE : public FunctionPass {
|
|||
|
||||
void getAnalysisUsage(AnalysisUsage& AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<DemandedBits>();
|
||||
AU.addRequired<DemandedBitsWrapperPass>();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
}
|
||||
};
|
||||
|
@ -54,14 +54,14 @@ struct BDCE : public FunctionPass {
|
|||
char BDCE::ID = 0;
|
||||
INITIALIZE_PASS_BEGIN(BDCE, "bdce", "Bit-Tracking Dead Code Elimination",
|
||||
false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(DemandedBits)
|
||||
INITIALIZE_PASS_DEPENDENCY(DemandedBitsWrapperPass)
|
||||
INITIALIZE_PASS_END(BDCE, "bdce", "Bit-Tracking Dead Code Elimination",
|
||||
false, false)
|
||||
|
||||
bool BDCE::runOnFunction(Function& F) {
|
||||
if (skipOptnoneFunction(F))
|
||||
return false;
|
||||
DemandedBits &DB = getAnalysis<DemandedBits>();
|
||||
auto &DB = getAnalysis<DemandedBitsWrapperPass>().getDemandedBits();
|
||||
|
||||
SmallVector<Instruction*, 128> Worklist;
|
||||
bool Changed = false;
|
||||
|
|
|
@ -1498,9 +1498,9 @@ public:
|
|||
LoopVectorizationCostModel(Loop *L, ScalarEvolution *SE, LoopInfo *LI,
|
||||
LoopVectorizationLegality *Legal,
|
||||
const TargetTransformInfo &TTI,
|
||||
const TargetLibraryInfo *TLI, DemandedBits *DB,
|
||||
AssumptionCache *AC, const Function *F,
|
||||
const LoopVectorizeHints *Hints,
|
||||
const TargetLibraryInfo *TLI,
|
||||
DemandedBits *DB, AssumptionCache *AC,
|
||||
const Function *F, const LoopVectorizeHints *Hints,
|
||||
SmallPtrSetImpl<const Value *> &ValuesToIgnore)
|
||||
: TheLoop(L), SE(SE), LI(LI), Legal(Legal), TTI(TTI), TLI(TLI), DB(DB),
|
||||
TheFunction(F), Hints(Hints), ValuesToIgnore(ValuesToIgnore) {}
|
||||
|
@ -1717,7 +1717,7 @@ struct LoopVectorize : public FunctionPass {
|
|||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
LAA = &getAnalysis<LoopAccessAnalysis>();
|
||||
DB = &getAnalysis<DemandedBits>();
|
||||
DB = &getAnalysis<DemandedBitsWrapperPass>().getDemandedBits();
|
||||
|
||||
// Compute some weights outside of the loop over the loops. Compute this
|
||||
// using a BranchProbability to re-use its scaling math.
|
||||
|
@ -2035,7 +2035,7 @@ struct LoopVectorize : public FunctionPass {
|
|||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addRequired<LoopAccessAnalysis>();
|
||||
AU.addRequired<DemandedBits>();
|
||||
AU.addRequired<DemandedBitsWrapperPass>();
|
||||
AU.addPreserved<LoopInfoWrapperPass>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<BasicAAWrapperPass>();
|
||||
|
@ -6064,7 +6064,7 @@ INITIALIZE_PASS_DEPENDENCY(LCSSA)
|
|||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopAccessAnalysis)
|
||||
INITIALIZE_PASS_DEPENDENCY(DemandedBits)
|
||||
INITIALIZE_PASS_DEPENDENCY(DemandedBitsWrapperPass)
|
||||
INITIALIZE_PASS_END(LoopVectorize, LV_NAME, lv_name, false, false)
|
||||
|
||||
namespace llvm {
|
||||
|
|
|
@ -3407,7 +3407,7 @@ struct SLPVectorizer : public FunctionPass {
|
|||
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||
DB = &getAnalysis<DemandedBits>();
|
||||
DB = &getAnalysis<DemandedBitsWrapperPass>().getDemandedBits();
|
||||
|
||||
Stores.clear();
|
||||
GEPs.clear();
|
||||
|
@ -3484,7 +3484,7 @@ struct SLPVectorizer : public FunctionPass {
|
|||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||
AU.addRequired<LoopInfoWrapperPass>();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addRequired<DemandedBits>();
|
||||
AU.addRequired<DemandedBitsWrapperPass>();
|
||||
AU.addPreserved<LoopInfoWrapperPass>();
|
||||
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<AAResultsWrapperPass>();
|
||||
|
@ -4575,7 +4575,7 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
|
|||
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
|
||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
||||
INITIALIZE_PASS_DEPENDENCY(DemandedBits)
|
||||
INITIALIZE_PASS_DEPENDENCY(DemandedBitsWrapperPass)
|
||||
INITIALIZE_PASS_END(SLPVectorizer, SV_NAME, lv_name, false, false)
|
||||
|
||||
namespace llvm {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
; RUN: opt -S -demanded-bits -analyze < %s | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: 'test_mul'
|
||||
; RUN: opt -S -disable-output -passes="print<demanded-bits>" < %s 2>&1 | FileCheck %s
|
||||
|
||||
; CHECK-DAG: DemandedBits: 0xFF for %1 = add nsw i32 %a, 5
|
||||
; CHECK-DAG: DemandedBits: 0xFF for %3 = trunc i32 %2 to i8
|
||||
; CHECK-DAG: DemandedBits: 0xFF for %2 = mul nsw i32 %1, %b
|
||||
|
|
Loading…
Reference in New Issue