DebugScope Verification Error

Hi,

I am running into a debug scope SIL Verifier error when creating a new
function (NF) from an existing one (F). Can someone point me where I am
going wrong?

NF = M.createFunction(...., F->getDebugScope());
SILBasicBlock *NFBody = NF->createBasicBlock();
SILBuilder NFBuilder(NFBody);
SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
...
for (auto &param : params) { /* Assume all are generic types */
  auto GenericsSILType = ....
  auto NewArg = NFBody->createFunctionArgument(GenericSILType);
  auto Conformances = Mod->lookupConformance(...);
  auto *InitRef = NFBuilder.createInitExistentialRef( Loc,
ArgDesc.Arg->getType(),
NewArg->getType().getSwiftRValueType()->getCanonicalType(), NewArg,
Conformances);
  ...
}

The InitRef instruction created above runs into SIL verifier error:

SIL verification failed: debug scope of instruction belongs to a different
function: !DS || DS->getParentFunction() == I->getFunction()
Verifying instruction:
   %0 = argument of bb0 : $τ_0_0 // user: %1
-> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol // user:
%2

The SIL looks correct to me though.

--Raj

I’d suggest looking at SILCloner.h as well as ScopeCloner in SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

···

On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev <swift-dev@swift.org> wrote:

Hi,

I am running into a debug scope SIL Verifier error when creating a new function (NF) from an existing one (F). Can someone point me where I am going wrong?

NF = M.createFunction(...., F->getDebugScope());
SILBasicBlock *NFBody = NF->createBasicBlock();
SILBuilder NFBuilder(NFBody);
SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
...
for (auto &param : params) { /* Assume all are generic types */
  auto GenericsSILType = ....
  auto NewArg = NFBody->createFunctionArgument(GenericSILType);
  auto Conformances = Mod->lookupConformance(...);
  auto *InitRef = NFBuilder.createInitExistentialRef( Loc, ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(), NewArg, Conformances);
  ...
}

The InitRef instruction created above runs into SIL verifier error:

SIL verification failed: debug scope of instruction belongs to a different function: !DS || DS->getParentFunction() == I->getFunction()
Verifying instruction:
   %0 = argument of bb0 : $τ_0_0 // user: %1
-> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol // user: %2

The SIL looks correct to me though.

--Raj
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Mark,

Thanks a lot for quick reply.

Is there any reason this interface in SILInstruction should be private?
void setDebugScope(SILBuilder &B, const SILDebugScope *DS);

In my case, I am splicing the old F into the new function NF. While
splicing retains the debug scope, the new instruction (InitRef) that I am
adding to NF is being created in some random scope (not F) even though I
explicitly make Builder's debug scope point to F's.

Best,
Raj

···

On Mon, Jan 15, 2018 at 9:52 AM, Mark Lacey <mark.lacey@apple.com> wrote:

I’d suggest looking at SILCloner.h as well as ScopeCloner in
SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

> On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev < > swift-dev@swift.org> wrote:
>
> Hi,
>
> I am running into a debug scope SIL Verifier error when creating a new
function (NF) from an existing one (F). Can someone point me where I am
going wrong?
>
> NF = M.createFunction(...., F->getDebugScope());
> SILBasicBlock *NFBody = NF->createBasicBlock();
> SILBuilder NFBuilder(NFBody);
> SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
> NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
> NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
> ...
> for (auto &param : params) { /* Assume all are generic types */
> auto GenericsSILType = ....
> auto NewArg = NFBody->createFunctionArgument(GenericSILType);
> auto Conformances = Mod->lookupConformance(...);
> auto *InitRef = NFBuilder.createInitExistentialRef( Loc,
ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(),
NewArg, Conformances);
> ...
> }
>
> The InitRef instruction created above runs into SIL verifier error:
>
> SIL verification failed: debug scope of instruction belongs to a
different function: !DS || DS->getParentFunction() == I->getFunction()
> Verifying instruction:
> %0 = argument of bb0 : $τ_0_0 // user: %1
> -> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol //
user: %2
>
> The SIL looks correct to me though.
>
> --Raj
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

Mark,

Thanks a lot for quick reply.

Is there any reason this interface in SILInstruction should be private?
void setDebugScope(SILBuilder &B, const SILDebugScope *DS);

