diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2011-06-12 15:42:51 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2011-06-12 15:42:51 +0000 | 
| commit | 56fe8f14099930935e3870e3e823c322a85c1c89 (patch) | |
| tree | b3032e51d630e8070e9e08d6641648f195316a80 /lib/CodeGen/MachineBasicBlock.cpp | |
| parent | 6b943ff3a3f8617113ecbf611cf0f8957e4e19d2 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MachineBasicBlock.cpp')
| -rw-r--r-- | lib/CodeGen/MachineBasicBlock.cpp | 41 | 
1 files changed, 39 insertions, 2 deletions
| diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 57f3e34d0c5a..68946a2c9d13 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -485,6 +485,30 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {          << " -- BB#" << NMBB->getNumber()          << " -- BB#" << Succ->getNumber() << '\n'); +  // On some targets like Mips, branches may kill virtual registers. Make sure +  // that LiveVariables is properly updated after updateTerminator replaces the +  // terminators. +  LiveVariables *LV = P->getAnalysisIfAvailable<LiveVariables>(); + +  // Collect a list of virtual registers killed by the terminators. +  SmallVector<unsigned, 4> KilledRegs; +  if (LV) +    for (iterator I = getFirstTerminator(), E = end(); I != E; ++I) { +      MachineInstr *MI = I; +      for (MachineInstr::mop_iterator OI = MI->operands_begin(), +           OE = MI->operands_end(); OI != OE; ++OI) { +        if (!OI->isReg() || !OI->isUse() || !OI->isKill() || OI->isUndef()) +          continue; +        unsigned Reg = OI->getReg(); +        if (TargetRegisterInfo::isVirtualRegister(Reg) && +            LV->getVarInfo(Reg).removeKill(MI)) { +          KilledRegs.push_back(Reg); +          DEBUG(dbgs() << "Removing terminator kill: " << *MI); +          OI->setIsKill(false); +        } +      } +    } +    ReplaceUsesOfBlockWith(Succ, NMBB);    updateTerminator(); @@ -502,9 +526,22 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {        if (i->getOperand(ni+1).getMBB() == this)          i->getOperand(ni+1).setMBB(NMBB); -  if (LiveVariables *LV = -        P->getAnalysisIfAvailable<LiveVariables>()) +  // Update LiveVariables. +  if (LV) { +    // Restore kills of virtual registers that were killed by the terminators. +    while (!KilledRegs.empty()) { +      unsigned Reg = KilledRegs.pop_back_val(); +      for (iterator I = end(), E = begin(); I != E;) { +        if (!(--I)->addRegisterKilled(Reg, NULL, /* addIfNotFound= */ false)) +          continue; +        LV->getVarInfo(Reg).Kills.push_back(I); +        DEBUG(dbgs() << "Restored terminator kill: " << *I); +        break; +      } +    } +    // Update relevant live-through information.      LV->addNewBlock(NMBB, this, Succ); +  }    if (MachineDominatorTree *MDT =        P->getAnalysisIfAvailable<MachineDominatorTree>()) { | 
