xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/CriticalAntiDepBreaker.h (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
10b57cec5SDimitry Andric //===- llvm/CodeGen/CriticalAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the CriticalAntiDepBreaker class, which
100b57cec5SDimitry Andric // implements register anti-dependence breaking along a blocks
110b57cec5SDimitry Andric // critical path during post-RA scheduler.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_CRITICALANTIDEPBREAKER_H
160b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_CRITICALANTIDEPBREAKER_H
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
19*5ffd83dbSDimitry Andric #include "llvm/CodeGen/AntiDepBreaker.h"
200b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
210b57cec5SDimitry Andric #include <map>
220b57cec5SDimitry Andric #include <vector>
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric namespace llvm {
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric class MachineBasicBlock;
270b57cec5SDimitry Andric class MachineFunction;
280b57cec5SDimitry Andric class MachineInstr;
290b57cec5SDimitry Andric class MachineOperand;
300b57cec5SDimitry Andric class MachineRegisterInfo;
310b57cec5SDimitry Andric class RegisterClassInfo;
320b57cec5SDimitry Andric class TargetInstrInfo;
330b57cec5SDimitry Andric class TargetRegisterClass;
340b57cec5SDimitry Andric class TargetRegisterInfo;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CriticalAntiDepBreaker : public AntiDepBreaker {
370b57cec5SDimitry Andric     MachineFunction& MF;
380b57cec5SDimitry Andric     MachineRegisterInfo &MRI;
390b57cec5SDimitry Andric     const TargetInstrInfo *TII;
400b57cec5SDimitry Andric     const TargetRegisterInfo *TRI;
410b57cec5SDimitry Andric     const RegisterClassInfo &RegClassInfo;
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric     /// The set of allocatable registers.
440b57cec5SDimitry Andric     /// We'll be ignoring anti-dependencies on non-allocatable registers,
450b57cec5SDimitry Andric     /// because they may not be safe to break.
460b57cec5SDimitry Andric     const BitVector AllocatableSet;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric     /// For live regs that are only used in one register class in a
490b57cec5SDimitry Andric     /// live range, the register class. If the register is not live, the
500b57cec5SDimitry Andric     /// corresponding value is null. If the register is live but used in
510b57cec5SDimitry Andric     /// multiple register classes, the corresponding value is -1 casted to a
520b57cec5SDimitry Andric     /// pointer.
530b57cec5SDimitry Andric     std::vector<const TargetRegisterClass *> Classes;
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric     /// Map registers to all their references within a live range.
560b57cec5SDimitry Andric     std::multimap<unsigned, MachineOperand *> RegRefs;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric     using RegRefIter =
590b57cec5SDimitry Andric         std::multimap<unsigned, MachineOperand *>::const_iterator;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric     /// The index of the most recent kill (proceeding bottom-up),
620b57cec5SDimitry Andric     /// or ~0u if the register is not live.
630b57cec5SDimitry Andric     std::vector<unsigned> KillIndices;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric     /// The index of the most recent complete def (proceeding
660b57cec5SDimitry Andric     /// bottom up), or ~0u if the register is live.
670b57cec5SDimitry Andric     std::vector<unsigned> DefIndices;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric     /// A set of registers which are live and cannot be changed to
700b57cec5SDimitry Andric     /// break anti-dependencies.
710b57cec5SDimitry Andric     BitVector KeepRegs;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   public:
740b57cec5SDimitry Andric     CriticalAntiDepBreaker(MachineFunction& MFi, const RegisterClassInfo &RCI);
750b57cec5SDimitry Andric     ~CriticalAntiDepBreaker() override;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric     /// Initialize anti-dep breaking for a new basic block.
780b57cec5SDimitry Andric     void StartBlock(MachineBasicBlock *BB) override;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric     /// Identifiy anti-dependencies along the critical path
810b57cec5SDimitry Andric     /// of the ScheduleDAG and break them by renaming registers.
820b57cec5SDimitry Andric     unsigned BreakAntiDependencies(const std::vector<SUnit> &SUnits,
830b57cec5SDimitry Andric                                    MachineBasicBlock::iterator Begin,
840b57cec5SDimitry Andric                                    MachineBasicBlock::iterator End,
850b57cec5SDimitry Andric                                    unsigned InsertPosIndex,
860b57cec5SDimitry Andric                                    DbgValueVector &DbgValues) override;
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric     /// Update liveness information to account for the current
890b57cec5SDimitry Andric     /// instruction, which will not be scheduled.
900b57cec5SDimitry Andric     void Observe(MachineInstr &MI, unsigned Count,
910b57cec5SDimitry Andric                  unsigned InsertPosIndex) override;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric     /// Finish anti-dep breaking for a basic block.
940b57cec5SDimitry Andric     void FinishBlock() override;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   private:
970b57cec5SDimitry Andric     void PrescanInstruction(MachineInstr &MI);
980b57cec5SDimitry Andric     void ScanInstruction(MachineInstr &MI, unsigned Count);
990b57cec5SDimitry Andric     bool isNewRegClobberedByRefs(RegRefIter RegRefBegin,
1000b57cec5SDimitry Andric                                  RegRefIter RegRefEnd,
1010b57cec5SDimitry Andric                                  unsigned NewReg);
1020b57cec5SDimitry Andric     unsigned findSuitableFreeRegister(RegRefIter RegRefBegin,
1030b57cec5SDimitry Andric                                       RegRefIter RegRefEnd,
1040b57cec5SDimitry Andric                                       unsigned AntiDepReg,
1050b57cec5SDimitry Andric                                       unsigned LastNewReg,
1060b57cec5SDimitry Andric                                       const TargetRegisterClass *RC,
1070b57cec5SDimitry Andric                                       SmallVectorImpl<unsigned> &Forbid);
1080b57cec5SDimitry Andric   };
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric } // end namespace llvm
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_CRITICALANTIDEPBREAKER_H
113