Skip to content

Commit b376658

Browse files
author
Josh Learn
committed
Refactor OSLogOptimization utility functions into a separate file
1 parent dd0f545 commit b376658

File tree

4 files changed

+111
-60
lines changed

4 files changed

+111
-60
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===--- CompileTimeInterpolationUtils.h ----------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// Utilities for the compile-time string interpolation approach used by the
14+
// OSLogOptimization pass.
15+
16+
#ifndef SWIFT_SILOPTIMIZER_COMPILE_TIME_INTERPOLATION_H
17+
#define SWIFT_SILOPTIMIZER_COMPILE_TIME_INTERPOLATION_H
18+
19+
#include "swift/SIL/SILBasicBlock.h"
20+
#include "swift/SIL/SILConstants.h"
21+
#include "swift/SILOptimizer/Utils/ConstExpr.h"
22+
23+
namespace swift {
24+
25+
/// Decide if the given instruction (which could possibly be a call) should
26+
/// be constant evaluated.
27+
///
28+
/// \returns true iff the given instruction is not a call or if it is, it calls
29+
/// a known constant-evaluable function such as string append etc., or calls
30+
/// a function annotate as "constant_evaluable".
31+
bool shouldAttemptEvaluation(SILInstruction *inst);
32+
33+
/// Skip or evaluate the given instruction based on the evaluation policy and
34+
/// handle errors. The policy is to evaluate all non-apply instructions as well
35+
/// as apply instructions that are marked as "constant_evaluable".
36+
std::pair<Optional<SILBasicBlock::iterator>, Optional<SymbolicValue>>
37+
evaluateOrSkip(ConstExprStepEvaluator &stepEval, SILBasicBlock::iterator instI);
38+
39+
/// Given a vector of SILValues \p worklist, compute the set of transitive
40+
/// users of these values (excluding the worklist values) by following the
41+
/// use-def chain starting at value. Note that this function does not follow
42+
/// use-def chains though branches.
43+
void getTransitiveUsers(SILInstructionResultArray values,
44+
SmallVectorImpl<SILInstruction *> &users);
45+
} // end namespace swift
46+
#endif

lib/SILOptimizer/Mandatory/OSLogOptimization.cpp

Lines changed: 4 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,12 @@
7676
#include "swift/AST/DiagnosticsSIL.h"
7777
#include "swift/AST/Expr.h"
7878
#include "swift/AST/Module.h"
79+
#include "swift/AST/SemanticAttrs.h"
7980
#include "swift/AST/SubstitutionMap.h"
8081
#include "swift/Basic/OptimizationMode.h"
81-
#include "swift/AST/SemanticAttrs.h"
8282
#include "swift/Demangling/Demangle.h"
8383
#include "swift/Demangling/Demangler.h"
84+
#include "swift/SIL/BasicBlockBits.h"
8485
#include "swift/SIL/BasicBlockUtils.h"
8586
#include "swift/SIL/CFG.h"
8687
#include "swift/SIL/InstructionUtils.h"
@@ -93,10 +94,10 @@
9394
#include "swift/SIL/SILLocation.h"
9495
#include "swift/SIL/SILModule.h"
9596
#include "swift/SIL/TypeLowering.h"
96-
#include "swift/SIL/BasicBlockBits.h"
9797
#include "swift/SILOptimizer/PassManager/Passes.h"
9898
#include "swift/SILOptimizer/PassManager/Transforms.h"
9999
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
100+
#include "swift/SILOptimizer/Utils/CompileTimeInterpolationUtils.h"
100101
#include "swift/SILOptimizer/Utils/ConstExpr.h"
101102
#include "swift/SILOptimizer/Utils/InstructionDeleter.h"
102103
#include "swift/SILOptimizer/Utils/SILInliner.h"
@@ -245,38 +246,6 @@ static bool isIntegerOrBoolType(SILType silType, ASTContext &astContext) {
245246
return nominalDecl && isStdlibIntegerOrBoolDecl(nominalDecl, astContext);
246247
}
247248

248-
/// Decide if the given instruction (which could possibly be a call) should
249-
/// be constant evaluated.
250-
///
251-
/// \returns true iff the given instruction is not a call or if it is, it calls
252-
/// a known constant-evaluable function such as string append etc., or calls
253-
/// a function annotate as "constant_evaluable".
254-
static bool shouldAttemptEvaluation(SILInstruction *inst) {
255-
auto *apply = dyn_cast<ApplyInst>(inst);
256-
if (!apply)
257-
return true;
258-
SILFunction *calleeFun = apply->getCalleeFunction();
259-
if (!calleeFun)
260-
return false;
261-
return isConstantEvaluable(calleeFun);
262-
}
263-
264-
/// Skip or evaluate the given instruction based on the evaluation policy and
265-
/// handle errors. The policy is to evaluate all non-apply instructions as well
266-
/// as apply instructions that are marked as "constant_evaluable".
267-
static std::pair<Optional<SILBasicBlock::iterator>, Optional<SymbolicValue>>
268-
evaluateOrSkip(ConstExprStepEvaluator &stepEval,
269-
SILBasicBlock::iterator instI) {
270-
SILInstruction *inst = &(*instI);
271-
272-
// Note that skipping a call conservatively approximates its effects on the
273-
// interpreter state.
274-
if (shouldAttemptEvaluation(inst)) {
275-
return stepEval.tryEvaluateOrElseMakeEffectsNonConstant(instI);
276-
}
277-
return stepEval.skipByMakingEffectsNonConstant(instI);
278-
}
279-
280249
/// Return true iff the given value is a stdlib Int or Bool and it not a direct
281250
/// construction of Int or Bool.
282251
static bool isFoldableIntOrBool(SILValue value, ASTContext &astContext) {
@@ -818,31 +787,6 @@ static SILValue emitCodeForSymbolicValue(SymbolicValue symVal,
818787
}
819788
}
820789

