[llvm-branch-commits] [llvm] [VPlan][Predicator] Preserve some uniform control flow (PR #217485)
Ashutosh Nema via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Sep 7 04:24:30 PDT 2026
================
@@ -478,30 +609,190 @@ void VPPredicator::run() {
// Mask all VPInstructions in the block.
for (VPRecipeBase &R : *VPBB) {
if (auto *VPI = dyn_cast<VPInstruction>(&R))
- VPI->addMask(BlockMask);
+ if (VPI->getOpcode() != VPInstruction::BranchOnCond)
+ VPI->addMask(BlockMask);
}
}
- for (VPBlockBase *VPBB : reverse(BlocksInCompactRPOTOrder))
- if (VPBB != Header)
- convertPhisToBlends(cast<VPBasicBlock>(VPBB));
+ // Cache blend terms before linearization. Computing them requires the
+ // original phi predecessor mappings and CFG successor relation, both of
+ // which are rewritten below. Skip the header which is the first block.
+ for (auto [BlockIdx, VPBB] : drop_begin(enumerate(
+ VPBlockUtils::blocksOnly<VPBasicBlock>(BlocksInCompactRPOTOrder)))) {
+ auto &Terms = BlendTerms[BlockIdx];
+ for (VPRecipeBase &R : VPBB->phis()) {
+ auto *Phi = cast<VPPhi>(&R);
+ Terms[Phi] = computeBlendTerms(Phi);
+ LLVM_DEBUG({
+ dbgs() << "Computed blend terms for ";
+ Phi->dump();
+ dbgs() << "\n";
+ for (BlendTermTy &Term : Terms[Phi]) {
+ dbgs() << " " << Term.second->getName() << ": ";
+ Term.first->dump();
+ }
+ });
+ }
+ }
+
+ // The following implements "Partial Control-Flow Linearization" by Simon Moll
+ // and Sebastian Hack.
+
+ using DeferredSuccessorsTy = SmallPtrSet<VPBlockBase *, 4>;
+ DenseMap<VPBlockBase *, DeferredSuccessorsTy> DeferredMap;
+ auto PopDeferred = [&](VPBlockBase *VPBB) -> DeferredSuccessorsTy {
+ auto It = DeferredMap.find(VPBB);
+ if (It != DeferredMap.end()) {
+ DeferredSuccessorsTy Res = std::move(It->second);
+ DeferredMap.erase(It);
+ return Res;
+ }
+ return {};
+ };
- // Linearize the blocks of the loop into one serial chain.
- VPBlockBase *PrevVPBB = nullptr;
for (VPBasicBlock *VPBB :
VPBlockUtils::blocksOnly<VPBasicBlock>(BlocksInCompactRPOTOrder)) {
+ LLVM_DEBUG(dbgs() << "Setting successors for " << VPBB->getName() << "\n");
auto Successors = to_vector(VPBB->getSuccessors());
- if (Successors.size() > 1)
- VPBB->getTerminator()->eraseFromParent();
- // Flatten the CFG in the loop. To do so, first disconnect VPBB from its
- // successors. Then connect VPBB to the previously visited VPBB.
- for (auto *Succ : Successors)
- VPBlockUtils::disconnectBlocks(VPBB, Succ);
- if (PrevVPBB)
- VPBlockUtils::connectBlocks(PrevVPBB, VPBB);
+ if (shouldPreserveTerminator(VPBB)) {
----------------
nema-ashutosh wrote:
It keeps the uniform br but never drops then/else masks ?
due to this mask loads appears for following case:
for (unsigned i = 0; i < len; i++)
if (flag) A[i] = B[i] + C[i];
else X[i] = Y[i] * Z[i];
https://github.com/llvm/llvm-project/pull/217485
More information about the llvm-branch-commits
mailing list