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;