1215746b4SAdam Nemet //===- LoopVersioning.cpp - Utility to version a loop ---------------------===//
2215746b4SAdam Nemet //
3215746b4SAdam Nemet //                     The LLVM Compiler Infrastructure
4215746b4SAdam Nemet //
5215746b4SAdam Nemet // This file is distributed under the University of Illinois Open Source
6215746b4SAdam Nemet // License. See LICENSE.TXT for details.
7215746b4SAdam Nemet //
8215746b4SAdam Nemet //===----------------------------------------------------------------------===//
9215746b4SAdam Nemet //
10215746b4SAdam Nemet // This file defines a utility class to perform loop versioning.  The versioned
11215746b4SAdam Nemet // loop speculates that otherwise may-aliasing memory accesses don't overlap and
12215746b4SAdam Nemet // emits checks to prove this.
13215746b4SAdam Nemet //
14215746b4SAdam Nemet //===----------------------------------------------------------------------===//
15215746b4SAdam Nemet 
1694c83370SDavid Blaikie #include "llvm/Transforms/Utils/LoopVersioning.h"
17215746b4SAdam Nemet #include "llvm/Analysis/LoopAccessAnalysis.h"
18215746b4SAdam Nemet #include "llvm/Analysis/LoopInfo.h"
192910a4f6SSilviu Baranga #include "llvm/Analysis/ScalarEvolutionExpander.h"
20215746b4SAdam Nemet #include "llvm/IR/Dominators.h"
21215746b4SAdam Nemet #include "llvm/Transforms/Utils/BasicBlockUtils.h"
22215746b4SAdam Nemet #include "llvm/Transforms/Utils/Cloning.h"
23215746b4SAdam Nemet 
24215746b4SAdam Nemet using namespace llvm;
25215746b4SAdam Nemet 
262910a4f6SSilviu Baranga LoopVersioning::LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI,
272910a4f6SSilviu Baranga                                DominatorTree *DT, ScalarEvolution *SE,
282910a4f6SSilviu Baranga                                bool UseLAIChecks)
292910a4f6SSilviu Baranga     : VersionedLoop(L), NonVersionedLoop(nullptr), LAI(LAI), LI(LI), DT(DT),
302910a4f6SSilviu Baranga       SE(SE) {
31215746b4SAdam Nemet   assert(L->getExitBlock() && "No single exit block");
32215746b4SAdam Nemet   assert(L->getLoopPreheader() && "No preheader");
332910a4f6SSilviu Baranga   if (UseLAIChecks) {
342910a4f6SSilviu Baranga     setAliasChecks(LAI.getRuntimePointerChecking()->getChecks());
35*9cd9a7e3SSilviu Baranga     setSCEVChecks(LAI.PSE.getUnionPredicate());
362910a4f6SSilviu Baranga   }
37215746b4SAdam Nemet }
38215746b4SAdam Nemet 
392910a4f6SSilviu Baranga void LoopVersioning::setAliasChecks(
402910a4f6SSilviu Baranga     const SmallVector<RuntimePointerChecking::PointerCheck, 4> Checks) {
412910a4f6SSilviu Baranga   AliasChecks = std::move(Checks);
422910a4f6SSilviu Baranga }
432910a4f6SSilviu Baranga 
442910a4f6SSilviu Baranga void LoopVersioning::setSCEVChecks(SCEVUnionPredicate Check) {
452910a4f6SSilviu Baranga   Preds = std::move(Check);
46dfaeb33eSAdam Nemet }
47dfaeb33eSAdam Nemet 
48e4813409SAdam Nemet void LoopVersioning::versionLoop(
49e4813409SAdam Nemet     const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
50215746b4SAdam Nemet   Instruction *FirstCheckInst;
51215746b4SAdam Nemet   Instruction *MemRuntimeCheck;
522910a4f6SSilviu Baranga   Value *SCEVRuntimeCheck;
532910a4f6SSilviu Baranga   Value *RuntimeCheck = nullptr;
542910a4f6SSilviu Baranga 
55215746b4SAdam Nemet   // Add the memcheck in the original preheader (this is empty initially).
562910a4f6SSilviu Baranga   BasicBlock *RuntimeCheckBB = VersionedLoop->getLoopPreheader();
57215746b4SAdam Nemet   std::tie(FirstCheckInst, MemRuntimeCheck) =
582910a4f6SSilviu Baranga       LAI.addRuntimeChecks(RuntimeCheckBB->getTerminator(), AliasChecks);
59215746b4SAdam Nemet   assert(MemRuntimeCheck && "called even though needsAnyChecking = false");
60215746b4SAdam Nemet 
61*9cd9a7e3SSilviu Baranga   const SCEVUnionPredicate &Pred = LAI.PSE.getUnionPredicate();
622910a4f6SSilviu Baranga   SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(),
632910a4f6SSilviu Baranga                    "scev.check");
642910a4f6SSilviu Baranga   SCEVRuntimeCheck =
652910a4f6SSilviu Baranga       Exp.expandCodeForPredicate(&Pred, RuntimeCheckBB->getTerminator());
662910a4f6SSilviu Baranga   auto *CI = dyn_cast<ConstantInt>(SCEVRuntimeCheck);
672910a4f6SSilviu Baranga 
682910a4f6SSilviu Baranga   // Discard the SCEV runtime check if it is always true.
692910a4f6SSilviu Baranga   if (CI && CI->isZero())
702910a4f6SSilviu Baranga     SCEVRuntimeCheck = nullptr;
712910a4f6SSilviu Baranga 
722910a4f6SSilviu Baranga   if (MemRuntimeCheck && SCEVRuntimeCheck) {
732910a4f6SSilviu Baranga     RuntimeCheck = BinaryOperator::Create(Instruction::Or, MemRuntimeCheck,
742910a4f6SSilviu Baranga                                           SCEVRuntimeCheck, "ldist.safe");
752910a4f6SSilviu Baranga     if (auto *I = dyn_cast<Instruction>(RuntimeCheck))
762910a4f6SSilviu Baranga       I->insertBefore(RuntimeCheckBB->getTerminator());
772910a4f6SSilviu Baranga   } else
782910a4f6SSilviu Baranga     RuntimeCheck = MemRuntimeCheck ? MemRuntimeCheck : SCEVRuntimeCheck;
792910a4f6SSilviu Baranga 
802910a4f6SSilviu Baranga   assert(RuntimeCheck && "called even though we don't need "
812910a4f6SSilviu Baranga                          "any runtime checks");
822910a4f6SSilviu Baranga 
83215746b4SAdam Nemet   // Rename the block to make the IR more readable.
842910a4f6SSilviu Baranga   RuntimeCheckBB->setName(VersionedLoop->getHeader()->getName() +
852910a4f6SSilviu Baranga                           ".lver.check");
86215746b4SAdam Nemet 
87215746b4SAdam Nemet   // Create empty preheader for the loop (and after cloning for the
88215746b4SAdam Nemet   // non-versioned loop).
892910a4f6SSilviu Baranga   BasicBlock *PH =
902910a4f6SSilviu Baranga       SplitBlock(RuntimeCheckBB, RuntimeCheckBB->getTerminator(), DT, LI);
91215746b4SAdam Nemet   PH->setName(VersionedLoop->getHeader()->getName() + ".ph");
92215746b4SAdam Nemet 
93215746b4SAdam Nemet   // Clone the loop including the preheader.
94215746b4SAdam Nemet   //
95215746b4SAdam Nemet   // FIXME: This does not currently preserve SimplifyLoop because the exit
96215746b4SAdam Nemet   // block is a join between the two loops.
97215746b4SAdam Nemet   SmallVector<BasicBlock *, 8> NonVersionedLoopBlocks;
98215746b4SAdam Nemet   NonVersionedLoop =
992910a4f6SSilviu Baranga       cloneLoopWithPreheader(PH, RuntimeCheckBB, VersionedLoop, VMap,
1002910a4f6SSilviu Baranga                              ".lver.orig", LI, DT, NonVersionedLoopBlocks);
101215746b4SAdam Nemet   remapInstructionsInBlocks(NonVersionedLoopBlocks, VMap);
102215746b4SAdam Nemet 
103215746b4SAdam Nemet   // Insert the conditional branch based on the result of the memchecks.
1042910a4f6SSilviu Baranga   Instruction *OrigTerm = RuntimeCheckBB->getTerminator();
105215746b4SAdam Nemet   BranchInst::Create(NonVersionedLoop->getLoopPreheader(),
1062910a4f6SSilviu Baranga                      VersionedLoop->getLoopPreheader(), RuntimeCheck, OrigTerm);
107215746b4SAdam Nemet   OrigTerm->eraseFromParent();
108215746b4SAdam Nemet 
109215746b4SAdam Nemet   // The loops merge in the original exit block.  This is now dominated by the
110215746b4SAdam Nemet   // memchecking block.
1112910a4f6SSilviu Baranga   DT->changeImmediateDominator(VersionedLoop->getExitBlock(), RuntimeCheckBB);
112e4813409SAdam Nemet 
113e4813409SAdam Nemet   // Adds the necessary PHI nodes for the versioned loops based on the
114e4813409SAdam Nemet   // loop-defined values used outside of the loop.
115e4813409SAdam Nemet   addPHINodes(DefsUsedOutside);
116215746b4SAdam Nemet }
117215746b4SAdam Nemet 
118215746b4SAdam Nemet void LoopVersioning::addPHINodes(
119215746b4SAdam Nemet     const SmallVectorImpl<Instruction *> &DefsUsedOutside) {
120215746b4SAdam Nemet   BasicBlock *PHIBlock = VersionedLoop->getExitBlock();
121215746b4SAdam Nemet   assert(PHIBlock && "No single successor to loop exit block");
122215746b4SAdam Nemet 
123215746b4SAdam Nemet   for (auto *Inst : DefsUsedOutside) {
124215746b4SAdam Nemet     auto *NonVersionedLoopInst = cast<Instruction>(VMap[Inst]);
125215746b4SAdam Nemet     PHINode *PN;
126215746b4SAdam Nemet 
127215746b4SAdam Nemet     // First see if we have a single-operand PHI with the value defined by the
128215746b4SAdam Nemet     // original loop.
129215746b4SAdam Nemet     for (auto I = PHIBlock->begin(); (PN = dyn_cast<PHINode>(I)); ++I) {
130215746b4SAdam Nemet       assert(PN->getNumOperands() == 1 &&
131215746b4SAdam Nemet              "Exit block should only have on predecessor");
132215746b4SAdam Nemet       if (PN->getIncomingValue(0) == Inst)
133215746b4SAdam Nemet         break;
134215746b4SAdam Nemet     }
135215746b4SAdam Nemet     // If not create it.
136215746b4SAdam Nemet     if (!PN) {
137215746b4SAdam Nemet       PN = PHINode::Create(Inst->getType(), 2, Inst->getName() + ".lver",
1385b4c837cSDuncan P. N. Exon Smith                            &PHIBlock->front());
139215746b4SAdam Nemet       for (auto *User : Inst->users())
140215746b4SAdam Nemet         if (!VersionedLoop->contains(cast<Instruction>(User)->getParent()))
141215746b4SAdam Nemet           User->replaceUsesOfWith(Inst, PN);
142215746b4SAdam Nemet       PN->addIncoming(Inst, VersionedLoop->getExitingBlock());
143215746b4SAdam Nemet     }
144215746b4SAdam Nemet     // Add the new incoming value from the non-versioned loop.
145215746b4SAdam Nemet     PN->addIncoming(NonVersionedLoopInst, NonVersionedLoop->getExitingBlock());
146215746b4SAdam Nemet   }
147215746b4SAdam Nemet }
148