|
31 | 31 | #include "llvm/IR/CFG.h"
|
32 | 32 | #include "llvm/IR/Constant.h"
|
33 | 33 | #include "llvm/IR/Constants.h"
|
| 34 | +#include "llvm/IR/DIBuilder.h" |
34 | 35 | #include "llvm/IR/DataLayout.h"
|
| 36 | +#include "llvm/IR/DebugInfoMetadata.h" |
35 | 37 | #include "llvm/IR/DerivedTypes.h"
|
36 | 38 | #include "llvm/IR/Dominators.h"
|
37 | 39 | #include "llvm/IR/Function.h"
|
38 | 40 | #include "llvm/IR/GlobalValue.h"
|
| 41 | +#include "llvm/IR/InstIterator.h" |
39 | 42 | #include "llvm/IR/InstrTypes.h"
|
40 | 43 | #include "llvm/IR/Instruction.h"
|
41 | 44 | #include "llvm/IR/Instructions.h"
|
@@ -1382,6 +1385,129 @@ void CodeExtractor::calculateNewCallTerminatorWeights(
|
1382 | 1385 | MDBuilder(TI->getContext()).createBranchWeights(BranchWeights));
|
1383 | 1386 | }
|
1384 | 1387 |
|
| 1388 | +/// Erase debug info intrinsics which refer to values in \p F but aren't in |
| 1389 | +/// \p F. |
| 1390 | +static void eraseDebugIntrinsicsWithNonLocalRefs(Function &F) { |
| 1391 | + for (Instruction &I : instructions(F)) { |
| 1392 | + SmallVector<DbgVariableIntrinsic *, 4> DbgUsers; |
| 1393 | + findDbgUsers(DbgUsers, &I); |
| 1394 | + for (DbgVariableIntrinsic *DVI : DbgUsers) |
| 1395 | + if (DVI->getFunction() != &F) |
| 1396 | + DVI->eraseFromParent(); |
| 1397 | + } |
| 1398 | +} |
| 1399 | + |
| 1400 | +/// Fix up the debug info in the old and new functions by pointing line |
| 1401 | +/// locations and debug intrinsics to the new subprogram scope, and by deleting |
| 1402 | +/// intrinsics which point to values outside of the new function. |
| 1403 | +static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, |
| 1404 | + CallInst &TheCall) { |
| 1405 | + DISubprogram *OldSP = OldFunc.getSubprogram(); |
| 1406 | + LLVMContext &Ctx = OldFunc.getContext(); |
| 1407 | + |
| 1408 | + // See llvm.org/PR44560, OpenMP passes an invalid subprogram to CodeExtractor. |
| 1409 | + bool NeedWorkaroundForOpenMPIRBuilderBug = |
| 1410 | + OldSP && OldSP->getRetainedNodes()->isTemporary(); |
| 1411 | + |
| 1412 | + if (!OldSP || NeedWorkaroundForOpenMPIRBuilderBug) { |
| 1413 | + // Erase any debug info the new function contains. |
| 1414 | + stripDebugInfo(NewFunc); |
| 1415 | + // Make sure the old function doesn't contain any non-local metadata refs. |
| 1416 | + eraseDebugIntrinsicsWithNonLocalRefs(NewFunc); |
| 1417 | + return; |
| 1418 | + } |
| 1419 | + |
| 1420 | + // Create a subprogram for the new function. Leave out a description of the |
| 1421 | + // function arguments, as the parameters don't correspond to anything at the |
| 1422 | + // source level. |
| 1423 | + assert(OldSP->getUnit() && "Missing compile unit for subprogram"); |
| 1424 | + DIBuilder DIB(*OldFunc.getParent(), /*AllowUnresolvedNodes=*/false, |
| 1425 | + OldSP->getUnit()); |
| 1426 | + auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); |
| 1427 | + DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagDefinition | |
| 1428 | + DISubprogram::SPFlagOptimized | |
| 1429 | + DISubprogram::SPFlagLocalToUnit; |
| 1430 | + auto NewSP = DIB.createFunction( |
| 1431 | + OldSP->getUnit(), NewFunc.getName(), NewFunc.getName(), OldSP->getFile(), |
| 1432 | + /*LineNo=*/0, SPType, /*ScopeLine=*/0, DINode::FlagZero, SPFlags); |
| 1433 | + NewFunc.setSubprogram(NewSP); |
| 1434 | + |
| 1435 | + // Debug intrinsics in the new function need to be updated in one of two |
| 1436 | + // ways: |
| 1437 | + // 1) They need to be deleted, because they describe a value in the old |
| 1438 | + // function. |
| 1439 | + // 2) They need to point to fresh metadata, e.g. because they currently |
| 1440 | + // point to a variable in the wrong scope. |
| 1441 | + SmallDenseMap<DINode *, DINode *> RemappedMetadata; |
| 1442 | + SmallVector<Instruction *, 4> DebugIntrinsicsToDelete; |
| 1443 | + for (Instruction &I : instructions(NewFunc)) { |
| 1444 | + auto *DII = dyn_cast<DbgInfoIntrinsic>(&I); |
| 1445 | + if (!DII) |
| 1446 | + continue; |
| 1447 | + |
| 1448 | + // Point the intrinsic to a fresh label within the new function. |
| 1449 | + if (auto *DLI = dyn_cast<DbgLabelInst>(&I)) { |
| 1450 | + DILabel *OldLabel = DLI->getLabel(); |
| 1451 | + DINode *&NewLabel = RemappedMetadata[OldLabel]; |
| 1452 | + if (!NewLabel) |
| 1453 | + NewLabel = DILabel::get(Ctx, NewSP, OldLabel->getName(), |
| 1454 | + OldLabel->getFile(), OldLabel->getLine()); |
| 1455 | + DLI->setArgOperand(0, MetadataAsValue::get(Ctx, NewLabel)); |
| 1456 | + continue; |
| 1457 | + } |
| 1458 | + |
| 1459 | + // If the location isn't a constant or an instruction, delete the |
| 1460 | + // intrinsic. |
| 1461 | + auto *DVI = cast<DbgVariableIntrinsic>(DII); |
| 1462 | + Value *Location = DVI->getVariableLocation(); |
| 1463 | + if (!Location || |
| 1464 | + (!isa<Constant>(Location) && !isa<Instruction>(Location))) { |
| 1465 | + DebugIntrinsicsToDelete.push_back(DVI); |
| 1466 | + continue; |
| 1467 | + } |
| 1468 | + |
| 1469 | + // If the variable location is an instruction but isn't in the new |
| 1470 | + // function, delete the intrinsic. |
| 1471 | + Instruction *LocationInst = dyn_cast<Instruction>(Location); |
| 1472 | + if (LocationInst && LocationInst->getFunction() != &NewFunc) { |
| 1473 | + DebugIntrinsicsToDelete.push_back(DVI); |
| 1474 | + continue; |
| 1475 | + } |
| 1476 | + |
| 1477 | + // Point the intrinsic to a fresh variable within the new function. |
| 1478 | + DILocalVariable *OldVar = DVI->getVariable(); |
| 1479 | + DINode *&NewVar = RemappedMetadata[OldVar]; |
| 1480 | + if (!NewVar) |
| 1481 | + NewVar = DIB.createAutoVariable( |
| 1482 | + NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(), |
| 1483 | + OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero, |
| 1484 | + OldVar->getAlignInBits()); |
| 1485 | + DVI->setArgOperand(1, MetadataAsValue::get(Ctx, NewVar)); |
| 1486 | + } |
| 1487 | + for (auto *DII : DebugIntrinsicsToDelete) |
| 1488 | + DII->eraseFromParent(); |
| 1489 | + DIB.finalizeSubprogram(NewSP); |
| 1490 | + |
| 1491 | + // Fix up the scope information attached to the line locations in the new |
| 1492 | + // function. |
| 1493 | + for (Instruction &I : instructions(NewFunc)) { |
| 1494 | + if (const DebugLoc &DL = I.getDebugLoc()) |
| 1495 | + I.setDebugLoc(DebugLoc::get(DL.getLine(), DL.getCol(), NewSP)); |
| 1496 | + |
| 1497 | + // Loop info metadata may contain line locations. Fix them up. |
| 1498 | + auto updateLoopInfoLoc = [&Ctx, |
| 1499 | + NewSP](const DILocation &Loc) -> DILocation * { |
| 1500 | + return DILocation::get(Ctx, Loc.getLine(), Loc.getColumn(), NewSP, |
| 1501 | + nullptr); |
| 1502 | + }; |
| 1503 | + updateLoopMetadataDebugLocations(I, updateLoopInfoLoc); |
| 1504 | + } |
| 1505 | + if (!TheCall.getDebugLoc()) |
| 1506 | + TheCall.setDebugLoc(DebugLoc::get(0, 0, OldSP)); |
| 1507 | + |
| 1508 | + eraseDebugIntrinsicsWithNonLocalRefs(NewFunc); |
| 1509 | +} |
| 1510 | + |
1385 | 1511 | Function *
|
1386 | 1512 | CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC) {
|
1387 | 1513 | if (!isEligible())
|
@@ -1567,26 +1693,7 @@ CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC) {
|
1567 | 1693 | }
|
1568 | 1694 | }
|
1569 | 1695 |
|
1570 |
| - // Erase debug info intrinsics. Variable updates within the new function are |
1571 |
| - // invisible to debuggers. This could be improved by defining a DISubprogram |
1572 |
| - // for the new function. |
1573 |
| - for (BasicBlock &BB : *newFunction) { |
1574 |
| - auto BlockIt = BB.begin(); |
1575 |
| - // Remove debug info intrinsics from the new function. |
1576 |
| - while (BlockIt != BB.end()) { |
1577 |
| - Instruction *Inst = &*BlockIt; |
1578 |
| - ++BlockIt; |
1579 |
| - if (isa<DbgInfoIntrinsic>(Inst)) |
1580 |
| - Inst->eraseFromParent(); |
1581 |
| - } |
1582 |
| - // Remove debug info intrinsics which refer to values in the new function |
1583 |
| - // from the old function. |
1584 |
| - SmallVector<DbgVariableIntrinsic *, 4> DbgUsers; |
1585 |
| - for (Instruction &I : BB) |
1586 |
| - findDbgUsers(DbgUsers, &I); |
1587 |
| - for (DbgVariableIntrinsic *DVI : DbgUsers) |
1588 |
| - DVI->eraseFromParent(); |
1589 |
| - } |
| 1696 | + fixupDebugInfoPostExtraction(*oldFunction, *newFunction, *TheCall); |
1590 | 1697 |
|
1591 | 1698 | // Mark the new function `noreturn` if applicable. Terminators which resume
|
1592 | 1699 | // exception propagation are treated as returning instructions. This is to
|
|
0 commit comments