|
| 1 | +//===--- CastOptimizer.h --------------------------------------------------===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift.org open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2014 - 2017 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 | +#ifndef SWIFT_SILOPTIMIZER_UTILS_CASTOPTIMIZER_H |
| 14 | +#define SWIFT_SILOPTIMIZER_UTILS_CASTOPTIMIZER_H |
| 15 | + |
| 16 | +#include "swift/Basic/ArrayRefView.h" |
| 17 | +#include "swift/SIL/SILBuilder.h" |
| 18 | +#include "swift/SIL/SILCloner.h" |
| 19 | +#include "swift/SIL/SILInstruction.h" |
| 20 | +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" |
| 21 | +#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" |
| 22 | +#include "swift/SILOptimizer/Analysis/EpilogueARCAnalysis.h" |
| 23 | +#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" |
| 24 | +#include "llvm/ADT/SmallPtrSet.h" |
| 25 | +#include "llvm/Support/Allocator.h" |
| 26 | +#include <functional> |
| 27 | +#include <utility> |
| 28 | + |
| 29 | +namespace swift { |
| 30 | + |
| 31 | +/// \brief This is a helper class used to optimize casts. |
| 32 | +class CastOptimizer { |
| 33 | + // Callback to be called when uses of an instruction should be replaced. |
| 34 | + std::function<void(SingleValueInstruction *I, ValueBase *V)> |
| 35 | + ReplaceInstUsesAction; |
| 36 | + |
| 37 | + // Callback to call when an instruction needs to be erased. |
| 38 | + std::function<void(SILInstruction *)> EraseInstAction; |
| 39 | + |
| 40 | + // Callback to call after an optimization was performed based on the fact |
| 41 | + // that a cast will succeed. |
| 42 | + std::function<void()> WillSucceedAction; |
| 43 | + |
| 44 | + // Callback to call after an optimization was performed based on the fact |
| 45 | + // that a cast will fail. |
| 46 | + std::function<void()> WillFailAction; |
| 47 | + |
| 48 | + /// Optimize a cast from a bridged ObjC type into |
| 49 | + /// a corresponding Swift type implementing _ObjectiveCBridgeable. |
| 50 | + SILInstruction *optimizeBridgedObjCToSwiftCast( |
| 51 | + SILInstruction *Inst, bool isConditional, SILValue Src, SILValue Dest, |
| 52 | + CanType Source, CanType Target, Type BridgedSourceTy, |
| 53 | + Type BridgedTargetTy, SILBasicBlock *SuccessBB, SILBasicBlock *FailureBB); |
| 54 | + |
| 55 | + /// Optimize a cast from a Swift type implementing _ObjectiveCBridgeable |
| 56 | + /// into a bridged ObjC type. |
| 57 | + SILInstruction *optimizeBridgedSwiftToObjCCast( |
| 58 | + SILInstruction *Inst, CastConsumptionKind ConsumptionKind, |
| 59 | + bool isConditional, SILValue Src, SILValue Dest, CanType Source, |
| 60 | + CanType Target, Type BridgedSourceTy, Type BridgedTargetTy, |
| 61 | + SILBasicBlock *SuccessBB, SILBasicBlock *FailureBB); |
| 62 | + |
| 63 | + void deleteInstructionsAfterUnreachable(SILInstruction *UnreachableInst, |
| 64 | + SILInstruction *TrapInst); |
| 65 | + |
| 66 | +public: |
| 67 | + CastOptimizer(std::function<void(SingleValueInstruction *I, ValueBase *V)> |
| 68 | + ReplaceInstUsesAction, |
| 69 | + std::function<void(SILInstruction *)> EraseAction, |
| 70 | + std::function<void()> WillSucceedAction, |
| 71 | + std::function<void()> WillFailAction = []() {}) |
| 72 | + : ReplaceInstUsesAction(ReplaceInstUsesAction), |
| 73 | + EraseInstAction(EraseAction), WillSucceedAction(WillSucceedAction), |
| 74 | + WillFailAction(WillFailAction) {} |
| 75 | + |
| 76 | + // This constructor is used in |
| 77 | + // 'SILOptimizer/Mandatory/ConstantPropagation.cpp'. MSVC2015 compiler |
| 78 | + // couldn't use the single constructor version which has three default |
| 79 | + // arguments. It seems the number of the default argument with lambda is |
| 80 | + // limited. |
| 81 | + CastOptimizer(std::function<void(SingleValueInstruction *I, ValueBase *V)> |
| 82 | + ReplaceInstUsesAction, |
| 83 | + std::function<void(SILInstruction *)> EraseAction = |
| 84 | + [](SILInstruction *) {}) |
| 85 | + : CastOptimizer(ReplaceInstUsesAction, EraseAction, []() {}, []() {}) {} |
| 86 | + |
| 87 | + /// Simplify checked_cast_br. It may change the control flow. |
| 88 | + SILInstruction *simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst); |
| 89 | + |
| 90 | + /// Simplify checked_cast_value_br. It may change the control flow. |
| 91 | + SILInstruction * |
| 92 | + simplifyCheckedCastValueBranchInst(CheckedCastValueBranchInst *Inst); |
| 93 | + |
| 94 | + /// Simplify checked_cast_addr_br. It may change the control flow. |
| 95 | + SILInstruction * |
| 96 | + simplifyCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *Inst); |
| 97 | + |
| 98 | + /// Optimize checked_cast_br. This cannot change the control flow. |
| 99 | + SILInstruction *optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst); |
| 100 | + |
| 101 | + /// Optimize checked_cast_value_br. This cannot change the control flow. |
| 102 | + SILInstruction * |
| 103 | + optimizeCheckedCastValueBranchInst(CheckedCastValueBranchInst *Inst); |
| 104 | + |
| 105 | + /// Optimize checked_cast_addr_br. This cannot change the control flow. |
| 106 | + SILInstruction * |
| 107 | + optimizeCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *Inst); |
| 108 | + |
| 109 | + /// Optimize unconditional_checked_cast. This cannot change the control flow. |
| 110 | + ValueBase * |
| 111 | + optimizeUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *Inst); |
| 112 | + |
| 113 | + /// Optimize unconditional_checked_cast_addr. This cannot change the control |
| 114 | + /// flow. |
| 115 | + SILInstruction *optimizeUnconditionalCheckedCastAddrInst( |
| 116 | + UnconditionalCheckedCastAddrInst *Inst); |
| 117 | + |
| 118 | + /// Check if it is a bridged cast and optimize it. |
| 119 | + /// May change the control flow. |
| 120 | + SILInstruction *optimizeBridgedCasts(SILInstruction *Inst, |
| 121 | + CastConsumptionKind ConsumptionKind, |
| 122 | + bool isConditional, SILValue Src, |
| 123 | + SILValue Dest, CanType Source, |
| 124 | + CanType Target, SILBasicBlock *SuccessBB, |
| 125 | + SILBasicBlock *FailureBB); |
| 126 | +}; |
| 127 | + |
| 128 | +} // namespace swift |
| 129 | + |
| 130 | +#endif // SWIFT_SILOPTIMIZER_UTILS_CASTOPTIMIZER_H |
0 commit comments