mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[move-only] Teach the move checker how to handle global_addr.
As part of this I also had to change how we emit global_addr in SILGenLValue. Specifically, only for noncopyable types, we no longer emit a single global_addr at the beginning of the function (in a sense auto-CSEing) and instead always emit a new global_addr for each access. The reason why we do this is that otherwise, access base visitor will consider all accesses to the global to be for the same single access. In contrast, by always emitting the global_addr each time, we provide a new base for each access allowing us to emit the diagnostics that we want to. rdar://102794400
This commit is contained in:
@@ -59,11 +59,14 @@ static void diagnose(ASTContext &context, SILInstruction *inst, Diag<T...> diag,
|
||||
context.Diags.diagnose(loc.getSourceLoc(), diag, std::forward<U>(args)...);
|
||||
}
|
||||
|
||||
static void getVariableNameForValue(MarkMustCheckInst *mmci,
|
||||
/// Helper function that actually implements getVariableNameForValue. Do not
|
||||
/// call it directly! Call the unary variants instead.
|
||||
static void getVariableNameForValue(SILValue value2,
|
||||
SILValue searchValue,
|
||||
SmallString<64> &resultingString) {
|
||||
// Before we do anything, lets see if we have an exact debug_value on our
|
||||
// mmci. In such a case, we can end early and are done.
|
||||
if (auto *use = getSingleDebugUse(mmci)) {
|
||||
if (auto *use = getSingleDebugUse(value2)) {
|
||||
if (auto debugVar = DebugVarCarryingInst(use->getUser())) {
|
||||
assert(debugVar.getKind() == DebugVarCarryingInst::Kind::DebugValue);
|
||||
resultingString += debugVar.getName();
|
||||
@@ -72,28 +75,27 @@ static void getVariableNameForValue(MarkMustCheckInst *mmci,
|
||||
}
|
||||
|
||||
// Otherwise, we need to look at our mark_must_check's operand.
|
||||
StackList<SILInstruction *> variableNamePath(mmci->getFunction());
|
||||
SILValue value = mmci->getOperand();
|
||||
StackList<SILInstruction *> variableNamePath(value2->getFunction());
|
||||
while (true) {
|
||||
if (auto *allocInst = dyn_cast<AllocationInst>(value)) {
|
||||
if (auto *allocInst = dyn_cast<AllocationInst>(searchValue)) {
|
||||
variableNamePath.push_back(allocInst);
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto *globalAddrInst = dyn_cast<GlobalAddrInst>(value)) {
|
||||
if (auto *globalAddrInst = dyn_cast<GlobalAddrInst>(searchValue)) {
|
||||
variableNamePath.push_back(globalAddrInst);
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto *rei = dyn_cast<RefElementAddrInst>(value)) {
|
||||
if (auto *rei = dyn_cast<RefElementAddrInst>(searchValue)) {
|
||||
variableNamePath.push_back(rei);
|
||||
value = rei->getOperand();
|
||||
searchValue = rei->getOperand();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we do not do an exact match, see if we can find a debug_var inst. If
|
||||
// we do, we always break since we have a root value.
|
||||
if (auto *use = getSingleDebugUse(value)) {
|
||||
if (auto *use = getSingleDebugUse(searchValue)) {
|
||||
if (auto debugVar = DebugVarCarryingInst(use->getUser())) {
|
||||
assert(debugVar.getKind() == DebugVarCarryingInst::Kind::DebugValue);
|
||||
variableNamePath.push_back(use->getUser());
|
||||
@@ -103,9 +105,9 @@ static void getVariableNameForValue(MarkMustCheckInst *mmci,
|
||||
|
||||
// Otherwise, try to see if we have a single value instruction we can look
|
||||
// through.
|
||||
if (isa<BeginBorrowInst>(value) || isa<LoadInst>(value) ||
|
||||
isa<BeginAccessInst>(value) || isa<MarkMustCheckInst>(value)) {
|
||||
value = cast<SingleValueInstruction>(value)->getOperand(0);
|
||||
if (isa<BeginBorrowInst>(searchValue) || isa<LoadInst>(searchValue) ||
|
||||
isa<BeginAccessInst>(searchValue) || isa<MarkMustCheckInst>(searchValue)) {
|
||||
searchValue = cast<SingleValueInstruction>(searchValue)->getOperand(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -132,6 +134,19 @@ static void getVariableNameForValue(MarkMustCheckInst *mmci,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void getVariableNameForValue(MarkMustCheckInst *mmci,
|
||||
SmallString<64> &resultingString) {
|
||||
return getVariableNameForValue(mmci, mmci->getOperand(), resultingString);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void getVariableNameForValue(SILValue value,
|
||||
SmallString<64> &resultingString) {
|
||||
return getVariableNameForValue(value, value, resultingString);
|
||||
}
|
||||
#endif
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MARK: Misc Diagnostics
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user