@@ -38,19 +38,18 @@ evaluateAndCacheCall(SILFunction &fn, SubstitutionMap substitutionMap,
38
38
// general framework.
39
39
40
40
enum class WellKnownFunction {
41
- Unknown,
42
41
// String.init()
43
42
StringInitEmpty,
44
43
// String.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
45
44
StringMakeUTF8
46
45
};
47
46
48
- static WellKnownFunction classifyFunction (SILFunction *fn) {
47
+ static llvm::Optional< WellKnownFunction> classifyFunction (SILFunction *fn) {
49
48
if (fn->hasSemanticsAttr (" string.init_empty" ))
50
49
return WellKnownFunction::StringInitEmpty;
51
50
if (fn->hasSemanticsAttr (" string.makeUTF8" ))
52
51
return WellKnownFunction::StringMakeUTF8;
53
- return WellKnownFunction::Unknown ;
52
+ return None ;
54
53
}
55
54
56
55
// ===----------------------------------------------------------------------===//
@@ -131,6 +130,9 @@ class ConstExprFunctionState {
131
130
llvm::Optional<SymbolicValue> computeOpaqueCallResult (ApplyInst *apply,
132
131
SILFunction *callee);
133
132
133
+ llvm::Optional<SymbolicValue>
134
+ computeWellKnownCallResult (ApplyInst *apply, WellKnownFunction callee);
135
+
134
136
SymbolicValue getSingleWriterAddressValue (SILValue addr);
135
137
SymbolicValue getConstAddrAndLoadResult (SILValue addr);
136
138
SymbolicValue loadAddrValue (SILValue addr, SymbolicValue addrVal);
@@ -541,26 +543,15 @@ ConstExprFunctionState::computeOpaqueCallResult(ApplyInst *apply,
541
543
return evaluator.getUnknown ((SILInstruction *)apply, UnknownReason::Default);
542
544
}
543
545
544
- // / Given a call to a function, determine whether it is a call to a constexpr
545
- // / function . If so, collect its arguments as constants, fold it and return
546
- // / None. If not, mark the results as Unknown, and return an Unknown with
547
- // / information about the error.
546
+ // / Given a call to a well known function, collect its arguments as constants,
547
+ // / fold it, and return None . If any of the arguments are not constants, marks
548
+ // / the call's results as Unknown, and return an Unknown with information about
549
+ // / the error.
548
550
llvm::Optional<SymbolicValue>
549
- ConstExprFunctionState::computeCallResult (ApplyInst *apply) {
551
+ ConstExprFunctionState::computeWellKnownCallResult (ApplyInst *apply,
552
+ WellKnownFunction callee) {
550
553
auto conventions = apply->getSubstCalleeConv ();
551
-
552
- // Determine the callee.
553
- auto calleeFn = getConstantValue (apply->getOperand (0 ));
554
- if (calleeFn.getKind () != SymbolicValue::Function)
555
- return evaluator.getUnknown ((SILInstruction *)apply,
556
- UnknownReason::Default);
557
-
558
- SILFunction *callee = calleeFn.getFunctionValue ();
559
-
560
- // If this is a well-known function, do not step into it.
561
- switch (classifyFunction (callee)) {
562
- default :
563
- break ;
554
+ switch (callee) {
564
555
case WellKnownFunction::StringInitEmpty: { // String.init()
565
556
assert (conventions.getNumDirectSILResults () == 1 &&
566
557
conventions.getNumIndirectSILResults () == 0 &&
@@ -589,6 +580,28 @@ ConstExprFunctionState::computeCallResult(ApplyInst *apply) {
589
580
return None;
590
581
}
591
582
}
583
+ llvm_unreachable (" unhandled WellKnownFunction" );
584
+ }
585
+
586
+ // / Given a call to a function, determine whether it is a call to a constexpr
587
+ // / function. If so, collect its arguments as constants, fold it and return
588
+ // / None. If not, mark the results as Unknown, and return an Unknown with
589
+ // / information about the error.
590
+ llvm::Optional<SymbolicValue>
591
+ ConstExprFunctionState::computeCallResult (ApplyInst *apply) {
592
+ auto conventions = apply->getSubstCalleeConv ();
593
+
594
+ // Determine the callee.
595
+ auto calleeFn = getConstantValue (apply->getOperand (0 ));
596
+ if (calleeFn.getKind () != SymbolicValue::Function)
597
+ return evaluator.getUnknown ((SILInstruction *)apply,
598
+ UnknownReason::Default);
599
+
600
+ SILFunction *callee = calleeFn.getFunctionValue ();
601
+
602
+ // If this is a well-known function, do not step into it.
603
+ if (auto wellKnownFunction = classifyFunction (callee))
604
+ return computeWellKnownCallResult (apply, *wellKnownFunction);
592
605
593
606
// Verify that we can fold all of the arguments to the call.
594
607
SmallVector<SymbolicValue, 4 > paramConstants;
0 commit comments