1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
//===--- Condition.h - Defines the SILGen Condition class -------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the Condition class, used by SIL Generation.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SIL_LOWERING_CONDITION_H
#define SWIFT_SIL_LOWERING_CONDITION_H
#include "llvm/ADT/ArrayRef.h"
#include "swift/SIL/SILLocation.h"
#include "swift/SIL/SILValue.h"
#include "SILGenFunction.h"
#include "Scope.h"
#include "llvm/Support/Compiler.h"
namespace swift {
class PatternBindingDecl;
class SILBasicBlock;
namespace Lowering {
/// A condition is the result of evaluating a boolean expression as
/// control flow.
///
/// For each Condition instance, `enterTrue` must be called before `complete`.
/// If `enterFalse` is skipped, then an empty fall-through block is created.
class LLVM_LIBRARY_VISIBILITY Condition {
/// The blocks responsible for executing the true and false conditions. These
/// are initialized non-null and set to null after being emitted.
SILBasicBlock *TrueBB;
SILBasicBlock *FalseBB;
/// The continuation block if both branches are possible.
SILBasicBlock *ContBB;
/// The location wrapping the originator conditional expression.
SILLocation Loc;
public:
Condition(SILBasicBlock *TrueBB, SILBasicBlock *FalseBB,
SILBasicBlock *ContBB,
SILLocation L)
: TrueBB(TrueBB), FalseBB(FalseBB), ContBB(ContBB), Loc(L)
{
assert((TrueBB != nullptr && FalseBB != nullptr) &&
"Requires non-null block pointers.");
}
/// enterTrue - Begin the emission of the true block.
void enterTrue(SILGenFunction &SGF) { enter(SGF, TrueBB); }
/// exitTrue - End the emission of the true block.
void exitTrue(SILGenFunction &SGF, ArrayRef<SILValue> Args = {}) {
exit(SGF, TrueBB, Args);
TrueBB = nullptr;
}
/// enterFalse - Begin the emission of the false block.
void enterFalse(SILGenFunction &SGF) { enter(SGF, FalseBB); }
/// exitFalse - End the emission of the true block.
void exitFalse(SILGenFunction &SGF, ArrayRef<SILValue> Args = {}) {
exit(SGF, FalseBB, Args);
FalseBB = nullptr;
}
/// complete - Complete this conditional execution. This should be called
/// only after all other calls on this Condition have been made.
/// This leaves SGF's SILGenBuilder at the continuation block.
SILBasicBlock *complete(SILGenFunction &SGF);
protected:
void enter(SILGenFunction &SGF, SILBasicBlock *destBB);
void exit(SILGenFunction &SGF, SILBasicBlock *destBB,
ArrayRef<SILValue> Args = {});
};
/// A conditional value is one that depends on conditional execution.
/// Depending on whether a type is address-only, it may be representable using
/// BB argument passing or by storing to a common result buffer.
class ConditionalValue {
SILGenFunction &SGF;
const TypeLowering &tl;
/// The continuation block that receives the conditional value.
SILBasicBlock *contBB;
/// The location associated with the value.
SILLocation loc;
/// The buffer to receive an address-only result, or the BB argument that
/// a loadable result is passed to.
SILValue result;
/// The Scope for the current branch.
std::optional<Scope> scope;
/// A place to hold conditional Initializations of our result.
std::unique_ptr<Initialization> currentInitialization;
public:
/// Begins a conditional computation of the type represented by the given
/// type lowering. This potentially emits a temporary allocation for the
/// result, so it must be called with the insertion point valid and dominating
/// any branches that will be involved in the computation.
ConditionalValue(SILGenFunction &SGF, SGFContext C, SILLocation loc,
const TypeLowering &valueTL);
/// Enter a branch of the conditional value computation. Expression evaluation
/// within this branch may use the returned SGFContext to potentially find a
/// buffer to emit into. If a basic block is given, the insertion point must
/// be invalid, and on return, the given basic block will be emitted, and the
/// insertion point will be inside it. If the basic block is null, then
/// codegen proceeds in the current basic block.
SGFContext enterBranch(SILBasicBlock *bb = nullptr);
/// Exit a branch of the conditional value computation, using the given value
/// as the result of the computation on this branch. Branches to the
/// continuation block for the conditional value. On return, the insertion
/// point will be invalid.
void exitBranch(RValue &&result);
/// Complete the conditional computation. The insertion point must be invalid.
/// On return, the continuation block for the conditional will be emitted, and
/// the insertion point will be inside it. The result of the conditional
/// computation will be returned.
ManagedValue complete();
};
} // end namespace Lowering
} // end namespace swift
#endif
|