This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: named address spaces: addr_space_convert never called


On 08/11/10 16:59, Georg Lay wrote:
Richard Guenther schrieb:
On Mon, Nov 8, 2010 at 3:39 PM, Georg Lay<avr@gjlay.de> wrote:
Hi, I just started playing around with named address spaces for avr.
Besides general space (ram), I introduced a second one, __pgm, which
shall address program memory where also constants may live. avr is
havard architecture, and both program memory and ram start at address 0.

 From this and the internals on TARGET_ADDR_SPACE_CONVERT I understand
that pointer casting will not work as expected, because that hook will
only get called if the respective address spaces are subsets. However,
neither is space-1 a subset of space-0 nor vice versa (or am I midlead
by internals?)

Is there a way to make it work in the case where the address spaces
are disjoint? Started this morning and everything went smooth until I
started messing around with pointer casts:


char cast_3 (char in_pgm, void * p) { return in_pgm ? (*((char __pgm *) p)) : (*((char *) p)); }

The cast looks fine from the trees perspective (excerpt from .expand):

The first cast nullifies the pointer.
;; Function cast_3 (cast_3)

cast_3 (char in_pgm, void * p)
{
  <address-space-1>  char * D.1934;
  char D.1930;

  # BLOCK 2 freq:10000
  # PRED: ENTRY [100.0%]  (fallthru,exec)
  if (in_pgm_2(D) != 0)
    goto<bb 3>;
  else
    goto<bb 4>;
  # SUCC: 3 [39.0%]  (true,exec) 4 [61.0%]  (false,exec)

  # BLOCK 3 freq:3900
  # PRED: 2 [39.0%]  (true,exec)
  D.1934_4 = (<address-space-1>  char *) p_3(D);
  D.1930_5 = *D.1934_4;
  goto<bb 5>;
  # SUCC: 5 [100.0%]  (fallthru,exec)

  # BLOCK 4 freq:6100
  # PRED: 2 [61.0%]  (false,exec)
  D.1930_6 = MEM[(char *)p_3(D)];
  # SUCC: 5 [100.0%]  (fallthru,exec)

  # BLOCK 5 freq:10000
  # PRED: 3 [100.0%]  (fallthru,exec) 4 [100.0%]  (fallthru,exec)
  # D.1930_1 = PHI<D.1930_5(3), D.1930_6(4)>
  return D.1930_1;
  # SUCC: EXIT [100.0%]

}

This produces the following RTL:

;; Generating RTL for gimple basic block 3

;; D.1930_5 = *D.1934_4;

(insn 10 9 11 (set (reg/f:PHI 47)
        (const_int 0 [0])) pgm.c:97 -1
     (nil))

(insn 11 10 0 (set (reg:QI 42 [ D.1930 ])
        (mem:QI (reg/f:PHI 47) [0 *D.1934_4+0 S1 A8 AS1])) pgm.c:97 -1
     (nil))

;; Generating RTL for gimple basic block 4

So as of internals doc, named address spaces are not intended to
implement this kind of memory?

If they are not subsets of each other how'd you convert a pointer pointing into one to point into the other address-space? I think the frontend should diagnose this as invalid.

The front end emits warning. However, explicit casts should yield only a warning if explicit requested.

With subsets relation returning true the code is like that (I changed
the test case to add 5, the there is an additional *addphi).

;; Generating RTL for gimple basic block 3

;; D.1987_6 = MEM[(<address-space-1> char *)D.1991_4 + 5B];

(insn 10 9 11 (set (reg:PHI 47)
         (subreg:PHI (reg/v/f:HI 46 [ p ]) 0)) pgm.c:98 -1
      (nil))

(insn 11 10 12 (set (reg:PHI 48)
         (reg:PHI 47)) pgm.c:98 -1
      (nil))

(insn 12 11 13 (set (reg/f:PHI 49)
         (plus:PHI (reg:PHI 47)
             (const_int 5 [0x5]))) pgm.c:98 -1
      (nil))

(insn 13 12 0 (set (reg:QI 42 [ D.1987 ])
         (mem:QI (reg/f:PHI 49) [0 MEM[(<address-space-1>  char
*)D.1991_4 + 5B]+0 S1 A8 AS1])) pgm.c:98 -1
      (nil))

;; Generating RTL for gimple basic block 4

This is fine.

However, I am still confused:

"A is a subset of B iff every member of A is alse member of B".

But in this case, an element of ram is not an element of flash nor is
an element of flash an element of ram. Written down as numbers, these
numers are the same, yes, so that information gets encoded in the
machine mode to know what addresses are legal and what instruction
must be used.

Memory is not linearized because that would imply to take the decision
at runtime.


Georg




Would be be possible to define a third memory space as "global" memory, of which both the ram and the flash are subsets? It is important to keep ram as the default memory space, but perhaps an artificial global memory space would let you do conversions like this safely and without warnings.

Even better would be if the global memory space could have 24-bit (or 32-bit if necessary) pointers, so that it would actually encompass all memory, with ram pointers at 0x800000 to match the addresses used by the linker. It would also make it a lot easier to use the full flash space on AVR's with more than 64K flash.

May I say I think it's great that you are looking into this? Program space access on the AVR was the first thing I thought of when I heard of the concept of named address spaces in C.

mvh.,

David


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]