1 //===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===// 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 10 #include "llvm/CodeGen/MachineInstrBundle.h" 11 #include "llvm/CodeGen/MachineInstrBuilder.h" 12 #include "llvm/CodeGen/Passes.h" 13 #include "llvm/CodeGen/MachineFunctionPass.h" 14 #include "llvm/Target/TargetInstrInfo.h" 15 #include "llvm/Target/TargetMachine.h" 16 #include "llvm/Target/TargetRegisterInfo.h" 17 #include "llvm/ADT/SmallSet.h" 18 #include "llvm/ADT/SmallVector.h" 19 using namespace llvm; 20 21 namespace { 22 class UnpackMachineBundles : public MachineFunctionPass { 23 public: 24 static char ID; // Pass identification 25 UnpackMachineBundles() : MachineFunctionPass(ID) { 26 initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry()); 27 } 28 29 virtual bool runOnMachineFunction(MachineFunction &MF); 30 }; 31 } // end anonymous namespace 32 33 char UnpackMachineBundles::ID = 0; 34 INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundle", 35 "Unpack machine instruction bundles", false, false) 36 37 FunctionPass *llvm::createUnpackMachineBundlesPass() { 38 return new UnpackMachineBundles(); 39 } 40 41 bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { 42 bool Changed = false; 43 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { 44 MachineBasicBlock *MBB = &*I; 45 46 for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(), 47 MIE = MBB->instr_end(); MII != MIE; ) { 48 MachineInstr *MI = &*MII; 49 50 // Remove BUNDLE instruction and the InsideBundle flags from bundled 51 // instructions. 52 if (MI->isBundle()) { 53 while (++MII != MIE && MII->isInsideBundle()) { 54 MII->setIsInsideBundle(false); 55 for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) { 56 MachineOperand &MO = MII->getOperand(i); 57 if (MO.isReg() && MO.isInternalRead()) 58 MO.setIsInternalRead(false); 59 } 60 } 61 MI->eraseFromParent(); 62 63 Changed = true; 64 continue; 65 } 66 67 ++MII; 68 } 69 } 70 71 return Changed; 72 } 73 74 /// finalizeBundle - Finalize a machine instruction bundle which includes 75 /// a sequence of instructions starting from FirstMI to LastMI (inclusive). 76 /// This routine adds a BUNDLE instruction to represent the bundle, it adds 77 /// IsInternalRead markers to MachineOperands which are defined inside the 78 /// bundle, and it copies externally visible defs and uses to the BUNDLE 79 /// instruction. 80 void llvm::finalizeBundle(MachineBasicBlock &MBB, 81 MachineBasicBlock::instr_iterator FirstMI, 82 MachineBasicBlock::instr_iterator LastMI) { 83 const TargetMachine &TM = MBB.getParent()->getTarget(); 84 const TargetInstrInfo *TII = TM.getInstrInfo(); 85 const TargetRegisterInfo *TRI = TM.getRegisterInfo(); 86 87 MachineInstrBuilder MIB = BuildMI(MBB, FirstMI, FirstMI->getDebugLoc(), 88 TII->get(TargetOpcode::BUNDLE)); 89 90 SmallVector<unsigned, 8> LocalDefs; 91 SmallSet<unsigned, 8> LocalDefSet; 92 SmallSet<unsigned, 8> DeadDefSet; 93 SmallSet<unsigned, 8> KilledDefSet; 94 SmallVector<unsigned, 8> ExternUses; 95 SmallSet<unsigned, 8> ExternUseSet; 96 SmallSet<unsigned, 8> KilledUseSet; 97 SmallSet<unsigned, 8> UndefUseSet; 98 SmallVector<MachineOperand*, 4> Defs; 99 do { 100 for (unsigned i = 0, e = FirstMI->getNumOperands(); i != e; ++i) { 101 MachineOperand &MO = FirstMI->getOperand(i); 102 if (!MO.isReg()) 103 continue; 104 if (MO.isDef()) { 105 Defs.push_back(&MO); 106 continue; 107 } 108 109 unsigned Reg = MO.getReg(); 110 if (!Reg) 111 continue; 112 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 113 if (LocalDefSet.count(Reg)) { 114 MO.setIsInternalRead(); 115 if (MO.isKill()) 116 // Internal def is now killed. 117 KilledDefSet.insert(Reg); 118 } else { 119 if (ExternUseSet.insert(Reg)) { 120 ExternUses.push_back(Reg); 121 if (MO.isUndef()) 122 UndefUseSet.insert(Reg); 123 } 124 if (MO.isKill()) 125 // External def is now killed. 126 KilledUseSet.insert(Reg); 127 } 128 } 129 130 for (unsigned i = 0, e = Defs.size(); i != e; ++i) { 131 MachineOperand &MO = *Defs[i]; 132 unsigned Reg = MO.getReg(); 133 if (!Reg) 134 continue; 135 136 if (LocalDefSet.insert(Reg)) { 137 LocalDefs.push_back(Reg); 138 if (MO.isDead()) { 139 DeadDefSet.insert(Reg); 140 } 141 } else { 142 // Re-defined inside the bundle, it's no longer killed. 143 KilledDefSet.erase(Reg); 144 if (!MO.isDead()) 145 // Previously defined but dead. 146 DeadDefSet.erase(Reg); 147 } 148 149 if (!MO.isDead()) { 150 for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); 151 unsigned SubReg = *SubRegs; ++SubRegs) { 152 if (LocalDefSet.insert(SubReg)) 153 LocalDefs.push_back(SubReg); 154 } 155 } 156 } 157 158 FirstMI->setIsInsideBundle(); 159 Defs.clear(); 160 } while (FirstMI++ != LastMI); 161 162 SmallSet<unsigned, 8> Added; 163 for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { 164 unsigned Reg = LocalDefs[i]; 165 if (Added.insert(Reg)) { 166 // If it's not live beyond end of the bundle, mark it dead. 167 bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg); 168 MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) | 169 getImplRegState(true)); 170 } 171 } 172 173 for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) { 174 unsigned Reg = ExternUses[i]; 175 bool isKill = KilledUseSet.count(Reg); 176 bool isUndef = UndefUseSet.count(Reg); 177 MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) | 178 getImplRegState(true)); 179 } 180 } 181