diff mbox

[09/29] add helper to test if a variable is "simple"

Message ID 20170816153455.97693-10-luc.vanoostenryck@gmail.com (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Luc Van Oostenryck Aug. 16, 2017, 3:34 p.m. UTC
Here by 'simple' we really mean 'worth of putting in a register'.

We select all scalar types as well as struct and unions with a
size not bigger than a long (register).

Global and static variables, variables which address have been
taken and volatiles variables are never selected.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 symbol.h | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Comments

Christopher Li Aug. 17, 2017, 7:19 a.m. UTC | #1
On Wed, Aug 16, 2017 at 11:34 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> Here by 'simple' we really mean 'worth of putting in a register'.
>
> We select all scalar types as well as struct and unions with a
> size not bigger than a long (register).
>
> Global and static variables, variables which address have been
> taken and volatiles variables are never selected.
>
> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
> ---
>  symbol.h | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
>
> diff --git a/symbol.h b/symbol.h
> index 327449611..3f075c5bc 100644
> --- a/symbol.h
> +++ b/symbol.h
> @@ -407,6 +407,39 @@ static inline int is_scalar_type(struct symbol *type)
>         return 0;
>  }
>
> +static inline int is_simple_type(struct symbol *type)
...
> +       case SYM_STRUCT:
> +       case SYM_UNION:
> +               return type->bit_size <= long_ctype.bit_size;

I think the function name should be some thing along the
line of "type fits register" or is_registerable_type.

union and struct are composite types. It is a bit
confusing calling them simple, if some one just looking
at the code without look at the commit message.


Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dibyendu Majumdar Aug. 17, 2017, 4:59 p.m. UTC | #2
Hi Chris,

On 17 August 2017 at 08:19, Christopher Li <sparse@chrisli.org> wrote:
> On Wed, Aug 16, 2017 at 11:34 AM, Luc Van Oostenryck
> <luc.vanoostenryck@gmail.com> wrote:
>> Here by 'simple' we really mean 'worth of putting in a register'.
>>
>> We select all scalar types as well as struct and unions with a
>> size not bigger than a long (register).
>>
>> Global and static variables, variables which address have been
>> taken and volatiles variables are never selected.
>>
>> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
>> ---
>>  symbol.h | 33 +++++++++++++++++++++++++++++++++
>>  1 file changed, 33 insertions(+)
>>
>> diff --git a/symbol.h b/symbol.h
>> index 327449611..3f075c5bc 100644
>> --- a/symbol.h
>> +++ b/symbol.h
>> @@ -407,6 +407,39 @@ static inline int is_scalar_type(struct symbol *type)
>>         return 0;
>>  }
>>
>> +static inline int is_simple_type(struct symbol *type)
> ...
>> +       case SYM_STRUCT:
>> +       case SYM_UNION:
>> +               return type->bit_size <= long_ctype.bit_size;
>
> I think the function name should be some thing along the
> line of "type fits register" or is_registerable_type.
>
> union and struct are composite types. It is a bit
> confusing calling them simple, if some one just looking
> at the code without look at the commit message.
>

Apart from that I faced a problem with this and had to disable
STRUCT/UNION from being treated as simple types.

The problem was when generating LLVM output for
https://github.com/dibyendumajumdar/dmr_c/blob/master/tests/eic/testcbrt.c.
I will investigate more and report back my findings.

Meanwhile I would be interested to see the results of a test with above.

Regards
Dibyendu
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 17, 2017, 7:14 p.m. UTC | #3
On Thu, Aug 17, 2017 at 9:19 AM, Christopher Li <sparse@chrisli.org> wrote:
>>
>> +static inline int is_simple_type(struct symbol *type)
> ...
>> +       case SYM_STRUCT:
>> +       case SYM_UNION:
>> +               return type->bit_size <= long_ctype.bit_size;
>
> I think the function name should be some thing along the
> line of "type fits register" or is_registerable_type.
>
> union and struct are composite types. It is a bit
> confusing calling them simple, if some one just looking
> at the code without look at the commit message.

