From 8f6a67632a70b757e59067646226bcaacd9c5bd7 Mon Sep 17 00:00:00 2001 From: Sam Parker Date: Fri, 3 Jan 2020 03:48:33 -0500 Subject: [PATCH] [ARM][NFC] Move tail predication checks Extract the tail predication validation checks out into their own LowOverHeadLoop method. --- llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 145 +++++++++++++++------------- 1 file changed, 76 insertions(+), 69 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp index 90bed32..136f7d7 100644 --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -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; @@ -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. @@ -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 &Insts = Block.getInsts(); for (auto &PredMI : Insts) { if (PredMI.Predicates.count(VCTP) || isVCTP(PredMI.MI)) @@ -380,8 +337,7 @@ void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils, for (auto *MI : PredMI.Predicates) dbgs() << " - " << *MI; ); - CannotTailPredicate = true; - return; + return false; } } @@ -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 @@ -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; } } @@ -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) { @@ -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 -- 2.7.4