@@ -1404,18 +1404,29 @@ static void generateSpills(SpillMapTy &SpillMap, FillMapTy &FillMap,
1404
1404
generateSpill (Var, Var);
1405
1405
1406
1406
// Spill any necessary incoming PHI values
1407
- SmallVector<PHINode *, 8 > SpilledPHIs ;
1407
+ MapVector<Value *, Value *> IncomingPHIValueMap ;
1408
1408
if (CS.isInvoke () && SpillOnExceptionPath) {
1409
1409
auto *Invoke = cast<InvokeInst>(CS.getInstruction ());
1410
1410
BasicBlock *Pred = Invoke->getParent ();
1411
- BasicBlock *Pad = Invoke->getUnwindDest ();
1412
- for (auto I = Pad->begin (); auto *PHI = dyn_cast<PHINode>(&*I); ++I) {
1413
- // Find the value to store for this PHI
1414
- Value *IncomingValue = PHI->getIncomingValueForBlock (Pred);
1415
- // Record that we're spilling this PHI.
1416
- SpilledPHIs.push_back (PHI);
1417
- // Generate the spill
1418
- generateSpill (PHI, IncomingValue);
1411
+ for (BasicBlock *Pad : Invoke->getTransitiveUnwindDests <false >()) {
1412
+ for (auto I = Pad->begin (); auto *PHI = dyn_cast<PHINode>(&*I); ++I) {
1413
+ // Find the value to store for this PHI
1414
+ Value *IncomingValue = PHI->getIncomingValueForBlock (Pred);
1415
+ // If the incoming value was itself a PHI we've walked over,
1416
+ // recurse to that incoming value
1417
+ auto MapIter = IncomingPHIValueMap.find (IncomingValue);
1418
+ if (MapIter != IncomingPHIValueMap.end ())
1419
+ IncomingValue = MapIter->second ;
1420
+ // Record the incoming value in case we see a use of it in
1421
+ // a subsequent PHI.
1422
+ IncomingPHIValueMap[PHI] = IncomingValue;
1423
+ // Generate the spill
1424
+ generateSpill (PHI, IncomingValue);
1425
+ }
1426
+ // Update pred if we're going to visit this block's successors,
1427
+ // which we'll do iff it's unsplittable.
1428
+ if (isa<TerminatorInst>(Pad->getFirstNonPHI ()))
1429
+ Pred = Pad;
1419
1430
}
1420
1431
}
1421
1432
@@ -1452,11 +1463,12 @@ static void generateSpills(SpillMapTy &SpillMap, FillMapTy &FillMap,
1452
1463
generateFill (Var, &*Pad->getFirstInsertionPt ());
1453
1464
};
1454
1465
auto *Invoke = cast<InvokeInst>(CS.getInstruction ());
1455
- BasicBlock *Pad = Invoke->getUnwindDest ();
1456
- for (Value *Var : LiveVec)
1457
- ensureFill (Var, Pad);
1458
- for (auto *PHI : SpilledPHIs)
1459
- ensureFill (PHI, Pad);
1466
+ for (BasicBlock *Pad : Invoke->getTransitiveUnwindDests ()) {
1467
+ for (Value *Var : LiveVec)
1468
+ ensureFill (Var, Pad);
1469
+ for (const auto &IncomingValuePair : IncomingPHIValueMap)
1470
+ ensureFill (IncomingValuePair.first , Pad);
1471
+ }
1460
1472
}
1461
1473
1462
1474
// If we've spilled on all paths, we don't need to generate any relocates,
@@ -1562,21 +1574,24 @@ makeStatepointExplicitImpl(const CallSite CS, /* to replace */
1562
1574
if (SpillOnExceptionPath) {
1563
1575
Result.UnwindToken = nullptr ;
1564
1576
} else {
1565
- BasicBlock *UnwindBlock = ToReplace->getUnwindDest ();
1566
- assert (!isa<PHINode>(UnwindBlock->begin ()) &&
1567
- UnwindBlock->getUniquePredecessor () &&
1568
- " can't safely insert in this block!" );
1569
-
1570
- Builder.SetInsertPoint (&*UnwindBlock->getFirstInsertionPt ());
1571
- Builder.SetCurrentDebugLocation (ToReplace->getDebugLoc ());
1572
-
1573
- // Attach exceptional gc relocates to the landingpad.
1574
- Instruction *ExceptionalToken = UnwindBlock->getLandingPadInst ();
1575
- Result.UnwindToken = ExceptionalToken;
1576
-
1577
- const unsigned LiveStartIdx = Statepoint (Token).gcPtrsStartIdx ();
1578
- CreateGCRelocates (LiveVariables, LiveStartIdx, BasePtrs, ExceptionalToken,
1579
- Builder);
1577
+ for (BasicBlock *UnwindBlock : ToReplace->getTransitiveUnwindDests ()) {
1578
+ assert (!isa<PHINode>(UnwindBlock->begin ()) &&
1579
+ UnwindBlock->getUniquePredecessor () &&
1580
+ " can't safely insert in this block!" );
1581
+
1582
+ Builder.SetInsertPoint (&*UnwindBlock->getFirstInsertionPt ());
1583
+ Builder.SetCurrentDebugLocation (ToReplace->getDebugLoc ());
1584
+
1585
+ // Attach exceptional gc relocates to the landingpad.
1586
+ Instruction *ExceptionalToken = UnwindBlock->getLandingPadInst ();
1587
+ assert (Result.UnwindToken == nullptr &&
1588
+ " Cannot report multiple unwind tokens" );
1589
+ Result.UnwindToken = ExceptionalToken;
1590
+
1591
+ const unsigned LiveStartIdx = Statepoint (Token).gcPtrsStartIdx ();
1592
+ CreateGCRelocates (LiveVariables, LiveStartIdx, BasePtrs,
1593
+ ExceptionalToken, Builder);
1594
+ }
1580
1595
}
1581
1596
1582
1597
// Generate gc relocates and returns for normal block
@@ -1868,7 +1883,8 @@ static void relocationViaAlloca(
1868
1883
// gc.results and gc.relocates, but that's fine.
1869
1884
if (auto II = dyn_cast<InvokeInst>(Statepoint)) {
1870
1885
InsertClobbersAt (&*II->getNormalDest ()->getFirstInsertionPt ());
1871
- InsertClobbersAt (&*II->getUnwindDest ()->getFirstInsertionPt ());
1886
+ for (BasicBlock *UnwindDest : II->getTransitiveUnwindDests ())
1887
+ InsertClobbersAt (&*UnwindDest->getFirstInsertionPt ());
1872
1888
} else {
1873
1889
InsertClobbersAt (cast<Instruction>(Statepoint)->getNextNode ());
1874
1890
}
@@ -2149,16 +2165,16 @@ static void rematerializeLiveValues(CallSite CS,
2149
2165
2150
2166
Instruction *NormalInsertBefore =
2151
2167
&*Invoke->getNormalDest ()->getFirstInsertionPt ();
2152
- Instruction *UnwindInsertBefore =
2153
- &*Invoke->getUnwindDest ()->getFirstInsertionPt ();
2154
-
2155
2168
Instruction *NormalRematerializedValue =
2156
2169
rematerializeChain (NormalInsertBefore);
2157
- Instruction *UnwindRematerializedValue =
2158
- rematerializeChain (UnwindInsertBefore);
2159
-
2160
2170
Info.RematerializedValues [NormalRematerializedValue] = LiveValue;
2161
- Info.RematerializedValues [UnwindRematerializedValue] = LiveValue;
2171
+
2172
+ for (BasicBlock *UnwindDest : Invoke->getTransitiveUnwindDests ()) {
2173
+ Instruction *UnwindInsertBefore = &*UnwindDest->getFirstInsertionPt ();
2174
+ Instruction *UnwindRematerializedValue =
2175
+ rematerializeChain (UnwindInsertBefore);
2176
+ Info.RematerializedValues [UnwindRematerializedValue] = LiveValue;
2177
+ }
2162
2178
}
2163
2179
}
2164
2180
0 commit comments