-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathCondition.h
146 lines (119 loc) · 5.31 KB
/
Condition.h
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
146
//===--- 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/Basic/Assertions.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