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 INITIALIZE_PASS(Localizer, DEBUG_TYPE, 25 "Move/duplicate certain instructions close to their use", false, 26 false) 27 28 Localizer::Localizer() : MachineFunctionPass(ID) { 29 initializeLocalizerPass(*PassRegistry::getPassRegistry()); 30 } 31 32 void Localizer::init(MachineFunction &MF) { MRI = &MF.getRegInfo(); } 33 34 bool Localizer::shouldLocalize(const MachineInstr &MI) { 35 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 bool Localizer::isLocalUse(MachineOperand &MOUse, const MachineInstr &Def, 48 MachineBasicBlock *&InsertMBB) { 49 MachineInstr &MIUse = *MOUse.getParent(); 50 InsertMBB = MIUse.getParent(); 51 if (MIUse.isPHI()) 52 InsertMBB = MIUse.getOperand(MIUse.getOperandNo(&MOUse) + 1).getMBB(); 53 return InsertMBB == Def.getParent(); 54 } 55 56 bool Localizer::runOnMachineFunction(MachineFunction &MF) { 57 // If the ISel pipeline failed, do not bother running that pass. 58 if (MF.getProperties().hasProperty( 59 MachineFunctionProperties::Property::FailedISel)) 60 return false; 61 62 LLVM_DEBUG(dbgs() << "Localize instructions for: " << MF.getName() << '\n'); 63 64 init(MF); 65 66 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 SmallPtrSet<MachineInstr *, 16> LocalizedInstrs; 70 DenseMap<std::pair<MachineBasicBlock *, unsigned>, unsigned> MBBWithLocalDef; 71 // TODO: Do bottom up traversal. 72 for (MachineBasicBlock &MBB : MF) { 73 for (MachineInstr &MI : MBB) { 74 if (LocalizedInstrs.count(&MI) || !shouldLocalize(MI)) 75 continue; 76 LLVM_DEBUG(dbgs() << "Should localize: " << MI); 77 assert(MI.getDesc().getNumDefs() == 1 && 78 "More than one definition not supported yet"); 79 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 for (auto MOIt = MRI->use_begin(Reg), MOItEnd = MRI->use_end(); 84 MOIt != MOItEnd;) { 85 MachineOperand &MOUse = *MOIt++; 86 // Check if the use is already local. 87 MachineBasicBlock *InsertMBB; 88 LLVM_DEBUG(MachineInstr &MIUse = *MOUse.getParent(); 89 dbgs() << "Checking use: " << MIUse 90 << " #Opd: " << MIUse.getOperandNo(&MOUse) << '\n'); 91 if (isLocalUse(MOUse, MI, InsertMBB)) 92 continue; 93 LLVM_DEBUG(dbgs() << "Fixing non-local use\n"); 94 Changed = true; 95 auto MBBAndReg = std::make_pair(InsertMBB, Reg); 96 auto NewVRegIt = MBBWithLocalDef.find(MBBAndReg); 97 if (NewVRegIt == MBBWithLocalDef.end()) { 98 // Create the localized instruction. 99 MachineInstr *LocalizedMI = MF.CloneMachineInstr(&MI); 100 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 InsertMBB->insert(InsertMBB->SkipPHIsAndLabels(InsertMBB->begin()), 105 LocalizedMI); 106 107 // Set a new register for the definition. 108 unsigned NewReg = 109 MRI->createGenericVirtualRegister(MRI->getType(Reg)); 110 MRI->setRegClassOrRegBank(NewReg, MRI->getRegClassOrRegBank(Reg)); 111 LocalizedMI->getOperand(0).setReg(NewReg); 112 NewVRegIt = 113 MBBWithLocalDef.insert(std::make_pair(MBBAndReg, NewReg)).first; 114 LLVM_DEBUG(dbgs() << "Inserted: " << *LocalizedMI); 115 } 116 LLVM_DEBUG(dbgs() << "Update use with: " << printReg(NewVRegIt->second) 117 << '\n'); 118 // Update the user reg. 119 MOUse.setReg(NewVRegIt->second); 120 } 121 } 122 } 123 return Changed; 124 } 125