821-
/// Given a SILValue \p value, compute the set of transitive users of the value
822-
/// (excluding value itself) by following the use-def chain starting at value.
823-
/// Note that this function does not follow use-def chains though branches.
824-
static void getTransitiveUsers(SILValue value,
825-
SmallVectorImpl<SILInstruction *> &users) {
826-
// Collect the instructions that are data dependent on the value using a
827-
// fix point iteration.
828-
SmallPtrSet<SILInstruction *, 16> visitedUsers;
829-
SmallVector<SILValue, 16> worklist;
830-
worklist.push_back(value);
831-
832-
while (!worklist.empty()) {
833-
SILValue currVal = worklist.pop_back_val();
834-
for (Operand *use : currVal->getUses()) {
835-
SILInstruction *user = use->getUser();
836-
if (visitedUsers.count(user))
837-
continue;
838-
visitedUsers.insert(user);
839-
llvm::copy(user->getResults(), std::back_inserter(worklist));
840-
}
841-
}
842-
// At this point, visitedUsers have all the transitive, data-dependent uses.
843-
users.append(visitedUsers.begin(), visitedUsers.end());
844-
}
845-
846790
/// Collect the end points of the instructions that are data dependent on \c
847791
/// value. A instruction is data dependent on \c value if its result may
848792
/// transitively depends on \c value. Note that data dependencies through
@@ -853,7 +797,7 @@ static void getTransitiveUsers(SILValue value,
853797
/// \param endUsers buffer for storing the found end points of the data
854798
/// dependence chain.
855799
static void
856-
getEndPointsOfDataDependentChain(SILValue value, SILFunction *fun,
800+
getEndPointsOfDataDependentChain(SingleValueInstruction *value, SILFunction *fun,
857801
SmallVectorImpl<SILInstruction *> &endUsers) {
858802
assert(!value->getType().isAddress());
859803

lib/SILOptimizer/Utils/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ target_sources(swiftSILOptimizer PRIVATE
66
CanonicalizeBorrowScope.cpp
77
CastOptimizer.cpp
88
CheckedCastBrJumpThreading.cpp
9+
CompileTimeInterpolationUtils.cpp
910
ConstantFolding.cpp
1011
ConstExpr.cpp
1112
Devirtualize.cpp
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===--- CompileTimeInterpolationUtils.cpp -------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/SILOptimizer/Utils/CompileTimeInterpolationUtils.h"
14+
#include "swift/AST/ASTContext.h"
15+
#include "swift/SIL/SILFunction.h"
16+
17+
using namespace swift;
18+
19+
bool swift::shouldAttemptEvaluation(SILInstruction *inst) {
20+
auto *apply = dyn_cast<ApplyInst>(inst);
21+
if (!apply)
22+
return true;
23+
SILFunction *calleeFun = apply->getCalleeFunction();
24+
if (!calleeFun)
25+
return false;
26+
return isConstantEvaluable(calleeFun);
27+
}
28+
29+
std::pair<Optional<SILBasicBlock::iterator>, Optional<SymbolicValue>>
30+
swift::evaluateOrSkip(ConstExprStepEvaluator &stepEval,
31+
SILBasicBlock::iterator instI) {
32+
SILInstruction *inst = &(*instI);
33+
34+
// Note that skipping a call conservatively approximates its effects on the
35+
// interpreter state.
36+
if (shouldAttemptEvaluation(inst)) {
37+
return stepEval.tryEvaluateOrElseMakeEffectsNonConstant(instI);
38+
}
39+
return stepEval.skipByMakingEffectsNonConstant(instI);
40+
}
41+
42+
void swift::getTransitiveUsers(SILInstructionResultArray values,
43+
SmallVectorImpl<SILInstruction *> &users) {
44+
// Collect the instructions that are data dependent on the value using a
45+
// fix point iteration.
46+
SmallPtrSet<SILInstruction *, 16> visited;
47+
SmallVector<SILValue, 16> worklist;
48+
llvm::copy(values, std::back_inserter(worklist));
49+
while (!worklist.empty()) {
50+
SILValue currVal = worklist.pop_back_val();
51+
for (Operand *use : currVal->getUses()) {
52+
SILInstruction *user = use->getUser();
53+
if (visited.count(user))
54+
continue;
55+
visited.insert(user);
56+
llvm::copy(user->getResults(), std::back_inserter(worklist));
57+
}
58+
}
59+
users.append(visited.begin(), visited.end());
60+
}

0 commit comments

Comments
 (0)