1//===- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the AntiDepBreaker class, which implements
10// anti-dependence breaking heuristics for post-register-allocation scheduling.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_CODEGEN_ANTIDEPBREAKER_H
15#define LLVM_LIB_CODEGEN_ANTIDEPBREAKER_H
16
17#include "llvm/ADT/iterator_range.h"
18#include "llvm/CodeGen/MachineBasicBlock.h"
19#include "llvm/CodeGen/MachineInstr.h"
20#include "llvm/CodeGen/MachineOperand.h"
21#include "llvm/CodeGen/ScheduleDAG.h"
22#include "llvm/Support/Compiler.h"
23#include <cassert>
24#include <utility>
25#include <vector>
26
27namespace llvm {
28
29/// This class works in conjunction with the post-RA scheduler to rename
30/// registers to break register anti-dependencies (WAR hazards).
31class LLVM_LIBRARY_VISIBILITY AntiDepBreaker {
32public:
33  using DbgValueVector =
34      std::vector<std::pair<MachineInstr *, MachineInstr *>>;
35
36  virtual ~AntiDepBreaker();
37
38  /// Initialize anti-dep breaking for a new basic block.
39  virtual void StartBlock(MachineBasicBlock *BB) = 0;
40
41  /// Identifiy anti-dependencies within a basic-block region and break them by
42  /// renaming registers. Return the number of anti-dependencies broken.
43  virtual unsigned BreakAntiDependencies(const std::vector<SUnit> &SUnits,
44                                         MachineBasicBlock::iterator Begin,
45                                         MachineBasicBlock::iterator End,
46                                         unsigned InsertPosIndex,
47                                         DbgValueVector &DbgValues) = 0;
48
49  /// Update liveness information to account for the current
50  /// instruction, which will not be scheduled.
51  virtual void Observe(MachineInstr &MI, unsigned Count,
52                       unsigned InsertPosIndex) = 0;
53
54  /// Finish anti-dep breaking for a basic block.
55  virtual void FinishBlock() = 0;
56
57  /// Update DBG_VALUE if dependency breaker is updating
58  /// other machine instruction to use NewReg.
59  void UpdateDbgValue(MachineInstr &MI, unsigned OldReg, unsigned NewReg) {
60    assert(MI.isDebugValue() && "MI is not DBG_VALUE!");
61    if (MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == OldReg)
62      MI.getOperand(0).setReg(NewReg);
63  }
64
65  /// Update all DBG_VALUE instructions that may be affected by the dependency
66  /// breaker's update of ParentMI to use NewReg.
67  void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI,
68                       unsigned OldReg, unsigned NewReg) {
69    // The following code is dependent on the order in which the DbgValues are
70    // constructed in ScheduleDAGInstrs::buildSchedGraph.
71    MachineInstr *PrevDbgMI = nullptr;
72    for (const auto &DV : make_range(DbgValues.crbegin(), DbgValues.crend())) {
73      MachineInstr *PrevMI = DV.second;
74      if ((PrevMI == ParentMI) || (PrevMI == PrevDbgMI)) {
75        MachineInstr *DbgMI = DV.first;
76        UpdateDbgValue(*DbgMI, OldReg, NewReg);
77        PrevDbgMI = DbgMI;
78      } else if (PrevDbgMI) {
79        break; // If no match and already found a DBG_VALUE, we're done.
80      }
81    }
82  }
83};
84
85} // end namespace llvm
86
87#endif // LLVM_LIB_CODEGEN_ANTIDEPBREAKER_H
88