brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · bf7f4fc Raw
158 lines · cpp
1//===- ReduceInstructionsMIR.cpp - Specialized Delta Pass -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements a function which calls the Generic Delta pass in order10// to reduce uninteresting MachineInstr from the MachineFunction.11//12//===----------------------------------------------------------------------===//13 14#include "ReduceInstructionsMIR.h"15#include "llvm/ADT/SetVector.h"16#include "llvm/CodeGen/MachineDominators.h"17#include "llvm/CodeGen/MachineFunction.h"18#include "llvm/CodeGen/MachineModuleInfo.h"19#include "llvm/CodeGen/MachineRegisterInfo.h"20#include "llvm/CodeGen/TargetInstrInfo.h"21 22using namespace llvm;23 24static Register getPrevDefOfRCInMBB(MachineBasicBlock &MBB,25                                    MachineBasicBlock::reverse_iterator &RI,26                                    const RegClassOrRegBank &RC, LLT Ty,27                                    SetVector<MachineInstr *> &ExcludeMIs) {28  auto MRI = &MBB.getParent()->getRegInfo();29  for (MachineBasicBlock::reverse_instr_iterator E = MBB.instr_rend(); RI != E;30       ++RI) {31    auto &MI = *RI;32    // All Def operands explicit and implicit.33    for (auto &MO : MI.operands()) {34      if (!MO.isReg() || !MO.isDef() || MO.isDead())35        continue;36      auto Reg = MO.getReg();37      if (Reg.isPhysical())38        continue;39 40      if (MRI->getRegClassOrRegBank(Reg) == RC && MRI->getType(Reg) == Ty &&41          !ExcludeMIs.count(MO.getParent()))42        return Reg;43    }44  }45  return 0;46}47 48static bool shouldNotRemoveInstruction(const TargetInstrInfo &TII,49                                       const MachineInstr &MI) {50  if (MI.isTerminator())51    return true;52 53  // The MIR is almost certainly going to be invalid if frame instructions are54  // deleted individually since they need to come in balanced pairs, so don't55  // try to delete them.56  if (MI.getOpcode() == TII.getCallFrameSetupOpcode() ||57      MI.getOpcode() == TII.getCallFrameDestroyOpcode())58    return true;59 60  return false;61}62 63static void extractInstrFromFunction(Oracle &O, MachineFunction &MF) {64  MachineDominatorTree MDT;65  MDT.recalculate(MF);66 67  auto MRI = &MF.getRegInfo();68  SetVector<MachineInstr *> ToDelete;69 70  const TargetSubtargetInfo &STI = MF.getSubtarget();71  const TargetInstrInfo *TII = STI.getInstrInfo();72  MachineBasicBlock *EntryMBB = &*MF.begin();73  MachineBasicBlock::iterator EntryInsPt =74      EntryMBB->SkipPHIsLabelsAndDebug(EntryMBB->begin());75 76  // Mark MIs for deletion according to some criteria.77  for (auto &MBB : MF) {78    for (auto &MI : MBB) {79      if (shouldNotRemoveInstruction(*TII, MI))80        continue;81      if (!O.shouldKeep())82        ToDelete.insert(&MI);83    }84  }85 86  // For each MI to be deleted update users of regs defined by that MI to use87  // some other dominating definition (that is not to be deleted).88  for (auto *MI : ToDelete) {89    for (auto &MO : MI->operands()) {90      if (!MO.isReg() || !MO.isDef() || MO.isDead())91        continue;92      auto Reg = MO.getReg();93      if (Reg.isPhysical())94        continue;95      auto UI = MRI->use_begin(Reg);96      auto UE = MRI->use_end();97 98      const auto &RegRC = MRI->getRegClassOrRegBank(Reg);99      LLT RegTy = MRI->getType(Reg);100 101      Register NewReg = 0;102      // If this is not a physical register and there are some uses.103      if (UI != UE) {104        MachineBasicBlock::reverse_iterator RI(*MI);105        MachineBasicBlock *BB = MI->getParent();106        ++RI;107 108        if (MDT.isReachableFromEntry(BB)) {109          while (NewReg == 0 && BB) {110            NewReg = getPrevDefOfRCInMBB(*BB, RI, RegRC, RegTy, ToDelete);111            // Prepare for idom(BB).112            if (auto *IDM = MDT.getNode(BB)->getIDom()) {113              BB = IDM->getBlock();114              RI = BB->rbegin();115            } else {116              BB = nullptr;117            }118          }119        }120      }121 122      // If no dominating definition was found then add an implicit def to the123      // top of the entry block.124      if (!NewReg) {125        NewReg = MRI->cloneVirtualRegister(Reg);126        bool IsGeneric = MRI->getRegClassOrNull(Reg) == nullptr;127        unsigned ImpDef = IsGeneric ? TargetOpcode::G_IMPLICIT_DEF128                                    : TargetOpcode::IMPLICIT_DEF;129 130        unsigned State = getRegState(MO);131        if (MO.getSubReg())132          State |= RegState::Undef;133 134        BuildMI(*EntryMBB, EntryInsPt, DebugLoc(), TII->get(ImpDef))135          .addReg(NewReg, State, MO.getSubReg());136      }137 138      // Update all uses.139      while (UI != UE) {140        auto &UMO = *UI++;141        UMO.setReg(NewReg);142      }143    }144  }145 146  // Finally delete the MIs.147  for (auto *MI : ToDelete)148    MI->eraseFromParent();149}150 151void llvm::reduceInstructionsMIRDeltaPass(Oracle &O,152                                          ReducerWorkItem &WorkItem) {153  for (const Function &F : WorkItem.getModule()) {154    if (MachineFunction *MF = WorkItem.MMI->getMachineFunction(F))155      extractInstrFromFunction(O, *MF);156  }157}158