From 5ad332f6cd42b59e7c9e0bdfc85b1e09961f52ed Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Tue, 19 Jan 2021 21:19:15 +0100 Subject: [PATCH 01/10] SILOptimizer: remove the unused findApplyFromDevirtualizedResult utility function --- include/swift/SILOptimizer/Utils/InstOptUtils.h | 2 -- lib/SILOptimizer/Utils/InstOptUtils.cpp | 14 -------------- 2 files changed, 16 deletions(-) diff --git a/include/swift/SILOptimizer/Utils/InstOptUtils.h b/include/swift/SILOptimizer/Utils/InstOptUtils.h index fadacc4fd6883..04d44e6f2de22 100644 --- a/include/swift/SILOptimizer/Utils/InstOptUtils.h +++ b/include/swift/SILOptimizer/Utils/InstOptUtils.h @@ -260,8 +260,6 @@ getConcreteValueOfExistentialBox(AllocExistentialBoxInst *existentialBox, SILValue getConcreteValueOfExistentialBoxAddr(SILValue addr, SILInstruction *ignoreUser); -FullApplySite findApplyFromDevirtualizedResult(SILValue value); - /// Cast a value into the expected, ABI compatible type if necessary. /// This may happen e.g. when: /// - a type of the return value is a subclass of the expected return type. diff --git a/lib/SILOptimizer/Utils/InstOptUtils.cpp b/lib/SILOptimizer/Utils/InstOptUtils.cpp index 0db1c49fe2892..63a66567a8574 100644 --- a/lib/SILOptimizer/Utils/InstOptUtils.cpp +++ b/lib/SILOptimizer/Utils/InstOptUtils.cpp @@ -810,20 +810,6 @@ getConcreteValueOfExistentialBoxAddr(SILValue addr, SILInstruction *ignoreUser) return getConcreteValueOfExistentialBox(box, singleStackStore); } -// Devirtualization of functions with covariant return types produces -// a result that is not an apply, but takes an apply as an -// argument. Attempt to dig the apply out from this result. -FullApplySite swift::findApplyFromDevirtualizedResult(SILValue v) { - if (auto Apply = FullApplySite::isa(v)) - return Apply; - - if (isa(v) || isa(v) || isa(v)) - return findApplyFromDevirtualizedResult( - cast(v)->getOperand(0)); - - return FullApplySite(); -} - bool swift::mayBindDynamicSelf(SILFunction *F) { if (!F->hasDynamicSelfMetadata()) return false; From 65ecb697c64116b13e4835ea0c0ab259af52f2b6 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 08:54:30 +0100 Subject: [PATCH 02/10] SIL: improve the API for ApplySite construction Replace the `isa(SILNode *)` with `isa(SILInstruction *)` and `isa(SILValue)`. This is much clearer and it also works if the SILValue is a MultiValueInstructionResult of an apply instruction. Also, use `isa` instead of `classof` in canOptimize() --- include/swift/SIL/ApplySite.h | 45 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index d9e1cee676464..48d80aa00cffd 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -90,28 +90,30 @@ class ApplySite { SILModule &getModule() const { return Inst->getModule(); } - static ApplySite isa(SILNode *node) { - auto *i = dyn_cast(node); - if (!i) - return ApplySite(); - - auto kind = ApplySiteKind::fromNodeKind(i->getKind()); + static ApplySite isa(SILInstruction *inst) { + auto kind = ApplySiteKind::fromNodeKind(inst->getKind()); if (!kind) return ApplySite(); switch (kind.getValue()) { case ApplySiteKind::ApplyInst: - return ApplySite(cast(node)); + return ApplySite(cast(inst)); case ApplySiteKind::BeginApplyInst: - return ApplySite(cast(node)); + return ApplySite(cast(inst)); case ApplySiteKind::TryApplyInst: - return ApplySite(cast(node)); + return ApplySite(cast(inst)); case ApplySiteKind::PartialApplyInst: - return ApplySite(cast(node)); + return ApplySite(cast(inst)); } llvm_unreachable("covered switch"); } + static ApplySite isa(SILValue value) { + if (auto *inst = value->getDefiningInstruction()) + return ApplySite::isa(inst); + return ApplySite(); + } + ApplySiteKind getKind() const { return ApplySiteKind(Inst->getKind()); } explicit operator bool() const { return Inst != nullptr; } @@ -181,8 +183,8 @@ class ApplySite { /// Calls to (previous_)dynamic_function_ref have a dynamic target function so /// we should not optimize them. bool canOptimize() const { - return !DynamicFunctionRefInst::classof(getCallee()) && - !PreviousDynamicFunctionRefInst::classof(getCallee()); + return !swift::isa(getCallee()) && + !swift::isa(getCallee()); } /// Return the type. @@ -493,24 +495,27 @@ class FullApplySite : public ApplySite { FullApplySite(BeginApplyInst *inst) : ApplySite(inst) {} FullApplySite(TryApplyInst *inst) : ApplySite(inst) {} - static FullApplySite isa(SILNode *node) { - auto *i = dyn_cast(node); - if (!i) - return FullApplySite(); - auto kind = FullApplySiteKind::fromNodeKind(i->getKind()); + static FullApplySite isa(SILInstruction *inst) { + auto kind = FullApplySiteKind::fromNodeKind(inst->getKind()); if (!kind) return FullApplySite(); switch (kind.getValue()) { case FullApplySiteKind::ApplyInst: - return FullApplySite(cast(node)); + return FullApplySite(cast(inst)); case FullApplySiteKind::BeginApplyInst: - return FullApplySite(cast(node)); + return FullApplySite(cast(inst)); case FullApplySiteKind::TryApplyInst: - return FullApplySite(cast(node)); + return FullApplySite(cast(inst)); } llvm_unreachable("covered switch"); } + static FullApplySite isa(SILValue value) { + if (auto *inst = value->getDefiningInstruction()) + return FullApplySite::isa(inst); + return FullApplySite(); + } + FullApplySiteKind getKind() const { return FullApplySiteKind(getInstruction()->getKind()); } From baab92345c3ab0ade4ede9e0d9b03438813635bb Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 09:12:52 +0100 Subject: [PATCH 03/10] DeadCodeElimination: a small cleanup Split `markValueLive(SILNode *)` into `markValueLive(SILValue)` and `markInstructionLive(SILInstruction*)` --- .../Transforms/DeadCodeElimination.cpp | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp index e6f034ae0b4c9..7429a73e626ee 100644 --- a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp +++ b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp @@ -188,7 +188,8 @@ class DCE : public SILFunctionTransform { void computeMinPredecessorLevels(PostDomTreeNode *root); void insertControllingInfo(SILBasicBlock *Block, unsigned Level); - void markValueLive(SILNode *V); + void markValueLive(SILValue V); + void markInstructionLive(SILInstruction *Inst); void markTerminatorArgsLive(SILBasicBlock *Pred, SILBasicBlock *Succ, size_t ArgIndex); void markControllingTerminatorsLive(SILBasicBlock *Block); @@ -208,32 +209,30 @@ class DCE : public SILFunctionTransform { // Keep track of the fact that V is live and add it to our worklist // so that we can process the values it depends on. -void DCE::markValueLive(SILNode *V) { - V = V->getRepresentativeSILNodeInObject(); - if (LiveValues.count(V) || isa(V)) - return; - - LLVM_DEBUG(llvm::dbgs() << "Marking as live:\n"); - LLVM_DEBUG(V->dump()); - - LiveValues.insert(V); +void DCE::markValueLive(SILValue V) { + if (SILInstruction *inst = V->getDefiningInstruction()) + return markInstructionLive(inst); - if (auto *Def = dyn_cast(V)) { - markControllingTerminatorsLive(Def->getParent()); - Worklist.push_back(Def); + if (!LiveValues.insert(V).second || isa(V)) return; - } - - // TODO: MultiValueInstruction - assert(isa(V) && - "Only expected instructions and arguments!"); + LLVM_DEBUG(llvm::dbgs() << "Marking as live: " << *V); auto *Arg = cast(V); markControllingTerminatorsLive(Arg->getParent()); propagateLiveBlockArgument(Arg); } +void DCE::markInstructionLive(SILInstruction *Inst) { + if (!LiveValues.insert(Inst).second) + return; + + LLVM_DEBUG(llvm::dbgs() << "Marking as live: " << *Inst); + + markControllingTerminatorsLive(Inst->getParent()); + Worklist.push_back(Inst); +} + /// Gets the producing instruction of a cond_fail condition. Currently these /// are overflow builtins but may be extended to other instructions in the /// future. @@ -263,7 +262,7 @@ void DCE::markLive(SILFunction &F) { if (auto *Prod = getProducer(cast(&I))) { addReverseDependency(Prod, &I); } else { - markValueLive(&I); + markInstructionLive(&I); } break; } @@ -272,7 +271,7 @@ void DCE::markLive(SILFunction &F) { if (!Op->getType().isAddress()) { addReverseDependency(Op, &I); } else { - markValueLive(&I); + markInstructionLive(&I); } break; } @@ -290,7 +289,7 @@ void DCE::markLive(SILFunction &F) { } default: if (seemsUseful(&I)) - markValueLive(&I); + markInstructionLive(&I); } } } @@ -319,7 +318,7 @@ void DCE::markTerminatorArgsLive(SILBasicBlock *Pred, // If the arguments are live, we need to keep the terminator that // delivers those arguments. - markValueLive(Term); + markInstructionLive(Term); switch (Term->getTermKind()) { case TermKind::ReturnInst: @@ -380,11 +379,11 @@ void DCE::propagateLiveBlockArgument(SILArgument *Arg) { // is in reverse direction: Only if its definition (the Arg) is alive, also // the debug_value instruction is alive. for (Operand *DU : getDebugUses(Arg)) - markValueLive(DU->getUser()); + markInstructionLive(DU->getUser()); // Mark all reverse dependencies on the Arg live for (auto *depInst : ReverseDependencies.lookup(Arg)) { - markValueLive(depInst); + markInstructionLive(depInst); } auto *Block = Arg->getParent(); @@ -406,14 +405,14 @@ void DCE::propagateLiveness(SILInstruction *I) { // debug_value instruction is alive. for (auto result : I->getResults()) for (Operand *DU : getDebugUses(result)) - markValueLive(DU->getUser()); + markInstructionLive(DU->getUser()); // Handle all other reverse-dependency instructions, like cond_fail, // fix_lifetime, destroy_value, etc. Only if the definition is alive, the // user itself is alive. for (auto res : I->getResults()) { for (auto *depInst : ReverseDependencies.lookup(res)) { - markValueLive(depInst); + markInstructionLive(depInst); } } return; @@ -802,7 +801,7 @@ void DCE::markControllingTerminatorsLive(SILBasicBlock *Block) { collectControllingBlocks(Block, ControllingBlocks); for (auto BB : ControllingBlocks) - markValueLive(BB->getTerminator()); + markInstructionLive(BB->getTerminator()); } } // end anonymous namespace From ee599d84d21eac54f2cbe0cea94b618326002ee8 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 09:35:52 +0100 Subject: [PATCH 04/10] DiagnoseInfiniteRecursion: correctly handle multi-result instructions when checking for invariant arguments. Use `getDefiningInstruction` instead of casting a a SILValue to SingleValueInstruction. --- .../Mandatory/DiagnoseInfiniteRecursion.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp b/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp index 17cb413096987..3a6f7ad4b8d38 100644 --- a/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp +++ b/lib/SILOptimizer/Mandatory/DiagnoseInfiniteRecursion.cpp @@ -158,15 +158,13 @@ class Invariants { /// Recursively walks the use-def chain starting at \p value and returns /// true if all visited values are invariant. bool isInvariantValue(SILValue value, - SmallPtrSetImpl &visited) const { - SILNode *node = value->getRepresentativeSILNodeInObject(); + SmallPtrSetImpl &visited) const { + if (SILInstruction *inst = value->getDefiningInstruction()) { + // Avoid exponential complexity in case a value is used by multiple + // operands. + if (!visited.insert(inst).second) + return true; - // Avoid exponential complexity in case a value is used by multiple - // operands. - if (!visited.insert(node).second) - return true; - - if (auto *inst = dyn_cast(node)) { if (!isMemoryInvariant() && inst->mayReadFromMemory()) return false; @@ -228,7 +226,7 @@ class Invariants { case TermKind::SwitchEnumInst: case TermKind::CheckedCastBranchInst: case TermKind::CheckedCastValueBranchInst: { - SmallPtrSet visited; + SmallPtrSet visited; return isInvariantValue(term->getOperand(0), visited); } default: From ea72895024248ce317fa6fca4eadca147eab3565 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 09:42:14 +0100 Subject: [PATCH 05/10] EscapeAnalysis: change the parameter of isNonWritableMemoryAddress from SILNode* to SILValue A small cleanup, NFC. --- lib/SILOptimizer/Analysis/EscapeAnalysis.cpp | 42 ++++++++++---------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp index 1f36e4d6156fa..ba1c236e900b2 100644 --- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp @@ -207,20 +207,20 @@ SILValue EscapeAnalysis::getPointerRoot(SILValue value) { return value; } -static bool isNonWritableMemoryAddress(SILNode *V) { +static bool isNonWritableMemoryAddress(SILValue V) { switch (V->getKind()) { - case SILNodeKind::FunctionRefInst: - case SILNodeKind::DynamicFunctionRefInst: - case SILNodeKind::PreviousDynamicFunctionRefInst: - case SILNodeKind::WitnessMethodInst: - case SILNodeKind::ClassMethodInst: - case SILNodeKind::SuperMethodInst: - case SILNodeKind::ObjCMethodInst: - case SILNodeKind::ObjCSuperMethodInst: - case SILNodeKind::StringLiteralInst: - case SILNodeKind::ThinToThickFunctionInst: - case SILNodeKind::ThinFunctionToPointerInst: - case SILNodeKind::PointerToThinFunctionInst: + case ValueKind::FunctionRefInst: + case ValueKind::DynamicFunctionRefInst: + case ValueKind::PreviousDynamicFunctionRefInst: + case ValueKind::WitnessMethodInst: + case ValueKind::ClassMethodInst: + case ValueKind::SuperMethodInst: + case ValueKind::ObjCMethodInst: + case ValueKind::ObjCSuperMethodInst: + case ValueKind::StringLiteralInst: + case ValueKind::ThinToThickFunctionInst: + case ValueKind::ThinFunctionToPointerInst: + case ValueKind::PointerToThinFunctionInst: // These instructions return pointers to memory which can't be a // destination of a store. return true; @@ -1622,8 +1622,10 @@ void EscapeAnalysis::ConnectionGraph::verify() const { ReachableBlocks reachable(F); reachable.visit([this](SILBasicBlock *bb) { for (auto &i : *bb) { - if (isNonWritableMemoryAddress(&i)) - continue; + if (auto *svi = dyn_cast(&i)) { + if (isNonWritableMemoryAddress(svi)) + continue; + } if (auto ai = dyn_cast(&i)) { if (EA->canOptimizeArrayUninitializedCall(ai).isValid()) @@ -2060,17 +2062,17 @@ void EscapeAnalysis::analyzeInstruction(SILInstruction *I, if (auto *SVI = dyn_cast(I)) { if (getPointerBase(SVI)) return; + + // Instructions which return the address of non-writable memory cannot have + // an effect on escaping. + if (isNonWritableMemoryAddress(SVI)) + return; } // Incidental uses produce no values and have no effect on their operands. if (isIncidentalUse(I)) return; - // Instructions which return the address of non-writable memory cannot have - // an effect on escaping. - if (isNonWritableMemoryAddress(I)) - return; - switch (I->getKind()) { case SILInstructionKind::AllocStackInst: case SILInstructionKind::AllocRefInst: From f812a2a775dcb111dc0d7347e1645fbc0a4a70a0 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 09:47:15 +0100 Subject: [PATCH 06/10] OwnershipUtils: check for SILInstructionKind instead of SILNodeKind This resolves a FIXME. Also, use `getDefiningInstruction()` instead of `getRepresentativeSILNodeInObject()` NFC --- lib/SIL/Utils/OwnershipUtils.cpp | 96 ++++++++++++++++---------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/lib/SIL/Utils/OwnershipUtils.cpp b/lib/SIL/Utils/OwnershipUtils.cpp index d18b47bdd3345..70845d2eda8b6 100644 --- a/lib/SIL/Utils/OwnershipUtils.cpp +++ b/lib/SIL/Utils/OwnershipUtils.cpp @@ -26,31 +26,29 @@ bool swift::isValueAddressOrTrivial(SILValue v) { } // These operations forward both owned and guaranteed ownership. -// -// FIXME: Should be implemented as a SILInstruction type check-cast. -static bool isOwnershipForwardingValueKind(SILNodeKind kind) { +static bool isOwnershipForwardingInstructionKind(SILInstructionKind kind) { switch (kind) { - case SILNodeKind::TupleInst: - case SILNodeKind::StructInst: - case SILNodeKind::EnumInst: - case SILNodeKind::DifferentiableFunctionInst: - case SILNodeKind::LinearFunctionInst: - case SILNodeKind::OpenExistentialRefInst: - case SILNodeKind::UpcastInst: - case SILNodeKind::UncheckedValueCastInst: - case SILNodeKind::UncheckedRefCastInst: - case SILNodeKind::ConvertFunctionInst: - case SILNodeKind::RefToBridgeObjectInst: - case SILNodeKind::BridgeObjectToRefInst: - case SILNodeKind::UnconditionalCheckedCastInst: - case SILNodeKind::UncheckedEnumDataInst: - case SILNodeKind::SelectEnumInst: - case SILNodeKind::SwitchEnumInst: - case SILNodeKind::CheckedCastBranchInst: - case SILNodeKind::DestructureStructInst: - case SILNodeKind::DestructureTupleInst: - case SILNodeKind::MarkDependenceInst: - case SILNodeKind::InitExistentialRefInst: + case SILInstructionKind::TupleInst: + case SILInstructionKind::StructInst: + case SILInstructionKind::EnumInst: + case SILInstructionKind::DifferentiableFunctionInst: + case SILInstructionKind::LinearFunctionInst: + case SILInstructionKind::OpenExistentialRefInst: + case SILInstructionKind::UpcastInst: + case SILInstructionKind::UncheckedValueCastInst: + case SILInstructionKind::UncheckedRefCastInst: + case SILInstructionKind::ConvertFunctionInst: + case SILInstructionKind::RefToBridgeObjectInst: + case SILInstructionKind::BridgeObjectToRefInst: + case SILInstructionKind::UnconditionalCheckedCastInst: + case SILInstructionKind::UncheckedEnumDataInst: + case SILInstructionKind::SelectEnumInst: + case SILInstructionKind::SwitchEnumInst: + case SILInstructionKind::CheckedCastBranchInst: + case SILInstructionKind::DestructureStructInst: + case SILInstructionKind::DestructureTupleInst: + case SILInstructionKind::MarkDependenceInst: + case SILInstructionKind::InitExistentialRefInst: return true; default: return false; @@ -59,17 +57,17 @@ static bool isOwnershipForwardingValueKind(SILNodeKind kind) { // These operations forward guaranteed ownership, but don't necessarily forward // owned values. -static bool isGuaranteedForwardingValueKind(SILNodeKind kind) { +static bool isGuaranteedForwardingInstructionKind(SILInstructionKind kind) { switch (kind) { - case SILNodeKind::TupleExtractInst: - case SILNodeKind::StructExtractInst: - case SILNodeKind::DifferentiableFunctionExtractInst: - case SILNodeKind::LinearFunctionExtractInst: - case SILNodeKind::OpenExistentialValueInst: - case SILNodeKind::OpenExistentialBoxValueInst: + case SILInstructionKind::TupleExtractInst: + case SILInstructionKind::StructExtractInst: + case SILInstructionKind::DifferentiableFunctionExtractInst: + case SILInstructionKind::LinearFunctionExtractInst: + case SILInstructionKind::OpenExistentialValueInst: + case SILInstructionKind::OpenExistentialBoxValueInst: return true; default: - return isOwnershipForwardingValueKind(kind); + return isOwnershipForwardingInstructionKind(kind); } } @@ -83,19 +81,21 @@ bool swift::canOpcodeForwardGuaranteedValues(SILValue value) { return true; } - auto *node = value->getRepresentativeSILNodeInObject(); - bool result = isGuaranteedForwardingValueKind(node->getKind()); + auto *inst = value->getDefiningInstruction(); + if (!inst) + return false; + + bool result = isGuaranteedForwardingInstructionKind(inst->getKind()); if (result) { - assert(!isa(node)); - assert(OwnershipForwardingMixin::isa(node)); + assert(!isa(inst)); + assert(OwnershipForwardingMixin::isa(inst)); } return result; } bool swift::canOpcodeForwardGuaranteedValues(Operand *use) { auto *user = use->getUser(); - auto kind = user->getKind(); - bool result = isOwnershipForwardingValueKind(SILNodeKind(kind)); + bool result = isOwnershipForwardingInstructionKind(user->getKind()); if (result) { assert(!isa(user)); assert(OwnershipForwardingMixin::isa(user)); @@ -103,12 +103,12 @@ bool swift::canOpcodeForwardGuaranteedValues(Operand *use) { return result; } -static bool isOwnedForwardingValueKind(SILNodeKind kind) { +static bool isOwnedForwardingValueKind(SILInstructionKind kind) { switch (kind) { - case SILNodeKind::MarkUninitializedInst: + case SILInstructionKind::MarkUninitializedInst: return true; default: - return isOwnershipForwardingValueKind(kind); + return isOwnershipForwardingInstructionKind(kind); } } @@ -121,19 +121,21 @@ bool swift::canOpcodeForwardOwnedValues(SILValue value) { assert(OwnershipForwardingMixin::isa(predTerm)); return true; } - auto *node = value->getRepresentativeSILNodeInObject(); - bool result = isOwnedForwardingValueKind(node->getKind()); + auto *inst = value->getDefiningInstruction(); + if (!inst) + return false; + + bool result = isOwnedForwardingValueKind(inst->getKind()); if (result) { - assert(!isa(node)); - assert(OwnershipForwardingMixin::isa(node)); + assert(!isa(inst)); + assert(OwnershipForwardingMixin::isa(inst)); } return result; } bool swift::canOpcodeForwardOwnedValues(Operand *use) { auto *user = use->getUser(); - auto kind = SILNodeKind(user->getKind()); - bool result = isOwnershipForwardingValueKind(kind); + bool result = isOwnershipForwardingInstructionKind(user->getKind()); if (result) { assert(OwnershipForwardingMixin::isa(user)); } From 5dab47c310a0ad1365f99ddafdeba79df6413b40 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 09:51:46 +0100 Subject: [PATCH 07/10] SILPrinter: split printUsersOfSILNode into printUsersOfValue and printUsersOfInstruction. A small cleanup, NFC. --- lib/SIL/IR/SILPrinter.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index c60e5f98cccbd..4e55a9be97d8f 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -761,17 +761,18 @@ class SILPrinter : public SILInstructionVisitor { /// Print out the users of the SILValue \p V. Return true if we printed out /// either an id or a use list. Return false otherwise. - bool printUsersOfSILNode(const SILNode *node, bool printedSlashes) { + bool printUsersOfValue(SILValue value, bool printedSlashes) { + return printUserList({value}, value, printedSlashes); + } + + bool printUsersOfInstruction(const SILInstruction *inst, bool printedSlashes) { llvm::SmallVector values; - if (auto *value = dyn_cast(node)) { - values.push_back(value); - } else if (auto *inst = dyn_cast(node)) { - assert(!isa(inst) && "SingleValueInstruction was " - "handled by the previous " - "value base check."); - llvm::copy(inst->getResults(), std::back_inserter(values)); - } + llvm::copy(inst->getResults(), std::back_inserter(values)); + return printUserList(values, inst, printedSlashes); + } + bool printUserList(ArrayRef values, const SILNode *node, + bool printedSlashes) { // If the set of values is empty, we need to print the ID of // the instruction. Otherwise, if none of the values has a use, // we don't need to do anything. @@ -1011,7 +1012,7 @@ class SILPrinter : public SILInstructionVisitor { printedSlashes = printTypeDependentOperands(I); // Print users, or id for valueless instructions. - printedSlashes = printUsersOfSILNode(I, printedSlashes); + printedSlashes = printUsersOfInstruction(I, printedSlashes); // Print SIL location. if (Ctx.printVerbose()) { @@ -1056,7 +1057,7 @@ class SILPrinter : public SILInstructionVisitor { << Ctx.getID(arg->getParent()) << " : " << arg->getType(); // Print users. - (void) printUsersOfSILNode(arg, false); + (void) printUsersOfValue(arg, false); *this << '\n'; } @@ -1093,7 +1094,7 @@ class SILPrinter : public SILInstructionVisitor { visit(static_cast(nonConstParent)); // Print users. - (void)printUsersOfSILNode(result, false); + (void)printUsersOfValue(result, false); *this << '\n'; } From e4f2bbfb0b5410d86091a66d8ddbf96aa360d6d1 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 10:02:47 +0100 Subject: [PATCH 08/10] SILDynamicCastInst: replace `getAs(SILNode *)` with `getAs(SILInstruction *)` A small cleanup, NFC --- include/swift/SIL/DynamicCasts.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/include/swift/SIL/DynamicCasts.h b/include/swift/SIL/DynamicCasts.h index 2f08945b77bc9..0d4e6bf642dc8 100644 --- a/include/swift/SIL/DynamicCasts.h +++ b/include/swift/SIL/DynamicCasts.h @@ -158,17 +158,14 @@ struct SILDynamicCastInst { SILDynamicCastInst(ID *i) : inst(i) {} #include "swift/SIL/SILNodes.def" - static SILDynamicCastInst getAs(SILNode *node) { - auto *i = dyn_cast(node); - if (!i) - return SILDynamicCastInst(); - auto kind = SILDynamicCastKind::fromNodeKind(i->getKind()); + static SILDynamicCastInst getAs(SILInstruction *inst) { + auto kind = SILDynamicCastKind::fromNodeKind(inst->getKind()); if (!kind) return SILDynamicCastInst(); switch (kind.getValue()) { #define DYNAMICCAST_INST(ID, PARENT) \ case SILDynamicCastKind::ID: \ - return SILDynamicCastInst(cast(node)); + return SILDynamicCastInst(cast(inst)); #include "swift/SIL/SILNodes.def" } } From 40f0980abf018156bdfbba8f534966503c1c551b Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 10:26:16 +0100 Subject: [PATCH 09/10] SIL: simplify the SILNode getParent functions. A small cleanup, NFC. --- include/swift/SIL/SILInstruction.h | 3 +-- lib/SIL/IR/SILValue.cpp | 25 +++++++++---------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index 0191ee733dd1e..a8dc15f95d63b 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -405,8 +405,7 @@ class SILInstruction return SILInstructionKind(SILNode::getKind()); } - const SILBasicBlock *getParent() const { return ParentBB; } - SILBasicBlock *getParent() { return ParentBB; } + SILBasicBlock *getParent() const { return ParentBB; } SILFunction *getFunction(); const SILFunction *getFunction() const; diff --git a/lib/SIL/IR/SILValue.cpp b/lib/SIL/IR/SILValue.cpp index 46e8247b99e1b..2ca8d4c7b6dc0 100644 --- a/lib/SIL/IR/SILValue.cpp +++ b/lib/SIL/IR/SILValue.cpp @@ -99,32 +99,25 @@ ValueBase::getDefiningInstructionResult() { } SILBasicBlock *SILNode::getParentBlock() const { - auto *CanonicalNode = - const_cast(this)->getRepresentativeSILNodeInObject(); - if (auto *Inst = dyn_cast(CanonicalNode)) + if (auto *Inst = dyn_cast(this)) return Inst->getParent(); - if (auto *Arg = dyn_cast(CanonicalNode)) + if (auto *Arg = dyn_cast(this)) return Arg->getParent(); + if (auto *MVR = dyn_cast(this)) { + return MVR->getParent()->getParent(); + } return nullptr; } SILFunction *SILNode::getFunction() const { - auto *CanonicalNode = - const_cast(this)->getRepresentativeSILNodeInObject(); - if (auto *Inst = dyn_cast(CanonicalNode)) - return Inst->getFunction(); - if (auto *Arg = dyn_cast(CanonicalNode)) - return Arg->getFunction(); + if (auto *parentBlock = getParentBlock()) + return parentBlock->getParent(); return nullptr; } SILModule *SILNode::getModule() const { - auto *CanonicalNode = - const_cast(this)->getRepresentativeSILNodeInObject(); - if (auto *Inst = dyn_cast(CanonicalNode)) - return &Inst->getModule(); - if (auto *Arg = dyn_cast(CanonicalNode)) - return &Arg->getModule(); + if (SILFunction *func = getFunction()) + return &func->getModule(); return nullptr; } From ff1991740a8587c16e764226b1e1e55fef07eb51 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Wed, 20 Jan 2021 11:09:50 +0100 Subject: [PATCH 10/10] SIL: let SingleValueInstruction only inherit from a single SILNode. This removes the ambiguity when casting from a SingleValueInstruction to SILNode, which makes the code simpler. E.g. the "isRepresentativeSILNode" logic is not needed anymore. Also, it reduces the size of the most used instruction class - SingleValueInstruction - by one pointer. Conceptually, SILInstruction is still a SILNode. But implementation-wise SILNode is not a base class of SILInstruction anymore. Only the two sub-classes of SILInstruction - SingleValueInstruction and NonSingleValueInstruction - inherit from SILNode. SingleValueInstruction's SILNode is embedded into a ValueBase and its relative offset in the class is the same as in NonSingleValueInstruction (see SILNodeOffsetChecker). This makes it possible to cast from a SILInstruction to a SILNode without knowing which SILInstruction sub-class it is. Casting to SILNode cannot be done implicitly, but only with an LLVM `cast` or with SILInstruction::asSILNode(). But this is a rare case anyway. --- include/swift/SIL/PrettyStackTrace.h | 4 +- include/swift/SIL/SILArgument.h | 8 +- include/swift/SIL/SILInstruction.h | 528 ++++++++++-------- include/swift/SIL/SILNode.h | 205 +++---- include/swift/SIL/SILNodes.def | 1 + include/swift/SIL/SILPrintContext.h | 2 +- include/swift/SIL/SILUndef.h | 2 +- include/swift/SIL/SILValue.h | 14 +- .../SILOptimizer/Analysis/AliasAnalysis.h | 2 +- .../SILOptimizer/Utils/LoadStoreOptUtils.h | 2 +- include/swift/SILOptimizer/Utils/SCCVisitor.h | 10 +- lib/SIL/IR/SILArgument.cpp | 2 +- lib/SIL/IR/SILBasicBlock.cpp | 2 +- lib/SIL/IR/SILFunction.cpp | 4 +- lib/SIL/IR/SILInstruction.cpp | 9 +- lib/SIL/IR/SILInstructions.cpp | 46 +- lib/SIL/IR/SILPrinter.cpp | 12 +- lib/SIL/IR/SILUndef.cpp | 2 +- lib/SIL/IR/SILValue.cpp | 17 - lib/SILOptimizer/ARC/ARCRegionState.cpp | 4 +- .../ARC/GlobalARCSequenceDataflow.cpp | 4 +- lib/SILOptimizer/ARC/RCStateTransition.cpp | 4 +- lib/SILOptimizer/ARC/RCStateTransition.h | 4 +- lib/SILOptimizer/ARC/RefCountState.cpp | 4 +- lib/SILOptimizer/Analysis/AliasAnalysis.cpp | 2 - lib/SILOptimizer/Analysis/EscapeAnalysis.cpp | 4 +- lib/SILOptimizer/Analysis/IVAnalysis.cpp | 3 +- .../Mandatory/Differentiation.cpp | 5 +- lib/SILOptimizer/PassManager/PassManager.cpp | 2 +- .../Transforms/DeadCodeElimination.cpp | 8 +- lib/SILOptimizer/Transforms/SILMem2Reg.cpp | 2 +- lib/SILOptimizer/Utils/ConstExpr.cpp | 65 +-- lib/SILOptimizer/Utils/LoadStoreOptUtils.cpp | 2 +- 33 files changed, 479 insertions(+), 506 deletions(-) diff --git a/include/swift/SIL/PrettyStackTrace.h b/include/swift/SIL/PrettyStackTrace.h index 1b35d3ebf3c7f..acfff4e3ef2af 100644 --- a/include/swift/SIL/PrettyStackTrace.h +++ b/include/swift/SIL/PrettyStackTrace.h @@ -19,12 +19,12 @@ #define SWIFT_SIL_PRETTYSTACKTRACE_H #include "swift/SIL/SILLocation.h" +#include "swift/SIL/SILNode.h" #include "llvm/Support/PrettyStackTrace.h" namespace swift { class ASTContext; class SILFunction; -class SILNode; void printSILLocationDescription(llvm::raw_ostream &out, SILLocation loc, ASTContext &ctx); @@ -74,7 +74,7 @@ class PrettyStackTraceSILNode : public llvm::PrettyStackTraceEntry { const char *Action; public: - PrettyStackTraceSILNode(const char *action, const SILNode *node) + PrettyStackTraceSILNode(const char *action, SILNodePointer node) : Node(node), Action(action) {} virtual void print(llvm::raw_ostream &OS) const override; diff --git a/include/swift/SIL/SILArgument.h b/include/swift/SIL/SILArgument.h index e21f7e6eb9f26..debe9aee198b9 100644 --- a/include/swift/SIL/SILArgument.h +++ b/include/swift/SIL/SILArgument.h @@ -78,7 +78,7 @@ class SILArgument : public ValueBase { explicit SILArgument(ValueKind subClassKind, SILType type, ValueOwnershipKind ownershipKind, const ValueDecl *inputDecl = nullptr) - : ValueBase(subClassKind, type, IsRepresentative::Yes), + : ValueBase(subClassKind, type), parentBlock(nullptr), decl(inputDecl) { Bits.SILArgument.VOKind = static_cast(ownershipKind); } @@ -106,7 +106,7 @@ class SILArgument : public ValueBase { static bool classof(const SILInstruction *) = delete; static bool classof(const SILUndef *) = delete; - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() >= SILNodeKind::First_SILArgument && node->getKind() <= SILNodeKind::Last_SILArgument; } @@ -279,7 +279,7 @@ class SILPhiArgument : public SILArgument { static bool classof(const SILInstruction *) = delete; static bool classof(const SILUndef *) = delete; - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind::SILPhiArgument; } }; @@ -322,7 +322,7 @@ class SILFunctionArgument : public SILArgument { static bool classof(const SILInstruction *) = delete; static bool classof(const SILUndef *) = delete; - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind::SILFunctionArgument; } }; diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index a8dc15f95d63b..88e297836be94 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -306,8 +306,17 @@ SILInstructionResultArray::getReversedValues() const { /// not captured by the formal operands; currently, these dependencies /// only arise due to certain instructions (e.g. open_existential_addr) /// that bind new archetypes in the local context. -class SILInstruction - : public SILNode, public llvm::ilist_node { +/// +/// Conceptually, SILInstruction is a sub-class of SILNode. But implementation- +/// wise, only the two sub-classes of SILInstruction - SingleValueInstruction +/// and NonSingleValueInstruction - inherit from SILNode. Although the +/// SingleValueInstruction's SILNode is embedded into a ValueBase, its relative +/// offset in the class is the same as in NonSingleValueInstruction (see +/// SILNodeOffsetChecker). This makes it possible to cast from a SILInstruction +/// to a SILNode without knowing which SILInstruction sub-class it is. +/// Note that casting a SILInstruction to a SILNode cannot be done implicitly, +/// but only with an LLVM `cast` or with SILInstruction::asSILNode(). +class SILInstruction : public llvm::ilist_node { friend llvm::ilist_traits; friend llvm::ilist_traits; friend SILBasicBlock; @@ -351,9 +360,7 @@ class SILInstruction SILInstructionResultArray getResultsImpl() const; protected: - SILInstruction(SILInstructionKind kind, SILDebugLocation DebugLoc) - : SILNode(SILNodeKind(kind), SILNodeStorageLocation::Instruction, - IsRepresentative::Yes), + SILInstruction(SILDebugLocation DebugLoc) : ParentBB(nullptr), Location(DebugLoc) { NumCreatedInstructions++; } @@ -399,16 +406,16 @@ class SILInstruction DoesNotRelease, MayRelease, }; + + SILNode *asSILNode(); + const SILNode *asSILNode() const; LLVM_ATTRIBUTE_ALWAYS_INLINE - SILInstructionKind getKind() const { - return SILInstructionKind(SILNode::getKind()); - } + SILInstructionKind getKind() const; SILBasicBlock *getParent() const { return ParentBB; } - SILFunction *getFunction(); - const SILFunction *getFunction() const; + SILFunction *getFunction() const; /// Is this instruction part of a static initializer of a SILGlobalVariable? bool isStaticInitializerInst() const { return getFunction() == nullptr; } @@ -732,9 +739,9 @@ class SILInstruction void dumpInContext() const; void printInContext(raw_ostream &OS) const; - static bool classof(const SILNode *N) { - return N->getKind() >= SILNodeKind::First_SILInstruction && - N->getKind() <= SILNodeKind::Last_SILInstruction; + static bool classof(SILNodePointer node) { + return node->getKind() >= SILNodeKind::First_SILInstruction && + node->getKind() <= SILNodeKind::Last_SILInstruction; } static bool classof(const SILInstruction *I) { return true; } @@ -742,6 +749,79 @@ class SILInstruction static bool classof(const ValueBase *) = delete; }; +inline SILNodePointer::SILNodePointer(const SILInstruction *inst) : + node(inst->asSILNode()) { } + +/// The base class for all instructions, which are not SingleValueInstructions: +/// NonValueInstruction and MultipleValueInstruction. +class NonSingleValueInstruction : public SILInstruction, public SILNode { + friend struct SILNodeOffsetChecker; +public: + NonSingleValueInstruction(SILInstructionKind kind, SILDebugLocation loc) + : SILInstruction(loc), SILNode((SILNodeKind)kind) {} + + using SILInstruction::operator new; + using SILInstruction::dumpInContext; + using SILInstruction::print; + using SILInstruction::printInContext; + + // Redeclare because lldb currently doesn't know about using-declarations + void dump() const; + SILFunction *getFunction() const { return SILInstruction::getFunction(); } + SILModule &getModule() const { return SILInstruction::getModule(); } + + /// Doesn't produce any results. + SILType getType() const = delete; + + LLVM_ATTRIBUTE_ALWAYS_INLINE + SILInstructionKind getKind() const { + return (SILInstructionKind)SILNode::getKind(); + } + + static bool classof(const ValueBase *value) = delete; + static bool classof(SILNodePointer node) { + return node->getKind() >= SILNodeKind::First_NonSingleValueInstruction && + node->getKind() <= SILNodeKind::Last_NonSingleValueInstruction; + } + static bool classof(const NonSingleValueInstruction *) { return true; } +}; + +inline SILNode *SILInstruction::asSILNode() { + // Even if this insttruction is not a NonSingleValueInstruction, but a + // SingleValueInstruction, the SILNode is at the same offset as in a + // NonSingleValueInstruction. See the top-level comment of SILInstruction. + SILNode *node = (NonSingleValueInstruction *)this; + assert(isa(node) || + isa(node)); + return node; +} +inline const SILNode *SILInstruction::asSILNode() const { + return (const_cast(this))->asSILNode(); +} + +inline SILNodePointer::SILNodePointer(const NonSingleValueInstruction *nsvi) : + node(nsvi) { } + +inline SILInstructionKind SILInstruction::getKind() const { + return SILInstructionKind(asSILNode()->getKind()); +} + +inline SILInstruction *SILNode::castToInstruction() { + assert(isa(this)); + // We use the same trick here as in SILInstruction::asSILNode(). + auto *nsvi = (NonSingleValueInstruction *)this; + assert((SILNodeKind)nsvi->getKind() == getKind()); + return nsvi; +} + +inline SILNode *SILNode::instAsNode(SILInstruction *inst) { + return inst->asSILNode(); +} +inline const SILNode *SILNode::instAsNode(const SILInstruction *inst) { + return inst->asSILNode(); +} + + struct SILInstruction::OperandToValue { const SILInstruction &i; bool skipTypeDependentOps; @@ -840,20 +920,17 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, /// both of which inherit from SILNode, it introduces the need for /// some care when working with SILNodes. See the comment on SILNode. class SingleValueInstruction : public SILInstruction, public ValueBase { - static bool isSingleValueInstKind(SILNodeKind kind) { - return kind >= SILNodeKind::First_SingleValueInstruction && - kind <= SILNodeKind::Last_SingleValueInstruction; - } - friend class SILInstruction; + friend struct SILNodeOffsetChecker; + SILInstructionResultArray getResultsImpl() const { return SILInstructionResultArray(this); } public: SingleValueInstruction(SILInstructionKind kind, SILDebugLocation loc, SILType type) - : SILInstruction(kind, loc), - ValueBase(ValueKind(kind), type, IsRepresentative::No) {} + : SILInstruction(loc), + ValueBase(ValueKind(kind), type) {} using SILInstruction::operator new; using SILInstruction::dumpInContext; @@ -862,12 +939,11 @@ class SingleValueInstruction : public SILInstruction, public ValueBase { // Redeclare because lldb currently doesn't know about using-declarations void dump() const; - SILFunction *getFunction() { return SILInstruction::getFunction(); } - const SILFunction *getFunction() const { - return SILInstruction::getFunction(); - } + SILFunction *getFunction() const { return SILInstruction::getFunction(); } SILModule &getModule() const { return SILInstruction::getModule(); } - SILInstructionKind getKind() const { return SILInstruction::getKind(); } + SILInstructionKind getKind() const { + return (SILInstructionKind)ValueBase::getKind(); + } void operator delete(void *Ptr, size_t) = delete; @@ -882,44 +958,37 @@ class SingleValueInstruction : public SILInstruction, public ValueBase { /// Override this to reflect the more efficient access pattern. SILInstructionResultArray getResults() const { return getResultsImpl(); } - static bool classof(const SILNode *node) { - return isSingleValueInstKind(node->getKind()); + static bool classof(SILNodePointer node) { + return node->getKind() >= SILNodeKind::First_SingleValueInstruction && + node->getKind() <= SILNodeKind::Last_SingleValueInstruction; } }; -// Resolve ambiguities. +struct SILNodeOffsetChecker { + static_assert(offsetof(SingleValueInstruction, Bits) == + offsetof(NonSingleValueInstruction, Bits), + "wrong SILNode layout in SILInstruction"); +}; + +inline SILNodePointer::SILNodePointer(const SingleValueInstruction *svi) : + node(svi) { } + +// Resolve SILInstruction vs SILNode ambiguities. inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, - const SingleValueInstruction &I) { - I.print(OS); + const NonSingleValueInstruction &I) { + cast(&I)->print(OS); return OS; } - -inline SingleValueInstruction *SILNode::castToSingleValueInstruction() { - assert(isa(this)); - - // We do reference static_casts to convince the host compiler to do - // null-unchecked conversions. - - // If we're in the value slot, cast through ValueBase. - if (getStorageLoc() == SILNodeStorageLocation::Value) { - return &static_cast( - static_cast(*this)); - - // Otherwise, cast through SILInstruction. - } else { - return &static_cast( - static_cast(*this)); - } +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const SingleValueInstruction &I) { + cast(&I)->print(OS); + return OS; } #define DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE(ID) \ - static bool classof(const SILNode *node) { \ + static bool classof(SILNodePointer node) { \ return node->getKind() >= SILNodeKind::First_##ID && \ node->getKind() <= SILNodeKind::Last_##ID; \ - } \ - static bool classof(const SingleValueInstruction *inst) { \ - return inst->getKind() >= SILInstructionKind::First_##ID && \ - inst->getKind() <= SILInstructionKind::Last_##ID; \ } /// Abstract base class used for isa checks on instructions to determine if they @@ -948,9 +1017,8 @@ class OwnershipForwardingMixin { /// Defined inline below due to forward declaration issues. static bool isa(SILInstructionKind kind); static bool isa(const SILInstruction *inst) { return isa(inst->getKind()); } - static bool isa(const SILNode *node) { - node = node->getRepresentativeSILNodeInObject(); - if (auto *i = dyn_cast(node)) + static bool isa(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return isa(i); return false; } @@ -975,8 +1043,8 @@ class FirstArgOwnershipForwardingSingleValueInst } public: - static bool classof(const SILNode *node) { - if (auto *i = dyn_cast(node)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -1008,8 +1076,8 @@ class OwnedFirstArgForwardingSingleValueInst return OwnershipKind::Owned; } - static bool classof(const SILNode *node) { - if (auto *i = dyn_cast(node)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -1047,8 +1115,8 @@ class GuaranteedFirstArgForwardingSingleValueInst return OwnershipKind::Guaranteed; } - static bool classof(const SILNode *node) { - if (auto *i = dyn_cast(node)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -1107,8 +1175,8 @@ class AllArgOwnershipForwardingSingleValueInst } public: - static bool classof(const SILNode *node) { - if (auto *i = dyn_cast(node)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -1174,7 +1242,7 @@ class MultipleValueInstructionResult : public ValueBase { static bool classof(const SILUndef *) = delete; static bool classof(const SILArgument *) = delete; static bool classof(const MultipleValueInstructionResult *) { return true; } - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { // This is an abstract class without anything implementing it right now, so // just return false. This will be fixed in a subsequent commit. SILNodeKind kind = node->getKind(); @@ -1197,13 +1265,13 @@ SILInstructionResultArray::SILInstructionResultArray(ArrayRef results) } /// An instruction that may produce an arbitrary number of values. -class MultipleValueInstruction : public SILInstruction { +class MultipleValueInstruction : public NonSingleValueInstruction { friend class SILInstruction; friend class SILInstructionResultArray; protected: MultipleValueInstruction(SILInstructionKind kind, SILDebugLocation loc) - : SILInstruction(kind, loc) {} + : NonSingleValueInstruction(kind, loc) {} public: void operator delete(void *Ptr, size_t) = delete; @@ -1220,7 +1288,7 @@ class MultipleValueInstruction : public SILInstruction { unsigned getNumResults() const { return getResults().size(); } - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { SILNodeKind kind = node->getKind(); return kind >= SILNodeKind::First_MultipleValueInstruction && kind <= SILNodeKind::Last_MultipleValueInstruction; @@ -1353,25 +1421,25 @@ class MultipleValueInstructionTrailingObjectsgetKind() >= SILNodeKind::First_NonValueInstruction && - N->getKind() <= SILNodeKind::Last_NonValueInstruction; + static bool classof(SILNodePointer node) { + return node->getKind() >= SILNodeKind::First_NonValueInstruction && + node->getKind() <= SILNodeKind::Last_NonValueInstruction; } static bool classof(const NonValueInstruction *) { return true; } }; #define DEFINE_ABSTRACT_NON_VALUE_INST_BOILERPLATE(ID) \ static bool classof(const ValueBase *value) = delete; \ - static bool classof(const SILNode *node) { \ + static bool classof(SILNodePointer node) { \ return node->getKind() >= SILNodeKind::First_##ID && \ node->getKind() <= SILNodeKind::Last_##ID; \ } @@ -1394,12 +1462,9 @@ class InstructionBase : public InstBase { return Kind; } - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind(Kind); } - static bool classof(const SingleValueInstruction *I) { // resolve ambiguities - return I->getKind() == Kind; - } }; template @@ -1416,7 +1481,7 @@ class InstructionBase : public InstBase { /// Can never dynamically succeed. static bool classof(const ValueBase *value) = delete; - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind(Kind); } }; @@ -1475,7 +1540,7 @@ class InstructionBaseWithTrailingOperands InstructionBaseWithTrailingOperands(ArrayRef Operands, Args &&...args) : InstructionBase(std::forward(args)...) { - SILInstruction::Bits.IBWTO.NumOperands = Operands.size(); + SILNode::Bits.IBWTO.NumOperands = Operands.size(); TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this, Operands); } @@ -1485,7 +1550,7 @@ class InstructionBaseWithTrailingOperands ArrayRef Operands, Args &&...args) : InstructionBase(std::forward(args)...) { - SILInstruction::Bits.IBWTO.NumOperands = Operands.size() + 1; + SILNode::Bits.IBWTO.NumOperands = Operands.size() + 1; TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this, Operand0, Operands); } @@ -1496,7 +1561,7 @@ class InstructionBaseWithTrailingOperands ArrayRef Operands, Args &&...args) : InstructionBase(std::forward(args)...) { - SILInstruction::Bits.IBWTO.NumOperands = Operands.size() + 2; + SILNode::Bits.IBWTO.NumOperands = Operands.size() + 2; TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this, Operand0, Operand1, Operands); } @@ -1504,7 +1569,7 @@ class InstructionBaseWithTrailingOperands // Destruct tail allocated objects. ~InstructionBaseWithTrailingOperands() { Operand *Operands = TrailingObjects::template getTrailingObjects(); - auto end = SILInstruction::Bits.IBWTO.NumOperands; + auto end = SILNode::Bits.IBWTO.NumOperands; for (unsigned i = 0; i < end; ++i) { Operands[i].~Operand(); } @@ -1512,17 +1577,17 @@ class InstructionBaseWithTrailingOperands size_t numTrailingObjects(typename TrailingObjects::template OverloadToken) const { - return SILInstruction::Bits.IBWTO.NumOperands; + return SILNode::Bits.IBWTO.NumOperands; } ArrayRef getAllOperands() const { return {TrailingObjects::template getTrailingObjects(), - SILInstruction::Bits.IBWTO.NumOperands}; + SILNode::Bits.IBWTO.NumOperands}; } MutableArrayRef getAllOperands() { return {TrailingObjects::template getTrailingObjects(), - SILInstruction::Bits.IBWTO.NumOperands}; + SILNode::Bits.IBWTO.NumOperands}; } }; @@ -1690,13 +1755,13 @@ class AllocStackInst final bool hasDynamicLifetime); size_t numTrailingObjects(OverloadToken) const { - return SILInstruction::Bits.AllocStackInst.NumOperands; + return SILNode::Bits.AllocStackInst.NumOperands; } public: ~AllocStackInst() { Operand *Operands = getTrailingObjects(); - size_t end = SILInstruction::Bits.AllocStackInst.NumOperands; + size_t end = SILNode::Bits.AllocStackInst.NumOperands; for (unsigned i = 0; i < end; ++i) { Operands[i].~Operand(); } @@ -1718,15 +1783,15 @@ class AllocStackInst final /// Return the debug variable information attached to this instruction. Optional getVarInfo() const { - auto RawValue = SILInstruction::Bits.AllocStackInst.VarInfo; + auto RawValue = SILNode::Bits.AllocStackInst.VarInfo; auto VI = TailAllocatedDebugVariable(RawValue); return VI.get(getDecl(), getTrailingObjects()); }; void setArgNo(unsigned N) { - auto RawValue = SILInstruction::Bits.AllocStackInst.VarInfo; + auto RawValue = SILNode::Bits.AllocStackInst.VarInfo; auto VI = TailAllocatedDebugVariable(RawValue); VI.setArgNo(N); - SILInstruction::Bits.AllocStackInst.VarInfo = VI.getRawValue(); + SILNode::Bits.AllocStackInst.VarInfo = VI.getRawValue(); } /// getElementType - Get the type of the allocated memory (as opposed to the @@ -1737,12 +1802,12 @@ class AllocStackInst final ArrayRef getAllOperands() const { return { getTrailingObjects(), - static_cast(SILInstruction::Bits.AllocStackInst.NumOperands) }; + static_cast(SILNode::Bits.AllocStackInst.NumOperands) }; } MutableArrayRef getAllOperands() { return { getTrailingObjects(), - static_cast(SILInstruction::Bits.AllocStackInst.NumOperands) }; + static_cast(SILNode::Bits.AllocStackInst.NumOperands) }; } ArrayRef getTypeDependentOperands() const { @@ -1776,16 +1841,16 @@ class AllocRefInstBase : public AllocationInst { } unsigned getNumTailTypes() const { - return SILInstruction::Bits.AllocRefInstBase.NumTailTypes; + return SILNode::Bits.AllocRefInstBase.NumTailTypes; } public: bool canAllocOnStack() const { - return SILInstruction::Bits.AllocRefInstBase.OnStack; + return SILNode::Bits.AllocRefInstBase.OnStack; } void setStackAllocatable(bool OnStack = true) { - SILInstruction::Bits.AllocRefInstBase.OnStack = OnStack; + SILNode::Bits.AllocRefInstBase.OnStack = OnStack; } ArrayRef getTailAllocatedTypes() const { @@ -1809,7 +1874,7 @@ class AllocRefInstBase : public AllocationInst { /// Whether to use Objective-C's allocation mechanism (+allocWithZone:). bool isObjC() const { - return SILInstruction::Bits.AllocRefInstBase.ObjC; + return SILNode::Bits.AllocRefInstBase.ObjC; } }; @@ -2539,8 +2604,8 @@ class BeginApplyResult final : public MultipleValueInstructionResult { /// over the implicit coroutine state? bool isTokenResult() const; // inline below - static bool classof(const SILNode *N) { - return N->getKind() == SILNodeKind::BeginApplyResult; + static bool classof(SILNodePointer node) { + return node->getKind() == SILNodeKind::BeginApplyResult; } }; @@ -2714,16 +2779,11 @@ class FunctionRefBaseInst : public LiteralInst { ArrayRef getAllOperands() const { return {}; } MutableArrayRef getAllOperands() { return {}; } - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return (node->getKind() == SILNodeKind::FunctionRefInst || node->getKind() == SILNodeKind::DynamicFunctionRefInst || node->getKind() == SILNodeKind::PreviousDynamicFunctionRefInst); } - static bool classof(const SingleValueInstruction *node) { - return (node->getKind() == SILInstructionKind::FunctionRefInst || - node->getKind() == SILInstructionKind::DynamicFunctionRefInst || - node->getKind() == SILInstructionKind::PreviousDynamicFunctionRefInst); - } }; /// FunctionRefInst - Represents a reference to a SIL function. @@ -2739,12 +2799,9 @@ class FunctionRefInst : public FunctionRefBaseInst { TypeExpansionContext context); public: - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind::FunctionRefInst; } - static bool classof(const SingleValueInstruction *node) { - return node->getKind() == SILInstructionKind::FunctionRefInst; - } }; class DynamicFunctionRefInst : public FunctionRefBaseInst { @@ -2759,12 +2816,9 @@ class DynamicFunctionRefInst : public FunctionRefBaseInst { TypeExpansionContext context); public: - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind::DynamicFunctionRefInst; } - static bool classof(const SingleValueInstruction *node) { - return node->getKind() == SILInstructionKind::DynamicFunctionRefInst; - } }; class PreviousDynamicFunctionRefInst : public FunctionRefBaseInst { @@ -2779,13 +2833,9 @@ class PreviousDynamicFunctionRefInst : public FunctionRefBaseInst { TypeExpansionContext context); public: - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind::PreviousDynamicFunctionRefInst; } - static bool classof(const SingleValueInstruction *node) { - return node->getKind() == - SILInstructionKind::PreviousDynamicFunctionRefInst; - } }; /// Component of a KeyPathInst. @@ -3317,9 +3367,9 @@ class GetAsyncContinuationInstBase /// True if the continuation can be used to resume the task by throwing an error. bool throws() const { return Throws; } - static bool classof(const SILNode *I) { - return I->getKind() >= SILNodeKind::First_GetAsyncContinuationInstBase && - I->getKind() <= SILNodeKind::Last_GetAsyncContinuationInstBase; + static bool classof(SILNodePointer node) { + return node->getKind() >= SILNodeKind::First_GetAsyncContinuationInstBase && + node->getKind() <= SILNodeKind::Last_GetAsyncContinuationInstBase; } }; @@ -3494,7 +3544,7 @@ class BuiltinInst final /// usages of the global via GlobalAddrInst. class AllocGlobalInst : public InstructionBase { + NonValueInstruction> { friend SILBuilder; SILGlobalVariable *Global; @@ -3658,12 +3708,12 @@ class StringLiteralInst final /// getValue - Return the string data for the literal, in UTF-8. StringRef getValue() const { return {getTrailingObjects(), - SILInstruction::Bits.StringLiteralInst.Length}; + SILNode::Bits.StringLiteralInst.Length}; } /// getEncoding - Return the desired encoding of the text. Encoding getEncoding() const { - return Encoding(SILInstruction::Bits.StringLiteralInst.TheEncoding); + return Encoding(SILNode::Bits.StringLiteralInst.TheEncoding); } /// getCodeUnitCount - Return encoding-based length of the string @@ -3707,16 +3757,16 @@ class LoadInst LoadOwnershipQualifier Q = LoadOwnershipQualifier::Unqualified) : UnaryInstructionBase(DebugLoc, LValue, LValue->getType().getObjectType()) { - SILInstruction::Bits.LoadInst.OwnershipQualifier = unsigned(Q); + SILNode::Bits.LoadInst.OwnershipQualifier = unsigned(Q); } public: LoadOwnershipQualifier getOwnershipQualifier() const { return LoadOwnershipQualifier( - SILInstruction::Bits.LoadInst.OwnershipQualifier); + SILNode::Bits.LoadInst.OwnershipQualifier); } void setOwnershipQualifier(LoadOwnershipQualifier qualifier) { - SILInstruction::Bits.LoadInst.OwnershipQualifier = unsigned(qualifier); + SILNode::Bits.LoadInst.OwnershipQualifier = unsigned(qualifier); } }; @@ -3755,10 +3805,10 @@ class StoreInst StoreOwnershipQualifier getOwnershipQualifier() const { return StoreOwnershipQualifier( - SILInstruction::Bits.StoreInst.OwnershipQualifier); + SILNode::Bits.StoreInst.OwnershipQualifier); } void setOwnershipQualifier(StoreOwnershipQualifier qualifier) { - SILInstruction::Bits.StoreInst.OwnershipQualifier = unsigned(qualifier); + SILNode::Bits.StoreInst.OwnershipQualifier = unsigned(qualifier); } }; @@ -3967,11 +4017,11 @@ class BeginAccessInst SILAccessKind accessKind, SILAccessEnforcement enforcement, bool noNestedConflict, bool fromBuiltin) : UnaryInstructionBase(loc, lvalue, lvalue->getType()) { - SILInstruction::Bits.BeginAccessInst.AccessKind = unsigned(accessKind); - SILInstruction::Bits.BeginAccessInst.Enforcement = unsigned(enforcement); - SILInstruction::Bits.BeginAccessInst.NoNestedConflict = + SILNode::Bits.BeginAccessInst.AccessKind = unsigned(accessKind); + SILNode::Bits.BeginAccessInst.Enforcement = unsigned(enforcement); + SILNode::Bits.BeginAccessInst.NoNestedConflict = unsigned(noNestedConflict); - SILInstruction::Bits.BeginAccessInst.FromBuiltin = + SILNode::Bits.BeginAccessInst.FromBuiltin = unsigned(fromBuiltin); static_assert(unsigned(SILAccessKind::Last) < (1 << 2), @@ -3989,18 +4039,18 @@ class BeginAccessInst public: SILAccessKind getAccessKind() const { - return SILAccessKind(SILInstruction::Bits.BeginAccessInst.AccessKind); + return SILAccessKind(SILNode::Bits.BeginAccessInst.AccessKind); } void setAccessKind(SILAccessKind kind) { - SILInstruction::Bits.BeginAccessInst.AccessKind = unsigned(kind); + SILNode::Bits.BeginAccessInst.AccessKind = unsigned(kind); } SILAccessEnforcement getEnforcement() const { return - SILAccessEnforcement(SILInstruction::Bits.BeginAccessInst.Enforcement); + SILAccessEnforcement(SILNode::Bits.BeginAccessInst.Enforcement); } void setEnforcement(SILAccessEnforcement enforcement) { - SILInstruction::Bits.BeginAccessInst.Enforcement = unsigned(enforcement); + SILNode::Bits.BeginAccessInst.Enforcement = unsigned(enforcement); } /// If hasNoNestedConflict is true, then it is a static guarantee against @@ -4010,17 +4060,17 @@ class BeginAccessInst /// its scope. This access may still conflict with an outer access scope; /// therefore may still require dynamic enforcement at a single point. bool hasNoNestedConflict() const { - return SILInstruction::Bits.BeginAccessInst.NoNestedConflict; + return SILNode::Bits.BeginAccessInst.NoNestedConflict; } void setNoNestedConflict(bool noNestedConflict) { - SILInstruction::Bits.BeginAccessInst.NoNestedConflict = noNestedConflict; + SILNode::Bits.BeginAccessInst.NoNestedConflict = noNestedConflict; } /// Return true if this access marker was emitted for a user-controlled /// Builtin. Return false if this access marker was auto-generated by the /// compiler to enforce formal access that derives from the language. bool isFromBuiltin() const { - return SILInstruction::Bits.BeginAccessInst.FromBuiltin; + return SILNode::Bits.BeginAccessInst.FromBuiltin; } SILValue getSource() const { @@ -4043,7 +4093,7 @@ class EndAccessInst private: EndAccessInst(SILDebugLocation loc, SILValue access, bool aborting = false) : UnaryInstructionBase(loc, access) { - SILInstruction::Bits.EndAccessInst.Aborting = aborting; + SILNode::Bits.EndAccessInst.Aborting = aborting; } public: @@ -4054,10 +4104,10 @@ class EndAccessInst /// Only AccessKind::Init and AccessKind::Deinit accesses can be /// aborted. bool isAborting() const { - return SILInstruction::Bits.EndAccessInst.Aborting; + return SILNode::Bits.EndAccessInst.Aborting; } void setAborting(bool aborting = true) { - SILInstruction::Bits.EndAccessInst.Aborting = aborting; + SILNode::Bits.EndAccessInst.Aborting = aborting; } BeginAccessInst *getBeginAccess() const { @@ -4091,31 +4141,31 @@ class BeginUnpairedAccessInst bool noNestedConflict, bool fromBuiltin) : InstructionBase(loc), Operands(this, addr, buffer) { - SILInstruction::Bits.BeginUnpairedAccessInst.AccessKind = + SILNode::Bits.BeginUnpairedAccessInst.AccessKind = unsigned(accessKind); - SILInstruction::Bits.BeginUnpairedAccessInst.Enforcement = + SILNode::Bits.BeginUnpairedAccessInst.Enforcement = unsigned(enforcement); - SILInstruction::Bits.BeginUnpairedAccessInst.NoNestedConflict = + SILNode::Bits.BeginUnpairedAccessInst.NoNestedConflict = unsigned(noNestedConflict); - SILInstruction::Bits.BeginUnpairedAccessInst.FromBuiltin = + SILNode::Bits.BeginUnpairedAccessInst.FromBuiltin = unsigned(fromBuiltin); } public: SILAccessKind getAccessKind() const { return SILAccessKind( - SILInstruction::Bits.BeginUnpairedAccessInst.AccessKind); + SILNode::Bits.BeginUnpairedAccessInst.AccessKind); } void setAccessKind(SILAccessKind kind) { - SILInstruction::Bits.BeginUnpairedAccessInst.AccessKind = unsigned(kind); + SILNode::Bits.BeginUnpairedAccessInst.AccessKind = unsigned(kind); } SILAccessEnforcement getEnforcement() const { return SILAccessEnforcement( - SILInstruction::Bits.BeginUnpairedAccessInst.Enforcement); + SILNode::Bits.BeginUnpairedAccessInst.Enforcement); } void setEnforcement(SILAccessEnforcement enforcement) { - SILInstruction::Bits.BeginUnpairedAccessInst.Enforcement + SILNode::Bits.BeginUnpairedAccessInst.Enforcement = unsigned(enforcement); } @@ -4126,10 +4176,10 @@ class BeginUnpairedAccessInst /// its scope. This access may still conflict with an outer access scope; /// therefore may still require dynamic enforcement at a single point. bool hasNoNestedConflict() const { - return SILInstruction::Bits.BeginUnpairedAccessInst.NoNestedConflict; + return SILNode::Bits.BeginUnpairedAccessInst.NoNestedConflict; } void setNoNestedConflict(bool noNestedConflict) { - SILInstruction::Bits.BeginUnpairedAccessInst.NoNestedConflict = + SILNode::Bits.BeginUnpairedAccessInst.NoNestedConflict = noNestedConflict; } @@ -4137,7 +4187,7 @@ class BeginUnpairedAccessInst /// Builtin. Return false if this access marker was auto-generated by the /// compiler to enforce formal access that derives from the language. bool isFromBuiltin() const { - return SILInstruction::Bits.BeginUnpairedAccessInst.FromBuiltin; + return SILNode::Bits.BeginUnpairedAccessInst.FromBuiltin; } SILValue getSource() const { @@ -4171,10 +4221,10 @@ class EndUnpairedAccessInst SILAccessEnforcement enforcement, bool aborting, bool fromBuiltin) : UnaryInstructionBase(loc, buffer) { - SILInstruction::Bits.EndUnpairedAccessInst.Enforcement + SILNode::Bits.EndUnpairedAccessInst.Enforcement = unsigned(enforcement); - SILInstruction::Bits.EndUnpairedAccessInst.Aborting = aborting; - SILInstruction::Bits.EndUnpairedAccessInst.FromBuiltin = fromBuiltin; + SILNode::Bits.EndUnpairedAccessInst.Aborting = aborting; + SILNode::Bits.EndUnpairedAccessInst.FromBuiltin = fromBuiltin; } public: @@ -4185,18 +4235,18 @@ class EndUnpairedAccessInst /// Only AccessKind::Init and AccessKind::Deinit accesses can be /// aborted. bool isAborting() const { - return SILInstruction::Bits.EndUnpairedAccessInst.Aborting; + return SILNode::Bits.EndUnpairedAccessInst.Aborting; } void setAborting(bool aborting) { - SILInstruction::Bits.EndUnpairedAccessInst.Aborting = aborting; + SILNode::Bits.EndUnpairedAccessInst.Aborting = aborting; } SILAccessEnforcement getEnforcement() const { return SILAccessEnforcement( - SILInstruction::Bits.EndUnpairedAccessInst.Enforcement); + SILNode::Bits.EndUnpairedAccessInst.Enforcement); } void setEnforcement(SILAccessEnforcement enforcement) { - SILInstruction::Bits.EndUnpairedAccessInst.Enforcement = + SILNode::Bits.EndUnpairedAccessInst.Enforcement = unsigned(enforcement); } @@ -4204,7 +4254,7 @@ class EndUnpairedAccessInst /// Builtin. Return false if this access marker was auto-generated by the /// compiler to enforce formal access that derives from the language. bool isFromBuiltin() const { - return SILInstruction::Bits.EndUnpairedAccessInst.FromBuiltin; + return SILNode::Bits.EndUnpairedAccessInst.FromBuiltin; } SILValue getBuffer() const { @@ -4272,10 +4322,10 @@ class AssignInst public: AssignOwnershipQualifier getOwnershipQualifier() const { return AssignOwnershipQualifier( - SILInstruction::Bits.AssignInst.OwnershipQualifier); + SILNode::Bits.AssignInst.OwnershipQualifier); } void setOwnershipQualifier(AssignOwnershipQualifier qualifier) { - SILInstruction::Bits.AssignInst.OwnershipQualifier = unsigned(qualifier); + SILNode::Bits.AssignInst.OwnershipQualifier = unsigned(qualifier); } }; @@ -4308,7 +4358,7 @@ class AssignByWrapperInst AssignOwnershipQualifier getOwnershipQualifier() const { return AssignOwnershipQualifier( - SILInstruction::Bits.AssignByWrapperInst.OwnershipQualifier); + SILNode::Bits.AssignByWrapperInst.OwnershipQualifier); } Destination getAssignDestination() const { return AssignDest; } @@ -4318,7 +4368,7 @@ class AssignByWrapperInst qualifier == AssignOwnershipQualifier::Reassign && dest == Destination::BackingWrapper || qualifier == AssignOwnershipQualifier::Reassign && dest == Destination::WrappedValue); - SILInstruction::Bits.AssignByWrapperInst.OwnershipQualifier = unsigned(qualifier); + SILNode::Bits.AssignByWrapperInst.OwnershipQualifier = unsigned(qualifier); AssignDest = dest; } }; @@ -4494,12 +4544,12 @@ class LoadReferenceInstBase LoadReferenceInstBase(SILDebugLocation loc, SILValue lvalue, IsTake_t isTake) : UnaryInstructionBase(loc, lvalue, getResultType(lvalue->getType())) { - SILInstruction::Bits.LoadReferenceInstBaseT.IsTake = unsigned(isTake); + SILNode::Bits.LoadReferenceInstBaseT.IsTake = unsigned(isTake); } public: IsTake_t isTake() const { - return IsTake_t(SILInstruction::Bits.LoadReferenceInstBaseT.IsTake); + return IsTake_t(SILNode::Bits.LoadReferenceInstBaseT.IsTake); } }; @@ -4513,7 +4563,7 @@ class StoreReferenceInstBase : public InstructionBase { IsInitialization_t isInit) : InstructionBase(loc), Operands(this, src, dest) { - SILInstruction::Bits.StoreReferenceInstBaseT.IsInitializationOfDest = + SILNode::Bits.StoreReferenceInstBaseT.IsInitializationOfDest = unsigned(isInit); } @@ -4523,10 +4573,10 @@ class StoreReferenceInstBase : public InstructionBase { IsInitialization_t isInitializationOfDest() const { return IsInitialization_t( - SILInstruction::Bits.StoreReferenceInstBaseT.IsInitializationOfDest); + SILNode::Bits.StoreReferenceInstBaseT.IsInitializationOfDest); } void setIsInitializationOfDest(IsInitialization_t I) { - SILInstruction::Bits.StoreReferenceInstBaseT.IsInitializationOfDest = + SILNode::Bits.StoreReferenceInstBaseT.IsInitializationOfDest = (bool)I; } @@ -4596,18 +4646,18 @@ class CopyAddrInst void setDest(SILValue V) { Operands[Dest].set(V); } IsTake_t isTakeOfSrc() const { - return IsTake_t(SILInstruction::Bits.CopyAddrInst.IsTakeOfSrc); + return IsTake_t(SILNode::Bits.CopyAddrInst.IsTakeOfSrc); } IsInitialization_t isInitializationOfDest() const { return IsInitialization_t( - SILInstruction::Bits.CopyAddrInst.IsInitializationOfDest); + SILNode::Bits.CopyAddrInst.IsInitializationOfDest); } void setIsTakeOfSrc(IsTake_t T) { - SILInstruction::Bits.CopyAddrInst.IsTakeOfSrc = (bool)T; + SILNode::Bits.CopyAddrInst.IsTakeOfSrc = (bool)T; } void setIsInitializationOfDest(IsInitialization_t I) { - SILInstruction::Bits.CopyAddrInst.IsInitializationOfDest = (bool)I; + SILNode::Bits.CopyAddrInst.IsInitializationOfDest = (bool)I; } ArrayRef getAllOperands() const { return Operands.asArray(); } @@ -4690,8 +4740,8 @@ class OwnershipForwardingConversionInst : public ConversionInst, } public: - static bool classof(const SILNode *node) { - if (auto *i = dyn_cast(node)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -4731,7 +4781,7 @@ class ConvertFunctionInst final : UnaryInstructionWithTypeDependentOperandsBase( DebugLoc, Operand, TypeDependentOperands, Ty, Operand.getOwnershipKind()) { - SILInstruction::Bits.ConvertFunctionInst.WithoutActuallyEscaping = + SILNode::Bits.ConvertFunctionInst.WithoutActuallyEscaping = WithoutActuallyEscaping; assert((Operand->getType().castTo()->isNoEscape() == Ty.castTo()->isNoEscape() || @@ -4756,7 +4806,7 @@ class ConvertFunctionInst final /// not be @noescape. Note that a non-escaping closure may have unboxed /// captured even though its SIL function type is "escaping". bool withoutActuallyEscaping() const { - return SILInstruction::Bits.ConvertFunctionInst.WithoutActuallyEscaping; + return SILNode::Bits.ConvertFunctionInst.WithoutActuallyEscaping; } /// Returns `true` if the function conversion is between types with the same @@ -4875,8 +4925,8 @@ class PointerToAddressInst PointerToAddressInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty, bool IsStrict, bool IsInvariant) : UnaryInstructionBase(DebugLoc, Operand, Ty) { - SILInstruction::Bits.PointerToAddressInst.IsStrict = IsStrict; - SILInstruction::Bits.PointerToAddressInst.IsInvariant = IsInvariant; + SILNode::Bits.PointerToAddressInst.IsStrict = IsStrict; + SILNode::Bits.PointerToAddressInst.IsInvariant = IsInvariant; } public: @@ -4884,13 +4934,13 @@ class PointerToAddressInst /// If true, then the type of each memory access dependent on /// this address must be consistent with the memory's bound type. bool isStrict() const { - return SILInstruction::Bits.PointerToAddressInst.IsStrict; + return SILNode::Bits.PointerToAddressInst.IsStrict; } /// Whether the returned address is invariant. /// If true, then loading from an address derived from this pointer always /// produces the same value. bool isInvariant() const { - return SILInstruction::Bits.PointerToAddressInst.IsInvariant; + return SILNode::Bits.PointerToAddressInst.IsInvariant; } }; @@ -5340,21 +5390,21 @@ class RefCountingInst : public NonValueInstruction { protected: RefCountingInst(SILInstructionKind Kind, SILDebugLocation DebugLoc) : NonValueInstruction(Kind, DebugLoc) { - SILInstruction::Bits.RefCountingInst.atomicity = bool(Atomicity::Atomic); + SILNode::Bits.RefCountingInst.atomicity = bool(Atomicity::Atomic); } public: void setAtomicity(Atomicity flag) { - SILInstruction::Bits.RefCountingInst.atomicity = bool(flag); + SILNode::Bits.RefCountingInst.atomicity = bool(flag); } void setNonAtomic() { - SILInstruction::Bits.RefCountingInst.atomicity = bool(Atomicity::NonAtomic); + SILNode::Bits.RefCountingInst.atomicity = bool(Atomicity::NonAtomic); } void setAtomic() { - SILInstruction::Bits.RefCountingInst.atomicity = bool(Atomicity::Atomic); + SILNode::Bits.RefCountingInst.atomicity = bool(Atomicity::Atomic); } Atomicity getAtomicity() const { - return Atomicity(SILInstruction::Bits.RefCountingInst.atomicity); + return Atomicity(SILNode::Bits.RefCountingInst.atomicity); } bool isNonAtomic() const { return getAtomicity() == Atomicity::NonAtomic; } bool isAtomic() const { return getAtomicity() == Atomicity::Atomic; } @@ -5504,7 +5554,7 @@ class ObjectInst final : public InstructionBaseWithTrailingOperands< Elements, DebugLoc, Ty, HasOwnership ? mergeSILValueOwnership(Elements) : ValueOwnershipKind(OwnershipKind::None)) { - SILInstruction::Bits.ObjectInst.NumBaseElements = NumBaseElements; + SILNode::Bits.ObjectInst.NumBaseElements = NumBaseElements; } /// Construct an ObjectInst. @@ -5527,13 +5577,13 @@ class ObjectInst final : public InstructionBaseWithTrailingOperands< /// The elements which initialize the stored properties of the object itself. OperandValueArrayRef getBaseElements() const { return OperandValueArrayRef(getAllOperands().slice(0, - SILInstruction::Bits.ObjectInst.NumBaseElements)); + SILNode::Bits.ObjectInst.NumBaseElements)); } /// The elements which initialize the tail allocated elements. OperandValueArrayRef getTailElements() const { return OperandValueArrayRef(getAllOperands().slice( - SILInstruction::Bits.ObjectInst.NumBaseElements)); + SILNode::Bits.ObjectInst.NumBaseElements)); } }; @@ -5821,7 +5871,7 @@ class SelectEnumInstBase Optional> CaseCounts, ProfileCounter DefaultCount) : SelectInstBase(kind, debugLoc, type) { - SILInstruction::Bits.SelectEnumInstBase.HasDefault = defaultValue; + SILNode::Bits.SelectEnumInstBase.HasDefault = defaultValue; } template static SELECT_ENUM_INST * @@ -5860,7 +5910,7 @@ class SelectEnumInstBase NullablePtr getUniqueCaseForDefault(); bool hasDefault() const { - return SILInstruction::Bits.SelectEnumInstBase.HasDefault; + return SILNode::Bits.SelectEnumInstBase.HasDefault; } SILValue getDefaultResult() const { @@ -5896,8 +5946,8 @@ class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase, } public: - static bool classof(const SILNode *node) { - if (auto *i = dyn_cast(node)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -6084,12 +6134,12 @@ class TupleExtractInst unsigned FieldNo, SILType ResultTy) : UnaryInstructionBase(DebugLoc, Operand, ResultTy, Operand.getOwnershipKind()) { - SILInstruction::Bits.TupleExtractInst.FieldNo = FieldNo; + SILNode::Bits.TupleExtractInst.FieldNo = FieldNo; } public: unsigned getFieldIndex() const { - return SILInstruction::Bits.TupleExtractInst.FieldNo; + return SILNode::Bits.TupleExtractInst.FieldNo; } TupleType *getTupleType() const { @@ -6116,12 +6166,12 @@ class TupleElementAddrInst TupleElementAddrInst(SILDebugLocation DebugLoc, SILValue Operand, unsigned FieldNo, SILType ResultTy) : UnaryInstructionBase(DebugLoc, Operand, ResultTy) { - SILInstruction::Bits.TupleElementAddrInst.FieldNo = FieldNo; + SILNode::Bits.TupleElementAddrInst.FieldNo = FieldNo; } public: unsigned getFieldIndex() const { - return SILInstruction::Bits.TupleElementAddrInst.FieldNo; + return SILNode::Bits.TupleElementAddrInst.FieldNo; } @@ -6177,7 +6227,7 @@ class FieldIndexCacheBase : public ParentTy { SILType type, VarDecl *field, ArgTys &&... extraArgs) : ParentTy(kind, loc, type, std::forward(extraArgs)...), field(field) { - SILInstruction::Bits.FieldIndexCacheBase.FieldIndex = InvalidFieldIndex; + SILNode::Bits.FieldIndexCacheBase.FieldIndex = InvalidFieldIndex; // This needs to be a concrete class to hold bitfield information. However, // it should only be extended by UnaryInstructions. assert(ParentTy::getNumOperands() == 1); @@ -6186,7 +6236,7 @@ class FieldIndexCacheBase : public ParentTy { VarDecl *getField() const { return field; } unsigned getFieldIndex() const { - unsigned idx = SILInstruction::Bits.FieldIndexCacheBase.FieldIndex; + unsigned idx = SILNode::Bits.FieldIndexCacheBase.FieldIndex; if (idx != InvalidFieldIndex) return idx; @@ -6200,7 +6250,7 @@ class FieldIndexCacheBase : public ParentTy { return s; } - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { SILNodeKind kind = node->getKind(); return kind == SILNodeKind::StructExtractInst || kind == SILNodeKind::StructElementAddrInst || @@ -6210,7 +6260,7 @@ class FieldIndexCacheBase : public ParentTy { private: unsigned cacheFieldIndex() { unsigned index = swift::getFieldIndex(getParentDecl(), getField()); - SILInstruction::Bits.FieldIndexCacheBase.FieldIndex = index; + SILNode::Bits.FieldIndexCacheBase.FieldIndex = index; return index; } }; @@ -6277,12 +6327,12 @@ class RefElementAddrInst /// Returns true if all loads of the same instance variable from the same /// class reference operand are guaranteed to yield the same value. bool isImmutable() const { - return SILInstruction::Bits.RefElementAddrInst.Immutable; + return SILNode::Bits.RefElementAddrInst.Immutable; } /// Sets the immutable flag. void setImmutable(bool immutable = true) { - SILInstruction::Bits.RefElementAddrInst.Immutable = immutable; + SILNode::Bits.RefElementAddrInst.Immutable = immutable; } }; @@ -6312,12 +6362,12 @@ class RefTailAddrInst /// Returns true if all loads of the same instance variable from the same /// class reference operand are guaranteed to yield the same value. bool isImmutable() const { - return SILInstruction::Bits.RefTailAddrInst.Immutable; + return SILNode::Bits.RefTailAddrInst.Immutable; } /// Sets the immutable flag. void setImmutable(bool immutable = true) { - SILInstruction::Bits.RefTailAddrInst.Immutable = immutable; + SILNode::Bits.RefTailAddrInst.Immutable = immutable; } }; @@ -6892,12 +6942,12 @@ class UncheckedOwnershipConversionInst UncheckedOwnershipConversionInst(SILDebugLocation DebugLoc, SILValue operand, ValueOwnershipKind Kind) : UnaryInstructionBase(DebugLoc, operand, operand->getType()) { - SILInstruction::Bits.UncheckedOwnershipConversionInst.Kind = Kind; + SILNode::Bits.UncheckedOwnershipConversionInst.Kind = Kind; } public: ValueOwnershipKind getConversionOwnershipKind() const { - unsigned kind = SILInstruction::Bits.UncheckedOwnershipConversionInst.Kind; + unsigned kind = SILNode::Bits.UncheckedOwnershipConversionInst.Kind; return ValueOwnershipKind(kind); } }; @@ -7065,8 +7115,8 @@ class BeginCOWMutationResult final : public MultipleValueInstructionResult { return const_cast(this)->getParent(); } - static bool classof(const SILNode *N) { - return N->getKind() == SILNodeKind::BeginCOWMutationResult; + static bool classof(SILNodePointer node) { + return node->getKind() == SILNodeKind::BeginCOWMutationResult; } }; @@ -7108,11 +7158,11 @@ class BeginCOWMutationInst final } bool isNative() const { - return SILInstruction::Bits.BeginCOWMutationInst.Native; + return SILNode::Bits.BeginCOWMutationInst.Native; } void setNative(bool native = true) { - SILInstruction::Bits.BeginCOWMutationInst.Native = native; + SILNode::Bits.BeginCOWMutationInst.Native = native; } }; @@ -7137,11 +7187,11 @@ class EndCOWMutationInst public: bool doKeepUnique() const { - return SILInstruction::Bits.EndCOWMutationInst.KeepUnique; + return SILNode::Bits.EndCOWMutationInst.KeepUnique; } void setKeepUnique(bool keepUnique = true) { - SILInstruction::Bits.EndCOWMutationInst.KeepUnique = keepUnique; + SILNode::Bits.EndCOWMutationInst.KeepUnique = keepUnique; } }; @@ -7206,16 +7256,16 @@ class DeallocRefInst : DeallocRefInst(SILDebugLocation DebugLoc, SILValue Operand, bool canBeOnStack = false) : UnaryInstructionBase(DebugLoc, Operand) { - SILInstruction::Bits.DeallocRefInst.OnStack = canBeOnStack; + SILNode::Bits.DeallocRefInst.OnStack = canBeOnStack; } public: bool canAllocOnStack() const { - return SILInstruction::Bits.DeallocRefInst.OnStack; + return SILNode::Bits.DeallocRefInst.OnStack; } void setStackAllocatable(bool OnStack) { - SILInstruction::Bits.DeallocRefInst.OnStack = OnStack; + SILNode::Bits.DeallocRefInst.OnStack = OnStack; } }; @@ -7634,8 +7684,8 @@ class OwnershipForwardingTermInst : public TermInst, } public: - static bool classof(const SILNode *node) { - if (auto *i = dyn_cast(node)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -7925,12 +7975,12 @@ class CondBranchInst final /// The number of arguments for the True branch. unsigned getNumTrueArgs() const { - return SILInstruction::Bits.CondBranchInst.NumTrueArgs; + return SILNode::Bits.CondBranchInst.NumTrueArgs; } /// The number of arguments for the False branch. unsigned getNumFalseArgs() const { return getAllOperands().size() - NumFixedOpers - - SILInstruction::Bits.CondBranchInst.NumTrueArgs; + SILNode::Bits.CondBranchInst.NumTrueArgs; } CondBranchInst(SILDebugLocation DebugLoc, SILValue Condition, @@ -8136,7 +8186,7 @@ class SwitchValueInst final } bool hasDefault() const { - return SILInstruction::Bits.SwitchValueInst.HasDefault; + return SILNode::Bits.SwitchValueInst.HasDefault; } SILBasicBlock *getDefaultBB() const { assert(hasDefault() && "doesn't have a default"); @@ -8193,8 +8243,8 @@ class SwitchEnumInstBase : public BaseTy { Rest &&... rest) : BaseTy(Kind, DebugLoc, std::forward(rest)...), Operands(this, Operand) { - SILInstruction::Bits.SEIBase.HasDefault = bool(DefaultBB); - SILInstruction::Bits.SEIBase.NumCases = CaseBBs.size(); + SILNode::Bits.SEIBase.HasDefault = bool(DefaultBB); + SILNode::Bits.SEIBase.NumCases = CaseBBs.size(); // Initialize the case and successor arrays. auto *cases = getCaseBuf(); auto *succs = getSuccessorBuf(); @@ -8240,7 +8290,7 @@ class SwitchEnumInstBase : public BaseTy { static_cast(getNumCases() + hasDefault())}; } - unsigned getNumCases() const { return SILInstruction::Bits.SEIBase.NumCases; } + unsigned getNumCases() const { return SILNode::Bits.SEIBase.NumCases; } std::pair getCase(unsigned i) const { @@ -8340,7 +8390,7 @@ class SwitchEnumInstBase : public BaseTy { return eltDecl; } - bool hasDefault() const { return SILInstruction::Bits.SEIBase.HasDefault; } + bool hasDefault() const { return SILNode::Bits.SEIBase.HasDefault; } SILBasicBlock *getDefaultBB() const { assert(hasDefault() && "doesn't have a default"); @@ -8358,9 +8408,9 @@ class SwitchEnumInstBase : public BaseTy { return getSuccessorBuf()[getNumCases()].getCount(); } - static bool classof(const SILInstruction *I) { - return I->getKind() >= SILInstructionKind::SwitchEnumInst && - I->getKind() <= SILInstructionKind::SwitchEnumAddrInst; + static bool classof(SILNodePointer node) { + return node->getKind() >= SILNodeKind::SwitchEnumInst && + node->getKind() <= SILNodeKind::SwitchEnumAddrInst; } }; @@ -9112,8 +9162,8 @@ class OwnershipForwardingMultipleValueInstruction assert(classof(kind) && "Missing subclass from classof?!"); } - static bool classof(const SILNode *n) { - if (auto *i = dyn_cast(n)) + static bool classof(SILNodePointer node) { + if (auto *i = dyn_cast(node.get())) return classof(i); return false; } @@ -9140,8 +9190,8 @@ class DestructureStructResult final : public MultipleValueInstructionResult { : MultipleValueInstructionResult(ValueKind::DestructureStructResult, Index, Type, OwnershipKind) {} - static bool classof(const SILNode *N) { - return N->getKind() == SILNodeKind::DestructureStructResult; + static bool classof(SILNodePointer node) { + return node->getKind() == SILNodeKind::DestructureStructResult; } DestructureStructInst *getParent(); @@ -9169,8 +9219,8 @@ class DestructureStructInst final static DestructureStructInst *create(const SILFunction &F, SILDebugLocation Loc, SILValue Operand); - static bool classof(const SILNode *N) { - return N->getKind() == SILNodeKind::DestructureStructInst; + static bool classof(SILNodePointer node) { + return node->getKind() == SILNodeKind::DestructureStructInst; } }; @@ -9189,8 +9239,8 @@ class DestructureTupleResult final : public MultipleValueInstructionResult { : MultipleValueInstructionResult(ValueKind::DestructureTupleResult, Index, Type, OwnershipKind) {} - static bool classof(const SILNode *N) { - return N->getKind() == SILNodeKind::DestructureTupleResult; + static bool classof(SILNodePointer node) { + return node->getKind() == SILNodeKind::DestructureTupleResult; } DestructureTupleInst *getParent(); @@ -9218,8 +9268,8 @@ class DestructureTupleInst final static DestructureTupleInst *create(const SILFunction &F, SILDebugLocation Loc, SILValue Operand); - static bool classof(const SILNode *N) { - return N->getKind() == SILNodeKind::DestructureTupleInst; + static bool classof(SILNodePointer node) { + return node->getKind() == SILNodeKind::DestructureTupleInst; } }; diff --git a/include/swift/SIL/SILNode.h b/include/swift/SIL/SILNode.h index 5cab8b05686dc..b9ffaf4c35444 100644 --- a/include/swift/SIL/SILNode.h +++ b/include/swift/SIL/SILNode.h @@ -18,7 +18,6 @@ #define SWIFT_SIL_SILNODE_H #include "llvm/Support/Compiler.h" -#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "swift/Basic/InlineBitfield.h" #include "swift/Basic/LLVM.h" @@ -29,9 +28,12 @@ namespace swift { class SILBasicBlock; class SILFunction; class SILInstruction; -class SILModule; class SingleValueInstruction; +class NonSingleValueInstruction; +class SILModule; class ValueBase; +class SILNode; +class SILValue; /// An enumeration which contains values for all the nodes in SILNodes.def. /// Other enumerators, like ValueKind and SILInstructionKind, ultimately @@ -50,6 +52,26 @@ enum { NumSILNodeKindBits = enum class SILInstructionKind : std::underlying_type::type; +/// A SILNode pointer which makes it possible to implicitly cast from all kind +/// of nodes, values and instructions (note: there is no implicit cast from +/// SILInstruction* to SILNode*). +/// It's mainly used to simplify classof-functions, but it can be used for other +/// SILNode-taking APIs, too. +/// Currently there is only a const-version of it. +class SILNodePointer { + const SILNode *node; +public: + SILNodePointer(const SILNode *node) : node(node) { } + SILNodePointer(const SILInstruction *inst); + SILNodePointer(const SingleValueInstruction *svi); + SILNodePointer(const NonSingleValueInstruction *nsvi); + SILNodePointer(SILValue value); + + const SILNode *get() const { return node; } + const SILNode *operator->() const { return node; } + operator const SILNode *() const { return node; } +}; + /// A SILNode is a node in the use-def graph of a SILFunction. It is /// either an instruction or a defined value which can be used by an /// instruction. A defined value may be an instruction result, a basic @@ -104,10 +126,8 @@ class alignas(8) SILNode { protected: union { uint64_t OpaqueBits; - SWIFT_INLINE_BITFIELD_BASE(SILNode, bitmax(NumSILNodeKindBits,8)+1+1, - Kind : bitmax(NumSILNodeKindBits,8), - StorageLoc : 1, - IsRepresentativeNode : 1 + SWIFT_INLINE_BITFIELD_BASE(SILNode, bitmax(NumSILNodeKindBits,8), + Kind : bitmax(NumSILNodeKindBits,8) ); SWIFT_INLINE_BITFIELD_EMPTY(ValueBase, SILNode); @@ -391,71 +411,18 @@ class alignas(8) SILNode { } Bits; - enum class SILNodeStorageLocation : uint8_t { Value, Instruction }; - - enum class IsRepresentative : bool { - No = false, - Yes = true, - }; - -private: - - SILNodeStorageLocation getStorageLoc() const { - return SILNodeStorageLocation(Bits.SILNode.StorageLoc); - } - - const SILNode *getRepresentativeSILNodeSlowPath() const; - protected: - SILNode(SILNodeKind kind, SILNodeStorageLocation storageLoc, - IsRepresentative isRepresentative) { + SILNode(SILNodeKind kind) { Bits.OpaqueBits = 0; Bits.SILNode.Kind = unsigned(kind); - Bits.SILNode.StorageLoc = unsigned(storageLoc); - Bits.SILNode.IsRepresentativeNode = unsigned(isRepresentative); } public: - /// Does the given kind of node inherit from multiple multiple SILNode base - /// classes? - /// - /// This enables one to know if their is a diamond in the inheritence - /// hierarchy for this SILNode. - static bool hasMultipleSILNodeBases(SILNodeKind kind) { - // Currently only SingleValueInstructions. Note that multi-result - // instructions shouldn't return true for this. - return kind >= SILNodeKind::First_SingleValueInstruction && - kind <= SILNodeKind::Last_SingleValueInstruction; - } - - /// Is this SILNode the representative SILNode subobject in this object? - bool isRepresentativeSILNodeInObject() const { - return Bits.SILNode.IsRepresentativeNode; - } - - /// Return a pointer to the representative SILNode subobject in this object. - SILNode *getRepresentativeSILNodeInObject() { - if (isRepresentativeSILNodeInObject()) - return this; - return const_cast(getRepresentativeSILNodeSlowPath()); - } - - const SILNode *getRepresentativeSILNodeInObject() const { - if (isRepresentativeSILNodeInObject()) - return this; - return getRepresentativeSILNodeSlowPath(); - } - LLVM_ATTRIBUTE_ALWAYS_INLINE SILNodeKind getKind() const { return SILNodeKind(Bits.SILNode.Kind); } - /// Return the SILNodeKind of this node's representative SILNode. - SILNodeKind getKindOfRepresentativeSILNodeInObject() const { - return getRepresentativeSILNodeInObject()->getKind(); - } - /// If this is a SILArgument or a SILInstruction get its parent basic block, /// otherwise return null. SILBasicBlock *getParentBlock() const; @@ -483,14 +450,13 @@ class alignas(8) SILNode { // Cast to SingleValueInstruction. This is an implementation detail // of the cast machinery. At a high level, all you need to know is to // never use static_cast to downcast a SILNode. - SingleValueInstruction *castToSingleValueInstruction(); - const SingleValueInstruction *castToSingleValueInstruction() const { - return const_cast(this)->castToSingleValueInstruction(); - } + SILInstruction *castToInstruction(); + const SILInstruction *castToInstruction() const; + + static SILNode *instAsNode(SILInstruction *inst); + static const SILNode *instAsNode(const SILInstruction *inst); - static bool classof(const SILNode *node) { - return true; - } + static bool classof(SILNodePointer node) { return true; } }; inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, @@ -499,67 +465,46 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, return OS; } -template struct cast_sil_node_is_unambiguous { - // The only ambiguity right now is between the value and instruction - // nodes on a SingleValueInstruction. - static constexpr bool value = - // If the destination type isn't a subclass of ValueBase or - // SILInstruction, there's no ambiguity. - (!std::is_base_of::value && - !std::is_base_of::value) - - // If the destination type is a proper subclass of ValueBase - // that isn't a subclass of SILInstruction, there's no ambiguity. - || (std::is_base_of::value && - !std::is_same::value && - !std::is_base_of::value) - - // If the destination type is a proper subclass of SILInstruction - // that isn't a subclass of ValueBase, there's no ambiguity. - || (std::is_base_of::value && - !std::is_same::value && - !std::is_base_of::value); +// Simply do a pointer cast from a SILNode to a SILNode. This is always +// possible, except the To-type is SILInstruction itself. +template +struct cast_from_SILNode { + static To *doit(SILNode *node) { return &static_cast(*node); } }; -template ::value, - bool IsKnownUnambiguous = - cast_sil_node_is_unambiguous::value> -struct cast_sil_node; - -// If all complete objects of the destination type are known to only -// contain a single node, we can just use a static_cast. -template -struct cast_sil_node { - static To *doit(SILNode *node) { - return &static_cast(*node); +// Handle the special case of casting a SILNode to SILInstruction itself. +// This does not apply to sub-classes of SILInstruction, because all sub-classes +// from SILInstructions are derived from SILNode. +template <> +struct cast_from_SILNode { + static SILInstruction *doit(SILNode *node) { + return &static_cast(*node->castToInstruction()); } }; +template <> +struct cast_from_SILNode { + static const SILInstruction *doit(SILNode *node) { + return &static_cast(*node->castToInstruction()); + } +}; + +template ::value> +struct cast_from_SILInstruction; -// If we're casting to a subclass of SingleValueInstruction, we don't -// need to dynamically check whether the node is an SVI. In fact, -// we can't, because the static_cast will be ambiguous. +// Simply do a pointer cast from a SILInstruction to a SILInstruction. template -struct cast_sil_node { - static To *doit(SILNode *node) { - auto svi = node->castToSingleValueInstruction(); - return &static_cast(*svi); +struct cast_from_SILInstruction { + static To *doit(SILInstruction *inst) { + return &static_cast(*inst); } }; -// Otherwise, we need to dynamically check which case we're in. +// Cast from a SILInstruction to a SILNode, which is not a SILInstruction. template -struct cast_sil_node { - static To *doit(SILNode *node) { - // If the node isn't dynamically a SingleValueInstruction, then this - // is indeed the SILNode subobject that's statically observable in To. - if (!SILNode::hasMultipleSILNodeBases(node->getKind())) { - return &static_cast(*node); - } - - auto svi = node->castToSingleValueInstruction(); - return &static_cast(*svi); +struct cast_from_SILInstruction { + static To *doit(SILInstruction *inst) { + return &static_cast(*SILNode::instAsNode(inst)); } }; @@ -567,20 +512,36 @@ struct cast_sil_node { namespace llvm { -/// Completely take over cast<>'ing from SILNode*. A static_cast to -/// ValueBase* or SILInstruction* can be quite wrong. +/// Completely take over cast<>'ing from SILNode* and SILInstruction*. +/// A static_cast to ValueBase* or SILInstruction* can be quite wrong. template struct cast_convert_val { using ret_type = typename cast_retty::ret_type; static ret_type doit(swift::SILNode *node) { - return swift::cast_sil_node::doit(node); + return swift::cast_from_SILNode::doit(node); } }; template struct cast_convert_val { using ret_type = typename cast_retty::ret_type; static ret_type doit(const swift::SILNode *node) { - return swift::cast_sil_node::doit(const_cast(node)); + return swift::cast_from_SILNode::doit(const_cast(node)); + } +}; +template +struct cast_convert_val { + using ret_type = typename cast_retty::ret_type; + static ret_type doit(swift::SILInstruction *inst) { + return swift::cast_from_SILInstruction::doit(inst); + } +}; +template +struct cast_convert_val { + using ret_type = typename cast_retty::ret_type; + static ret_type doit(const swift::SILInstruction *inst) { + return swift::cast_from_SILInstruction:: + doit(const_cast(inst)); } }; diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def index b88fbc85890b5..ff4ef0104a27a 100644 --- a/include/swift/SIL/SILNodes.def +++ b/include/swift/SIL/SILNodes.def @@ -913,6 +913,7 @@ MULTIPLE_VALUE_INST(DestructureStructInst, destructure_struct, MULTIPLE_VALUE_INST(DestructureTupleInst, destructure_tuple, MultipleValueInstruction, None, DoesNotRelease) INST_RANGE(MultipleValueInstruction, BeginApplyInst, DestructureTupleInst) +NODE_RANGE(NonSingleValueInstruction, UnreachableInst, DestructureTupleInst) NODE_RANGE(SILInstruction, AllocStackInst, DestructureTupleInst) NODE_RANGE(SILNode, SILPhiArgument, DestructureTupleInst) diff --git a/include/swift/SIL/SILPrintContext.h b/include/swift/SIL/SILPrintContext.h index 0b9c2c1448b44..39a0e9683abd4 100644 --- a/include/swift/SIL/SILPrintContext.h +++ b/include/swift/SIL/SILPrintContext.h @@ -108,7 +108,7 @@ class SILPrintContext { SILPrintContext::ID getID(const SILBasicBlock *Block); - SILPrintContext::ID getID(const SILNode *node); + SILPrintContext::ID getID(SILNodePointer node); /// Returns true if the \p Scope has and ID assigned. bool hasScopeID(const SILDebugScope *Scope) const { diff --git a/include/swift/SIL/SILUndef.h b/include/swift/SIL/SILUndef.h index 8d7540bc70a35..ecbf54df084aa 100644 --- a/include/swift/SIL/SILUndef.h +++ b/include/swift/SIL/SILUndef.h @@ -43,7 +43,7 @@ class SILUndef : public ValueBase { static bool classof(const SILArgument *) = delete; static bool classof(const SILInstruction *) = delete; - static bool classof(const SILNode *node) { + static bool classof(SILNodePointer node) { return node->getKind() == SILNodeKind::SILUndef; } }; diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h index 11bfa317eb984..fbb289692a0a2 100644 --- a/include/swift/SIL/SILValue.h +++ b/include/swift/SIL/SILValue.h @@ -346,10 +346,8 @@ class ValueBase : public SILNode, public SILAllocated { ValueBase &operator=(const ValueBase &) = delete; protected: - ValueBase(ValueKind kind, SILType type, IsRepresentative isRepresentative) - : SILNode(SILNodeKind(kind), SILNodeStorageLocation::Value, - isRepresentative), - Type(type) {} + ValueBase(ValueKind kind, SILType type) + : SILNode(SILNodeKind(kind)), Type(type) {} public: ~ValueBase() { @@ -517,9 +515,9 @@ class ValueBase : public SILNode, public SILAllocated { /// result index, or None if it is not defined by an instruction. Optional getDefiningInstructionResult(); - static bool classof(const SILNode *N) { - return N->getKind() >= SILNodeKind::First_ValueBase && - N->getKind() <= SILNodeKind::Last_ValueBase; + static bool classof(SILNodePointer node) { + return node->getKind() >= SILNodeKind::First_ValueBase && + node->getKind() <= SILNodeKind::Last_ValueBase; } static bool classof(const ValueBase *V) { return true; } @@ -618,6 +616,8 @@ class SILValue { void verifyOwnership(DeadEndBlocks *DEBlocks) const; }; +inline SILNodePointer::SILNodePointer(SILValue value) : node(value) { } + inline bool ValueOwnershipKind::isCompatibleWith(SILValue other) const { return isCompatibleWith(other.getOwnershipKind()); } diff --git a/include/swift/SILOptimizer/Analysis/AliasAnalysis.h b/include/swift/SILOptimizer/Analysis/AliasAnalysis.h index c33bca6b73dd1..ac59ec026d00c 100644 --- a/include/swift/SILOptimizer/Analysis/AliasAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/AliasAnalysis.h @@ -153,7 +153,7 @@ class AliasAnalysis : public SILAnalysis { /// It's needed if e.g. \p inst is an address projection and its operand gets /// replaced with a different underlying object. void invalidateInstruction(SILInstruction *inst) { - handleDeleteNotification(inst); + handleDeleteNotification(inst->asSILNode()); } /// Perform an alias query to see if V1, V2 refer to the same values. diff --git a/include/swift/SILOptimizer/Utils/LoadStoreOptUtils.h b/include/swift/SILOptimizer/Utils/LoadStoreOptUtils.h index eab73575a5e1f..8eac3bf971620 100644 --- a/include/swift/SILOptimizer/Utils/LoadStoreOptUtils.h +++ b/include/swift/SILOptimizer/Utils/LoadStoreOptUtils.h @@ -269,7 +269,7 @@ class LSValue : public LSBase { } auto Res = Path.getValue().createExtract(Val, &*InsertPt, true); if (Val != Base) { - Res = makeCopiedValueAvailable(Res, Inst->getParentBlock(), + Res = makeCopiedValueAvailable(Res, Inst->getParent(), jointPostDomComputer); Builder.emitEndBorrowOperation(InsertPt->getLoc(), Val); // Insert a destroy on the Base diff --git a/include/swift/SILOptimizer/Utils/SCCVisitor.h b/include/swift/SILOptimizer/Utils/SCCVisitor.h index e5f2dd665b201..2bc658529e355 100644 --- a/include/swift/SILOptimizer/Utils/SCCVisitor.h +++ b/include/swift/SILOptimizer/Utils/SCCVisitor.h @@ -84,8 +84,6 @@ class SCCVisitor { } DFSInfo &addDFSInfo(SILNode *node) { - assert(node->isRepresentativeSILNodeInObject()); - auto insertion = ValueInfoMap.try_emplace(node, new DFSInfo(node, CurrentNum++)); assert(insertion.second && "Cannot add DFS info more than once!"); @@ -93,7 +91,6 @@ class SCCVisitor { } DFSInfo &getDFSInfo(SILNode *node) { - assert(node->isRepresentativeSILNodeInObject()); auto it = ValueInfoMap.find(node); assert(it != ValueInfoMap.end() && "Expected to find value in DFS info map!"); @@ -170,7 +167,7 @@ class SCCVisitor { } void maybeDFS(SILInstruction *inst) { - (void) maybeDFSCanonicalNode(inst->getRepresentativeSILNodeInObject()); + (void) maybeDFSCanonicalNode(inst->asSILNode()); } /// Continue a DFS from the given node, finding the strongly @@ -178,9 +175,6 @@ class SCCVisitor { /// and returning the DFSInfo for the node. /// But if we've already visited the node, just return null. DFSInfo *maybeDFSCanonicalNode(SILNode *node) { - assert(node->isRepresentativeSILNodeInObject() && - "should already be canonical"); - if (!Visited.insert(node).second) return nullptr; @@ -194,7 +188,7 @@ class SCCVisitor { // Visit each unvisited operand, updating the lowest DFS number we've seen // reachable in User's SCC. for (SILValue operandValue : operands) { - SILNode *operandNode = operandValue->getRepresentativeSILNodeInObject(); + SILNode *operandNode = operandValue; if (auto operandNodeInfo = maybeDFSCanonicalNode(operandNode)) { nodeInfo.LowNum = std::min(nodeInfo.LowNum, operandNodeInfo->LowNum); } else if (DFSStack.count(operandNode)) { diff --git a/lib/SIL/IR/SILArgument.cpp b/lib/SIL/IR/SILArgument.cpp index 1e9e87eaed7d6..693f8820868cb 100644 --- a/lib/SIL/IR/SILArgument.cpp +++ b/lib/SIL/IR/SILArgument.cpp @@ -27,7 +27,7 @@ SILArgument::SILArgument(ValueKind subClassKind, SILBasicBlock *inputParentBlock, SILType type, ValueOwnershipKind ownershipKind, const ValueDecl *inputDecl) - : ValueBase(subClassKind, type, IsRepresentative::Yes), + : ValueBase(subClassKind, type), parentBlock(inputParentBlock), decl(inputDecl) { Bits.SILArgument.VOKind = static_cast(ownershipKind); inputParentBlock->insertArgument(inputParentBlock->args_end(), this); diff --git a/lib/SIL/IR/SILBasicBlock.cpp b/lib/SIL/IR/SILBasicBlock.cpp index 58a9c8614eec3..7d49b03436067 100644 --- a/lib/SIL/IR/SILBasicBlock.cpp +++ b/lib/SIL/IR/SILBasicBlock.cpp @@ -115,7 +115,7 @@ void SILBasicBlock::eraseInstructions() { SILBasicBlock::iterator SILBasicBlock::erase(SILInstruction *I) { // Notify the delete handlers that this instruction is going away. SILModule &module = getModule(); - module.notifyDeleteHandlers(&*I); + module.notifyDeleteHandlers(I->asSILNode()); auto nextIter = InstList.erase(I); module.deallocateInst(I); return nextIter; diff --git a/lib/SIL/IR/SILFunction.cpp b/lib/SIL/IR/SILFunction.cpp index 3704620a071b7..6e216ebacb3a0 100644 --- a/lib/SIL/IR/SILFunction.cpp +++ b/lib/SIL/IR/SILFunction.cpp @@ -246,10 +246,10 @@ void SILFunction::numberValues(llvm::DenseMap & for (auto &I : BB) { auto results = I.getResults(); if (results.empty()) { - ValueToNumberMap[&I] = idx++; + ValueToNumberMap[I.asSILNode()] = idx++; } else { // Assign the instruction node the first result ID. - ValueToNumberMap[&I] = idx; + ValueToNumberMap[I.asSILNode()] = idx; for (auto result : results) { ValueToNumberMap[result] = idx++; } diff --git a/lib/SIL/IR/SILInstruction.cpp b/lib/SIL/IR/SILInstruction.cpp index d9bdd427dc031..88a49bbf57582 100644 --- a/lib/SIL/IR/SILInstruction.cpp +++ b/lib/SIL/IR/SILInstruction.cpp @@ -99,13 +99,10 @@ transferNodesFromList(llvm::ilist_traits &L2, // Assert that all subclasses of ValueBase implement classof. #define NODE(CLASS, PARENT) \ - ASSERT_IMPLEMENTS_STATIC(CLASS, PARENT, classof, bool(const SILNode*)); + ASSERT_IMPLEMENTS_STATIC(CLASS, PARENT, classof, bool(SILNodePointer)); #include "swift/SIL/SILNodes.def" -SILFunction *SILInstruction::getFunction() { - return getParent()->getParent(); -} -const SILFunction *SILInstruction::getFunction() const { +SILFunction *SILInstruction::getFunction() const { return getParent()->getParent(); } @@ -1540,7 +1537,7 @@ MultipleValueInstruction::getIndexOfResult(SILValue Target) const { MultipleValueInstructionResult::MultipleValueInstructionResult( ValueKind valueKind, unsigned index, SILType type, ValueOwnershipKind ownershipKind) - : ValueBase(valueKind, type, IsRepresentative::No) { + : ValueBase(valueKind, type) { setOwnershipKind(ownershipKind); setIndex(index); } diff --git a/lib/SIL/IR/SILInstructions.cpp b/lib/SIL/IR/SILInstructions.cpp index 76e754947fd75..4b6e8510db812 100644 --- a/lib/SIL/IR/SILInstructions.cpp +++ b/lib/SIL/IR/SILInstructions.cpp @@ -154,11 +154,11 @@ AllocStackInst::AllocStackInst(SILDebugLocation Loc, SILType elementType, bool hasDynamicLifetime) : InstructionBase(Loc, elementType.getAddressType()), dynamicLifetime(hasDynamicLifetime) { - SILInstruction::Bits.AllocStackInst.NumOperands = + SILNode::Bits.AllocStackInst.NumOperands = TypeDependentOperands.size(); - assert(SILInstruction::Bits.AllocStackInst.NumOperands == + assert(SILNode::Bits.AllocStackInst.NumOperands == TypeDependentOperands.size() && "Truncation"); - SILInstruction::Bits.AllocStackInst.VarInfo = + SILNode::Bits.AllocStackInst.VarInfo = TailAllocatedDebugVariable(Var, getTrailingObjects()).getRawValue(); TrailingOperandsList::InitOperandsList(getAllOperands().begin(), this, TypeDependentOperands); @@ -205,10 +205,10 @@ AllocRefInstBase::AllocRefInstBase(SILInstructionKind Kind, bool objc, bool canBeOnStack, ArrayRef ElementTypes) : AllocationInst(Kind, Loc, ObjectType) { - SILInstruction::Bits.AllocRefInstBase.ObjC = objc; - SILInstruction::Bits.AllocRefInstBase.OnStack = canBeOnStack; - SILInstruction::Bits.AllocRefInstBase.NumTailTypes = ElementTypes.size(); - assert(SILInstruction::Bits.AllocRefInstBase.NumTailTypes == + SILNode::Bits.AllocRefInstBase.ObjC = objc; + SILNode::Bits.AllocRefInstBase.OnStack = canBeOnStack; + SILNode::Bits.AllocRefInstBase.NumTailTypes = ElementTypes.size(); + assert(SILNode::Bits.AllocRefInstBase.NumTailTypes == ElementTypes.size() && "Truncation"); assert(!objc || ElementTypes.empty()); } @@ -892,7 +892,7 @@ static void *allocateLiteralInstWithBitSize(SILModule &M, unsigned bits) { IntegerLiteralInst::IntegerLiteralInst(SILDebugLocation Loc, SILType Ty, const llvm::APInt &Value) : InstructionBase(Loc, Ty) { - SILInstruction::Bits.IntegerLiteralInst.numBits = Value.getBitWidth(); + SILNode::Bits.IntegerLiteralInst.numBits = Value.getBitWidth(); std::uninitialized_copy_n(Value.getRawData(), Value.getNumWords(), getTrailingObjects()); } @@ -952,7 +952,7 @@ IntegerLiteralInst *IntegerLiteralInst::create(IntegerLiteralExpr *E, /// getValue - Return the APInt for the underlying integer literal. APInt IntegerLiteralInst::getValue() const { - auto numBits = SILInstruction::Bits.IntegerLiteralInst.numBits; + auto numBits = SILNode::Bits.IntegerLiteralInst.numBits; return APInt(numBits, {getTrailingObjects(), getWordsForBitWidth(numBits)}); } @@ -960,7 +960,7 @@ APInt IntegerLiteralInst::getValue() const { FloatLiteralInst::FloatLiteralInst(SILDebugLocation Loc, SILType Ty, const APInt &Bits) : InstructionBase(Loc, Ty) { - SILInstruction::Bits.FloatLiteralInst.numBits = Bits.getBitWidth(); + SILNode::Bits.FloatLiteralInst.numBits = Bits.getBitWidth(); std::uninitialized_copy_n(Bits.getRawData(), Bits.getNumWords(), getTrailingObjects()); } @@ -992,7 +992,7 @@ FloatLiteralInst *FloatLiteralInst::create(FloatLiteralExpr *E, } APInt FloatLiteralInst::getBits() const { - auto numBits = SILInstruction::Bits.FloatLiteralInst.numBits; + auto numBits = SILNode::Bits.FloatLiteralInst.numBits; return APInt(numBits, {getTrailingObjects(), getWordsForBitWidth(numBits)}); } @@ -1005,8 +1005,8 @@ APFloat FloatLiteralInst::getValue() const { StringLiteralInst::StringLiteralInst(SILDebugLocation Loc, StringRef Text, Encoding encoding, SILType Ty) : InstructionBase(Loc, Ty) { - SILInstruction::Bits.StringLiteralInst.TheEncoding = unsigned(encoding); - SILInstruction::Bits.StringLiteralInst.Length = Text.size(); + SILNode::Bits.StringLiteralInst.TheEncoding = unsigned(encoding); + SILNode::Bits.StringLiteralInst.Length = Text.size(); memcpy(getTrailingObjects(), Text.data(), Text.size()); } @@ -1036,14 +1036,14 @@ CondFailInst *CondFailInst::create(SILDebugLocation DebugLoc, SILValue Operand, } uint64_t StringLiteralInst::getCodeUnitCount() { - return SILInstruction::Bits.StringLiteralInst.Length; + return SILNode::Bits.StringLiteralInst.Length; } StoreInst::StoreInst( SILDebugLocation Loc, SILValue Src, SILValue Dest, StoreOwnershipQualifier Qualifier = StoreOwnershipQualifier::Unqualified) : InstructionBase(Loc), Operands(this, Src, Dest) { - SILInstruction::Bits.StoreInst.OwnershipQualifier = unsigned(Qualifier); + SILNode::Bits.StoreInst.OwnershipQualifier = unsigned(Qualifier); } StoreBorrowInst::StoreBorrowInst(SILDebugLocation DebugLoc, SILValue Src, @@ -1074,7 +1074,7 @@ StringRef swift::getSILAccessEnforcementName(SILAccessEnforcement enforcement) { AssignInst::AssignInst(SILDebugLocation Loc, SILValue Src, SILValue Dest, AssignOwnershipQualifier Qualifier) : AssignInstBase(Loc, Src, Dest) { - SILInstruction::Bits.AssignInst.OwnershipQualifier = unsigned(Qualifier); + SILNode::Bits.AssignInst.OwnershipQualifier = unsigned(Qualifier); } AssignByWrapperInst::AssignByWrapperInst(SILDebugLocation Loc, @@ -1084,7 +1084,7 @@ AssignByWrapperInst::AssignByWrapperInst(SILDebugLocation Loc, AssignOwnershipQualifier Qualifier) : AssignInstBase(Loc, Src, Dest, Initializer, Setter) { assert(Initializer->getType().is()); - SILInstruction::Bits.AssignByWrapperInst.OwnershipQualifier = + SILNode::Bits.AssignByWrapperInst.OwnershipQualifier = unsigned(Qualifier); } @@ -1100,8 +1100,8 @@ CopyAddrInst::CopyAddrInst(SILDebugLocation Loc, SILValue SrcLValue, SILValue DestLValue, IsTake_t isTakeOfSrc, IsInitialization_t isInitializationOfDest) : InstructionBase(Loc), Operands(this, SrcLValue, DestLValue) { - SILInstruction::Bits.CopyAddrInst.IsTakeOfSrc = bool(isTakeOfSrc); - SILInstruction::Bits.CopyAddrInst.IsInitializationOfDest = + SILNode::Bits.CopyAddrInst.IsTakeOfSrc = bool(isTakeOfSrc); + SILNode::Bits.CopyAddrInst.IsInitializationOfDest = bool(isInitializationOfDest); } @@ -1561,8 +1561,8 @@ CondBranchInst::CondBranchInst(SILDebugLocation Loc, SILValue Condition, : InstructionBaseWithTrailingOperands(Condition, Args, Loc), DestBBs{{{this, TrueBB, TrueBBCount}, {this, FalseBB, FalseBBCount}}} { assert(Args.size() == (NumTrue + NumFalse) && "Invalid number of args"); - SILInstruction::Bits.CondBranchInst.NumTrueArgs = NumTrue; - assert(SILInstruction::Bits.CondBranchInst.NumTrueArgs == NumTrue && + SILNode::Bits.CondBranchInst.NumTrueArgs = NumTrue; + assert(SILNode::Bits.CondBranchInst.NumTrueArgs == NumTrue && "Truncation"); assert(TrueBB != FalseBB && "Identical destinations"); } @@ -1646,7 +1646,7 @@ void CondBranchInst::swapSuccessors() { // Finally swap the number of arguments that we have. The number of false // arguments is derived from the number of true arguments, therefore: - SILInstruction::Bits.CondBranchInst.NumTrueArgs = getNumFalseArgs(); + SILNode::Bits.CondBranchInst.NumTrueArgs = getNumFalseArgs(); } SwitchValueInst::SwitchValueInst(SILDebugLocation Loc, SILValue Operand, @@ -1654,7 +1654,7 @@ SwitchValueInst::SwitchValueInst(SILDebugLocation Loc, SILValue Operand, ArrayRef Cases, ArrayRef BBs) : InstructionBaseWithTrailingOperands(Operand, Cases, Loc) { - SILInstruction::Bits.SwitchValueInst.HasDefault = bool(DefaultBB); + SILNode::Bits.SwitchValueInst.HasDefault = bool(DefaultBB); // Initialize the successor array. auto *succs = getSuccessorBuf(); unsigned OperandBitWidth = 0; diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index 4e55a9be97d8f..f735c5e2bdd6c 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -771,7 +771,7 @@ class SILPrinter : public SILInstructionVisitor { return printUserList(values, inst, printedSlashes); } - bool printUserList(ArrayRef values, const SILNode *node, + bool printUserList(ArrayRef values, SILNodePointer node, bool printedSlashes) { // If the set of values is empty, we need to print the ID of // the instruction. Otherwise, if none of the values has a use, @@ -1100,7 +1100,7 @@ class SILPrinter : public SILInstructionVisitor { } void printInContext(const SILNode *node) { - auto sortByID = [&](const SILNode *a, const SILNode *b) { + auto sortByID = [&](SILNodePointer a, SILNodePointer b) { return Ctx.getID(a).Number < Ctx.getID(b).Number; }; @@ -3129,7 +3129,7 @@ void SILInstruction::dumpInContext() const { } void SILInstruction::printInContext(llvm::raw_ostream &OS) const { SILPrintContext Ctx(OS); - SILPrinter(Ctx).printInContext(this); + SILPrinter(Ctx).printInContext(asSILNode()); } void SILVTableEntry::print(llvm::raw_ostream &OS) const { @@ -3593,11 +3593,11 @@ ID SILPrintContext::getID(const SILBasicBlock *Block) { return R; } -ID SILPrintContext::getID(const SILNode *node) { +ID SILPrintContext::getID(SILNodePointer node) { if (node == nullptr) return {ID::Null, ~0U}; - if (isa(node)) + if (isa(node.get())) return {ID::SILUndef, 0}; SILBasicBlock *BB = node->getParentBlock(); @@ -3626,7 +3626,7 @@ ID SILPrintContext::getID(const SILNode *node) { unsigned idx = 0; for (auto &I : *BB) { // Give the instruction itself the next ID. - ValueToIDMap[&I] = idx; + ValueToIDMap[I.asSILNode()] = idx; // If there are no results, make sure we don't reuse that ID. auto results = I.getResults(); diff --git a/lib/SIL/IR/SILUndef.cpp b/lib/SIL/IR/SILUndef.cpp index 21831a8cf6683..e1c94d0216353 100644 --- a/lib/SIL/IR/SILUndef.cpp +++ b/lib/SIL/IR/SILUndef.cpp @@ -16,7 +16,7 @@ using namespace swift; SILUndef::SILUndef(SILType type) - : ValueBase(ValueKind::SILUndef, type, IsRepresentative::Yes) {} + : ValueBase(ValueKind::SILUndef, type) {} SILUndef *SILUndef::get(SILType ty, SILModule &m) { SILUndef *&entry = m.UndefValues[ty]; diff --git a/lib/SIL/IR/SILValue.cpp b/lib/SIL/IR/SILValue.cpp index 2ca8d4c7b6dc0..bd4488ea840fb 100644 --- a/lib/SIL/IR/SILValue.cpp +++ b/lib/SIL/IR/SILValue.cpp @@ -121,23 +121,6 @@ SILModule *SILNode::getModule() const { return nullptr; } -const SILNode *SILNode::getRepresentativeSILNodeSlowPath() const { - assert(getStorageLoc() != SILNodeStorageLocation::Instruction); - - if (isa(this)) { - assert(hasMultipleSILNodeBases(getKind())); - return &static_cast( - static_cast( - static_cast(*this))); - } - - if (auto *MVR = dyn_cast(this)) { - return MVR->getParent(); - } - - llvm_unreachable("Invalid value for slow path"); -} - /// Get a location for this value. SILLocation SILValue::getLoc() const { if (auto *instr = Value->getDefiningInstruction()) diff --git a/lib/SILOptimizer/ARC/ARCRegionState.cpp b/lib/SILOptimizer/ARC/ARCRegionState.cpp index f30d0049ff500..2161cc569fb72 100644 --- a/lib/SILOptimizer/ARC/ARCRegionState.cpp +++ b/lib/SILOptimizer/ARC/ARCRegionState.cpp @@ -194,7 +194,7 @@ bool ARCRegionState::processBlockBottomUp( LLVM_DEBUG(llvm::dbgs() << "VISITING:\n " << *I); - auto Result = DataflowVisitor.visit(I); + auto Result = DataflowVisitor.visit(I->asSILNode()); // If this instruction can have no further effects on another instructions, // continue. This happens for instance if we have cleared all of the state @@ -359,7 +359,7 @@ bool ARCRegionState::processBlockTopDown( LLVM_DEBUG(llvm::dbgs() << "VISITING:\n " << *I); - auto Result = DataflowVisitor.visit(I); + auto Result = DataflowVisitor.visit(I->asSILNode()); // If this instruction can have no further effects on another instructions, // continue. This happens for instance if we have cleared all of the state diff --git a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp index 1e851075f9719..c462faa2f05c6 100644 --- a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp +++ b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp @@ -87,7 +87,7 @@ bool ARCSequenceDataflowEvaluator::processBBTopDown(ARCBBState &BBState) { LLVM_DEBUG(llvm::dbgs() << "VISITING:\n " << I); - auto Result = DataflowVisitor.visit(&I); + auto Result = DataflowVisitor.visit(I.asSILNode()); // If this instruction can have no further effects on another instructions, // continue. This happens for instance if we have cleared all of the state @@ -247,7 +247,7 @@ bool ARCSequenceDataflowEvaluator::processBBBottomUp( LLVM_DEBUG(llvm::dbgs() << "VISITING:\n " << I); - auto Result = DataflowVisitor.visit(&I); + auto Result = DataflowVisitor.visit(I.asSILNode()); // If this instruction can have no further effects on another instructions, // continue. This happens for instance if we have cleared all of the state diff --git a/lib/SILOptimizer/ARC/RCStateTransition.cpp b/lib/SILOptimizer/ARC/RCStateTransition.cpp index 07a4ff9634ad0..2bf5947104331 100644 --- a/lib/SILOptimizer/ARC/RCStateTransition.cpp +++ b/lib/SILOptimizer/ARC/RCStateTransition.cpp @@ -129,12 +129,12 @@ bool RCStateTransition::matchingInst(SILInstruction *Inst) const { return false; if (Kind == RCStateTransitionKind::StrongIncrement) { - auto InstTransKind = getRCStateTransitionKind(Inst); + auto InstTransKind = getRCStateTransitionKind(Inst->asSILNode()); return InstTransKind == RCStateTransitionKind::StrongDecrement; } if (Kind == RCStateTransitionKind::StrongDecrement) { - auto InstTransKind = getRCStateTransitionKind(Inst); + auto InstTransKind = getRCStateTransitionKind(Inst->asSILNode()); return InstTransKind == RCStateTransitionKind::StrongIncrement; } diff --git a/lib/SILOptimizer/ARC/RCStateTransition.h b/lib/SILOptimizer/ARC/RCStateTransition.h index 7789cb9697f77..d7fc602d2775d 100644 --- a/lib/SILOptimizer/ARC/RCStateTransition.h +++ b/lib/SILOptimizer/ARC/RCStateTransition.h @@ -87,9 +87,9 @@ class RCStateTransition { RCStateTransition(ImmutablePointerSet *I) { assert(I->size() == 1); SILInstruction *Inst = *I->begin(); - Kind = getRCStateTransitionKind(Inst); + Kind = getRCStateTransitionKind(Inst->asSILNode()); if (isRCStateTransitionEndPoint(Kind)) { - EndPoint = Inst; + EndPoint = Inst->asSILNode(); return; } diff --git a/lib/SILOptimizer/ARC/RefCountState.cpp b/lib/SILOptimizer/ARC/RefCountState.cpp index 6b2e7495cc6c7..a03ac87819f6e 100644 --- a/lib/SILOptimizer/ARC/RefCountState.cpp +++ b/lib/SILOptimizer/ARC/RefCountState.cpp @@ -363,7 +363,7 @@ bool BottomUpRefCountState::handlePotentialGuaranteedUser( // Instructions that we do not recognize (and thus will not move) and that // *must* use RCIdentity, implies we are always known safe as long as meet // over all path constraints are satisfied. - if (isRCStateTransitionUnknown(PotentialGuaranteedUser)) + if (isRCStateTransitionUnknown(PotentialGuaranteedUser->asSILNode())) if (mustUseValue(PotentialGuaranteedUser, getRCRoot(), AA)) FoundNonARCUser = true; @@ -422,7 +422,7 @@ bool BottomUpRefCountState::handlePotentialUser(SILInstruction *PotentialUser, // Instructions that we do not recognize (and thus will not move) and that // *must* use RCIdentity, implies we are always known safe as long as meet // over all path constraints are satisfied. - if (isRCStateTransitionUnknown(PotentialUser)) + if (isRCStateTransitionUnknown(PotentialUser->asSILNode())) if (mustUseValue(PotentialUser, getRCRoot(), AA)) FoundNonARCUser = true; diff --git a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp index b9e74eb7a6234..94ebca5098e26 100644 --- a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp @@ -539,8 +539,6 @@ bool AliasAnalysis::typesMayAlias(SILType T1, SILType T2, } void AliasAnalysis::handleDeleteNotification(SILNode *node) { - assert(node->isRepresentativeSILNodeInObject()); - // The pointer 'node' is going away. We can't scan the whole cache // and remove all of the occurrences of the pointer. Instead we remove // the pointer from the index caches. diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp index ba1c236e900b2..e34cd443addcd 100644 --- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp @@ -1553,8 +1553,8 @@ void EscapeAnalysis::ConnectionGraph::print(llvm::raw_ostream &OS) const { const char *Separator = ""; for (unsigned VIdx = Nd->UsePoints.find_first(); VIdx != -1u; VIdx = Nd->UsePoints.find_next(VIdx)) { - auto node = UsePointTable[VIdx]; - OS << Separator << '%' << InstToIDMap[node]; + SILInstruction *inst = UsePointTable[VIdx]; + OS << Separator << '%' << InstToIDMap[inst->asSILNode()]; Separator = ","; } break; diff --git a/lib/SILOptimizer/Analysis/IVAnalysis.cpp b/lib/SILOptimizer/Analysis/IVAnalysis.cpp index a2e2e0903a732..d26fe04615821 100644 --- a/lib/SILOptimizer/Analysis/IVAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/IVAnalysis.cpp @@ -20,9 +20,8 @@ using namespace swift::PatternMatch; #if !defined(NDEBUG) static bool inSCC(ValueBase *value, IVInfo::SCCType &SCC) { - SILNode *valueNode = value->getRepresentativeSILNodeInObject(); for (SILNode *node : SCC) { - if (node->getRepresentativeSILNodeInObject() == valueNode) + if (node == value) return true; } return false; diff --git a/lib/SILOptimizer/Mandatory/Differentiation.cpp b/lib/SILOptimizer/Mandatory/Differentiation.cpp index d8cbc32302db7..faa104b4d77e0 100644 --- a/lib/SILOptimizer/Mandatory/Differentiation.cpp +++ b/lib/SILOptimizer/Mandatory/Differentiation.cpp @@ -1292,7 +1292,7 @@ void DifferentiationTransformer::foldDifferentiableFunctionExtraction( bool DifferentiationTransformer::processDifferentiableFunctionInst( DifferentiableFunctionInst *dfi) { PrettyStackTraceSILNode dfiTrace("canonicalizing `differentiable_function`", - cast(dfi)); + dfi); PrettyStackTraceSILFunction fnTrace("...in", dfi->getFunction()); LLVM_DEBUG({ auto &s = getADDebugStream() << "Processing DifferentiableFunctionInst:\n"; @@ -1332,8 +1332,7 @@ bool DifferentiationTransformer::processDifferentiableFunctionInst( bool DifferentiationTransformer::processLinearFunctionInst( LinearFunctionInst *lfi) { - PrettyStackTraceSILNode dfiTrace("canonicalizing `linear_function`", - cast(lfi)); + PrettyStackTraceSILNode dfiTrace("canonicalizing `linear_function`", lfi); PrettyStackTraceSILFunction fnTrace("...in", lfi->getFunction()); LLVM_DEBUG({ auto &s = getADDebugStream() << "Processing LinearFunctionInst:\n"; diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp index d08990304f95b..d9908a07706c2 100644 --- a/lib/SILOptimizer/PassManager/PassManager.cpp +++ b/lib/SILOptimizer/PassManager/PassManager.cpp @@ -1034,7 +1034,7 @@ namespace llvm { std::string Label; raw_string_ostream O(Label); SILInstruction *Inst = I.baseIter->FAS.getInstruction(); - O << '%' << Node->CG->InstToIDMap[Inst]; + O << '%' << Node->CG->InstToIDMap[Inst->asSILNode()]; return Label; } diff --git a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp index 7429a73e626ee..f6191daa3e746 100644 --- a/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp +++ b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp @@ -224,7 +224,7 @@ void DCE::markValueLive(SILValue V) { } void DCE::markInstructionLive(SILInstruction *Inst) { - if (!LiveValues.insert(Inst).second) + if (!LiveValues.insert(Inst->asSILNode()).second) return; LLVM_DEBUG(llvm::dbgs() << "Marking as live: " << *Inst); @@ -492,7 +492,7 @@ void DCE::replaceBranchWithJump(SILInstruction *Inst, SILBasicBlock *Block) { } void DCE::endLifetimeOfLiveValue(SILValue value, SILInstruction *insertPt) { - if (!LiveValues.count(value->getRepresentativeSILNodeInObject())) { + if (!LiveValues.count(value)) { return; } SILBuilderWithScope builder(insertPt); @@ -539,7 +539,7 @@ bool DCE::removeDead(SILFunction &F) { auto insertPt = getInsertAfterPoint(arg).getValue(); SILBuilderWithScope builder(insertPt); auto *destroy = builder.createDestroyValue(insertPt->getLoc(), arg); - LiveValues.insert(destroy->getRepresentativeSILNodeInObject()); + LiveValues.insert(destroy->asSILNode()); } i++; Changed = true; @@ -565,7 +565,7 @@ bool DCE::removeDead(SILFunction &F) { for (auto I = BB.begin(), E = BB.end(); I != E; ) { auto *Inst = &*I; ++I; - if (LiveValues.count(Inst) || isa(Inst)) + if (LiveValues.count(Inst->asSILNode()) || isa(Inst)) continue; // We want to replace dead terminators with unconditional branches to diff --git a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp index 3c1d0269a0aaa..90fe9cbdb6ba2 100644 --- a/lib/SILOptimizer/Transforms/SILMem2Reg.cpp +++ b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp @@ -662,7 +662,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *ASI) { } // Remove dead address instructions that may be uses of the allocation. - SILNode *Node = Inst; + SILNode *Node = Inst->asSILNode(); while (isa(Node) || isa(Node) || isa(Node)) { diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp index d0d29dd2adbbd..c5ba918ea011d 100644 --- a/lib/SILOptimizer/Utils/ConstExpr.cpp +++ b/lib/SILOptimizer/Utils/ConstExpr.cpp @@ -793,7 +793,7 @@ ConstExprFunctionState::computeOpaqueCallResult(ApplyInst *apply, SILFunction *callee) { LLVM_DEBUG(llvm::dbgs() << "ConstExpr Opaque Callee: " << *callee << "\n"); return evaluator.getUnknown( - (SILInstruction *)apply, + apply, UnknownReason::createCalleeImplementationUnknown(callee)); } @@ -882,7 +882,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, } } return evaluator.getUnknown( - (SILInstruction *)apply, + apply, UnknownReason::createTrap(message, evaluator.getAllocator())); } case WellKnownFunction::ArrayInitEmpty: { // Array.init() @@ -893,7 +893,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, auto typeValue = getConstantValue(apply->getOperand(1)); if (typeValue.getKind() != SymbolicValue::Metatype) { return typeValue.isConstant() - ? getUnknown(evaluator, (SILInstruction *)apply, + ? getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue) : typeValue; } @@ -928,8 +928,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, // Allocating uninitialized arrays is supported only in flow-sensitive mode. // TODO: the top-level mode in the interpreter should be phased out. if (recursivelyComputeValueIfNotInState) - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::Default); + return getUnknown(evaluator, apply, UnknownReason::Default); SmallVector elementConstants; // Set array elements to uninitialized state. Subsequent stores through @@ -1003,8 +1002,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, if (!arrayValue.isConstant()) return arrayValue; if (arrayValue.getKind() != SymbolicValue::Array) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } // Create a new array storage by appending the \c element to the existing @@ -1042,16 +1040,14 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, conventions.getNumParameters() == 4 && "unexpected signature"); auto literal = getConstantValue(apply->getOperand(1)); if (literal.getKind() != SymbolicValue::String) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } auto literalVal = literal.getStringValue(); auto byteCount = getConstantValue(apply->getOperand(2)); if (byteCount.getKind() != SymbolicValue::Integer || byteCount.getIntegerValue().getLimitedValue() != literalVal.size()) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } setValue(apply, literal); return None; @@ -1068,8 +1064,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, return otherString; } if (otherString.getKind() != SymbolicValue::String) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } auto inoutOperand = apply->getOperand(2); @@ -1078,8 +1073,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, return firstString; } if (firstString.getKind() != SymbolicValue::String) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } auto result = SmallString<8>(firstString.getStringValue()); @@ -1097,14 +1091,12 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, auto firstString = getConstantValue(apply->getOperand(1)); if (firstString.getKind() != SymbolicValue::String) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } auto otherString = getConstantValue(apply->getOperand(2)); if (otherString.getKind() != SymbolicValue::String) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } // The result is a Swift.Bool which is a struct that wraps an Int1. @@ -1130,8 +1122,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, } if (stringArgument.getKind() != SymbolicValue::String) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } // Replace all precent symbol (%) in the string with double percents (%%) @@ -1163,8 +1154,7 @@ ConstExprFunctionState::computeWellKnownCallResult(ApplyInst *apply, Optional isSignedIntegerType = getSignIfStdlibIntegerType(argumentType); if (!isSignedIntegerType.hasValue()) { - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); } // Load the stdlib integer's value and convert it to a string. SymbolicValue stdlibIntegerValue = @@ -1213,8 +1203,7 @@ ConstExprFunctionState::computeCallResult(ApplyInst *apply) { // Determine the callee. auto calleeFn = getConstantValue(apply->getOperand(0)); if (calleeFn.getKind() != SymbolicValue::Function) - return getUnknown(evaluator, (SILInstruction *)apply, - UnknownReason::InvalidOperandValue); + return getUnknown(evaluator, apply, UnknownReason::InvalidOperandValue); SILFunction *callee = calleeFn.getFunctionValue(); evaluator.recordCalledFunctionIfEnabled(callee); @@ -1231,7 +1220,7 @@ ConstExprFunctionState::computeCallResult(ApplyInst *apply) { auto op = apply->getOperand(i + 1); SymbolicValue argValue = getConstantValue(op); if (!argValue.isConstant()) { - return evaluator.getUnknown((SILInstruction *)apply, + return evaluator.getUnknown(apply, UnknownReason::createCallArgumentUnknown(i)); } paramConstants.push_back(argValue); @@ -1280,7 +1269,7 @@ ConstExprFunctionState::computeCallResult(ApplyInst *apply) { auto conf = protoSelfToConcreteType.lookupConformance( protocol->getSelfInterfaceType()->getCanonicalType(), protocol); if (conf.isInvalid()) - return getUnknown(evaluator, (SILInstruction *)apply, + return getUnknown(evaluator, apply, UnknownReason::UnknownWitnessMethodConformance); callSubMap = getWitnessMethodSubstitutions( @@ -1709,7 +1698,7 @@ llvm::Optional ConstExprFunctionState::evaluateClosureCreation( if (!calleeValue.isConstant()) return calleeValue; if (calleeValue.getKind() != SymbolicValue::Function) { - return getUnknown(evaluator, (SILInstruction *)closureInst, + return getUnknown(evaluator, closureInst, UnknownReason::InvalidOperandValue); } @@ -1796,7 +1785,7 @@ ConstExprFunctionState::evaluateFlowSensitive(SILInstruction *inst) { return None; // Conditional fail actually failed. return evaluator.getUnknown( - (SILInstruction *)inst, + inst->asSILNode(), UnknownReason::createTrap( (Twine("trap: ") + condFail->getMessage()).str(), evaluator.getAllocator())); @@ -1866,7 +1855,8 @@ ConstExprFunctionState::evaluateFlowSensitive(SILInstruction *inst) { LLVM_DEBUG(llvm::dbgs() << "ConstExpr Unknown FS: " << *inst << "\n"); // If this is an unknown instruction with no results then bail out. - return getUnknown(evaluator, inst, UnknownReason::UnsupportedInstruction); + return getUnknown(evaluator, inst->asSILNode(), + UnknownReason::UnsupportedInstruction); } std::pair, Optional> @@ -1985,8 +1975,8 @@ ConstExprFunctionState::evaluateInstructionAndGetNext( DynamicCastFeasibility castResult = classifyDynamicCast( inst->getModule().getSwiftModule(), sourceType, targetType); if (castResult == DynamicCastFeasibility::MaySucceed) { - return {None, - getUnknown(evaluator, inst, UnknownReason::UnknownCastResult)}; + return {None, getUnknown(evaluator, inst->asSILNode(), + UnknownReason::UnknownCastResult)}; } // Determine the basic block to jump to. SILBasicBlock *resultBB = @@ -2007,8 +1997,8 @@ ConstExprFunctionState::evaluateInstructionAndGetNext( LLVM_DEBUG(llvm::dbgs() << "ConstExpr: Unknown Branch Instruction: " << *inst << "\n"); - return {None, - getUnknown(evaluator, inst, UnknownReason::UnsupportedInstruction)}; + return {None, getUnknown(evaluator, inst->asSILNode(), + UnknownReason::UnsupportedInstruction)}; } /// Evaluate a call to the specified function as if it were a constant @@ -2054,7 +2044,8 @@ evaluateAndCacheCall(SILFunction &fn, SubstitutionMap substitutionMap, // Make sure we haven't exceeded our interpreter iteration cap. if (++numInstEvaluated > ConstExprLimit) { - return getUnknown(evaluator, inst, UnknownReason::TooManyInstructions); + return getUnknown(evaluator, inst->asSILNode(), + UnknownReason::TooManyInstructions); } if (isa(inst)) { @@ -2205,7 +2196,7 @@ ConstExprStepEvaluator::skipByMakingEffectsNonConstant( SmallVector accessPath; auto *memoryObject = constVal.getAddressValue(accessPath); auto unknownValue = SymbolicValue::getUnknown( - inst, + inst->asSILNode(), UnknownReason::create(UnknownReason::MutatedByUnevaluatedInstruction), {}, evaluator.getAllocator()); @@ -2222,7 +2213,7 @@ ConstExprStepEvaluator::skipByMakingEffectsNonConstant( for (auto result : inst->getResults()) { internalState->setValue( result, SymbolicValue::getUnknown( - inst, + inst->asSILNode(), UnknownReason::create( UnknownReason::ReturnedByUnevaluatedInstruction), {}, evaluator.getAllocator())); diff --git a/lib/SILOptimizer/Utils/LoadStoreOptUtils.cpp b/lib/SILOptimizer/Utils/LoadStoreOptUtils.cpp index e319d0bf6d0ec..dd96084f69954 100644 --- a/lib/SILOptimizer/Utils/LoadStoreOptUtils.cpp +++ b/lib/SILOptimizer/Utils/LoadStoreOptUtils.cpp @@ -120,7 +120,7 @@ void LSValue::reduceInner(LSLocation &Base, SILModule *M, Builder, RegularLocation::getAutoGeneratedLocation(), Base.getType(M, context).getObjectType(), Vals); - auto AvailVal = makeNewValueAvailable(AI.get(), InsertPt->getParentBlock(), + auto AvailVal = makeNewValueAvailable(AI.get(), InsertPt->getParent(), jointPostDomComputer); // This is the Value for the current base.