// Insert Defs and Uses of MI into the sets RegDefs and RegUses. void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI, SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegUses) { // If MI is a call or return, just examine the explicit non-variadic operands. MCInstrDesc MCID = MI->getDesc(); unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands() : MI->getNumOperands(); for (unsigned I = 0; I != E; ++I) { const MachineOperand &MO = MI->getOperand(I); unsigned Reg; if (!MO.isReg() || !(Reg = MO.getReg())) continue; if (MO.isDef()) RegDefs.insert(Reg); else if (MO.isUse()) RegUses.insert(Reg); } // Call & return instructions defines SP implicitly. Implicit defines are not // included in the RegDefs set of calls but instructions modifying SP cannot // be inserted in the delay slot of a call/return as these instructions are // expanded to multiple instructions with SP modified before the branch that // has the delay slot. if (MI->isCall() || MI->isReturn()) RegDefs.insert(Lanai::SP); }
bool Filler::delayHasHazard(MachineBasicBlock::instr_iterator MI, bool &SawLoad, bool &SawStore, SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegUses) { if (MI->isImplicitDef() || MI->isKill()) return true; // Loads or stores cannot be moved past a store to the delay slot // and stores cannot be moved past a load. if (MI->mayLoad()) { if (SawStore) return true; SawLoad = true; } if (MI->mayStore()) { if (SawStore) return true; SawStore = true; if (SawLoad) return true; } assert((!MI->isCall() && !MI->isReturn()) && "Cannot put calls or returns in delay slot."); for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { const MachineOperand &MO = MI->getOperand(I); unsigned Reg; if (!MO.isReg() || !(Reg = MO.getReg())) continue; // skip if (MO.isDef()) { // check whether Reg is defined or used before delay slot. if (isRegInSet(RegDefs, Reg) || isRegInSet(RegUses, Reg)) return true; } if (MO.isUse()) { // check whether Reg is defined before delay slot. if (isRegInSet(RegDefs, Reg)) return true; } } return false; }
// Insert Defs and Uses of MI into the sets RegDefs and RegUses. void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI, SmallSet<unsigned, 32> &RegDefs, SmallSet<unsigned, 32> &RegUses) { // If MI is a call or return, just examine the explicit non-variadic operands. MCInstrDesc MCID = MI->getDesc(); unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands() : MI->getNumOperands(); for (unsigned I = 0; I != E; ++I) { const MachineOperand &MO = MI->getOperand(I); unsigned Reg; if (!MO.isReg() || !(Reg = MO.getReg())) continue; if (MO.isDef()) RegDefs.insert(Reg); else if (MO.isUse()) RegUses.insert(Reg); } }