Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/Hexagon/HexagonStoreWidening.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 //===- HexagonStoreWidening.cpp -------------------------------------------===// | 1 //===- HexagonStoreWidening.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 // Replace sequences of "narrow" stores to adjacent memory locations with | 8 // Replace sequences of "narrow" stores to adjacent memory locations with |
10 // a fewer "wide" stores that have the same effect. | 9 // a fewer "wide" stores that have the same effect. |
11 // For example, replace: | 10 // For example, replace: |
336 // by checking if the next wider size would exceed the limit. | 335 // by checking if the next wider size would exceed the limit. |
337 if ((2*SizeAccum-1) & FirstOffset) | 336 if ((2*SizeAccum-1) & FirstOffset) |
338 return false; | 337 return false; |
339 | 338 |
340 OG.push_back(FirstMI); | 339 OG.push_back(FirstMI); |
341 MachineInstr *S1 = FirstMI, *S2 = *(Begin+1); | 340 MachineInstr *S1 = FirstMI; |
342 InstrGroup::iterator I = Begin+1; | |
343 | 341 |
344 // Pow2Num will be the largest number of elements in OG such that the sum | 342 // Pow2Num will be the largest number of elements in OG such that the sum |
345 // of sizes of stores 0...Pow2Num-1 will be a power of 2. | 343 // of sizes of stores 0...Pow2Num-1 will be a power of 2. |
346 unsigned Pow2Num = 1; | 344 unsigned Pow2Num = 1; |
347 unsigned Pow2Size = SizeAccum; | 345 unsigned Pow2Size = SizeAccum; |
349 // Be greedy: keep accumulating stores as long as they are to adjacent | 347 // Be greedy: keep accumulating stores as long as they are to adjacent |
350 // memory locations, and as long as the total number of bytes stored | 348 // memory locations, and as long as the total number of bytes stored |
351 // does not exceed the limit (MaxSize). | 349 // does not exceed the limit (MaxSize). |
352 // Keep track of when the total size covered is a power of 2, since | 350 // Keep track of when the total size covered is a power of 2, since |
353 // this is a size a single store can cover. | 351 // this is a size a single store can cover. |
354 while (I != End) { | 352 for (InstrGroup::iterator I = Begin + 1; I != End; ++I) { |
355 S2 = *I; | 353 MachineInstr *S2 = *I; |
356 // Stores are sorted, so if S1 and S2 are not adjacent, there won't be | 354 // Stores are sorted, so if S1 and S2 are not adjacent, there won't be |
357 // any other store to fill the "hole". | 355 // any other store to fill the "hole". |
358 if (!storesAreAdjacent(S1, S2)) | 356 if (!storesAreAdjacent(S1, S2)) |
359 break; | 357 break; |
360 | 358 |
370 } | 368 } |
371 if ((2*Pow2Size-1) & FirstOffset) | 369 if ((2*Pow2Size-1) & FirstOffset) |
372 break; | 370 break; |
373 | 371 |
374 S1 = S2; | 372 S1 = S2; |
375 ++I; | |
376 } | 373 } |
377 | 374 |
378 // The stores don't add up to anything that can be widened. Clean up. | 375 // The stores don't add up to anything that can be widened. Clean up. |
379 if (Pow2Num <= 1) { | 376 if (Pow2Num <= 1) { |
380 OG.clear(); | 377 OG.clear(); |
431 | 428 |
432 int Val = (TotalSize == 2) ? int16_t(Acc) : int(Acc); | 429 int Val = (TotalSize == 2) ? int16_t(Acc) : int(Acc); |
433 const MCInstrDesc &StD = TII->get(WOpc); | 430 const MCInstrDesc &StD = TII->get(WOpc); |
434 MachineOperand &MR = FirstSt->getOperand(0); | 431 MachineOperand &MR = FirstSt->getOperand(0); |
435 int64_t Off = FirstSt->getOperand(1).getImm(); | 432 int64_t Off = FirstSt->getOperand(1).getImm(); |
436 MachineInstr *StI = BuildMI(*MF, DL, StD) | 433 MachineInstr *StI = |
437 .addReg(MR.getReg(), getKillRegState(MR.isKill())) | 434 BuildMI(*MF, DL, StD) |
438 .addImm(Off) | 435 .addReg(MR.getReg(), getKillRegState(MR.isKill()), MR.getSubReg()) |
439 .addImm(Val); | 436 .addImm(Off) |
437 .addImm(Val); | |
440 StI->addMemOperand(*MF, NewM); | 438 StI->addMemOperand(*MF, NewM); |
441 NG.push_back(StI); | 439 NG.push_back(StI); |
442 } else { | 440 } else { |
443 // Create vreg = A2_tfrsi #Acc; mem[hw] = vreg | 441 // Create vreg = A2_tfrsi #Acc; mem[hw] = vreg |
444 const MCInstrDesc &TfrD = TII->get(Hexagon::A2_tfrsi); | 442 const MCInstrDesc &TfrD = TII->get(Hexagon::A2_tfrsi); |
453 assert(WOpc && "Unexpected size"); | 451 assert(WOpc && "Unexpected size"); |
454 | 452 |
455 const MCInstrDesc &StD = TII->get(WOpc); | 453 const MCInstrDesc &StD = TII->get(WOpc); |
456 MachineOperand &MR = FirstSt->getOperand(0); | 454 MachineOperand &MR = FirstSt->getOperand(0); |
457 int64_t Off = FirstSt->getOperand(1).getImm(); | 455 int64_t Off = FirstSt->getOperand(1).getImm(); |
458 MachineInstr *StI = BuildMI(*MF, DL, StD) | 456 MachineInstr *StI = |
459 .addReg(MR.getReg(), getKillRegState(MR.isKill())) | 457 BuildMI(*MF, DL, StD) |
460 .addImm(Off) | 458 .addReg(MR.getReg(), getKillRegState(MR.isKill()), MR.getSubReg()) |
461 .addReg(VReg, RegState::Kill); | 459 .addImm(Off) |
460 .addReg(VReg, RegState::Kill); | |
462 StI->addMemOperand(*MF, NewM); | 461 StI->addMemOperand(*MF, NewM); |
463 NG.push_back(StI); | 462 NG.push_back(StI); |
464 } | 463 } |
465 | 464 |
466 return true; | 465 return true; |
470 // new group NG. Conceptually, remove all instructions in OG, and then | 469 // new group NG. Conceptually, remove all instructions in OG, and then |
471 // insert all instructions in NG, starting at where the first instruction | 470 // insert all instructions in NG, starting at where the first instruction |
472 // from OG was (in the order in which they appeared in the basic block). | 471 // from OG was (in the order in which they appeared in the basic block). |
473 // (The ordering in OG does not have to match the order in the basic block.) | 472 // (The ordering in OG does not have to match the order in the basic block.) |
474 bool HexagonStoreWidening::replaceStores(InstrGroup &OG, InstrGroup &NG) { | 473 bool HexagonStoreWidening::replaceStores(InstrGroup &OG, InstrGroup &NG) { |
475 DEBUG({ | 474 LLVM_DEBUG({ |
476 dbgs() << "Replacing:\n"; | 475 dbgs() << "Replacing:\n"; |
477 for (auto I : OG) | 476 for (auto I : OG) |
478 dbgs() << " " << *I; | 477 dbgs() << " " << *I; |
479 dbgs() << "with\n"; | 478 dbgs() << "with\n"; |
480 for (auto I : NG) | 479 for (auto I : NG) |
574 auto Less = [] (const MachineInstr *A, const MachineInstr *B) -> bool { | 573 auto Less = [] (const MachineInstr *A, const MachineInstr *B) -> bool { |
575 return getStoreOffset(A) < getStoreOffset(B); | 574 return getStoreOffset(A) < getStoreOffset(B); |
576 }; | 575 }; |
577 for (auto &G : SGs) { | 576 for (auto &G : SGs) { |
578 assert(G.size() > 1 && "Store group with fewer than 2 elements"); | 577 assert(G.size() > 1 && "Store group with fewer than 2 elements"); |
579 std::sort(G.begin(), G.end(), Less); | 578 llvm::sort(G, Less); |
580 | 579 |
581 Changed |= processStoreGroup(G); | 580 Changed |= processStoreGroup(G); |
582 } | 581 } |
583 | 582 |
584 return Changed; | 583 return Changed; |