Skip to content

Commit 1decce2

Browse files
committed
[arc] Move isARCInertBB into ProgramTerminationAnalysis.cpp from ARCAnalysis.cpp.
1 parent 2085f9b commit 1decce2

File tree

6 files changed

+119
-88
lines changed

6 files changed

+119
-88
lines changed

include/swift/SILAnalysis/ARCAnalysis.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_SILANALYSIS_ARCANALYSIS_H
1414
#define SWIFT_SILANALYSIS_ARCANALYSIS_H
1515

16+
#include "swift/SIL/SILArgument.h"
1617
#include "swift/SIL/SILValue.h"
1718
#include "swift/SIL/SILBasicBlock.h"
1819
#include "llvm/ADT/SmallPtrSet.h"
@@ -102,9 +103,6 @@ valueHasARCDecrementOrCheckInInstructionRange(SILValue Op,
102103
SILBasicBlock::iterator End,
103104
AliasAnalysis *AA);
104105

105-
/// Match a call to a trap BB with no ARC relevant side effects.
106-
bool isARCInertTrapBB(SILBasicBlock *BB);
107-
108106
/// A class that attempts to match owned arguments and corresponding epilogue
109107
/// releases for a specific function.
110108
///

include/swift/SILAnalysis/ProgramTerminationAnalysis.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,12 @@
3535
namespace swift {
3636

3737
class ProgramTerminationFunctionInfo {
38-
llvm::SmallPtrSet<SILBasicBlock *, 4> ProgramTerminatingBlocks;
38+
llvm::SmallPtrSet<const SILBasicBlock *, 4> ProgramTerminatingBlocks;
3939

4040
public:
41-
ProgramTerminationFunctionInfo(SILFunction *F) {
42-
for (auto &BB : *F) {
43-
if (!isARCInertTrapBB(&BB))
44-
continue;
45-
ProgramTerminatingBlocks.insert(&BB);
46-
}
47-
}
41+
ProgramTerminationFunctionInfo(const SILFunction *F);
4842

49-
bool isProgramTerminatingBlock(SILBasicBlock *BB) {
43+
bool isProgramTerminatingBlock(const SILBasicBlock *BB) const {
5044
return ProgramTerminatingBlocks.count(BB);
5145
}
5246
};

lib/SILAnalysis/ARCAnalysis.cpp

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -503,78 +503,6 @@ mayGuaranteedUseValue(SILInstruction *User, SILValue Ptr, AliasAnalysis *AA) {
503503
// Utilities for recognizing trap BBs that are ARC inert
504504
//===----------------------------------------------------------------------===//
505505

506-
static bool ignoreableApplyInstInUnreachableBlock(ApplyInst *AI) {
507-
const char *fatalName =
508-
"_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_";
509-
auto *Fn = AI->getCalleeFunction();
510-
511-
// We use endswith here since if we specialize fatal error we will always
512-
// prepend the specialization records to fatalName.
513-
if (!Fn || !Fn->getName().endswith(fatalName))
514-
return false;
515-
516-
return true;
517-
}
518-
519-
static bool ignoreableBuiltinInstInUnreachableBlock(BuiltinInst *BI) {
520-
const BuiltinInfo &BInfo = BI->getBuiltinInfo();
521-
if (BInfo.ID == BuiltinValueKind::CondUnreachable)
522-
return true;
523-
524-
const IntrinsicInfo &IInfo = BI->getIntrinsicInfo();
525-
if (IInfo.ID == llvm::Intrinsic::trap)
526-
return true;
527-
528-
return false;
529-
}
530-
531-
/// Match a call to a trap BB with no ARC relevant side effects.
532-
bool swift::isARCInertTrapBB(SILBasicBlock *BB) {
533-
// Do a quick check at the beginning to make sure that our terminator is
534-
// actually an unreachable. This ensures that in many cases this function will
535-
// exit early and quickly.
536-
auto II = BB->rbegin();
537-
if (!isa<UnreachableInst>(*II))
538-
return false;
539-
540-
auto IE = BB->rend();
541-
while (II != IE) {
542-
// Ignore any instructions without side effects.
543-
if (!II->mayHaveSideEffects()) {
544-
++II;
545-
continue;
546-
}
547-
548-
// Ignore cond fail.
549-
if (isa<CondFailInst>(*II)) {
550-
++II;
551-
continue;
552-
}
553-
554-
// Check for apply insts that we can ignore.
555-
if (auto *AI = dyn_cast<ApplyInst>(&*II)) {
556-
if (ignoreableApplyInstInUnreachableBlock(AI)) {
557-
++II;
558-
continue;
559-
}
560-
}
561-
562-
// Check for builtins that we can ignore.
563-
if (auto *BI = dyn_cast<BuiltinInst>(&*II)) {
564-
if (ignoreableBuiltinInstInUnreachableBlock(BI)) {
565-
++II;
566-
continue;
567-
}
568-
}
569-
570-
// If we can't ignore the instruction, return false.
571-
return false;
572-
}
573-
574-
// Otherwise, we have an unreachable and every instruction is inert from an
575-
// ARC perspective in an unreachable BB.
576-
return true;
577-
}
578506

579507
//===----------------------------------------------------------------------===//
580508
// Owned Argument Utilities

lib/SILAnalysis/Analysis.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,3 @@ SILAnalysis *swift::createClassHierarchyAnalysis(SILModule *M) {
6161
SILAnalysis *swift::createBasicCalleeAnalysis(SILModule *M) {
6262
return new BasicCalleeAnalysis(M);
6363
}
64-
65-
SILAnalysis *swift::createProgramTerminationAnalysis(SILModule *M) {
66-
return new ProgramTerminationAnalysis(M);
67-
}

lib/SILAnalysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_swift_library(swiftSILAnalysis
1515
LoopAnalysis.cpp
1616
LoopRegionAnalysis.cpp
1717
MemoryBehavior.cpp
18+
ProgramTerminationAnalysis.cpp
1819
RCIdentityAnalysis.cpp
1920
SideEffectAnalysis.cpp
2021
SimplifyInstruction.cpp
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===--- ProgramTerminationAnalysis.cpp -----------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#define DEBUG_TYPE "program-termination-analysis"
14+
#include "swift/SILAnalysis/ProgramTerminationAnalysis.h"
15+
#include "swift/SIL/SILFunction.h"
16+
17+
using namespace swift;
18+
19+
//===----------------------------------------------------------------------===//
20+
// Utility
21+
//===----------------------------------------------------------------------===//
22+
23+
static bool ignoreableApplyInstInUnreachableBlock(const ApplyInst *AI) {
24+
const char *fatalName = "_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_";
25+
const auto *Fn = AI->getCalleeFunction();
26+
27+
// We use endswith here since if we specialize fatal error we will always
28+
// prepend the specialization records to fatalName.
29+
if (!Fn || !Fn->getName().endswith(fatalName))
30+
return false;
31+
32+
return true;
33+
}
34+
35+
static bool ignoreableBuiltinInstInUnreachableBlock(const BuiltinInst *BI) {
36+
const BuiltinInfo &BInfo = BI->getBuiltinInfo();
37+
if (BInfo.ID == BuiltinValueKind::CondUnreachable)
38+
return true;
39+
40+
const IntrinsicInfo &IInfo = BI->getIntrinsicInfo();
41+
if (IInfo.ID == llvm::Intrinsic::trap)
42+
return true;
43+
44+
return false;
45+
}
46+
47+
/// Match a call to a trap BB with no ARC relevant side effects.
48+
static bool isARCInertTrapBB(const SILBasicBlock *BB) {
49+
// Do a quick check at the beginning to make sure that our terminator is
50+
// actually an unreachable. This ensures that in many cases this function will
51+
// exit early and quickly.
52+
auto II = BB->rbegin();
53+
if (!isa<UnreachableInst>(*II))
54+
return false;
55+
56+
auto IE = BB->rend();
57+
while (II != IE) {
58+
// Ignore any instructions without side effects.
59+
if (!II->mayHaveSideEffects()) {
60+
++II;
61+
continue;
62+
}
63+
64+
// Ignore cond fail.
65+
if (isa<CondFailInst>(*II)) {
66+
++II;
67+
continue;
68+
}
69+
70+
// Check for apply insts that we can ignore.
71+
if (auto *AI = dyn_cast<ApplyInst>(&*II)) {
72+
if (ignoreableApplyInstInUnreachableBlock(AI)) {
73+
++II;
74+
continue;
75+
}
76+
}
77+
78+
// Check for builtins that we can ignore.
79+
if (auto *BI = dyn_cast<BuiltinInst>(&*II)) {
80+
if (ignoreableBuiltinInstInUnreachableBlock(BI)) {
81+
++II;
82+
continue;
83+
}
84+
}
85+
86+
// If we can't ignore the instruction, return false.
87+
return false;
88+
}
89+
90+
// Otherwise, we have an unreachable and every instruction is inert from an
91+
// ARC perspective in an unreachable BB.
92+
return true;
93+
}
94+
95+
//===----------------------------------------------------------------------===//
96+
// ProgramTerminationFunctionInfo
97+
//===----------------------------------------------------------------------===//
98+
99+
ProgramTerminationFunctionInfo::ProgramTerminationFunctionInfo(
100+
const SILFunction *F) {
101+
for (const auto &BB : *F) {
102+
if (!isARCInertTrapBB(&BB))
103+
continue;
104+
ProgramTerminatingBlocks.insert(&BB);
105+
}
106+
}
107+
108+
//===----------------------------------------------------------------------===//
109+
// Top level Entrypoint
110+
//===----------------------------------------------------------------------===//
111+
112+
SILAnalysis *swift::createProgramTerminationAnalysis(SILModule *M) {
113+
return new ProgramTerminationAnalysis(M);
114+
}

0 commit comments

Comments
 (0)