In my case, I am splicing the old F into the new function NF. While splicing retains the debug scope, the new instruction (InitRef) that I am adding to NF is being created in some random scope (not F) even though I explicitly make Builder's debug scope point to F's.

The assert you originally hit appears to indicate that the parentFunction of the debug scope for an instruction should be the same as the function the instruction is in. I am not very familiar with the requirements of our debug information and debug scopes, but this seems like a reasonable expectation.

I suggested looking at SILCloner because it is the primary way by which we clone functions, and clearly has to deal with debug scopes when it does so.

I’m not sure how much more help I can be on this matter, but perhaps someone more knowledgable can chime in.

Mark

···

On Jan 15, 2018, at 12:54 PM, Raj Barik <rkbarik@gmail.com> wrote:

Best,
Raj

On Mon, Jan 15, 2018 at 9:52 AM, Mark Lacey <mark.lacey@apple.com <mailto:mark.lacey@apple.com>> wrote:
I’d suggest looking at SILCloner.h as well as ScopeCloner in SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

> On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>
> Hi,
>
> I am running into a debug scope SIL Verifier error when creating a new function (NF) from an existing one (F). Can someone point me where I am going wrong?
>
> NF = M.createFunction(...., F->getDebugScope());
> SILBasicBlock *NFBody = NF->createBasicBlock();
> SILBuilder NFBuilder(NFBody);
> SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
> NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
> NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
> ...
> for (auto &param : params) { /* Assume all are generic types */
> auto GenericsSILType = ....
> auto NewArg = NFBody->createFunctionArgument(GenericSILType);
> auto Conformances = Mod->lookupConformance(...);
> auto *InitRef = NFBuilder.createInitExistentialRef( Loc, ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(), NewArg, Conformances);
> ...
> }
>
> The InitRef instruction created above runs into SIL verifier error:
>
> SIL verification failed: debug scope of instruction belongs to a different function: !DS || DS->getParentFunction() == I->getFunction()
> Verifying instruction:
> %0 = argument of bb0 : $τ_0_0 // user: %1
> -> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol // user: %2
>
> The SIL looks correct to me though.
>
> --Raj
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org <mailto:swift-dev@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-dev

Thanks Mark. You are right, the following assertion fails

require(!DS || DS->getParentFunction() == I->getFunction(),
            "debug scope of instruction belongs to a different function");

I am not sure if we need such a check.

···

On Mon, Jan 15, 2018 at 4:16 PM, Mark Lacey <mark.lacey@apple.com> wrote:

On Jan 15, 2018, at 12:54 PM, Raj Barik <rkbarik@gmail.com> wrote:

Mark,

Thanks a lot for quick reply.

Is there any reason this interface in SILInstruction should be private?
void setDebugScope(SILBuilder &B, const SILDebugScope *DS);

In my case, I am splicing the old F into the new function NF. While
splicing retains the debug scope, the new instruction (InitRef) that I am
adding to NF is being created in some random scope (not F) even though I
explicitly make Builder's debug scope point to F's.

The assert you originally hit appears to indicate that the parentFunction
of the debug scope for an instruction should be the same as the function
the instruction is in. I am not very familiar with the requirements of our
debug information and debug scopes, but this seems like a reasonable
expectation.

I suggested looking at SILCloner because it is the primary way by which we
clone functions, and clearly has to deal with debug scopes when it does so.

I’m not sure how much more help I can be on this matter, but perhaps
someone more knowledgable can chime in.

Mark

Best,
Raj

On Mon, Jan 15, 2018 at 9:52 AM, Mark Lacey <mark.lacey@apple.com> wrote:

I’d suggest looking at SILCloner.h as well as ScopeCloner in
SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