I agree it's confusing, and yes I would like a better name.
OTOH 'registrable' is not exactly the conveyed meaning.
'register' is a concept that pertains to the backend, that
is machine specific, a pseudo may need several registers
and a register can hold several pseudos, ...

Here what we really want to select is something along:
'it's interesting to see it as a flow of value' vs.
'it's better to see it as a change in state'.
And yes, very often that just correspond to registers.

Note: it's not even 'what can be put in a pseudo(-register)'
          were selecting here. It's OK to have pseudos for
          'non-simple' values, They will just be transient and we
          won't be interested in their 'flow'.

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 17, 2017, 7:17 p.m. UTC | #4
On Thu, Aug 17, 2017 at 6:59 PM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
>
> Apart from that I faced a problem with this and had to disable
> STRUCT/UNION from being treated as simple types.

That's only a problem/a limitation of your backend.

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dibyendu Majumdar Aug. 17, 2017, 7:21 p.m. UTC | #5
Hi Luc,

On 17 August 2017 at 20:17, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Thu, Aug 17, 2017 at 6:59 PM, Dibyendu Majumdar
> <mobile@majumdar.org.uk> wrote:
>>
>> Apart from that I faced a problem with this and had to disable
>> STRUCT/UNION from being treated as simple types.
>
> That's only a problem/a limitation of your backend.
>

Possibly - I haven't checked yet. Are you able to generate code / and
run the test case using your LLVM backend?

Regards
Dibyendu
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 17, 2017, 7:25 p.m. UTC | #6
On Thu, Aug 17, 2017 at 9:21 PM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
>>> Apart from that I faced a problem with this and had to disable
>>> STRUCT/UNION from being treated as simple types.
>>
>> That's only a problem/a limitation of your backend.
>>
>
> Possibly - I haven't checked yet. Are you able to generate code / and
> run the test case using your LLVM backend?

Possibly not but you're the only use of the LLVM backend, so it's yours ;)

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dibyendu Majumdar Aug. 17, 2017, 7:28 p.m. UTC | #7
Hi Luc,

On 17 August 2017 at 20:25, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> On Thu, Aug 17, 2017 at 9:21 PM, Dibyendu Majumdar
> <mobile@majumdar.org.uk> wrote:
>>>> Apart from that I faced a problem with this and had to disable
>>>> STRUCT/UNION from being treated as simple types.
>>>
>>> That's only a problem/a limitation of your backend.
>>>
>>
>> Possibly - I haven't checked yet. Are you able to generate code / and
>> run the test case using your LLVM backend?
>
> Possibly not but you're the only use of the LLVM backend, so it's yours ;)
>

I will check at my end and revert with my thoughts.

But I would have preferred if the SSA change was like for like
initially - rather than introducing new breaking changes. That should
ideally come as patches later on.

Regards
Dibyendu
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 17, 2017, 7:51 p.m. UTC | #8
On Thu, Aug 17, 2017 at 6:59 PM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
>
> Apart from that I faced a problem with this and had to disable
> STRUCT/UNION from being treated as simple types.
>
> The problem was when generating LLVM output for
> https://github.com/dibyendumajumdar/dmr_c/blob/master/tests/eic/testcbrt.c.
> I will investigate more and report back my findings.

There is indeed a problem with this case. It seems there is a mixup
with types somewhere and sparse-llvm needs a few lines more.

I'll look at it in the following days.

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Christopher Li Aug. 18, 2017, 4:13 p.m. UTC | #9
On Thu, Aug 17, 2017 at 3:14 PM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
>
> I agree it's confusing, and yes I would like a better name.
> OTOH 'registrable' is not exactly the conveyed meaning.
> 'register' is a concept that pertains to the backend, that
> is machine specific, a pseudo may need several registers
> and a register can hold several pseudos, ...

Sure, I saw your new name some thing like promote-able.
That is good.

