#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
bool PossiblyLoopIndependent,
unsigned CommonLevels)
: Dependence(Source, Destination), Levels(CommonLevels),
- LoopIndependent(PossiblyLoopIndependent), Consistent(true),
- DV(CommonLevels ? new DVEntry[CommonLevels] : nullptr) {}
+ LoopIndependent(PossiblyLoopIndependent) {
+ Consistent = true;
+ DV = CommonLevels ? new DVEntry[CommonLevels] : nullptr;
+}
// The rest are simple getters that hide the implementation.
OS << "!\n";
}
-
-
-static
-AliasAnalysis::AliasResult underlyingObjectsAlias(AliasAnalysis *AA,
- const Value *A,
- const Value *B) {
- const Value *AObj = GetUnderlyingObject(A);
- const Value *BObj = GetUnderlyingObject(B);
+static AliasAnalysis::AliasResult underlyingObjectsAlias(AliasAnalysis *AA,
+ const DataLayout &DL,
+ const Value *A,
+ const Value *B) {
+ const Value *AObj = GetUnderlyingObject(A, DL);
+ const Value *BObj = GetUnderlyingObject(B, DL);
return AA->alias(AObj, AA->getTypeStoreSize(AObj->getType()),
BObj, AA->getTypeStoreSize(BObj->getType()));
}
Value *SrcPtr = getPointerOperand(Src);
Value *DstPtr = getPointerOperand(Dst);
- switch (underlyingObjectsAlias(AA, DstPtr, SrcPtr)) {
+ switch (underlyingObjectsAlias(AA, F->getParent()->getDataLayout(), DstPtr,
+ SrcPtr)) {
case AliasAnalysis::MayAlias:
case AliasAnalysis::PartialAlias:
// cannot analyse objects if we don't understand their aliasing.
DEBUG(dbgs() << " common nesting levels = " << CommonLevels << "\n");
DEBUG(dbgs() << " maximum nesting levels = " << MaxLevels << "\n");
- auto Result = llvm::make_unique<FullDependence>(
- Src, Dst, PossiblyLoopIndependent, CommonLevels);
+ FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
++TotalArrayPairs;
// See if there are GEPs we can use.
DEBUG(dbgs() << " SrcPtrSCEV = " << *SrcPtrSCEV << "\n");
DEBUG(dbgs() << " DstPtrSCEV = " << *DstPtrSCEV << "\n");
- UsefulGEP =
- isLoopInvariant(SrcPtrSCEV, LI->getLoopFor(Src->getParent())) &&
- isLoopInvariant(DstPtrSCEV, LI->getLoopFor(Dst->getParent()));
+ UsefulGEP = isLoopInvariant(SrcPtrSCEV, LI->getLoopFor(Src->getParent())) &&
+ isLoopInvariant(DstPtrSCEV, LI->getLoopFor(Dst->getParent())) &&
+ (SrcGEP->getNumOperands() == DstGEP->getNumOperands());
}
unsigned Pairs = UsefulGEP ? SrcGEP->idx_end() - SrcGEP->idx_begin() : 1;
SmallVector<Subscript, 4> Pair(Pairs);
collectCommonLoops(Pair[SI].Dst,
LI->getLoopFor(Dst->getParent()),
Pair[SI].Loops);
- Result->Consistent = false;
- }
- else if (Pair[SI].Classification == Subscript::ZIV) {
+ Result.Consistent = false;
+ } else if (Pair[SI].Classification == Subscript::ZIV) {
// always separable
Separable.set(SI);
}
switch (Pair[SI].Classification) {
case Subscript::ZIV:
DEBUG(dbgs() << ", ZIV\n");
- if (testZIV(Pair[SI].Src, Pair[SI].Dst, *Result))
+ if (testZIV(Pair[SI].Src, Pair[SI].Dst, Result))
return nullptr;
break;
case Subscript::SIV: {
DEBUG(dbgs() << ", SIV\n");
unsigned Level;
const SCEV *SplitIter = nullptr;
- if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, *Result, NewConstraint,
+ if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result, NewConstraint,
SplitIter))
return nullptr;
break;
}
case Subscript::RDIV:
DEBUG(dbgs() << ", RDIV\n");
- if (testRDIV(Pair[SI].Src, Pair[SI].Dst, *Result))
+ if (testRDIV(Pair[SI].Src, Pair[SI].Dst, Result))
return nullptr;
break;
case Subscript::MIV:
DEBUG(dbgs() << ", MIV\n");
- if (testMIV(Pair[SI].Src, Pair[SI].Dst, Pair[SI].Loops, *Result))
+ if (testMIV(Pair[SI].Src, Pair[SI].Dst, Pair[SI].Loops, Result))
return nullptr;
break;
default:
unsigned Level;
const SCEV *SplitIter = nullptr;
DEBUG(dbgs() << "SIV\n");
- if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, *Result, NewConstraint,
+ if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
SplitIter))
return nullptr;
ConstrainedLevels.set(Level);
// SJ is an MIV subscript that's part of the current coupled group
DEBUG(dbgs() << "\tSJ = " << SJ << "\n");
if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
- Constraints, Result->Consistent)) {
+ Constraints, Result.Consistent)) {
DEBUG(dbgs() << "\t Changed\n");
++DeltaPropagations;
Pair[SJ].Classification =
switch (Pair[SJ].Classification) {
case Subscript::ZIV:
DEBUG(dbgs() << "ZIV\n");
- if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, *Result))
+ if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
return nullptr;
Mivs.reset(SJ);
break;
for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
if (Pair[SJ].Classification == Subscript::RDIV) {
DEBUG(dbgs() << "RDIV test\n");
- if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, *Result))
+ if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
return nullptr;
// I don't yet understand how to propagate RDIV results
Mivs.reset(SJ);
for (int SJ = Mivs.find_first(); SJ >= 0; SJ = Mivs.find_next(SJ)) {
if (Pair[SJ].Classification == Subscript::MIV) {
DEBUG(dbgs() << "MIV test\n");
- if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, *Result))
+ if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
return nullptr;
}
else
llvm_unreachable("expected only MIV subscripts at this point");
}
- // update Result->DV from constraint vector
+ // update Result.DV from constraint vector
DEBUG(dbgs() << " updating\n");
- for (int SJ = ConstrainedLevels.find_first();
- SJ >= 0; SJ = ConstrainedLevels.find_next(SJ)) {
- updateDirection(Result->DV[SJ - 1], Constraints[SJ]);
- if (Result->DV[SJ - 1].Direction == Dependence::DVEntry::NONE)
+ for (int SJ = ConstrainedLevels.find_first(); SJ >= 0;
+ SJ = ConstrainedLevels.find_next(SJ)) {
+ if (SJ > (int)CommonLevels)
+ break;
+ updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
+ if (Result.DV[SJ - 1].Direction == Dependence::DVEntry::NONE)
return nullptr;
}
}
CompleteLoops |= Pair[SI].Loops;
for (unsigned II = 1; II <= CommonLevels; ++II)
if (CompleteLoops[II])
- Result->DV[II - 1].Scalar = false;
+ Result.DV[II - 1].Scalar = false;
if (PossiblyLoopIndependent) {
// Make sure the LoopIndependent flag is set correctly.
// All directions must include equal, otherwise no
// loop-independent dependence is possible.
for (unsigned II = 1; II <= CommonLevels; ++II) {
- if (!(Result->getDirection(II) & Dependence::DVEntry::EQ)) {
- Result->LoopIndependent = false;
+ if (!(Result.getDirection(II) & Dependence::DVEntry::EQ)) {
+ Result.LoopIndependent = false;
break;
}
}
// loop-independent dependence possible, then no dependence exists.
bool AllEqual = true;
for (unsigned II = 1; II <= CommonLevels; ++II) {
- if (Result->getDirection(II) != Dependence::DVEntry::EQ) {
+ if (Result.getDirection(II) != Dependence::DVEntry::EQ) {
AllEqual = false;
break;
}
return nullptr;
}
- return std::move(Result);
+ auto Final = make_unique<FullDependence>(Result);
+ Result.DV = nullptr;
+ return std::move(Final);
}
assert(isLoadOrStore(Dst));
Value *SrcPtr = getPointerOperand(Src);
Value *DstPtr = getPointerOperand(Dst);
- assert(underlyingObjectsAlias(AA, DstPtr, SrcPtr) ==
- AliasAnalysis::MustAlias);
+ assert(underlyingObjectsAlias(AA, F->getParent()->getDataLayout(), DstPtr,
+ SrcPtr) == AliasAnalysis::MustAlias);
// establish loop nesting levels
establishNestingLevels(Src, Dst);
SrcGEP->getPointerOperandType() == DstGEP->getPointerOperandType()) {
const SCEV *SrcPtrSCEV = SE->getSCEV(SrcGEP->getPointerOperand());
const SCEV *DstPtrSCEV = SE->getSCEV(DstGEP->getPointerOperand());
- UsefulGEP =
- isLoopInvariant(SrcPtrSCEV, LI->getLoopFor(Src->getParent())) &&
- isLoopInvariant(DstPtrSCEV, LI->getLoopFor(Dst->getParent()));
+ UsefulGEP = isLoopInvariant(SrcPtrSCEV, LI->getLoopFor(Src->getParent())) &&
+ isLoopInvariant(DstPtrSCEV, LI->getLoopFor(Dst->getParent())) &&
+ (SrcGEP->getNumOperands() == DstGEP->getNumOperands());
}
unsigned Pairs = UsefulGEP ? SrcGEP->idx_end() - SrcGEP->idx_begin() : 1;
SmallVector<Subscript, 4> Pair(Pairs);