CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Has anyone else noticed CCS have changed array maths.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

Has anyone else noticed CCS have changed array maths.
PostPosted: Sun Oct 01, 2017 4:14 am     Reply with quote

Hi,

Was re-compiling an old program that has always generated an 'interrupts disabled to prevent re-entrancy' warning, because it uses a structure array access inside an interrupt, and it uses the int16 multiply to calculate the location needed in this. Given this is a modern PIC with a hardware multiplier, it is only a very few instructions, but was always slightly 'annoying', since such accesses are very fundamental. Had last compiled it on 5.070, and switched to 5.074, and was surprised to see the warning disappear.

A quick change backwards and forwards confirmed the change. On .074, the compiler is generating two copies of some of the integer maths routines, without being asked.
Has anyone else noticed this?.

Will have to investigate to see if it also applies to chips without the hardware multiply.

Can't see anything about this in the change list, except a mention of an optimisation bug being fixed in interrupt handlers.
It is still giving the warning in 5.072, and not in 5.073.
It is using 100bytes more ROM in my case.

So has anyone else noticed?.
Any issues seen?. (If anything I'd expect things to be better!...).

Current tests are looking hopeful for me.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 01, 2017 6:59 am     Reply with quote

It still gives me a warning for divide by 16. It may have been removed for
for structures, but not for general math. This was tested with vs. 5.074.
Quote:

Executing: "C:\Program files\Picc\CCSC.exe" +FH "PCH_Test.c" +DF
+LY -T -A +M -Z +Y=9 +EA #__buildcount__="0" #__18F46K22=TRUE
>>> Warning 216 "PCH_Test.c" Line 23(1,2): Interrupts disabled during
call to prevent re-entrancy: (@DIV1616)
Memory usage: ROM=1% RAM=1% - 1%
0 Errors, 1 Warnings.
Build Successful.

Test program:
Code:

#include <18F46K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT
#use delay(clock=4M)

int16 timer1_value;

#int_timer1
void ccp1_isr()
{
timer1_value = get_timer1() / 3;
}


//=====================================
void main(void)
{
int16 value;
int16 result;

result=value/3;

while(TRUE);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sun Oct 01, 2017 7:40 am     Reply with quote

I think it is only the array index calculation that has been changed. Makes sense if you think about it, since it is always just a simple multiplication and addition, with the size determined by the RAM size of the chip. To add the whole library would be a lot bulkier (as you know we can trick it to do this if required), but it has always been a bit annoying, when you use anything other than a simple array, and end up with the warning. I was using a 2 dimensional array to hold lines of data and pointers to them. Far the easiest way to do what I wanted, but came with the warning, that I accepted. To suddenly have it disappear, was a surprise... Smile

So far been running since last night without any glitches, so it suggests the change hasn't brought any unwanted 'luggage', except a bit more code space used.
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Sun Oct 01, 2017 8:49 am     Reply with quote

It's nice that they changed it, but I didn't notice. Quite some time ago I did notice that same warning, so I dug a bit and found that a mul at the heart of an array access in an isr was to blame. To get round the warning, I encapsulated the multiplication in my own function, my_mult(), so as to force the compiler to use two different multiplications - one "virgin" for the isr, and the other, for everything else.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sun Oct 01, 2017 9:16 am     Reply with quote

That was neat. You can actually make the whole maths library 'duplicate' (just as with the delay functions), but it is quite cumbersome. Your approach was a neat way round.
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

PostPosted: Mon Oct 02, 2017 6:58 am     Reply with quote

newguy wrote:
It's nice that they changed it, but I didn't notice. Quite some time ago I did notice that same warning, so I dug a bit and found that a mul at the heart of an array access in an isr was to blame. To get round the warning, I encapsulated the multiplication in my own function, my_mult(), so as to force the compiler to use two different multiplications - one "virgin" for the isr, and the other, for everything else.


That's neat. A question on how this works:

Say one uses my_multi() which does a multiply and the main code does a multiply. What prevents the compiler from making one internal function for multiplying and simply just calling that both in the main and in my_multi?

Just wanting to make sure I understand so we don't get bugs down the line if the compiler decides to change how it does things.
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Mon Oct 02, 2017 7:14 am     Reply with quote

This was quite some time ago, so bear with me... I believe that I wrapped it in a #separate, which forced the compiler to treat it as a completely separate function.

The point about accessing an array is that (apparently until recently), CCS was using a multiply to figure out the offset into the array. That sort of implementation, of course, is going to be inlined by the compiler. In other words, bypassing your new multiply function. No need to disable interrupts anymore with that sort of code structure.

I can't take the credit for the idea. PCM, on a number of occasions I believe, has recommended wrapping printf in your own wrapper, my_printf(), for similar reasons. I was just following his lead when I did this with the multiply.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Mon Oct 02, 2017 7:26 am     Reply with quote

Yes, I too have wrappered printf here for quite a few things. For a program that has to do just one maths operation in a interrupt it makes an alternative to the #ORG solution (you can use an explicit #ORG before the interrupt handler so that the maths library routines used are loaded 'with' this, and then a separate one for the main code).
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Mon Oct 02, 2017 8:13 am     Reply with quote

Now I remember why I'd wrap printf in my own wrapper function: to reduce code size because CCS, by default, tends to inline printf.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Mon Oct 02, 2017 9:20 am     Reply with quote

Yes. Generally the CCS optimisation tends to be for performance, rather than for space. Tricks like this are then a way of switching this type of thing to a form that is slightly more compact. Especially when repeated calls are made using the same format.
Woody



Joined: 11 Sep 2003
Posts: 83
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Tue Jun 29, 2021 9:41 am     Reply with quote

Excuses for reviving this old thread but I would like to ask: do I need to do something special to make the compiler solve the 'interrupts disabled to prevent re-entrancy [@MUL1616]' warning?

I'm using compiler version 5.104 on an 18F55Q43 (which has a hardware multiplier), but still get the warning for the same reason as Ttelmah decribes in this thread, using a two dimensional array in an (ADC) interrupt and outside that interrupt as well.

Just wondering.

Paul
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jun 30, 2021 12:01 am     Reply with quote

You have to be doing something else. Double check you are not doing
something like a multiplication in the interrupt.

I just built a deliberate test to check:
Code:

#include <18F55Q43.h>
#device ADC=12

#FUSES NOWDT                    //No Watch Dog Timer

#use delay(internal=32000000)

unsigned int16 array[3][10] = {
{1,2,3,4,5,6,7,8,9,10},
{1,2,3,4,5,6,7,8,9,10},
{1,2,3,4,5,6,7,8,9,10}
};

unsigned int16 rval=0; //return value
int index1=0,index2=0; //array indexes
   
#int_timer1
void tick(void)
{
   rval=array[index1][index2]; //array access

   if (++index2==10) //increment indexes through the array
   {
      index2=0;
      if (++index1==3)
         index1=0;   
   }
}

void main()
{
   unsigned int16 testval=0, result, aval;
   
   //basic tick for interrupt
   setup_timer_1(T1_FOSC | T1_DIV_BY_8);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      delay_ms(500);
      //now perform a 16bit multiplication
      result=testval*rval;
      testval++;
      //double check by forcing an array access here as well
      aval=array[index1][index2];
   }
}


And it compiles without giving the error. A look at the listing shows it
merrily using a MULLW in the interrupt to multiply the index by the
length of the array line, without calling the MUL1616 library.

Thinking about it, is possibly one of your array indexes larger than 255?.
I suspect that would force the mul library to be used again.
Woody



Joined: 11 Sep 2003
Posts: 83
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Wed Jun 30, 2021 12:47 am     Reply with quote

Quote:
Thinking about it, is possibly one of your array indexes larger than 255?.
I suspect that would force the mul library to be used again.


Well, the indexes are both int8. The 2 dimensional array itself however is 384 bytes long (12 sensors, and 16 16-bit values each). For a test I shortened it to 8 values per sensor and that indeed gets rid of the warning.

I need those 16 values (might even want 32 values later on) so I guess I'll have to live with the warning.
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jun 30, 2021 2:01 am     Reply with quote

No, it should handle an array over 255 entries. The mul instruction, accepts
two int8's, but returns an int16. It sounds as if somebody at CCS writing
this decided not to handle the possibility of >255 return. However I'm sure
some of my arrays using this are larger than this, and aren't giving the
error. I really would talk to CCS about this. Possibly it is wrong on some
particular chips?. Sad
Point out that the multiply does give a int16 return.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group