> On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev < >> swift-dev@swift.org> wrote:
>
> Hi,
>
> I am running into a debug scope SIL Verifier error when creating a new
function (NF) from an existing one (F). Can someone point me where I am
going wrong?
>
> NF = M.createFunction(...., F->getDebugScope());
> SILBasicBlock *NFBody = NF->createBasicBlock();
> SILBuilder NFBuilder(NFBody);
> SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
> NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
> NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
> ...
> for (auto &param : params) { /* Assume all are generic types */
> auto GenericsSILType = ....
> auto NewArg = NFBody->createFunctionArgument(GenericSILType);
> auto Conformances = Mod->lookupConformance(...);
> auto *InitRef = NFBuilder.createInitExistentialRef( Loc,
ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(),
NewArg, Conformances);
> ...
> }
>
> The InitRef instruction created above runs into SIL verifier error:
>
> SIL verification failed: debug scope of instruction belongs to a
different function: !DS || DS->getParentFunction() == I->getFunction()
> Verifying instruction:
> %0 = argument of bb0 : $τ_0_0 // user: %1
> -> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol //
user: %2
>
> The SIL looks correct to me though.
>
> --Raj
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

+ Adrian and Davide, since they work in this area.

Hi Raj,

Thanks Mark. You are right, the following assertion fails

require(!DS || DS->getParentFunction() == I->getFunction(),
            "debug scope of instruction belongs to a different function");

I am not sure if we need such a check.

This check exists to ensure that the debug info generated for a program is helpful. For example, a function with the wrong debug scope attached might make for confusing backtraces.

vedant

···

On Jan 15, 2018, at 4:48 PM, Raj Barik via swift-dev <swift-dev@swift.org> wrote:

On Mon, Jan 15, 2018 at 4:16 PM, Mark Lacey <mark.lacey@apple.com <mailto:mark.lacey@apple.com>> wrote:

On Jan 15, 2018, at 12:54 PM, Raj Barik <rkbarik@gmail.com <mailto:rkbarik@gmail.com>> wrote:

Mark,

Thanks a lot for quick reply.

Is there any reason this interface in SILInstruction should be private?
void setDebugScope(SILBuilder &B, const SILDebugScope *DS);

In my case, I am splicing the old F into the new function NF. While splicing retains the debug scope, the new instruction (InitRef) that I am adding to NF is being created in some random scope (not F) even though I explicitly make Builder's debug scope point to F's.

The assert you originally hit appears to indicate that the parentFunction of the debug scope for an instruction should be the same as the function the instruction is in. I am not very familiar with the requirements of our debug information and debug scopes, but this seems like a reasonable expectation.

I suggested looking at SILCloner because it is the primary way by which we clone functions, and clearly has to deal with debug scopes when it does so.

I’m not sure how much more help I can be on this matter, but perhaps someone more knowledgable can chime in.

Mark

Best,
Raj

On Mon, Jan 15, 2018 at 9:52 AM, Mark Lacey <mark.lacey@apple.com <mailto:mark.lacey@apple.com>> wrote:
I’d suggest looking at SILCloner.h as well as ScopeCloner in SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

> On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>
> Hi,
>
> I am running into a debug scope SIL Verifier error when creating a new function (NF) from an existing one (F). Can someone point me where I am going wrong?
>
> NF = M.createFunction(...., F->getDebugScope());
> SILBasicBlock *NFBody = NF->createBasicBlock();
> SILBuilder NFBuilder(NFBody);
> SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
> NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
> NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
> ...
> for (auto &param : params) { /* Assume all are generic types */
> auto GenericsSILType = ....
> auto NewArg = NFBody->createFunctionArgument(GenericSILType);
> auto Conformances = Mod->lookupConformance(...);
> auto *InitRef = NFBuilder.createInitExistentialRef( Loc, ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(), NewArg, Conformances);
> ...
> }
>
> The InitRef instruction created above runs into SIL verifier error:
>
> SIL verification failed: debug scope of instruction belongs to a different function: !DS || DS->getParentFunction() == I->getFunction()
> Verifying instruction:
> %0 = argument of bb0 : $τ_0_0 // user: %1
> -> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol // user: %2
>
> The SIL looks correct to me though.
>
> --Raj
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org <mailto:swift-dev@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

+ Adrian and Davide, since they work in this area.

Hi Raj,

Thanks Mark. You are right, the following assertion fails

require(!DS || DS->getParentFunction() == I->getFunction(),
            "debug scope of instruction belongs to a different function");

I am not sure if we need such a check.

This check exists to ensure that the debug info generated for a program is helpful. For example, a function with the wrong debug scope attached might make for confusing backtraces.

