1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

Preserve the assumption cache more often

We were clearing it out in LoopUnswitch and InlineFunction instead of
attempting to preserve it.

llvm-svn: 278860
This commit is contained in:
David Majnemer 2016-08-16 22:07:32 +00:00
parent 110b6da1b2
commit b267649967
2 changed files with 29 additions and 18 deletions

View File

@ -1078,10 +1078,6 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
F->getBasicBlockList(), F->getBasicBlockList(),
NewBlocks[0]->getIterator(), F->end()); NewBlocks[0]->getIterator(), F->end());
// FIXME: We could register any cloned assumptions instead of clearing the
// whole function's cache.
AC->clear();
// Now we create the new Loop object for the versioned loop. // Now we create the new Loop object for the versioned loop.
Loop *NewLoop = CloneLoop(L, L->getParentLoop(), VMap, LI, LPM); Loop *NewLoop = CloneLoop(L, L->getParentLoop(), VMap, LI, LPM);
@ -1131,10 +1127,15 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
} }
// Rewrite the code to refer to itself. // Rewrite the code to refer to itself.
for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i) {
for (Instruction &I : *NewBlocks[i]) for (Instruction &I : *NewBlocks[i]) {
RemapInstruction(&I, VMap, RemapInstruction(&I, VMap,
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
if (auto *II = dyn_cast<IntrinsicInst>(&I))
if (II->getIntrinsicID() == Intrinsic::assume)
AC->registerAssumption(II);
}
}
// Rewrite the original preheader to select between versions of the loop. // Rewrite the original preheader to select between versions of the loop.
BranchInst *OldBR = cast<BranchInst>(loopPreheader->getTerminator()); BranchInst *OldBR = cast<BranchInst>(loopPreheader->getTerminator());

View File

@ -1055,6 +1055,9 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap,
static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) { static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
if (!PreserveAlignmentAssumptions) if (!PreserveAlignmentAssumptions)
return; return;
AssumptionCache *AC = IFI.GetAssumptionCache
? &(*IFI.GetAssumptionCache)(*CS.getCaller())
: nullptr;
auto &DL = CS.getCaller()->getParent()->getDataLayout(); auto &DL = CS.getCaller()->getParent()->getDataLayout();
// To avoid inserting redundant assumptions, we should check for assumptions // To avoid inserting redundant assumptions, we should check for assumptions
@ -1077,13 +1080,13 @@ static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
// If we can already prove the asserted alignment in the context of the // If we can already prove the asserted alignment in the context of the
// caller, then don't bother inserting the assumption. // caller, then don't bother inserting the assumption.
Value *Arg = CS.getArgument(I->getArgNo()); Value *Arg = CS.getArgument(I->getArgNo());
if (getKnownAlignment(Arg, DL, CS.getInstruction(), if (getKnownAlignment(Arg, DL, CS.getInstruction(), AC, &DT) >= Align)
&(*IFI.GetAssumptionCache)(*CS.getCaller()),
&DT) >= Align)
continue; continue;
IRBuilder<>(CS.getInstruction()) CallInst *NewAssumption = IRBuilder<>(CS.getInstruction())
.CreateAlignmentAssumption(DL, Arg, Align); .CreateAlignmentAssumption(DL, Arg, Align);
if (AC)
AC->registerAssumption(NewAssumption);
} }
} }
} }
@ -1194,12 +1197,13 @@ static Value *HandleByValArgument(Value *Arg, Instruction *TheCall,
if (ByValAlignment <= 1) // 0 = unspecified, 1 = no particular alignment. if (ByValAlignment <= 1) // 0 = unspecified, 1 = no particular alignment.
return Arg; return Arg;
AssumptionCache *AC =
IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr;
const DataLayout &DL = Caller->getParent()->getDataLayout(); const DataLayout &DL = Caller->getParent()->getDataLayout();
// If the pointer is already known to be sufficiently aligned, or if we can // If the pointer is already known to be sufficiently aligned, or if we can
// round it up to a larger alignment, then we don't need a temporary. // round it up to a larger alignment, then we don't need a temporary.
if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall, if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall, AC) >=
&(*IFI.GetAssumptionCache)(*Caller)) >=
ByValAlignment) ByValAlignment)
return Arg; return Arg;
@ -1609,10 +1613,15 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// Propagate llvm.mem.parallel_loop_access if necessary. // Propagate llvm.mem.parallel_loop_access if necessary.
PropagateParallelLoopAccessMetadata(CS, VMap); PropagateParallelLoopAccessMetadata(CS, VMap);
// FIXME: We could register any cloned assumptions instead of clearing the // Register any cloned assumptions.
// whole function's cache.
if (IFI.GetAssumptionCache) if (IFI.GetAssumptionCache)
(*IFI.GetAssumptionCache)(*Caller).clear(); for (BasicBlock &NewBlock :
make_range(FirstNewBlock->getIterator(), Caller->end()))
for (Instruction &I : NewBlock) {
if (auto *II = dyn_cast<IntrinsicInst>(&I))
if (II->getIntrinsicID() == Intrinsic::assume)
(*IFI.GetAssumptionCache)(*Caller).registerAssumption(II);
}
} }
// If there are any alloca instructions in the block that used to be the entry // If there are any alloca instructions in the block that used to be the entry
@ -2130,9 +2139,10 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// the entries are the same or undef). If so, remove the PHI so it doesn't // the entries are the same or undef). If so, remove the PHI so it doesn't
// block other optimizations. // block other optimizations.
if (PHI) { if (PHI) {
AssumptionCache *AC =
IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr;
auto &DL = Caller->getParent()->getDataLayout(); auto &DL = Caller->getParent()->getDataLayout();
if (Value *V = SimplifyInstruction(PHI, DL, nullptr, nullptr, if (Value *V = SimplifyInstruction(PHI, DL, nullptr, nullptr, AC)) {
&(*IFI.GetAssumptionCache)(*Caller))) {
PHI->replaceAllUsesWith(V); PHI->replaceAllUsesWith(V);
PHI->eraseFromParent(); PHI->eraseFromParent();
} }