mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Swift Optimizer: constant fold builtins in the simplification passes
This commit is contained in:
@@ -23,8 +23,9 @@ extension BuiltinInst : OnoneSimplifyable {
|
||||
case .IsSameMetatype:
|
||||
optimizeIsSameMetatype(context)
|
||||
default:
|
||||
// TODO: handle other builtin types
|
||||
break
|
||||
if let literal = constantFold(context) {
|
||||
uses.replaceAll(with: literal, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,6 +283,12 @@ extension Instruction {
|
||||
}
|
||||
}
|
||||
|
||||
extension BuiltinInst {
|
||||
func constantFold(_ context: some MutatingContext) -> Value? {
|
||||
context._bridged.constantFoldBuiltin(bridged).value
|
||||
}
|
||||
}
|
||||
|
||||
extension RefCountingInst {
|
||||
func setAtomicity(isAtomic: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
|
||||
@@ -202,5 +202,5 @@ final class PlaceholderValue : Value {
|
||||
}
|
||||
|
||||
extension OptionalBridgedValue {
|
||||
var value: Value? { obj.getAs(AnyObject.self) as? Value }
|
||||
public var value: Value? { obj.getAs(AnyObject.self) as? Value }
|
||||
}
|
||||
|
||||
@@ -202,6 +202,9 @@ struct BridgedPassContext {
|
||||
|
||||
bool tryDeleteDeadClosure(BridgedInstruction closure) const;
|
||||
|
||||
SWIFT_IMPORT_UNSAFE
|
||||
OptionalBridgedValue constantFoldBuiltin(BridgedInstruction builtin) const;
|
||||
|
||||
SWIFT_IMPORT_UNSAFE
|
||||
BridgedValue getSILUndef(swift::SILType type) const {
|
||||
return {swift::SILUndef::get(type, *invocation->getFunction())};
|
||||
|
||||
@@ -52,6 +52,10 @@ APInt constantFoldDiv(APInt lhs, APInt rhs, bool &Overflow, BuiltinValueKind ID)
|
||||
/// The \p ID must be the ID of a trunc/sext/zext builtin.
|
||||
APInt constantFoldCast(APInt val, const BuiltinInfo &BI);
|
||||
|
||||
/// If `ResultsInError` is not none than errors are diagnosed and
|
||||
/// `ResultsInError` is set to true in case of an error.
|
||||
SILValue constantFoldBuiltin(BuiltinInst *BI,
|
||||
Optional<bool> &ResultsInError);
|
||||
|
||||
/// A utility class to do constant folding.
|
||||
class ConstantFolder {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "swift/SILOptimizer/OptimizerBridging.h"
|
||||
#include "swift/SILOptimizer/PassManager/PrettyStackTrace.h"
|
||||
#include "swift/SILOptimizer/PassManager/Transforms.h"
|
||||
#include "swift/SILOptimizer/Utils/ConstantFolding.h"
|
||||
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
|
||||
#include "swift/SILOptimizer/Utils/OptimizerStatsUtils.h"
|
||||
#include "swift/SILOptimizer/Utils/StackNesting.h"
|
||||
@@ -1420,6 +1421,12 @@ bool BridgedPassContext::tryDeleteDeadClosure(BridgedInstruction closure) const
|
||||
return ::tryDeleteDeadClosure(closure.getAs<SingleValueInstruction>(), InstModCallbacks());
|
||||
}
|
||||
|
||||
OptionalBridgedValue BridgedPassContext::constantFoldBuiltin(BridgedInstruction builtin) const {
|
||||
auto bi = builtin.getAs<BuiltinInst>();
|
||||
Optional<bool> resultsInError;
|
||||
return {::constantFoldBuiltin(bi, resultsInError)};
|
||||
}
|
||||
|
||||
void BridgedPassContext::fixStackNesting(BridgedFunction function) const {
|
||||
switch (StackNesting::fixNesting(function.getFunction())) {
|
||||
case StackNesting::Changes::None:
|
||||
|
||||
@@ -566,7 +566,7 @@ static SILValue constantFoldBinary(BuiltinInst *BI,
|
||||
Optional<bool> &ResultsInError) {
|
||||
switch (ID) {
|
||||
default:
|
||||
llvm_unreachable("Not all BUILTIN_BINARY_OPERATIONs are covered!");
|
||||
return nullptr;
|
||||
|
||||
// Not supported yet (not easily computable for APInt).
|
||||
case BuiltinValueKind::ExactSDiv:
|
||||
@@ -1134,7 +1134,7 @@ static SILValue constantFoldIsConcrete(BuiltinInst *BI) {
|
||||
return inst;
|
||||
}
|
||||
|
||||
static SILValue constantFoldBuiltin(BuiltinInst *BI,
|
||||
SILValue swift::constantFoldBuiltin(BuiltinInst *BI,
|
||||
Optional<bool> &ResultsInError) {
|
||||
const IntrinsicInfo &Intrinsic = BI->getIntrinsicInfo();
|
||||
SILModule &M = BI->getModule();
|
||||
|
||||
@@ -24,6 +24,23 @@ class C1<T> {
|
||||
class C2<T> : C1<T> {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil @constantFoldAdd
|
||||
// CHECK: [[A:%.*]] = integer_literal $Builtin.Int64, 12
|
||||
// CHECK: [[C:%.*]] = integer_literal $Builtin.Int1, 0
|
||||
// CHECK: [[T:%.*]] = tuple ([[A]] : $Builtin.Int64, [[C]] : $Builtin.Int1)
|
||||
// CHECK: [[R:%.*]] = tuple_extract [[T]] : $(Builtin.Int64, Builtin.Int1), 0
|
||||
// CHECK: return [[R]]
|
||||
// CHECK: } // end sil function 'constantFoldAdd'
|
||||
sil @constantFoldAdd : $@convention(thin) () -> Builtin.Int64 {
|
||||
bb0:
|
||||
%0 = integer_literal $Builtin.Int64, 10
|
||||
%1 = integer_literal $Builtin.Int64, 2
|
||||
%2 = integer_literal $Builtin.Int1, 1
|
||||
%3 = builtin "sadd_with_overflow_Int64"(%0 : $Builtin.Int64, %1 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
||||
%4 = tuple_extract %3 : $(Builtin.Int64, Builtin.Int1), 0
|
||||
return %4 : $Builtin.Int64
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil @isConcrete_true
|
||||
// CHECK: bb0(%0 : $@thin Int.Type):
|
||||
// CHECK: [[R:%.*]] = integer_literal $Builtin.Int1, -1
|
||||
|
||||
Reference in New Issue
Block a user