@@ -309,23 +309,18 @@ class SICacheControl {
309
309
SIAtomicAddrSpace AddrSpace) const = 0;
310
310
311
311
// / Update \p MI memory instruction of kind \p Op associated with address
312
- // / spaces \p AddrSpace to indicate it is volatile and/or nontemporal. Return
313
- // / true iff the instruction was modified.
312
+ // / spaces \p AddrSpace to indicate it is volatile and/or
313
+ // / nontemporal/last-use. Return true iff the instruction was modified.
314
314
virtual bool enableVolatileAndOrNonTemporal (MachineBasicBlock::iterator &MI,
315
315
SIAtomicAddrSpace AddrSpace,
316
316
SIMemOp Op, bool IsVolatile,
317
- bool IsNonTemporal) const = 0;
317
+ bool IsNonTemporal,
318
+ bool IsLastUse = false ) const = 0;
318
319
319
320
virtual bool expandSystemScopeStore (MachineBasicBlock::iterator &MI) const {
320
321
return false ;
321
322
};
322
323
323
- // / Update \p MI memory instruction to indicate it is a last use. Return true
324
- // / iff the instruction was modified.
325
- virtual bool enableLastUse (MachineInstr &MI, bool IsLastUse) const {
326
- return false ;
327
- }
328
-
329
324
// / Inserts any necessary instructions at position \p Pos relative
330
325
// / to instruction \p MI to ensure memory instructions before \p Pos of kind
331
326
// / \p Op associated with address spaces \p AddrSpace have completed. Used
@@ -404,8 +399,8 @@ class SIGfx6CacheControl : public SICacheControl {
404
399
405
400
bool enableVolatileAndOrNonTemporal (MachineBasicBlock::iterator &MI,
406
401
SIAtomicAddrSpace AddrSpace, SIMemOp Op,
407
- bool IsVolatile,
408
- bool IsNonTemporal ) const override ;
402
+ bool IsVolatile, bool IsNonTemporal,
403
+ bool IsLastUse ) const override ;
409
404
410
405
bool insertWait (MachineBasicBlock::iterator &MI,
411
406
SIAtomicScope Scope,
@@ -457,8 +452,8 @@ class SIGfx90ACacheControl : public SIGfx7CacheControl {
457
452
458
453
bool enableVolatileAndOrNonTemporal (MachineBasicBlock::iterator &MI,
459
454
SIAtomicAddrSpace AddrSpace, SIMemOp Op,
460
- bool IsVolatile,
461
- bool IsNonTemporal ) const override ;
455
+ bool IsVolatile, bool IsNonTemporal,
456
+ bool IsLastUse ) const override ;
462
457
463
458
bool insertWait (MachineBasicBlock::iterator &MI,
464
459
SIAtomicScope Scope,
@@ -518,8 +513,8 @@ class SIGfx940CacheControl : public SIGfx90ACacheControl {
518
513
519
514
bool enableVolatileAndOrNonTemporal (MachineBasicBlock::iterator &MI,
520
515
SIAtomicAddrSpace AddrSpace, SIMemOp Op,
521
- bool IsVolatile,
522
- bool IsNonTemporal ) const override ;
516
+ bool IsVolatile, bool IsNonTemporal,
517
+ bool IsLastUse ) const override ;
523
518
524
519
bool insertAcquire (MachineBasicBlock::iterator &MI, SIAtomicScope Scope,
525
520
SIAtomicAddrSpace AddrSpace, Position Pos) const override ;
@@ -562,8 +557,8 @@ class SIGfx10CacheControl : public SIGfx7CacheControl {
562
557
563
558
bool enableVolatileAndOrNonTemporal (MachineBasicBlock::iterator &MI,
564
559
SIAtomicAddrSpace AddrSpace, SIMemOp Op,
565
- bool IsVolatile,
566
- bool IsNonTemporal ) const override ;
560
+ bool IsVolatile, bool IsNonTemporal,
561
+ bool IsLastUse ) const override ;
567
562
568
563
bool insertWait (MachineBasicBlock::iterator &MI,
569
564
SIAtomicScope Scope,
@@ -588,8 +583,8 @@ class SIGfx11CacheControl : public SIGfx10CacheControl {
588
583
589
584
bool enableVolatileAndOrNonTemporal (MachineBasicBlock::iterator &MI,
590
585
SIAtomicAddrSpace AddrSpace, SIMemOp Op,
591
- bool IsVolatile,
592
- bool IsNonTemporal ) const override ;
586
+ bool IsVolatile, bool IsNonTemporal,
587
+ bool IsLastUse ) const override ;
593
588
};
594
589
595
590
class SIGfx12CacheControl : public SIGfx11CacheControl {
@@ -624,12 +619,10 @@ class SIGfx12CacheControl : public SIGfx11CacheControl {
624
619
625
620
bool enableVolatileAndOrNonTemporal (MachineBasicBlock::iterator &MI,
626
621
SIAtomicAddrSpace AddrSpace, SIMemOp Op,
627
- bool IsVolatile,
628
- bool IsNonTemporal ) const override ;
622
+ bool IsVolatile, bool IsNonTemporal,
623
+ bool IsLastUse ) const override ;
629
624
630
625
bool expandSystemScopeStore (MachineBasicBlock::iterator &MI) const override ;
631
-
632
- bool enableLastUse (MachineInstr &MI, bool IsLastUse) const override ;
633
626
};
634
627
635
628
class SIMemoryLegalizer final : public MachineFunctionPass {
@@ -983,7 +976,7 @@ bool SIGfx6CacheControl::enableRMWCacheBypass(
983
976
984
977
bool SIGfx6CacheControl::enableVolatileAndOrNonTemporal (
985
978
MachineBasicBlock::iterator &MI, SIAtomicAddrSpace AddrSpace, SIMemOp Op,
986
- bool IsVolatile, bool IsNonTemporal) const {
979
+ bool IsVolatile, bool IsNonTemporal, bool IsLastUse = false ) const {
987
980
// Only handle load and store, not atomic read-modify-write insructions. The
988
981
// latter use glc to indicate if the atomic returns a result and so must not
989
982
// be used for cache control.
@@ -1336,7 +1329,7 @@ bool SIGfx90ACacheControl::enableRMWCacheBypass(
1336
1329
1337
1330
bool SIGfx90ACacheControl::enableVolatileAndOrNonTemporal (
1338
1331
MachineBasicBlock::iterator &MI, SIAtomicAddrSpace AddrSpace, SIMemOp Op,
1339
- bool IsVolatile, bool IsNonTemporal) const {
1332
+ bool IsVolatile, bool IsNonTemporal, bool IsLastUse = false ) const {
1340
1333
// Only handle load and store, not atomic read-modify-write insructions. The
1341
1334
// latter use glc to indicate if the atomic returns a result and so must not
1342
1335
// be used for cache control.
@@ -1638,7 +1631,7 @@ bool SIGfx940CacheControl::enableRMWCacheBypass(
1638
1631
1639
1632
bool SIGfx940CacheControl::enableVolatileAndOrNonTemporal (
1640
1633
MachineBasicBlock::iterator &MI, SIAtomicAddrSpace AddrSpace, SIMemOp Op,
1641
- bool IsVolatile, bool IsNonTemporal) const {
1634
+ bool IsVolatile, bool IsNonTemporal, bool IsLastUse = false ) const {
1642
1635
// Only handle load and store, not atomic read-modify-write insructions. The
1643
1636
// latter use glc to indicate if the atomic returns a result and so must not
1644
1637
// be used for cache control.
@@ -1870,7 +1863,7 @@ bool SIGfx10CacheControl::enableLoadCacheBypass(
1870
1863
1871
1864
bool SIGfx10CacheControl::enableVolatileAndOrNonTemporal (
1872
1865
MachineBasicBlock::iterator &MI, SIAtomicAddrSpace AddrSpace, SIMemOp Op,
1873
- bool IsVolatile, bool IsNonTemporal) const {
1866
+ bool IsVolatile, bool IsNonTemporal, bool IsLastUse = false ) const {
1874
1867
1875
1868
// Only handle load and store, not atomic read-modify-write insructions. The
1876
1869
// latter use glc to indicate if the atomic returns a result and so must not
@@ -2141,7 +2134,7 @@ bool SIGfx11CacheControl::enableLoadCacheBypass(
2141
2134
2142
2135
bool SIGfx11CacheControl::enableVolatileAndOrNonTemporal (
2143
2136
MachineBasicBlock::iterator &MI, SIAtomicAddrSpace AddrSpace, SIMemOp Op,
2144
- bool IsVolatile, bool IsNonTemporal) const {
2137
+ bool IsVolatile, bool IsNonTemporal, bool IsLastUse = false ) const {
2145
2138
2146
2139
// Only handle load and store, not atomic read-modify-write insructions. The
2147
2140
// latter use glc to indicate if the atomic returns a result and so must not
@@ -2393,7 +2386,7 @@ bool SIGfx12CacheControl::insertAcquire(MachineBasicBlock::iterator &MI,
2393
2386
2394
2387
bool SIGfx12CacheControl::enableVolatileAndOrNonTemporal (
2395
2388
MachineBasicBlock::iterator &MI, SIAtomicAddrSpace AddrSpace, SIMemOp Op,
2396
- bool IsVolatile, bool IsNonTemporal) const {
2389
+ bool IsVolatile, bool IsNonTemporal, bool IsLastUse = false ) const {
2397
2390
2398
2391
// Only handle load and store, not atomic read-modify-write instructions.
2399
2392
assert (MI->mayLoad () ^ MI->mayStore ());
@@ -2406,7 +2399,10 @@ bool SIGfx12CacheControl::enableVolatileAndOrNonTemporal(
2406
2399
2407
2400
bool Changed = false ;
2408
2401
2409
- if (IsNonTemporal) {
2402
+ if (IsLastUse) {
2403
+ // Set last-use hint.
2404
+ Changed |= setTH (MI, AMDGPU::CPol::TH_LU);
2405
+ } else if (IsNonTemporal) {
2410
2406
// Set non-temporal hint for all cache levels.
2411
2407
Changed |= setTH (MI, AMDGPU::CPol::TH_NT);
2412
2408
}
@@ -2429,12 +2425,6 @@ bool SIGfx12CacheControl::enableVolatileAndOrNonTemporal(
2429
2425
return Changed;
2430
2426
}
2431
2427
2432
- bool SIGfx12CacheControl::enableLastUse (MachineInstr &MI,
2433
- bool IsLastUse) const {
2434
- assert (MI.mayLoad () && !MI.mayStore ());
2435
- return IsLastUse ? setTH (MI, AMDGPU::CPol::TH_LU) : false ;
2436
- }
2437
-
2438
2428
bool SIGfx12CacheControl::expandSystemScopeStore (
2439
2429
MachineBasicBlock::iterator &MI) const {
2440
2430
MachineOperand *CPol = TII->getNamedOperand (*MI, OpName::cpol);
@@ -2491,18 +2481,12 @@ bool SIMemoryLegalizer::expandLoad(const SIMemOpInfo &MOI,
2491
2481
return Changed;
2492
2482
}
2493
2483
2494
- // enableVolatileAndOrNonTemporal can insert instructions and advance iterator
2495
- // MI and we need original instruction for enabling last use.
2496
- MachineInstr &Inst = *MI;
2497
-
2498
2484
// Atomic instructions already bypass caches to the scope specified by the
2499
- // SyncScope operand. Only non-atomic volatile and nontemporal instructions
2500
- // need additional treatment.
2501
- Changed |= CC->enableVolatileAndOrNonTemporal (MI, MOI.getInstrAddrSpace (),
2502
- SIMemOp::LOAD, MOI.isVolatile (),
2503
- MOI.isNonTemporal ());
2504
-
2505
- Changed |= CC->enableLastUse (Inst, MOI.isLastUse ());
2485
+ // SyncScope operand. Only non-atomic volatile and nontemporal/last-use
2486
+ // instructions need additional treatment.
2487
+ Changed |= CC->enableVolatileAndOrNonTemporal (
2488
+ MI, MOI.getInstrAddrSpace (), SIMemOp::LOAD, MOI.isVolatile (),
2489
+ MOI.isNonTemporal (), MOI.isLastUse ());
2506
2490
2507
2491
return Changed;
2508
2492
}
0 commit comments