Skip to content

Commit 64b7c4f

Browse files
committed
Add Builtin.print_disabled()
1 parent c2fd49c commit 64b7c4f

File tree

16 files changed

+111
-5
lines changed

16 files changed

+111
-5
lines changed

include/swift/AST/Builtins.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,9 @@ BUILTIN_MISC_OPERATION(StaticReport, "staticReport", "", Special)
642642
/// Returns the selected assertion configuration.
643643
BUILTIN_MISC_OPERATION(AssertConf, "assert_configuration", "n", Special)
644644

645+
/// PrintDisabled has type () -> Bool
646+
BUILTIN_MISC_OPERATION(PrintDisabled, "print_disabled", "n", Special)
647+
645648
/// StringObjectOr has type (T,T) -> T.
646649
/// Sets bits in a string object. The first operand is bit-cast string literal
647650
/// pointer to an integer. The second operand is the bit mask to be or'd into

include/swift/AST/SILOptions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ class SILOptions {
127127
/// The assert configuration controls how assertions behave.
128128
unsigned AssertConfig = Debug;
129129

130+
enum PrintConfiguration: unsigned {
131+
// Used by stdlib code to tell whether client is built with -disable-print
132+
Normal = 0,
133+
Disabled = 1,
134+
};
135+
136+
/// The print configuration how printing from stdlib should behave.
137+
unsigned PrintConfig = Normal;
138+
130139
/// Should we print out instruction counts if -print-stats is passed in?
131140
bool PrintInstCounts = false;
132141

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ def enable_experimental_static_assert :
446446
Flag<["-"], "enable-experimental-static-assert">,
447447
HelpText<"Enable experimental #assert">;
448448

449+
def experimental_disable_print : Flag<["-"], "experimental-disable-print">,
450+
Flags<[FrontendOption, HelpHidden]>,
451+
HelpText<"Turn print() calls into no-ops.">;
452+
449453
def enable_experimental_named_opaque_types :
450454
Flag<["-"], "enable-experimental-named-opaque-types">,
451455
HelpText<"Enable experimental support for named opaque result types">;

include/swift/SILOptimizer/Utils/ConstantFolding.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ class ConstantFolder {
6464
/// The assert configuration of SILOptions.
6565
unsigned AssertConfiguration;
6666

67+
/// The print configuration of SILOptions.
68+
unsigned PrintConfiguration;
69+
6770
/// Print diagnostics as part of mandatory constant propagation.
6871
bool EnableDiagnostics;
6972

@@ -79,11 +82,13 @@ class ConstantFolder {
7982
/// \param Callback Called for each constant folded instruction.
8083
ConstantFolder(SILOptFunctionBuilder &FuncBuilder,
8184
unsigned AssertConfiguration,
85+
unsigned PrintConfiguration,
8286
bool EnableDiagnostics = false,
8387
std::function<void (SILInstruction *)> Callback =
8488
[](SILInstruction *){}) :
8589
FuncBuilder(FuncBuilder),
8690
AssertConfiguration(AssertConfiguration),
91+
PrintConfiguration(PrintConfiguration),
8792
EnableDiagnostics(EnableDiagnostics),
8893
Callback(Callback) { }
8994

lib/AST/Builtins.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,6 +1682,12 @@ static ValueDecl *getAssertConfOperation(ASTContext &C, Identifier Id) {
16821682
return getBuiltinFunction(Id, {}, Int32Ty);
16831683
}
16841684

1685+
static ValueDecl *getPrintDisabledOperation(ASTContext &C, Identifier Id) {
1686+
// () -> Int1
1687+
auto Int1Ty = BuiltinIntegerType::get(1, C);
1688+
return getBuiltinFunction(Id, {}, Int1Ty);
1689+
}
1690+
16851691
static ValueDecl *getFixLifetimeOperation(ASTContext &C, Identifier Id) {
16861692
// <T> T -> ()
16871693
BuiltinFunctionBuilder builder(C);
@@ -2675,6 +2681,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
26752681

26762682
case BuiltinValueKind::AssertConf:
26772683
return getAssertConfOperation(Context, Id);
2684+
2685+
case BuiltinValueKind::PrintDisabled:
2686+
return getPrintDisabledOperation(Context, Id);
26782687

26792688
case BuiltinValueKind::FixLifetime:
26802689
return getFixLifetimeOperation(Context, Id);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,13 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
13971397
(IRGenOpts.shouldOptimize() ? SILOptions::Release : SILOptions::Debug);
13981398
}
13991399

1400+
Opts.PrintConfig = Args.hasArg(OPT_experimental_disable_print)
1401+
? SILOptions::Disabled
1402+
: SILOptions::Normal;
1403+
if (FEOpts.ParseStdlib) {
1404+
Opts.PrintConfig = SILOptions::DisableReplacement;
1405+
}
1406+
14001407
// -Ounchecked might also set removal of runtime asserts (cond_fail).
14011408
Opts.RemoveRuntimeAsserts |= Args.hasArg(OPT_RemoveRuntimeAsserts);
14021409

lib/IRGen/GenBuiltin.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,10 @@ if (Builtin.ID == BuiltinValueKind::id) { \
10871087
out.add(DebugAssert);
10881088
return;
10891089
}
1090+
1091+
if (Builtin.ID == BuiltinValueKind::PrintDisabled) {
1092+
llvm_unreachable("PrintDisabled not constant folded");
1093+
}
10901094

10911095
if (Builtin.ID == BuiltinValueKind::DestroyArray) {
10921096
// The input type is (T.Type, Builtin.RawPointer, Builtin.Word).

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AllocRaw)
641641
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, And)
642642
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, GenericAnd)
643643
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AssertConf)
644+
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, PrintDisabled)
644645
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AssignCopyArrayNoAlias)
645646
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AssignCopyArrayFrontToBack)
646647
BUILTIN_OPERAND_OWNERSHIP(InstantaneousUse, AssignCopyArrayBackToFront)

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ CONSTANT_OWNERSHIP_BUILTIN(None, IsSameMetatype)
486486
CONSTANT_OWNERSHIP_BUILTIN(None, Alignof)
487487
CONSTANT_OWNERSHIP_BUILTIN(None, AllocRaw)
488488
CONSTANT_OWNERSHIP_BUILTIN(None, AssertConf)
489+
CONSTANT_OWNERSHIP_BUILTIN(None, PrintDisabled)
489490
CONSTANT_OWNERSHIP_BUILTIN(None, UToSCheckedTrunc)
490491
CONSTANT_OWNERSHIP_BUILTIN(None, SToSCheckedTrunc)
491492
CONSTANT_OWNERSHIP_BUILTIN(None, SToUCheckedTrunc)

