LCOV - code coverage report
Current view: top level - lib/CodeGen/GlobalISel - Localizer.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 45 45 100.0 %
Date: 2017-09-14 15:23:50 Functions: 7 7 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      726688 : INITIALIZE_PASS(Localizer, DEBUG_TYPE,
      25             :                 "Move/duplicate certain instructions close to their use", false,
      26             :                 false)
      27             : 
      28          19 : Localizer::Localizer() : MachineFunctionPass(ID) {
      29          19 :   initializeLocalizerPass(*PassRegistry::getPassRegistry());
      30          19 : }
      31             : 
      32          17 : void Localizer::init(MachineFunction &MF) { MRI = &MF.getRegInfo(); }
      33             : 
      34          85 : bool Localizer::shouldLocalize(const MachineInstr &MI) {
      35          85 :   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          15 :   case TargetOpcode::G_CONSTANT:
      41             :   case TargetOpcode::G_FCONSTANT:
      42             :   case TargetOpcode::G_FRAME_INDEX:
      43          15 :     return true;
      44             :   }
      45             : }
      46             : 
      47          36 : bool Localizer::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
      48             :                            MachineBasicBlock *&InsertMBB) {
      49          36 :   MachineInstr &MIUse = *MOUse.getParent();
      50          36 :   InsertMBB = MIUse.getParent();
      51             :   if (MIUse.isPHI())
      52          18 :     InsertMBB = MIUse.getOperand(MIUse.getOperandNo(&MOUse) + 1).getMBB();
      53          36 :   return InsertMBB == Def.getParent();
      54             : }
      55             : 
      56          37 : bool Localizer::runOnMachineFunction(MachineFunction &MF) {
      57             :   // If the ISel pipeline failed, do not bother running that pass.
      58          74 :   if (MF.getProperties().hasProperty(
      59             :           MachineFunctionProperties::Property::FailedISel))
      60             :     return false;
      61             : 
      62             :   DEBUG(dbgs() << "Localize instructions for: " << MF.getName() << '\n');
      63             : 
      64          17 :   init(MF);
      65             : 
      66          17 :   bool Changed = false;
      67             :   // Keep track of the instructions we localized.
      68             :   // We won't need to process them if we see them later in the CFG.
      69          17 :   SmallPtrSet<MachineInstr *, 16> LocalizedInstrs;
      70          34 :   DenseMap<std::pair<MachineBasicBlock *, unsigned>, unsigned> MBBWithLocalDef;
      71             :   // TODO: Do bottom up traversal.
      72          89 :   for (MachineBasicBlock &MBB : MF) {
      73         356 :     for (MachineInstr &MI : MBB) {
      74         102 :       if (LocalizedInstrs.count(&MI) || !shouldLocalize(MI))
      75          87 :         continue;
      76             :       DEBUG(dbgs() << "Should localize: " << MI);
      77             :       assert(MI.getDesc().getNumDefs() == 1 &&
      78             :              "More than one definition not supported yet");
      79          15 :       unsigned Reg = MI.getOperand(0).getReg();
      80             :       // Check if all the users of MI are local.
      81             :       // We are going to invalidation the list of use operands, so we
      82             :       // can't use range iterator.
      83          30 :       for (auto MOIt = MRI->use_begin(Reg), MOItEnd = MRI->use_end();
      84          51 :            MOIt != MOItEnd;) {
      85          72 :         MachineOperand &MOUse = *MOIt++;
      86             :         // Check if the use is already local.
      87             :         MachineBasicBlock *InsertMBB;
      88             :         DEBUG(MachineInstr &MIUse = *MOUse.getParent();
      89             :               dbgs() << "Checking use: " << MIUse
      90             :                      << " #Opd: " << MIUse.getOperandNo(&MOUse) << '\n');
      91          36 :         if (isLocalUse(MOUse, MI, InsertMBB))
      92          18 :           continue;
      93             :         DEBUG(dbgs() << "Fixing non-local use\n");
      94          18 :         Changed = true;
      95          36 :         auto MBBAndReg = std::make_pair(InsertMBB, Reg);
      96          18 :         auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg);
      97          36 :         if (NewVRegIt == MBBWithLocalDef.end()) {
      98             :           // Create the localized instruction.
      99          17 :           MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI);
     100          17 :           LocalizedInstrs.insert(LocalizedMI);
     101             :           // Don't try to be smart for the insertion point.
     102             :           // There is no guarantee that the first seen use is the first
     103             :           // use in the block.
     104          17 :           InsertMBB->insert(InsertMBB->SkipPHIsAndLabels(InsertMBB->begin()),
     105          34 :                             LocalizedMI);
     106             : 
     107             :           // Set a new register for the definition.
     108             :           unsigned NewReg =
     109          17 :               MRI->createGenericVirtualRegister(MRI->getType(Reg));
     110          51 :           MRI->setRegClassOrRegBank(NewReg, MRI->getRegClassOrRegBank(Reg));
     111          17 :           LocalizedMI->getOperand(0).setReg(NewReg);
     112          17 :           NewVRegIt =
     113          68 :               MBBWithLocalDef.insert(std::make_pair(MBBAndReg, NewReg)).first;
     114             :           DEBUG(dbgs() << "Inserted: " << *LocalizedMI);
     115             :         }
     116             :         DEBUG(dbgs() << "Update use with: " << PrintReg(NewVRegIt->second)
     117             :                      << '\n');
     118             :         // Update the user reg.
     119          18 :         MOUse.setReg(NewVRegIt->second);
     120             :       }
     121             :     }
     122             :   }
     123          17 :   return Changed;
     124             : }

Generated by: LCOV version 1.13