It's more than just confusing backtraces. If these invariants aren't met the LLVM IR generated from this SIL will not pass the LLVM IR verifier or in older versions even crash LLVM.

The constraint being checked in this assertion is that each instruction must be in a lexical scope whose top-level ancestor is the function itself. I.e., it is not legal to move an instruction from one function to another with updating that instruction's debug information by either reparenting it into the new function or by creating inline information for it. SILClonerWithScope implements this re-parenting of instructions into a new function for you.

-- adrian

···

On Jan 16, 2018, at 1:20 PM, Vedant Kumar <vsk@apple.com> wrote:

On Jan 15, 2018, at 4:48 PM, Raj Barik via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

vedant

On Mon, Jan 15, 2018 at 4:16 PM, Mark Lacey <mark.lacey@apple.com <mailto:mark.lacey@apple.com>> wrote:

On Jan 15, 2018, at 12:54 PM, Raj Barik <rkbarik@gmail.com <mailto:rkbarik@gmail.com>> wrote:

Mark,

Thanks a lot for quick reply.

Is there any reason this interface in SILInstruction should be private?
void setDebugScope(SILBuilder &B, const SILDebugScope *DS);

In my case, I am splicing the old F into the new function NF. While splicing retains the debug scope, the new instruction (InitRef) that I am adding to NF is being created in some random scope (not F) even though I explicitly make Builder's debug scope point to F's.

The assert you originally hit appears to indicate that the parentFunction of the debug scope for an instruction should be the same as the function the instruction is in. I am not very familiar with the requirements of our debug information and debug scopes, but this seems like a reasonable expectation.

I suggested looking at SILCloner because it is the primary way by which we clone functions, and clearly has to deal with debug scopes when it does so.

I’m not sure how much more help I can be on this matter, but perhaps someone more knowledgable can chime in.

Mark

Best,
Raj

On Mon, Jan 15, 2018 at 9:52 AM, Mark Lacey <mark.lacey@apple.com <mailto:mark.lacey@apple.com>> wrote:
I’d suggest looking at SILCloner.h as well as ScopeCloner in SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

> On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>
> Hi,
>
> I am running into a debug scope SIL Verifier error when creating a new function (NF) from an existing one (F). Can someone point me where I am going wrong?
>
> NF = M.createFunction(...., F->getDebugScope());
> SILBasicBlock *NFBody = NF->createBasicBlock();
> SILBuilder NFBuilder(NFBody);
> SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
> NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
> NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
> ...
> for (auto &param : params) { /* Assume all are generic types */
> auto GenericsSILType = ....
> auto NewArg = NFBody->createFunctionArgument(GenericSILType);
> auto Conformances = Mod->lookupConformance(...);
> auto *InitRef = NFBuilder.createInitExistentialRef( Loc, ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(), NewArg, Conformances);
> ...
> }
>
> The InitRef instruction created above runs into SIL verifier error:
>
> SIL verification failed: debug scope of instruction belongs to a different function: !DS || DS->getParentFunction() == I->getFunction()
> Verifying instruction:
> %0 = argument of bb0 : $τ_0_0 // user: %1
> -> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol // user: %2
>
> The SIL looks correct to me though.
>
> --Raj
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org <mailto:swift-dev@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

Thanks a lot for the clarification Adrain and Vedant.

What confused me is the cycle -- A SILFunction has a DeubgScope and the
DebugScope points back to the SILFunction. During moving instructions
across functions, one can easily mess up the pointers. As you all pointed
out, one needs to also use ScopeCloner to get around this problem.

Does it make sense not to have the cycle, i.e., DebugScopes are made
independent of SILFunction so that multiple SILFunction(s) can share the
same DebugScope?

···

On Tue, Jan 16, 2018 at 1:26 PM, Adrian Prantl <aprantl@apple.com> wrote:

On Jan 16, 2018, at 1:20 PM, Vedant Kumar <vsk@apple.com> wrote:

+ Adrian and Davide, since they work in this area.

Hi Raj,

On Jan 15, 2018, at 4:48 PM, Raj Barik via swift-dev <swift-dev@swift.org> > wrote:

Thanks Mark. You are right, the following assertion fails

require(!DS || DS->getParentFunction() == I->getFunction(),
            "debug scope of instruction belongs to a different function");

