18 #define DEBUG_TYPE "aarch64-pbqp" 37 bool isFPReg(
unsigned reg) {
38 return AArch64::FPR32RegClass.contains(reg) ||
39 AArch64::FPR64RegClass.contains(reg) ||
40 AArch64::FPR128RegClass.contains(reg);
44 bool isOdd(
unsigned reg) {
150 bool haveSameParity(
unsigned reg1,
unsigned reg2) {
151 assert(isFPReg(reg1) &&
"Expecting an FP register for reg1");
152 assert(isFPReg(reg2) &&
"Expecting an FP register for reg2");
154 return isOdd(reg1) == isOdd(reg2);
159 bool A57ChainingConstraint::addIntraChainConstraint(
PBQPRAGraph &
G,
unsigned Rd,
177 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRdAllowed =
179 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRaAllowed =
189 bool livesOverlap = ld.
overlaps(la);
192 vRaAllowed->size() + 1, 0);
193 for (
unsigned i = 0, ie = vRdAllowed->size(); i != ie; ++i) {
194 unsigned pRd = (*vRdAllowed)[i];
195 for (
unsigned j = 0, je = vRaAllowed->size(); j != je; ++j) {
196 unsigned pRa = (*vRaAllowed)[j];
198 costs[i + 1][j + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
200 costs[i + 1][j + 1] = haveSameParity(pRd, pRa) ? 0.0 : 1.0;
203 G.
addEdge(node1, node2, std::move(costs));
214 for (
unsigned i = 0, ie = vRdAllowed->size(); i != ie; ++i) {
215 unsigned pRd = (*vRdAllowed)[i];
219 PBQP::PBQPNum sameParityMax = std::numeric_limits<PBQP::PBQPNum>::min();
220 for (
unsigned j = 0, je = vRaAllowed->size(); j != je; ++j) {
221 unsigned pRa = (*vRaAllowed)[j];
222 if (haveSameParity(pRd, pRa))
223 if (costs[i + 1][j + 1] !=
224 std::numeric_limits<PBQP::PBQPNum>::infinity() &&
225 costs[i + 1][j + 1] > sameParityMax)
226 sameParityMax = costs[i + 1][j + 1];
231 for (
unsigned j = 0, je = vRaAllowed->size(); j != je; ++j) {
232 unsigned pRa = (*vRaAllowed)[j];
233 if (!haveSameParity(pRd, pRa))
234 if (sameParityMax > costs[i + 1][j + 1])
235 costs[i + 1][j + 1] = sameParityMax + 1.0;
243 void A57ChainingConstraint::addInterChainConstraint(
PBQPRAGraph &G,
unsigned Rd,
248 if (Chains.
count(Ra)) {
251 <<
" to " <<
printReg(Rd, TRI) <<
'\n';);
264 for (
auto r : Chains) {
271 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRdAllowed =
275 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRrAllowed =
280 "PBQP error ! The edge should exist !");
291 for (
unsigned i = 0, ie = vRdAllowed->size(); i != ie; ++i) {
292 unsigned pRd = (*vRdAllowed)[i];
296 PBQP::PBQPNum sameParityMax = std::numeric_limits<PBQP::PBQPNum>::min();
297 for (
unsigned j = 0, je = vRrAllowed->size(); j != je; ++j) {
298 unsigned pRa = (*vRrAllowed)[j];
299 if (!haveSameParity(pRd, pRa))
300 if (costs[i + 1][j + 1] !=
301 std::numeric_limits<PBQP::PBQPNum>::infinity() &&
302 costs[i + 1][j + 1] > sameParityMax)
303 sameParityMax = costs[i + 1][j + 1];
308 for (
unsigned j = 0, je = vRrAllowed->size(); j != je; ++j) {
309 unsigned pRa = (*vRrAllowed)[j];
310 if (haveSameParity(pRd, pRa))
311 if (sameParityMax > costs[i + 1][j + 1])
312 costs[i + 1][j + 1] = sameParityMax + 1.0;
334 for (
const auto &MBB: MF) {
337 for (
const auto &
MI: MBB) {
340 for (
auto r : Chains) {
348 while (!toDel.
empty()) {
349 Chains.remove(toDel.
back());
354 switch (
MI.getOpcode()) {
355 case AArch64::FMSUBSrrr:
356 case AArch64::FMADDSrrr:
357 case AArch64::FNMSUBSrrr:
358 case AArch64::FNMADDSrrr:
359 case AArch64::FMSUBDrrr:
360 case AArch64::FMADDDrrr:
361 case AArch64::FNMSUBDrrr:
362 case AArch64::FNMADDDrrr: {
363 unsigned Rd =
MI.getOperand(0).getReg();
364 unsigned Ra =
MI.getOperand(3).getReg();
366 if (addIntraChainConstraint(G, Rd, Ra))
367 addInterChainConstraint(G, Rd, Ra);
371 case AArch64::FMLAv2f32:
372 case AArch64::FMLSv2f32: {
373 unsigned Rd =
MI.getOperand(0).getReg();
374 addInterChainConstraint(G, Rd, Rd);
This class represents lattice values for constants.
EdgeId addEdge(NodeId N1Id, NodeId N2Id, OtherVectorT Costs)
Add an edge between the given nodes with the given costs.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void push_back(const T &Elt)
EdgeId findEdge(NodeId N1Id, NodeId N2Id)
Get the edge connecting two nodes.
LiveInterval - This class represents the liveness of a register, or stack slot.
void updateEdgeCosts(EdgeId EId, OtherMatrixT Costs)
Update an edge's cost matrix.
NodeId getEdgeNode1Id(EdgeId EId) const
Get the first node connected to this edge.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
NodeMetadata & getNodeMetadata(NodeId NId)
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
bool remove(const value_type &X)
Remove an item from the set vector.
void apply(PBQPRAGraph &G) override
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
const Matrix & getEdgeCosts(EdgeId EId) const
Get an edge's cost matrix.
bool expiredAt(SlotIndex index) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
GraphMetadata & getMetadata()
Get a reference to the graph metadata.
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
LiveInterval & getInterval(unsigned Reg)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
void clear()
Completely clear the SetVector.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
static EdgeId invalidEdgeId()
Returns a value representing an invalid (non-existent) edge.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
LLVM_NODISCARD bool empty() const
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
static bool regJustKilledBefore(const LiveIntervals &LIs, unsigned reg, const MachineInstr &MI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
typename RegAllocSolverImpl ::RawMatrix RawMatrix
SlotIndex - An opaque wrapper around machine indexes.