LCOV - code coverage report
Current view: top level - lib/CodeGen/GlobalISel - Localizer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 39 100.0 %
Date: 2018-10-20 13:21:21 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- Localizer.cpp ---------------------- Localize some instrs -*- C++ -*-==//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : /// \file
      10             : /// This file implements the Localizer class.
      11             : //===----------------------------------------------------------------------===//
      12             : 
      13             : #include "llvm/CodeGen/GlobalISel/Localizer.h"
      14             : #include "llvm/ADT/DenseMap.h"
      15             : #include "llvm/ADT/SmallPtrSet.h"
      16             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      17             : #include "llvm/Support/Debug.h"
      18             : 
      19             : #define DEBUG_TYPE "localizer"
      20             : 
      21             : using namespace llvm;
      22             : 
      23             : char Localizer::ID = 0;
      24      655328 : INITIALIZE_PASS(Localizer, DEBUG_TYPE,
      25             :                 "Move/duplicate certain instructions close to their use", false,
      26             :                 false)
      27             : 
      28          50 : Localizer::Localizer() : MachineFunctionPass(ID) {
      29          50 :   initializeLocalizerPass(*PassRegistry::getPassRegistry());
      30          50 : }
      31             : 
      32          56 : void Localizer::init(MachineFunction &MF) { MRI = &MF.getRegInfo(); }
      33             : 
      34         640 : bool Localizer::shouldLocalize(const MachineInstr &MI) {
      35         640 :   switch (MI.getOpcode()) {
      36             :   default:
      37             :     return false;
      38             :   // Constants-like instructions should be close to their users.
      39             :   // We don't want long live-ranges for them.
      40             :   case TargetOpcode::G_CONSTANT:
      41             :   case TargetOpcode::G_FCONSTANT:
      42             :   case TargetOpcode::G_FRAME_INDEX:
      43             :     return true;
      44             :   }
      45             : }
      46             : 
      47          39 : void Localizer::getAnalysisUsage(AnalysisUsage &AU) const {
      48          39 :   getSelectionDAGFallbackAnalysisUsage(AU);
      49          39 :   MachineFunctionPass::getAnalysisUsage(AU);
      50          39 : }
      51             : 
      52         149 : bool Localizer::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
      53             :                            MachineBasicBlock *&InsertMBB) {
      54         149 :   MachineInstr &MIUse = *MOUse.getParent();
      55         149 :   InsertMBB = MIUse.getParent();
      56             :   if (MIUse.isPHI())
      57          22 :     InsertMBB = MIUse.getOperand(MIUse.getOperandNo(&MOUse) + 1).getMBB();
      58         149 :   return InsertMBB == Def.getParent();
      59             : }
      60             : 
      61          95 : bool Localizer::runOnMachineFunction(MachineFunction &MF) {
      62             :   // If the ISel pipeline failed, do not bother running that pass.
      63          95 :   if (MF.getProperties().hasProperty(
      64             :           MachineFunctionProperties::Property::FailedISel))
      65             :     return false;
      66             : 
      67             :   LLVM_DEBUG(dbgs() << "Localize instructions for: " << MF.getName() << '\n');
      68             : 
      69          56 :   init(MF);
      70             : 
      71             :   bool Changed = false;
      72             :   // Keep track of the instructions we localized.
      73             :   // We won't need to process them if we see them later in the CFG.
      74             :   SmallPtrSet<MachineInstr *, 16> LocalizedInstrs;
      75             :   DenseMap<std::pair<MachineBasicBlock *, unsigned>, unsigned> MBBWithLocalDef;
      76             :   // TODO: Do bottom up traversal.
      77         154 :   for (MachineBasicBlock &MBB : MF) {
      78         769 :     for (MachineInstr &MI : MBB) {
      79         671 :       if (LocalizedInstrs.count(&MI) || !shouldLocalize(MI))
      80             :         continue;
      81             :       LLVM_DEBUG(dbgs() << "Should localize: " << MI);
      82             :       assert(MI.getDesc().getNumDefs() == 1 &&
      83             :              "More than one definition not supported yet");
      84         102 :       unsigned Reg = MI.getOperand(0).getReg();
      85             :       // Check if all the users of MI are local.
      86             :       // We are going to invalidation the list of use operands, so we
      87             :       // can't use range iterator.
      88         102 :       for (auto MOIt = MRI->use_begin(Reg), MOItEnd = MRI->use_end();
      89         251 :            MOIt != MOItEnd;) {
      90             :         MachineOperand &MOUse = *MOIt++;
      91             :         // Check if the use is already local.
      92             :         MachineBasicBlock *InsertMBB;
      93             :         LLVM_DEBUG(MachineInstr &MIUse = *MOUse.getParent();
      94             :                    dbgs() << "Checking use: " << MIUse
      95             :                           << " #Opd: " << MIUse.getOperandNo(&MOUse) << '\n');
      96         149 :         if (isLocalUse(MOUse, MI, InsertMBB))
      97         117 :           continue;
      98             :         LLVM_DEBUG(dbgs() << "Fixing non-local use\n");
      99             :         Changed = true;
     100          32 :         auto MBBAndReg = std::make_pair(InsertMBB, Reg);
     101          32 :         auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg);
     102          32 :         if (NewVRegIt == MBBWithLocalDef.end()) {
     103             :           // Create the localized instruction.
     104          31 :           MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI);
     105          31 :           LocalizedInstrs.insert(LocalizedMI);
     106             :           // Don't try to be smart for the insertion point.
     107             :           // There is no guarantee that the first seen use is the first
     108             :           // use in the block.
     109             :           InsertMBB->insert(InsertMBB->SkipPHIsAndLabels(InsertMBB->begin()),
     110          62 :                             LocalizedMI);
     111             : 
     112             :           // Set a new register for the definition.
     113             :           unsigned NewReg =
     114          62 :               MRI->createGenericVirtualRegister(MRI->getType(Reg));
     115          31 :           MRI->setRegClassOrRegBank(NewReg, MRI->getRegClassOrRegBank(Reg));
     116          31 :           LocalizedMI->getOperand(0).setReg(NewReg);
     117          31 :           NewVRegIt =
     118          31 :               MBBWithLocalDef.insert(std::make_pair(MBBAndReg, NewReg)).first;
     119             :           LLVM_DEBUG(dbgs() << "Inserted: " << *LocalizedMI);
     120             :         }
     121             :         LLVM_DEBUG(dbgs() << "Update use with: " << printReg(NewVRegIt->second)
     122             :                           << '\n');
     123             :         // Update the user reg.
     124          32 :         MOUse.setReg(NewVRegIt->second);
     125             :       }
     126             :     }
     127             :   }
     128             :   return Changed;
     129             : }

Generated by: LCOV version 1.13