// RUN: %empty-directory(%t) // RUN: %empty-directory(%t/MCP) // This test makes sure that the module cache hash properly // namespaces/distinguishes modules when recompiling from a .swiftinterface file // depending on if: // // a. OSSA Modules are enabled or not. // b. If OSSA Modules are enabled, additionally distinguish in between the various optimization levels. // // This will allow for users who want to work with ossa modules in their project // to build with OSSA even if the original project was not compiled in OSSA // mode. // 1. Build a .swiftinterface for all the different optimization levels. These // optimization levels are embedded in the swift interface file and control how // we regenerate the module. As proven by the test // different-mode-have-same-interface-file.swift in this directory, we know that // the flag does not impact the swift interface file. // RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/SwiftModuleDefault.swiftinterface -parse-stdlib %s -module-name SwiftModuleDefault -enable-library-evolution -swift-version 5 // RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/SwiftModuleOnone.swiftinterface -parse-stdlib %s -module-name SwiftModuleOnone -enable-library-evolution -swift-version 5 -Onone // RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/SwiftModuleO.swiftinterface -parse-stdlib %s -module-name SwiftModuleO -enable-library-evolution -swift-version 5 -O // RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/SwiftModuleOsize.swiftinterface -parse-stdlib %s -module-name SwiftModuleOsize -enable-library-evolution -swift-version 5 -Osize // 2. Create some trivial programs that import the various libraries with the // various opt levels and with/without expecting a rebuild remark from the // compiler. The remark allows us another way to validate that we are rebuilding // what we expect. // RUN: echo "import SwiftModuleDefault // expected-remark {{rebuilding module 'SwiftModuleDefault'}}" > %t/test.default.remark.swift // RUN: echo "import SwiftModuleOnone // expected-remark {{rebuilding module 'SwiftModuleOnone'}}" > %t/test.Onone.remark.swift // RUN: echo "import SwiftModuleO // expected-remark {{rebuilding module 'SwiftModuleO'}}" > %t/test.O.remark.swift // RUN: echo "import SwiftModuleOsize // expected-remark {{rebuilding module 'SwiftModuleOsize'}}" > %t/test.Osize.remark.swift // RUN: echo 'import SwiftModuleDefault' > %t/test.default.swift // RUN: echo 'import SwiftModuleOnone' > %t/test.Onone.swift // RUN: echo 'import SwiftModuleO' > %t/test.O.swift // RUN: echo 'import SwiftModuleOsize' > %t/test.Osize.swift // 3. Then compile those helper test files and make sure we emit the appropriate // swift modules. // // This means that we test the following: // // a. idempotence: That invoking twice with/without the emit-ossa-modules flag // always doesn't result in a new swift interface being emitted. // // b. That that -emit-ossa-modules cause us to use a different swift module. // // c. When compiling without optimizations, the emit-ossa-modules does nothing // and we always serialize SIL in OSSA form. // // d. That when compiling with optimizations, the emit-ossa-modules controls // whether or not SIL is serialized in OSSA form. // // NOTE: What we compile the test file with does not matter. The swift interface // file controls how the module is optimized. /////////////////////////////// // No Optimization Specified // /////////////////////////////// // RUN: %empty-directory(%t/MCP.default) // RUN: %empty-directory(%t/MCP.default/old) // RUN: ls %t/MCP.default | count 1 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.default -parse-stdlib -I %t %t/test.default.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.default | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.default -parse-stdlib -I %t %t/test.default.swift -Rmodule-interface-rebuild -verify // RUN: %target-sil-opt -module-name SwiftModuleDefault %t/MCP.default/*.swiftmodule > %t/MCP.default/old/first.sil // RUN: cat %t/MCP.default/old/first.sil | grep '@$s18SwiftModuleDefault3fooAA5KlassCyF' | grep '[[]ossa[]]' // RUN: mv %t/MCP.default/*.swiftmodule %t/MCP.default/old // RUN: ls %t/MCP.default | count 2 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.default -parse-stdlib -I %t %t/test.default.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.default | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.default -parse-stdlib -I %t %t/test.default.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.default | count 3 // RUN: %target-sil-opt -module-name SwiftModuleDefault %t/MCP.default/*.swiftmodule > %t/MCP.default/second.sil // // These should be the same. // RUN: diff -u %t/MCP.default/old/first.sil %t/MCP.default/second.sil // // But their actual names should be different since the hash is in the file name. // RUN: cd %t/MCP.default && ls *.swiftmodule > %t/MCP.default/firstFile // RUN: cd %t/MCP.default/old && ls *.swiftmodule > %t/MCP.default/secondFile // RUN: not diff -u %t/MCP.default/firstFile %t/MCP.default/secondFile /////////// // Onone // /////////// // RUN: %empty-directory(%t/MCP.Onone) // RUN: %empty-directory(%t/MCP.Onone/old) // RUN: ls %t/MCP.Onone | count 1 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.Onone -parse-stdlib -I %t %t/test.Onone.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.Onone | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.Onone -parse-stdlib -I %t %t/test.Onone.swift -Rmodule-interface-rebuild -verify // RUN: %target-sil-opt -module-name SwiftModuleOnone %t/MCP.Onone/*.swiftmodule | grep '@$s16SwiftModuleOnone3fooAA5KlassCyF' | grep '[[]ossa[]]' // RUN: mv %t/MCP.Onone/*.swiftmodule %t/MCP.Onone/old // RUN: ls %t/MCP.Onone | count 2 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.Onone -parse-stdlib -I %t %t/test.Onone.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.Onone | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.Onone -parse-stdlib -I %t %t/test.Onone.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.Onone | count 3 // // These should be the same. // // But their name should be different // RUN: cd %t/MCP.Onone && ls *.swiftmodule > %t/MCP.Onone/firstFile // RUN: cd %t/MCP.Onone/old && ls *.swiftmodule > %t/MCP.Onone/secondFile // RUN: not diff -u %t/MCP.Onone/firstFile %t/MCP.Onone/secondFile /////////// // Osize // /////////// // RUN: %empty-directory(%t/MCP.Osize) // RUN: %empty-directory(%t/MCP.Osize/old) // RUN: ls %t/MCP.Osize | count 1 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.Osize -parse-stdlib -I %t %t/test.Osize.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.Osize | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.Osize -parse-stdlib -I %t %t/test.Osize.swift -Rmodule-interface-rebuild -verify // The grep at the end is an inverse so we are validating that the line doesn't have ossa. // RUN: %target-sil-opt -module-name SwiftModuleOsize %t/MCP.Osize/*.swiftmodule | grep '@$s16SwiftModuleOsize3fooAA5KlassCyF' | grep -v '[[]ossa[]]' // RUN: mv %t/MCP.Osize/*.swiftmodule %t/MCP.Osize/old // RUN: ls %t/MCP.Osize | count 2 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.Osize -parse-stdlib -I %t %t/test.Osize.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.Osize | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.Osize -parse-stdlib -I %t %t/test.Osize.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.Osize | count 3 // RUN: %target-sil-opt -module-name SwiftModuleOsize %t/MCP.Osize/*.swiftmodule | grep '@$s16SwiftModuleOsize3fooAA5KlassCyF' | grep '[[]ossa[]]' // // These should not be the same. // RUN: not diff -u %t/MCP.Osize/*.swiftmodule %t/MCP.Osize/old/*.swiftmodule // // And their name should be different // RUN: cd %t/MCP.Osize && ls *.swiftmodule > %t/MCP.Osize/firstFile // RUN: cd %t/MCP.Osize/old && ls *.swiftmodule > %t/MCP.Osize/secondFile // RUN: not diff -u %t/MCP.Osize/firstFile %t/MCP.Osize/secondFile /////// // O // /////// // RUN: %empty-directory(%t/MCP.O) // RUN: %empty-directory(%t/MCP.O/old) // RUN: ls %t/MCP.O | count 1 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.O -parse-stdlib -I %t %t/test.O.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.O | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -module-cache-path %t/MCP.O -parse-stdlib -I %t %t/test.O.swift -Rmodule-interface-rebuild -verify // The grep at the end is an inverse so we are validating that the line doesn't have ossa. // RUN: %target-sil-opt -module-name SwiftModuleO %t/MCP.O/*.swiftmodule | grep '@$s12SwiftModuleO3fooAA5KlassCyF' | grep -v '[[]ossa[]]' // RUN: mv %t/MCP.O/*.swiftmodule %t/MCP.O/old // RUN: ls %t/MCP.O | count 2 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.O -parse-stdlib -I %t %t/test.O.remark.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.O | count 3 // RUN: %target-swift-frontend -typecheck -sdk '' -enable-ossa-modules -module-cache-path %t/MCP.O -parse-stdlib -I %t %t/test.O.swift -Rmodule-interface-rebuild -verify // RUN: ls %t/MCP.O | count 3 // RUN: %target-sil-opt -module-name SwiftModuleO %t/MCP.O/*.swiftmodule | grep '@$s12SwiftModuleO3fooAA5KlassCyF' | grep '[[]ossa[]]' // // These should not be the same. // RUN: not diff -u %t/MCP.O/*.swiftmodule %t/MCP.O/old/*.swiftmodule // // And their name should be different // RUN: cd %t/MCP.O && ls *.swiftmodule > %t/MCP.O/firstFile // RUN: cd %t/MCP.O/old && ls *.swiftmodule > %t/MCP.O/secondFile // RUN: not diff -u %t/MCP.O/firstFile %t/MCP.O/secondFile @_fixed_layout public final class Klass { public init() { } } // This is the inlinable function that we are looking for. @inlinable public func foo() -> Klass { return Klass() }