<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Thanks, added virtual destructor....</div><div><br></div>Author: david_goodwin<br>Date: Mon Oct 26 14:00:47 2009<br>New Revision: 85141<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=85141&view=rev">http://llvm.org/viewvc/llvm-project?rev=85141&view=rev</a><br>Log:<br>Add virtual destructor.<br><br>Modified:<br>   llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h<br><div><div><br></div><div><br></div><div>On Oct 26, 2009, at 11:38 AM, Chandler Carruth wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>FYI, this change causes both llvm::AntiDepBreaker and<br>llvm::CriticalAntiDepBreaker to have virtual functions and an<br>accessible non-virtual destructor.<br><br>On Mon, Oct 26, 2009 at 9:59 AM, David Goodwin <<a href="mailto:david_goodwin@apple.com">david_goodwin@apple.com</a>> wrote:<br><blockquote type="cite">Author: david_goodwin<br></blockquote><blockquote type="cite">Date: Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">New Revision: 85127<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=85127&view=rev">http://llvm.org/viewvc/llvm-project?rev=85127&view=rev</a><br></blockquote><blockquote type="cite">Log:<br></blockquote><blockquote type="cite">Break anti-dependence breaking out into its own class.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Added:<br></blockquote><blockquote type="cite">   llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h<br></blockquote><blockquote type="cite">   llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp<br></blockquote><blockquote type="cite">   llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h<br></blockquote><blockquote type="cite">Modified:<br></blockquote><blockquote type="cite">   llvm/trunk/lib/CodeGen/CMakeLists.txt<br></blockquote><blockquote type="cite">   llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp<br></blockquote><blockquote type="cite">   llvm/trunk/lib/Target/ARM/ARMSubtarget.h<br></blockquote><blockquote type="cite">   llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Added: llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h?rev=85127&view=auto</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h (added)<br></blockquote><blockquote type="cite">+++ llvm/trunk/include/llvm/CodeGen/AntiDepBreaker.h Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">@@ -0,0 +1,56 @@<br></blockquote><blockquote type="cite">+//=- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-=//<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//                     The LLVM Compiler Infrastructure<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+// This file is distributed under the University of Illinois Open Source<br></blockquote><blockquote type="cite">+// License. See LICENSE.TXT for details.<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//===----------------------------------------------------------------------===//<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+// This file implements the AntiDepBreaker class, which implements<br></blockquote><blockquote type="cite">+// anti-dependence breaking heuristics for post-register-allocation scheduling.<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//===----------------------------------------------------------------------===//<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H<br></blockquote><blockquote type="cite">+#define LLVM_CODEGEN_ANTIDEPBREAKER_H<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineBasicBlock.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineFrameInfo.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineFunction.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineRegisterInfo.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/ScheduleDAG.h"<br></blockquote><blockquote type="cite">+#include "llvm/Target/TargetRegisterInfo.h"<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+namespace llvm {<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+/// AntiDepBreaker - This class works into conjunction with the<br></blockquote><blockquote type="cite">+/// post-RA scheduler to rename registers to break register<br></blockquote><blockquote type="cite">+/// anti-dependencies.<br></blockquote><blockquote type="cite">+class AntiDepBreaker {<br></blockquote><blockquote type="cite">+public:<br></blockquote><blockquote type="cite">+  /// Start - Initialize anti-dep breaking for a new basic block.<br></blockquote><blockquote type="cite">+  virtual void StartBlock(MachineBasicBlock *BB) =0;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// BreakAntiDependencies - Identifiy anti-dependencies within a<br></blockquote><blockquote type="cite">+  /// basic-block region and break them by renaming registers. Return<br></blockquote><blockquote type="cite">+  /// the number of anti-dependencies broken.<br></blockquote><blockquote type="cite">+  ///<br></blockquote><blockquote type="cite">+  virtual unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,<br></blockquote><blockquote type="cite">+                                         MachineBasicBlock::iterator& Begin,<br></blockquote><blockquote type="cite">+                                         MachineBasicBlock::iterator& End,<br></blockquote><blockquote type="cite">+                                         unsigned InsertPosIndex) =0;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// Observe - Update liveness information to account for the current<br></blockquote><blockquote type="cite">+  /// instruction, which will not be scheduled.<br></blockquote><blockquote type="cite">+  ///<br></blockquote><blockquote type="cite">+  virtual void Observe(MachineInstr *MI, unsigned Count,<br></blockquote><blockquote type="cite">+                       unsigned InsertPosIndex) =0;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// Finish - Finish anti-dep breaking for a basic block.<br></blockquote><blockquote type="cite">+  virtual void FinishBlock() =0;<br></blockquote><blockquote type="cite">+};<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#endif<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: llvm/trunk/lib/CodeGen/CMakeLists.txt<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CMakeLists.txt?rev=85127&r1=85126&r2=85127&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- llvm/trunk/lib/CodeGen/CMakeLists.txt (original)<br></blockquote><blockquote type="cite">+++ llvm/trunk/lib/CodeGen/CMakeLists.txt Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">@@ -1,6 +1,7 @@<br></blockquote><blockquote type="cite"> add_llvm_library(LLVMCodeGen<br></blockquote><blockquote type="cite">  BranchFolding.cpp<br></blockquote><blockquote type="cite">  CodePlacementOpt.cpp<br></blockquote><blockquote type="cite">+  CriticalAntiDepBreaker.cpp<br></blockquote><blockquote type="cite">  DeadMachineInstructionElim.cpp<br></blockquote><blockquote type="cite">  DwarfEHPrepare.cpp<br></blockquote><blockquote type="cite">  ELFCodeEmitter.cpp<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp?rev=85127&view=auto</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp (added)<br></blockquote><blockquote type="cite">+++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.cpp Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">@@ -0,0 +1,539 @@<br></blockquote><blockquote type="cite">+//===----- CriticalAntiDepBreaker.cpp - Anti-dep breaker -------- ---------===//<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//                     The LLVM Compiler Infrastructure<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+// This file is distributed under the University of Illinois Open Source<br></blockquote><blockquote type="cite">+// License. See LICENSE.TXT for details.<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//===----------------------------------------------------------------------===//<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+// This file implements the CriticalAntiDepBreaker class, which<br></blockquote><blockquote type="cite">+// implements register anti-dependence breaking along a blocks<br></blockquote><blockquote type="cite">+// critical path during post-RA scheduler.<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//===----------------------------------------------------------------------===//<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#define DEBUG_TYPE "critical-antidep"<br></blockquote><blockquote type="cite">+#include "CriticalAntiDepBreaker.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineBasicBlock.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineFrameInfo.h"<br></blockquote><blockquote type="cite">+#include "llvm/Target/TargetMachine.h"<br></blockquote><blockquote type="cite">+#include "llvm/Target/TargetRegisterInfo.h"<br></blockquote><blockquote type="cite">+#include "llvm/Support/Debug.h"<br></blockquote><blockquote type="cite">+#include "llvm/Support/ErrorHandling.h"<br></blockquote><blockquote type="cite">+#include "llvm/Support/raw_ostream.h"<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+using namespace llvm;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+CriticalAntiDepBreaker::<br></blockquote><blockquote type="cite">+CriticalAntiDepBreaker(MachineFunction& MFi) :<br></blockquote><blockquote type="cite">+  AntiDepBreaker(), MF(MFi),<br></blockquote><blockquote type="cite">+  MRI(MF.getRegInfo()),<br></blockquote><blockquote type="cite">+  TRI(MF.getTarget().getRegisterInfo()),<br></blockquote><blockquote type="cite">+  AllocatableSet(TRI->getAllocatableSet(MF))<br></blockquote><blockquote type="cite">+{<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+CriticalAntiDepBreaker::~CriticalAntiDepBreaker() {<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {<br></blockquote><blockquote type="cite">+  // Clear out the register class data.<br></blockquote><blockquote type="cite">+  std::fill(Classes, array_endof(Classes),<br></blockquote><blockquote type="cite">+            static_cast<const TargetRegisterClass *>(0));<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Initialize the indices to indicate that no registers are live.<br></blockquote><blockquote type="cite">+  std::fill(KillIndices, array_endof(KillIndices), ~0u);<br></blockquote><blockquote type="cite">+  std::fill(DefIndices, array_endof(DefIndices), BB->size());<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Clear "do not change" set.<br></blockquote><blockquote type="cite">+  KeepRegs.clear();<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn());<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Determine the live-out physregs for this block.<br></blockquote><blockquote type="cite">+  if (IsReturnBlock) {<br></blockquote><blockquote type="cite">+    // In a return block, examine the function live-out regs.<br></blockquote><blockquote type="cite">+    for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(),<br></blockquote><blockquote type="cite">+         E = MRI.liveout_end(); I != E; ++I) {<br></blockquote><blockquote type="cite">+      unsigned Reg = *I;<br></blockquote><blockquote type="cite">+      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+      KillIndices[Reg] = BB->size();<br></blockquote><blockquote type="cite">+      DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">+      // Repeat, for all aliases.<br></blockquote><blockquote type="cite">+      for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">+        unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">+        Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+        KillIndices[AliasReg] = BB->size();<br></blockquote><blockquote type="cite">+        DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+  } else {<br></blockquote><blockquote type="cite">+    // In a non-return block, examine the live-in regs of all successors.<br></blockquote><blockquote type="cite">+    for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),<br></blockquote><blockquote type="cite">+         SE = BB->succ_end(); SI != SE; ++SI)<br></blockquote><blockquote type="cite">+      for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(),<br></blockquote><blockquote type="cite">+           E = (*SI)->livein_end(); I != E; ++I) {<br></blockquote><blockquote type="cite">+        unsigned Reg = *I;<br></blockquote><blockquote type="cite">+        Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+        KillIndices[Reg] = BB->size();<br></blockquote><blockquote type="cite">+        DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">+        // Repeat, for all aliases.<br></blockquote><blockquote type="cite">+        for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">+          unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">+          Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+          KillIndices[AliasReg] = BB->size();<br></blockquote><blockquote type="cite">+          DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">+        }<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Mark live-out callee-saved registers. In a return block this is<br></blockquote><blockquote type="cite">+  // all callee-saved registers. In non-return this is any<br></blockquote><blockquote type="cite">+  // callee-saved register that is not saved in the prolog.<br></blockquote><blockquote type="cite">+  const MachineFrameInfo *MFI = MF.getFrameInfo();<br></blockquote><blockquote type="cite">+  BitVector Pristine = MFI->getPristineRegs(BB);<br></blockquote><blockquote type="cite">+  for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) {<br></blockquote><blockquote type="cite">+    unsigned Reg = *I;<br></blockquote><blockquote type="cite">+    if (!IsReturnBlock && !Pristine.test(Reg)) continue;<br></blockquote><blockquote type="cite">+    Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+    KillIndices[Reg] = BB->size();<br></blockquote><blockquote type="cite">+    DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">+    // Repeat, for all aliases.<br></blockquote><blockquote type="cite">+    for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">+      unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">+      Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+      KillIndices[AliasReg] = BB->size();<br></blockquote><blockquote type="cite">+      DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+void CriticalAntiDepBreaker::FinishBlock() {<br></blockquote><blockquote type="cite">+  RegRefs.clear();<br></blockquote><blockquote type="cite">+  KeepRegs.clear();<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+void CriticalAntiDepBreaker::Observe(MachineInstr *MI, unsigned Count,<br></blockquote><blockquote type="cite">+                                     unsigned InsertPosIndex) {<br></blockquote><blockquote type="cite">+  assert(Count < InsertPosIndex && "Instruction index out of expected range!");<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Any register which was defined within the previous scheduling region<br></blockquote><blockquote type="cite">+  // may have been rescheduled and its lifetime may overlap with registers<br></blockquote><blockquote type="cite">+  // in ways not reflected in our current liveness state. For each such<br></blockquote><blockquote type="cite">+  // register, adjust the liveness state to be conservatively correct.<br></blockquote><blockquote type="cite">+  for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg)<br></blockquote><blockquote type="cite">+    if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) {<br></blockquote><blockquote type="cite">+      assert(KillIndices[Reg] == ~0u && "Clobbered register is live!");<br></blockquote><blockquote type="cite">+      // Mark this register to be non-renamable.<br></blockquote><blockquote type="cite">+      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+      // Move the def index to the end of the previous region, to reflect<br></blockquote><blockquote type="cite">+      // that the def could theoretically have been scheduled at the end.<br></blockquote><blockquote type="cite">+      DefIndices[Reg] = InsertPosIndex;<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  PrescanInstruction(MI);<br></blockquote><blockquote type="cite">+  ScanInstruction(MI, Count);<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+/// CriticalPathStep - Return the next SUnit after SU on the bottom-up<br></blockquote><blockquote type="cite">+/// critical path.<br></blockquote><blockquote type="cite">+static SDep *CriticalPathStep(SUnit *SU) {<br></blockquote><blockquote type="cite">+  SDep *Next = 0;<br></blockquote><blockquote type="cite">+  unsigned NextDepth = 0;<br></blockquote><blockquote type="cite">+  // Find the predecessor edge with the greatest depth.<br></blockquote><blockquote type="cite">+  for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end();<br></blockquote><blockquote type="cite">+       P != PE; ++P) {<br></blockquote><blockquote type="cite">+    SUnit *PredSU = P->getSUnit();<br></blockquote><blockquote type="cite">+    unsigned PredLatency = P->getLatency();<br></blockquote><blockquote type="cite">+    unsigned PredTotalLatency = PredSU->getDepth() + PredLatency;<br></blockquote><blockquote type="cite">+    // In the case of a latency tie, prefer an anti-dependency edge over<br></blockquote><blockquote type="cite">+    // other types of edges.<br></blockquote><blockquote type="cite">+    if (NextDepth < PredTotalLatency ||<br></blockquote><blockquote type="cite">+        (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) {<br></blockquote><blockquote type="cite">+      NextDepth = PredTotalLatency;<br></blockquote><blockquote type="cite">+      Next = &*P;<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+  return Next;<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr *MI) {<br></blockquote><blockquote type="cite">+  // Scan the register operands for this instruction and update<br></blockquote><blockquote type="cite">+  // Classes and RegRefs.<br></blockquote><blockquote type="cite">+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">+    MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">+    if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">+    unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">+    if (Reg == 0) continue;<br></blockquote><blockquote type="cite">+    const TargetRegisterClass *NewRC = 0;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    if (i < MI->getDesc().getNumOperands())<br></blockquote><blockquote type="cite">+      NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // For now, only allow the register to be changed if its register<br></blockquote><blockquote type="cite">+    // class is consistent across all uses.<br></blockquote><blockquote type="cite">+    if (!Classes[Reg] && NewRC)<br></blockquote><blockquote type="cite">+      Classes[Reg] = NewRC;<br></blockquote><blockquote type="cite">+    else if (!NewRC || Classes[Reg] != NewRC)<br></blockquote><blockquote type="cite">+      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // Now check for aliases.<br></blockquote><blockquote type="cite">+    for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">+      // If an alias of the reg is used during the live range, give up.<br></blockquote><blockquote type="cite">+      // Note that this allows us to skip checking if AntiDepReg<br></blockquote><blockquote type="cite">+      // overlaps with any of the aliases, among other things.<br></blockquote><blockquote type="cite">+      unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">+      if (Classes[AliasReg]) {<br></blockquote><blockquote type="cite">+        Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+        Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // If we're still willing to consider this register, note the reference.<br></blockquote><blockquote type="cite">+    if (Classes[Reg] != reinterpret_cast<TargetRegisterClass *>(-1))<br></blockquote><blockquote type="cite">+      RegRefs.insert(std::make_pair(Reg, &MO));<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // It's not safe to change register allocation for source operands of<br></blockquote><blockquote type="cite">+    // that have special allocation requirements.<br></blockquote><blockquote type="cite">+    if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) {<br></blockquote><blockquote type="cite">+      if (KeepRegs.insert(Reg)) {<br></blockquote><blockquote type="cite">+        for (const unsigned *Subreg = TRI->getSubRegisters(Reg);<br></blockquote><blockquote type="cite">+             *Subreg; ++Subreg)<br></blockquote><blockquote type="cite">+          KeepRegs.insert(*Subreg);<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+void CriticalAntiDepBreaker::ScanInstruction(MachineInstr *MI,<br></blockquote><blockquote type="cite">+                                             unsigned Count) {<br></blockquote><blockquote type="cite">+  // Update liveness.<br></blockquote><blockquote type="cite">+  // Proceding upwards, registers that are defed but not used in this<br></blockquote><blockquote type="cite">+  // instruction are now dead.<br></blockquote><blockquote type="cite">+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">+    MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">+    if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">+    unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">+    if (Reg == 0) continue;<br></blockquote><blockquote type="cite">+    if (!MO.isDef()) continue;<br></blockquote><blockquote type="cite">+    // Ignore two-addr defs.<br></blockquote><blockquote type="cite">+    if (MI->isRegTiedToUseOperand(i)) continue;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    DefIndices[Reg] = Count;<br></blockquote><blockquote type="cite">+    KillIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">+    assert(((KillIndices[Reg] == ~0u) !=<br></blockquote><blockquote type="cite">+            (DefIndices[Reg] == ~0u)) &&<br></blockquote><blockquote type="cite">+           "Kill and Def maps aren't consistent for Reg!");<br></blockquote><blockquote type="cite">+    KeepRegs.erase(Reg);<br></blockquote><blockquote type="cite">+    Classes[Reg] = 0;<br></blockquote><blockquote type="cite">+    RegRefs.erase(Reg);<br></blockquote><blockquote type="cite">+    // Repeat, for all subregs.<br></blockquote><blockquote type="cite">+    for (const unsigned *Subreg = TRI->getSubRegisters(Reg);<br></blockquote><blockquote type="cite">+         *Subreg; ++Subreg) {<br></blockquote><blockquote type="cite">+      unsigned SubregReg = *Subreg;<br></blockquote><blockquote type="cite">+      DefIndices[SubregReg] = Count;<br></blockquote><blockquote type="cite">+      KillIndices[SubregReg] = ~0u;<br></blockquote><blockquote type="cite">+      KeepRegs.erase(SubregReg);<br></blockquote><blockquote type="cite">+      Classes[SubregReg] = 0;<br></blockquote><blockquote type="cite">+      RegRefs.erase(SubregReg);<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+    // Conservatively mark super-registers as unusable.<br></blockquote><blockquote type="cite">+    for (const unsigned *Super = TRI->getSuperRegisters(Reg);<br></blockquote><blockquote type="cite">+         *Super; ++Super) {<br></blockquote><blockquote type="cite">+      unsigned SuperReg = *Super;<br></blockquote><blockquote type="cite">+      Classes[SuperReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">+    MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">+    if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">+    unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">+    if (Reg == 0) continue;<br></blockquote><blockquote type="cite">+    if (!MO.isUse()) continue;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    const TargetRegisterClass *NewRC = 0;<br></blockquote><blockquote type="cite">+    if (i < MI->getDesc().getNumOperands())<br></blockquote><blockquote type="cite">+      NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // For now, only allow the register to be changed if its register<br></blockquote><blockquote type="cite">+    // class is consistent across all uses.<br></blockquote><blockquote type="cite">+    if (!Classes[Reg] && NewRC)<br></blockquote><blockquote type="cite">+      Classes[Reg] = NewRC;<br></blockquote><blockquote type="cite">+    else if (!NewRC || Classes[Reg] != NewRC)<br></blockquote><blockquote type="cite">+      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    RegRefs.insert(std::make_pair(Reg, &MO));<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // It wasn't previously live but now it is, this is a kill.<br></blockquote><blockquote type="cite">+    if (KillIndices[Reg] == ~0u) {<br></blockquote><blockquote type="cite">+      KillIndices[Reg] = Count;<br></blockquote><blockquote type="cite">+      DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">+          assert(((KillIndices[Reg] == ~0u) !=<br></blockquote><blockquote type="cite">+                  (DefIndices[Reg] == ~0u)) &&<br></blockquote><blockquote type="cite">+               "Kill and Def maps aren't consistent for Reg!");<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+    // Repeat, for all aliases.<br></blockquote><blockquote type="cite">+    for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">+      unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">+      if (KillIndices[AliasReg] == ~0u) {<br></blockquote><blockquote type="cite">+        KillIndices[AliasReg] = Count;<br></blockquote><blockquote type="cite">+        DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+unsigned<br></blockquote><blockquote type="cite">+CriticalAntiDepBreaker::findSuitableFreeRegister(unsigned AntiDepReg,<br></blockquote><blockquote type="cite">+                                                 unsigned LastNewReg,<br></blockquote><blockquote type="cite">+                                                 const TargetRegisterClass *RC) {<br></blockquote><blockquote type="cite">+  for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF),<br></blockquote><blockquote type="cite">+       RE = RC->allocation_order_end(MF); R != RE; ++R) {<br></blockquote><blockquote type="cite">+    unsigned NewReg = *R;<br></blockquote><blockquote type="cite">+    // Don't replace a register with itself.<br></blockquote><blockquote type="cite">+    if (NewReg == AntiDepReg) continue;<br></blockquote><blockquote type="cite">+    // Don't replace a register with one that was recently used to repair<br></blockquote><blockquote type="cite">+    // an anti-dependence with this AntiDepReg, because that would<br></blockquote><blockquote type="cite">+    // re-introduce that anti-dependence.<br></blockquote><blockquote type="cite">+    if (NewReg == LastNewReg) continue;<br></blockquote><blockquote type="cite">+    // If NewReg is dead and NewReg's most recent def is not before<br></blockquote><blockquote type="cite">+    // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg.<br></blockquote><blockquote type="cite">+    assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) &&<br></blockquote><blockquote type="cite">+           "Kill and Def maps aren't consistent for AntiDepReg!");<br></blockquote><blockquote type="cite">+    assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) &&<br></blockquote><blockquote type="cite">+           "Kill and Def maps aren't consistent for NewReg!");<br></blockquote><blockquote type="cite">+    if (KillIndices[NewReg] != ~0u ||<br></blockquote><blockquote type="cite">+        Classes[NewReg] == reinterpret_cast<TargetRegisterClass *>(-1) ||<br></blockquote><blockquote type="cite">+        KillIndices[AntiDepReg] > DefIndices[NewReg])<br></blockquote><blockquote type="cite">+      continue;<br></blockquote><blockquote type="cite">+    return NewReg;<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // No registers are free and available!<br></blockquote><blockquote type="cite">+  return 0;<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+unsigned CriticalAntiDepBreaker::<br></blockquote><blockquote type="cite">+BreakAntiDependencies(std::vector<SUnit>& SUnits,<br></blockquote><blockquote type="cite">+                      MachineBasicBlock::iterator& Begin,<br></blockquote><blockquote type="cite">+                      MachineBasicBlock::iterator& End,<br></blockquote><blockquote type="cite">+                      unsigned InsertPosIndex) {<br></blockquote><blockquote type="cite">+  // The code below assumes that there is at least one instruction,<br></blockquote><blockquote type="cite">+  // so just duck out immediately if the block is empty.<br></blockquote><blockquote type="cite">+  if (SUnits.empty()) return 0;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Find the node at the bottom of the critical path.<br></blockquote><blockquote type="cite">+  SUnit *Max = 0;<br></blockquote><blockquote type="cite">+  for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {<br></blockquote><blockquote type="cite">+    SUnit *SU = &SUnits[i];<br></blockquote><blockquote type="cite">+    if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency)<br></blockquote><blockquote type="cite">+      Max = SU;<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#ifndef NDEBUG<br></blockquote><blockquote type="cite">+  {<br></blockquote><blockquote type="cite">+    DEBUG(errs() << "Critical path has total latency "<br></blockquote><blockquote type="cite">+          << (Max->getDepth() + Max->Latency) << "\n");<br></blockquote><blockquote type="cite">+    DEBUG(errs() << "Available regs:");<br></blockquote><blockquote type="cite">+    for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) {<br></blockquote><blockquote type="cite">+      if (KillIndices[Reg] == ~0u)<br></blockquote><blockquote type="cite">+        DEBUG(errs() << " " << TRI->getName(Reg));<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+    DEBUG(errs() << '\n');<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+#endif<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Track progress along the critical path through the SUnit graph as we walk<br></blockquote><blockquote type="cite">+  // the instructions.<br></blockquote><blockquote type="cite">+  SUnit *CriticalPathSU = Max;<br></blockquote><blockquote type="cite">+  MachineInstr *CriticalPathMI = CriticalPathSU->getInstr();<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Consider this pattern:<br></blockquote><blockquote type="cite">+  //   A = ...<br></blockquote><blockquote type="cite">+  //   ... = A<br></blockquote><blockquote type="cite">+  //   A = ...<br></blockquote><blockquote type="cite">+  //   ... = A<br></blockquote><blockquote type="cite">+  //   A = ...<br></blockquote><blockquote type="cite">+  //   ... = A<br></blockquote><blockquote type="cite">+  //   A = ...<br></blockquote><blockquote type="cite">+  //   ... = A<br></blockquote><blockquote type="cite">+  // There are three anti-dependencies here, and without special care,<br></blockquote><blockquote type="cite">+  // we'd break all of them using the same register:<br></blockquote><blockquote type="cite">+  //   A = ...<br></blockquote><blockquote type="cite">+  //   ... = A<br></blockquote><blockquote type="cite">+  //   B = ...<br></blockquote><blockquote type="cite">+  //   ... = B<br></blockquote><blockquote type="cite">+  //   B = ...<br></blockquote><blockquote type="cite">+  //   ... = B<br></blockquote><blockquote type="cite">+  //   B = ...<br></blockquote><blockquote type="cite">+  //   ... = B<br></blockquote><blockquote type="cite">+  // because at each anti-dependence, B is the first register that<br></blockquote><blockquote type="cite">+  // isn't A which is free.  This re-introduces anti-dependencies<br></blockquote><blockquote type="cite">+  // at all but one of the original anti-dependencies that we were<br></blockquote><blockquote type="cite">+  // trying to break.  To avoid this, keep track of the most recent<br></blockquote><blockquote type="cite">+  // register that each register was replaced with, avoid<br></blockquote><blockquote type="cite">+  // using it to repair an anti-dependence on the same register.<br></blockquote><blockquote type="cite">+  // This lets us produce this:<br></blockquote><blockquote type="cite">+  //   A = ...<br></blockquote><blockquote type="cite">+  //   ... = A<br></blockquote><blockquote type="cite">+  //   B = ...<br></blockquote><blockquote type="cite">+  //   ... = B<br></blockquote><blockquote type="cite">+  //   C = ...<br></blockquote><blockquote type="cite">+  //   ... = C<br></blockquote><blockquote type="cite">+  //   B = ...<br></blockquote><blockquote type="cite">+  //   ... = B<br></blockquote><blockquote type="cite">+  // This still has an anti-dependence on B, but at least it isn't on the<br></blockquote><blockquote type="cite">+  // original critical path.<br></blockquote><blockquote type="cite">+  //<br></blockquote><blockquote type="cite">+  // TODO: If we tracked more than one register here, we could potentially<br></blockquote><blockquote type="cite">+  // fix that remaining critical edge too. This is a little more involved,<br></blockquote><blockquote type="cite">+  // because unlike the most recent register, less recent registers should<br></blockquote><blockquote type="cite">+  // still be considered, though only if no other registers are available.<br></blockquote><blockquote type="cite">+  unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {};<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  // Attempt to break anti-dependence edges on the critical path. Walk the<br></blockquote><blockquote type="cite">+  // instructions from the bottom up, tracking information about liveness<br></blockquote><blockquote type="cite">+  // as we go to help determine which registers are available.<br></blockquote><blockquote type="cite">+  unsigned Broken = 0;<br></blockquote><blockquote type="cite">+  unsigned Count = InsertPosIndex - 1;<br></blockquote><blockquote type="cite">+  for (MachineBasicBlock::iterator I = End, E = Begin;<br></blockquote><blockquote type="cite">+       I != E; --Count) {<br></blockquote><blockquote type="cite">+    MachineInstr *MI = --I;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // Check if this instruction has a dependence on the critical path that<br></blockquote><blockquote type="cite">+    // is an anti-dependence that we may be able to break. If it is, set<br></blockquote><blockquote type="cite">+    // AntiDepReg to the non-zero register associated with the anti-dependence.<br></blockquote><blockquote type="cite">+    //<br></blockquote><blockquote type="cite">+    // We limit our attention to the critical path as a heuristic to avoid<br></blockquote><blockquote type="cite">+    // breaking anti-dependence edges that aren't going to significantly<br></blockquote><blockquote type="cite">+    // impact the overall schedule. There are a limited number of registers<br></blockquote><blockquote type="cite">+    // and we want to save them for the important edges.<br></blockquote><blockquote type="cite">+    //<br></blockquote><blockquote type="cite">+    // TODO: Instructions with multiple defs could have multiple<br></blockquote><blockquote type="cite">+    // anti-dependencies. The current code here only knows how to break one<br></blockquote><blockquote type="cite">+    // edge per instruction. Note that we'd have to be able to break all of<br></blockquote><blockquote type="cite">+    // the anti-dependencies in an instruction in order to be effective.<br></blockquote><blockquote type="cite">+    unsigned AntiDepReg = 0;<br></blockquote><blockquote type="cite">+    if (MI == CriticalPathMI) {<br></blockquote><blockquote type="cite">+      if (SDep *Edge = CriticalPathStep(CriticalPathSU)) {<br></blockquote><blockquote type="cite">+        SUnit *NextSU = Edge->getSUnit();<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+        // Only consider anti-dependence edges.<br></blockquote><blockquote type="cite">+        if (Edge->getKind() == SDep::Anti) {<br></blockquote><blockquote type="cite">+          AntiDepReg = Edge->getReg();<br></blockquote><blockquote type="cite">+          assert(AntiDepReg != 0 && "Anti-dependence on reg0?");<br></blockquote><blockquote type="cite">+          if (!AllocatableSet.test(AntiDepReg))<br></blockquote><blockquote type="cite">+            // Don't break anti-dependencies on non-allocatable registers.<br></blockquote><blockquote type="cite">+            AntiDepReg = 0;<br></blockquote><blockquote type="cite">+          else if (KeepRegs.count(AntiDepReg))<br></blockquote><blockquote type="cite">+            // Don't break anti-dependencies if an use down below requires<br></blockquote><blockquote type="cite">+            // this exact register.<br></blockquote><blockquote type="cite">+            AntiDepReg = 0;<br></blockquote><blockquote type="cite">+          else {<br></blockquote><blockquote type="cite">+            // If the SUnit has other dependencies on the SUnit that it<br></blockquote><blockquote type="cite">+            // anti-depends on, don't bother breaking the anti-dependency<br></blockquote><blockquote type="cite">+            // since those edges would prevent such units from being<br></blockquote><blockquote type="cite">+            // scheduled past each other regardless.<br></blockquote><blockquote type="cite">+            //<br></blockquote><blockquote type="cite">+            // Also, if there are dependencies on other SUnits with the<br></blockquote><blockquote type="cite">+            // same register as the anti-dependency, don't attempt to<br></blockquote><blockquote type="cite">+            // break it.<br></blockquote><blockquote type="cite">+            for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(),<br></blockquote><blockquote type="cite">+                 PE = CriticalPathSU->Preds.end(); P != PE; ++P)<br></blockquote><blockquote type="cite">+              if (P->getSUnit() == NextSU ?<br></blockquote><blockquote type="cite">+                    (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) :<br></blockquote><blockquote type="cite">+                    (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) {<br></blockquote><blockquote type="cite">+                AntiDepReg = 0;<br></blockquote><blockquote type="cite">+                break;<br></blockquote><blockquote type="cite">+              }<br></blockquote><blockquote type="cite">+          }<br></blockquote><blockquote type="cite">+        }<br></blockquote><blockquote type="cite">+        CriticalPathSU = NextSU;<br></blockquote><blockquote type="cite">+        CriticalPathMI = CriticalPathSU->getInstr();<br></blockquote><blockquote type="cite">+      } else {<br></blockquote><blockquote type="cite">+        // We've reached the end of the critical path.<br></blockquote><blockquote type="cite">+        CriticalPathSU = 0;<br></blockquote><blockquote type="cite">+        CriticalPathMI = 0;<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    PrescanInstruction(MI);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    if (MI->getDesc().hasExtraDefRegAllocReq())<br></blockquote><blockquote type="cite">+      // If this instruction's defs have special allocation requirement, don't<br></blockquote><blockquote type="cite">+      // break this anti-dependency.<br></blockquote><blockquote type="cite">+      AntiDepReg = 0;<br></blockquote><blockquote type="cite">+    else if (AntiDepReg) {<br></blockquote><blockquote type="cite">+      // If this instruction has a use of AntiDepReg, breaking it<br></blockquote><blockquote type="cite">+      // is invalid.<br></blockquote><blockquote type="cite">+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">+        MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">+        if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">+        unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">+        if (Reg == 0) continue;<br></blockquote><blockquote type="cite">+        if (MO.isUse() && AntiDepReg == Reg) {<br></blockquote><blockquote type="cite">+          AntiDepReg = 0;<br></blockquote><blockquote type="cite">+          break;<br></blockquote><blockquote type="cite">+        }<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // Determine AntiDepReg's register class, if it is live and is<br></blockquote><blockquote type="cite">+    // consistently used within a single class.<br></blockquote><blockquote type="cite">+    const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0;<br></blockquote><blockquote type="cite">+    assert((AntiDepReg == 0 || RC != NULL) &&<br></blockquote><blockquote type="cite">+           "Register should be live if it's causing an anti-dependence!");<br></blockquote><blockquote type="cite">+    if (RC == reinterpret_cast<TargetRegisterClass *>(-1))<br></blockquote><blockquote type="cite">+      AntiDepReg = 0;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    // Look for a suitable register to use to break the anti-depenence.<br></blockquote><blockquote type="cite">+    //<br></blockquote><blockquote type="cite">+    // TODO: Instead of picking the first free register, consider which might<br></blockquote><blockquote type="cite">+    // be the best.<br></blockquote><blockquote type="cite">+    if (AntiDepReg != 0) {<br></blockquote><blockquote type="cite">+      if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg,<br></blockquote><blockquote type="cite">+                                                     LastNewReg[AntiDepReg],<br></blockquote><blockquote type="cite">+                                                     RC)) {<br></blockquote><blockquote type="cite">+        DEBUG(errs() << "Breaking anti-dependence edge on "<br></blockquote><blockquote type="cite">+              << TRI->getName(AntiDepReg)<br></blockquote><blockquote type="cite">+              << " with " << RegRefs.count(AntiDepReg) << " references"<br></blockquote><blockquote type="cite">+              << " using " << TRI->getName(NewReg) << "!\n");<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+        // Update the references to the old register to refer to the new<br></blockquote><blockquote type="cite">+        // register.<br></blockquote><blockquote type="cite">+        std::pair<std::multimap<unsigned, MachineOperand *>::iterator,<br></blockquote><blockquote type="cite">+                  std::multimap<unsigned, MachineOperand *>::iterator><br></blockquote><blockquote type="cite">+           Range = RegRefs.equal_range(AntiDepReg);<br></blockquote><blockquote type="cite">+        for (std::multimap<unsigned, MachineOperand *>::iterator<br></blockquote><blockquote type="cite">+             Q = Range.first, QE = Range.second; Q != QE; ++Q)<br></blockquote><blockquote type="cite">+          Q->second->setReg(NewReg);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+        // We just went back in time and modified history; the<br></blockquote><blockquote type="cite">+        // liveness information for the anti-depenence reg is now<br></blockquote><blockquote type="cite">+        // inconsistent. Set the state as if it were dead.<br></blockquote><blockquote type="cite">+        Classes[NewReg] = Classes[AntiDepReg];<br></blockquote><blockquote type="cite">+        DefIndices[NewReg] = DefIndices[AntiDepReg];<br></blockquote><blockquote type="cite">+        KillIndices[NewReg] = KillIndices[AntiDepReg];<br></blockquote><blockquote type="cite">+        assert(((KillIndices[NewReg] == ~0u) !=<br></blockquote><blockquote type="cite">+                (DefIndices[NewReg] == ~0u)) &&<br></blockquote><blockquote type="cite">+             "Kill and Def maps aren't consistent for NewReg!");<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+        Classes[AntiDepReg] = 0;<br></blockquote><blockquote type="cite">+        DefIndices[AntiDepReg] = KillIndices[AntiDepReg];<br></blockquote><blockquote type="cite">+        KillIndices[AntiDepReg] = ~0u;<br></blockquote><blockquote type="cite">+        assert(((KillIndices[AntiDepReg] == ~0u) !=<br></blockquote><blockquote type="cite">+                (DefIndices[AntiDepReg] == ~0u)) &&<br></blockquote><blockquote type="cite">+             "Kill and Def maps aren't consistent for AntiDepReg!");<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+        RegRefs.erase(AntiDepReg);<br></blockquote><blockquote type="cite">+        LastNewReg[AntiDepReg] = NewReg;<br></blockquote><blockquote type="cite">+        ++Broken;<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    ScanInstruction(MI, Count);<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  return Broken;<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Added: llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h?rev=85127&view=auto</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h (added)<br></blockquote><blockquote type="cite">+++ llvm/trunk/lib/CodeGen/CriticalAntiDepBreaker.h Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">@@ -0,0 +1,95 @@<br></blockquote><blockquote type="cite">+//=- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-=//<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//                     The LLVM Compiler Infrastructure<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+// This file is distributed under the University of Illinois Open Source<br></blockquote><blockquote type="cite">+// License. See LICENSE.TXT for details.<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//===----------------------------------------------------------------------===//<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+// This file implements the CriticalAntiDepBreaker class, which<br></blockquote><blockquote type="cite">+// implements register anti-dependence breaking along a blocks<br></blockquote><blockquote type="cite">+// critical path during post-RA scheduler.<br></blockquote><blockquote type="cite">+//<br></blockquote><blockquote type="cite">+//===----------------------------------------------------------------------===//<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#ifndef LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H<br></blockquote><blockquote type="cite">+#define LLVM_CODEGEN_CRITICALANTIDEPBREAKER_H<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/AntiDepBreaker.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineBasicBlock.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineFrameInfo.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineFunction.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/MachineRegisterInfo.h"<br></blockquote><blockquote type="cite">+#include "llvm/CodeGen/ScheduleDAG.h"<br></blockquote><blockquote type="cite">+#include "llvm/Target/TargetRegisterInfo.h"<br></blockquote><blockquote type="cite">+#include "llvm/ADT/BitVector.h"<br></blockquote><blockquote type="cite">+#include "llvm/ADT/SmallSet.h"<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+namespace llvm {<br></blockquote><blockquote type="cite">+  class CriticalAntiDepBreaker : public AntiDepBreaker {<br></blockquote><blockquote type="cite">+    MachineFunction& MF;<br></blockquote><blockquote type="cite">+    MachineRegisterInfo &MRI;<br></blockquote><blockquote type="cite">+    const TargetRegisterInfo *TRI;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// AllocatableSet - The set of allocatable registers.<br></blockquote><blockquote type="cite">+    /// We'll be ignoring anti-dependencies on non-allocatable registers,<br></blockquote><blockquote type="cite">+    /// because they may not be safe to break.<br></blockquote><blockquote type="cite">+    const BitVector AllocatableSet;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// Classes - For live regs that are only used in one register class in a<br></blockquote><blockquote type="cite">+    /// live range, the register class. If the register is not live, the<br></blockquote><blockquote type="cite">+    /// corresponding value is null. If the register is live but used in<br></blockquote><blockquote type="cite">+    /// multiple register classes, the corresponding value is -1 casted to a<br></blockquote><blockquote type="cite">+    /// pointer.<br></blockquote><blockquote type="cite">+    const TargetRegisterClass *<br></blockquote><blockquote type="cite">+      Classes[TargetRegisterInfo::FirstVirtualRegister];<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// RegRegs - Map registers to all their references within a live range.<br></blockquote><blockquote type="cite">+    std::multimap<unsigned, MachineOperand *> RegRefs;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// KillIndices - The index of the most recent kill (proceding bottom-up),<br></blockquote><blockquote type="cite">+    /// or ~0u if the register is not live.<br></blockquote><blockquote type="cite">+    unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister];<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// DefIndices - The index of the most recent complete def (proceding bottom<br></blockquote><blockquote type="cite">+    /// up), or ~0u if the register is live.<br></blockquote><blockquote type="cite">+    unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister];<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// KeepRegs - A set of registers which are live and cannot be changed to<br></blockquote><blockquote type="cite">+    /// break anti-dependencies.<br></blockquote><blockquote type="cite">+    SmallSet<unsigned, 4> KeepRegs;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  public:<br></blockquote><blockquote type="cite">+    CriticalAntiDepBreaker(MachineFunction& MFi);<br></blockquote><blockquote type="cite">+    ~CriticalAntiDepBreaker();<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// Start - Initialize anti-dep breaking for a new basic block.<br></blockquote><blockquote type="cite">+    void StartBlock(MachineBasicBlock *BB);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// BreakAntiDependencies - Identifiy anti-dependencies along the critical path<br></blockquote><blockquote type="cite">+    /// of the ScheduleDAG and break them by renaming registers.<br></blockquote><blockquote type="cite">+    ///<br></blockquote><blockquote type="cite">+    unsigned BreakAntiDependencies(std::vector<SUnit>& SUnits,<br></blockquote><blockquote type="cite">+                                   MachineBasicBlock::iterator& Begin,<br></blockquote><blockquote type="cite">+                                   MachineBasicBlock::iterator& End,<br></blockquote><blockquote type="cite">+                                   unsigned InsertPosIndex);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// Observe - Update liveness information to account for the current<br></blockquote><blockquote type="cite">+    /// instruction, which will not be scheduled.<br></blockquote><blockquote type="cite">+    ///<br></blockquote><blockquote type="cite">+    void Observe(MachineInstr *MI, unsigned Count, unsigned InsertPosIndex);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    /// Finish - Finish anti-dep breaking for a basic block.<br></blockquote><blockquote type="cite">+    void FinishBlock();<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  private:<br></blockquote><blockquote type="cite">+    void PrescanInstruction(MachineInstr *MI);<br></blockquote><blockquote type="cite">+    void ScanInstruction(MachineInstr *MI, unsigned Count);<br></blockquote><blockquote type="cite">+    unsigned findSuitableFreeRegister(unsigned AntiDepReg,<br></blockquote><blockquote type="cite">+                                      unsigned LastNewReg,<br></blockquote><blockquote type="cite">+                                      const TargetRegisterClass *);<br></blockquote><blockquote type="cite">+  };<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+#endif<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=85127&r1=85126&r2=85127&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original)<br></blockquote><blockquote type="cite">+++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">@@ -19,6 +19,7 @@<br></blockquote><blockquote type="cite"> //===----------------------------------------------------------------------===//<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"> #define DEBUG_TYPE "post-RA-sched"<br></blockquote><blockquote type="cite">+#include "CriticalAntiDepBreaker.h"<br></blockquote><blockquote type="cite"> #include "ExactHazardRecognizer.h"<br></blockquote><blockquote type="cite"> #include "SimpleHazardRecognizer.h"<br></blockquote><blockquote type="cite"> #include "ScheduleDAGInstrs.h"<br></blockquote><blockquote type="cite">@@ -40,6 +41,7 @@<br></blockquote><blockquote type="cite"> #include "llvm/Support/Debug.h"<br></blockquote><blockquote type="cite"> #include "llvm/Support/ErrorHandling.h"<br></blockquote><blockquote type="cite"> #include "llvm/Support/raw_ostream.h"<br></blockquote><blockquote type="cite">+#include "llvm/ADT/BitVector.h"<br></blockquote><blockquote type="cite"> #include "llvm/ADT/Statistic.h"<br></blockquote><blockquote type="cite"> #include <map><br></blockquote><blockquote type="cite"> #include <set><br></blockquote><blockquote type="cite">@@ -47,6 +49,7 @@<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"> STATISTIC(NumNoops, "Number of noops inserted");<br></blockquote><blockquote type="cite"> STATISTIC(NumStalls, "Number of pipeline stalls");<br></blockquote><blockquote type="cite">+STATISTIC(NumFixedAnti, "Number of fixed anti-dependencies");<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"> // Post-RA scheduling is enabled with<br></blockquote><blockquote type="cite"> // TargetSubtarget.enablePostRAScheduler(). This flag can be used to<br></blockquote><blockquote type="cite">@@ -55,10 +58,11 @@<br></blockquote><blockquote type="cite"> EnablePostRAScheduler("post-RA-scheduler",<br></blockquote><blockquote type="cite">                       cl::desc("Enable scheduling after register allocation"),<br></blockquote><blockquote type="cite">                       cl::init(false), cl::Hidden);<br></blockquote><blockquote type="cite">-static cl::opt<bool><br></blockquote><blockquote type="cite">+static cl::opt<std::string><br></blockquote><blockquote type="cite"> EnableAntiDepBreaking("break-anti-dependencies",<br></blockquote><blockquote type="cite">-                      cl::desc("Break post-RA scheduling anti-dependencies"),<br></blockquote><blockquote type="cite">-                      cl::init(true), cl::Hidden);<br></blockquote><blockquote type="cite">+                      cl::desc("Break post-RA scheduling anti-dependencies: "<br></blockquote><blockquote type="cite">+                               "\"critical\", \"all\", or \"none\""),<br></blockquote><blockquote type="cite">+                      cl::init("none"), cl::Hidden);<br></blockquote><blockquote type="cite"> static cl::opt<bool><br></blockquote><blockquote type="cite"> EnablePostRAHazardAvoidance("avoid-hazards",<br></blockquote><blockquote type="cite">                      cl::desc("Enable exact hazard avoidance"),<br></blockquote><blockquote type="cite">@@ -116,56 +120,30 @@<br></blockquote><blockquote type="cite">    /// Topo - A topological ordering for SUnits.<br></blockquote><blockquote type="cite">    ScheduleDAGTopologicalSort Topo;<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-    /// AllocatableSet - The set of allocatable registers.<br></blockquote><blockquote type="cite">-    /// We'll be ignoring anti-dependencies on non-allocatable registers,<br></blockquote><blockquote type="cite">-    /// because they may not be safe to break.<br></blockquote><blockquote type="cite">-    const BitVector AllocatableSet;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">    /// HazardRec - The hazard recognizer to use.<br></blockquote><blockquote type="cite">    ScheduleHazardRecognizer *HazardRec;<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">+    /// AntiDepBreak - Anti-dependence breaking object, or NULL if none<br></blockquote><blockquote type="cite">+    AntiDepBreaker *AntiDepBreak;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">    /// AA - AliasAnalysis for making memory reference queries.<br></blockquote><blockquote type="cite">    AliasAnalysis *AA;<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-    /// AntiDepMode - Anti-dependence breaking mode<br></blockquote><blockquote type="cite">-    TargetSubtarget::AntiDepBreakMode AntiDepMode;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    /// Classes - For live regs that are only used in one register class in a<br></blockquote><blockquote type="cite">-    /// live range, the register class. If the register is not live, the<br></blockquote><blockquote type="cite">-    /// corresponding value is null. If the register is live but used in<br></blockquote><blockquote type="cite">-    /// multiple register classes, the corresponding value is -1 casted to a<br></blockquote><blockquote type="cite">-    /// pointer.<br></blockquote><blockquote type="cite">-    const TargetRegisterClass *<br></blockquote><blockquote type="cite">-      Classes[TargetRegisterInfo::FirstVirtualRegister];<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    /// RegRegs - Map registers to all their references within a live range.<br></blockquote><blockquote type="cite">-    std::multimap<unsigned, MachineOperand *> RegRefs;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">    /// KillIndices - The index of the most recent kill (proceding bottom-up),<br></blockquote><blockquote type="cite">    /// or ~0u if the register is not live.<br></blockquote><blockquote type="cite">    unsigned KillIndices[TargetRegisterInfo::FirstVirtualRegister];<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-    /// DefIndices - The index of the most recent complete def (proceding bottom<br></blockquote><blockquote type="cite">-    /// up), or ~0u if the register is live.<br></blockquote><blockquote type="cite">-    unsigned DefIndices[TargetRegisterInfo::FirstVirtualRegister];<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    /// KeepRegs - A set of registers which are live and cannot be changed to<br></blockquote><blockquote type="cite">-    /// break anti-dependencies.<br></blockquote><blockquote type="cite">-    SmallSet<unsigned, 4> KeepRegs;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">  public:<br></blockquote><blockquote type="cite">    SchedulePostRATDList(MachineFunction &MF,<br></blockquote><blockquote type="cite">                         const MachineLoopInfo &MLI,<br></blockquote><blockquote type="cite">                         const MachineDominatorTree &MDT,<br></blockquote><blockquote type="cite">                         ScheduleHazardRecognizer *HR,<br></blockquote><blockquote type="cite">-                         AliasAnalysis *aa,<br></blockquote><blockquote type="cite">-                         TargetSubtarget::AntiDepBreakMode adm)<br></blockquote><blockquote type="cite">+                         AntiDepBreaker *ADB,<br></blockquote><blockquote type="cite">+                         AliasAnalysis *aa)<br></blockquote><blockquote type="cite">      : ScheduleDAGInstrs(MF, MLI, MDT), Topo(SUnits),<br></blockquote><blockquote type="cite">-        AllocatableSet(TRI->getAllocatableSet(MF)),<br></blockquote><blockquote type="cite">-      HazardRec(HR), AA(aa), AntiDepMode(adm) {}<br></blockquote><blockquote type="cite">+      HazardRec(HR), AntiDepBreak(ADB), AA(aa) {}<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">    ~SchedulePostRATDList() {<br></blockquote><blockquote type="cite">-      delete HazardRec;<br></blockquote><blockquote type="cite">    }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">    /// StartBlock - Initialize register live-range state for scheduling in<br></blockquote><blockquote type="cite">@@ -177,11 +155,6 @@<br></blockquote><blockquote type="cite">    ///<br></blockquote><blockquote type="cite">    void Schedule();<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-    /// FixupKills - Fix register kill flags that have been made<br></blockquote><blockquote type="cite">-    /// invalid due to scheduling<br></blockquote><blockquote type="cite">-    ///<br></blockquote><blockquote type="cite">-    void FixupKills(MachineBasicBlock *MBB);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">    /// Observe - Update liveness information to account for the current<br></blockquote><blockquote type="cite">    /// instruction, which will not be scheduled.<br></blockquote><blockquote type="cite">    ///<br></blockquote><blockquote type="cite">@@ -191,17 +164,16 @@<br></blockquote><blockquote type="cite">    ///<br></blockquote><blockquote type="cite">    void FinishBlock();<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">+    /// FixupKills - Fix register kill flags that have been made<br></blockquote><blockquote type="cite">+    /// invalid due to scheduling<br></blockquote><blockquote type="cite">+    ///<br></blockquote><blockquote type="cite">+    void FixupKills(MachineBasicBlock *MBB);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">  private:<br></blockquote><blockquote type="cite">-    void PrescanInstruction(MachineInstr *MI);<br></blockquote><blockquote type="cite">-    void ScanInstruction(MachineInstr *MI, unsigned Count);<br></blockquote><blockquote type="cite">    void ReleaseSucc(SUnit *SU, SDep *SuccEdge);<br></blockquote><blockquote type="cite">    void ReleaseSuccessors(SUnit *SU);<br></blockquote><blockquote type="cite">    void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);<br></blockquote><blockquote type="cite">    void ListScheduleTopDown();<br></blockquote><blockquote type="cite">-    bool BreakAntiDependencies();<br></blockquote><blockquote type="cite">-    unsigned findSuitableFreeRegister(unsigned AntiDepReg,<br></blockquote><blockquote type="cite">-                                      unsigned LastNewReg,<br></blockquote><blockquote type="cite">-                                      const TargetRegisterClass *);<br></blockquote><blockquote type="cite">    void StartBlockForKills(MachineBasicBlock *BB);<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">    // ToggleKillFlag - Toggle a register operand kill flag. Other<br></blockquote><blockquote type="cite">@@ -250,8 +222,9 @@<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">  // Check for antidep breaking override...<br></blockquote><blockquote type="cite">  if (EnableAntiDepBreaking.getPosition() > 0) {<br></blockquote><blockquote type="cite">-    AntiDepMode = (EnableAntiDepBreaking) ?<br></blockquote><blockquote type="cite">-      TargetSubtarget::ANTIDEP_CRITICAL : TargetSubtarget::ANTIDEP_NONE;<br></blockquote><blockquote type="cite">+    AntiDepMode = (EnableAntiDepBreaking == "all") ? TargetSubtarget::ANTIDEP_ALL :<br></blockquote><blockquote type="cite">+      (EnableAntiDepBreaking == "critical") ? TargetSubtarget::ANTIDEP_CRITICAL :<br></blockquote><blockquote type="cite">+      TargetSubtarget::ANTIDEP_NONE;<br></blockquote><blockquote type="cite">  }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">  DEBUG(errs() << "PostRAScheduler\n");<br></blockquote><blockquote type="cite">@@ -262,8 +235,12 @@<br></blockquote><blockquote type="cite">  ScheduleHazardRecognizer *HR = EnablePostRAHazardAvoidance ?<br></blockquote><blockquote type="cite">    (ScheduleHazardRecognizer *)new ExactHazardRecognizer(InstrItins) :<br></blockquote><blockquote type="cite">    (ScheduleHazardRecognizer *)new SimpleHazardRecognizer();<br></blockquote><blockquote type="cite">+  AntiDepBreaker *ADB =<br></blockquote><blockquote type="cite">+    (AntiDepMode == TargetSubtarget::ANTIDEP_ALL) ? NULL /* FIXME */ :<br></blockquote><blockquote type="cite">+    (AntiDepMode == TargetSubtarget::ANTIDEP_CRITICAL) ?<br></blockquote><blockquote type="cite">+    new CriticalAntiDepBreaker(Fn) : NULL;<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-  SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, AA, AntiDepMode);<br></blockquote><blockquote type="cite">+  SchedulePostRATDList Scheduler(Fn, MLI, MDT, HR, ADB, AA);<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">  // Loop over all of the basic blocks<br></blockquote><blockquote type="cite">  for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();<br></blockquote><blockquote type="cite">@@ -311,6 +288,9 @@<br></blockquote><blockquote type="cite">    Scheduler.FixupKills(MBB);<br></blockquote><blockquote type="cite">  }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">+  delete HR;<br></blockquote><blockquote type="cite">+  delete ADB;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">  return true;<br></blockquote><blockquote type="cite"> }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">@@ -321,78 +301,10 @@<br></blockquote><blockquote type="cite">  // Call the superclass.<br></blockquote><blockquote type="cite">  ScheduleDAGInstrs::StartBlock(BB);<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-  // Reset the hazard recognizer.<br></blockquote><blockquote type="cite">+  // Reset the hazard recognizer and anti-dep breaker.<br></blockquote><blockquote type="cite">  HazardRec->Reset();<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Clear out the register class data.<br></blockquote><blockquote type="cite">-  std::fill(Classes, array_endof(Classes),<br></blockquote><blockquote type="cite">-            static_cast<const TargetRegisterClass *>(0));<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Initialize the indices to indicate that no registers are live.<br></blockquote><blockquote type="cite">-  std::fill(KillIndices, array_endof(KillIndices), ~0u);<br></blockquote><blockquote type="cite">-  std::fill(DefIndices, array_endof(DefIndices), BB->size());<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Clear "do not change" set.<br></blockquote><blockquote type="cite">-  KeepRegs.clear();<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  bool IsReturnBlock = (!BB->empty() && BB->back().getDesc().isReturn());<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Determine the live-out physregs for this block.<br></blockquote><blockquote type="cite">-  if (IsReturnBlock) {<br></blockquote><blockquote type="cite">-    // In a return block, examine the function live-out regs.<br></blockquote><blockquote type="cite">-    for (MachineRegisterInfo::liveout_iterator I = MRI.liveout_begin(),<br></blockquote><blockquote type="cite">-         E = MRI.liveout_end(); I != E; ++I) {<br></blockquote><blockquote type="cite">-      unsigned Reg = *I;<br></blockquote><blockquote type="cite">-      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-      KillIndices[Reg] = BB->size();<br></blockquote><blockquote type="cite">-      DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">-      // Repeat, for all aliases.<br></blockquote><blockquote type="cite">-      for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">-        unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">-        Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-        KillIndices[AliasReg] = BB->size();<br></blockquote><blockquote type="cite">-        DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-  } else {<br></blockquote><blockquote type="cite">-    // In a non-return block, examine the live-in regs of all successors.<br></blockquote><blockquote type="cite">-    for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),<br></blockquote><blockquote type="cite">-         SE = BB->succ_end(); SI != SE; ++SI)<br></blockquote><blockquote type="cite">-      for (MachineBasicBlock::livein_iterator I = (*SI)->livein_begin(),<br></blockquote><blockquote type="cite">-           E = (*SI)->livein_end(); I != E; ++I) {<br></blockquote><blockquote type="cite">-        unsigned Reg = *I;<br></blockquote><blockquote type="cite">-        Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-        KillIndices[Reg] = BB->size();<br></blockquote><blockquote type="cite">-        DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">-        // Repeat, for all aliases.<br></blockquote><blockquote type="cite">-        for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">-          unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">-          Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-          KillIndices[AliasReg] = BB->size();<br></blockquote><blockquote type="cite">-          DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">-        }<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Mark live-out callee-saved registers. In a return block this is<br></blockquote><blockquote type="cite">-  // all callee-saved registers. In non-return this is any<br></blockquote><blockquote type="cite">-  // callee-saved register that is not saved in the prolog.<br></blockquote><blockquote type="cite">-  const MachineFrameInfo *MFI = MF.getFrameInfo();<br></blockquote><blockquote type="cite">-  BitVector Pristine = MFI->getPristineRegs(BB);<br></blockquote><blockquote type="cite">-  for (const unsigned *I = TRI->getCalleeSavedRegs(); *I; ++I) {<br></blockquote><blockquote type="cite">-    unsigned Reg = *I;<br></blockquote><blockquote type="cite">-    if (!IsReturnBlock && !Pristine.test(Reg)) continue;<br></blockquote><blockquote type="cite">-    Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-    KillIndices[Reg] = BB->size();<br></blockquote><blockquote type="cite">-    DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">-    // Repeat, for all aliases.<br></blockquote><blockquote type="cite">-    for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">-      unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">-      Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-      KillIndices[AliasReg] = BB->size();<br></blockquote><blockquote type="cite">-      DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">+  if (AntiDepBreak != NULL)<br></blockquote><blockquote type="cite">+    AntiDepBreak->StartBlock(BB);<br></blockquote><blockquote type="cite"> }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"> /// Schedule - Schedule the instruction range using list scheduling.<br></blockquote><blockquote type="cite">@@ -403,8 +315,11 @@<br></blockquote><blockquote type="cite">  // Build the scheduling graph.<br></blockquote><blockquote type="cite">  BuildSchedGraph(AA);<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-  if (AntiDepMode != TargetSubtarget::ANTIDEP_NONE) {<br></blockquote><blockquote type="cite">-    if (BreakAntiDependencies()) {<br></blockquote><blockquote type="cite">+  if (AntiDepBreak != NULL) {<br></blockquote><blockquote type="cite">+    unsigned Broken =<br></blockquote><blockquote type="cite">+      AntiDepBreak->BreakAntiDependencies(SUnits, Begin, InsertPos,<br></blockquote><blockquote type="cite">+                                          InsertPosIndex);<br></blockquote><blockquote type="cite">+    if (Broken > 0) {<br></blockquote><blockquote type="cite">      // We made changes. Update the dependency graph.<br></blockquote><blockquote type="cite">      // Theoretically we could update the graph in place:<br></blockquote><blockquote type="cite">      // When a live range is changed to use a different register, remove<br></blockquote><blockquote type="cite">@@ -415,6 +330,8 @@<br></blockquote><blockquote type="cite">      EntrySU = SUnit();<br></blockquote><blockquote type="cite">      ExitSU = SUnit();<br></blockquote><blockquote type="cite">      BuildSchedGraph(AA);<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+      NumFixedAnti += Broken;<br></blockquote><blockquote type="cite">    }<br></blockquote><blockquote type="cite">  }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">@@ -432,436 +349,20 @@<br></blockquote><blockquote type="cite"> /// instruction, which will not be scheduled.<br></blockquote><blockquote type="cite"> ///<br></blockquote><blockquote type="cite"> void SchedulePostRATDList::Observe(MachineInstr *MI, unsigned Count) {<br></blockquote><blockquote type="cite">-  assert(Count < InsertPosIndex && "Instruction index out of expected range!");<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Any register which was defined within the previous scheduling region<br></blockquote><blockquote type="cite">-  // may have been rescheduled and its lifetime may overlap with registers<br></blockquote><blockquote type="cite">-  // in ways not reflected in our current liveness state. For each such<br></blockquote><blockquote type="cite">-  // register, adjust the liveness state to be conservatively correct.<br></blockquote><blockquote type="cite">-  for (unsigned Reg = 0; Reg != TargetRegisterInfo::FirstVirtualRegister; ++Reg)<br></blockquote><blockquote type="cite">-    if (DefIndices[Reg] < InsertPosIndex && DefIndices[Reg] >= Count) {<br></blockquote><blockquote type="cite">-      assert(KillIndices[Reg] == ~0u && "Clobbered register is live!");<br></blockquote><blockquote type="cite">-      // Mark this register to be non-renamable.<br></blockquote><blockquote type="cite">-      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-      // Move the def index to the end of the previous region, to reflect<br></blockquote><blockquote type="cite">-      // that the def could theoretically have been scheduled at the end.<br></blockquote><blockquote type="cite">-      DefIndices[Reg] = InsertPosIndex;<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  PrescanInstruction(MI);<br></blockquote><blockquote type="cite">-  ScanInstruction(MI, Count);<br></blockquote><blockquote type="cite">+  if (AntiDepBreak != NULL)<br></blockquote><blockquote type="cite">+    AntiDepBreak->Observe(MI, Count, InsertPosIndex);<br></blockquote><blockquote type="cite"> }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"> /// FinishBlock - Clean up register live-range state.<br></blockquote><blockquote type="cite"> ///<br></blockquote><blockquote type="cite"> void SchedulePostRATDList::FinishBlock() {<br></blockquote><blockquote type="cite">-  RegRefs.clear();<br></blockquote><blockquote type="cite">+  if (AntiDepBreak != NULL)<br></blockquote><blockquote type="cite">+    AntiDepBreak->FinishBlock();<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">  // Call the superclass.<br></blockquote><blockquote type="cite">  ScheduleDAGInstrs::FinishBlock();<br></blockquote><blockquote type="cite"> }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-/// CriticalPathStep - Return the next SUnit after SU on the bottom-up<br></blockquote><blockquote type="cite">-/// critical path.<br></blockquote><blockquote type="cite">-static SDep *CriticalPathStep(SUnit *SU) {<br></blockquote><blockquote type="cite">-  SDep *Next = 0;<br></blockquote><blockquote type="cite">-  unsigned NextDepth = 0;<br></blockquote><blockquote type="cite">-  // Find the predecessor edge with the greatest depth.<br></blockquote><blockquote type="cite">-  for (SUnit::pred_iterator P = SU->Preds.begin(), PE = SU->Preds.end();<br></blockquote><blockquote type="cite">-       P != PE; ++P) {<br></blockquote><blockquote type="cite">-    SUnit *PredSU = P->getSUnit();<br></blockquote><blockquote type="cite">-    unsigned PredLatency = P->getLatency();<br></blockquote><blockquote type="cite">-    unsigned PredTotalLatency = PredSU->getDepth() + PredLatency;<br></blockquote><blockquote type="cite">-    // In the case of a latency tie, prefer an anti-dependency edge over<br></blockquote><blockquote type="cite">-    // other types of edges.<br></blockquote><blockquote type="cite">-    if (NextDepth < PredTotalLatency ||<br></blockquote><blockquote type="cite">-        (NextDepth == PredTotalLatency && P->getKind() == SDep::Anti)) {<br></blockquote><blockquote type="cite">-      NextDepth = PredTotalLatency;<br></blockquote><blockquote type="cite">-      Next = &*P;<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-  return Next;<br></blockquote><blockquote type="cite">-}<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-void SchedulePostRATDList::PrescanInstruction(MachineInstr *MI) {<br></blockquote><blockquote type="cite">-  // Scan the register operands for this instruction and update<br></blockquote><blockquote type="cite">-  // Classes and RegRefs.<br></blockquote><blockquote type="cite">-  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">-    MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">-    if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">-    unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">-    if (Reg == 0) continue;<br></blockquote><blockquote type="cite">-    const TargetRegisterClass *NewRC = 0;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    if (i < MI->getDesc().getNumOperands())<br></blockquote><blockquote type="cite">-      NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // For now, only allow the register to be changed if its register<br></blockquote><blockquote type="cite">-    // class is consistent across all uses.<br></blockquote><blockquote type="cite">-    if (!Classes[Reg] && NewRC)<br></blockquote><blockquote type="cite">-      Classes[Reg] = NewRC;<br></blockquote><blockquote type="cite">-    else if (!NewRC || Classes[Reg] != NewRC)<br></blockquote><blockquote type="cite">-      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // Now check for aliases.<br></blockquote><blockquote type="cite">-    for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">-      // If an alias of the reg is used during the live range, give up.<br></blockquote><blockquote type="cite">-      // Note that this allows us to skip checking if AntiDepReg<br></blockquote><blockquote type="cite">-      // overlaps with any of the aliases, among other things.<br></blockquote><blockquote type="cite">-      unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">-      if (Classes[AliasReg]) {<br></blockquote><blockquote type="cite">-        Classes[AliasReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-        Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // If we're still willing to consider this register, note the reference.<br></blockquote><blockquote type="cite">-    if (Classes[Reg] != reinterpret_cast<TargetRegisterClass *>(-1))<br></blockquote><blockquote type="cite">-      RegRefs.insert(std::make_pair(Reg, &MO));<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // It's not safe to change register allocation for source operands of<br></blockquote><blockquote type="cite">-    // that have special allocation requirements.<br></blockquote><blockquote type="cite">-    if (MO.isUse() && MI->getDesc().hasExtraSrcRegAllocReq()) {<br></blockquote><blockquote type="cite">-      if (KeepRegs.insert(Reg)) {<br></blockquote><blockquote type="cite">-        for (const unsigned *Subreg = TRI->getSubRegisters(Reg);<br></blockquote><blockquote type="cite">-             *Subreg; ++Subreg)<br></blockquote><blockquote type="cite">-          KeepRegs.insert(*Subreg);<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-}<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,<br></blockquote><blockquote type="cite">-                                           unsigned Count) {<br></blockquote><blockquote type="cite">-  // Update liveness.<br></blockquote><blockquote type="cite">-  // Proceding upwards, registers that are defed but not used in this<br></blockquote><blockquote type="cite">-  // instruction are now dead.<br></blockquote><blockquote type="cite">-  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">-    MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">-    if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">-    unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">-    if (Reg == 0) continue;<br></blockquote><blockquote type="cite">-    if (!MO.isDef()) continue;<br></blockquote><blockquote type="cite">-    // Ignore two-addr defs.<br></blockquote><blockquote type="cite">-    if (MI->isRegTiedToUseOperand(i)) continue;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    DefIndices[Reg] = Count;<br></blockquote><blockquote type="cite">-    KillIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">-    assert(((KillIndices[Reg] == ~0u) !=<br></blockquote><blockquote type="cite">-            (DefIndices[Reg] == ~0u)) &&<br></blockquote><blockquote type="cite">-           "Kill and Def maps aren't consistent for Reg!");<br></blockquote><blockquote type="cite">-    KeepRegs.erase(Reg);<br></blockquote><blockquote type="cite">-    Classes[Reg] = 0;<br></blockquote><blockquote type="cite">-    RegRefs.erase(Reg);<br></blockquote><blockquote type="cite">-    // Repeat, for all subregs.<br></blockquote><blockquote type="cite">-    for (const unsigned *Subreg = TRI->getSubRegisters(Reg);<br></blockquote><blockquote type="cite">-         *Subreg; ++Subreg) {<br></blockquote><blockquote type="cite">-      unsigned SubregReg = *Subreg;<br></blockquote><blockquote type="cite">-      DefIndices[SubregReg] = Count;<br></blockquote><blockquote type="cite">-      KillIndices[SubregReg] = ~0u;<br></blockquote><blockquote type="cite">-      KeepRegs.erase(SubregReg);<br></blockquote><blockquote type="cite">-      Classes[SubregReg] = 0;<br></blockquote><blockquote type="cite">-      RegRefs.erase(SubregReg);<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-    // Conservatively mark super-registers as unusable.<br></blockquote><blockquote type="cite">-    for (const unsigned *Super = TRI->getSuperRegisters(Reg);<br></blockquote><blockquote type="cite">-         *Super; ++Super) {<br></blockquote><blockquote type="cite">-      unsigned SuperReg = *Super;<br></blockquote><blockquote type="cite">-      Classes[SuperReg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">-    MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">-    if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">-    unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">-    if (Reg == 0) continue;<br></blockquote><blockquote type="cite">-    if (!MO.isUse()) continue;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    const TargetRegisterClass *NewRC = 0;<br></blockquote><blockquote type="cite">-    if (i < MI->getDesc().getNumOperands())<br></blockquote><blockquote type="cite">-      NewRC = MI->getDesc().OpInfo[i].getRegClass(TRI);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // For now, only allow the register to be changed if its register<br></blockquote><blockquote type="cite">-    // class is consistent across all uses.<br></blockquote><blockquote type="cite">-    if (!Classes[Reg] && NewRC)<br></blockquote><blockquote type="cite">-      Classes[Reg] = NewRC;<br></blockquote><blockquote type="cite">-    else if (!NewRC || Classes[Reg] != NewRC)<br></blockquote><blockquote type="cite">-      Classes[Reg] = reinterpret_cast<TargetRegisterClass *>(-1);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    RegRefs.insert(std::make_pair(Reg, &MO));<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // It wasn't previously live but now it is, this is a kill.<br></blockquote><blockquote type="cite">-    if (KillIndices[Reg] == ~0u) {<br></blockquote><blockquote type="cite">-      KillIndices[Reg] = Count;<br></blockquote><blockquote type="cite">-      DefIndices[Reg] = ~0u;<br></blockquote><blockquote type="cite">-          assert(((KillIndices[Reg] == ~0u) !=<br></blockquote><blockquote type="cite">-                  (DefIndices[Reg] == ~0u)) &&<br></blockquote><blockquote type="cite">-               "Kill and Def maps aren't consistent for Reg!");<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-    // Repeat, for all aliases.<br></blockquote><blockquote type="cite">-    for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {<br></blockquote><blockquote type="cite">-      unsigned AliasReg = *Alias;<br></blockquote><blockquote type="cite">-      if (KillIndices[AliasReg] == ~0u) {<br></blockquote><blockquote type="cite">-        KillIndices[AliasReg] = Count;<br></blockquote><blockquote type="cite">-        DefIndices[AliasReg] = ~0u;<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-}<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-unsigned<br></blockquote><blockquote type="cite">-SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg,<br></blockquote><blockquote type="cite">-                                               unsigned LastNewReg,<br></blockquote><blockquote type="cite">-                                               const TargetRegisterClass *RC) {<br></blockquote><blockquote type="cite">-  for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF),<br></blockquote><blockquote type="cite">-       RE = RC->allocation_order_end(MF); R != RE; ++R) {<br></blockquote><blockquote type="cite">-    unsigned NewReg = *R;<br></blockquote><blockquote type="cite">-    // Don't replace a register with itself.<br></blockquote><blockquote type="cite">-    if (NewReg == AntiDepReg) continue;<br></blockquote><blockquote type="cite">-    // Don't replace a register with one that was recently used to repair<br></blockquote><blockquote type="cite">-    // an anti-dependence with this AntiDepReg, because that would<br></blockquote><blockquote type="cite">-    // re-introduce that anti-dependence.<br></blockquote><blockquote type="cite">-    if (NewReg == LastNewReg) continue;<br></blockquote><blockquote type="cite">-    // If NewReg is dead and NewReg's most recent def is not before<br></blockquote><blockquote type="cite">-    // AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg.<br></blockquote><blockquote type="cite">-    assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) &&<br></blockquote><blockquote type="cite">-           "Kill and Def maps aren't consistent for AntiDepReg!");<br></blockquote><blockquote type="cite">-    assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) &&<br></blockquote><blockquote type="cite">-           "Kill and Def maps aren't consistent for NewReg!");<br></blockquote><blockquote type="cite">-    if (KillIndices[NewReg] != ~0u ||<br></blockquote><blockquote type="cite">-        Classes[NewReg] == reinterpret_cast<TargetRegisterClass *>(-1) ||<br></blockquote><blockquote type="cite">-        KillIndices[AntiDepReg] > DefIndices[NewReg])<br></blockquote><blockquote type="cite">-      continue;<br></blockquote><blockquote type="cite">-    return NewReg;<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // No registers are free and available!<br></blockquote><blockquote type="cite">-  return 0;<br></blockquote><blockquote type="cite">-}<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path<br></blockquote><blockquote type="cite">-/// of the ScheduleDAG and break them by renaming registers.<br></blockquote><blockquote type="cite">-///<br></blockquote><blockquote type="cite">-bool SchedulePostRATDList::BreakAntiDependencies() {<br></blockquote><blockquote type="cite">-  // The code below assumes that there is at least one instruction,<br></blockquote><blockquote type="cite">-  // so just duck out immediately if the block is empty.<br></blockquote><blockquote type="cite">-  if (SUnits.empty()) return false;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Find the node at the bottom of the critical path.<br></blockquote><blockquote type="cite">-  SUnit *Max = 0;<br></blockquote><blockquote type="cite">-  for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {<br></blockquote><blockquote type="cite">-    SUnit *SU = &SUnits[i];<br></blockquote><blockquote type="cite">-    if (!Max || SU->getDepth() + SU->Latency > Max->getDepth() + Max->Latency)<br></blockquote><blockquote type="cite">-      Max = SU;<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-#ifndef NDEBUG<br></blockquote><blockquote type="cite">-  {<br></blockquote><blockquote type="cite">-    DEBUG(errs() << "Critical path has total latency "<br></blockquote><blockquote type="cite">-          << (Max->getDepth() + Max->Latency) << "\n");<br></blockquote><blockquote type="cite">-    DEBUG(errs() << "Available regs:");<br></blockquote><blockquote type="cite">-    for (unsigned Reg = 0; Reg < TRI->getNumRegs(); ++Reg) {<br></blockquote><blockquote type="cite">-      if (KillIndices[Reg] == ~0u)<br></blockquote><blockquote type="cite">-        DEBUG(errs() << " " << TRI->getName(Reg));<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-    DEBUG(errs() << '\n');<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-#endif<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Track progress along the critical path through the SUnit graph as we walk<br></blockquote><blockquote type="cite">-  // the instructions.<br></blockquote><blockquote type="cite">-  SUnit *CriticalPathSU = Max;<br></blockquote><blockquote type="cite">-  MachineInstr *CriticalPathMI = CriticalPathSU->getInstr();<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Consider this pattern:<br></blockquote><blockquote type="cite">-  //   A = ...<br></blockquote><blockquote type="cite">-  //   ... = A<br></blockquote><blockquote type="cite">-  //   A = ...<br></blockquote><blockquote type="cite">-  //   ... = A<br></blockquote><blockquote type="cite">-  //   A = ...<br></blockquote><blockquote type="cite">-  //   ... = A<br></blockquote><blockquote type="cite">-  //   A = ...<br></blockquote><blockquote type="cite">-  //   ... = A<br></blockquote><blockquote type="cite">-  // There are three anti-dependencies here, and without special care,<br></blockquote><blockquote type="cite">-  // we'd break all of them using the same register:<br></blockquote><blockquote type="cite">-  //   A = ...<br></blockquote><blockquote type="cite">-  //   ... = A<br></blockquote><blockquote type="cite">-  //   B = ...<br></blockquote><blockquote type="cite">-  //   ... = B<br></blockquote><blockquote type="cite">-  //   B = ...<br></blockquote><blockquote type="cite">-  //   ... = B<br></blockquote><blockquote type="cite">-  //   B = ...<br></blockquote><blockquote type="cite">-  //   ... = B<br></blockquote><blockquote type="cite">-  // because at each anti-dependence, B is the first register that<br></blockquote><blockquote type="cite">-  // isn't A which is free.  This re-introduces anti-dependencies<br></blockquote><blockquote type="cite">-  // at all but one of the original anti-dependencies that we were<br></blockquote><blockquote type="cite">-  // trying to break.  To avoid this, keep track of the most recent<br></blockquote><blockquote type="cite">-  // register that each register was replaced with, avoid<br></blockquote><blockquote type="cite">-  // using it to repair an anti-dependence on the same register.<br></blockquote><blockquote type="cite">-  // This lets us produce this:<br></blockquote><blockquote type="cite">-  //   A = ...<br></blockquote><blockquote type="cite">-  //   ... = A<br></blockquote><blockquote type="cite">-  //   B = ...<br></blockquote><blockquote type="cite">-  //   ... = B<br></blockquote><blockquote type="cite">-  //   C = ...<br></blockquote><blockquote type="cite">-  //   ... = C<br></blockquote><blockquote type="cite">-  //   B = ...<br></blockquote><blockquote type="cite">-  //   ... = B<br></blockquote><blockquote type="cite">-  // This still has an anti-dependence on B, but at least it isn't on the<br></blockquote><blockquote type="cite">-  // original critical path.<br></blockquote><blockquote type="cite">-  //<br></blockquote><blockquote type="cite">-  // TODO: If we tracked more than one register here, we could potentially<br></blockquote><blockquote type="cite">-  // fix that remaining critical edge too. This is a little more involved,<br></blockquote><blockquote type="cite">-  // because unlike the most recent register, less recent registers should<br></blockquote><blockquote type="cite">-  // still be considered, though only if no other registers are available.<br></blockquote><blockquote type="cite">-  unsigned LastNewReg[TargetRegisterInfo::FirstVirtualRegister] = {};<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  // Attempt to break anti-dependence edges on the critical path. Walk the<br></blockquote><blockquote type="cite">-  // instructions from the bottom up, tracking information about liveness<br></blockquote><blockquote type="cite">-  // as we go to help determine which registers are available.<br></blockquote><blockquote type="cite">-  bool Changed = false;<br></blockquote><blockquote type="cite">-  unsigned Count = InsertPosIndex - 1;<br></blockquote><blockquote type="cite">-  for (MachineBasicBlock::iterator I = InsertPos, E = Begin;<br></blockquote><blockquote type="cite">-       I != E; --Count) {<br></blockquote><blockquote type="cite">-    MachineInstr *MI = --I;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // Check if this instruction has a dependence on the critical path that<br></blockquote><blockquote type="cite">-    // is an anti-dependence that we may be able to break. If it is, set<br></blockquote><blockquote type="cite">-    // AntiDepReg to the non-zero register associated with the anti-dependence.<br></blockquote><blockquote type="cite">-    //<br></blockquote><blockquote type="cite">-    // We limit our attention to the critical path as a heuristic to avoid<br></blockquote><blockquote type="cite">-    // breaking anti-dependence edges that aren't going to significantly<br></blockquote><blockquote type="cite">-    // impact the overall schedule. There are a limited number of registers<br></blockquote><blockquote type="cite">-    // and we want to save them for the important edges.<br></blockquote><blockquote type="cite">-    //<br></blockquote><blockquote type="cite">-    // TODO: Instructions with multiple defs could have multiple<br></blockquote><blockquote type="cite">-    // anti-dependencies. The current code here only knows how to break one<br></blockquote><blockquote type="cite">-    // edge per instruction. Note that we'd have to be able to break all of<br></blockquote><blockquote type="cite">-    // the anti-dependencies in an instruction in order to be effective.<br></blockquote><blockquote type="cite">-    unsigned AntiDepReg = 0;<br></blockquote><blockquote type="cite">-    if (MI == CriticalPathMI) {<br></blockquote><blockquote type="cite">-      if (SDep *Edge = CriticalPathStep(CriticalPathSU)) {<br></blockquote><blockquote type="cite">-        SUnit *NextSU = Edge->getSUnit();<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-        // Only consider anti-dependence edges.<br></blockquote><blockquote type="cite">-        if (Edge->getKind() == SDep::Anti) {<br></blockquote><blockquote type="cite">-          AntiDepReg = Edge->getReg();<br></blockquote><blockquote type="cite">-          assert(AntiDepReg != 0 && "Anti-dependence on reg0?");<br></blockquote><blockquote type="cite">-          if (!AllocatableSet.test(AntiDepReg))<br></blockquote><blockquote type="cite">-            // Don't break anti-dependencies on non-allocatable registers.<br></blockquote><blockquote type="cite">-            AntiDepReg = 0;<br></blockquote><blockquote type="cite">-          else if (KeepRegs.count(AntiDepReg))<br></blockquote><blockquote type="cite">-            // Don't break anti-dependencies if an use down below requires<br></blockquote><blockquote type="cite">-            // this exact register.<br></blockquote><blockquote type="cite">-            AntiDepReg = 0;<br></blockquote><blockquote type="cite">-          else {<br></blockquote><blockquote type="cite">-            // If the SUnit has other dependencies on the SUnit that it<br></blockquote><blockquote type="cite">-            // anti-depends on, don't bother breaking the anti-dependency<br></blockquote><blockquote type="cite">-            // since those edges would prevent such units from being<br></blockquote><blockquote type="cite">-            // scheduled past each other regardless.<br></blockquote><blockquote type="cite">-            //<br></blockquote><blockquote type="cite">-            // Also, if there are dependencies on other SUnits with the<br></blockquote><blockquote type="cite">-            // same register as the anti-dependency, don't attempt to<br></blockquote><blockquote type="cite">-            // break it.<br></blockquote><blockquote type="cite">-            for (SUnit::pred_iterator P = CriticalPathSU->Preds.begin(),<br></blockquote><blockquote type="cite">-                 PE = CriticalPathSU->Preds.end(); P != PE; ++P)<br></blockquote><blockquote type="cite">-              if (P->getSUnit() == NextSU ?<br></blockquote><blockquote type="cite">-                    (P->getKind() != SDep::Anti || P->getReg() != AntiDepReg) :<br></blockquote><blockquote type="cite">-                    (P->getKind() == SDep::Data && P->getReg() == AntiDepReg)) {<br></blockquote><blockquote type="cite">-                AntiDepReg = 0;<br></blockquote><blockquote type="cite">-                break;<br></blockquote><blockquote type="cite">-              }<br></blockquote><blockquote type="cite">-          }<br></blockquote><blockquote type="cite">-        }<br></blockquote><blockquote type="cite">-        CriticalPathSU = NextSU;<br></blockquote><blockquote type="cite">-        CriticalPathMI = CriticalPathSU->getInstr();<br></blockquote><blockquote type="cite">-      } else {<br></blockquote><blockquote type="cite">-        // We've reached the end of the critical path.<br></blockquote><blockquote type="cite">-        CriticalPathSU = 0;<br></blockquote><blockquote type="cite">-        CriticalPathMI = 0;<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    PrescanInstruction(MI);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    if (MI->getDesc().hasExtraDefRegAllocReq())<br></blockquote><blockquote type="cite">-      // If this instruction's defs have special allocation requirement, don't<br></blockquote><blockquote type="cite">-      // break this anti-dependency.<br></blockquote><blockquote type="cite">-      AntiDepReg = 0;<br></blockquote><blockquote type="cite">-    else if (AntiDepReg) {<br></blockquote><blockquote type="cite">-      // If this instruction has a use of AntiDepReg, breaking it<br></blockquote><blockquote type="cite">-      // is invalid.<br></blockquote><blockquote type="cite">-      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {<br></blockquote><blockquote type="cite">-        MachineOperand &MO = MI->getOperand(i);<br></blockquote><blockquote type="cite">-        if (!MO.isReg()) continue;<br></blockquote><blockquote type="cite">-        unsigned Reg = MO.getReg();<br></blockquote><blockquote type="cite">-        if (Reg == 0) continue;<br></blockquote><blockquote type="cite">-        if (MO.isUse() && AntiDepReg == Reg) {<br></blockquote><blockquote type="cite">-          AntiDepReg = 0;<br></blockquote><blockquote type="cite">-          break;<br></blockquote><blockquote type="cite">-        }<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // Determine AntiDepReg's register class, if it is live and is<br></blockquote><blockquote type="cite">-    // consistently used within a single class.<br></blockquote><blockquote type="cite">-    const TargetRegisterClass *RC = AntiDepReg != 0 ? Classes[AntiDepReg] : 0;<br></blockquote><blockquote type="cite">-    assert((AntiDepReg == 0 || RC != NULL) &&<br></blockquote><blockquote type="cite">-           "Register should be live if it's causing an anti-dependence!");<br></blockquote><blockquote type="cite">-    if (RC == reinterpret_cast<TargetRegisterClass *>(-1))<br></blockquote><blockquote type="cite">-      AntiDepReg = 0;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    // Look for a suitable register to use to break the anti-depenence.<br></blockquote><blockquote type="cite">-    //<br></blockquote><blockquote type="cite">-    // TODO: Instead of picking the first free register, consider which might<br></blockquote><blockquote type="cite">-    // be the best.<br></blockquote><blockquote type="cite">-    if (AntiDepReg != 0) {<br></blockquote><blockquote type="cite">-      if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg,<br></blockquote><blockquote type="cite">-                                                     LastNewReg[AntiDepReg],<br></blockquote><blockquote type="cite">-                                                     RC)) {<br></blockquote><blockquote type="cite">-        DEBUG(errs() << "Breaking anti-dependence edge on "<br></blockquote><blockquote type="cite">-              << TRI->getName(AntiDepReg)<br></blockquote><blockquote type="cite">-              << " with " << RegRefs.count(AntiDepReg) << " references"<br></blockquote><blockquote type="cite">-              << " using " << TRI->getName(NewReg) << "!\n");<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-        // Update the references to the old register to refer to the new<br></blockquote><blockquote type="cite">-        // register.<br></blockquote><blockquote type="cite">-        std::pair<std::multimap<unsigned, MachineOperand *>::iterator,<br></blockquote><blockquote type="cite">-                  std::multimap<unsigned, MachineOperand *>::iterator><br></blockquote><blockquote type="cite">-           Range = RegRefs.equal_range(AntiDepReg);<br></blockquote><blockquote type="cite">-        for (std::multimap<unsigned, MachineOperand *>::iterator<br></blockquote><blockquote type="cite">-             Q = Range.first, QE = Range.second; Q != QE; ++Q)<br></blockquote><blockquote type="cite">-          Q->second->setReg(NewReg);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-        // We just went back in time and modified history; the<br></blockquote><blockquote type="cite">-        // liveness information for the anti-depenence reg is now<br></blockquote><blockquote type="cite">-        // inconsistent. Set the state as if it were dead.<br></blockquote><blockquote type="cite">-        Classes[NewReg] = Classes[AntiDepReg];<br></blockquote><blockquote type="cite">-        DefIndices[NewReg] = DefIndices[AntiDepReg];<br></blockquote><blockquote type="cite">-        KillIndices[NewReg] = KillIndices[AntiDepReg];<br></blockquote><blockquote type="cite">-        assert(((KillIndices[NewReg] == ~0u) !=<br></blockquote><blockquote type="cite">-                (DefIndices[NewReg] == ~0u)) &&<br></blockquote><blockquote type="cite">-             "Kill and Def maps aren't consistent for NewReg!");<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-        Classes[AntiDepReg] = 0;<br></blockquote><blockquote type="cite">-        DefIndices[AntiDepReg] = KillIndices[AntiDepReg];<br></blockquote><blockquote type="cite">-        KillIndices[AntiDepReg] = ~0u;<br></blockquote><blockquote type="cite">-        assert(((KillIndices[AntiDepReg] == ~0u) !=<br></blockquote><blockquote type="cite">-                (DefIndices[AntiDepReg] == ~0u)) &&<br></blockquote><blockquote type="cite">-             "Kill and Def maps aren't consistent for AntiDepReg!");<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-        RegRefs.erase(AntiDepReg);<br></blockquote><blockquote type="cite">-        Changed = true;<br></blockquote><blockquote type="cite">-        LastNewReg[AntiDepReg] = NewReg;<br></blockquote><blockquote type="cite">-      }<br></blockquote><blockquote type="cite">-    }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-    ScanInstruction(MI, Count);<br></blockquote><blockquote type="cite">-  }<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">-  return Changed;<br></blockquote><blockquote type="cite">-}<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite"> /// StartBlockForKills - Initialize register live-range state for updating kills<br></blockquote><blockquote type="cite"> ///<br></blockquote><blockquote type="cite"> void SchedulePostRATDList::StartBlockForKills(MachineBasicBlock *BB) {<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=85127&r1=85126&r2=85127&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original)<br></blockquote><blockquote type="cite">+++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">@@ -130,7 +130,7 @@<br></blockquote><blockquote type="cite">  /// for Thumb1.<br></blockquote><blockquote type="cite">  bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,<br></blockquote><blockquote type="cite">                             TargetSubtarget::AntiDepBreakMode& mode) const {<br></blockquote><blockquote type="cite">-    mode = TargetSubtarget::ANTIDEP_NONE;<br></blockquote><blockquote type="cite">+    mode = TargetSubtarget::ANTIDEP_CRITICAL;<br></blockquote><blockquote type="cite">    return PostRAScheduler && OptLevel >= CodeGenOpt::Default;<br></blockquote><blockquote type="cite">  }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll?rev=85127&r1=85126&r2=85127&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll (original)<br></blockquote><blockquote type="cite">+++ llvm/trunk/test/CodeGen/X86/break-anti-dependencies.ll Mon Oct 26 11:59:04 2009<br></blockquote><blockquote type="cite">@@ -1,7 +1,7 @@<br></blockquote><blockquote type="cite">-; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=false > %t<br></blockquote><blockquote type="cite">+; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=none > %t<br></blockquote><blockquote type="cite"> ; RUN:   grep {%xmm0} %t | count 14<br></blockquote><blockquote type="cite"> ; RUN:   not grep {%xmm1} %t<br></blockquote><blockquote type="cite">-; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies > %t<br></blockquote><blockquote type="cite">+; RUN: llc < %s -march=x86-64 -post-RA-scheduler -break-anti-dependencies=critical > %t<br></blockquote><blockquote type="cite"> ; RUN:   grep {%xmm0} %t | count 7<br></blockquote><blockquote type="cite"> ; RUN:   grep {%xmm1} %t | count 7<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">_______________________________________________<br></blockquote><blockquote type="cite">llvm-commits mailing list<br></blockquote><blockquote type="cite"><a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br></blockquote><blockquote type="cite"><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br></blockquote><blockquote type="cite"><br></blockquote></div></blockquote></div><br></body></html>