I am not sure if we need such a check.

This check exists to ensure that the debug info generated for a program is
helpful. For example, a function with the wrong debug scope attached might
make for confusing backtraces.

It's more than just confusing backtraces. If these invariants aren't met
the LLVM IR generated from this SIL will not pass the LLVM IR verifier or
in older versions even crash LLVM.

The constraint being checked in this assertion is that each instruction
must be in a lexical scope whose top-level ancestor is the function itself.
I.e., it is not legal to move an instruction from one function to another
with updating that instruction's debug information by either reparenting it
into the new function or by creating inline information for it.
SILClonerWithScope implements this re-parenting of instructions into a new
function for you.

-- adrian

vedant

On Mon, Jan 15, 2018 at 4:16 PM, Mark Lacey <mark.lacey@apple.com> wrote:

On Jan 15, 2018, at 12:54 PM, Raj Barik <rkbarik@gmail.com> wrote:

Mark,

Thanks a lot for quick reply.

Is there any reason this interface in SILInstruction should be private?
void setDebugScope(SILBuilder &B, const SILDebugScope *DS);

In my case, I am splicing the old F into the new function NF. While
splicing retains the debug scope, the new instruction (InitRef) that I am
adding to NF is being created in some random scope (not F) even though I
explicitly make Builder's debug scope point to F's.

The assert you originally hit appears to indicate that the parentFunction
of the debug scope for an instruction should be the same as the function
the instruction is in. I am not very familiar with the requirements of our
debug information and debug scopes, but this seems like a reasonable
expectation.

I suggested looking at SILCloner because it is the primary way by which
we clone functions, and clearly has to deal with debug scopes when it does
so.

I’m not sure how much more help I can be on this matter, but perhaps
someone more knowledgable can chime in.

Mark

Best,
Raj

On Mon, Jan 15, 2018 at 9:52 AM, Mark Lacey <mark.lacey@apple.com> wrote:

I’d suggest looking at SILCloner.h as well as ScopeCloner in
SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

> On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev < >>> swift-dev@swift.org> wrote:
>
> Hi,
>
> I am running into a debug scope SIL Verifier error when creating a new
function (NF) from an existing one (F). Can someone point me where I am
going wrong?
>
> NF = M.createFunction(...., F->getDebugScope());
> SILBasicBlock *NFBody = NF->createBasicBlock();
> SILBuilder NFBuilder(NFBody);
> SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
> NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
> NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
> ...
> for (auto &param : params) { /* Assume all are generic types */
> auto GenericsSILType = ....
> auto NewArg = NFBody->createFunctionArgument(GenericSILType);
> auto Conformances = Mod->lookupConformance(...);
> auto *InitRef = NFBuilder.createInitExistentialRef( Loc,
ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(),
NewArg, Conformances);
> ...
> }
>
> The InitRef instruction created above runs into SIL verifier error:
>
> SIL verification failed: debug scope of instruction belongs to a
different function: !DS || DS->getParentFunction() == I->getFunction()
> Verifying instruction:
> %0 = argument of bb0 : $τ_0_0 // user: %1
> -> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol //
user: %2
>
> The SIL looks correct to me though.
>
> --Raj
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Thanks a lot for the clarification Adrain and Vedant.

What confused me is the cycle -- A SILFunction has a DeubgScope and the DebugScope points back to the SILFunction. During moving instructions across functions, one can easily mess up the pointers. As you all pointed out, one needs to also use ScopeCloner to get around this problem.

Does it make sense not to have the cycle, i.e., DebugScopes are made independent of SILFunction so that multiple SILFunction(s) can share the same DebugScope?

SILDebugScopes are also the vehicle to represent inlining information. If you want to change the representation such that SILDebugScopes can be shared between functions, you will have to change how inline info is being represented. Representing it differently is definitely possibly, but you also have to redesign inline info along with it.

-- adrian

···

On Jan 16, 2018, at 1:49 PM, Raj Barik <rkbarik@gmail.com> wrote:

On Tue, Jan 16, 2018 at 1:26 PM, Adrian Prantl <aprantl@apple.com <mailto:aprantl@apple.com>> wrote:

