Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
polly/trunk/lib/Analysis/ScopDetection.cpp
Show First 20 Lines • Show All 477 Lines • ▼ Show 20 Lines | bool ScopDetection::onlyValidRequiredInvariantLoads( | ||||
for (LoadInst *Load : RequiredILS) { | for (LoadInst *Load : RequiredILS) { | ||||
// If we already know a load has been accepted as required invariant, we | // If we already know a load has been accepted as required invariant, we | ||||
// already run the validation below once and consequently don't need to | // already run the validation below once and consequently don't need to | ||||
// run it again. Hence, we return early. For certain test cases (e.g., | // run it again. Hence, we return early. For certain test cases (e.g., | ||||
// COSMO this avoids us spending 50% of scop-detection time in this | // COSMO this avoids us spending 50% of scop-detection time in this | ||||
// very function (and its children). | // very function (and its children). | ||||
if (Context.RequiredILS.count(Load)) | if (Context.RequiredILS.count(Load)) | ||||
continue; | continue; | ||||
if (!isHoistableLoad(Load, CurRegion, LI, SE, DT, Context.RequiredILS)) | |||||
if (!isHoistableLoad(Load, CurRegion, LI, SE, DT)) | |||||
return false; | return false; | ||||
for (auto NonAffineRegion : Context.NonAffineSubRegionSet) { | for (auto NonAffineRegion : Context.NonAffineSubRegionSet) { | ||||
if (isSafeToLoadUnconditionally(Load->getPointerOperand(), | if (isSafeToLoadUnconditionally(Load->getPointerOperand(), | ||||
Load->getAlignment(), DL)) | Load->getAlignment(), DL)) | ||||
continue; | continue; | ||||
if (NonAffineRegion->contains(Load) && | if (NonAffineRegion->contains(Load) && | ||||
▲ Show 20 Lines • Show All 437 Lines • ▼ Show 20 Lines | for (const SCEV *DelinearizedSize : Sizes) { | ||||
if (!isAffine(DelinearizedSize, Scope, Context)) { | if (!isAffine(DelinearizedSize, Scope, Context)) { | ||||
Sizes.clear(); | Sizes.clear(); | ||||
break; | break; | ||||
} | } | ||||
if (auto *Unknown = dyn_cast<SCEVUnknown>(DelinearizedSize)) { | if (auto *Unknown = dyn_cast<SCEVUnknown>(DelinearizedSize)) { | ||||
auto *V = dyn_cast<Value>(Unknown->getValue()); | auto *V = dyn_cast<Value>(Unknown->getValue()); | ||||
if (auto *Load = dyn_cast<LoadInst>(V)) { | if (auto *Load = dyn_cast<LoadInst>(V)) { | ||||
if (Context.CurRegion.contains(Load) && | if (Context.CurRegion.contains(Load) && | ||||
isHoistableLoad(Load, CurRegion, LI, SE, DT)) | isHoistableLoad(Load, CurRegion, LI, SE, DT, Context.RequiredILS)) | ||||
Context.RequiredILS.insert(Load); | Context.RequiredILS.insert(Load); | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
if (hasScalarDepsInsideRegion(DelinearizedSize, &CurRegion, Scope, false, | if (hasScalarDepsInsideRegion(DelinearizedSize, &CurRegion, Scope, false, | ||||
Context.RequiredILS)) | Context.RequiredILS)) | ||||
return invalid<ReportNonAffineAccess>( | return invalid<ReportNonAffineAccess>( | ||||
Context, /*Assert=*/true, DelinearizedSize, | Context, /*Assert=*/true, DelinearizedSize, | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF, | ||||
if (!AS.isMustAlias()) { | if (!AS.isMustAlias()) { | ||||
if (PollyUseRuntimeAliasChecks) { | if (PollyUseRuntimeAliasChecks) { | ||||
bool CanBuildRunTimeCheck = true; | bool CanBuildRunTimeCheck = true; | ||||
// The run-time alias check places code that involves the base pointer at | // The run-time alias check places code that involves the base pointer at | ||||
// the beginning of the SCoP. This breaks if the base pointer is defined | // the beginning of the SCoP. This breaks if the base pointer is defined | ||||
// inside the scop. Hence, we can only create a run-time check if we are | // inside the scop. Hence, we can only create a run-time check if we are | ||||
// sure the base pointer is not an instruction defined inside the scop. | // sure the base pointer is not an instruction defined inside the scop. | ||||
// However, we can ignore loads that will be hoisted. | // However, we can ignore loads that will be hoisted. | ||||
InvariantLoadsSetTy VariantLS, InvariantLS; | |||||
// In order to detect loads which are dependent on other invariant loads | |||||
// as invariant, we use fixed-point iteration method here i.e we iterate | |||||
// over the alias set for arbitrary number of times until it is safe to | |||||
// assume that all the invariant loads have been detected | |||||
while (1) { | |||||
const unsigned int VariantSize = VariantLS.size(), | |||||
InvariantSize = InvariantLS.size(); | |||||
for (const auto &Ptr : AS) { | for (const auto &Ptr : AS) { | ||||
Instruction *Inst = dyn_cast<Instruction>(Ptr.getValue()); | Instruction *Inst = dyn_cast<Instruction>(Ptr.getValue()); | ||||
if (Inst && Context.CurRegion.contains(Inst)) { | if (Inst && Context.CurRegion.contains(Inst)) { | ||||
auto *Load = dyn_cast<LoadInst>(Inst); | auto *Load = dyn_cast<LoadInst>(Inst); | ||||
if (Load && isHoistableLoad(Load, Context.CurRegion, LI, SE, DT)) { | if (Load && InvariantLS.count(Load)) | ||||
Context.RequiredILS.insert(Load); | |||||
continue; | continue; | ||||
if (Load && isHoistableLoad(Load, Context.CurRegion, LI, SE, DT, | |||||
InvariantLS)) { | |||||
if (VariantLS.count(Load)) | |||||
VariantLS.remove(Load); | |||||
Context.RequiredILS.insert(Load); | |||||
InvariantLS.insert(Load); | |||||
} else { | |||||
CanBuildRunTimeCheck = false; | |||||
VariantLS.insert(Load); | |||||
} | |||||
} | |||||
} | } | ||||
CanBuildRunTimeCheck = false; | if (InvariantSize == InvariantLS.size() && | ||||
VariantSize == VariantLS.size()) | |||||
break; | break; | ||||
} | } | ||||
} | |||||
if (CanBuildRunTimeCheck) | if (CanBuildRunTimeCheck) | ||||
return true; | return true; | ||||
} | } | ||||
return invalid<ReportAlias>(Context, /*Assert=*/true, Inst, AS); | return invalid<ReportAlias>(Context, /*Assert=*/true, Inst, AS); | ||||
} | } | ||||
return true; | return true; | ||||
▲ Show 20 Lines • Show All 755 Lines • Show Last 20 Lines |