diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-30 01:45:55 +0000 | 
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-30 01:45:55 +0000 | 
| commit | efab16d43bedc5a6cd82745f883e40cc4b63b905 (patch) | |
| tree | f6e1089bff4d80067dca0643a91cc404d7e7a74b /llvm | |
| parent | b5b71fe628da6e3e4cdeca2515ac445f69ece512 (diff) | |
| download | bcm5719-llvm-efab16d43bedc5a6cd82745f883e40cc4b63b905.tar.gz bcm5719-llvm-efab16d43bedc5a6cd82745f883e40cc4b63b905.zip  | |
Handle implicit_defs in the register coalescer. I am still trying to produce
a reduced testcase, but this fixes pr13209.
llvm-svn: 159479
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.cpp | 67 | 
1 files changed, 40 insertions, 27 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index 19b6ffcb51b..6ef098d1a14 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -1172,14 +1172,11 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li,    MachineInstr *MI = li.getInstructionFromIndex(VNI->def); -  if (!MI || !MI->isFullCopy() || CP.isPartial() || CP.isPhys()) +  if (!MI || CP.isPartial() || CP.isPhys())      return false;    unsigned Dst = MI->getOperand(0).getReg(); -  unsigned Src = MI->getOperand(1).getReg(); - -  if (!TargetRegisterInfo::isVirtualRegister(Src) || -      !TargetRegisterInfo::isVirtualRegister(Dst)) +  if (!TargetRegisterInfo::isVirtualRegister(Dst))      return false;    unsigned A = CP.getDstReg(); @@ -1189,34 +1186,47 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li,      std::swap(A, B);    assert(Dst == A); -  const MachineInstr *OtherMI = li.getInstructionFromIndex(OtherVNI->def); +  MachineInstr *OtherMI = li.getInstructionFromIndex(OtherVNI->def); -  if (!OtherMI || !OtherMI->isFullCopy()) +  if (!OtherMI)      return false;    unsigned OtherDst = OtherMI->getOperand(0).getReg(); -  unsigned OtherSrc = OtherMI->getOperand(1).getReg(); - -  if (!TargetRegisterInfo::isVirtualRegister(OtherSrc) || -      !TargetRegisterInfo::isVirtualRegister(OtherDst)) +  if (!TargetRegisterInfo::isVirtualRegister(OtherDst))      return false;    assert(OtherDst == B); -  if (Src != OtherSrc) -    return false; +  if (MI->isImplicitDef()) { +    DupCopies.push_back(MI); +    return true; +  } else { +    if (!MI->isFullCopy()) +      return false; +    unsigned Src = MI->getOperand(1).getReg(); +    if (!TargetRegisterInfo::isVirtualRegister(Src)) +      return false; +    if (!OtherMI->isFullCopy()) +      return false; +    unsigned OtherSrc = OtherMI->getOperand(1).getReg(); +    if (!TargetRegisterInfo::isVirtualRegister(OtherSrc)) +      return false; -  // If the copies use two different value numbers of X, we cannot merge -  // A and B. -  LiveInterval &SrcInt = li.getInterval(Src); -  // getVNInfoBefore returns NULL for undef copies. In this case, the -  // optimization is still safe. -  if (SrcInt.getVNInfoBefore(OtherVNI->def) != SrcInt.getVNInfoBefore(VNI->def)) -    return false; +    if (Src != OtherSrc) +      return false; -  DupCopies.push_back(MI); +    // If the copies use two different value numbers of X, we cannot merge +    // A and B. +    LiveInterval &SrcInt = li.getInterval(Src); +    // getVNInfoBefore returns NULL for undef copies. In this case, the +    // optimization is still safe. +    if (SrcInt.getVNInfoBefore(OtherVNI->def) != +        SrcInt.getVNInfoBefore(VNI->def)) +      return false; -  return true; +    DupCopies.push_back(MI); +    return true; +  }  }  /// joinIntervals - Attempt to join these two intervals.  On failure, this @@ -1254,7 +1264,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {        continue;      MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);      assert(MI && "Missing def"); -    if (!MI->isCopyLike())  // Src not defined by a copy? +    if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?        continue;      // Figure out the value # from the RHS. @@ -1283,7 +1293,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {        continue;      MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);      assert(MI && "Missing def"); -    if (!MI->isCopyLike())  // Src not defined by a copy? +    if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?        continue;      // Figure out the value # from the LHS. @@ -1429,14 +1439,17 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {      if (!ErasedInstrs.insert(MI))        continue; -    // We have pretended that the assignment to B in +    // If MI is a copy, then we have pretended that the assignment to B in      // A = X      // B = X      // was actually a copy from A. Now that we decided to coalesce A and B,      // transform the code into      // A = X -    unsigned Src = MI->getOperand(1).getReg(); -    SourceRegisters.push_back(Src); +    // In the case of the implicit_def, we just have to remove it. +    if (!MI->isImplicitDef()) { +      unsigned Src = MI->getOperand(1).getReg(); +      SourceRegisters.push_back(Src); +    }      LIS->RemoveMachineInstrFromMaps(MI);      MI->eraseFromParent();    }  | 

