Skip to content

Commit 723c621

Browse files
committed
Run ObjCARCContract when optimizing no matter the IRGenOutputKind.
Previously, we were just running ObjCARCContract when codegening. This is out of character with the rest of the LLVM passes in Swift, namely that after these have run, an IR pass no longer contains any compiler intrinsics. This can be seen by SwiftARCContract running in the -O pipeline. This commit harmonizes the behavior here. For testing purposes, I added a flag that disables the running of ObjCARCContract for testing purposes. rdar://34824507
1 parent 111499d commit 723c621

File tree

5 files changed

+73
-22
lines changed

5 files changed

+73
-22
lines changed

lib/IRGen/IRGen.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#define DEBUG_TYPE "irgen"
18-
#include "swift/Subsystems.h"
18+
#include "IRGenModule.h"
1919
#include "swift/AST/DiagnosticsIRGen.h"
2020
#include "swift/AST/IRGenOptions.h"
2121
#include "swift/AST/LinkLibrary.h"
22-
#include "swift/SIL/SILModule.h"
2322
#include "swift/Basic/Defer.h"
2423
#include "swift/Basic/Dwarf.h"
2524
#include "swift/Basic/Platform.h"
@@ -29,51 +28,57 @@
2928
#include "swift/ClangImporter/ClangImporter.h"
3029
#include "swift/IRGen/IRGenPublic.h"
3130
#include "swift/IRGen/IRGenSILPasses.h"
32-
#include "swift/LLVMPasses/PassesFwd.h"
3331
#include "swift/LLVMPasses/Passes.h"
34-
#include "swift/SILOptimizer/PassManager/Passes.h"
32+
#include "swift/LLVMPasses/PassesFwd.h"
33+
#include "swift/SIL/SILModule.h"
3534
#include "swift/SILOptimizer/PassManager/PassManager.h"
3635
#include "swift/SILOptimizer/PassManager/PassPipeline.h"
36+
#include "swift/SILOptimizer/PassManager/Passes.h"
37+
#include "swift/Subsystems.h"
3738
#include "clang/Basic/TargetInfo.h"
38-
#include "llvm/Bitcode/BitcodeWriterPass.h"
39+
#include "llvm/ADT/StringSet.h"
40+
#include "llvm/Analysis/AliasAnalysis.h"
3941
#include "llvm/Bitcode/BitcodeWriter.h"
42+
#include "llvm/Bitcode/BitcodeWriterPass.h"
4043
#include "llvm/CodeGen/BasicTTIImpl.h"
4144
#include "llvm/IR/Constants.h"
4245
#include "llvm/IR/DataLayout.h"
4346
#include "llvm/IR/IRPrintingPasses.h"
44-
#include "llvm/IR/LegacyPassManager.h"
4547
#include "llvm/IR/LLVMContext.h"
48+
#include "llvm/IR/LegacyPassManager.h"
4649
#include "llvm/IR/Module.h"
4750
#include "llvm/IR/ValueSymbolTable.h"
4851
#include "llvm/IR/Verifier.h"
4952
#include "llvm/Linker/Linker.h"
5053
#include "llvm/MC/SubtargetFeature.h"
54+
#include "llvm/Object/ObjectFile.h"
55+
#include "llvm/Support/CommandLine.h"
5156
#include "llvm/Support/Debug.h"
5257
#include "llvm/Support/ErrorHandling.h"
5358
#include "llvm/Support/FileSystem.h"
5459
#include "llvm/Support/FormattedStream.h"
55-
#include "llvm/Support/TargetRegistry.h"
56-
#include "llvm/Support/Path.h"
57-
#include "llvm/Support/Mutex.h"
5860
#include "llvm/Support/MD5.h"
59-
#include "llvm/ADT/StringSet.h"
60-
#include "llvm/Analysis/AliasAnalysis.h"
61+
#include "llvm/Support/Mutex.h"
62+
#include "llvm/Support/Path.h"
63+
#include "llvm/Support/TargetRegistry.h"
6164
#include "llvm/Target/TargetMachine.h"
6265
#include "llvm/Target/TargetSubtargetInfo.h"
63-
#include "llvm/Transforms/Instrumentation.h"
6466
#include "llvm/Transforms/IPO.h"
6567
#include "llvm/Transforms/IPO/AlwaysInliner.h"
6668
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
69+
#include "llvm/Transforms/Instrumentation.h"
6770
#include "llvm/Transforms/ObjCARC.h"
68-
#include "llvm/Object/ObjectFile.h"
69-
#include "IRGenModule.h"
7071

7172
#include <thread>
7273

7374
using namespace swift;
7475
using namespace irgen;
7576
using namespace llvm;
7677

