Skip to content

Conversation

@MathiasVP
Copy link
Contributor

I was hacking on a solution to #8497 and was surprised to learn that Location.isBefore is really Location.lineIsBefore.

As an added bonus to this PR, this will improve our IR generation for code that uses gotos:

Currently, our only use of Location.isBefore predicate is to determine whether a goto statement creates a back edge in the control-flow graph. So on main, the following program:

int test() {
  int x = 42;
  goto next; next:

  return x;
}

gets translated as:

int test()
  Block 0
    v1_1(void)       = EnterFunction      :
    m1_2(unknown)    = AliasedDefinition  :
    m1_3(unknown)    = InitializeNonLocal :
    m1_4(unknown)    = Chi                : total:m1_2, partial:m1_3
    r2_1(glval<int>) = VariableAddress[x] :
    r2_2(int)        = Constant[42]       :
    m2_3(int)        = Store[x]           : &:r2_1, r2_2
    v3_1(void)       = NoOp               :
  Goto (back edge) -> Block 1

  Block 1
    v3_2(void)       = NoOp                     :
    r6_1(glval<int>) = VariableAddress[#return] :
    r6_2(glval<int>) = VariableAddress[x]       :
    r6_3(int)        = Load[x]                  : &:r6_2, m2_3
    m6_4(int)        = Store[#return]           : &:r6_1, r6_3
    r1_5(glval<int>) = VariableAddress[#return] :
    v1_6(void)       = ReturnValue              : &:r1_5, m6_4
    v1_7(void)       = AliasedUse               : m1_3
    v1_8(void)       = ExitFunction             :

i.e., we conservatively assume that the goto could be a back edge. However, with this PR the same code is translated as:

int test()
  Block 0
    v1_1(void)       = EnterFunction            :
    m1_2(unknown)    = AliasedDefinition        :
    m1_3(unknown)    = InitializeNonLocal       :
    m1_4(unknown)    = Chi                      : total:m1_2, partial:m1_3
    r2_1(glval<int>) = VariableAddress[x]       :
    r2_2(int)        = Constant[42]             :
    m2_3(int)        = Store[x]                 : &:r2_1, r2_2
    v3_1(void)       = NoOp                     :
    v3_2(void)       = NoOp                     :
    r6_1(glval<int>) = VariableAddress[#return] :
    r6_2(glval<int>) = VariableAddress[x]       :
    r6_3(int)        = Load[x]                  : &:r6_2, m2_3
    m6_4(int)        = Store[#return]           : &:r6_1, r6_3
    r1_5(glval<int>) = VariableAddress[#return] :
    v1_6(void)       = ReturnValue              : &:r1_5, m6_4
    v1_7(void)       = AliasedUse               : m1_3
    v1_8(void)       = ExitFunction             :

with no back edge!

I admit this is a bit of a niche case. But it's nice to see that it actually does have the intended effect.

@MathiasVP MathiasVP added the C++ label Mar 22, 2022
@MathiasVP MathiasVP requested a review from a team as a code owner March 22, 2022 10:35
@MathiasVP MathiasVP force-pushed the more-precise-is-before branch from 896d888 to fe0e970 Compare March 22, 2022 11:50
@MathiasVP
Copy link
Contributor Author

@geoffw0 convinced me that we shouldn't change the behavior of the existing predicate. So I've force-pushed a backward-compatible version.

I've changed IR generation so that it uses the new predicate to get the behavior I described in the PR description.

@jketema
Copy link
Contributor

jketema commented Mar 22, 2022

You might want to add the goto example to the IR tests?

@MathiasVP
Copy link
Contributor Author

You might want to add the goto example to the IR tests?

Good point! I'll do that.

@MathiasVP MathiasVP force-pushed the more-precise-is-before branch from fe0e970 to 93346a5 Compare March 22, 2022 12:17
@MathiasVP
Copy link
Contributor Author

Done. I did another force-push to insert the test in the right commit.

@MathiasVP MathiasVP added the no-change-note-required This PR does not need a change note label Mar 22, 2022
pragma[inline]
predicate isBefore(Location l) {
this.getFile() = l.getFile() and this.getEndLine() < l.getStartLine()
predicate isBefore(Location l) { isBefore(l, false) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shows a warning about an implicit this here. Should that be fixed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it really should. I'll add the explicit this, but I won't force-push the change since that will mess up the DCA run.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise this LGTM.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c35b385.

Copy link
Contributor

@jketema jketema left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@MathiasVP MathiasVP merged commit a81024a into github:main Mar 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C++ no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants