Skip to content

Commit cc50cc8

Browse files
authored
Merge pull request #71945 from eeckstein/undef-parent-function
SwiftCompilerSources: support `Undef.parentFunction` and `PlaceholderValue.parentFunction`
2 parents 064c8c5 + 8137adf commit cc50cc8

File tree

10 files changed

+46
-23
lines changed

10 files changed

+46
-23
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/LifetimeDependenceUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ struct LifetimeDependence : CustomStringConvertible {
185185
var parentValue: Value { scope.parentValue }
186186

187187
var function: Function {
188-
dependentValue.parentFunction // dependentValue can't be undef
188+
dependentValue.parentFunction
189189
}
190190

191191
var description: String {

SwiftCompilerSources/Sources/Optimizer/Utilities/OptUtils.swift

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,6 @@ extension Value {
4747
/// check, because it treats a value_to_bridge_object instruction as "trivial".
4848
/// It can also handle non-trivial enums with trivial cases.
4949
func isTrivial(_ context: some Context) -> Bool {
50-
if self is Undef {
51-
return true
52-
}
5350
var worklist = ValueWorklist(context)
5451
defer { worklist.deinitialize() }
5552

@@ -64,12 +61,12 @@ extension Value {
6461
switch v {
6562
case is ValueToBridgeObjectInst:
6663
break
67-
case is StructInst, is TupleInst:
68-
let inst = (v as! SingleValueInstruction)
69-
worklist.pushIfNotVisited(contentsOf: inst.operands.values.filter { !($0 is Undef) })
64+
case let si as StructInst:
65+
worklist.pushIfNotVisited(contentsOf: si.operands.values)
66+
case let ti as TupleInst:
67+
worklist.pushIfNotVisited(contentsOf: ti.operands.values)
7068
case let en as EnumInst:
71-
if let payload = en.payload,
72-
!(payload is Undef) {
69+
if let payload = en.payload {
7370
worklist.pushIfNotVisited(payload)
7471
}
7572
default:

SwiftCompilerSources/Sources/SIL/Value.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ public protocol Value : AnyObject, CustomStringConvertible {
2525
var definingInstruction: Instruction? { get }
2626

2727
/// The block where the value is defined.
28-
///
29-
/// It's not legal to get the definingBlock of an `Undef` value.
3028
var parentBlock: BasicBlock { get }
3129

30+
/// The function where the value lives in.
31+
///
32+
/// It's not legal to get the parentFunction of an instruction in a global initializer.
33+
var parentFunction: Function { get }
34+
3235
/// True if the value has a trivial type.
3336
var hasTrivialType: Bool { get }
3437

@@ -113,6 +116,7 @@ extension Value {
113116

114117
public var uses: UseList { UseList(bridged.getFirstUse()) }
115118

119+
// Default implementation for all values which have a parent block, like instructions and arguments.
116120
public var parentFunction: Function { parentBlock.parentFunction }
117121

118122
public var type: Type { bridged.getType().type }
@@ -206,8 +210,11 @@ extension BridgedValue {
206210
public final class Undef : Value {
207211
public var definingInstruction: Instruction? { nil }
208212

213+
public var parentFunction: Function { bridged.SILUndef_getParentFunction().function }
214+
209215
public var parentBlock: BasicBlock {
210-
fatalError("undef has no defining block")
216+
// By convention, undefs are considered to be defined at the entry of the function.
217+
parentFunction.entryBlock
211218
}
212219

213220
/// Undef has not parent function, therefore the default `hasTrivialType` does not work.
@@ -221,9 +228,12 @@ public final class Undef : Value {
221228

222229
final class PlaceholderValue : Value {
223230
public var definingInstruction: Instruction? { nil }
231+
224232
public var parentBlock: BasicBlock {
225233
fatalError("PlaceholderValue has no defining block")
226234
}
235+
236+
public var parentFunction: Function { bridged.PlaceholderValue_getParentFunction().function }
227237
}
228238

229239
extension OptionalBridgedValue {

include/swift/SIL/SILBridging.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ struct BridgedValue {
414414
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE OptionalBridgedOperand getFirstUse() const;
415415
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedType getType() const;
416416
BRIDGED_INLINE Ownership getOwnership() const;
417+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedFunction SILUndef_getParentFunction() const;
418+
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedFunction PlaceholderValue_getParentFunction() const;
417419

418420
bool findPointerEscape() const;
419421
};

include/swift/SIL/SILBridgingImpl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,14 @@ BridgedValue::Ownership BridgedValue::getOwnership() const {
418418
return castOwnership(getSILValue()->getOwnershipKind());
419419
}
420420

421+
BridgedFunction BridgedValue::SILUndef_getParentFunction() const {
422+
return {llvm::cast<swift::SILUndef>(getSILValue())->getParent()};
423+
}
424+
425+
BridgedFunction BridgedValue::PlaceholderValue_getParentFunction() const {
426+
return {llvm::cast<swift::PlaceholderValue>(getSILValue())->getParent()};
427+
}
428+
421429
//===----------------------------------------------------------------------===//
422430
// BridgedOperand
423431
//===----------------------------------------------------------------------===//

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,9 +592,7 @@ SILCloner<ImplClass>::getMappedValue(SILValue Value) {
592592
// If we have undef, just remap the type.
593593
if (auto *U = dyn_cast<SILUndef>(Value)) {
594594
auto type = getOpType(U->getType());
595-
ValueBase *undef =
596-
(type == U->getType() ? U : SILUndef::get(Builder.getFunction(), type));
597-
return SILValue(undef);
595+
return SILUndef::get(Builder.getFunction(), type);
598596
}
599597

600598
llvm_unreachable("Unmapped value while cloning?");

lib/SIL/IR/SILValue.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ SILBasicBlock *SILNode::getParentBlock() const {
209209
if (auto *MVR = dyn_cast<MultipleValueInstructionResult>(this)) {
210210
return MVR->getParent()->getParent();
211211
}
212+
if (auto *undef = dyn_cast<SILUndef>(this)) {
213+
// By convention, undefs are considered to be defined at the entry of the function.
214+
return undef->getParent()->getEntryBlock();
215+
}
212216
return nullptr;
213217
}
214218

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
12631263
"instruction isn't dominated by its bb argument operand");
12641264
}
12651265

1266+
if (auto *undef = dyn_cast<SILUndef>(operand.get())) {
1267+
require(undef->getParent() == BB->getParent(), "SILUndef in wrong function");
1268+
}
1269+
12661270
require(operand.getUser() == I,
12671271
"instruction's operand's owner isn't the instruction");
12681272
require(isOperandInValueUses(&operand), "operand value isn't used by operand");

test/SILOptimizer/simplify_cfg_args.sil

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -745,14 +745,14 @@ enum ThreeWay {
745745

746746
// CHECK-LABEL: sil hidden [noinline] @testUnwrapEnumArg : $@convention(thin) () -> () {
747747
// CHECK: bb0:
748-
// CHECK: br bb1(undef : $Builtin.Int64, %{{.*}} : $Payload)
749-
// CHECK: bb1(%{{.*}} : $Builtin.Int64, %{{.*}} : $Payload):
748+
// CHECK: br bb1(%{{.*}} : $Payload)
749+
// CHECK: bb1(%{{.*}} : $Payload):
750750
// CHECK: alloc_stack $Payload
751751
// CHECK: switch_enum undef : $ThreeWay, case #ThreeWay.one!enumelt: bb4, case #ThreeWay.two!enumelt: bb2, case #ThreeWay.three!enumelt: bb3
752752
// CHECK: bb2:
753753
// CHECK: [[P2:%.*]] = load %{{.*}} : $*Payload
754754
// CHECK: dealloc_stack %{{.*}} : $*Payload
755-
// CHECK: br bb1(undef : $Builtin.Int64, [[P2]] : $Payload)
755+
// CHECK: br bb1([[P2]] : $Payload)
756756
// CHECK: bb3:
757757
// CHECK: [[P3:%.*]] = load %{{.*}} : $*Payload
758758
// CHECK: dealloc_stack %{{.*}} : $*Payload
@@ -764,7 +764,7 @@ enum ThreeWay {
764764
// CHECK: bb5:
765765
// CHECK: br bb7
766766
// CHECK: bb6:
767-
// CHECK: br bb1(undef : $Builtin.Int64, [[P4]] : $Payload)
767+
// CHECK: br bb1([[P4]] : $Payload)
768768
// CHECK: bb7:
769769
// CHECK: return %{{.*}} : $()
770770
// CHECK-LABEL: } // end sil function 'testUnwrapEnumArg'

test/SILOptimizer/simplify_cfg_args_ossa.sil

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -723,14 +723,14 @@ enum ThreeWay {
723723

724724
// CHECK-LABEL: sil hidden [noinline] [ossa] @testUnwrapEnumArg : $@convention(thin) () -> () {
725725
// CHECK: bb0:
726-
// CHECK: br bb1(undef : $Builtin.Int64, %{{.*}} : $Payload)
727-
// CHECK: bb1(%{{.*}} : $Builtin.Int64, %{{.*}} : $Payload):
726+
// CHECK: br bb1(%{{.*}} : $Payload)
727+
// CHECK: bb1(%{{.*}} : $Payload):
728728
// CHECK: alloc_stack $Payload
729729
// CHECK: switch_enum undef : $ThreeWay, case #ThreeWay.one!enumelt: bb4, case #ThreeWay.two!enumelt: bb2, case #ThreeWay.three!enumelt: bb3
730730
// CHECK: bb2:
731731
// CHECK: [[P2:%.*]] = load [trivial] %{{.*}} : $*Payload
732732
// CHECK: dealloc_stack %{{.*}} : $*Payload
733-
// CHECK: br bb1(undef : $Builtin.Int64, [[P2]] : $Payload)
733+
// CHECK: br bb1([[P2]] : $Payload)
734734
// CHECK: bb3:
735735
// CHECK: [[P3:%.*]] = load [trivial] %{{.*}} : $*Payload
736736
// CHECK: dealloc_stack %{{.*}} : $*Payload
@@ -740,7 +740,7 @@ enum ThreeWay {
740740
// CHECK: dealloc_stack %{{.*}} : $*Payload
741741
// CHECK: cond_br undef, bb6, bb5
742742
// CHECK: bb5:
743-
// CHECK: br bb1(undef : $Builtin.Int64, [[P4]] : $Payload)
743+
// CHECK: br bb1([[P4]] : $Payload)
744744
// CHECK: bb6:
745745
// CHECK: br bb7
746746
// CHECK: bb7:

0 commit comments

Comments
 (0)