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];
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)) {
264 for (
auto r : Chains) {
271 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRdAllowed =
275 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRrAllowed =
280 "PBQP error ! The edge should exist !");
282 DEBUG(
dbgs() <<
"Refining constraint !\n";);
291 for (
unsigned i = 0, ie = vRdAllowed->size(); i != ie; ++i) {
292 unsigned pRd = (*vRdAllowed)[i];
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);
void push_back(const T &Elt)
NodeId getEdgeNode1Id(EdgeId EId) const
Get the first node connected to this edge.
EdgeId addEdge(NodeId N1Id, NodeId N2Id, OtherVectorT Costs)
Add an edge between the given nodes with the given costs.
EdgeId findEdge(NodeId N1Id, NodeId N2Id)
Get the edge connecting two nodes.
LiveInterval - This class represents the liveness of a register, or stack slot.
SlotIndex getInstructionIndex(const MachineInstr *instr) const
Returns the base index of the given instruction.
void updateEdgeCosts(EdgeId EId, OtherMatrixT Costs)
Update an edge's cost matrix.
RegAllocSolverImpl::RawMatrix RawMatrix
NodeMetadata & getNodeMetadata(NodeId NId)
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.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
bool remove(const value_type &X)
Remove an item from the set vector.
PrintReg - Helper class for printing registers on a raw_ostream.
void apply(PBQPRAGraph &G) override
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool expiredAt(SlotIndex index) const
bool regsOverlap(unsigned regA, unsigned regB) const
regsOverlap - Returns true if the two registers are equal or alias each other.
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
GraphMetadata & getMetadata()
Get a reference to the graph metadata.
const Matrix & getEdgeCosts(EdgeId EId) const
Get an edge's cost matrix.
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 dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
static EdgeId invalidEdgeId()
Returns a value representing an invalid (non-existent) edge.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
static bool regJustKilledBefore(const LiveIntervals &LIs, unsigned reg, const MachineInstr &MI)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
SlotIndex - An opaque wrapper around machine indexes.