-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[VPlan] Model middle block via VPIRBasicBlock. #95816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -448,13 +448,29 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) { | |
} | ||
|
||
void VPIRBasicBlock::execute(VPTransformState *State) { | ||
assert(getHierarchicalPredecessors().empty() && | ||
"VPIRBasicBlock cannot have predecessors at the moment"); | ||
assert(getHierarchicalSuccessors().empty() && | ||
"VPIRBasicBlock cannot have successors at the moment"); | ||
|
||
State->Builder.SetInsertPoint(getIRBasicBlock()->getTerminator()); | ||
executeRecipes(State, getIRBasicBlock()); | ||
|
||
for (VPBlockBase *PredVPBlock : getHierarchicalPredecessors()) { | ||
VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock(); | ||
BasicBlock *PredBB = State->CFG.VPBB2IRBB[PredVPBB]; | ||
assert(PredBB && "Predecessor basic-block not found building successor."); | ||
LLVM_DEBUG(dbgs() << "LV: draw edge from" << PredBB->getName() << '\n'); | ||
|
||
auto *PredBBTerminator = PredBB->getTerminator(); | ||
auto *TermBr = cast<BranchInst>(PredBBTerminator); | ||
// Set each forward successor here when it is created, excluding | ||
// backedges. A backward successor is set when the branch is created. | ||
const auto &PredVPSuccessors = PredVPBB->getHierarchicalSuccessors(); | ||
unsigned idx = PredVPSuccessors.front() == this ? 0 : 1; | ||
assert(!TermBr->getSuccessor(idx) && | ||
"Trying to reset an existing successor block."); | ||
TermBr->setSuccessor(idx, IRBB); | ||
State->CFG.DTU.applyUpdates({{DominatorTree::Insert, PredBB, IRBB}}); | ||
} | ||
} | ||
|
||
void VPBasicBlock::execute(VPTransformState *State) { | ||
|
@@ -468,30 +484,14 @@ void VPBasicBlock::execute(VPTransformState *State) { | |
return R && !R->isReplicator(); | ||
}; | ||
|
||
// 1. Create an IR basic block, or reuse the last one or ExitBB if possible. | ||
if (getPlan()->getVectorLoopRegion()->getSingleSuccessor() == this) { | ||
// ExitBB can be re-used for the exit block of the Plan. | ||
NewBB = State->CFG.ExitBB; | ||
State->CFG.PrevBB = NewBB; | ||
State->Builder.SetInsertPoint(NewBB->getFirstNonPHI()); | ||
|
||
// Update the branch instruction in the predecessor to branch to ExitBB. | ||
VPBlockBase *PredVPB = getSingleHierarchicalPredecessor(); | ||
VPBasicBlock *ExitingVPBB = PredVPB->getExitingBasicBlock(); | ||
assert(PredVPB->getSingleSuccessor() == this && | ||
"predecessor must have the current block as only successor"); | ||
BasicBlock *ExitingBB = State->CFG.VPBB2IRBB[ExitingVPBB]; | ||
// The Exit block of a loop is always set to be successor 0 of the Exiting | ||
// block. | ||
cast<BranchInst>(ExitingBB->getTerminator())->setSuccessor(0, NewBB); | ||
State->CFG.DTU.applyUpdates({{DominatorTree::Insert, ExitingBB, NewBB}}); | ||
} else if (PrevVPBB && /* A */ | ||
!((SingleHPred = getSingleHierarchicalPredecessor()) && | ||
SingleHPred->getExitingBasicBlock() == PrevVPBB && | ||
PrevVPBB->getSingleHierarchicalSuccessor() && | ||
(SingleHPred->getParent() == getEnclosingLoopRegion() && | ||
!IsLoopRegion(SingleHPred))) && /* B */ | ||
!(Replica && getPredecessors().empty())) { /* C */ | ||
// 1. Create an IR basic block. | ||
if (PrevVPBB && /* A */ | ||
!((SingleHPred = getSingleHierarchicalPredecessor()) && | ||
SingleHPred->getExitingBasicBlock() == PrevVPBB && | ||
PrevVPBB->getSingleHierarchicalSuccessor() && | ||
(SingleHPred->getParent() == getEnclosingLoopRegion() && | ||
!IsLoopRegion(SingleHPred))) && /* B */ | ||
!(Replica && getPredecessors().empty())) { /* C */ | ||
// The last IR basic block is reused, as an optimization, in three cases: | ||
// A. the first VPBB reuses the loop pre-header BB - when PrevVPBB is null; | ||
// B. when the current VPBB has a single (hierarchical) predecessor which | ||
|
@@ -842,6 +842,19 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV, | |
} | ||
} | ||
|
||
/// Replace \p VPBB with a VPIRBasicBlock wrapping \p IRBB. All recipes from \p | ||
/// VPBB are moved to the newly created VPIRBasicBlock. | ||
static void replaceVPBBWithIRVPBB(VPBasicBlock *VPBB, BasicBlock *IRBB) { | ||
assert(VPBB->getNumSuccessors() == 0 && "VPBB must be a leave node"); | ||
VPIRBasicBlock *IRMiddleVPBB = new VPIRBasicBlock(IRBB); | ||
for (auto &R : make_early_inc_range(*VPBB)) | ||
R.moveBefore(*IRMiddleVPBB, IRMiddleVPBB->end()); | ||
VPBlockBase *PredVPBB = VPBB->getSinglePredecessor(); | ||
VPBlockUtils::disconnectBlocks(PredVPBB, VPBB); | ||
VPBlockUtils::connectBlocks(PredVPBB, IRMiddleVPBB); | ||
delete VPBB; | ||
} | ||
|
||
/// Generate the code inside the preheader and body of the vectorized loop. | ||
/// Assumes a single pre-header basic-block was created for this. Introduce | ||
/// additional basic-blocks as needed, and fill them all. | ||
|
@@ -851,6 +864,9 @@ void VPlan::execute(VPTransformState *State) { | |
State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor(); | ||
BasicBlock *VectorPreHeader = State->CFG.PrevBB; | ||
State->Builder.SetInsertPoint(VectorPreHeader->getTerminator()); | ||
replaceVPBBWithIRVPBB( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another option may be to place this in prepareToExecute(), as its finalizing VPlan before actually generating code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Left at the current position as it re-uses |
||
cast<VPBasicBlock>(getVectorLoopRegion()->getSingleSuccessor()), | ||
State->CFG.ExitBB); | ||
|
||
// Disconnect VectorPreHeader from ExitBB in both the CFG and DT. | ||
cast<BranchInst>(VectorPreHeader->getTerminator())->setSuccessor(0, nullptr); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VPBB must have a single predecessor, and no successor - expecting IRBB to be at the End of VPlan's scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now yes , added an assert for successors; the next patch will relax this further.