Skip to content

Commit

Permalink
[ARM][NFC] Move tail predication checks
Browse files Browse the repository at this point in the history
Extract the tail predication validation checks out into their own
LowOverHeadLoop method.
  • Loading branch information
sparker-arm committed Jan 3, 2020
1 parent 3186b18 commit 8f6a676
Showing 1 changed file with 76 additions and 69 deletions.
145 changes: 76 additions & 69 deletions llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
Expand Up @@ -121,7 +121,7 @@ namespace {

// If this is an MVE instruction, check that we know how to use tail
// predication with it.
void CheckTPValidity(MachineInstr *MI) {
void AnalyseMVEInst(MachineInstr *MI) {
if (CannotTailPredicate)
return;

Expand All @@ -148,6 +148,10 @@ namespace {
!CannotTailPredicate && ML->getNumBlocks() == 1;
}

bool ValidateTailPredicate(MachineInstr *StartInsertPt,
ReachingDefAnalysis *RDA,
MachineLoopInfo *MLI);

// Is it safe to define LR with DLS/WLS?
// LR can be defined if it is the operand to start, because it's the same
// value, or if it's going to be equivalent to the operand to Start.
Expand Down Expand Up @@ -313,64 +317,17 @@ static bool IsSafeToMove(MachineInstr *From, MachineInstr *To, ReachingDefAnalys
return true;
}

void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils,
ReachingDefAnalysis *RDA,
MachineLoopInfo *MLI) {
if (Revert)
return;

if (!End->getOperand(1).isMBB())
report_fatal_error("Expected LoopEnd to target basic block");

// TODO Maybe there's cases where the target doesn't have to be the header,
// but for now be safe and revert.
if (End->getOperand(1).getMBB() != ML->getHeader()) {
LLVM_DEBUG(dbgs() << "ARM Loops: LoopEnd is not targetting header.\n");
Revert = true;
return;
}

// The WLS and LE instructions have 12-bits for the label offset. WLS
// requires a positive offset, while LE uses negative.
if (BBUtils->getOffsetOf(End) < BBUtils->getOffsetOf(ML->getHeader()) ||
!BBUtils->isBBInRange(End, ML->getHeader(), 4094)) {
LLVM_DEBUG(dbgs() << "ARM Loops: LE offset is out-of-range\n");
Revert = true;
return;
}

if (Start->getOpcode() == ARM::t2WhileLoopStart &&
(BBUtils->getOffsetOf(Start) >
BBUtils->getOffsetOf(Start->getOperand(1).getMBB()) ||
!BBUtils->isBBInRange(Start, Start->getOperand(1).getMBB(), 4094))) {
LLVM_DEBUG(dbgs() << "ARM Loops: WLS offset is out-of-range!\n");
Revert = true;
return;
}

InsertPt = Revert ? nullptr : IsSafeToDefineLR(RDA);
if (!InsertPt) {
LLVM_DEBUG(dbgs() << "ARM Loops: Unable to find safe insertion point.\n");
Revert = true;
return;
} else
LLVM_DEBUG(dbgs() << "ARM Loops: Start insertion point: " << *InsertPt);

if (!IsTailPredicationLegal()) {
LLVM_DEBUG(dbgs() << "ARM Loops: Tail-predication is not valid.\n");
return;
}

bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt,
ReachingDefAnalysis *RDA,
MachineLoopInfo *MLI) {
// All predication within the loop should be based on vctp. If the block
// isn't predicated on entry, check whether the vctp is within the block
// and that all other instructions are then predicated on it.
for (auto &Block : VPTBlocks) {
if (Block.IsPredicatedOn(VCTP))
continue;
if (!Block.HasNonUniformPredicate() || !isVCTP(Block.getDivergent()->MI)) {
CannotTailPredicate = true;
return;
}
if (!Block.HasNonUniformPredicate() || !isVCTP(Block.getDivergent()->MI))
return false;
SmallVectorImpl<PredicatedMI> &Insts = Block.getInsts();
for (auto &PredMI : Insts) {
if (PredMI.Predicates.count(VCTP) || isVCTP(PredMI.MI))
Expand All @@ -380,8 +337,7 @@ void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils,
for (auto *MI : PredMI.Predicates)
dbgs() << " - " << *MI;
);
CannotTailPredicate = true;
return;
return false;
}
}

Expand All @@ -395,8 +351,8 @@ void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils,
// TODO: Check whether this is just a mov of a register that would be
// available.
if (RDA->getReachingDef(VCTP, NumElements) >= 0) {
CannotTailPredicate = true;
return;
LLVM_DEBUG(dbgs() << "ARM Loops: VCTP operand is defined in the loop.\n");
return false;
}

// The element count register maybe defined after InsertPt, in which case we
Expand All @@ -414,10 +370,8 @@ void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils,
InsertPt->removeFromParent();
InsertBB->insertAfter(MachineBasicBlock::iterator(ElemDef), InsertPt);
LLVM_DEBUG(dbgs() << "ARM Loops: Moved start past: " << *ElemDef);
} else {
CannotTailPredicate = true;
return;
}
} else
return false;
}
}

