#include "llvm/Transforms/Scalar/LoopInterchange.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/LoopCacheAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopNestAnalysis.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include <cassert>
#include <utility>
#include <vector>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(LoopsInterchanged, "Number of loops interchanged");
static cl::opt<int> LoopInterchangeCostThreshold(
"loop-interchange-threshold", cl::init(0), cl::Hidden,
cl::desc("Interchange if you gain more than this number"));
namespace {
LoopVector;
CharMatrix;
}
static const unsigned MaxMemInstrCount = …;
static const unsigned MaxLoopNestDepth = …;
#ifdef DUMP_DEP_MATRICIES
static void printDepMatrix(CharMatrix &DepMatrix) {
for (auto &Row : DepMatrix) {
for (auto D : Row)
LLVM_DEBUG(dbgs() << D << " ");
LLVM_DEBUG(dbgs() << "\n");
}
}
#endif
static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
Loop *L, DependenceInfo *DI,
ScalarEvolution *SE) { … }
static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx,
unsigned ToIndx) { … }
static bool isLexicographicallyPositive(std::vector<char> &DV) { … }
static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix,
unsigned InnerLoopId,
unsigned OuterLoopId) { … }
static void populateWorklist(Loop &L, LoopVector &LoopList) { … }
namespace {
class LoopInterchangeLegality { … };
class LoopInterchangeProfitability { … };
class LoopInterchangeTransform { … };
struct LoopInterchange { … };
}
bool LoopInterchangeLegality::containsUnsafeInstructions(BasicBlock *BB) { … }
bool LoopInterchangeLegality::tightlyNested(Loop *OuterLoop, Loop *InnerLoop) { … }
bool LoopInterchangeLegality::isLoopStructureUnderstood() { … }
static Value *followLCSSA(Value *SV) { … }
static PHINode *findInnerReductionPhi(Loop *L, Value *V) { … }
bool LoopInterchangeLegality::findInductionAndReductions(
Loop *L, SmallVector<PHINode *, 8> &Inductions, Loop *InnerLoop) { … }
bool LoopInterchangeLegality::currentLimitations() { … }
bool LoopInterchangeLegality::findInductions(
Loop *L, SmallVectorImpl<PHINode *> &Inductions) { … }
static bool
areInnerLoopExitPHIsSupported(Loop *InnerL, Loop *OuterL,
SmallPtrSetImpl<PHINode *> &Reductions) { … }
static bool areOuterLoopExitPHIsSupported(Loop *OuterLoop, Loop *InnerLoop) { … }
static bool areInnerLoopLatchPHIsSupported(Loop *OuterLoop, Loop *InnerLoop) { … }
bool LoopInterchangeLegality::canInterchangeLoops(unsigned InnerLoopId,
unsigned OuterLoopId,
CharMatrix &DepMatrix) { … }
int LoopInterchangeProfitability::getInstrOrderCost() { … }
std::optional<bool>
LoopInterchangeProfitability::isProfitablePerLoopCacheAnalysis(
const DenseMap<const Loop *, unsigned> &CostMap,
std::unique_ptr<CacheCost> &CC) { … }
std::optional<bool>
LoopInterchangeProfitability::isProfitablePerInstrOrderCost() { … }
std::optional<bool> LoopInterchangeProfitability::isProfitableForVectorization(
unsigned InnerLoopId, unsigned OuterLoopId, CharMatrix &DepMatrix) { … }
bool LoopInterchangeProfitability::isProfitable(
const Loop *InnerLoop, const Loop *OuterLoop, unsigned InnerLoopId,
unsigned OuterLoopId, CharMatrix &DepMatrix,
const DenseMap<const Loop *, unsigned> &CostMap,
std::unique_ptr<CacheCost> &CC) { … }
void LoopInterchangeTransform::removeChildLoop(Loop *OuterLoop,
Loop *InnerLoop) { … }
void LoopInterchangeTransform::restructureLoops(
Loop *NewInner, Loop *NewOuter, BasicBlock *OrigInnerPreHeader,
BasicBlock *OrigOuterPreHeader) { … }
bool LoopInterchangeTransform::transform() { … }
static void moveBBContents(BasicBlock *FromBB, Instruction *InsertBefore) { … }
static void swapBBContents(BasicBlock *BB1, BasicBlock *BB2) { … }
static void updateSuccessor(BranchInst *BI, BasicBlock *OldBB,
BasicBlock *NewBB,
std::vector<DominatorTree::UpdateType> &DTUpdates,
bool MustUpdateOnce = true) { … }
static void moveLCSSAPhis(BasicBlock *InnerExit, BasicBlock *InnerHeader,
BasicBlock *InnerLatch, BasicBlock *OuterHeader,
BasicBlock *OuterLatch, BasicBlock *OuterExit,
Loop *InnerLoop, LoopInfo *LI) { … }
bool LoopInterchangeTransform::adjustLoopBranches() { … }
bool LoopInterchangeTransform::adjustLoopLinks() { … }
PreservedAnalyses LoopInterchangePass::run(LoopNest &LN,
LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR,
LPMUpdater &U) { … }