Skip to content

Commit adb35f3

Browse files
Add support for llvm.dbg.coroframe_entry in the CoroSplitter pass.
Make sure the CoroSplitter pass correctly handles llvm.dbg.coroframe_entry intrinsics. Also, convert them to llvm.dbg.declares so that any subsquent passes do not need to be amended to support the llvm.dbg.coroframe_entry intrinsic.
1 parent d6484cf commit adb35f3

File tree

1 file changed

+57
-9
lines changed

1 file changed

+57
-9
lines changed

llvm/lib/Transforms/Coroutines/CoroFrame.cpp

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,8 @@ static void cacheDIVar(FrameDataInfo &FrameData,
555555
};
556556
CacheIt(findDbgDeclares(V));
557557
CacheIt(findDVRDeclares(V));
558+
CacheIt(findDbgCoroFrameEntrys(V));
559+
CacheIt(findDVRCoroFrameEntrys(V));
558560
}
559561
}
560562

@@ -1156,6 +1158,46 @@ static void insertSpills(const FrameDataInfo &FrameData, coro::Shape &Shape) {
11561158
for_each(DVRs, SalvageOne);
11571159
}
11581160

1161+
TinyPtrVector<DbgCoroFrameEntryInst *> DICoros =
1162+
findDbgCoroFrameEntrys(Def);
1163+
TinyPtrVector<DbgVariableRecord *> DVRCoros = findDVRCoroFrameEntrys(Def);
1164+
// Try best to find dbg.coroframe_entry. If the spill is a temp, there may
1165+
// not be a direct dbg.coroframe_entry. Walk up the load chain to find one
1166+
// from an alias.
1167+
if (F->getSubprogram()) {
1168+
auto *CurDef = Def;
1169+
while (DICoros.empty() && DVRCoros.empty() && isa<LoadInst>(CurDef)) {
1170+
auto *LdInst = cast<LoadInst>(CurDef);
1171+
// Only consider ptr to ptr same type load.
1172+
if (LdInst->getPointerOperandType() != LdInst->getType())
1173+
break;
1174+
CurDef = LdInst->getPointerOperand();
1175+
if (!isa<AllocaInst, LoadInst>(CurDef))
1176+
break;
1177+
DICoros = findDbgCoroFrameEntrys(CurDef);
1178+
DVRCoros = findDVRCoroFrameEntrys(CurDef);
1179+
}
1180+
}
1181+
1182+
auto SalvageOneCoro = [&](auto *DDI) {
1183+
// This dbg.coroframe_entry is preserved for all coro-split function
1184+
// fragments. It will be unreachable in the main function, and
1185+
// processed by coro::salvageDebugInfo() by the Cloner. However, convert
1186+
// it to a dbg.declare to make sure future passes don't have to deal
1187+
// with a dbg.coroframe_entry.
1188+
DbgVariableRecord *NewDVR = new DbgVariableRecord(
1189+
ValueAsMetadata::get(CurrentReload), DDI->getVariable(),
1190+
DDI->getExpression(), DDI->getDebugLoc(),
1191+
DbgVariableRecord::LocationType::Declare);
1192+
Builder.GetInsertPoint()->getParent()->insertDbgRecordBefore(
1193+
NewDVR, Builder.GetInsertPoint());
1194+
// This dbg.coroframe_entry is for the main function entry point. It
1195+
// will be deleted in all coro-split functions.
1196+
coro::salvageDebugInfo(ArgToAllocaMap, *DDI, false /*UseEntryValue*/);
1197+
};
1198+
for_each(DICoros, SalvageOneCoro);
1199+
for_each(DVRCoros, SalvageOneCoro);
1200+
11591201
// If we have a single edge PHINode, remove it and replace it with a
11601202
// reload from the coroutine frame. (We already took care of multi edge
11611203
// PHINodes by normalizing them in the rewritePHIs function).
@@ -1954,10 +1996,10 @@ void coro::salvageDebugInfo(
19541996

19551997
DVI.replaceVariableLocationOp(OriginalStorage, Storage);
19561998
DVI.setExpression(Expr);
1957-
// We only hoist dbg.declare today since it doesn't make sense to hoist
1958-
// dbg.value since it does not have the same function wide guarantees that
1959-
// dbg.declare does.
1960-
if (isa<DbgDeclareInst>(DVI)) {
1999+
// We only hoist dbg.declare and dbg.coroframe_entry today since it doesn't
2000+
// make sense to hoist dbg.value since it does not have the same function wide
2001+
// guarantees that dbg.declare and dbg.coroframe_entry do.
2002+
if (isa<DbgDeclareInst>(DVI) || isa<DbgCoroFrameEntryInst>(DVI)) {
19612003
std::optional<BasicBlock::iterator> InsertPt;
19622004
if (auto *I = dyn_cast<Instruction>(Storage)) {
19632005
InsertPt = I->getInsertionPointAfterDef();
@@ -1982,7 +2024,7 @@ void coro::salvageDebugInfo(
19822024
Function *F = DVR.getFunction();
19832025
// Follow the pointer arithmetic all the way to the incoming
19842026
// function argument and convert into a DIExpression.
1985-
bool SkipOutermostLoad = DVR.isDbgDeclare();
2027+
bool SkipOutermostLoad = DVR.isDbgDeclare() || DVR.isDbgCoroFrameEntry();
19862028
Value *OriginalStorage = DVR.getVariableLocationOp(0);
19872029

19882030
auto SalvagedInfo =
@@ -1996,10 +2038,11 @@ void coro::salvageDebugInfo(
19962038

19972039
DVR.replaceVariableLocationOp(OriginalStorage, Storage);
19982040
DVR.setExpression(Expr);
1999-
// We only hoist dbg.declare today since it doesn't make sense to hoist
2000-
// dbg.value since it does not have the same function wide guarantees that
2001-
// dbg.declare does.
2002-
if (DVR.getType() == DbgVariableRecord::LocationType::Declare) {
2041+
// We only hoist dbg.declare and dbg.coroframe_entry today since it doesn't
2042+
// make sense to hoist dbg.value since it does not have the same function wide
2043+
// guarantees that dbg.declare and dbg.coroframe_entry do.
2044+
if (DVR.getType() == DbgVariableRecord::LocationType::Declare ||
2045+
DVR.getType() == DbgVariableRecord::LocationType::CoroFrameEntry) {
20032046
std::optional<BasicBlock::iterator> InsertPt;
20042047
if (auto *I = dyn_cast<Instruction>(Storage)) {
20052048
InsertPt = I->getInsertionPointAfterDef();
@@ -2014,6 +2057,11 @@ void coro::salvageDebugInfo(
20142057
InsertPt = F->getEntryBlock().begin();
20152058
if (InsertPt) {
20162059
DVR.removeFromParent();
2060+
// If there is a dbg.coroframe_entry being reinserted, insert it as a
2061+
// dbg.declare instead, so that subsequent passes don't have to deal with
2062+
// a dbg.coroframe_entry.
2063+
if (DVR.getType() == DbgVariableRecord::LocationType::CoroFrameEntry)
2064+
DVR.Type = DbgVariableRecord::LocationType::Declare;
20172065
(*InsertPt)->getParent()->insertDbgRecordBefore(&DVR, *InsertPt);
20182066
}
20192067
}

0 commit comments

Comments
 (0)