lib/SILOptimizer/IPO/GlobalOpt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ replaceLoadsByKnownValue(SILFunction *InitF, SILGlobalVariable *SILG,
409409
// constant, e.g.
410410
// let a = 1
411411
// let b = a + 1
412-
ConstantFolder constFolder(FunctionBuilder, PM->getOptions().AssertConfig);
412+
ConstantFolder constFolder(FunctionBuilder, PM->getOptions().AssertConfig,
413+
PM->getOptions().PrintConfig);
413414
for (SILInstruction *inst : insertedInsts) {
414415
constFolder.addToWorklist(inst);
415416
}

lib/SILOptimizer/Mandatory/ConstantPropagation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ConstantPropagation : public SILFunctionTransform {
3535
void run() override {
3636
SILOptFunctionBuilder FuncBuilder(*this);
3737
ConstantFolder Folder(FuncBuilder, getOptions().AssertConfig,
38-
EnableDiagnostics);
38+
getOptions().PrintConfig, EnableDiagnostics);
3939
Folder.initializeWorklist(*getFunction());
4040
auto Invalidation = Folder.processWorkList();
4141

lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ static bool isBarrier(SILInstruction *inst) {
123123
case BuiltinValueKind::ShuffleVector:
124124
case BuiltinValueKind::StaticReport:
125125
case BuiltinValueKind::AssertConf:
126+
case BuiltinValueKind::PrintDisabled:
126127
case BuiltinValueKind::StringObjectOr:
127128
case BuiltinValueKind::UToSCheckedTrunc:
128129
case BuiltinValueKind::SToUCheckedTrunc:

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class SimplifyCFG {
138138
bool EnableJumpThread)
139139
: FuncBuilder(T), Fn(Fn), PM(T.getPassManager()),
140140
ConstFolder(FuncBuilder, PM->getOptions().AssertConfig,
141+
PM->getOptions().PrintConfig,
141142
/* EnableDiagnostics */ false,
142143
[&](SILInstruction *I) { constFoldingCallback(I); }),
143144
ShouldVerify(Verify), EnableJumpThread(EnableJumpThread) {}

lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,15 @@ static SILValue constantFoldIsConcrete(BuiltinInst *BI) {
11521152
return inst;
11531153
}
11541154

1155+
static SILValue constantFoldPrintDisabled(BuiltinInst *BI, bool PrintDisabled) {
1156+
SILBuilderWithScope builder(BI);
1157+
auto *inst = builder.createIntegerLiteral(
1158+
BI->getLoc(), SILType::getBuiltinIntegerType(1, builder.getASTContext()),
1159+
PrintDisabled);
1160+
BI->replaceAllUsesWith(inst);
1161+
return inst;
1162+
}
1163+
11551164
static SILValue constantFoldBuiltin(BuiltinInst *BI,
11561165
Optional<bool> &ResultsInError) {
11571166
const IntrinsicInfo &Intrinsic = BI->getIntrinsicInfo();
@@ -1569,7 +1578,8 @@ void ConstantFolder::initializeWorklist(SILFunction &f) {
15691578
}
15701579

15711580
if (isApplyOfBuiltin(*inst, BuiltinValueKind::GlobalStringTablePointer) ||
1572-
isApplyOfBuiltin(*inst, BuiltinValueKind::IsConcrete)) {
1581+
isApplyOfBuiltin(*inst, BuiltinValueKind::IsConcrete) ||
1582+
isApplyOfBuiltin(*inst, BuiltinValueKind::PrintDisabled)) {
15731583
WorkList.insert(inst);
15741584
continue;
15751585
}
@@ -1779,7 +1789,7 @@ ConstantFolder::processWorkList() {
17791789
if (isApplyOfBuiltin(*I, BuiltinValueKind::GlobalStringTablePointer)) {
17801790
if (constantFoldGlobalStringTablePointerBuiltin(cast<BuiltinInst>(I),
17811791
EnableDiagnostics)) {
1782-
// Here, the bulitin instruction got folded, so clean it up.
1792+
// Here, the builtin instruction got folded, so clean it up.
17831793
eliminateDeadInstruction(I, callbacks);
17841794
}
17851795
continue;
@@ -1804,13 +1814,25 @@ ConstantFolder::processWorkList() {
18041814

18051815
if (isApplyOfBuiltin(*I, BuiltinValueKind::IsConcrete)) {
18061816
if (constantFoldIsConcrete(cast<BuiltinInst>(I))) {
1807-
// Here, the bulitin instruction got folded, so clean it up.
1817+
// Here, the builtin instruction got folded, so clean it up.
18081818
recursivelyDeleteTriviallyDeadInstructions(I, /*force*/ true,
18091819
callbacks);
18101820
}
18111821
continue;
18121822
}
18131823

1824+
if (PrintConfiguration != SILOptions::DisableReplacement) {
1825+
if (isApplyOfBuiltin(*I, BuiltinValueKind::PrintDisabled)) {
1826+
if (constantFoldPrintDisabled(cast<BuiltinInst>(I),
1827+
PrintConfiguration ==
1828+
SILOptions::Disabled)) {
1829+
// Here, the builtin instruction got folded, so clean it up.
1830+
eliminateDeadInstruction(I, callbacks);
1831+
}
1832+
continue;
1833+
}
1834+
}
1835+
18141836
if (auto *bi = dyn_cast<BuiltinInst>(I)) {
18151837
if (auto kind = bi->getBuiltinKind()) {
18161838
if (SILValue v = specializePolymorphicBuiltin(bi, kind.getValue())) {

stdlib/public/core/Builtin.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,19 @@ func _trueAfterDiagnostics() -> Builtin.Int1 {
768768
return true._value
769769
}
770770

771+
/// Whether client code is built with -print-disabled.
772+
@_alwaysEmitIntoClient
773+
private func _isPrintingDisabled() -> Bool {
774+
return Bool(Builtin.print_disabled())
775+
}
776+
777+
// For testing only.
778+
@_alwaysEmitIntoClient
779+
private func _customPrint(_ s: String) {
780+
if _isPrintingDisabled() { return }
781+
print(s)
782+
}
783+
771784
/// Returns the dynamic type of a value.
772785
///
773786
/// You can use the `type(of:)` function to find the dynamic type of a value,

test/stdlib/print-disabled.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -o %t/Release -O
3+
// RUN: %target-build-swift %s -Xfrontend -disable-access-control -o %t/ReleasePrintDisabled -O -disable-print
4+
// RUN: %target-run %t/Release | %FileCheck %s
5+
// RUN: %target-run %t/ReleasePrintDisabled | %FileCheck %s --check-prefix CHECK-PRINT-DISABLED
6+
7+
// REQUIRES: executable_test
8+
9+
#if canImport(Darwin)
10+
import Darwin
11+
#elseif canImport(Glibc)
12+
import Glibc
13+
#elseif os(Windows)
14+
import CRT
15+
import WinSDK
16+
#endif
17+
18+
puts("Start\n")
19+
_customPrint("Hello world!")
20+
21+
// CHECK: Start
22+
// CHECK: Hello world!
23+
24+
// CHECK-PRINT-DISABLED: Start
25+
// CHECK-PRINT-DISABLED-NOT: Hello world!

0 commit comments

Comments
 (0)