| //===--- RawSILInstLowering.cpp -------------------------------------------===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "MandatoryOptUtils.h" |
| #include "swift/SIL/SILBuilder.h" |
| #include "swift/SIL/SILFunction.h" |
| #include "swift/SIL/SILInstruction.h" |
| #include "swift/SILOptimizer/PassManager/Passes.h" |
| #include "swift/SILOptimizer/PassManager/Transforms.h" |
| |
| using namespace swift; |
| |
| /// lowerRawSILOperations - There are a variety of raw-sil instructions like |
| /// 'assign' that are only used by this pass. Now that definite initialization |
| /// checking is done, remove them. |
| static bool lowerRawSILOperations(SILFunction &Fn) { |
| bool Changed = false; |
| for (auto &BB : Fn) { |
| auto I = BB.begin(), E = BB.end(); |
| while (I != E) { |
| SILInstruction *Inst = &*I; |
| ++I; |
| |
| // Unprocessed assigns just lower into assignments, not initializations. |
| if (auto *AI = dyn_cast<AssignInst>(Inst)) { |
| SILBuilderWithScope B(AI); |
| lowerAssignInstruction(B, AI, |
| PartialInitializationKind::IsNotInitialization); |
| // Assign lowering may split the block. If it did, |
| // reset our iteration range to the block after the insertion. |
| if (B.getInsertionBB() != &BB) |
| I = E; |
| Changed = true; |
| continue; |
| } |
| |
| // mark_uninitialized just becomes a noop, resolving to its operand. |
| if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst)) { |
| MUI->replaceAllUsesWith(MUI->getOperand()); |
| MUI->eraseFromParent(); |
| Changed = true; |
| continue; |
| } |
| |
| // mark_function_escape just gets zapped. |
| if (isa<MarkFunctionEscapeInst>(Inst)) { |
| Inst->eraseFromParent(); |
| Changed = true; |
| continue; |
| } |
| } |
| } |
| return Changed; |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Top Level Entrypoint |
| //===----------------------------------------------------------------------===// |
| |
| namespace { |
| |
| class RawSILInstLowering : public SILFunctionTransform { |
| void run() override { |
| // Do not try to relower raw instructions in canonical SIL. There won't be |
| // any there. |
| if (getFunction()->wasDeserializedCanonical()) { |
| return; |
| } |
| |
| // Lower raw-sil only instructions used by this pass, like "assign". |
| if (lowerRawSILOperations(*getFunction())) |
| invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody); |
| } |
| }; |
| |
| } // end anonymous namespace |
| |
| SILTransform *swift::createRawSILInstLowering() { |
| return new RawSILInstLowering(); |
| } |