mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
[LibCallsShrinkWrap] Teach the pass how to preserve the dominator.
llvm-svn: 301471
This commit is contained in:
parent
330c3cc9d2
commit
3f6585ed54
@ -33,6 +33,7 @@
|
|||||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||||
#include "llvm/IR/CFG.h"
|
#include "llvm/IR/CFG.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
|
#include "llvm/IR/Dominators.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/InstVisitor.h"
|
#include "llvm/IR/InstVisitor.h"
|
||||||
@ -82,7 +83,8 @@ INITIALIZE_PASS_END(LibCallsShrinkWrapLegacyPass, "libcalls-shrinkwrap",
|
|||||||
namespace {
|
namespace {
|
||||||
class LibCallsShrinkWrap : public InstVisitor<LibCallsShrinkWrap> {
|
class LibCallsShrinkWrap : public InstVisitor<LibCallsShrinkWrap> {
|
||||||
public:
|
public:
|
||||||
LibCallsShrinkWrap(const TargetLibraryInfo &TLI) : TLI(TLI), Changed(false){};
|
LibCallsShrinkWrap(const TargetLibraryInfo &TLI, DominatorTree *DT)
|
||||||
|
: TLI(TLI), DT(DT), Changed(false){};
|
||||||
bool isChanged() const { return Changed; }
|
bool isChanged() const { return Changed; }
|
||||||
void visitCallInst(CallInst &CI) { checkCandidate(CI); }
|
void visitCallInst(CallInst &CI) { checkCandidate(CI); }
|
||||||
void perform() {
|
void perform() {
|
||||||
@ -134,6 +136,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TargetLibraryInfo &TLI;
|
const TargetLibraryInfo &TLI;
|
||||||
|
DominatorTree *DT;
|
||||||
SmallVector<CallInst *, 16> WorkList;
|
SmallVector<CallInst *, 16> WorkList;
|
||||||
bool Changed;
|
bool Changed;
|
||||||
};
|
};
|
||||||
@ -502,11 +505,14 @@ void LibCallsShrinkWrap::shrinkWrapCI(CallInst *CI, Value *Cond) {
|
|||||||
assert(Cond != nullptr && "hrinkWrapCI is not expecting an empty call inst");
|
assert(Cond != nullptr && "hrinkWrapCI is not expecting an empty call inst");
|
||||||
MDNode *BranchWeights =
|
MDNode *BranchWeights =
|
||||||
MDBuilder(CI->getContext()).createBranchWeights(1, 2000);
|
MDBuilder(CI->getContext()).createBranchWeights(1, 2000);
|
||||||
|
|
||||||
TerminatorInst *NewInst =
|
TerminatorInst *NewInst =
|
||||||
SplitBlockAndInsertIfThen(Cond, CI, false, BranchWeights);
|
SplitBlockAndInsertIfThen(Cond, CI, false, BranchWeights, DT);
|
||||||
BasicBlock *CallBB = NewInst->getParent();
|
BasicBlock *CallBB = NewInst->getParent();
|
||||||
CallBB->setName("cdce.call");
|
CallBB->setName("cdce.call");
|
||||||
CallBB->getSingleSuccessor()->setName("cdce.end");
|
BasicBlock *SuccBB = CallBB->getSingleSuccessor();
|
||||||
|
assert(SuccBB && "The split block should have a single successor");
|
||||||
|
SuccBB->setName("cdce.end");
|
||||||
CI->removeFromParent();
|
CI->removeFromParent();
|
||||||
CallBB->getInstList().insert(CallBB->getFirstInsertionPt(), CI);
|
CallBB->getInstList().insert(CallBB->getFirstInsertionPt(), CI);
|
||||||
DEBUG(dbgs() << "== Basic Block After ==");
|
DEBUG(dbgs() << "== Basic Block After ==");
|
||||||
@ -532,22 +538,32 @@ bool LibCallsShrinkWrap::perform(CallInst *CI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LibCallsShrinkWrapLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
void LibCallsShrinkWrapLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool runImpl(Function &F, const TargetLibraryInfo &TLI) {
|
static bool runImpl(Function &F, const TargetLibraryInfo &TLI,
|
||||||
|
DominatorTree *DT) {
|
||||||
if (F.hasFnAttribute(Attribute::OptimizeForSize))
|
if (F.hasFnAttribute(Attribute::OptimizeForSize))
|
||||||
return false;
|
return false;
|
||||||
LibCallsShrinkWrap CCDCE(TLI);
|
LibCallsShrinkWrap CCDCE(TLI, DT);
|
||||||
CCDCE.visit(F);
|
CCDCE.visit(F);
|
||||||
CCDCE.perform();
|
CCDCE.perform();
|
||||||
|
|
||||||
|
// Verify the dominator after we've updated it locally.
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (DT)
|
||||||
|
DT->verifyDomTree();
|
||||||
|
#endif
|
||||||
return CCDCE.isChanged();
|
return CCDCE.isChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LibCallsShrinkWrapLegacyPass::runOnFunction(Function &F) {
|
bool LibCallsShrinkWrapLegacyPass::runOnFunction(Function &F) {
|
||||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||||
return runImpl(F, TLI);
|
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
|
||||||
|
auto *DT = DTWP ? &DTWP->getDomTree() : nullptr;
|
||||||
|
return runImpl(F, TLI, DT);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -561,11 +577,13 @@ FunctionPass *createLibCallsShrinkWrapPass() {
|
|||||||
PreservedAnalyses LibCallsShrinkWrapPass::run(Function &F,
|
PreservedAnalyses LibCallsShrinkWrapPass::run(Function &F,
|
||||||
FunctionAnalysisManager &FAM) {
|
FunctionAnalysisManager &FAM) {
|
||||||
auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
|
auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
|
||||||
bool Changed = runImpl(F, TLI);
|
auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
|
||||||
|
bool Changed = runImpl(F, TLI, DT);
|
||||||
if (!Changed)
|
if (!Changed)
|
||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
auto PA = PreservedAnalyses();
|
auto PA = PreservedAnalyses();
|
||||||
PA.preserve<GlobalsAA>();
|
PA.preserve<GlobalsAA>();
|
||||||
|
PA.preserve<DominatorTreeAnalysis>();
|
||||||
return PA;
|
return PA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user