@@ -1400,6 +1400,61 @@ static void recomputeLiveInValues(
1400
1400
}
1401
1401
}
1402
1402
1403
+ // Utility function which clones all instructions from "ChainToBase"
1404
+ // and inserts them before "InsertBefore". Returns rematerialized value
1405
+ // which should be used after statepoint.
1406
+ static Instruction *rematerializeChain (ArrayRef<Instruction *> ChainToBase,
1407
+ Instruction *InsertBefore,
1408
+ Value *RootOfChain,
1409
+ Value *AlternateLiveBase) {
1410
+ Instruction *LastClonedValue = nullptr ;
1411
+ Instruction *LastValue = nullptr ;
1412
+ // Walk backwards to visit top-most instructions first.
1413
+ for (Instruction *Instr :
1414
+ make_range (ChainToBase.rbegin (), ChainToBase.rend ())) {
1415
+ // Only GEP's and casts are supported as we need to be careful to not
1416
+ // introduce any new uses of pointers not in the liveset.
1417
+ // Note that it's fine to introduce new uses of pointers which were
1418
+ // otherwise not used after this statepoint.
1419
+ assert (isa<GetElementPtrInst>(Instr) || isa<CastInst>(Instr));
1420
+
1421
+ Instruction *ClonedValue = Instr->clone ();
1422
+ ClonedValue->insertBefore (InsertBefore);
1423
+ ClonedValue->setName (Instr->getName () + " .remat" );
1424
+
1425
+ // If it is not first instruction in the chain then it uses previously
1426
+ // cloned value. We should update it to use cloned value.
1427
+ if (LastClonedValue) {
1428
+ assert (LastValue);
1429
+ ClonedValue->replaceUsesOfWith (LastValue, LastClonedValue);
1430
+ #ifndef NDEBUG
1431
+ for (auto *OpValue : ClonedValue->operand_values ()) {
1432
+ // Assert that cloned instruction does not use any instructions from
1433
+ // this chain other than LastClonedValue
1434
+ assert (!is_contained (ChainToBase, OpValue) &&
1435
+ " incorrect use in rematerialization chain" );
1436
+ // Assert that the cloned instruction does not use the RootOfChain
1437
+ // or the AlternateLiveBase.
1438
+ assert (OpValue != RootOfChain && OpValue != AlternateLiveBase);
1439
+ }
1440
+ #endif
1441
+ } else {
1442
+ // For the first instruction, replace the use of unrelocated base i.e.
1443
+ // RootOfChain/OrigRootPhi, with the corresponding PHI present in the
1444
+ // live set. They have been proved to be the same PHI nodes. Note
1445
+ // that the *only* use of the RootOfChain in the ChainToBase list is
1446
+ // the first Value in the list.
1447
+ if (RootOfChain != AlternateLiveBase)
1448
+ ClonedValue->replaceUsesOfWith (RootOfChain, AlternateLiveBase);
1449
+ }
1450
+
1451
+ LastClonedValue = ClonedValue;
1452
+ LastValue = Instr;
1453
+ }
1454
+ assert (LastClonedValue);
1455
+ return LastClonedValue;
1456
+ }
1457
+
1403
1458
// When inserting gc.relocate and gc.result calls, we need to ensure there are
1404
1459
// no uses of the original value / return value between the gc.statepoint and
1405
1460
// the gc.relocate / gc.result call. One case which can arise is a phi node
@@ -2415,69 +2470,14 @@ static void rematerializeLiveValues(CallBase *Call,
2415
2470
2416
2471
// Clone instructions and record them inside "Info" structure.
2417
2472
2418
- // For each live pointer find get its defining chain.
2419
- SmallVector<Instruction *, 3 > ChainToBase = Record.ChainToBase ;
2420
- // Walk backwards to visit top-most instructions first.
2421
- std::reverse (ChainToBase.begin (), ChainToBase.end ());
2422
-
2423
- // Utility function which clones all instructions from "ChainToBase"
2424
- // and inserts them before "InsertBefore". Returns rematerialized value
2425
- // which should be used after statepoint.
2426
- auto rematerializeChain = [&ChainToBase](
2427
- Instruction *InsertBefore, Value *RootOfChain, Value *AlternateLiveBase) {
2428
- Instruction *LastClonedValue = nullptr ;
2429
- Instruction *LastValue = nullptr ;
2430
- for (Instruction *Instr: ChainToBase) {
2431
- // Only GEP's and casts are supported as we need to be careful to not
2432
- // introduce any new uses of pointers not in the liveset.
2433
- // Note that it's fine to introduce new uses of pointers which were
2434
- // otherwise not used after this statepoint.
2435
- assert (isa<GetElementPtrInst>(Instr) || isa<CastInst>(Instr));
2436
-
2437
- Instruction *ClonedValue = Instr->clone ();
2438
- ClonedValue->insertBefore (InsertBefore);
2439
- ClonedValue->setName (Instr->getName () + " .remat" );
2440
-
2441
- // If it is not first instruction in the chain then it uses previously
2442
- // cloned value. We should update it to use cloned value.
2443
- if (LastClonedValue) {
2444
- assert (LastValue);
2445
- ClonedValue->replaceUsesOfWith (LastValue, LastClonedValue);
2446
- #ifndef NDEBUG
2447
- for (auto *OpValue : ClonedValue->operand_values ()) {
2448
- // Assert that cloned instruction does not use any instructions from
2449
- // this chain other than LastClonedValue
2450
- assert (!is_contained (ChainToBase, OpValue) &&
2451
- " incorrect use in rematerialization chain" );
2452
- // Assert that the cloned instruction does not use the RootOfChain
2453
- // or the AlternateLiveBase.
2454
- assert (OpValue != RootOfChain && OpValue != AlternateLiveBase);
2455
- }
2456
- #endif
2457
- } else {
2458
- // For the first instruction, replace the use of unrelocated base i.e.
2459
- // RootOfChain/OrigRootPhi, with the corresponding PHI present in the
2460
- // live set. They have been proved to be the same PHI nodes. Note
2461
- // that the *only* use of the RootOfChain in the ChainToBase list is
2462
- // the first Value in the list.
2463
- if (RootOfChain != AlternateLiveBase)
2464
- ClonedValue->replaceUsesOfWith (RootOfChain, AlternateLiveBase);
2465
- }
2466
-
2467
- LastClonedValue = ClonedValue;
2468
- LastValue = Instr;
2469
- }
2470
- assert (LastClonedValue);
2471
- return LastClonedValue;
2472
- };
2473
-
2474
2473
// Different cases for calls and invokes. For invokes we need to clone
2475
2474
// instructions both on normal and unwind path.
2476
2475
if (isa<CallInst>(Call)) {
2477
2476
Instruction *InsertBefore = Call->getNextNode ();
2478
2477
assert (InsertBefore);
2479
- Instruction *RematerializedValue = rematerializeChain (
2480
- InsertBefore, Record.RootOfChain , PointerToBase[LiveValue]);
2478
+ Instruction *RematerializedValue =
2479
+ rematerializeChain (Record.ChainToBase , InsertBefore,
2480
+ Record.RootOfChain , PointerToBase[LiveValue]);
2481
2481
Info.RematerializedValues [RematerializedValue] = LiveValue;
2482
2482
} else {
2483
2483
auto *Invoke = cast<InvokeInst>(Call);
@@ -2487,17 +2487,19 @@ static void rematerializeLiveValues(CallBase *Call,
2487
2487
Instruction *UnwindInsertBefore =
2488
2488
&*Invoke->getUnwindDest ()->getFirstInsertionPt ();
2489
2489
2490
- Instruction *NormalRematerializedValue = rematerializeChain (
2491
- NormalInsertBefore, Record.RootOfChain , PointerToBase[LiveValue]);
2492
- Instruction *UnwindRematerializedValue = rematerializeChain (
2493
- UnwindInsertBefore, Record.RootOfChain , PointerToBase[LiveValue]);
2490
+ Instruction *NormalRematerializedValue =
2491
+ rematerializeChain (Record.ChainToBase , NormalInsertBefore,
2492
+ Record.RootOfChain , PointerToBase[LiveValue]);
2493
+ Instruction *UnwindRematerializedValue =
2494
+ rematerializeChain (Record.ChainToBase , UnwindInsertBefore,
2495
+ Record.RootOfChain , PointerToBase[LiveValue]);
2494
2496
2495
2497
Info.RematerializedValues [NormalRematerializedValue] = LiveValue;
2496
2498
Info.RematerializedValues [UnwindRematerializedValue] = LiveValue;
2497
2499
}
2498
2500
}
2499
2501
2500
- // Remove rematerializaed values from the live set
2502
+ // Remove rematerialized values from the live set.
2501
2503
for (auto *LiveValue: LiveValuesToBeDeleted) {
2502
2504
Info.LiveSet .remove (LiveValue);
2503
2505
}
0 commit comments