Mercurial > hg > CbC > CbC_llvm
diff lib/CodeGen/AggressiveAntiDepBreaker.cpp @ 120:1172e4bd9c6f
update 4.0.0
author | mir3636 |
---|---|
date | Fri, 25 Nov 2016 19:14:25 +0900 |
parents | 7d135dc70f03 |
children | 803732b1fca8 |
line wrap: on
line diff
--- a/lib/CodeGen/AggressiveAntiDepBreaker.cpp Tue Jan 26 22:56:36 2016 +0900 +++ b/lib/CodeGen/AggressiveAntiDepBreaker.cpp Fri Nov 25 19:14:25 2016 +0900 @@ -161,8 +161,8 @@ // Mark live-out callee-saved registers. In a return block this is // all callee-saved registers. In non-return this is any // callee-saved register that is not saved in the prolog. - const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(MF); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + BitVector Pristine = MFI.getPristineRegs(MF); for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) { unsigned Reg = *I; if (!IsReturnBlock && !Pristine.test(Reg)) continue; @@ -180,7 +180,7 @@ State = nullptr; } -void AggressiveAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count, +void AggressiveAntiDepBreaker::Observe(MachineInstr &MI, unsigned Count, unsigned InsertPosIndex) { assert(Count < InsertPosIndex && "Instruction index out of expected range!"); @@ -190,7 +190,7 @@ ScanInstruction(MI, Count); DEBUG(dbgs() << "Observe: "); - DEBUG(MI->dump()); + DEBUG(MI.dump()); DEBUG(dbgs() << "\tRegs:"); std::vector<unsigned> &DefIndices = State->GetDefIndices(); @@ -214,9 +214,8 @@ DEBUG(dbgs() << '\n'); } -bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr *MI, - MachineOperand& MO) -{ +bool AggressiveAntiDepBreaker::IsImplicitDefUse(MachineInstr &MI, + MachineOperand &MO) { if (!MO.isReg() || !MO.isImplicit()) return false; @@ -226,19 +225,19 @@ MachineOperand *Op = nullptr; if (MO.isDef()) - Op = MI->findRegisterUseOperand(Reg, true); + Op = MI.findRegisterUseOperand(Reg, true); else - Op = MI->findRegisterDefOperand(Reg); + Op = MI.findRegisterDefOperand(Reg); return(Op && Op->isImplicit()); } -void AggressiveAntiDepBreaker::GetPassthruRegs(MachineInstr *MI, - std::set<unsigned>& PassthruRegs) { - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); +void AggressiveAntiDepBreaker::GetPassthruRegs( + MachineInstr &MI, std::set<unsigned> &PassthruRegs) { + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI.getOperand(i); if (!MO.isReg()) continue; - if ((MO.isDef() && MI->isRegTiedToUseOperand(i)) || + if ((MO.isDef() && MI.isRegTiedToUseOperand(i)) || IsImplicitDefUse(MI, MO)) { const unsigned Reg = MO.getReg(); for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true); @@ -313,28 +312,30 @@ DEBUG(if (header) { dbgs() << header << TRI->getName(Reg); header = nullptr; }); DEBUG(dbgs() << "->g" << State->GetGroup(Reg) << tag); - } - // Repeat for subregisters. - for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { - unsigned SubregReg = *SubRegs; - if (!State->IsLive(SubregReg)) { - KillIndices[SubregReg] = KillIdx; - DefIndices[SubregReg] = ~0u; - RegRefs.erase(SubregReg); - State->LeaveGroup(SubregReg); - DEBUG(if (header) { - dbgs() << header << TRI->getName(Reg); header = nullptr; }); - DEBUG(dbgs() << " " << TRI->getName(SubregReg) << "->g" << - State->GetGroup(SubregReg) << tag); + // Repeat for subregisters. Note that we only do this if the superregister + // was not live because otherwise, regardless whether we have an explicit + // use of the subregister, the subregister's contents are needed for the + // uses of the superregister. + for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { + unsigned SubregReg = *SubRegs; + if (!State->IsLive(SubregReg)) { + KillIndices[SubregReg] = KillIdx; + DefIndices[SubregReg] = ~0u; + RegRefs.erase(SubregReg); + State->LeaveGroup(SubregReg); + DEBUG(if (header) { + dbgs() << header << TRI->getName(Reg); header = nullptr; }); + DEBUG(dbgs() << " " << TRI->getName(SubregReg) << "->g" << + State->GetGroup(SubregReg) << tag); + } } } DEBUG(if (!header && footer) dbgs() << footer); } -void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, - unsigned Count, - std::set<unsigned>& PassthruRegs) { +void AggressiveAntiDepBreaker::PrescanInstruction( + MachineInstr &MI, unsigned Count, std::set<unsigned> &PassthruRegs) { std::vector<unsigned> &DefIndices = State->GetDefIndices(); std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& RegRefs = State->GetRegRefs(); @@ -344,8 +345,8 @@ // dead, or because only a subregister is live at the def. If we // don't do this the dead def will be incorrectly merged into the // previous def. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI.getOperand(i); if (!MO.isReg() || !MO.isDef()) continue; unsigned Reg = MO.getReg(); if (Reg == 0) continue; @@ -354,8 +355,8 @@ } DEBUG(dbgs() << "\tDef Groups:"); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI.getOperand(i); if (!MO.isReg() || !MO.isDef()) continue; unsigned Reg = MO.getReg(); if (Reg == 0) continue; @@ -367,8 +368,8 @@ // defined in a call must not be changed (ABI). Inline assembly may // reference either system calls or the register directly. Skip it until we // can tell user specified registers from compiler-specified. - if (MI->isCall() || MI->hasExtraDefRegAllocReq() || - TII->isPredicated(MI) || MI->isInlineAsm()) { + if (MI.isCall() || MI.hasExtraDefRegAllocReq() || TII->isPredicated(MI) || + MI.isInlineAsm()) { DEBUG(if (State->GetGroup(Reg) != 0) dbgs() << "->g0(alloc-req)"); State->UnionGroups(Reg, 0); } @@ -386,8 +387,8 @@ // Note register reference... const TargetRegisterClass *RC = nullptr; - if (i < MI->getDesc().getNumOperands()) - RC = TII->getRegClass(MI->getDesc(), i, TRI, MF); + if (i < MI.getDesc().getNumOperands()) + RC = TII->getRegClass(MI.getDesc(), i, TRI, MF); AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; RegRefs.insert(std::make_pair(Reg, RR)); } @@ -396,13 +397,13 @@ // Scan the register defs for this instruction and update // live-ranges. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI.getOperand(i); if (!MO.isReg() || !MO.isDef()) continue; unsigned Reg = MO.getReg(); if (Reg == 0) continue; // Ignore KILLs and passthru registers for liveness... - if (MI->isKill() || (PassthruRegs.count(Reg) != 0)) + if (MI.isKill() || (PassthruRegs.count(Reg) != 0)) continue; // Update def for Reg and aliases. @@ -421,7 +422,7 @@ } } -void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI, +void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr &MI, unsigned Count) { DEBUG(dbgs() << "\tUse Groups:"); std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& @@ -444,14 +445,13 @@ // instruction which may not be executed. The second R6 def may or may not // re-define R6 so it's not safe to change it since the last R6 use cannot be // changed. - bool Special = MI->isCall() || - MI->hasExtraSrcRegAllocReq() || - TII->isPredicated(MI) || MI->isInlineAsm(); + bool Special = MI.isCall() || MI.hasExtraSrcRegAllocReq() || + TII->isPredicated(MI) || MI.isInlineAsm(); // Scan the register uses for this instruction and update // live-ranges, groups and RegRefs. - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI.getOperand(i); if (!MO.isReg() || !MO.isUse()) continue; unsigned Reg = MO.getReg(); if (Reg == 0) continue; @@ -471,8 +471,8 @@ // Note register reference... const TargetRegisterClass *RC = nullptr; - if (i < MI->getDesc().getNumOperands()) - RC = TII->getRegClass(MI->getDesc(), i, TRI, MF); + if (i < MI.getDesc().getNumOperands()) + RC = TII->getRegClass(MI.getDesc(), i, TRI, MF); AggressiveAntiDepState::RegisterReference RR = { &MO, RC }; RegRefs.insert(std::make_pair(Reg, RR)); } @@ -481,12 +481,12 @@ // Form a group of all defs and uses of a KILL instruction to ensure // that all registers are renamed as a group. - if (MI->isKill()) { + if (MI.isKill()) { DEBUG(dbgs() << "\tKill Group:"); unsigned FirstReg = 0; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); + for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { + MachineOperand &MO = MI.getOperand(i); if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); if (Reg == 0) continue; @@ -563,13 +563,16 @@ if (RegRefs.count(Reg) > 0) { DEBUG(dbgs() << "\t\t" << TRI->getName(Reg) << ":"); - BitVector BV = GetRenameRegisters(Reg); - RenameRegisterMap.insert(std::pair<unsigned, BitVector>(Reg, BV)); + BitVector &BV = RenameRegisterMap[Reg]; + assert(BV.empty()); + BV = GetRenameRegisters(Reg); - DEBUG(dbgs() << " ::"); - DEBUG(for (int r = BV.find_first(); r != -1; r = BV.find_next(r)) - dbgs() << " " << TRI->getName(r)); - DEBUG(dbgs() << "\n"); + DEBUG({ + dbgs() << " ::"; + for (int r = BV.find_first(); r != -1; r = BV.find_next(r)) + dbgs() << " " << TRI->getName(r); + dbgs() << "\n"; + }); } } @@ -650,8 +653,7 @@ DEBUG(dbgs() << " " << TRI->getName(NewReg)); // Check if Reg can be renamed to NewReg. - BitVector BV = RenameRegisterMap[Reg]; - if (!BV.test(NewReg)) { + if (!RenameRegisterMap[Reg].test(NewReg)) { DEBUG(dbgs() << "(no rename)"); goto next_super_reg; } @@ -785,6 +787,8 @@ DEBUG(dbgs() << '\n'); #endif + BitVector RegAliases(TRI->getNumRegs()); + // Attempt to break anti-dependence edges. Walk the instructions // from the bottom up, tracking information about liveness as we go // to help determine which registers are available. @@ -792,13 +796,13 @@ unsigned Count = InsertPosIndex - 1; for (MachineBasicBlock::iterator I = End, E = Begin; I != E; --Count) { - MachineInstr *MI = --I; + MachineInstr &MI = *--I; - if (MI->isDebugValue()) + if (MI.isDebugValue()) continue; DEBUG(dbgs() << "Anti: "); - DEBUG(MI->dump()); + DEBUG(MI.dump()); std::set<unsigned> PassthruRegs; GetPassthruRegs(MI, PassthruRegs); @@ -809,13 +813,13 @@ // The dependence edges that represent anti- and output- // dependencies that are candidates for breaking. std::vector<const SDep *> Edges; - const SUnit *PathSU = MISUnitMap[MI]; + const SUnit *PathSU = MISUnitMap[&MI]; AntiDepEdges(PathSU, Edges); // If MI is not on the critical path, then we don't rename // registers in the CriticalPathSet. BitVector *ExcludeRegs = nullptr; - if (MI == CriticalPathMI) { + if (&MI == CriticalPathMI) { CriticalPathSU = CriticalPathStep(CriticalPathSU); CriticalPathMI = (CriticalPathSU) ? CriticalPathSU->getInstr() : nullptr; } else if (CriticalPathSet.any()) { @@ -824,7 +828,7 @@ // Ignore KILL instructions (they form a group in ScanInstruction // but don't cause any anti-dependence breaking themselves) - if (!MI->isKill()) { + if (!MI.isKill()) { // Attempt to break each anti-dependency... for (unsigned i = 0, e = Edges.size(); i != e; ++i) { const SDep *Edge = Edges[i]; @@ -854,7 +858,7 @@ continue; } else { // No anti-dep breaking for implicit deps - MachineOperand *AntiDepOp = MI->findRegisterDefOperand(AntiDepReg); + MachineOperand *AntiDepOp = MI.findRegisterDefOperand(AntiDepReg); assert(AntiDepOp && "Can't find index for defined register operand"); if (!AntiDepOp || AntiDepOp->isImplicit()) { DEBUG(dbgs() << " (implicit)\n"); @@ -896,6 +900,29 @@ } if (AntiDepReg == 0) continue; + + // If the definition of the anti-dependency register does not start + // a new live range, bail out. This can happen if the anti-dep + // register is a sub-register of another register whose live range + // spans over PathSU. In such case, PathSU defines only a part of + // the larger register. + RegAliases.reset(); + for (MCRegAliasIterator AI(AntiDepReg, TRI, true); AI.isValid(); ++AI) + RegAliases.set(*AI); + for (SDep S : PathSU->Succs) { + SDep::Kind K = S.getKind(); + if (K != SDep::Data && K != SDep::Output && K != SDep::Anti) + continue; + unsigned R = S.getReg(); + if (!RegAliases[R]) + continue; + if (R == AntiDepReg || TRI->isSubRegister(AntiDepReg, R)) + continue; + AntiDepReg = 0; + break; + } + + if (AntiDepReg == 0) continue; } assert(AntiDepReg != 0); @@ -938,7 +965,7 @@ for (DbgValueVector::iterator DVI = DbgValues.begin(), DVE = DbgValues.end(); DVI != DVE; ++DVI) if (DVI->second == Q.second.Operand->getParent()) - UpdateDbgValue(DVI->first, AntiDepReg, NewReg); + UpdateDbgValue(*DVI->first, AntiDepReg, NewReg); } // We just went back in time and modified history; the