Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
35234 views
//===- DeadMachineInstructionElim.cpp - Remove dead machine instructions --===//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 is an extremely simple MachineInstr-level dead-code-elimination pass.9//10//===----------------------------------------------------------------------===//1112#include "llvm/CodeGen/DeadMachineInstructionElim.h"13#include "llvm/ADT/PostOrderIterator.h"14#include "llvm/ADT/Statistic.h"15#include "llvm/CodeGen/LiveRegUnits.h"16#include "llvm/CodeGen/MachineFunctionPass.h"17#include "llvm/CodeGen/MachineRegisterInfo.h"18#include "llvm/CodeGen/TargetSubtargetInfo.h"19#include "llvm/InitializePasses.h"20#include "llvm/Pass.h"21#include "llvm/Support/Debug.h"22#include "llvm/Support/raw_ostream.h"2324using namespace llvm;2526#define DEBUG_TYPE "dead-mi-elimination"2728STATISTIC(NumDeletes, "Number of dead instructions deleted");2930namespace {31class DeadMachineInstructionElimImpl {32const MachineRegisterInfo *MRI = nullptr;33const TargetInstrInfo *TII = nullptr;34LiveRegUnits LivePhysRegs;3536public:37bool runImpl(MachineFunction &MF);3839private:40bool isDead(const MachineInstr *MI) const;41bool eliminateDeadMI(MachineFunction &MF);42};4344class DeadMachineInstructionElim : public MachineFunctionPass {45public:46static char ID; // Pass identification, replacement for typeid4748DeadMachineInstructionElim() : MachineFunctionPass(ID) {49initializeDeadMachineInstructionElimPass(*PassRegistry::getPassRegistry());50}5152bool runOnMachineFunction(MachineFunction &MF) override {53if (skipFunction(MF.getFunction()))54return false;55return DeadMachineInstructionElimImpl().runImpl(MF);56}5758void getAnalysisUsage(AnalysisUsage &AU) const override {59AU.setPreservesCFG();60MachineFunctionPass::getAnalysisUsage(AU);61}62};63} // namespace6465PreservedAnalyses66DeadMachineInstructionElimPass::run(MachineFunction &MF,67MachineFunctionAnalysisManager &) {68if (!DeadMachineInstructionElimImpl().runImpl(MF))69return PreservedAnalyses::all();70PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();71PA.preserveSet<CFGAnalyses>();72return PA;73}7475char DeadMachineInstructionElim::ID = 0;76char &llvm::DeadMachineInstructionElimID = DeadMachineInstructionElim::ID;7778INITIALIZE_PASS(DeadMachineInstructionElim, DEBUG_TYPE,79"Remove dead machine instructions", false, false)8081bool DeadMachineInstructionElimImpl::isDead(const MachineInstr *MI) const {82// Technically speaking inline asm without side effects and no defs can still83// be deleted. But there is so much bad inline asm code out there, we should84// let them be.85if (MI->isInlineAsm())86return false;8788// Don't delete frame allocation labels.89if (MI->getOpcode() == TargetOpcode::LOCAL_ESCAPE)90return false;9192// Don't delete instructions with side effects.93bool SawStore = false;94if (!MI->isSafeToMove(nullptr, SawStore) && !MI->isPHI())95return false;9697// Examine each operand.98for (const MachineOperand &MO : MI->all_defs()) {99Register Reg = MO.getReg();100if (Reg.isPhysical()) {101// Don't delete live physreg defs, or any reserved register defs.102if (!LivePhysRegs.available(Reg) || MRI->isReserved(Reg))103return false;104} else {105if (MO.isDead()) {106#ifndef NDEBUG107// Basic check on the register. All of them should be 'undef'.108for (auto &U : MRI->use_nodbg_operands(Reg))109assert(U.isUndef() && "'Undef' use on a 'dead' register is found!");110#endif111continue;112}113for (const MachineInstr &Use : MRI->use_nodbg_instructions(Reg)) {114if (&Use != MI)115// This def has a non-debug use. Don't delete the instruction!116return false;117}118}119}120121// If there are no defs with uses, the instruction is dead.122return true;123}124125bool DeadMachineInstructionElimImpl::runImpl(MachineFunction &MF) {126MRI = &MF.getRegInfo();127128const TargetSubtargetInfo &ST = MF.getSubtarget();129TII = ST.getInstrInfo();130LivePhysRegs.init(*ST.getRegisterInfo());131132bool AnyChanges = eliminateDeadMI(MF);133while (AnyChanges && eliminateDeadMI(MF))134;135return AnyChanges;136}137138bool DeadMachineInstructionElimImpl::eliminateDeadMI(MachineFunction &MF) {139bool AnyChanges = false;140141// Loop over all instructions in all blocks, from bottom to top, so that it's142// more likely that chains of dependent but ultimately dead instructions will143// be cleaned up.144for (MachineBasicBlock *MBB : post_order(&MF)) {145LivePhysRegs.addLiveOuts(*MBB);146147// Now scan the instructions and delete dead ones, tracking physreg148// liveness as we go.149for (MachineInstr &MI : make_early_inc_range(reverse(*MBB))) {150// If the instruction is dead, delete it!151if (isDead(&MI)) {152LLVM_DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << MI);153// It is possible that some DBG_VALUE instructions refer to this154// instruction. They will be deleted in the live debug variable155// analysis.156MI.eraseFromParent();157AnyChanges = true;158++NumDeletes;159continue;160}161162LivePhysRegs.stepBackward(MI);163}164}165166LivePhysRegs.clear();167return AnyChanges;168}169170171