Skip to content

Commit 9370929

Browse files
authored
Merge pull request #40775 from gottesmm/move-function-defer
[move-function] Implement support for checking in defers
2 parents dd7aebf + 7c7b9ee commit 9370929

13 files changed

+1619
-68
lines changed

include/swift/Demangling/Demangle.h

+2
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ enum class FunctionSigSpecializationParamKind : unsigned {
108108
ClosureProp = 5,
109109
BoxToValue = 6,
110110
BoxToStack = 7,
111+
InOutToOut = 8,
111112

112113
// Option Set Flags use bits 6-31. This gives us 26 bits to use for option
113114
// flags.
@@ -144,6 +145,7 @@ enum class SpecializationPass : uint8_t {
144145
CapturePropagation,
145146
FunctionSignatureOpts,
146147
GenericSpecializer,
148+
MoveDiagnosticInOutToOut,
147149
};
148150

149151
static inline char encodeSpecializationPass(SpecializationPass Pass) {

include/swift/SIL/SILCloner.h

+31
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
128128
ArrayRef<SILValue> entryArgs,
129129
bool replaceOriginalFunctionInPlace = false);
130130

131+
/// The same as clone function body, except the caller can provide a callback
132+
/// that allows for an entry arg to be assigned to a custom old argument. This
133+
/// is useful if one re-arranges parameters when converting from inout to out.
134+
void
135+
cloneFunctionBody(SILFunction *F, SILBasicBlock *clonedEntryBB,
136+
ArrayRef<SILValue> entryArgs,
137+
llvm::function_ref<SILValue(SILValue)> entryArgToOldArgMap);
138+
131139
/// MARK: Callback utilities used from CRTP extensions during cloning.
132140
/// These should only be called from within an instruction cloning visitor.
133141

@@ -613,6 +621,29 @@ void SILCloner<ImplClass>::cloneFunctionBody(SILFunction *F,
613621
commonFixUp(F);
614622
}
615623

624+
template <typename ImplClass>
625+
void SILCloner<ImplClass>::cloneFunctionBody(
626+
SILFunction *F, SILBasicBlock *clonedEntryBB, ArrayRef<SILValue> entryArgs,
627+
llvm::function_ref<SILValue(SILValue)> entryArgIndexToOldArgIndex) {
628+
assert(F != clonedEntryBB->getParent() && "Must clone into a new function.");
629+
assert(BBMap.empty() && "This API does not allow clients to map blocks.");
630+
assert(ValueMap.empty() && "Stale ValueMap.");
631+
632+
assert(entryArgs.size() == F->getArguments().size());
633+
for (unsigned i = 0, e = entryArgs.size(); i != e; ++i) {
634+
ValueMap[entryArgIndexToOldArgIndex(entryArgs[i])] = entryArgs[i];
635+
}
636+
637+
BBMap.insert(std::make_pair(&*F->begin(), clonedEntryBB));
638+
639+
Builder.setInsertionPoint(clonedEntryBB);
640+
641+
// This will layout all newly cloned blocks immediate after clonedEntryBB.
642+
visitBlocksDepthFirst(&*F->begin());
643+
644+
commonFixUp(F);
645+
}
646+
616647
template<typename ImplClass>
617648
void SILCloner<ImplClass>::clonePhiArgs(SILBasicBlock *oldBB) {
618649
auto *mappedBB = BBMap[oldBB];

include/swift/SIL/SILFunction.h

+13
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,19 @@ class SILFunction
10561056
/// generic.
10571057
SubstitutionMap getForwardingSubstitutionMap();
10581058

1059+
/// Returns true if this SILFunction must be a defer statement.
1060+
///
1061+
/// NOTE: This may return false for defer statements that have been
1062+
/// deserialized without a DeclContext. This means that this is guaranteed to
1063+
/// be correct for SILFunctions in Raw SIL that were not deserialized as
1064+
/// canonical. Thus one can use it for diagnostics.
1065+
bool isDefer() const {
1066+
if (auto *dc = getDeclContext())
1067+
if (auto *decl = dyn_cast_or_null<FuncDecl>(dc->getAsDecl()))
1068+
return decl->isDeferBody();
1069+
return false;
1070+
}
1071+
10591072
//===--------------------------------------------------------------------===//
10601073
// Block List Access
10611074
//===--------------------------------------------------------------------===//

include/swift/SILOptimizer/Utils/SpecializationMangler.h

+17-12
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,24 @@ class FunctionSignatureSpecializationMangler : public SpecializationMangler {
6262
using ArgumentModifierIntBase = uint16_t;
6363
enum class ArgumentModifier : ArgumentModifierIntBase {
6464
// Option Space 4 bits (i.e. 16 options).
65-
Unmodified=0,
66-
ConstantProp=1,
67-
ClosureProp=2,
68-
BoxToValue=3,
69-
BoxToStack=4,
70-
First_Option=0, Last_Option=31,
65+
Unmodified = 0,
66+
ConstantProp = 1,
67+
ClosureProp = 2,
68+
BoxToValue = 3,
69+
BoxToStack = 4,
70+
InOutToOut = 5,
71+
72+
First_Option = 0,
73+
Last_Option = 31,
7174

7275
// Option Set Space. 12 bits (i.e. 12 option).
73-
Dead=32,
74-
OwnedToGuaranteed=64,
75-
SROA=128,
76-
GuaranteedToOwned=256,
77-
ExistentialToGeneric=512,
78-
First_OptionSetEntry=32, LastOptionSetEntry=32768,
76+
Dead = 32,
77+
OwnedToGuaranteed = 64,
78+
SROA = 128,
79+
GuaranteedToOwned = 256,
80+
ExistentialToGeneric = 512,
81+
First_OptionSetEntry = 32,
82+
LastOptionSetEntry = 32768,
7983
};
8084

8185
using ArgInfo = std::pair<ArgumentModifierIntBase,
@@ -102,6 +106,7 @@ class FunctionSignatureSpecializationMangler : public SpecializationMangler {
102106
void setArgumentSROA(unsigned OrigArgIdx);
103107
void setArgumentBoxToValue(unsigned OrigArgIdx);
104108
void setArgumentBoxToStack(unsigned OrigArgIdx);
109+
void setArgumentInOutToOut(unsigned OrigArgIdx);
105110
void setReturnValueOwnedToUnowned();
106111

107112
std::string mangle();

lib/Demangling/Demangler.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -2950,6 +2950,11 @@ NodePointer Demangler::demangleFuncSpecParam(Node::Kind Kind) {
29502950
return addChild(Param, createNode(
29512951
Node::Kind::FunctionSignatureSpecializationParamKind,
29522952
unsigned(FunctionSigSpecializationParamKind::BoxToStack)));
2953+
case 'r':
2954+
return addChild(
2955+
Param,
2956+
createNode(Node::Kind::FunctionSignatureSpecializationParamKind,
2957+
unsigned(FunctionSigSpecializationParamKind::InOutToOut)));
29532958
default:
29542959
return nullptr;
29552960
}

lib/Demangling/NodePrinter.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,7 @@ void NodePrinter::printFunctionSigSpecializationParams(NodePointer Node,
10171017
switch (K) {
10181018
case FunctionSigSpecializationParamKind::BoxToValue:
10191019
case FunctionSigSpecializationParamKind::BoxToStack:
1020+
case FunctionSigSpecializationParamKind::InOutToOut:
10201021
print(Node->getChild(Idx++), depth + 1);
10211022
break;
10221023
case FunctionSigSpecializationParamKind::ConstantPropFunction:
@@ -1587,6 +1588,9 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
15871588
case FunctionSigSpecializationParamKind::BoxToStack:
15881589
Printer << "Stack Promoted from Box";
15891590
return nullptr;
1591+
case FunctionSigSpecializationParamKind::InOutToOut:
1592+
Printer << "InOut Converted to Out";
1593+
return nullptr;
15901594
case FunctionSigSpecializationParamKind::ConstantPropFunction:
15911595
Printer << "Constant Propagated Function";
15921596
return nullptr;

lib/Demangling/OldDemangler.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,11 @@ class OldDemangler {
645645
if (!result)
646646
return nullptr;
647647
param->addChild(result, Factory);
648+
} else if (Mangled.nextIf("r_")) {
649+
auto result = FUNCSIGSPEC_CREATE_PARAM_KIND(InOutToOut);
650+
if (!result)
651+
return nullptr;
652+
param->addChild(result, Factory);
648653
} else {
649654
// Otherwise handle option sets.
650655
unsigned Value = 0;

lib/Demangling/Remangler.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,9 @@ Remangler::mangleFunctionSignatureSpecializationParam(Node *node,
14071407
case FunctionSigSpecializationParamKind::BoxToStack:
14081408
Buffer << 's';
14091409
break;
1410+
case FunctionSigSpecializationParamKind::InOutToOut:
1411+
Buffer << 'r';
1412+
break;
14101413
case FunctionSigSpecializationParamKind::SROA:
14111414
Buffer << 'x';
14121415
break;

0 commit comments

Comments
 (0)