On Jan 16, 2018, at 1:20 PM, Vedant Kumar <vsk@apple.com <mailto:vsk@apple.com>> wrote:

+ Adrian and Davide, since they work in this area.

Hi Raj,

On Jan 15, 2018, at 4:48 PM, Raj Barik via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Thanks Mark. You are right, the following assertion fails

require(!DS || DS->getParentFunction() == I->getFunction(),
            "debug scope of instruction belongs to a different function");

I am not sure if we need such a check.

This check exists to ensure that the debug info generated for a program is helpful. For example, a function with the wrong debug scope attached might make for confusing backtraces.

It's more than just confusing backtraces. If these invariants aren't met the LLVM IR generated from this SIL will not pass the LLVM IR verifier or in older versions even crash LLVM.

The constraint being checked in this assertion is that each instruction must be in a lexical scope whose top-level ancestor is the function itself. I.e., it is not legal to move an instruction from one function to another with updating that instruction's debug information by either reparenting it into the new function or by creating inline information for it. SILClonerWithScope implements this re-parenting of instructions into a new function for you.

-- adrian

vedant

On Mon, Jan 15, 2018 at 4:16 PM, Mark Lacey <mark.lacey@apple.com <mailto:mark.lacey@apple.com>> wrote:

On Jan 15, 2018, at 12:54 PM, Raj Barik <rkbarik@gmail.com <mailto:rkbarik@gmail.com>> wrote:

Mark,

Thanks a lot for quick reply.

Is there any reason this interface in SILInstruction should be private?
void setDebugScope(SILBuilder &B, const SILDebugScope *DS);

In my case, I am splicing the old F into the new function NF. While splicing retains the debug scope, the new instruction (InitRef) that I am adding to NF is being created in some random scope (not F) even though I explicitly make Builder's debug scope point to F's.

The assert you originally hit appears to indicate that the parentFunction of the debug scope for an instruction should be the same as the function the instruction is in. I am not very familiar with the requirements of our debug information and debug scopes, but this seems like a reasonable expectation.

I suggested looking at SILCloner because it is the primary way by which we clone functions, and clearly has to deal with debug scopes when it does so.

I’m not sure how much more help I can be on this matter, but perhaps someone more knowledgable can chime in.

Mark

Best,
Raj

On Mon, Jan 15, 2018 at 9:52 AM, Mark Lacey <mark.lacey@apple.com <mailto:mark.lacey@apple.com>> wrote:
I’d suggest looking at SILCloner.h as well as ScopeCloner in SILBasicBlock.cpp to see how they are dealing with debug scopes.

Mark

> On Jan 15, 2018, at 9:24 AM, Raj Barik via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>
> Hi,
>
> I am running into a debug scope SIL Verifier error when creating a new function (NF) from an existing one (F). Can someone point me where I am going wrong?
>
> NF = M.createFunction(...., F->getDebugScope());
> SILBasicBlock *NFBody = NF->createBasicBlock();
> SILBuilder NFBuilder(NFBody);
> SILOpenedArchetypesTracker OpenedArchetypesTrackerNF(NF);
> NFBuilder.setOpenedArchetypesTracker(&OpenedArchetypesTrackerNF);
> NFBuilder.setCurrentDebugScope(NFBody->getParent()->getDebugScope());
> ...
> for (auto &param : params) { /* Assume all are generic types */
> auto GenericsSILType = ....
> auto NewArg = NFBody->createFunctionArgument(GenericSILType);
> auto Conformances = Mod->lookupConformance(...);
> auto *InitRef = NFBuilder.createInitExistentialRef( Loc, ArgDesc.Arg->getType(), NewArg->getType().getSwiftRValueType()->getCanonicalType(), NewArg, Conformances);
> ...
> }
>
> The InitRef instruction created above runs into SIL verifier error:
>
> SIL verification failed: debug scope of instruction belongs to a different function: !DS || DS->getParentFunction() == I->getFunction()
> Verifying instruction:
> %0 = argument of bb0 : $τ_0_0 // user: %1
> -> %1 = init_existential_ref %0 : $τ_0_0 : $τ_0_0, $SomeProtocol // user: %2
>
> The SIL looks correct to me though.
>
> --Raj
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org <mailto:swift-dev@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev