Share

Small Device C Compiler

Tracker: Bugs

5 too many slocs in DSEG - ID: 2817223
Last Update: Comment added ( frief )

sdcc 2.9.0

too many slocs in DSEG, even

/////////////////////////////////
example code:
void taskAIBufferExecute(void)
{
static data char ch = 0;
data float tx, ty;

tx = (float)ADCRead(ch);

ty = tx * 3.123898E-5
+ x[ch][0] * 1.2495591E-4
+ x[ch][1] * 1.8743388E-4
+ x[ch][2] * 1.2495591E-4
+ x[ch][3] * 3.123898E-5
+ y[ch][0] * 3.5897338
- y[ch][1] * 4.851276
+ y[ch][2] * 2.9240527
- y[ch][3] * 0.6630105;
...

sdcc --model-large

/////////////////////////////////
lst file:
440
;--------------------------------------------------------
441 ; internal ram data
442
;--------------------------------------------------------
443 .area DSEG (DATA)
0000 444 _DIOBufferR::
0000 445 .ds 8
0008 446 _GetAnalogI_fResult_1_1:
0008 447 .ds 4
000C 448 _GetAnalogI_x_1_1:
000C 449 .ds 4
0010 450 _GetAnalogI_xn_1_1:
0010 451 .ds 4
0014 452 _taskAIBufferExecute_ch_1_1:
0014 453 .ds 1
0015 454 _taskAIBufferExecute_tx_1_1:
0015 455 .ds 4
0019 456 _taskAIBufferExecute_ty_1_1:
0019 457 .ds 4
001D 458 _taskAIBufferExecute_sloc0_1_0:
001D 459 .ds 4
0021 460 _taskAIBufferExecute_sloc1_1_0:
0021 461 .ds 4
0025 462 _taskAIBufferExecute_sloc2_1_0:
0025 463 .ds 4
0029 464 _taskAIBufferExecute_sloc3_1_0:
0029 465 .ds 4
002D 466 _taskAIBufferExecute_sloc4_1_0:
002D 467 .ds 4
0031 468 _taskAIBufferExecute_sloc5_1_0:
0031 469 .ds 4
0035 470 _taskAIBufferExecute_sloc6_1_0:
0035 471 .ds 4
0039 472 _taskAIBufferExecute_sloc7_1_0:
0039 473 .ds 4
003D 474 _taskAIBufferExecute_sloc8_1_0:
003D 475 .ds 4
0041 476 _taskAIBufferExecute_sloc9_1_0:
0041 477 .ds 4
0045 478 _taskAIBufferExecute_sloc10_1_0:
0045 479 .ds 4
0049 480 _taskAIBufferExecute_sloc11_1_0:
0049 481 .ds 4
004D 482 _taskAIBufferExecute_sloc12_1_0:
004D 483 .ds 4
0051 484 _taskDIOBufferExecute_cAddrI2C_1_1:
0051 485 .ds 1


martin white ( kensenjiha ) - 2009-07-06 03:02

5

Closed

Rejected

Maarten Brock

C-Front End

non bugs

Public


Comments ( 5 )

Date: 2009-07-10 07:09
Sender: frief

thanks for posting the context.
It seems SDCC's Global Common Subexpression Elimination does a bad job
here.

(It temporarily stores ALL those x[ch][n]; x[ch][m] and there are too many
of them for this to make sense)

I see thee ways out:

a) use option --nogcse

b) move those y[ch][n+1] = y[ch][n]; to a separate function

c) use memmove( &y[ch][1], &y[ch][0], 3* sizeof(float) ); and
memmove( &x[ch][1], &x[ch][0], 3* sizeof(float) ); instead of the
assignments.
(memmove is a little slow you might want to write a specialized
version)


Maybe SDCC should have an option
"LimitNumberOfBytesForSLOCsPerFunctionOrPerFile"?

Greetings,
Frieder


Date: 2009-07-10 02:31
Sender: kensenjiha

the source code:
//**********************************************************
// Filename : IO_drv.C
//
//
// Description : IO driver for ADAM5510
//
//
//
// History:
// Created: 2004.7.16, TanYin
// v1.30: for JA, 200508, Martin
//**********************************************************



#include <stdio.h>
#include <limits.h>

// set init value to avoid false alarm while reset
xdata unsigned short afInportAnalog [14] =
{10000,10000,10000,10000,10000,10000,10000,10000,10000,10000,10000,10000,10000,10000};

data char DIOBufferR[8] =
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

char DIOBufferW[8]=
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

char DIOBufferWMask[8] =
{
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F
};

float Consts[4] = {1,2,3,4};

// for IIR filter
static float x[14][4] =
{
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0}
};

static float y[14][4] =
{
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0},
{0,0,0,0},{0,0,0,0}
};

extern short ADCRead(char ch);


float GetRawAnalogI(char cPortNum)
{
data float fResult;

// convert reading to mA
// HW version 1.0 ((2500mV / 120ohm)/65535 readings) =
3.1789629e-4f
// HW version 1.3~1.4 ((2500mV / 121ohm)/65535readings) =
3.1526905e-4f
// HW Version 2.0 ((2500mV / 100ohm)/65535 readings) =
3.8147555E-4f
//
//
fResult = (float)(afInportAnalog[cPortNum]) * 3.8147555e-4f;

return fResult;
}



//============================================================================
float GetAnalogI(char pPortNum)
{
data float fResult, x, xn;
data char cTemp;

xn = 1.0f;
fResult = 0.0f;

x = GetRawAnalogI( pPortNum);

// calibration 1st..3rd order
for (cTemp = 0; cTemp < 2; cTemp ++)
{
fResult += Consts[cTemp] * xn;
xn *= x;
}

return fResult;
}


/*
===========================================================================

buffer analog input data and perform digital LPF

Butterworth IIR filter 1
Filter type: LP
Passband: 0 - 400 Hz@8ksps
Order: 2

Coefficients
a[0] = 0.020083366 b[0] = 1.0
a[1] = 0.040166732 b[1] = -1.5610181
a[2] = 0.020083366 b[2] = 0.6413515

Butterworth IIR filter 2
Filter type: LP
Passband: 0 - 40 Hz @8ksps
Order: 2

Coefficients
a[0] = 2.4135913E-4 b[0] = 1.0
a[1] = 4.8271826E-4 b[1] = -1.9555782
a[2] = 2.4135913E-4 b[2] = 0.9565437

Butterworth IIR filter 3
Filter type: LP
Passband: 0 - 200 Hz
Order: 2

Coefficients
a[0] = 0.005542717 b[0] = 1.0
a[1] = 0.011085434 b[1] = -1.7786318
a[2] = 0.005542717 b[2] = 0.80080265

8Butterworth IIR filter 4
Filter type: LP
Passband: 0 - 200 Hz@8ksps
Order: 4

Coefficients
a[0] = 3.123898E-5 b[0] = 1.0
a[1] = 1.2495591E-4 b[1] = -3.5897338
a[2] = 1.8743388E-4 b[2] = 4.851276
a[3] = 1.2495591E-4 b[3] = -2.9240527
a[4] = 3.123898E-5 b[4] = 0.6630105

actual sample rate:
about 460 / channels
per channel 46 sps
*/
void taskAIBufferExecute(void)
{
static data char ch = 0;
data float tx, ty;

tx = (float)ADCRead(ch);
// using a IIR LPF
/*
// filter 1
ty = (float)tx * 0.020083366 + x[ch][0] * 0.040166732 + x[ch][1] *
0.020083366
+ y[ch][0] * 1.5610181 - y[ch][1] * 0.6413515;
*/
/*
// filter 3
ty = (float)tx * 0.005542717 + x[ch][0] * 0.011085434 + x[ch][1] *
0.005542717
+ y[ch][0] * 1.7786318 - y[ch][1] * 0.80080265;
*/

ty = tx * 3.123898E-5
+ x[ch][0] * 1.2495591E-4
+ x[ch][1] * 1.8743388E-4
+ x[ch][2] * 1.2495591E-4
+ x[ch][3] * 3.123898E-5
+ y[ch][0] * 3.5897338
- y[ch][1] * 4.851276
+ y[ch][2] * 2.9240527
- y[ch][3] * 0.6630105;

if (ty < 0.5f)
{
afInportAnalog[ch] = 0;
}
else if (ty > 65534.5f)
{
afInportAnalog[ch] = 65535;
}
else
{
afInportAnalog[ch] = (unsigned short)ty;
}

y[ch][3] = y[ch][2];
y[ch][2] = y[ch][1];
y[ch][1] = y[ch][0];
y[ch][0] = ty;

x[ch][3] = x[ch][2];
x[ch][2] = x[ch][1];
x[ch][1] = x[ch][0];
x[ch][0] = tx;

ch++;
// for product 0~9, for debug, 0~13
if ((ch >= 10) || (ch < 0))
{
ch = 0;
}
}





Date: 2009-07-07 10:56
Sender: wek_

But, Maarten,

while it is undoubtedly true that floating point arithmetic is memory
intensive, I see no reason for this expression to use more than two
intermediate (potentially spill) variables.

Indeed, trying to compile a function containing this expression, SDCC
invariably produces only one spill variable (4 bytes).

So, there must be something else in the original function which produces
the excessive spill. And that might, or might not, reveal a bug in the
compiler. That's why I ask the OP to post a complete program to be able to
reproduce his findings.

JW


Date: 2009-07-07 10:24
Sender: maartenbrockProject Admin

Floating point calculations are difficult for an 8051, requiring many
registers. Writing such complicated calculations makes it even worse. So
the compiler needs many spil locations for intermediate results. And then
it is bound to run out of memory. I recommend to split it up so that it
uses only one multiplication and one addition per instruction.


Date: 2009-07-07 06:06
Sender: wek_

Can you please post a complete program demonstrating the problem?

Jan Waclawek


Attached File

No Files Currently Attached

Changes ( 5 )

Field Old Value Date By
status_id Open 2009-07-07 10:24 maartenbrock
resolution_id None 2009-07-07 10:24 maartenbrock
artifact_group_id None 2009-07-07 10:24 maartenbrock
assigned_to nobody 2009-07-07 10:24 maartenbrock
close_date - 2009-07-07 10:24 maartenbrock