mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
ae65e281f3
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
184 lines
6.8 KiB
C++
184 lines
6.8 KiB
C++
//==- llvm/CodeGen/AggressiveAntiDepBreaker.h - Anti-Dep Support -*- C++ -*-==//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the AggressiveAntiDepBreaker class, which
|
|
// implements register anti-dependence breaking during post-RA
|
|
// scheduling. It attempts to break all anti-dependencies within a
|
|
// block.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H
|
|
#define LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H
|
|
|
|
#include "AntiDepBreaker.h"
|
|
#include "llvm/ADT/BitVector.h"
|
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include <map>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
namespace llvm {
|
|
|
|
class MachineBasicBlock;
|
|
class MachineFunction;
|
|
class MachineInstr;
|
|
class MachineOperand;
|
|
class MachineRegisterInfo;
|
|
class RegisterClassInfo;
|
|
class TargetInstrInfo;
|
|
class TargetRegisterClass;
|
|
class TargetRegisterInfo;
|
|
|
|
/// Contains all the state necessary for anti-dep breaking.
|
|
class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepState {
|
|
public:
|
|
/// Information about a register reference within a liverange
|
|
struct RegisterReference {
|
|
/// The registers operand
|
|
MachineOperand *Operand;
|
|
|
|
/// The register class
|
|
const TargetRegisterClass *RC;
|
|
};
|
|
|
|
private:
|
|
/// Number of non-virtual target registers (i.e. TRI->getNumRegs()).
|
|
const unsigned NumTargetRegs;
|
|
|
|
/// Implements a disjoint-union data structure to
|
|
/// form register groups. A node is represented by an index into
|
|
/// the vector. A node can "point to" itself to indicate that it
|
|
/// is the parent of a group, or point to another node to indicate
|
|
/// that it is a member of the same group as that node.
|
|
std::vector<unsigned> GroupNodes;
|
|
|
|
/// For each register, the index of the GroupNode
|
|
/// currently representing the group that the register belongs to.
|
|
/// Register 0 is always represented by the 0 group, a group
|
|
/// composed of registers that are not eligible for anti-aliasing.
|
|
std::vector<unsigned> GroupNodeIndices;
|
|
|
|
/// Map registers to all their references within a live range.
|
|
std::multimap<unsigned, RegisterReference> RegRefs;
|
|
|
|
/// The index of the most recent kill (proceeding bottom-up),
|
|
/// or ~0u if the register is not live.
|
|
std::vector<unsigned> KillIndices;
|
|
|
|
/// The index of the most recent complete def (proceeding bottom
|
|
/// up), or ~0u if the register is live.
|
|
std::vector<unsigned> DefIndices;
|
|
|
|
public:
|
|
AggressiveAntiDepState(const unsigned TargetRegs, MachineBasicBlock *BB);
|
|
|
|
/// Return the kill indices.
|
|
std::vector<unsigned> &GetKillIndices() { return KillIndices; }
|
|
|
|
/// Return the define indices.
|
|
std::vector<unsigned> &GetDefIndices() { return DefIndices; }
|
|
|
|
/// Return the RegRefs map.
|
|
std::multimap<unsigned, RegisterReference>& GetRegRefs() { return RegRefs; }
|
|
|
|
// Get the group for a register. The returned value is
|
|
// the index of the GroupNode representing the group.
|
|
unsigned GetGroup(unsigned Reg);
|
|
|
|
// Return a vector of the registers belonging to a group.
|
|
// If RegRefs is non-NULL then only included referenced registers.
|
|
void GetGroupRegs(
|
|
unsigned Group,
|
|
std::vector<unsigned> &Regs,
|
|
std::multimap<unsigned,
|
|
AggressiveAntiDepState::RegisterReference> *RegRefs);
|
|
|
|
// Union Reg1's and Reg2's groups to form a new group.
|
|
// Return the index of the GroupNode representing the group.
|
|
unsigned UnionGroups(unsigned Reg1, unsigned Reg2);
|
|
|
|
// Remove a register from its current group and place
|
|
// it alone in its own group. Return the index of the GroupNode
|
|
// representing the registers new group.
|
|
unsigned LeaveGroup(unsigned Reg);
|
|
|
|
/// Return true if Reg is live.
|
|
bool IsLive(unsigned Reg);
|
|
};
|
|
|
|
class LLVM_LIBRARY_VISIBILITY AggressiveAntiDepBreaker
|
|
: public AntiDepBreaker {
|
|
MachineFunction &MF;
|
|
MachineRegisterInfo &MRI;
|
|
const TargetInstrInfo *TII;
|
|
const TargetRegisterInfo *TRI;
|
|
const RegisterClassInfo &RegClassInfo;
|
|
|
|
/// The set of registers that should only be
|
|
/// renamed if they are on the critical path.
|
|
BitVector CriticalPathSet;
|
|
|
|
/// The state used to identify and rename anti-dependence registers.
|
|
AggressiveAntiDepState *State = nullptr;
|
|
|
|
public:
|
|
AggressiveAntiDepBreaker(MachineFunction &MFi,
|
|
const RegisterClassInfo &RCI,
|
|
TargetSubtargetInfo::RegClassVector& CriticalPathRCs);
|
|
~AggressiveAntiDepBreaker() override;
|
|
|
|
/// Initialize anti-dep breaking for a new basic block.
|
|
void StartBlock(MachineBasicBlock *BB) override;
|
|
|
|
/// Identifiy anti-dependencies along the critical path
|
|
/// of the ScheduleDAG and break them by renaming registers.
|
|
unsigned BreakAntiDependencies(const std::vector<SUnit> &SUnits,
|
|
MachineBasicBlock::iterator Begin,
|
|
MachineBasicBlock::iterator End,
|
|
unsigned InsertPosIndex,
|
|
DbgValueVector &DbgValues) override;
|
|
|
|
/// Update liveness information to account for the current
|
|
/// instruction, which will not be scheduled.
|
|
void Observe(MachineInstr &MI, unsigned Count,
|
|
unsigned InsertPosIndex) override;
|
|
|
|
/// Finish anti-dep breaking for a basic block.
|
|
void FinishBlock() override;
|
|
|
|
private:
|
|
/// Keep track of a position in the allocation order for each regclass.
|
|
using RenameOrderType = std::map<const TargetRegisterClass *, unsigned>;
|
|
|
|
/// Return true if MO represents a register
|
|
/// that is both implicitly used and defined in MI
|
|
bool IsImplicitDefUse(MachineInstr &MI, MachineOperand &MO);
|
|
|
|
/// If MI implicitly def/uses a register, then
|
|
/// return that register and all subregisters.
|
|
void GetPassthruRegs(MachineInstr &MI, std::set<unsigned> &PassthruRegs);
|
|
|
|
void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag,
|
|
const char *header = nullptr,
|
|
const char *footer = nullptr);
|
|
|
|
void PrescanInstruction(MachineInstr &MI, unsigned Count,
|
|
std::set<unsigned> &PassthruRegs);
|
|
void ScanInstruction(MachineInstr &MI, unsigned Count);
|
|
BitVector GetRenameRegisters(unsigned Reg);
|
|
bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex,
|
|
RenameOrderType& RenameOrder,
|
|
std::map<unsigned, unsigned> &RenameMap);
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_LIB_CODEGEN_AGGRESSIVEANTIDEPBREAKER_H
|