Files
swift-mirror/SwiftCompilerSources/Sources/Optimizer/TestPasses/MemBehaviorDumper.swift
Erik Eckstein a312732f84 AliasAnalysis: consider memory effects of a consume/destroy of a class on it's let-fields
Although a let-field can never be mutated, a release or consume of the class must be considered as writing to such a field.

This change removes the special handling of let-fields in two places, where they don't belong.
Class fields are handled by ImmutableScope anyway.
Handling of global let-variable is temporarily removed by this commit.

Fixes a miscompile.
rdar://142996449
2025-01-20 08:50:56 +01:00

84 lines
2.3 KiB
Swift

//===--- MemBehaviorDumper.swift ------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SIL
/// Prints the memory behavior of relevant instructions in relation to address values of the function.
let memBehaviorDumper = FunctionPass(name: "dump-mem-behavior") {
(function: Function, context: FunctionPassContext) in
let aliasAnalysis = context.aliasAnalysis
print("@\(function.name)")
let values = function.allValues
var currentPair = 0
for inst in function.instructions where inst.shouldTest {
for value in values where value.definingInstruction != inst {
if value.type.isAddress {
let read = inst.mayRead(fromAddress: value, aliasAnalysis)
let write = inst.mayWrite(toAddress: value, aliasAnalysis)
print("PAIR #\(currentPair).")
print(" \(inst)")
print(" \(value)")
print(" r=\(read ? 1 : 0),w=\(write ? 1 : 0)")
currentPair += 1
}
}
}
print()
}
private extension Function {
var allValues: [Value] {
var values: [Value] = []
for block in blocks {
values.append(contentsOf: block.arguments.map { $0 })
for inst in block.instructions {
values.append(contentsOf: inst.results)
}
}
return values
}
}
private extension Instruction {
var shouldTest: Bool {
switch self {
case is ApplySite,
is EndApplyInst,
is AbortApplyInst,
is BeginAccessInst,
is EndAccessInst,
is EndCOWMutationInst,
is CopyValueInst,
is DestroyValueInst,
is StrongReleaseInst,
is IsUniqueInst,
is EndBorrowInst,
is LoadInst,
is LoadBorrowInst,
is StoreInst,
is CopyAddrInst,
is BuiltinInst,
is StoreBorrowInst,
is DebugValueInst:
return true
default:
return false
}
}
}