/// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// We assume there is only one delay slot per delayed instruction. bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; for (Iter I = MBB.begin(); I != MBB.end(); ++I) { if (!hasUnoccupiedSlot(&*I)) continue; ++FilledSlots; Changed = true; // Delay slot filling is disabled at -O0. if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None)) { if (searchBackward(MBB, I)) continue; if (I->isTerminator()) { if (searchSuccBBs(MBB, I)) continue; } else if (searchForward(MBB, I)) { continue; } } // Bundle the NOP to the instruction with the delay slot. BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); MIBundleBuilder(MBB, I, llvm::next(llvm::next(I))); } return Changed; }
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// We assume there is only one delay slot per delayed instruction. bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); bool InMicroMipsMode = STI.inMicroMipsMode(); const MipsInstrInfo *TII = STI.getInstrInfo(); for (Iter I = MBB.begin(); I != MBB.end(); ++I) { if (!hasUnoccupiedSlot(&*I)) continue; ++FilledSlots; Changed = true; // Delay slot filling is disabled at -O0. if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None)) { bool Filled = false; if (searchBackward(MBB, I)) { Filled = true; } else if (I->isTerminator()) { if (searchSuccBBs(MBB, I)) { Filled = true; } } else if (searchForward(MBB, I)) { Filled = true; } if (Filled) { // Get instruction with delay slot. MachineBasicBlock::instr_iterator DSI(I); if (InMicroMipsMode && TII->GetInstSizeInBytes(std::next(DSI)) == 2 && DSI->isCall()) { // If instruction in delay slot is 16b change opcode to // corresponding instruction with short delay slot. DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode()))); } continue; } } // If instruction is BEQ or BNE with one ZERO register, then instead of // adding NOP replace this instruction with the corresponding compact // branch instruction, i.e. BEQZC or BNEZC. unsigned Opcode = I->getOpcode(); if (InMicroMipsMode) { switch (Opcode) { case Mips::BEQ: case Mips::BNE: if (((unsigned) I->getOperand(1).getReg()) == Mips::ZERO) { I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); continue; } break; case Mips::JR: case Mips::PseudoReturn: case Mips::PseudoIndirectBranch: // For microMIPS the PseudoReturn and PseudoIndirectBranch are allways // expanded to JR_MM, so they can be replaced with JRC16_MM. I = replaceWithCompactJump(MBB, I, I->getDebugLoc()); continue; default: break; } } // Bundle the NOP to the instruction with the delay slot. BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); MIBundleBuilder(MBB, I, std::next(I, 2)); } return Changed; }
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// We assume there is only one delay slot per delayed instruction. bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); bool InMicroMipsMode = STI.inMicroMipsMode(); const MipsInstrInfo *TII = STI.getInstrInfo(); if (InMicroMipsMode && STI.hasMips32r6()) { // This is microMIPS32r6 or microMIPS64r6 processor. Delay slot for // branching instructions is not needed. return Changed; } for (Iter I = MBB.begin(); I != MBB.end(); ++I) { if (!hasUnoccupiedSlot(&*I)) continue; ++FilledSlots; Changed = true; // Delay slot filling is disabled at -O0. if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None)) { bool Filled = false; if (searchBackward(MBB, I)) { Filled = true; } else if (I->isTerminator()) { if (searchSuccBBs(MBB, I)) { Filled = true; } } else if (searchForward(MBB, I)) { Filled = true; } if (Filled) { // Get instruction with delay slot. MachineBasicBlock::instr_iterator DSI(I); if (InMicroMipsMode && TII->GetInstSizeInBytes(&*std::next(DSI)) == 2 && DSI->isCall()) { // If instruction in delay slot is 16b change opcode to // corresponding instruction with short delay slot. DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode()))); } continue; } } // For microMIPS if instruction is BEQ or BNE with one ZERO register, then // instead of adding NOP replace this instruction with the corresponding // compact branch instruction, i.e. BEQZC or BNEZC. Additionally // PseudoReturn and PseudoIndirectBranch are expanded to JR_MM, so they can // be replaced with JRC16_MM. // For MIPSR6 attempt to produce the corresponding compact (no delay slot) // form of the CTI. For indirect jumps this will not require inserting a // NOP and for branches will hopefully avoid requiring a NOP. if ((InMicroMipsMode || STI.hasMips32r6()) && TII->getEquivalentCompactForm(I)) { I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); continue; } // Bundle the NOP to the instruction with the delay slot. BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); MIBundleBuilder(MBB, I, std::next(I, 2)); } return Changed; }