2015-07-11 02:55:13 +08:00
|
|
|
//===- LoopVersioning.cpp - Utility to version a loop ---------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines a utility class to perform loop versioning. The versioned
|
|
|
|
// loop speculates that otherwise may-aliasing memory accesses don't overlap and
|
|
|
|
// emits checks to prove this.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-10-27 02:40:56 +08:00
|
|
|
#include "llvm/Transforms/Utils/LoopVersioning.h"
|
2015-07-11 02:55:13 +08:00
|
|
|
#include "llvm/Analysis/LoopAccessAnalysis.h"
|
|
|
|
#include "llvm/Analysis/LoopInfo.h"
|
2015-11-09 21:26:09 +08:00
|
|
|
#include "llvm/Analysis/ScalarEvolutionExpander.h"
|
2015-07-11 02:55:13 +08:00
|
|
|
#include "llvm/IR/Dominators.h"
|
|
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
|
|
#include "llvm/Transforms/Utils/Cloning.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2015-11-09 21:26:09 +08:00
|
|
|
LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI,
|
|
|
|
DominatorTree *DT, ScalarEvolution *SE,
|
|
|
|
bool UseLAIChecks)
|
|
|
|
: VersionedLoop(L), NonVersionedLoop(nullptr), LAI(LAI), LI(LI), DT(DT),
|
|
|
|
SE(SE) {
|
2015-07-11 02:55:13 +08:00
|
|
|
assert(L->getExitBlock() && "No single exit block");
|
2015-08-13 00:51:19 +08:00
|
|
|
assert(L->getLoopPreheader() && "No preheader");
|
2015-11-09 21:26:09 +08:00
|
|
|
if (UseLAIChecks) {
|
|
|
|
setAliasChecks(LAI.getRuntimePointerChecking()->getChecks());
|
Re-commit r255115, with the PredicatedScalarEvolution class moved to
ScalarEvolution.h, in order to avoid cyclic dependencies between the Transform
and Analysis modules:
[LV][LAA] Add a layer over SCEV to apply run-time checked knowledge on SCEV expressions
Summary:
This change creates a layer over ScalarEvolution for LAA and LV, and centralizes the
usage of SCEV predicates. The SCEVPredicatedLayer takes the statically deduced knowledge
by ScalarEvolution and applies the knowledge from the SCEV predicates. The end goal is
that both LAA and LV should use this interface everywhere.
This also solves a problem involving the result of SCEV expression rewritting when
the predicate changes. Suppose we have the expression (sext {a,+,b}) and two predicates
P1: {a,+,b} has nsw
P2: b = 1.
Applying P1 and then P2 gives us {a,+,1}, while applying P2 and the P1 gives us
sext({a,+,1}) (the AddRec expression was changed by P2 so P1 no longer applies).
The SCEVPredicatedLayer maintains the order of transformations by feeding back
the results of previous transformations into new transformations, and therefore
avoiding this issue.
The SCEVPredicatedLayer maintains a cache to remember the results of previous
SCEV rewritting results. This also has the benefit of reducing the overall number
of expression rewrites.
Reviewers: mzolotukhin, anemet
Subscribers: jmolloy, sanjoy, llvm-commits
Differential Revision: http://reviews.llvm.org/D14296
llvm-svn: 255122
2015-12-10 00:06:28 +08:00
|
|
|
setSCEVChecks(LAI.PSE.getUnionPredicate());
|
2015-11-09 21:26:09 +08:00
|
|
|
}
|
2015-08-13 00:51:19 +08:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:26:09 +08:00
|
|
|
void LoopVersioning::setAliasChecks(
|
|
|
|
const SmallVector<RuntimePointerChecking::PointerCheck, 4> Checks) {
|
|
|
|
AliasChecks = std::move(Checks);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LoopVersioning::setSCEVChecks(SCEVUnionPredicate Check) {
|
|
|
|
Preds = std::move(Check);
|
2015-07-11 02:55:13 +08:00
|
|
|
}
|
|
|
|
|
2015-08-21 01:22:29 +08:00
|
|
|
void LoopVersioning::versionLoop(
|
|
|
|
const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
|
2015-07-11 02:55:13 +08:00
|
|
|
Instruction *FirstCheckInst;
|
|
|
|
Instruction *MemRuntimeCheck;
|
2015-11-09 21:26:09 +08:00
|
|
|
Value *SCEVRuntimeCheck;
|
|
|
|
Value *RuntimeCheck = nullptr;
|
|
|
|
|
2015-07-11 02:55:13 +08:00
|
|
|
// Add the memcheck in the original preheader (this is empty initially).
|
2015-11-09 21:26:09 +08:00
|
|
|
BasicBlock *RuntimeCheckBB = VersionedLoop->getLoopPreheader();
|
2015-07-11 02:55:13 +08:00
|
|
|
std::tie(FirstCheckInst, MemRuntimeCheck) =
|
2015-11-09 21:26:09 +08:00
|
|
|
LAI.addRuntimeChecks(RuntimeCheckBB->getTerminator(), AliasChecks);
|
2015-07-11 02:55:13 +08:00
|
|
|
assert(MemRuntimeCheck && "called even though needsAnyChecking = false");
|
|
|
|
|
Re-commit r255115, with the PredicatedScalarEvolution class moved to
ScalarEvolution.h, in order to avoid cyclic dependencies between the Transform
and Analysis modules:
[LV][LAA] Add a layer over SCEV to apply run-time checked knowledge on SCEV expressions
Summary:
This change creates a layer over ScalarEvolution for LAA and LV, and centralizes the
usage of SCEV predicates. The SCEVPredicatedLayer takes the statically deduced knowledge
by ScalarEvolution and applies the knowledge from the SCEV predicates. The end goal is
that both LAA and LV should use this interface everywhere.
This also solves a problem involving the result of SCEV expression rewritting when
the predicate changes. Suppose we have the expression (sext {a,+,b}) and two predicates
P1: {a,+,b} has nsw
P2: b = 1.
Applying P1 and then P2 gives us {a,+,1}, while applying P2 and the P1 gives us
sext({a,+,1}) (the AddRec expression was changed by P2 so P1 no longer applies).
The SCEVPredicatedLayer maintains the order of transformations by feeding back
the results of previous transformations into new transformations, and therefore
avoiding this issue.
The SCEVPredicatedLayer maintains a cache to remember the results of previous
SCEV rewritting results. This also has the benefit of reducing the overall number
of expression rewrites.
Reviewers: mzolotukhin, anemet
Subscribers: jmolloy, sanjoy, llvm-commits
Differential Revision: http://reviews.llvm.org/D14296
llvm-svn: 255122
2015-12-10 00:06:28 +08:00
|
|
|
const SCEVUnionPredicate &Pred = LAI.PSE.getUnionPredicate();
|
2015-11-09 21:26:09 +08:00
|
|
|
SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(),
|
|
|
|
"scev.check");
|
|
|
|
SCEVRuntimeCheck =
|
|
|
|
Exp.expandCodeForPredicate(&Pred, RuntimeCheckBB->getTerminator());
|
|
|
|
auto *CI = dyn_cast<ConstantInt>(SCEVRuntimeCheck);
|
|
|
|
|
|
|
|
// Discard the SCEV runtime check if it is always true.
|
|
|
|
if (CI && CI->isZero())
|
|
|
|
SCEVRuntimeCheck = nullptr;
|
|
|
|
|
|
|
|
if (MemRuntimeCheck && SCEVRuntimeCheck) {
|
|
|
|
RuntimeCheck = BinaryOperator::Create(Instruction::Or, MemRuntimeCheck,
|
|
|
|
SCEVRuntimeCheck, "ldist.safe");
|
|
|
|
if (auto *I = dyn_cast<Instruction>(RuntimeCheck))
|
|
|
|
I->insertBefore(RuntimeCheckBB->getTerminator());
|
|
|
|
} else
|
|
|
|
RuntimeCheck = MemRuntimeCheck ? MemRuntimeCheck : SCEVRuntimeCheck;
|
|
|
|
|
|
|
|
assert(RuntimeCheck && "called even though we don't need "
|
|
|
|
"any runtime checks");
|
|
|
|
|
2015-07-11 02:55:13 +08:00
|
|
|
// Rename the block to make the IR more readable.
|
2015-11-09 21:26:09 +08:00
|
|
|
RuntimeCheckBB->setName(VersionedLoop->getHeader()->getName() +
|
|
|
|
".lver.check");
|
2015-07-11 02:55:13 +08:00
|
|
|
|
|
|
|
// Create empty preheader for the loop (and after cloning for the
|
|
|
|
// non-versioned loop).
|
2015-11-09 21:26:09 +08:00
|
|
|
BasicBlock *PH =
|
|
|
|
SplitBlock(RuntimeCheckBB, RuntimeCheckBB->getTerminator(), DT, LI);
|
2015-07-11 02:55:13 +08:00
|
|
|
PH->setName(VersionedLoop->getHeader()->getName() + ".ph");
|
|
|
|
|
|
|
|
// Clone the loop including the preheader.
|
|
|
|
//
|
|
|
|
// FIXME: This does not currently preserve SimplifyLoop because the exit
|
|
|
|
// block is a join between the two loops.
|
|
|
|
SmallVector<BasicBlock *, 8> NonVersionedLoopBlocks;
|
|
|
|
NonVersionedLoop =
|
2015-11-09 21:26:09 +08:00
|
|
|
cloneLoopWithPreheader(PH, RuntimeCheckBB, VersionedLoop, VMap,
|
|
|
|
".lver.orig", LI, DT, NonVersionedLoopBlocks);
|
2015-07-11 02:55:13 +08:00
|
|
|
remapInstructionsInBlocks(NonVersionedLoopBlocks, VMap);
|
|
|
|
|
|
|
|
// Insert the conditional branch based on the result of the memchecks.
|
2015-11-09 21:26:09 +08:00
|
|
|
Instruction *OrigTerm = RuntimeCheckBB->getTerminator();
|
2015-07-11 02:55:13 +08:00
|
|
|
BranchInst::Create(NonVersionedLoop->getLoopPreheader(),
|
2015-11-09 21:26:09 +08:00
|
|
|
VersionedLoop->getLoopPreheader(), RuntimeCheck, OrigTerm);
|
2015-07-11 02:55:13 +08:00
|
|
|
OrigTerm->eraseFromParent();
|
|
|
|
|
|
|
|
// The loops merge in the original exit block. This is now dominated by the
|
|
|
|
// memchecking block.
|
2015-11-09 21:26:09 +08:00
|
|
|
DT->changeImmediateDominator(VersionedLoop->getExitBlock(), RuntimeCheckBB);
|
2015-08-21 01:22:29 +08:00
|
|
|
|
|
|
|
// Adds the necessary PHI nodes for the versioned loops based on the
|
|
|
|
// loop-defined values used outside of the loop.
|
|
|
|
addPHINodes(DefsUsedOutside);
|
2015-07-11 02:55:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void LoopVersioning::addPHINodes(
|
|
|
|
const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
|
|
|
|
BasicBlock *PHIBlock = VersionedLoop->getExitBlock();
|
|
|
|
assert(PHIBlock && "No single successor to loop exit block");
|
|
|
|
|
|
|
|
for (auto *Inst : DefsUsedOutside) {
|
|
|
|
auto *NonVersionedLoopInst = cast<Instruction>(VMap[Inst]);
|
|
|
|
PHINode *PN;
|
|
|
|
|
|
|
|
// First see if we have a single-operand PHI with the value defined by the
|
|
|
|
// original loop.
|
|
|
|
for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) {
|
|
|
|
assert(PN->getNumOperands() == 1 &&
|
|
|
|
"Exit block should only have on predecessor");
|
|
|
|
if (PN->getIncomingValue(0) == Inst)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// If not create it.
|
|
|
|
if (!PN) {
|
|
|
|
PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".lver",
|
2015-10-13 10:39:05 +08:00
|
|
|
&PHIBlock->front());
|
2015-07-11 02:55:13 +08:00
|
|
|
for (auto *User : Inst->users())
|
|
|
|
if (!VersionedLoop->contains(cast<Instruction>(User)->getParent()))
|
|
|
|
User->replaceUsesOfWith(Inst, PN);
|
|
|
|
PN->addIncoming(Inst, VersionedLoop->getExitingBlock());
|
|
|
|
}
|
|
|
|
// Add the new incoming value from the non-versioned loop.
|
|
|
|
PN->addIncoming(NonVersionedLoopInst, NonVersionedLoop->getExitingBlock());
|
|
|
|
}
|
|
|
|
}
|