Expand All @@ -439,20 +393,73 @@ void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils,

// First, find the block that looks like the preheader.
MachineBasicBlock *MBB = MLI->findLoopPreheader(ML, true);
if (!MBB) {
CannotTailPredicate = true;
return;
}
if (!MBB)
return false;

// Then search backwards for a def, until we get to InsertBB.
while (MBB != InsertBB) {
CannotTailPredicate = CannotProvideElements(MBB, NumElements);
if (CannotTailPredicate)
return;
if (CannotProvideElements(MBB, NumElements))
return false;
MBB = *MBB->pred_begin();
}

LLVM_DEBUG(dbgs() << "ARM Loops: Will use tail predication.\n");
return true;
}

void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils,
ReachingDefAnalysis *RDA,
MachineLoopInfo *MLI) {
if (Revert)
return;

if (!End->getOperand(1).isMBB())
report_fatal_error("Expected LoopEnd to target basic block");

// TODO Maybe there's cases where the target doesn't have to be the header,
// but for now be safe and revert.
if (End->getOperand(1).getMBB() != ML->getHeader()) {
LLVM_DEBUG(dbgs() << "ARM Loops: LoopEnd is not targetting header.\n");
Revert = true;
return;
}

// The WLS and LE instructions have 12-bits for the label offset. WLS
// requires a positive offset, while LE uses negative.
if (BBUtils->getOffsetOf(End) < BBUtils->getOffsetOf(ML->getHeader()) ||
!BBUtils->isBBInRange(End, ML->getHeader(), 4094)) {
LLVM_DEBUG(dbgs() << "ARM Loops: LE offset is out-of-range\n");
Revert = true;
return;
}

if (Start->getOpcode() == ARM::t2WhileLoopStart &&
(BBUtils->getOffsetOf(Start) >
BBUtils->getOffsetOf(Start->getOperand(1).getMBB()) ||
!BBUtils->isBBInRange(Start, Start->getOperand(1).getMBB(), 4094))) {
LLVM_DEBUG(dbgs() << "ARM Loops: WLS offset is out-of-range!\n");
Revert = true;
return;
}

InsertPt = Revert ? nullptr : IsSafeToDefineLR(RDA);
if (!InsertPt) {
LLVM_DEBUG(dbgs() << "ARM Loops: Unable to find safe insertion point.\n");
Revert = true;
return;
} else
LLVM_DEBUG(dbgs() << "ARM Loops: Start insertion point: " << *InsertPt);

if (!IsTailPredicationLegal()) {
LLVM_DEBUG(dbgs() << "ARM Loops: Tail-predication is not valid.\n");
return;
}

assert(ML->getBlocks().size() == 1 &&
"Shouldn't be processing a loop with more than one block");
CannotTailPredicate = !ValidateTailPredicate(InsertPt, RDA, MLI);
LLVM_DEBUG(if (CannotTailPredicate)
dbgs() << "ARM Loops: Couldn't validate tail predicate.\n");
}

bool LowOverheadLoop::RecordVPTBlocks(MachineInstr* MI) {
Expand Down Expand Up @@ -601,7 +608,7 @@ bool ARMLowOverheadLoops::ProcessLoop(MachineLoop *ML) {
} else {
// Record VPR defs and build up their corresponding vpt blocks.
// Check we know how to tail predicate any mve instructions.
LoLoop.CheckTPValidity(&MI);
LoLoop.AnalyseMVEInst(&MI);
}

// We need to ensure that LR is not used or defined inbetween LoopDec and
Expand Down

0 comments on commit 8f6a676

Please sign in to comment.