Menu

#602 Propagate pointer type (mcs51, pdk15)

None
open
None
5
2023-07-03
2019-02-08
No

For e.g.

const char a[] = "test";
int i;

char f(unsigned char u)
{
    const char *p = a + u;

    i++;

    return(*p);
}

SDCC knows that a is in code space. But that information is not propagated to p, so the *p is an inefficient (for mcs51 and pdk15) read from a generic pointer instead of a read from a cpointer.

Philipp

Discussion

  • Frieder Ferlemann

    Feature request 160 https://sourceforge.net/p/sdcc/feature-requests/160/#af0e is probably related. It's about idata though.
    (To compile the dated example "idata" needs to be prepended with dual underscore.)

     
  • Oleg Endo

    Oleg Endo - 2023-07-01

    I've observed that pointer type propagation does work sometimes.

     
    • Philipp Klaus Krause

      Yes. There is some basic such functionality in SDCC now. But this is so important for generating efficient code for mcs51, SDCC needs to get better at it.
      Maybe we could use some of the generalized constant propagation infrastructure for this (currently in the genconstprop branch, already very useful for integers).

       
      • Philipp Klaus Krause

        Here is a simple code sample, that I want to use as test code for the improvements:

        #include <stdint.h>
        
        inline uintptr_t obfuscate_ptr(const char *ptr)
        {
            return (uintptr_t)ptr ^ 0xabcd;
        }
        
        inline char get_from_obfuscated_ptr(uintptr_t optr, uint8_t offset)
        {
            return (((char *)(optr ^ 0xabcd))[offset]);
        }
        
        #define CSTRING "string in __code"
        #define DSTRING "string in __data"
        #define XSTRING "string in __xdata"
        #define SSTRING "string on stack"
        
        #ifndef __SDCC_mcs51
        #define __xdata __data
        #endif
        
        const char cstring[] = CSTRING;
        __data char dstring[] = DSTRING;
        __xdata char xstring[] = XSTRING;
        
        void chars (char c, char d, char x, char s);
        
        void test(uint8_t offset)
        {
            char sstring[] = SSTRING;
        
            uintptr_t costringptr = obfuscate_ptr (cstring);
            uintptr_t dostringptr = obfuscate_ptr (dstring);
            uintptr_t xostringptr = obfuscate_ptr (xstring);
            uintptr_t sostringptr = obfuscate_ptr (sstring);
        
            chars (
                get_from_obfuscated_ptr(costringptr, offset),
                get_from_obfuscated_ptr(dostringptr, offset),
                get_from_obfuscated_ptr(xostringptr, offset),
                get_from_obfuscated_ptr(sostringptr, offset));
        }
        

        Currently, we call __gptrget four times, both for mcs51 and pdk. Let's see if we can do better for 4.4.0.

         

        Last edit: Philipp Klaus Krause 2023-07-02
  • Philipp Klaus Krause

    As of [r14202], the optimization works in the genconstprop branch. So far writes via pointers are not covered yet, but the more important case of reads is.

     

    Related

    Commit: [r14202]

  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
    • Group: -->
     

Log in to post a comment.