Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
Show First 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | void VPlanVerifier::verifyHierarchicalCFG( | ||||
if (!EnableHCFGVerifier) | if (!EnableHCFGVerifier) | ||||
return; | return; | ||||
LLVM_DEBUG(dbgs() << "Verifying VPlan H-CFG.\n"); | LLVM_DEBUG(dbgs() << "Verifying VPlan H-CFG.\n"); | ||||
assert(!TopRegion->getParent() && "VPlan Top Region should have no parent."); | assert(!TopRegion->getParent() && "VPlan Top Region should have no parent."); | ||||
verifyRegionRec(TopRegion); | verifyRegionRec(TopRegion); | ||||
} | } | ||||
static bool | // Verify that phi-like recipes are at the beginning of \p VPBB, with no | ||||
verifyVPBasicBlock(const VPBasicBlock *VPBB, | // other recipes in between. Also check that only header blocks contain | ||||
DenseMap<const VPBlockBase *, unsigned> &BlockNumbering) { | // VPHeaderPHIRecipes. | ||||
// Verify that phi-like recipes are at the beginning of the block, with no | static bool verifyPhiRecipes(const VPBasicBlock *VPBB) { | ||||
Ayal: Perhaps worth outlining the first part that verifies phi recipes, breaking the somewhat long… | |||||
Done! fhahn: Done! | |||||
// other recipes in between. | |||||
auto RecipeI = VPBB->begin(); | auto RecipeI = VPBB->begin(); | ||||
auto End = VPBB->end(); | auto End = VPBB->end(); | ||||
unsigned NumActiveLaneMaskPhiRecipes = 0; | unsigned NumActiveLaneMaskPhiRecipes = 0; | ||||
const VPRegionBlock *ParentR = VPBB->getParent(); | |||||
bool IsHeaderVPBB = ParentR && !ParentR->isReplicator() && | |||||
ParentR->getEntryBasicBlock() == VPBB; | |||||
while (RecipeI != End && RecipeI->isPhi()) { | while (RecipeI != End && RecipeI->isPhi()) { | ||||
if (isa<VPActiveLaneMaskPHIRecipe>(RecipeI)) | if (isa<VPActiveLaneMaskPHIRecipe>(RecipeI)) | ||||
NumActiveLaneMaskPhiRecipes++; | NumActiveLaneMaskPhiRecipes++; | ||||
if (IsHeaderVPBB && !isa<VPHeaderPHIRecipe>(*RecipeI)) { | |||||
errs() << "Found non-header PHI recipe in header VPBB"; | |||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |||||
errs() << ": "; | |||||
RecipeI->dump(); | |||||
#endif | |||||
return false; | |||||
} | |||||
if (!IsHeaderVPBB && isa<VPHeaderPHIRecipe>(*RecipeI)) { | |||||
errs() << "Found header PHI recipe in non-header VPBB"; | |||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |||||
errs() << ": "; | |||||
RecipeI->dump(); | |||||
#endif | |||||
return false; | |||||
} | |||||
RecipeI++; | RecipeI++; | ||||
} | } | ||||
if (NumActiveLaneMaskPhiRecipes > 1) { | if (NumActiveLaneMaskPhiRecipes > 1) { | ||||
errs() << "There should be no more than one VPActiveLaneMaskPHIRecipe"; | errs() << "There should be no more than one VPActiveLaneMaskPHIRecipe"; | ||||
return false; | return false; | ||||
} | } | ||||
while (RecipeI != End) { | while (RecipeI != End) { | ||||
if (RecipeI->isPhi() && !isa<VPBlendRecipe>(&*RecipeI)) { | if (RecipeI->isPhi() && !isa<VPBlendRecipe>(&*RecipeI)) { | ||||
errs() << "Found phi-like recipe after non-phi recipe"; | errs() << "Found phi-like recipe after non-phi recipe"; | ||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||||
errs() << ": "; | errs() << ": "; | ||||
RecipeI->dump(); | RecipeI->dump(); | ||||
errs() << "after\n"; | errs() << "after\n"; | ||||
std::prev(RecipeI)->dump(); | std::prev(RecipeI)->dump(); | ||||
#endif | #endif | ||||
return false; | return false; | ||||
} | } | ||||
RecipeI++; | RecipeI++; | ||||
} | } | ||||
return true; | |||||
} | |||||
static bool | |||||
verifyVPBasicBlock(const VPBasicBlock *VPBB, | |||||
DenseMap<const VPBlockBase *, unsigned> &BlockNumbering) { | |||||
if (!verifyPhiRecipes(VPBB)) | |||||
return false; | |||||
// Verify that defs in VPBB dominate all their uses. The current | // Verify that defs in VPBB dominate all their uses. The current | ||||
// implementation is still incomplete. | // implementation is still incomplete. | ||||
DenseMap<const VPRecipeBase *, unsigned> RecipeNumbering; | DenseMap<const VPRecipeBase *, unsigned> RecipeNumbering; | ||||
unsigned Cnt = 0; | unsigned Cnt = 0; | ||||
for (const VPRecipeBase &R : *VPBB) | for (const VPRecipeBase &R : *VPBB) | ||||
RecipeNumbering[&R] = Cnt++; | RecipeNumbering[&R] = Cnt++; | ||||
▲ Show 20 Lines • Show All 116 Lines • Show Last 20 Lines |
Perhaps worth outlining the first part that verifies phi recipes, breaking the somewhat long method into two?