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.
bool remove(const value_type &X)
Remove an item from the set vector.
LLVM_NODISCARD bool empty() const
void apply(PBQPRAGraph &G) override
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool expiredAt(SlotIndex index) const
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
bool regsOverlap(unsigned regA, unsigned regB) const
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
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.
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.
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual void print(raw_ostream &O, const Module *M) const
print - Print out the internal state of the pass.
SlotIndex - An opaque wrapper around machine indexes.