>
> Here what we really want to select is something along:
> 'it's interesting to see it as a flow of value' vs.
> 'it's better to see it as a change in state'.
> And yes, very often that just correspond to registers.
>
> Note: it's not even 'what can be put in a pseudo(-register)'
>           were selecting here. It's OK to have pseudos for
>           'non-simple' values, They will just be transient and we
>           won't be interested in their 'flow'.

We need to be very careful about composite type pointer alias.
Any pointer alias to the member of the struct need to take
into account as well.

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Christopher Li Aug. 18, 2017, 4:18 p.m. UTC | #10
On Thu, Aug 17, 2017 at 3:28 PM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
>
> I will check at my end and revert with my thoughts.
>
> But I would have preferred if the SSA change was like for like
> initially - rather than introducing new breaking changes. That should
> ideally come as patches later on.

I just realized another side effect of doing the SSA conversion on
the AST directly. It means we will not have access to the linearization
byte code before promoting the memory variable to pseudo.

If you are depending on that pre-simplified byte code, then you don't
have a choice not do it. Maybe later on we can consider an option to
avoid doing the SSA conversion on memory variable as an option.

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 18, 2017, 4:26 p.m. UTC | #11
On Fri, Aug 18, 2017 at 6:13 PM, Christopher Li <sparse@chrisli.org> wrote:
>>
>> Note: it's not even 'what can be put in a pseudo(-register)'
>>           were selecting here. It's OK to have pseudos for
>>           'non-simple' values, They will just be transient and we
>>           won't be interested in their 'flow'.
>
> We need to be very careful about composite type pointer alias.

There are only pointer aliases if there are pointers. Here, we're only
interested in local variables.

But, and thanks to this remarks, I added a test and realized that
contrary to what I thought, the MOD_ADDRESSABLE is *not*
propagated from member to parent. So for the moment, I'll need
to drop this and only look at pure scalar variables. It's annoying.

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 18, 2017, 4:38 p.m. UTC | #12
On Fri, Aug 18, 2017 at 6:18 PM, Christopher Li <sparse@chrisli.org> wrote:
>
> I just realized another side effect of doing the SSA conversion on
> the AST directly. It means we will not have access to the linearization
> byte code before promoting the memory variable to pseudo.

Of course.
But consider the other side: it means that you already have already
a lot of variables promoted to pseudo *while* doing the linearization.
It means that you already can know quite a bit about the 'values'
during linearization and avoid to generate code that will be thrown
away soon after being created.

> Maybe later on we can consider an option to
> avoid doing the SSA conversion on memory variable as an option.

Sure, but it's a serious research topic too.
Lots can be done. A few things are easy and cheap, most are quite
complex and expensive.

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dibyendu Majumdar Aug. 18, 2017, 6:15 p.m. UTC | #13
Hi Chris,

On 18 August 2017 at 17:18, Christopher Li <sparse@chrisli.org> wrote:
> On Thu, Aug 17, 2017 at 3:28 PM, Dibyendu Majumdar
> <mobile@majumdar.org.uk> wrote:
>>
>> I will check at my end and revert with my thoughts.
>>
>> But I would have preferred if the SSA change was like for like
>> initially - rather than introducing new breaking changes. That should
>> ideally come as patches later on.
>
> I just realized another side effect of doing the SSA conversion on
> the AST directly. It means we will not have access to the linearization
> byte code before promoting the memory variable to pseudo.
>
> If you are depending on that pre-simplified byte code, then you don't
> have a choice not do it. Maybe later on we can consider an option to
> avoid doing the SSA conversion on memory variable as an option.
>

