forked from OSchip/llvm-project
[SimplifyCFG] put the optional assumption cache pointer in the options struct; NFCI
This is a follow-up to https://reviews.llvm.org/D38138. I fixed the capitalization of some functions because we're changing those lines anyway and that helped verify that we weren't accidentally dropping any options by using default param values. llvm-svn: 314930
This commit is contained in:
parent
63ed8c6c2e
commit
4c33d5213b
|
@ -59,12 +59,15 @@ struct SimplifyCFGOptions {
|
||||||
int BonusInstThreshold;
|
int BonusInstThreshold;
|
||||||
bool ConvertSwitchToLookupTable;
|
bool ConvertSwitchToLookupTable;
|
||||||
bool NeedCanonicalLoop;
|
bool NeedCanonicalLoop;
|
||||||
|
AssumptionCache *AC;
|
||||||
|
|
||||||
SimplifyCFGOptions(int BonusThreshold = 1, bool SwitchToLookup = false,
|
SimplifyCFGOptions(int BonusThreshold = 1, bool SwitchToLookup = false,
|
||||||
bool CanonicalLoops = true)
|
bool CanonicalLoops = true,
|
||||||
|
AssumptionCache *AssumpCache = nullptr)
|
||||||
: BonusInstThreshold(BonusThreshold),
|
: BonusInstThreshold(BonusThreshold),
|
||||||
ConvertSwitchToLookupTable(SwitchToLookup),
|
ConvertSwitchToLookupTable(SwitchToLookup),
|
||||||
NeedCanonicalLoop(CanonicalLoops) {}
|
NeedCanonicalLoop(CanonicalLoops),
|
||||||
|
AC(AssumpCache) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -157,8 +160,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
|
||||||
/// It returns true if a modification was made, possibly deleting the basic
|
/// It returns true if a modification was made, possibly deleting the basic
|
||||||
/// block that was pointed to. LoopHeaders is an optional input parameter
|
/// block that was pointed to. LoopHeaders is an optional input parameter
|
||||||
/// providing the set of loop headers that SimplifyCFG should not eliminate.
|
/// providing the set of loop headers that SimplifyCFG should not eliminate.
|
||||||
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||||
AssumptionCache *AC = nullptr,
|
|
||||||
const SimplifyCFGOptions &Options = {},
|
const SimplifyCFGOptions &Options = {},
|
||||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);
|
SmallPtrSetImpl<BasicBlock *> *LoopHeaders = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ size_t DwarfEHPrepare::pruneUnreachableResumes(
|
||||||
BasicBlock *BB = RI->getParent();
|
BasicBlock *BB = RI->getParent();
|
||||||
new UnreachableInst(Ctx, RI);
|
new UnreachableInst(Ctx, RI);
|
||||||
RI->eraseFromParent();
|
RI->eraseFromParent();
|
||||||
SimplifyCFG(BB, TTI);
|
simplifyCFG(BB, TTI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Resumes.resize(ResumesLeft);
|
Resumes.resize(ResumesLeft);
|
||||||
|
|
|
@ -142,7 +142,7 @@ static BasicBlock *unifyReturnBlockSet(Function &F,
|
||||||
|
|
||||||
for (BasicBlock *BB : ReturningBlocks) {
|
for (BasicBlock *BB : ReturningBlocks) {
|
||||||
// Cleanup possible branch to unconditional branch to the return.
|
// Cleanup possible branch to unconditional branch to the return.
|
||||||
SimplifyCFG(BB, TTI, nullptr, {2});
|
simplifyCFG(BB, TTI, {2});
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewRetBlock;
|
return NewRetBlock;
|
||||||
|
|
|
@ -129,7 +129,6 @@ static bool mergeEmptyReturnBlocks(Function &F) {
|
||||||
/// Call SimplifyCFG on all the blocks in the function,
|
/// Call SimplifyCFG on all the blocks in the function,
|
||||||
/// iterating until no more changes are made.
|
/// iterating until no more changes are made.
|
||||||
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||||
AssumptionCache *AC,
|
|
||||||
const SimplifyCFGOptions &Options) {
|
const SimplifyCFGOptions &Options) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
bool LocalChange = true;
|
bool LocalChange = true;
|
||||||
|
@ -145,7 +144,7 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||||
|
|
||||||
// Loop over all of the basic blocks and remove them if they are unneeded.
|
// Loop over all of the basic blocks and remove them if they are unneeded.
|
||||||
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
|
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
|
||||||
if (SimplifyCFG(&*BBIt++, TTI, AC, Options, &LoopHeaders)) {
|
if (simplifyCFG(&*BBIt++, TTI, Options, &LoopHeaders)) {
|
||||||
LocalChange = true;
|
LocalChange = true;
|
||||||
++NumSimpl;
|
++NumSimpl;
|
||||||
}
|
}
|
||||||
|
@ -156,11 +155,10 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
||||||
AssumptionCache *AC,
|
|
||||||
const SimplifyCFGOptions &Options) {
|
const SimplifyCFGOptions &Options) {
|
||||||
bool EverChanged = removeUnreachableBlocks(F);
|
bool EverChanged = removeUnreachableBlocks(F);
|
||||||
EverChanged |= mergeEmptyReturnBlocks(F);
|
EverChanged |= mergeEmptyReturnBlocks(F);
|
||||||
EverChanged |= iterativelySimplifyCFG(F, TTI, AC, Options);
|
EverChanged |= iterativelySimplifyCFG(F, TTI, Options);
|
||||||
|
|
||||||
// If neither pass changed anything, we're done.
|
// If neither pass changed anything, we're done.
|
||||||
if (!EverChanged) return false;
|
if (!EverChanged) return false;
|
||||||
|
@ -174,7 +172,7 @@ static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
EverChanged = iterativelySimplifyCFG(F, TTI, AC, Options);
|
EverChanged = iterativelySimplifyCFG(F, TTI, Options);
|
||||||
EverChanged |= removeUnreachableBlocks(F);
|
EverChanged |= removeUnreachableBlocks(F);
|
||||||
} while (EverChanged);
|
} while (EverChanged);
|
||||||
|
|
||||||
|
@ -190,9 +188,8 @@ SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &PassOptions)
|
||||||
PreservedAnalyses SimplifyCFGPass::run(Function &F,
|
PreservedAnalyses SimplifyCFGPass::run(Function &F,
|
||||||
FunctionAnalysisManager &AM) {
|
FunctionAnalysisManager &AM) {
|
||||||
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
|
||||||
auto &AC = AM.getResult<AssumptionAnalysis>(F);
|
Options.AC = &AM.getResult<AssumptionAnalysis>(F);
|
||||||
|
if (!simplifyFunctionCFG(F, TTI, Options))
|
||||||
if (!simplifyFunctionCFG(F, TTI, &AC, Options))
|
|
||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
PreservedAnalyses PA;
|
PreservedAnalyses PA;
|
||||||
PA.preserve<GlobalsAA>();
|
PA.preserve<GlobalsAA>();
|
||||||
|
@ -221,9 +218,9 @@ struct BaseCFGSimplifyPass : public FunctionPass {
|
||||||
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
|
||||||
const TargetTransformInfo &TTI =
|
const TargetTransformInfo &TTI =
|
||||||
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
|
||||||
return simplifyFunctionCFG(
|
return simplifyFunctionCFG(F, TTI,
|
||||||
F, TTI, AC,
|
{BonusInstThreshold, ConvertSwitchToLookupTable,
|
||||||
{BonusInstThreshold, ConvertSwitchToLookupTable, KeepCanonicalLoops});
|
KeepCanonicalLoops, AC});
|
||||||
}
|
}
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||||
|
|
|
@ -167,7 +167,6 @@ struct ValueEqualityComparisonCase {
|
||||||
class SimplifyCFGOpt {
|
class SimplifyCFGOpt {
|
||||||
const TargetTransformInfo &TTI;
|
const TargetTransformInfo &TTI;
|
||||||
const DataLayout &DL;
|
const DataLayout &DL;
|
||||||
AssumptionCache *AC;
|
|
||||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
|
SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
|
||||||
const SimplifyCFGOptions &Options;
|
const SimplifyCFGOptions &Options;
|
||||||
|
|
||||||
|
@ -193,10 +192,9 @@ class SimplifyCFGOpt {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
|
SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
|
||||||
AssumptionCache *AC,
|
|
||||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders,
|
SmallPtrSetImpl<BasicBlock *> *LoopHeaders,
|
||||||
const SimplifyCFGOptions &Opts)
|
const SimplifyCFGOptions &Opts)
|
||||||
: TTI(TTI), DL(DL), AC(AC), LoopHeaders(LoopHeaders), Options(Opts) {}
|
: TTI(TTI), DL(DL), LoopHeaders(LoopHeaders), Options(Opts) {}
|
||||||
|
|
||||||
bool run(BasicBlock *BB);
|
bool run(BasicBlock *BB);
|
||||||
};
|
};
|
||||||
|
@ -3484,10 +3482,9 @@ static bool SimplifyIndirectBrOnSelect(IndirectBrInst *IBI, SelectInst *SI) {
|
||||||
///
|
///
|
||||||
/// We prefer to split the edge to 'end' so that there is a true/false entry to
|
/// We prefer to split the edge to 'end' so that there is a true/false entry to
|
||||||
/// the PHI, merging the third icmp into the switch.
|
/// the PHI, merging the third icmp into the switch.
|
||||||
static bool TryToSimplifyUncondBranchWithICmpInIt(
|
static bool tryToSimplifyUncondBranchWithICmpInIt(
|
||||||
ICmpInst *ICI, IRBuilder<> &Builder, const DataLayout &DL,
|
ICmpInst *ICI, IRBuilder<> &Builder, const DataLayout &DL,
|
||||||
const TargetTransformInfo &TTI, AssumptionCache *AC,
|
const TargetTransformInfo &TTI, const SimplifyCFGOptions &Options) {
|
||||||
const SimplifyCFGOptions &Options) {
|
|
||||||
BasicBlock *BB = ICI->getParent();
|
BasicBlock *BB = ICI->getParent();
|
||||||
|
|
||||||
// If the block has any PHIs in it or the icmp has multiple uses, it is too
|
// If the block has any PHIs in it or the icmp has multiple uses, it is too
|
||||||
|
@ -3522,7 +3519,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(
|
||||||
ICI->eraseFromParent();
|
ICI->eraseFromParent();
|
||||||
}
|
}
|
||||||
// BB is now empty, so it is likely to simplify away.
|
// BB is now empty, so it is likely to simplify away.
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ok, the block is reachable from the default dest. If the constant we're
|
// Ok, the block is reachable from the default dest. If the constant we're
|
||||||
|
@ -3538,7 +3535,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(
|
||||||
ICI->replaceAllUsesWith(V);
|
ICI->replaceAllUsesWith(V);
|
||||||
ICI->eraseFromParent();
|
ICI->eraseFromParent();
|
||||||
// BB is now empty, so it is likely to simplify away.
|
// BB is now empty, so it is likely to simplify away.
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The use of the icmp has to be in the 'end' block, by the only PHI node in
|
// The use of the icmp has to be in the 'end' block, by the only PHI node in
|
||||||
|
@ -4336,7 +4333,7 @@ static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||||
|
|
||||||
/// Compute masked bits for the condition of a switch
|
/// Compute masked bits for the condition of a switch
|
||||||
/// and use it to remove dead cases.
|
/// and use it to remove dead cases.
|
||||||
static bool EliminateDeadSwitchCases(SwitchInst *SI, AssumptionCache *AC,
|
static bool eliminateDeadSwitchCases(SwitchInst *SI, AssumptionCache *AC,
|
||||||
const DataLayout &DL) {
|
const DataLayout &DL) {
|
||||||
Value *Cond = SI->getCondition();
|
Value *Cond = SI->getCondition();
|
||||||
unsigned Bits = Cond->getType()->getIntegerBitWidth();
|
unsigned Bits = Cond->getType()->getIntegerBitWidth();
|
||||||
|
@ -4763,8 +4760,8 @@ static void RemoveSwitchAfterSelectConversion(SwitchInst *SI, PHINode *PHI,
|
||||||
/// If the switch is only used to initialize one or more
|
/// If the switch is only used to initialize one or more
|
||||||
/// phi nodes in a common successor block with only two different
|
/// phi nodes in a common successor block with only two different
|
||||||
/// constant values, replace the switch with select.
|
/// constant values, replace the switch with select.
|
||||||
static bool SwitchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
|
static bool switchToSelect(SwitchInst *SI, IRBuilder<> &Builder,
|
||||||
AssumptionCache *AC, const DataLayout &DL,
|
const DataLayout &DL,
|
||||||
const TargetTransformInfo &TTI) {
|
const TargetTransformInfo &TTI) {
|
||||||
Value *const Cond = SI->getCondition();
|
Value *const Cond = SI->getCondition();
|
||||||
PHINode *PHI = nullptr;
|
PHINode *PHI = nullptr;
|
||||||
|
@ -5517,12 +5514,12 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||||
// see if that predecessor totally determines the outcome of this switch.
|
// see if that predecessor totally determines the outcome of this switch.
|
||||||
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
|
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
|
||||||
if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred, Builder))
|
if (SimplifyEqualityComparisonWithOnlyPredecessor(SI, OnlyPred, Builder))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
Value *Cond = SI->getCondition();
|
Value *Cond = SI->getCondition();
|
||||||
if (SelectInst *Select = dyn_cast<SelectInst>(Cond))
|
if (SelectInst *Select = dyn_cast<SelectInst>(Cond))
|
||||||
if (SimplifySwitchOnSelect(SI, Select))
|
if (SimplifySwitchOnSelect(SI, Select))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
// If the block only contains the switch, see if we can fold the block
|
// If the block only contains the switch, see if we can fold the block
|
||||||
// away into any preds.
|
// away into any preds.
|
||||||
|
@ -5532,22 +5529,22 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||||
++BBI;
|
++BBI;
|
||||||
if (SI == &*BBI)
|
if (SI == &*BBI)
|
||||||
if (FoldValueComparisonIntoPredecessors(SI, Builder))
|
if (FoldValueComparisonIntoPredecessors(SI, Builder))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to transform the switch into an icmp and a branch.
|
// Try to transform the switch into an icmp and a branch.
|
||||||
if (TurnSwitchRangeIntoICmp(SI, Builder))
|
if (TurnSwitchRangeIntoICmp(SI, Builder))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
// Remove unreachable cases.
|
// Remove unreachable cases.
|
||||||
if (EliminateDeadSwitchCases(SI, AC, DL))
|
if (eliminateDeadSwitchCases(SI, Options.AC, DL))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
if (SwitchToSelect(SI, Builder, AC, DL, TTI))
|
if (switchToSelect(SI, Builder, DL, TTI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
if (ForwardSwitchConditionToPHI(SI))
|
if (ForwardSwitchConditionToPHI(SI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
// The conversion from switch to lookup tables results in difficult-to-analyze
|
// The conversion from switch to lookup tables results in difficult-to-analyze
|
||||||
// code and makes pruning branches much harder. This is a problem if the
|
// code and makes pruning branches much harder. This is a problem if the
|
||||||
|
@ -5556,10 +5553,10 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
|
||||||
// optimisation pipeline.
|
// optimisation pipeline.
|
||||||
if (Options.ConvertSwitchToLookupTable &&
|
if (Options.ConvertSwitchToLookupTable &&
|
||||||
SwitchToLookupTable(SI, Builder, DL, TTI))
|
SwitchToLookupTable(SI, Builder, DL, TTI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
if (ReduceSwitchRange(SI, Builder, DL, TTI))
|
if (ReduceSwitchRange(SI, Builder, DL, TTI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5597,7 +5594,7 @@ bool SimplifyCFGOpt::SimplifyIndirectBr(IndirectBrInst *IBI) {
|
||||||
|
|
||||||
if (SelectInst *SI = dyn_cast<SelectInst>(IBI->getAddress())) {
|
if (SelectInst *SI = dyn_cast<SelectInst>(IBI->getAddress())) {
|
||||||
if (SimplifyIndirectBrOnSelect(IBI, SI))
|
if (SimplifyIndirectBrOnSelect(IBI, SI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
@ -5707,8 +5704,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
|
||||||
for (++I; isa<DbgInfoIntrinsic>(I); ++I)
|
for (++I; isa<DbgInfoIntrinsic>(I); ++I)
|
||||||
;
|
;
|
||||||
if (I->isTerminator() &&
|
if (I->isTerminator() &&
|
||||||
TryToSimplifyUncondBranchWithICmpInIt(ICI, Builder, DL, TTI, AC,
|
tryToSimplifyUncondBranchWithICmpInIt(ICI, Builder, DL, TTI, Options))
|
||||||
Options))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5726,7 +5722,7 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI,
|
||||||
// predecessor and use logical operations to update the incoming value
|
// predecessor and use logical operations to update the incoming value
|
||||||
// for PHI nodes in common successor.
|
// for PHI nodes in common successor.
|
||||||
if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
|
if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5751,7 +5747,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
// switch.
|
// switch.
|
||||||
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
|
if (BasicBlock *OnlyPred = BB->getSinglePredecessor())
|
||||||
if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred, Builder))
|
if (SimplifyEqualityComparisonWithOnlyPredecessor(BI, OnlyPred, Builder))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
// This block must be empty, except for the setcond inst, if it exists.
|
// This block must be empty, except for the setcond inst, if it exists.
|
||||||
// Ignore dbg intrinsics.
|
// Ignore dbg intrinsics.
|
||||||
|
@ -5761,14 +5757,14 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
++I;
|
++I;
|
||||||
if (&*I == BI) {
|
if (&*I == BI) {
|
||||||
if (FoldValueComparisonIntoPredecessors(BI, Builder))
|
if (FoldValueComparisonIntoPredecessors(BI, Builder))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
} else if (&*I == cast<Instruction>(BI->getCondition())) {
|
} else if (&*I == cast<Instruction>(BI->getCondition())) {
|
||||||
++I;
|
++I;
|
||||||
// Ignore dbg intrinsics.
|
// Ignore dbg intrinsics.
|
||||||
while (isa<DbgInfoIntrinsic>(I))
|
while (isa<DbgInfoIntrinsic>(I))
|
||||||
++I;
|
++I;
|
||||||
if (&*I == BI && FoldValueComparisonIntoPredecessors(BI, Builder))
|
if (&*I == BI && FoldValueComparisonIntoPredecessors(BI, Builder))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5795,7 +5791,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
: ConstantInt::getFalse(BB->getContext());
|
: ConstantInt::getFalse(BB->getContext());
|
||||||
BI->setCondition(CI);
|
BI->setCondition(CI);
|
||||||
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
|
RecursivelyDeleteTriviallyDeadInstructions(OldCond);
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5804,7 +5800,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
// branches to us and one of our successors, fold the comparison into the
|
// branches to us and one of our successors, fold the comparison into the
|
||||||
// predecessor and use logical operations to pick the right destination.
|
// predecessor and use logical operations to pick the right destination.
|
||||||
if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
|
if (FoldBranchToCommonDest(BI, Options.BonusInstThreshold))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
// We have a conditional branch to two blocks that are only reachable
|
// We have a conditional branch to two blocks that are only reachable
|
||||||
// from BI. We know that the condbr dominates the two blocks, so see if
|
// from BI. We know that the condbr dominates the two blocks, so see if
|
||||||
|
@ -5813,7 +5809,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
if (BI->getSuccessor(0)->getSinglePredecessor()) {
|
if (BI->getSuccessor(0)->getSinglePredecessor()) {
|
||||||
if (BI->getSuccessor(1)->getSinglePredecessor()) {
|
if (BI->getSuccessor(1)->getSinglePredecessor()) {
|
||||||
if (HoistThenElseCodeToIf(BI, TTI))
|
if (HoistThenElseCodeToIf(BI, TTI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
} else {
|
} else {
|
||||||
// If Successor #1 has multiple preds, we may be able to conditionally
|
// If Successor #1 has multiple preds, we may be able to conditionally
|
||||||
// execute Successor #0 if it branches to Successor #1.
|
// execute Successor #0 if it branches to Successor #1.
|
||||||
|
@ -5821,7 +5817,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
if (Succ0TI->getNumSuccessors() == 1 &&
|
if (Succ0TI->getNumSuccessors() == 1 &&
|
||||||
Succ0TI->getSuccessor(0) == BI->getSuccessor(1))
|
Succ0TI->getSuccessor(0) == BI->getSuccessor(1))
|
||||||
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(0), TTI))
|
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(0), TTI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
} else if (BI->getSuccessor(1)->getSinglePredecessor()) {
|
} else if (BI->getSuccessor(1)->getSinglePredecessor()) {
|
||||||
// If Successor #0 has multiple preds, we may be able to conditionally
|
// If Successor #0 has multiple preds, we may be able to conditionally
|
||||||
|
@ -5830,22 +5826,22 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
if (Succ1TI->getNumSuccessors() == 1 &&
|
if (Succ1TI->getNumSuccessors() == 1 &&
|
||||||
Succ1TI->getSuccessor(0) == BI->getSuccessor(0))
|
Succ1TI->getSuccessor(0) == BI->getSuccessor(0))
|
||||||
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(1), TTI))
|
if (SpeculativelyExecuteBB(BI, BI->getSuccessor(1), TTI))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a branch on a phi node in the current block, thread control
|
// If this is a branch on a phi node in the current block, thread control
|
||||||
// through this block if any PHI node entries are constants.
|
// through this block if any PHI node entries are constants.
|
||||||
if (PHINode *PN = dyn_cast<PHINode>(BI->getCondition()))
|
if (PHINode *PN = dyn_cast<PHINode>(BI->getCondition()))
|
||||||
if (PN->getParent() == BI->getParent())
|
if (PN->getParent() == BI->getParent())
|
||||||
if (FoldCondBranchOnPHI(BI, DL, AC))
|
if (FoldCondBranchOnPHI(BI, DL, Options.AC))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
// Scan predecessor blocks for conditional branches.
|
// Scan predecessor blocks for conditional branches.
|
||||||
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
|
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
|
||||||
if (BranchInst *PBI = dyn_cast<BranchInst>((*PI)->getTerminator()))
|
if (BranchInst *PBI = dyn_cast<BranchInst>((*PI)->getTerminator()))
|
||||||
if (PBI != BI && PBI->isConditional())
|
if (PBI != BI && PBI->isConditional())
|
||||||
if (SimplifyCondBranchToCondBranch(PBI, BI, DL))
|
if (SimplifyCondBranchToCondBranch(PBI, BI, DL))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
// Look for diamond patterns.
|
// Look for diamond patterns.
|
||||||
if (MergeCondStores)
|
if (MergeCondStores)
|
||||||
|
@ -5853,7 +5849,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
|
||||||
if (BranchInst *PBI = dyn_cast<BranchInst>(PrevBB->getTerminator()))
|
if (BranchInst *PBI = dyn_cast<BranchInst>(PrevBB->getTerminator()))
|
||||||
if (PBI != BI && PBI->isConditional())
|
if (PBI != BI && PBI->isConditional())
|
||||||
if (mergeConditionalStores(PBI, BI, DL))
|
if (mergeConditionalStores(PBI, BI, DL))
|
||||||
return SimplifyCFG(BB, TTI, AC, Options) | true;
|
return simplifyCFG(BB, TTI, Options) | true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6009,10 +6005,10 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llvm::SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
bool llvm::simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
|
||||||
AssumptionCache *AC, const SimplifyCFGOptions &Options,
|
const SimplifyCFGOptions &Options,
|
||||||
SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
|
SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
|
||||||
return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(), AC, LoopHeaders,
|
return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(), LoopHeaders,
|
||||||
Options)
|
Options)
|
||||||
.run(BB);
|
.run(BB);
|
||||||
}
|
}
|
||||||
|
|
|
@ -648,7 +648,7 @@ bool ReduceSimplifyCFG::TestBlocks(std::vector<const BasicBlock *> &BBs) {
|
||||||
++BBIt;
|
++BBIt;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SimplifyCFG(&*BBIt++, TTI);
|
simplifyCFG(&*BBIt++, TTI);
|
||||||
}
|
}
|
||||||
// Verify we didn't break anything
|
// Verify we didn't break anything
|
||||||
std::vector<std::string> Passes;
|
std::vector<std::string> Passes;
|
||||||
|
|
Loading…
Reference in New Issue