/// Generate a predicated version of MI (where the condition is given via /// PredR and Cond) at the point indicated by Where. void HexagonExpandCondsets::predicateAt(const MachineOperand &DefOp, MachineInstr &MI, MachineBasicBlock::iterator Where, const MachineOperand &PredOp, bool Cond, std::set<unsigned> &UpdRegs) { // The problem with updating live intervals is that we can move one def // past another def. In particular, this can happen when moving an A2_tfrt // over an A2_tfrf defining the same register. From the point of view of // live intervals, these two instructions are two separate definitions, // and each one starts another live segment. LiveIntervals's "handleMove" // does not allow such moves, so we need to handle it ourselves. To avoid // invalidating liveness data while we are using it, the move will be // implemented in 4 steps: (1) add a clone of the instruction MI at the // target location, (2) update liveness, (3) delete the old instruction, // and (4) update liveness again. MachineBasicBlock &B = *MI.getParent(); DebugLoc DL = Where->getDebugLoc(); // "Where" points to an instruction. unsigned Opc = MI.getOpcode(); unsigned PredOpc = HII->getCondOpcode(Opc, !Cond); MachineInstrBuilder MB = BuildMI(B, Where, DL, HII->get(PredOpc)); unsigned Ox = 0, NP = MI.getNumOperands(); // Skip all defs from MI first. while (Ox < NP) { MachineOperand &MO = MI.getOperand(Ox); if (!MO.isReg() || !MO.isDef()) break; Ox++; } // Add the new def, then the predicate register, then the rest of the // operands. MB.addReg(DefOp.getReg(), getRegState(DefOp), DefOp.getSubReg()); MB.addReg(PredOp.getReg(), PredOp.isUndef() ? RegState::Undef : 0, PredOp.getSubReg()); while (Ox < NP) { MachineOperand &MO = MI.getOperand(Ox); if (!MO.isReg() || !MO.isImplicit()) MB.add(MO); Ox++; } MachineFunction &MF = *B.getParent(); MachineInstr::mmo_iterator I = MI.memoperands_begin(); unsigned NR = std::distance(I, MI.memoperands_end()); MachineInstr::mmo_iterator MemRefs = MF.allocateMemRefsArray(NR); for (unsigned i = 0; i < NR; ++i) MemRefs[i] = *I++; MB.setMemRefs(MemRefs, MemRefs+NR); MachineInstr *NewI = MB; NewI->clearKillInfo(); LIS->InsertMachineInstrInMaps(*NewI); for (auto &Op : NewI->operands()) if (Op.isReg()) UpdRegs.insert(Op.getReg()); }
void Liveness::resetKills(MachineBasicBlock *B) { auto CopyLiveIns = [] (MachineBasicBlock *B, BitVector &LV) -> void { for (auto I = B->livein_begin(), E = B->livein_end(); I != E; ++I) LV.set(I->PhysReg); }; BitVector LiveIn(TRI.getNumRegs()), Live(TRI.getNumRegs()); CopyLiveIns(B, LiveIn); for (auto SI : B->successors()) CopyLiveIns(SI, Live); for (auto I = B->rbegin(), E = B->rend(); I != E; ++I) { MachineInstr *MI = &*I; if (MI->isDebugValue()) continue; MI->clearKillInfo(); for (auto &Op : MI->operands()) { // An implicit def of a super-register may not necessarily start a // live range of it, since an implicit use could be used to keep parts // of it live. Instead of analyzing the implicit operands, ignore // implicit defs. if (!Op.isReg() || !Op.isDef() || Op.isImplicit()) continue; unsigned R = Op.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(R)) continue; for (MCSubRegIterator SR(R, &TRI, true); SR.isValid(); ++SR) Live.reset(*SR); } for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isUse()) continue; unsigned R = Op.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(R)) continue; bool IsLive = false; for (MCRegAliasIterator AR(R, &TRI, true); AR.isValid(); ++AR) { if (!Live[*AR]) continue; IsLive = true; break; } if (IsLive) continue; Op.setIsKill(true); for (MCSubRegIterator SR(R, &TRI, true); SR.isValid(); ++SR) Live.set(*SR); } } }
void Liveness::resetKills(MachineBasicBlock *B) { auto CopyLiveIns = [] (MachineBasicBlock *B, BitVector &LV) -> void { for (auto I = B->livein_begin(), E = B->livein_end(); I != E; ++I) LV.set(I->PhysReg); }; BitVector LiveIn(TRI.getNumRegs()), Live(TRI.getNumRegs()); CopyLiveIns(B, LiveIn); for (auto SI : B->successors()) CopyLiveIns(SI, Live); for (auto I = B->rbegin(), E = B->rend(); I != E; ++I) { MachineInstr *MI = &*I; if (MI->isDebugValue()) continue; MI->clearKillInfo(); for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isDef()) continue; unsigned R = Op.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(R)) continue; for (MCSubRegIterator SR(R, &TRI, true); SR.isValid(); ++SR) Live.reset(*SR); } for (auto &Op : MI->operands()) { if (!Op.isReg() || !Op.isUse()) continue; unsigned R = Op.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(R)) continue; bool IsLive = false; for (MCRegAliasIterator AR(R, &TRI, true); AR.isValid(); ++AR) { if (!Live[*AR]) continue; IsLive = true; break; } if (IsLive) continue; Op.setIsKill(true); for (MCSubRegIterator SR(R, &TRI, true); SR.isValid(); ++SR) Live.set(*SR); } } }
/// Generate a conditional transfer, copying the value SrcOp to the /// destination register DstR:DstSR, and using the predicate register from /// PredOp. The Cond argument specifies whether the predicate is to be /// if(PredOp), or if(!PredOp). MachineInstr *HexagonExpandCondsets::genTfrFor(MachineOperand &SrcOp, unsigned DstR, unsigned DstSR, const MachineOperand &PredOp, bool Cond) { MachineInstr *MI = SrcOp.getParent(); MachineBasicBlock &B = *MI->getParent(); MachineBasicBlock::iterator At = MI; DebugLoc DL = MI->getDebugLoc(); // Don't avoid identity copies here (i.e. if the source and the destination // are the same registers). It is actually better to generate them here, // since this would cause the copy to potentially be predicated in the next // step. The predication will remove such a copy if it is unable to /// predicate. unsigned Opc = getCondTfrOpcode(SrcOp, Cond); MachineInstr *TfrI = BuildMI(B, At, DL, HII->get(Opc)) .addReg(DstR, RegState::Define, DstSR) .addOperand(PredOp) .addOperand(SrcOp); // We don't want any kills yet. TfrI->clearKillInfo(); DEBUG(dbgs() << "created an initial copy: " << *TfrI); return TfrI; }