mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SwiftCompilerSources: move the Verifier to the SIL module
This commit is contained in:
@@ -17,7 +17,7 @@ import OptimizerBridging
|
||||
@_cdecl("initializeSwiftModules")
|
||||
public func initializeSwiftModules() {
|
||||
registerAST()
|
||||
registerSILClasses()
|
||||
registerSIL()
|
||||
registerSwiftAnalyses()
|
||||
registerUtilities()
|
||||
registerSwiftPasses()
|
||||
@@ -160,6 +160,5 @@ private func registerSwiftAnalyses() {
|
||||
}
|
||||
|
||||
private func registerUtilities() {
|
||||
registerVerifier()
|
||||
registerPhiUpdater()
|
||||
}
|
||||
|
||||
@@ -20,5 +20,4 @@ swift_compiler_sources(Optimizer
|
||||
OwnershipLiveness.swift
|
||||
PhiUpdater.swift
|
||||
StaticInitCloner.swift
|
||||
Verifier.swift
|
||||
)
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
import Basic
|
||||
import SILBridging
|
||||
|
||||
public func registerSIL() {
|
||||
registerSILClasses()
|
||||
registerUtilities()
|
||||
}
|
||||
|
||||
private func register<T: AnyObject>(_ cl: T.Type) {
|
||||
"\(cl)"._withBridgedStringRef { nameStr in
|
||||
let metatype = unsafeBitCast(cl, to: SwiftMetatype.self)
|
||||
@@ -20,7 +25,7 @@ private func register<T: AnyObject>(_ cl: T.Type) {
|
||||
}
|
||||
}
|
||||
|
||||
public func registerSILClasses() {
|
||||
private func registerSILClasses() {
|
||||
Function.register()
|
||||
register(BasicBlock.self)
|
||||
register(GlobalVariable.self)
|
||||
@@ -262,3 +267,7 @@ public func registerSILClasses() {
|
||||
register(MergeIsolationRegionInst.self)
|
||||
register(IgnoredUseInst.self)
|
||||
}
|
||||
|
||||
private func registerUtilities() {
|
||||
registerVerifier()
|
||||
}
|
||||
|
||||
@@ -15,5 +15,6 @@ swift_compiler_sources(SIL
|
||||
SSAUpdater.swift
|
||||
Test.swift
|
||||
WalkUtils.swift
|
||||
Verifier.swift
|
||||
)
|
||||
|
||||
|
||||
@@ -10,24 +10,29 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import SIL
|
||||
import OptimizerBridging
|
||||
import SILBridging
|
||||
|
||||
/// To add verification for a specific instruction, let the instruction class conform to
|
||||
/// this protocol and implement the `verify` method.
|
||||
private protocol VerifiableInstruction : Instruction {
|
||||
func verify(_ context: FunctionPassContext)
|
||||
func verify(_ context: VerifierContext)
|
||||
}
|
||||
|
||||
private func require(_ condition: Bool, _ message: @autoclosure () -> String, atInstruction: Instruction? = nil) {
|
||||
if !condition {
|
||||
let msg = message()
|
||||
msg._withBridgedStringRef { stringRef in
|
||||
verifierError(stringRef, atInstruction.bridged, Optional<Argument>.none.bridged)
|
||||
BridgedVerifier.verifierError(stringRef, atInstruction.bridged, Optional<Argument>.none.bridged)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VerifierContext: Context {
|
||||
let _bridged: BridgedContext
|
||||
}
|
||||
|
||||
extension Function {
|
||||
func verify(_ context: FunctionPassContext) {
|
||||
func verify(_ context: VerifierContext) {
|
||||
for block in blocks {
|
||||
for arg in block.arguments {
|
||||
arg.verify(context)
|
||||
@@ -63,16 +68,17 @@ private extension Instruction {
|
||||
}
|
||||
|
||||
private extension Argument {
|
||||
func verify(_ context: FunctionPassContext) {
|
||||
func verify(_ context: VerifierContext) {
|
||||
if let phi = Phi(self), phi.value.ownership == .guaranteed {
|
||||
|
||||
phi.verifyBorrowedFromUse()
|
||||
|
||||
require(phi.isReborrow == phi.hasBorrowEndingUse ||
|
||||
// In a dead-end block an end_borrow might have been deleted.
|
||||
// TODO: this check is not needed anymore once we have complete OSSA lifetimes.
|
||||
(isReborrow && context.deadEndBlocks.isDeadEnd(parentBlock)),
|
||||
// TODO: enable this check once we have complete OSSA lifetimes.
|
||||
// In a dead-end block an end_borrow might have been deleted.
|
||||
/*
|
||||
require(phi.isReborrow == phi.hasBorrowEndingUse,
|
||||
"\(self) has stale reborrow flag");
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +101,7 @@ private extension Phi {
|
||||
}
|
||||
|
||||
extension BorrowedFromInst : VerifiableInstruction {
|
||||
func verify(_ context: FunctionPassContext) {
|
||||
func verify(_ context: VerifierContext) {
|
||||
|
||||
for ev in enclosingValues {
|
||||
require(ev.isValidEnclosingValueInBorrowedFrom, "invalid enclosing value in borrowed-from: \(ev)")
|
||||
@@ -135,7 +141,7 @@ private extension Value {
|
||||
}
|
||||
|
||||
extension LoadBorrowInst : VerifiableInstruction {
|
||||
func verify(_ context: FunctionPassContext) {
|
||||
func verify(_ context: VerifierContext) {
|
||||
if isUnchecked {
|
||||
return
|
||||
}
|
||||
@@ -149,7 +155,7 @@ extension LoadBorrowInst : VerifiableInstruction {
|
||||
}
|
||||
|
||||
extension VectorBaseAddrInst : VerifiableInstruction {
|
||||
func verify(_ context: FunctionPassContext) {
|
||||
func verify(_ context: VerifierContext) {
|
||||
require(vector.type.isBuiltinFixedArray,
|
||||
"vector operand of vector_element_addr must be a Builtin.FixedArray")
|
||||
require(type == vector.type.builtinFixedArrayElementType(in: parentFunction,
|
||||
@@ -164,10 +170,10 @@ extension VectorBaseAddrInst : VerifiableInstruction {
|
||||
// Otherwise the risk would be too big for false alarms. It also means that this verification is not perfect and
|
||||
// might miss some subtle violations.
|
||||
private struct MutatingUsesWalker : AddressDefUseWalker {
|
||||
let context: FunctionPassContext
|
||||
let context: VerifierContext
|
||||
var mutatingInstructions: InstructionSet
|
||||
|
||||
init(_ context: FunctionPassContext) {
|
||||
init(_ context: VerifierContext) {
|
||||
self.context = context
|
||||
self.mutatingInstructions = InstructionSet(context)
|
||||
}
|
||||
@@ -268,9 +274,9 @@ private extension Operand {
|
||||
}
|
||||
|
||||
func registerVerifier() {
|
||||
BridgedUtilities.registerVerifier(
|
||||
BridgedVerifier.registerVerifier(
|
||||
{ (bridgedCtxt: BridgedContext, bridgedFunction: BridgedFunction) in
|
||||
let context = FunctionPassContext(_bridged: bridgedCtxt)
|
||||
let context = VerifierContext(_bridged: bridgedCtxt)
|
||||
bridgedFunction.function.verify(context)
|
||||
}
|
||||
)
|
||||
@@ -1494,6 +1494,16 @@ struct BridgedContext {
|
||||
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE Slab freeSlab(Slab slab) const;
|
||||
};
|
||||
|
||||
struct BridgedVerifier {
|
||||
typedef void (* _Nonnull VerifyFunctionFn)(BridgedContext, BridgedFunction);
|
||||
|
||||
static void runSwiftFunctionVerification(swift::SILFunction * _Nonnull f, swift::SILContext * _Nonnull context);
|
||||
|
||||
static void registerVerifier(VerifyFunctionFn verifyFunctionFn);
|
||||
static void verifierError(BridgedStringRef message, OptionalBridgedInstruction atInstruction,
|
||||
OptionalBridgedArgument atArgument);
|
||||
};
|
||||
|
||||
namespace swift::test {
|
||||
struct Arguments;
|
||||
class FunctionTest;
|
||||
|
||||
@@ -120,11 +120,9 @@ struct BridgedPostDomTree {
|
||||
};
|
||||
|
||||
struct BridgedUtilities {
|
||||
typedef void (* _Nonnull VerifyFunctionFn)(BridgedContext, BridgedFunction);
|
||||
typedef void (* _Nonnull UpdateFunctionFn)(BridgedContext, BridgedFunction);
|
||||
typedef void (* _Nonnull UpdatePhisFn)(BridgedContext, BridgedArrayRef);
|
||||
|
||||
static void registerVerifier(VerifyFunctionFn verifyFunctionFn);
|
||||
static void registerPhiUpdater(UpdateFunctionFn updateBorrowedFromFn,
|
||||
UpdatePhisFn updateBorrowedFromPhisFn,
|
||||
UpdatePhisFn replacePhisWithIncomingValuesFn);
|
||||
@@ -279,8 +277,6 @@ BridgedDynamicCastResult classifyDynamicCastBridged(BridgedCanType sourceTy, Bri
|
||||
|
||||
BridgedDynamicCastResult classifyDynamicCastBridged(BridgedInstruction inst);
|
||||
|
||||
void verifierError(BridgedStringRef message, OptionalBridgedInstruction atInstruction, OptionalBridgedArgument atArgument);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pass registration
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -775,3 +775,26 @@ void SILContext::freeOperandSet(OperandSet *set) {
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// BridgedVerifier
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static BridgedVerifier::VerifyFunctionFn verifyFunctionFunction = nullptr;
|
||||
|
||||
void BridgedVerifier::registerVerifier(VerifyFunctionFn verifyFunctionFn) {
|
||||
verifyFunctionFunction = verifyFunctionFn;
|
||||
}
|
||||
|
||||
void BridgedVerifier::runSwiftFunctionVerification(SILFunction * _Nonnull f, SILContext * _Nonnull context) {
|
||||
if (!verifyFunctionFunction)
|
||||
return;
|
||||
|
||||
verifyFunctionFunction({context}, {f});
|
||||
}
|
||||
|
||||
void BridgedVerifier::verifierError(BridgedStringRef message,
|
||||
OptionalBridgedInstruction atInstruction,
|
||||
OptionalBridgedArgument atArgument) {
|
||||
Twine msg(message.unbridged());
|
||||
verificationFailure(msg, atInstruction.unbridged(), atArgument.unbridged(), /*extraContext=*/nullptr);
|
||||
}
|
||||
|
||||
@@ -49,16 +49,7 @@ llvm::cl::opt<bool> DisableSwiftVerification(
|
||||
// PassManager
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static BridgedUtilities::VerifyFunctionFn verifyFunctionFunction;
|
||||
|
||||
void BridgedUtilities::registerVerifier(VerifyFunctionFn verifyFunctionFn) {
|
||||
verifyFunctionFunction = verifyFunctionFn;
|
||||
}
|
||||
|
||||
void SILPassManager::runSwiftFunctionVerification(SILFunction *f) {
|
||||
if (!verifyFunctionFunction)
|
||||
return;
|
||||
|
||||
if (f->getModule().getOptions().VerifyNone)
|
||||
return;
|
||||
|
||||
@@ -70,7 +61,7 @@ void SILPassManager::runSwiftFunctionVerification(SILFunction *f) {
|
||||
}
|
||||
|
||||
getSwiftPassInvocation()->beginVerifyFunction(f);
|
||||
verifyFunctionFunction({getSwiftPassInvocation()}, {f});
|
||||
BridgedVerifier::runSwiftFunctionVerification(f, getSwiftPassInvocation());
|
||||
getSwiftPassInvocation()->endVerifyFunction();
|
||||
}
|
||||
|
||||
@@ -507,13 +498,6 @@ void BridgedBuilder::destroyCapturedArgs(BridgedInstruction partialApply) const
|
||||
}
|
||||
}
|
||||
|
||||
void verifierError(BridgedStringRef message,
|
||||
OptionalBridgedInstruction atInstruction,
|
||||
OptionalBridgedArgument atArgument) {
|
||||
Twine msg(message.unbridged());
|
||||
verificationFailure(msg, atInstruction.unbridged(), atArgument.unbridged(), /*extraContext=*/nullptr);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Test
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user