I have it setup so that if optimization is switched off I skip the CSE
/ Flow Simplification steps. In the older version the
simplify_symbol_usage() was also being skipped but that is not used
now. (Although the way I have merged this - I have the old code still
there, and I can switch between the two implementations using a
#define).

As all my LLVM tests pass in this setup this is fine right now. I
still get failures in some cases when the other subsequent stages are
enabled - so there must be some incorrect simplifications occurring
somewhere. I do not yet have specific tests to track down where the
issues are.

As I mentioned before - ideally it would be good have a SSA step that
is reusable. Then you could run this step several times during the
process - and allow some simplification phases to generate non SSA
code. Perhaps the new SSA approach can be adapted for this. This would
also allow access to the first pass linearized output without
promotion to pseudos.

But this should not stop us from moving forward with this change - as
I think the SSA hooks into the linearization step are pretty specific
and it should be relatively easy to have a mode where those steps are
"dummied" - i.e. do nothing.

I have a question though. For my other backend I need liveness
analysis done even if I skip the other steps. Is it okay to run the
liveness analysis phase while skipping the CSE / Flow simplification
phases?

Regards
Dibyendu
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Christopher Li Aug. 18, 2017, 6:35 p.m. UTC | #14
On Fri, Aug 18, 2017 at 2:15 PM, Dibyendu Majumdar
<mobile@majumdar.org.uk> wrote:
> I have it setup so that if optimization is switched off I skip the CSE
> / Flow Simplification steps. In the older version the
> simplify_symbol_usage() was also being skipped but that is not used
> now. (Although the way I have merged this - I have the old code still
> there, and I can switch between the two implementations using a
> #define).
>
> As all my LLVM tests pass in this setup this is fine right now. I
> still get failures in some cases when the other subsequent stages are
> enabled - so there must be some incorrect simplifications occurring
> somewhere. I do not yet have specific tests to track down where the
> issues are.

At the point the SSA code is not merge yet. After we merger it.
report back if you found some issue using the llvm back end.

>
> As I mentioned before - ideally it would be good have a SSA step that
> is reusable. Then you could run this step several times during the
> process - and allow some simplification phases to generate non SSA
> code. Perhaps the new SSA approach can be adapted for this. This would
> also allow access to the first pass linearized output without
> promotion to pseudos.

As the way this ssa conversion is implement. I actually don't know
how hard it is to skip the promotion. I haven't look to that part of
the code yet. I image there will be a test if this variable has been
taking address or not. If so, it can't directly promote to pseudo without
the load/store. That would be one possible place to insert the option
to disable this. But again, let me look at the code first.

> But this should not stop us from moving forward with this change - as
> I think the SSA hooks into the linearization step are pretty specific
> and it should be relatively easy to have a mode where those steps are
> "dummied" - i.e. do nothing.
>
> I have a question though. For my other backend I need liveness
> analysis done even if I skip the other steps. Is it okay to run the
> liveness analysis phase while skipping the CSE / Flow simplification
> phases?

You can, but it is less effective. You will see a lot of load/store into the
memory. SSA make it easy to trace the define and usage chain.
Without that you can't really see well what is going on with the content
of the memory.

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 18, 2017, 7:21 p.m. UTC | #15
On Fri, Aug 18, 2017 at 8:35 PM, Christopher Li <sparse@chrisli.org> wrote:
>
> As the way this ssa conversion is implement. I actually don't know
> how hard it is to skip the promotion.

It's very easy, you just need for is_promotable() to always return
false. But really, what would be the point?

The points that matter to me are:
1) generate correct SSA information.
    This is ultra-important because with incorrect SSA
     a lot of the optimizations are wrong, introduce errors
     and infinite loops or need ugly workarounds.
2) correct any other issues sparse could have with the generated IR
3) correct any errors sparse could have with an optimization
4) add support for construct sparse doesn't support yet
5) add more features, make the sparse's code more efficient
    and the generated IR too.
5') do not forget that sparse is firstly the/a C checker for the kernel
    (and others projects).

>> I have a question though. For my other backend I need liveness
>> analysis done even if I skip the other steps. Is it okay to run the
>> liveness analysis phase while skipping the CSE / Flow simplification
>> phases?
>
> You can, but it is less effective. You will see a lot of load/store into the
> memory. SSA make it easy to trace the define and usage chain.
> Without that you can't really see well what is going on with the content
> of the memory.

