Path: blob/main/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCCTRLoopsVerify.cpp
35269 views
//===-- PPCCTRLoops.cpp - Verify CTR loops -----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This pass verifies that all bdnz/bdz instructions are dominated by a loop9// mtctr before any other instructions that might clobber the ctr register.10//11//===----------------------------------------------------------------------===//1213// CTR loops are produced by the HardwareLoops pass and this pass is simply a14// verification that no invalid CTR loops are produced. As such, it isn't15// something that needs to be run (or even defined) for Release builds so the16// entire file is guarded by NDEBUG.17#ifndef NDEBUG18#include "MCTargetDesc/PPCMCTargetDesc.h"19#include "PPC.h"20#include "llvm/ADT/SmallSet.h"21#include "llvm/ADT/SmallVector.h"22#include "llvm/ADT/StringRef.h"23#include "llvm/ADT/ilist_iterator.h"24#include "llvm/CodeGen/MachineBasicBlock.h"25#include "llvm/CodeGen/MachineDominators.h"26#include "llvm/CodeGen/MachineFunction.h"27#include "llvm/CodeGen/MachineFunctionPass.h"28#include "llvm/CodeGen/MachineInstr.h"29#include "llvm/CodeGen/MachineInstrBundleIterator.h"30#include "llvm/CodeGen/MachineOperand.h"31#include "llvm/CodeGen/Register.h"32#include "llvm/InitializePasses.h"33#include "llvm/Pass.h"34#include "llvm/PassRegistry.h"35#include "llvm/Support/CodeGen.h"36#include "llvm/Support/Debug.h"37#include "llvm/Support/ErrorHandling.h"38#include "llvm/Support/GenericDomTreeConstruction.h"39#include "llvm/Support/Printable.h"40#include "llvm/Support/raw_ostream.h"4142using namespace llvm;4344#define DEBUG_TYPE "ppc-ctrloops-verify"4546namespace {4748struct PPCCTRLoopsVerify : public MachineFunctionPass {49public:50static char ID;5152PPCCTRLoopsVerify() : MachineFunctionPass(ID) {53initializePPCCTRLoopsVerifyPass(*PassRegistry::getPassRegistry());54}5556void getAnalysisUsage(AnalysisUsage &AU) const override {57AU.addRequired<MachineDominatorTreeWrapperPass>();58MachineFunctionPass::getAnalysisUsage(AU);59}6061bool runOnMachineFunction(MachineFunction &MF) override;6263private:64MachineDominatorTree *MDT;65};6667char PPCCTRLoopsVerify::ID = 0;68} // end anonymous namespace6970INITIALIZE_PASS_BEGIN(PPCCTRLoopsVerify, "ppc-ctr-loops-verify",71"PowerPC CTR Loops Verify", false, false)72INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)73INITIALIZE_PASS_END(PPCCTRLoopsVerify, "ppc-ctr-loops-verify",74"PowerPC CTR Loops Verify", false, false)7576FunctionPass *llvm::createPPCCTRLoopsVerify() {77return new PPCCTRLoopsVerify();78}7980static bool clobbersCTR(const MachineInstr &MI) {81for (const MachineOperand &MO : MI.operands()) {82if (MO.isReg()) {83if (MO.isDef() && (MO.getReg() == PPC::CTR || MO.getReg() == PPC::CTR8))84return true;85} else if (MO.isRegMask()) {86if (MO.clobbersPhysReg(PPC::CTR) || MO.clobbersPhysReg(PPC::CTR8))87return true;88}89}9091return false;92}9394static bool verifyCTRBranch(MachineBasicBlock *MBB,95MachineBasicBlock::iterator I) {96MachineBasicBlock::iterator BI = I;97SmallSet<MachineBasicBlock *, 16> Visited;98SmallVector<MachineBasicBlock *, 8> Preds;99bool CheckPreds;100101if (I == MBB->begin()) {102Visited.insert(MBB);103goto queue_preds;104} else105--I;106107check_block:108Visited.insert(MBB);109if (I == MBB->end())110goto queue_preds;111112CheckPreds = true;113for (MachineBasicBlock::iterator IE = MBB->begin();; --I) {114unsigned Opc = I->getOpcode();115if (Opc == PPC::MTCTRloop || Opc == PPC::MTCTR8loop) {116CheckPreds = false;117break;118}119120if (I != BI && clobbersCTR(*I)) {121LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " (" << MBB->getFullName()122<< ") instruction " << *I123<< " clobbers CTR, invalidating "124<< printMBBReference(*BI->getParent()) << " ("125<< BI->getParent()->getFullName() << ") instruction "126<< *BI << "\n");127return false;128}129130if (I == IE)131break;132}133134if (!CheckPreds && Preds.empty())135return true;136137if (CheckPreds) {138queue_preds:139if (MachineFunction::iterator(MBB) == MBB->getParent()->begin()) {140LLVM_DEBUG(dbgs() << "Unable to find a MTCTR instruction for "141<< printMBBReference(*BI->getParent()) << " ("142<< BI->getParent()->getFullName() << ") instruction "143<< *BI << "\n");144return false;145}146147append_range(Preds, MBB->predecessors());148}149150do {151MBB = Preds.pop_back_val();152if (!Visited.count(MBB)) {153I = MBB->getLastNonDebugInstr();154goto check_block;155}156} while (!Preds.empty());157158return true;159}160161bool PPCCTRLoopsVerify::runOnMachineFunction(MachineFunction &MF) {162MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();163164// Verify that all bdnz/bdz instructions are dominated by a loop mtctr before165// any other instructions that might clobber the ctr register.166for (MachineBasicBlock &MBB : MF) {167if (!MDT->isReachableFromEntry(&MBB))168continue;169170for (MachineBasicBlock::iterator MII = MBB.getFirstTerminator(),171MIIE = MBB.end(); MII != MIIE; ++MII) {172unsigned Opc = MII->getOpcode();173if (Opc == PPC::BDNZ8 || Opc == PPC::BDNZ ||174Opc == PPC::BDZ8 || Opc == PPC::BDZ)175if (!verifyCTRBranch(&MBB, MII))176llvm_unreachable("Invalid PPC CTR loop!");177}178}179180return false;181}182#endif // NDEBUG183184185