On Sat, Jun 1, 2019 at 5:49 PM Richard Sandiford
<[email protected]> wrote:
>
> Taking the address of a variable stops us doing var-tracking on it,
> so that we just use the DECL_RTL instead. This can easily cause wrong
> debug info for regions of code that would have had correct debug info
> if the variable weren't addressable. E.g.:
>
> {
> int base;
> get_start (&base);
> x[i1] = base;
> base += 1; // No need to store this
> x[i2] = base; // ...so the debug info for "base" is wrong here
> }
>
> or (the motivating example):
>
> {
> int base;
> get_start (&base);
> for (int i = 0; i < n; ++i)
> {
> x[i] = base;
> base += y[i]; // Can apply LSM here, so the debug info for "base"
> // in the loop is wrong
> }
> consume (&base);
> }
>
> This patch series lets us use the DECL_RTL location for some parts of a
> variable's lifetime and debug-bind locations for other parts:
>
> 1) Gimple uses "VAR s=> VAR" to bind VAR to its DECL_RTL. The binding
> holds until overridden.
>
> 2) RTL does the same thing using:
>
> (var_location VAR (decl_rtl_ref VAR))
>
> where DECL_RTL_REF is a new rtx code that captures the DECL_RTL
> by reference rather than by value.
>
> We can't just use "(var_location VAR (mem X))" for this, because
> that would bind VAR to the value that (mem X) has at that exact point.
> VAR would therefore get reset by any possible change to (mem X),
> whereas here we want it to track (possibly indirect) updates instead.
>
> 3) The gimplifier decides which variables should get the new treatment
> and emits "VAR s=> VAR" to mark the start of VAR's lifetime.
> Clobbers continue to mark the end of VAR's lifetime.
>
> 4) Stores to VAR implicitly reestablish the link between VAR and its
> DECL_RTL. This is simpler (and IMO more robust) than inserting an
> explicit "VAR s=> VAR" at every write.
>
> 5) gsi_remove tries to insert "VAR => X" in place of a deleted "VAR = X",
> falling back to a "VAR => NULL" reset if that fails.
>
> Patch 1 handles the new rtl code, patch 2 adds the gimple framework,
> and patch 3 uses it for LSM.
So I wonder how it handles
void __attribute__((noinline)) foo(int *p) { *p = 42; }
int x;
int main()
{
int base = 1;
foo (&base);
base = 2;
*(x ? &x : &base) = 1; // (*)
return 0;
}
here we DSE the base = 2 store leaving a
# DEBUG base = 2
stmt? But there's an indirect store that also stores
to base - what will the debug info say at/after (*)? Will
it claim that base is 2? At least I do not see that
the connection with bases DECL_RTL is re-established?
There's a clobber of base before return 0 so you eventually
have to add some dummy stmt you can print base after
the indirect store.
That said, doesn't "aliasing" create another source of wrong-debug
with your approach that might be even worse?
Otherwise the patches look reasonable.
Richard.
> Bootstrapped & regtested on aarch64-linux-gnu and x86_64-linux-gnu.
> OK to install?
>
> Richard