Skip to content

Commit 9b51e69

Browse files
committed
Swift Optimizer: constant fold builtins in the simplification passes
1 parent 88973a3 commit 9b51e69

File tree

8 files changed

+43
-5
lines changed

8 files changed

+43
-5
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ extension BuiltinInst : OnoneSimplifyable {
2323
case .IsSameMetatype:
2424
optimizeIsSameMetatype(context)
2525
default:
26-
// TODO: handle other builtin types
27-
break
26+
if let literal = constantFold(context) {
27+
uses.replaceAll(with: literal, context)
28+
}
2829
}
2930
}
3031
}

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,12 @@ extension Instruction {
283283
}
284284
}
285285

286+
extension BuiltinInst {
287+
func constantFold(_ context: some MutatingContext) -> Value? {
288+
context._bridged.constantFoldBuiltin(bridged).value
289+
}
290+
}
291+
286292
extension RefCountingInst {
287293
func setAtomicity(isAtomic: Bool, _ context: some MutatingContext) {
288294
context.notifyInstructionsChanged()

SwiftCompilerSources/Sources/SIL/Value.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,5 @@ final class PlaceholderValue : Value {
202202
}
203203

204204
extension OptionalBridgedValue {
205-
var value: Value? { obj.getAs(AnyObject.self) as? Value }
205+
public var value: Value? { obj.getAs(AnyObject.self) as? Value }
206206
}

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ struct BridgedPassContext {
202202

203203
bool tryDeleteDeadClosure(BridgedInstruction closure) const;
204204

205+
SWIFT_IMPORT_UNSAFE
206+
OptionalBridgedValue constantFoldBuiltin(BridgedInstruction builtin) const;
207+
205208
SWIFT_IMPORT_UNSAFE
206209
BridgedValue getSILUndef(swift::SILType type) const {
207210
return {swift::SILUndef::get(type, *invocation->getFunction())};

include/swift/SILOptimizer/Utils/ConstantFolding.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ APInt constantFoldDiv(APInt lhs, APInt rhs, bool &Overflow, BuiltinValueKind ID)
5252
/// The \p ID must be the ID of a trunc/sext/zext builtin.
5353
APInt constantFoldCast(APInt val, const BuiltinInfo &BI);
5454

55+
/// If `ResultsInError` is not none than errors are diagnosed and
56+
/// `ResultsInError` is set to true in case of an error.
57+
SILValue constantFoldBuiltin(BuiltinInst *BI,
58+
Optional<bool> &ResultsInError);
5559

5660
/// A utility class to do constant folding.
5761
class ConstantFolder {

lib/SILOptimizer/PassManager/PassManager.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "swift/SILOptimizer/OptimizerBridging.h"
2828
#include "swift/SILOptimizer/PassManager/PrettyStackTrace.h"
2929
#include "swift/SILOptimizer/PassManager/Transforms.h"
30+
#include "swift/SILOptimizer/Utils/ConstantFolding.h"
3031
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
3132
#include "swift/SILOptimizer/Utils/OptimizerStatsUtils.h"
3233
#include "swift/SILOptimizer/Utils/StackNesting.h"
@@ -1420,6 +1421,12 @@ bool BridgedPassContext::tryDeleteDeadClosure(BridgedInstruction closure) const
14201421
return ::tryDeleteDeadClosure(closure.getAs<SingleValueInstruction>(), InstModCallbacks());
14211422
}
14221423

1424+
OptionalBridgedValue BridgedPassContext::constantFoldBuiltin(BridgedInstruction builtin) const {
1425+
auto bi = builtin.getAs<BuiltinInst>();
1426+
Optional<bool> resultsInError;
1427+
return {::constantFoldBuiltin(bi, resultsInError)};
1428+
}
1429+
14231430
void BridgedPassContext::fixStackNesting(BridgedFunction function) const {
14241431
switch (StackNesting::fixNesting(function.getFunction())) {
14251432
case StackNesting::Changes::None:

lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ static SILValue constantFoldBinary(BuiltinInst *BI,
566566
Optional<bool> &ResultsInError) {
567567
switch (ID) {
568568
default:
569-
llvm_unreachable("Not all BUILTIN_BINARY_OPERATIONs are covered!");
569+
return nullptr;
570570

571571
// Not supported yet (not easily computable for APInt).
572572
case BuiltinValueKind::ExactSDiv:
@@ -1134,7 +1134,7 @@ static SILValue constantFoldIsConcrete(BuiltinInst *BI) {
11341134
return inst;
11351135
}
11361136

1137-
static SILValue constantFoldBuiltin(BuiltinInst *BI,
1137+
SILValue swift::constantFoldBuiltin(BuiltinInst *BI,
11381138
Optional<bool> &ResultsInError) {
11391139
const IntrinsicInfo &Intrinsic = BI->getIntrinsicInfo();
11401140
SILModule &M = BI->getModule();

test/SILOptimizer/simplify_builtin.sil

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,23 @@ class C1<T> {
2424
class C2<T> : C1<T> {
2525
}
2626

27+
// CHECK-LABEL: sil @constantFoldAdd
28+
// CHECK: [[A:%.*]] = integer_literal $Builtin.Int64, 12
29+
// CHECK: [[C:%.*]] = integer_literal $Builtin.Int1, 0
30+
// CHECK: [[T:%.*]] = tuple ([[A]] : $Builtin.Int64, [[C]] : $Builtin.Int1)
31+
// CHECK: [[R:%.*]] = tuple_extract [[T]] : $(Builtin.Int64, Builtin.Int1), 0
32+
// CHECK: return [[R]]
33+
// CHECK: } // end sil function 'constantFoldAdd'
34+
sil @constantFoldAdd : $@convention(thin) () -> Builtin.Int64 {
35+
bb0:
36+
%0 = integer_literal $Builtin.Int64, 10
37+
%1 = integer_literal $Builtin.Int64, 2
38+
%2 = integer_literal $Builtin.Int1, 1
39+
%3 = builtin "sadd_with_overflow_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
40+
%4 = tuple_extract %3 : $(Builtin.Int64, Builtin.Int1), 0
41+
return %4 : $Builtin.Int64
42+
}
43+
2744
// CHECK-LABEL: sil @isConcrete_true
2845
// CHECK: bb0(%0 : $@thin Int.Type):
2946
// CHECK: [[R:%.*]] = integer_literal $Builtin.Int1, -1

0 commit comments

Comments
 (0)