Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/Hexagon/HexagonSplitDouble.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- HexagonSplitDouble.cpp ---------------------------------------------===// | 1 //===- HexagonSplitDouble.cpp ---------------------------------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 | 8 |
10 #define DEBUG_TYPE "hsdr" | 9 #define DEBUG_TYPE "hsdr" |
11 | 10 |
24 #include "llvm/CodeGen/MachineLoopInfo.h" | 23 #include "llvm/CodeGen/MachineLoopInfo.h" |
25 #include "llvm/CodeGen/MachineMemOperand.h" | 24 #include "llvm/CodeGen/MachineMemOperand.h" |
26 #include "llvm/CodeGen/MachineOperand.h" | 25 #include "llvm/CodeGen/MachineOperand.h" |
27 #include "llvm/CodeGen/MachineRegisterInfo.h" | 26 #include "llvm/CodeGen/MachineRegisterInfo.h" |
28 #include "llvm/CodeGen/TargetRegisterInfo.h" | 27 #include "llvm/CodeGen/TargetRegisterInfo.h" |
28 #include "llvm/Config/llvm-config.h" | |
29 #include "llvm/IR/DebugLoc.h" | 29 #include "llvm/IR/DebugLoc.h" |
30 #include "llvm/Pass.h" | 30 #include "llvm/Pass.h" |
31 #include "llvm/Support/CommandLine.h" | 31 #include "llvm/Support/CommandLine.h" |
32 #include "llvm/Support/Compiler.h" | 32 #include "llvm/Support/Compiler.h" |
33 #include "llvm/Support/Debug.h" | 33 #include "llvm/Support/Debug.h" |
53 | 53 |
54 static cl::opt<int> MaxHSDR("max-hsdr", cl::Hidden, cl::init(-1), | 54 static cl::opt<int> MaxHSDR("max-hsdr", cl::Hidden, cl::init(-1), |
55 cl::desc("Maximum number of split partitions")); | 55 cl::desc("Maximum number of split partitions")); |
56 static cl::opt<bool> MemRefsFixed("hsdr-no-mem", cl::Hidden, cl::init(true), | 56 static cl::opt<bool> MemRefsFixed("hsdr-no-mem", cl::Hidden, cl::init(true), |
57 cl::desc("Do not split loads or stores")); | 57 cl::desc("Do not split loads or stores")); |
58 static cl::opt<bool> SplitAll("hsdr-split-all", cl::Hidden, cl::init(false), | |
59 cl::desc("Split all partitions")); | |
58 | 60 |
59 namespace { | 61 namespace { |
60 | 62 |
61 class HexagonSplitDoubleRegs : public MachineFunctionPass { | 63 class HexagonSplitDoubleRegs : public MachineFunctionPass { |
62 public: | 64 public: |
63 static char ID; | 65 static char ID; |
64 | 66 |
65 HexagonSplitDoubleRegs() : MachineFunctionPass(ID) { | 67 HexagonSplitDoubleRegs() : MachineFunctionPass(ID) {} |
66 initializeHexagonSplitDoubleRegsPass(*PassRegistry::getPassRegistry()); | |
67 } | |
68 | 68 |
69 StringRef getPassName() const override { | 69 StringRef getPassName() const override { |
70 return "Hexagon Split Double Registers"; | 70 return "Hexagon Split Double Registers"; |
71 } | 71 } |
72 | 72 |
95 bool isInduction(unsigned Reg, LoopRegMap &IRM) const; | 95 bool isInduction(unsigned Reg, LoopRegMap &IRM) const; |
96 bool isVolatileInstr(const MachineInstr *MI) const; | 96 bool isVolatileInstr(const MachineInstr *MI) const; |
97 bool isFixedInstr(const MachineInstr *MI) const; | 97 bool isFixedInstr(const MachineInstr *MI) const; |
98 void partitionRegisters(UUSetMap &P2Rs); | 98 void partitionRegisters(UUSetMap &P2Rs); |
99 int32_t profit(const MachineInstr *MI) const; | 99 int32_t profit(const MachineInstr *MI) const; |
100 int32_t profit(unsigned Reg) const; | |
100 bool isProfitable(const USet &Part, LoopRegMap &IRM) const; | 101 bool isProfitable(const USet &Part, LoopRegMap &IRM) const; |
101 | 102 |
102 void collectIndRegsForLoop(const MachineLoop *L, USet &Rs); | 103 void collectIndRegsForLoop(const MachineLoop *L, USet &Rs); |
103 void collectIndRegs(LoopRegMap &IRM); | 104 void collectIndRegs(LoopRegMap &IRM); |
104 | 105 |
149 } | 150 } |
150 return false; | 151 return false; |
151 } | 152 } |
152 | 153 |
153 bool HexagonSplitDoubleRegs::isVolatileInstr(const MachineInstr *MI) const { | 154 bool HexagonSplitDoubleRegs::isVolatileInstr(const MachineInstr *MI) const { |
154 for (auto &I : MI->memoperands()) | 155 for (auto &MO : MI->memoperands()) |
155 if (I->isVolatile()) | 156 if (MO->isVolatile() || MO->isAtomic()) |
156 return true; | 157 return true; |
157 return false; | 158 return false; |
158 } | 159 } |
159 | 160 |
160 bool HexagonSplitDoubleRegs::isFixedInstr(const MachineInstr *MI) const { | 161 bool HexagonSplitDoubleRegs::isFixedInstr(const MachineInstr *MI) const { |
161 if (MI->mayLoad() || MI->mayStore()) | 162 if (MI->mayLoad() || MI->mayStore()) |
162 if (MemRefsFixed || isVolatileInstr(MI)) | 163 if (MemRefsFixed || isVolatileInstr(MI)) |
163 return true; | 164 return true; |
164 if (MI->isDebugValue()) | 165 if (MI->isDebugInstr()) |
165 return false; | 166 return false; |
166 | 167 |
167 unsigned Opc = MI->getOpcode(); | 168 unsigned Opc = MI->getOpcode(); |
168 switch (Opc) { | 169 switch (Opc) { |
169 default: | 170 default: |
208 | 209 |
209 for (auto &Op : MI->operands()) { | 210 for (auto &Op : MI->operands()) { |
210 if (!Op.isReg()) | 211 if (!Op.isReg()) |
211 continue; | 212 continue; |
212 unsigned R = Op.getReg(); | 213 unsigned R = Op.getReg(); |
213 if (!TargetRegisterInfo::isVirtualRegister(R)) | 214 if (!Register::isVirtualRegister(R)) |
214 return true; | 215 return true; |
215 } | 216 } |
216 return false; | 217 return false; |
217 } | 218 } |
218 | 219 |
221 using UVect = std::vector<unsigned>; | 222 using UVect = std::vector<unsigned>; |
222 | 223 |
223 unsigned NumRegs = MRI->getNumVirtRegs(); | 224 unsigned NumRegs = MRI->getNumVirtRegs(); |
224 BitVector DoubleRegs(NumRegs); | 225 BitVector DoubleRegs(NumRegs); |
225 for (unsigned i = 0; i < NumRegs; ++i) { | 226 for (unsigned i = 0; i < NumRegs; ++i) { |
226 unsigned R = TargetRegisterInfo::index2VirtReg(i); | 227 unsigned R = Register::index2VirtReg(i); |
227 if (MRI->getRegClass(R) == DoubleRC) | 228 if (MRI->getRegClass(R) == DoubleRC) |
228 DoubleRegs.set(i); | 229 DoubleRegs.set(i); |
229 } | 230 } |
230 | 231 |
231 BitVector FixedRegs(NumRegs); | 232 BitVector FixedRegs(NumRegs); |
232 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { | 233 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { |
233 unsigned R = TargetRegisterInfo::index2VirtReg(x); | 234 unsigned R = Register::index2VirtReg(x); |
234 MachineInstr *DefI = MRI->getVRegDef(R); | 235 MachineInstr *DefI = MRI->getVRegDef(R); |
235 // In some cases a register may exist, but never be defined or used. | 236 // In some cases a register may exist, but never be defined or used. |
236 // It should never appear anywhere, but mark it as "fixed", just to be | 237 // It should never appear anywhere, but mark it as "fixed", just to be |
237 // safe. | 238 // safe. |
238 if (!DefI || isFixedInstr(DefI)) | 239 if (!DefI || isFixedInstr(DefI)) |
241 | 242 |
242 UUSetMap AssocMap; | 243 UUSetMap AssocMap; |
243 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { | 244 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { |
244 if (FixedRegs[x]) | 245 if (FixedRegs[x]) |
245 continue; | 246 continue; |
246 unsigned R = TargetRegisterInfo::index2VirtReg(x); | 247 unsigned R = Register::index2VirtReg(x); |
247 DEBUG(dbgs() << printReg(R, TRI) << " ~~"); | 248 LLVM_DEBUG(dbgs() << printReg(R, TRI) << " ~~"); |
248 USet &Asc = AssocMap[R]; | 249 USet &Asc = AssocMap[R]; |
249 for (auto U = MRI->use_nodbg_begin(R), Z = MRI->use_nodbg_end(); | 250 for (auto U = MRI->use_nodbg_begin(R), Z = MRI->use_nodbg_end(); |
250 U != Z; ++U) { | 251 U != Z; ++U) { |
251 MachineOperand &Op = *U; | 252 MachineOperand &Op = *U; |
252 MachineInstr *UseI = Op.getParent(); | 253 MachineInstr *UseI = Op.getParent(); |
256 MachineOperand &MO = UseI->getOperand(i); | 257 MachineOperand &MO = UseI->getOperand(i); |
257 // Skip non-registers or registers with subregisters. | 258 // Skip non-registers or registers with subregisters. |
258 if (&MO == &Op || !MO.isReg() || MO.getSubReg()) | 259 if (&MO == &Op || !MO.isReg() || MO.getSubReg()) |
259 continue; | 260 continue; |
260 unsigned T = MO.getReg(); | 261 unsigned T = MO.getReg(); |
261 if (!TargetRegisterInfo::isVirtualRegister(T)) { | 262 if (!Register::isVirtualRegister(T)) { |
262 FixedRegs.set(x); | 263 FixedRegs.set(x); |
263 continue; | 264 continue; |
264 } | 265 } |
265 if (MRI->getRegClass(T) != DoubleRC) | 266 if (MRI->getRegClass(T) != DoubleRC) |
266 continue; | 267 continue; |
267 unsigned u = TargetRegisterInfo::virtReg2Index(T); | 268 unsigned u = Register::virtReg2Index(T); |
268 if (FixedRegs[u]) | 269 if (FixedRegs[u]) |
269 continue; | 270 continue; |
270 DEBUG(dbgs() << ' ' << printReg(T, TRI)); | 271 LLVM_DEBUG(dbgs() << ' ' << printReg(T, TRI)); |
271 Asc.insert(T); | 272 Asc.insert(T); |
272 // Make it symmetric. | 273 // Make it symmetric. |
273 AssocMap[T].insert(R); | 274 AssocMap[T].insert(R); |
274 } | 275 } |
275 } | 276 } |
276 DEBUG(dbgs() << '\n'); | 277 LLVM_DEBUG(dbgs() << '\n'); |
277 } | 278 } |
278 | 279 |
279 UUMap R2P; | 280 UUMap R2P; |
280 unsigned NextP = 1; | 281 unsigned NextP = 1; |
281 USet Visited; | 282 USet Visited; |
282 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { | 283 for (int x = DoubleRegs.find_first(); x >= 0; x = DoubleRegs.find_next(x)) { |
283 unsigned R = TargetRegisterInfo::index2VirtReg(x); | 284 unsigned R = Register::index2VirtReg(x); |
284 if (Visited.count(R)) | 285 if (Visited.count(R)) |
285 continue; | 286 continue; |
286 // Create a new partition for R. | 287 // Create a new partition for R. |
287 unsigned ThisP = FixedRegs[x] ? 0 : NextP++; | 288 unsigned ThisP = FixedRegs[x] ? 0 : NextP++; |
288 UVect WorkQ; | 289 UVect WorkQ; |
302 | 303 |
303 for (auto I : R2P) | 304 for (auto I : R2P) |
304 P2Rs[I.second].insert(I.first); | 305 P2Rs[I.second].insert(I.first); |
305 } | 306 } |
306 | 307 |
307 static inline int32_t profitImm(unsigned Lo, unsigned Hi) { | 308 static inline int32_t profitImm(unsigned Imm) { |
308 int32_t P = 0; | 309 int32_t P = 0; |
309 bool LoZ1 = false, HiZ1 = false; | 310 if (Imm == 0 || Imm == 0xFFFFFFFF) |
310 if (Lo == 0 || Lo == 0xFFFFFFFF) | 311 P += 10; |
311 P += 10, LoZ1 = true; | |
312 if (Hi == 0 || Hi == 0xFFFFFFFF) | |
313 P += 10, HiZ1 = true; | |
314 if (!LoZ1 && !HiZ1 && Lo == Hi) | |
315 P += 3; | |
316 return P; | 312 return P; |
317 } | 313 } |
318 | 314 |
319 int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const { | 315 int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const { |
320 unsigned ImmX = 0; | 316 unsigned ImmX = 0; |
340 case Hexagon::A2_tfrpi: | 336 case Hexagon::A2_tfrpi: |
341 case Hexagon::CONST64: { | 337 case Hexagon::CONST64: { |
342 uint64_t D = MI->getOperand(1).getImm(); | 338 uint64_t D = MI->getOperand(1).getImm(); |
343 unsigned Lo = D & 0xFFFFFFFFULL; | 339 unsigned Lo = D & 0xFFFFFFFFULL; |
344 unsigned Hi = D >> 32; | 340 unsigned Hi = D >> 32; |
345 return profitImm(Lo, Hi); | 341 return profitImm(Lo) + profitImm(Hi); |
346 } | 342 } |
347 case Hexagon::A2_combineii: | 343 case Hexagon::A2_combineii: |
348 case Hexagon::A4_combineii: | 344 case Hexagon::A4_combineii: { |
349 return profitImm(MI->getOperand(1).getImm(), | 345 const MachineOperand &Op1 = MI->getOperand(1); |
350 MI->getOperand(2).getImm()); | 346 const MachineOperand &Op2 = MI->getOperand(2); |
347 int32_t Prof1 = Op1.isImm() ? profitImm(Op1.getImm()) : 0; | |
348 int32_t Prof2 = Op2.isImm() ? profitImm(Op2.getImm()) : 0; | |
349 return Prof1 + Prof2; | |
350 } | |
351 case Hexagon::A4_combineri: | 351 case Hexagon::A4_combineri: |
352 ImmX++; | 352 ImmX++; |
353 // Fall through into A4_combineir. | 353 // Fall through into A4_combineir. |
354 LLVM_FALLTHROUGH; | 354 LLVM_FALLTHROUGH; |
355 case Hexagon::A4_combineir: { | 355 case Hexagon::A4_combineir: { |
356 ImmX++; | 356 ImmX++; |
357 int64_t V = MI->getOperand(ImmX).getImm(); | 357 const MachineOperand &OpX = MI->getOperand(ImmX); |
358 if (V == 0 || V == -1) | 358 if (OpX.isImm()) { |
359 return 10; | 359 int64_t V = OpX.getImm(); |
360 if (V == 0 || V == -1) | |
361 return 10; | |
362 } | |
360 // Fall through into A2_combinew. | 363 // Fall through into A2_combinew. |
361 LLVM_FALLTHROUGH; | 364 LLVM_FALLTHROUGH; |
362 } | 365 } |
363 case Hexagon::A2_combinew: | 366 case Hexagon::A2_combinew: |
364 return 2; | 367 return 2; |
366 case Hexagon::A2_sxtw: | 369 case Hexagon::A2_sxtw: |
367 return 3; | 370 return 3; |
368 | 371 |
369 case Hexagon::A2_andp: | 372 case Hexagon::A2_andp: |
370 case Hexagon::A2_orp: | 373 case Hexagon::A2_orp: |
371 case Hexagon::A2_xorp: | 374 case Hexagon::A2_xorp: { |
372 return 1; | 375 unsigned Rs = MI->getOperand(1).getReg(); |
376 unsigned Rt = MI->getOperand(2).getReg(); | |
377 return profit(Rs) + profit(Rt); | |
378 } | |
373 | 379 |
374 case Hexagon::S2_asl_i_p_or: { | 380 case Hexagon::S2_asl_i_p_or: { |
375 unsigned S = MI->getOperand(3).getImm(); | 381 unsigned S = MI->getOperand(3).getImm(); |
376 if (S == 0 || S == 32) | 382 if (S == 0 || S == 32) |
377 return 10; | 383 return 10; |
388 if (S == 48) | 394 if (S == 48) |
389 return 7; | 395 return 7; |
390 return -10; | 396 return -10; |
391 } | 397 } |
392 | 398 |
399 return 0; | |
400 } | |
401 | |
402 int32_t HexagonSplitDoubleRegs::profit(unsigned Reg) const { | |
403 assert(Register::isVirtualRegister(Reg)); | |
404 | |
405 const MachineInstr *DefI = MRI->getVRegDef(Reg); | |
406 switch (DefI->getOpcode()) { | |
407 case Hexagon::A2_tfrpi: | |
408 case Hexagon::CONST64: | |
409 case Hexagon::A2_combineii: | |
410 case Hexagon::A4_combineii: | |
411 case Hexagon::A4_combineri: | |
412 case Hexagon::A4_combineir: | |
413 case Hexagon::A2_combinew: | |
414 return profit(DefI); | |
415 default: | |
416 break; | |
417 } | |
393 return 0; | 418 return 0; |
394 } | 419 } |
395 | 420 |
396 bool HexagonSplitDoubleRegs::isProfitable(const USet &Part, LoopRegMap &IRM) | 421 bool HexagonSplitDoubleRegs::isProfitable(const USet &Part, LoopRegMap &IRM) |
397 const { | 422 const { |
440 } | 465 } |
441 | 466 |
442 if (FixedNum > 0 && LoopPhiNum > 0) | 467 if (FixedNum > 0 && LoopPhiNum > 0) |
443 TotalP -= 20*LoopPhiNum; | 468 TotalP -= 20*LoopPhiNum; |
444 | 469 |
445 DEBUG(dbgs() << "Partition profit: " << TotalP << '\n'); | 470 LLVM_DEBUG(dbgs() << "Partition profit: " << TotalP << '\n'); |
471 if (SplitAll) | |
472 return true; | |
446 return TotalP > 0; | 473 return TotalP > 0; |
447 } | 474 } |
448 | 475 |
449 void HexagonSplitDoubleRegs::collectIndRegsForLoop(const MachineLoop *L, | 476 void HexagonSplitDoubleRegs::collectIndRegsForLoop(const MachineLoop *L, |
450 USet &Rs) { | 477 USet &Rs) { |
533 UVect::iterator End = llvm::remove_if(DP, NoIndOp); | 560 UVect::iterator End = llvm::remove_if(DP, NoIndOp); |
534 Rs.insert(DP.begin(), End); | 561 Rs.insert(DP.begin(), End); |
535 Rs.insert(CmpR1); | 562 Rs.insert(CmpR1); |
536 Rs.insert(CmpR2); | 563 Rs.insert(CmpR2); |
537 | 564 |
538 DEBUG({ | 565 LLVM_DEBUG({ |
539 dbgs() << "For loop at " << printMBBReference(*HB) << " ind regs: "; | 566 dbgs() << "For loop at " << printMBBReference(*HB) << " ind regs: "; |
540 dump_partition(dbgs(), Rs, *TRI); | 567 dump_partition(dbgs(), Rs, *TRI); |
541 dbgs() << '\n'; | 568 dbgs() << '\n'; |
542 }); | 569 }); |
543 } | 570 } |
576 continue; | 603 continue; |
577 } | 604 } |
578 // For register operands, set the subregister. | 605 // For register operands, set the subregister. |
579 unsigned R = Op.getReg(); | 606 unsigned R = Op.getReg(); |
580 unsigned SR = Op.getSubReg(); | 607 unsigned SR = Op.getSubReg(); |
581 bool isVirtReg = TargetRegisterInfo::isVirtualRegister(R); | 608 bool isVirtReg = Register::isVirtualRegister(R); |
582 bool isKill = Op.isKill(); | 609 bool isKill = Op.isKill(); |
583 if (isVirtReg && MRI->getRegClass(R) == DoubleRC) { | 610 if (isVirtReg && MRI->getRegClass(R) == DoubleRC) { |
584 isKill = false; | 611 isKill = false; |
585 UUPairMap::const_iterator F = PairMap.find(R); | 612 UUPairMap::const_iterator F = PairMap.find(R); |
586 if (F == PairMap.end()) { | 613 if (F == PairMap.end()) { |
708 DebugLoc DL = MI->getDebugLoc(); | 735 DebugLoc DL = MI->getDebugLoc(); |
709 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); | 736 UUPairMap::const_iterator F = PairMap.find(Op0.getReg()); |
710 assert(F != PairMap.end()); | 737 assert(F != PairMap.end()); |
711 const UUPair &P = F->second; | 738 const UUPair &P = F->second; |
712 | 739 |
713 if (Op1.isImm()) { | 740 if (!Op1.isReg()) { |
714 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second) | 741 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second) |
715 .addImm(Op1.getImm()); | 742 .add(Op1); |
716 } else if (Op1.isReg()) { | 743 } else { |
717 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second) | 744 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second) |
718 .addReg(Op1.getReg(), getRegState(Op1), Op1.getSubReg()); | 745 .addReg(Op1.getReg(), getRegState(Op1), Op1.getSubReg()); |
719 } else | 746 } |
720 llvm_unreachable("Unexpected operand"); | 747 |
721 | 748 if (!Op2.isReg()) { |
722 if (Op2.isImm()) { | |
723 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first) | 749 BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first) |
724 .addImm(Op2.getImm()); | 750 .add(Op2); |
725 } else if (Op2.isReg()) { | 751 } else { |
726 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first) | 752 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first) |
727 .addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg()); | 753 .addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg()); |
728 } else | 754 } |
729 llvm_unreachable("Unexpected operand"); | |
730 } | 755 } |
731 | 756 |
732 void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI, | 757 void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI, |
733 const UUPairMap &PairMap) { | 758 const UUPairMap &PairMap) { |
734 MachineOperand &Op0 = MI->getOperand(0); | 759 MachineOperand &Op0 = MI->getOperand(0); |
968 | 993 |
969 bool HexagonSplitDoubleRegs::splitInstr(MachineInstr *MI, | 994 bool HexagonSplitDoubleRegs::splitInstr(MachineInstr *MI, |
970 const UUPairMap &PairMap) { | 995 const UUPairMap &PairMap) { |
971 using namespace Hexagon; | 996 using namespace Hexagon; |
972 | 997 |
973 DEBUG(dbgs() << "Splitting: " << *MI); | 998 LLVM_DEBUG(dbgs() << "Splitting: " << *MI); |
974 bool Split = false; | 999 bool Split = false; |
975 unsigned Opc = MI->getOpcode(); | 1000 unsigned Opc = MI->getOpcode(); |
976 | 1001 |
977 switch (Opc) { | 1002 switch (Opc) { |
978 case TargetOpcode::PHI: | 1003 case TargetOpcode::PHI: |
1078 | 1103 |
1079 for (auto &Op : MI->operands()) { | 1104 for (auto &Op : MI->operands()) { |
1080 if (!Op.isReg() || !Op.isUse()) | 1105 if (!Op.isReg() || !Op.isUse()) |
1081 continue; | 1106 continue; |
1082 unsigned R = Op.getReg(); | 1107 unsigned R = Op.getReg(); |
1083 if (!TargetRegisterInfo::isVirtualRegister(R)) | 1108 if (!Register::isVirtualRegister(R)) |
1084 continue; | 1109 continue; |
1085 if (MRI->getRegClass(R) != DoubleRC || Op.getSubReg()) | 1110 if (MRI->getRegClass(R) != DoubleRC || Op.getSubReg()) |
1086 continue; | 1111 continue; |
1087 UUPairMap::const_iterator F = PairMap.find(R); | 1112 UUPairMap::const_iterator F = PairMap.find(R); |
1088 if (F == PairMap.end()) | 1113 if (F == PairMap.end()) |
1102 using MISet = std::set<MachineInstr *>; | 1127 using MISet = std::set<MachineInstr *>; |
1103 | 1128 |
1104 const TargetRegisterClass *IntRC = &Hexagon::IntRegsRegClass; | 1129 const TargetRegisterClass *IntRC = &Hexagon::IntRegsRegClass; |
1105 bool Changed = false; | 1130 bool Changed = false; |
1106 | 1131 |
1107 DEBUG(dbgs() << "Splitting partition: "; dump_partition(dbgs(), Part, *TRI); | 1132 LLVM_DEBUG(dbgs() << "Splitting partition: "; |
1108 dbgs() << '\n'); | 1133 dump_partition(dbgs(), Part, *TRI); dbgs() << '\n'); |
1109 | 1134 |
1110 UUPairMap PairMap; | 1135 UUPairMap PairMap; |
1111 | 1136 |
1112 MISet SplitIns; | 1137 MISet SplitIns; |
1113 for (unsigned DR : Part) { | 1138 for (unsigned DR : Part) { |
1120 U != W; ++U) | 1145 U != W; ++U) |
1121 SplitIns.insert(U->getParent()); | 1146 SplitIns.insert(U->getParent()); |
1122 | 1147 |
1123 unsigned LoR = MRI->createVirtualRegister(IntRC); | 1148 unsigned LoR = MRI->createVirtualRegister(IntRC); |
1124 unsigned HiR = MRI->createVirtualRegister(IntRC); | 1149 unsigned HiR = MRI->createVirtualRegister(IntRC); |
1125 DEBUG(dbgs() << "Created mapping: " << printReg(DR, TRI) << " -> " | 1150 LLVM_DEBUG(dbgs() << "Created mapping: " << printReg(DR, TRI) << " -> " |
1126 << printReg(HiR, TRI) << ':' << printReg(LoR, TRI) << '\n'); | 1151 << printReg(HiR, TRI) << ':' << printReg(LoR, TRI) |
1152 << '\n'); | |
1127 PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR))); | 1153 PairMap.insert(std::make_pair(DR, UUPair(LoR, HiR))); |
1128 } | 1154 } |
1129 | 1155 |
1130 MISet Erase; | 1156 MISet Erase; |
1131 for (auto MI : SplitIns) { | 1157 for (auto MI : SplitIns) { |
1158 | 1184 |
1159 return Changed; | 1185 return Changed; |
1160 } | 1186 } |
1161 | 1187 |
1162 bool HexagonSplitDoubleRegs::runOnMachineFunction(MachineFunction &MF) { | 1188 bool HexagonSplitDoubleRegs::runOnMachineFunction(MachineFunction &MF) { |
1163 DEBUG(dbgs() << "Splitting double registers in function: " | |
1164 << MF.getName() << '\n'); | |
1165 | |
1166 if (skipFunction(MF.getFunction())) | 1189 if (skipFunction(MF.getFunction())) |
1167 return false; | 1190 return false; |
1191 | |
1192 LLVM_DEBUG(dbgs() << "Splitting double registers in function: " | |
1193 << MF.getName() << '\n'); | |
1168 | 1194 |
1169 auto &ST = MF.getSubtarget<HexagonSubtarget>(); | 1195 auto &ST = MF.getSubtarget<HexagonSubtarget>(); |
1170 TRI = ST.getRegisterInfo(); | 1196 TRI = ST.getRegisterInfo(); |
1171 TII = ST.getInstrInfo(); | 1197 TII = ST.getInstrInfo(); |
1172 MRI = &MF.getRegInfo(); | 1198 MRI = &MF.getRegInfo(); |
1176 LoopRegMap IRM; | 1202 LoopRegMap IRM; |
1177 | 1203 |
1178 collectIndRegs(IRM); | 1204 collectIndRegs(IRM); |
1179 partitionRegisters(P2Rs); | 1205 partitionRegisters(P2Rs); |
1180 | 1206 |
1181 DEBUG({ | 1207 LLVM_DEBUG({ |
1182 dbgs() << "Register partitioning: (partition #0 is fixed)\n"; | 1208 dbgs() << "Register partitioning: (partition #0 is fixed)\n"; |
1183 for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) { | 1209 for (UUSetMap::iterator I = P2Rs.begin(), E = P2Rs.end(); I != E; ++I) { |
1184 dbgs() << '#' << I->first << " -> "; | 1210 dbgs() << '#' << I->first << " -> "; |
1185 dump_partition(dbgs(), I->second, *TRI); | 1211 dump_partition(dbgs(), I->second, *TRI); |
1186 dbgs() << '\n'; | 1212 dbgs() << '\n'; |
1194 if (I->first == 0) | 1220 if (I->first == 0) |
1195 continue; | 1221 continue; |
1196 if (Limit >= 0 && Counter >= Limit) | 1222 if (Limit >= 0 && Counter >= Limit) |
1197 break; | 1223 break; |
1198 USet &Part = I->second; | 1224 USet &Part = I->second; |
1199 DEBUG(dbgs() << "Calculating profit for partition #" << I->first << '\n'); | 1225 LLVM_DEBUG(dbgs() << "Calculating profit for partition #" << I->first |
1226 << '\n'); | |
1200 if (!isProfitable(Part, IRM)) | 1227 if (!isProfitable(Part, IRM)) |
1201 continue; | 1228 continue; |
1202 Counter++; | 1229 Counter++; |
1203 Changed |= splitPartition(Part); | 1230 Changed |= splitPartition(Part); |
1204 } | 1231 } |