78+
static cl::opt<bool> DisableObjCARCContract(
79+
"disable-objc-arc-contract", cl::Hidden,
80+
cl::desc("Disable running objc arc contract for testing purposes"));
81+
7782
namespace {
7883
// We need this to access IRGenOptions from extension functions
7984
class PassManagerBuilderWrapper : public PassManagerBuilder {
@@ -446,6 +451,13 @@ bool swift::performLLVM(IRGenOptions &Opts, DiagnosticEngine *Diags,
446451

447452
legacy::PassManager EmitPasses;
448453

454+
// Make sure we do ARC contraction under optimization. We don't
455+
// rely on any other LLVM ARC transformations, but we do need ARC
456+
// contraction to add the objc_retainAutoreleasedReturnValue
457+
// assembly markers and remove clang.arc.used.
458+
if (Opts.Optimize && !DisableObjCARCContract)
459+
EmitPasses.add(createObjCARCContractPass());
460+
449461
// Set up the final emission passes.
450462
switch (Opts.OutputKind) {
451463
case IRGenOutputKind::Module:
@@ -466,13 +478,6 @@ bool swift::performLLVM(IRGenOptions &Opts, DiagnosticEngine *Diags,
466478
EmitPasses.add(createTargetTransformInfoWrapperPass(
467479
TargetMachine->getTargetIRAnalysis()));
468480

469-
// Make sure we do ARC contraction under optimization. We don't
470-
// rely on any other LLVM ARC transformations, but we do need ARC
471-
// contraction to add the objc_retainAutoreleasedReturnValue
472-
// assembly markers.
473-
if (Opts.Optimize)
474-
EmitPasses.add(createObjCARCContractPass());
475-
476481
bool fail = TargetMachine->addPassesToEmitFile(EmitPasses, *RawOS,
477482
FileType, !Opts.Verify);
478483
if (fail) {

test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function(get_test_dependencies SDK result_var_name)
4646
swift-api-digester swift-refactor)
4747
if(NOT SWIFT_BUILT_STANDALONE)
4848
list(APPEND deps_binaries FileCheck arcmt-test c-arcmt-test c-index-test
49-
clang llc llvm-cov llvm-dwarfdump llvm-link llvm-as llvm-profdata not)
49+
clang llc llvm-cov llvm-dwarfdump llvm-link llvm-as llvm-dis llvm-profdata not)
5050
endif()
5151
if(SWIFT_BUILD_SOURCEKIT)
5252
list(APPEND deps_binaries sourcekitd-test complete-test)

test/IRGen/Inputs/StaticInline.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,18 @@
33
static inline NSString *staticInlineFun() {
44
return [[NSLocale currentLocale] localeIdentifier];
55
}
6+
7+
static inline __attribute__((ns_returns_retained))
8+
NSURL *_Nullable test(NSFileManager *self_, NSURL *originalItemURL,
9+
NSURL *newItemURL, NSString *_Nullable backupItemName,
10+
NSFileManagerItemReplacementOptions options,
11+
NSError **_Nullable error) {
12+
NSURL *result = nil;
13+
BOOL success = [self_ replaceItemAtURL:originalItemURL
14+
withItemAtURL:newItemURL
15+
backupItemName:backupItemName
16+
options:options
17+
resultingItemURL:&result
18+
error:error];
19+
return success ? result : nil;
20+
}

test/IRGen/objc_arc_contract.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Make sure that we run objc arc contract when emitting ir or bc with optimization enabled.
2+
3+
// RUN: %empty-directory(%t)
4+
5+
// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-ir -Xllvm -disable-objc-arc-contract -parse-as-library -O | %FileCheck --check-prefix=CHECK-WITHOUT-PASS %s
6+
// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-bc -Xllvm -disable-objc-arc-contract -parse-as-library -O -o %t/test1.bc && %llvm-dis -o - %t/test1.bc | %FileCheck --check-prefix=CHECK-WITHOUT-PASS %s
7+
8+
// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-ir -parse-as-library -O | %FileCheck --check-prefix=CHECK-WITH-PASS %s
9+
// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-bc -parse-as-library -O -o %t/test2.bc && %llvm-dis -o - %t/test2.bc | %FileCheck --check-prefix=CHECK-WITH-PASS %s
10+
11+
12+
// REQUIRES: objc_interop
13+
// REQUIRES: asserts
14+
15+
// CHECK-WITHOUT-PASS: call void (...) @clang.arc.use
16+
// CHECK-WITH-PASS-NOT: call void (...) @clang.arc.use
17+
18+
import Foundation
19+
20+
@inline(never)
21+
public func foo() throws {
22+
let x: FileManager! = nil
23+
let y = URL(string: "http://swift.org")
24+
let z: URL! = nil
25+
let w: String = "foo"
26+
var e: NSError? = nil
27+
test(x, y, z, w, .usingNewMetadataOnly, &e)
28+
}

test/lit.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ config.llvm_profdata = inferSwiftBinary('llvm-profdata')
262262
config.llvm_cov = inferSwiftBinary('llvm-cov')
263263
config.filecheck = inferSwiftBinary('FileCheck')
264264
config.llvm_dwarfdump = inferSwiftBinary('llvm-dwarfdump')
265+
config.llvm_dis = inferSwiftBinary('llvm-dis')
265266
config.sourcekitd_test = inferSwiftBinary('sourcekitd-test')
266267
config.complete_test = inferSwiftBinary('complete-test')
267268
config.swift_api_digester = inferSwiftBinary('swift-api-digester')
@@ -354,6 +355,7 @@ config.substitutions.append( ('%swift-format', config.swift_format) )
354355
config.substitutions.append( ('%llvm-link', config.llvm_link) )
355356
config.substitutions.append( ('%swift-llvm-opt', config.swift_llvm_opt) )
356357
config.substitutions.append( ('%llvm-dwarfdump', config.llvm_dwarfdump) )
358+
config.substitutions.append( ('%llvm-dis', config.llvm_dis) )
357359

358360
# This must come after all substitutions containing "%swift".
359361
config.substitutions.append(
@@ -426,6 +428,7 @@ disallow('swift-ide-test')
426428
disallow('clang')
427429
disallow('FileCheck')
428430
disallow('llvm-dwarfdump')
431+
disallow('llvm-dis')
429432

430433
config.substitutions.insert(0,
431434
('%p',

0 commit comments

Comments
 (0)