Indeed, but I'm not very sure about Dibyendu's question here.
You can have promoted all possible memory accesses to pseudos
and still generating totally un-optimized code because you skipped
the CSE and all others optimizations. It's two largely orthogonal
things.

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Christopher Li Aug. 18, 2017, 8:14 p.m. UTC | #16
On Fri, Aug 18, 2017 at 3:21 PM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
>
> It's very easy, you just need for is_promotable() to always return
> false. But really, what would be the point?

I was mostly thinking debugging and verification purpose.
AST to linearized byte code without the SSA conversion of
memory variable is very straight forward.

Also, I just realized that, promoting memory access into SSA
pseudo is actually not avoidable at instruction level. After CSE
and flow optimization, there might open up new chance to
promote local variable into SSA form. We might need some code
to promote memory access to SSA pseudo from instruction level
any way.

> The points that matter to me are:
> 1) generate correct SSA information.
>     This is ultra-important because with incorrect SSA
>      a lot of the optimizations are wrong, introduce errors
>      and infinite loops or need ugly workarounds.

That I totally agree. Incorrect SSA can't not use as SSA at all.

> 2) correct any other issues sparse could have with the generated IR
> 3) correct any errors sparse could have with an optimization
> 4) add support for construct sparse doesn't support yet
> 5) add more features, make the sparse's code more efficient
>     and the generated IR too.

All agree.

> 5') do not forget that sparse is firstly the/a C checker for the kernel
>     (and others projects).

Sure. But sparse need to get good IR to perform the checking.

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luc Van Oostenryck Aug. 18, 2017, 8:27 p.m. UTC | #17
On Fri, Aug 18, 2017 at 10:14 PM, Christopher Li <sparse@chrisli.org> wrote:
> On Fri, Aug 18, 2017 at 3:21 PM, Luc Van Oostenryck wrote:
>
>> The points that matter to me are:
>> 1) generate correct SSA information.
>>     This is ultra-important because with incorrect SSA
>>      a lot of the optimizations are wrong, introduce errors
>>      and infinite loops or need ugly workarounds.
>
> That I totally agree. Incorrect SSA can't not use as SSA at all.
>
>> 2) correct any other issues sparse could have with the generated IR
>> 3) correct any errors sparse could have with an optimization
>> 4) add support for construct sparse doesn't support yet
>> 5) add more features, make the sparse's code more efficient
>>     and the generated IR too.
>
> All agree.
>
>> 5') do not forget that sparse is firstly the/a C checker for the kernel
>>     (and others projects).
>
> Sure. But sparse need to get good IR to perform the checking.

Hence, points 2 & 3 :)

-- Luc
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/symbol.h b/symbol.h
index 327449611..3f075c5bc 100644
--- a/symbol.h
+++ b/symbol.h
@@ -407,6 +407,39 @@  static inline int is_scalar_type(struct symbol *type)
 	return 0;
 }
 
+static inline int is_simple_type(struct symbol *type)
+{
+	if (type->type == SYM_NODE)
+		type = type->ctype.base_type;
+	switch (type->type) {
+	case SYM_ENUM:
+	case SYM_BITFIELD:
+	case SYM_PTR:
+	case SYM_RESTRICT:	// OK, always integer types
+		return 1;
+	case SYM_STRUCT:
+	case SYM_UNION:
+		return type->bit_size <= long_ctype.bit_size;
+	default:
+		break;
+	}
+	if (type->ctype.base_type == &int_type)
+		return 1;
+	if (type->ctype.base_type == &fp_type)
+		return 1;
+	return 0;
+}
+
+static inline int is_simple_var(struct symbol *var)
+{
+	if (!is_simple_type(var))
+		return 0;
+#define	MOD_NONREG	(MOD_STATIC|MOD_NONLOCAL|MOD_ADDRESSABLE|MOD_VOLATILE)
+	if (var->ctype.modifiers & MOD_NONREG)
+		return 0;
+	return 1;
+}
+
 static inline int is_function(struct symbol *type)
 {
 	return type && type->type == SYM_FN;