forked from OSchip/llvm-project
[CallSiteSplitting] Preserve DominatorTreeAnalysis.
The dominator tree analysis can be preserved easily. Some other kinds of analysis can probably be preserved too. Reviewers: junbuml, dberlin Reviewed By: dberlin Differential Revision: https://reviews.llvm.org/D43173 llvm-svn: 328206
This commit is contained in:
parent
3bf58317f7
commit
9bc0bc4b9b
|
@ -292,7 +292,8 @@ static void copyMustTailReturn(BasicBlock *SplitBB, Instruction *CI,
|
||||||
/// created in createCallSitesOnPredicatedArgument().
|
/// created in createCallSitesOnPredicatedArgument().
|
||||||
static void splitCallSite(
|
static void splitCallSite(
|
||||||
CallSite CS,
|
CallSite CS,
|
||||||
const SmallVectorImpl<std::pair<BasicBlock *, ConditionsTy>> &Preds) {
|
const SmallVectorImpl<std::pair<BasicBlock *, ConditionsTy>> &Preds,
|
||||||
|
DominatorTree *DT) {
|
||||||
Instruction *Instr = CS.getInstruction();
|
Instruction *Instr = CS.getInstruction();
|
||||||
BasicBlock *TailBB = Instr->getParent();
|
BasicBlock *TailBB = Instr->getParent();
|
||||||
bool IsMustTailCall = CS.isMustTailCall();
|
bool IsMustTailCall = CS.isMustTailCall();
|
||||||
|
@ -314,7 +315,8 @@ static void splitCallSite(
|
||||||
for (unsigned i = 0; i < Preds.size(); i++) {
|
for (unsigned i = 0; i < Preds.size(); i++) {
|
||||||
BasicBlock *PredBB = Preds[i].first;
|
BasicBlock *PredBB = Preds[i].first;
|
||||||
BasicBlock *SplitBlock = DuplicateInstructionsInSplitBetween(
|
BasicBlock *SplitBlock = DuplicateInstructionsInSplitBetween(
|
||||||
TailBB, PredBB, &*std::next(Instr->getIterator()), ValueToValueMaps[i]);
|
TailBB, PredBB, &*std::next(Instr->getIterator()), ValueToValueMaps[i],
|
||||||
|
DT);
|
||||||
assert(SplitBlock && "Unexpected new basic block split.");
|
assert(SplitBlock && "Unexpected new basic block split.");
|
||||||
|
|
||||||
Instruction *NewCI =
|
Instruction *NewCI =
|
||||||
|
@ -424,18 +426,18 @@ static bool isPredicatedOnPHI(CallSite CS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tryToSplitOnPHIPredicatedArgument(CallSite CS) {
|
static bool tryToSplitOnPHIPredicatedArgument(CallSite CS, DominatorTree *DT) {
|
||||||
if (!isPredicatedOnPHI(CS))
|
if (!isPredicatedOnPHI(CS))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto Preds = getTwoPredecessors(CS.getInstruction()->getParent());
|
auto Preds = getTwoPredecessors(CS.getInstruction()->getParent());
|
||||||
SmallVector<std::pair<BasicBlock *, ConditionsTy>, 2> PredsCS = {
|
SmallVector<std::pair<BasicBlock *, ConditionsTy>, 2> PredsCS = {
|
||||||
{Preds[0], {}}, {Preds[1], {}}};
|
{Preds[0], {}}, {Preds[1], {}}};
|
||||||
splitCallSite(CS, PredsCS);
|
splitCallSite(CS, PredsCS, DT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tryToSplitOnPredicatedArgument(CallSite CS) {
|
static bool tryToSplitOnPredicatedArgument(CallSite CS, DominatorTree *DT) {
|
||||||
auto Preds = getTwoPredecessors(CS.getInstruction()->getParent());
|
auto Preds = getTwoPredecessors(CS.getInstruction()->getParent());
|
||||||
if (Preds[0] == Preds[1])
|
if (Preds[0] == Preds[1])
|
||||||
return false;
|
return false;
|
||||||
|
@ -453,19 +455,20 @@ static bool tryToSplitOnPredicatedArgument(CallSite CS) {
|
||||||
}))
|
}))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
splitCallSite(CS, PredsCS);
|
splitCallSite(CS, PredsCS, DT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tryToSplitCallSite(CallSite CS, TargetTransformInfo &TTI) {
|
static bool tryToSplitCallSite(CallSite CS, TargetTransformInfo &TTI,
|
||||||
|
DominatorTree *DT) {
|
||||||
if (!CS.arg_size() || !canSplitCallSite(CS, TTI))
|
if (!CS.arg_size() || !canSplitCallSite(CS, TTI))
|
||||||
return false;
|
return false;
|
||||||
return tryToSplitOnPredicatedArgument(CS) ||
|
return tryToSplitOnPredicatedArgument(CS, DT) ||
|
||||||
tryToSplitOnPHIPredicatedArgument(CS);
|
tryToSplitOnPHIPredicatedArgument(CS, DT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI,
|
static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI,
|
||||||
TargetTransformInfo &TTI) {
|
TargetTransformInfo &TTI, DominatorTree *DT) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE;) {
|
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE;) {
|
||||||
BasicBlock &BB = *BI++;
|
BasicBlock &BB = *BI++;
|
||||||
|
@ -489,7 +492,7 @@ static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI,
|
||||||
// Check if such path is possible before attempting the splitting.
|
// Check if such path is possible before attempting the splitting.
|
||||||
bool IsMustTail = CS.isMustTailCall();
|
bool IsMustTail = CS.isMustTailCall();
|
||||||
|
|
||||||
Changed |= tryToSplitCallSite(CS, TTI);
|
Changed |= tryToSplitCallSite(CS, TTI, DT);
|
||||||
|
|
||||||
// There're no interesting instructions after this. The call site
|
// There're no interesting instructions after this. The call site
|
||||||
// itself might have been erased on splitting.
|
// itself might have been erased on splitting.
|
||||||
|
@ -510,6 +513,7 @@ struct CallSiteSplittingLegacyPass : public FunctionPass {
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||||
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
AU.addRequired<TargetLibraryInfoWrapperPass>();
|
||||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||||
|
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||||
FunctionPass::getAnalysisUsage(AU);
|
FunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,7 +523,9 @@ struct CallSiteSplittingLegacyPass : public FunctionPass {
|
||||||
|
|
||||||
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
|
||||||
auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||||
return doCallSiteSplitting(F, TLI, TTI);
|
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
|
||||||
|
return doCallSiteSplitting(F, TLI, TTI,
|
||||||
|
DTWP ? &DTWP->getDomTree() : nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -539,9 +545,11 @@ PreservedAnalyses CallSiteSplittingPass::run(Function &F,
|
||||||
FunctionAnalysisManager &AM) {
|
FunctionAnalysisManager &AM) {
|
||||||
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||||
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
||||||
|
auto *DT = AM.getCachedResult<DominatorTreeAnalysis>(F);
|
||||||
|
|
||||||
if (!doCallSiteSplitting(F, TLI, TTI))
|
if (!doCallSiteSplitting(F, TLI, TTI, DT))
|
||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
PreservedAnalyses PA;
|
PreservedAnalyses PA;
|
||||||
|
PA.preserve<DominatorTreeAnalysis>();
|
||||||
return PA;
|
return PA;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue