29 #define DEBUG_TYPE "aarch64-pbqp"
36 bool isFPReg(
unsigned reg) {
37 return AArch64::FPR32RegClass.contains(reg) ||
38 AArch64::FPR64RegClass.contains(reg) ||
39 AArch64::FPR128RegClass.contains(reg);
43 bool isOdd(
unsigned reg) {
149 bool haveSameParity(
unsigned reg1,
unsigned reg2) {
150 assert(isFPReg(reg1) &&
"Expecting an FP register for reg1");
151 assert(isFPReg(reg2) &&
"Expecting an FP register for reg2");
153 return isOdd(reg1) == isOdd(reg2);
158 bool A57ChainingConstraint::addIntraChainConstraint(
PBQPRAGraph &
G,
unsigned Rd,
176 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRdAllowed =
177 &
G.getNodeMetadata(node1).getAllowedRegs();
178 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRaAllowed =
179 &
G.getNodeMetadata(node2).getAllowedRegs();
185 if (edge ==
G.invalidEdgeId()) {
188 bool livesOverlap = ld.
overlaps(la);
191 vRaAllowed->size() + 1, 0);
192 for (
unsigned i = 0, ie = vRdAllowed->size();
i != ie; ++
i) {
193 unsigned pRd = (*vRdAllowed)[
i];
194 for (
unsigned j = 0, je = vRaAllowed->size();
j != je; ++
j) {
195 unsigned pRa = (*vRaAllowed)[
j];
197 costs[
i + 1][
j + 1] = std::numeric_limits<PBQP::PBQPNum>::infinity();
199 costs[
i + 1][
j + 1] = haveSameParity(pRd, pRa) ? 0.0 : 1.0;
206 if (
G.getEdgeNode1Id(edge) == node2) {
213 for (
unsigned i = 0, ie = vRdAllowed->size();
i != ie; ++
i) {
214 unsigned pRd = (*vRdAllowed)[
i];
219 for (
unsigned j = 0, je = vRaAllowed->size();
j != je; ++
j) {
220 unsigned pRa = (*vRaAllowed)[
j];
221 if (haveSameParity(pRd, pRa))
222 if (costs[
i + 1][
j + 1] !=
223 std::numeric_limits<PBQP::PBQPNum>::infinity() &&
224 costs[
i + 1][
j + 1] > sameParityMax)
225 sameParityMax = costs[
i + 1][
j + 1];
230 for (
unsigned j = 0, je = vRaAllowed->size();
j != je; ++
j) {
231 unsigned pRa = (*vRaAllowed)[
j];
232 if (!haveSameParity(pRd, pRa))
233 if (sameParityMax > costs[
i + 1][
j + 1])
234 costs[
i + 1][
j + 1] = sameParityMax + 1.0;
242 void A57ChainingConstraint::addInterChainConstraint(
PBQPRAGraph &
G,
unsigned Rd,
247 if (Chains.
count(Ra)) {
250 <<
" to " <<
printReg(Rd, TRI) <<
'\n';);
263 for (
auto r : Chains) {
270 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRdAllowed =
271 &
G.getNodeMetadata(node1).getAllowedRegs();
274 const PBQPRAGraph::NodeMetadata::AllowedRegVector *vRrAllowed =
275 &
G.getNodeMetadata(node2).getAllowedRegs();
278 assert(edge !=
G.invalidEdgeId() &&
279 "PBQP error ! The edge should exist !");
283 if (
G.getEdgeNode1Id(edge) == node2) {
290 for (
unsigned i = 0, ie = vRdAllowed->size();
i != ie; ++
i) {
291 unsigned pRd = (*vRdAllowed)[
i];
296 for (
unsigned j = 0, je = vRrAllowed->size();
j != je; ++
j) {
297 unsigned pRa = (*vRrAllowed)[
j];
298 if (!haveSameParity(pRd, pRa))
299 if (costs[
i + 1][
j + 1] !=
300 std::numeric_limits<PBQP::PBQPNum>::infinity() &&
301 costs[
i + 1][
j + 1] > sameParityMax)
302 sameParityMax = costs[
i + 1][
j + 1];
307 for (
unsigned j = 0, je = vRrAllowed->size();
j != je; ++
j) {
308 unsigned pRa = (*vRrAllowed)[
j];
309 if (haveSameParity(pRd, pRa))
310 if (sameParityMax > costs[
i + 1][
j + 1])
311 costs[
i + 1][
j + 1] = sameParityMax + 1.0;
333 for (
const auto &
MBB: MF) {
336 for (
const auto &
MI:
MBB) {
339 for (
auto r : Chains) {
347 while (!toDel.empty()) {
348 Chains.remove(toDel.back());
353 switch (
MI.getOpcode()) {
354 case AArch64::FMSUBSrrr:
355 case AArch64::FMADDSrrr:
356 case AArch64::FNMSUBSrrr:
357 case AArch64::FNMADDSrrr:
358 case AArch64::FMSUBDrrr:
359 case AArch64::FMADDDrrr:
360 case AArch64::FNMSUBDrrr:
361 case AArch64::FNMADDDrrr: {
365 if (addIntraChainConstraint(
G, Rd, Ra))
366 addInterChainConstraint(
G, Rd, Ra);
370 case AArch64::FMLAv2f32:
371 case AArch64::FMLSv2f32: {
373 addInterChainConstraint(
G, Rd, Rd);