In the simplest case, several steps are perfomed:
/* note #undef's at end of file */
#define EPS 1.0e-6
void simp2(float **a,int m,int n,int *ip,int kp)
{
int k,i;
float qp,q0,q,q1;
*ip=0;
for (i=1;i<=m;i++)
if (a[i+1][kp+1] < -EPS) break;
if (i>m) return;
q1 = -a[i+1][1]/a[i+1][kp+1];
*ip=i;
pfor (i=*ip+1;i<=m;i++) {
if (a[i+1][kp+1] < -EPS) {
q = -a[i+1][1]/a[i+1][kp+1];
if (q < q1) {
*ip=i;
q1=q;
} else if (q == q1) {
for (k=1;k<=n;k++) {
qp = -a[*ip+1][k+1]/a[*ip+1][kp+1];
q0 = -a[i+1][k+1]/a[i+1][kp+1];
if (q0 != qp) break;
}
if (q0 < qp) *ip=i;
}
}
}
}
#undef EPS
This is transformed into several major code sections:
#include "simp2_speculation.h"
void simp2(float **a,int m,int n,int *ip,int kp)
{
int k,i;
float qp,q0,q,q1;
*ip=0;
for (i=1; (i<=m); i++)
if ((a[(i+1)][(kp+1)]<(-0.000001)))
break;
if ((i>m))
return ;
q1=((-a[(i+1)][1])/a[(i+1)][(kp+1)]);
*ip=i;
if ((!sInSpeculation))
{
i=(*ip+1);
simp2_1V.i=i;
simp2_1V.m=m;
simp2_1V.a=a;
simp2_1V.kp=kp;
simp2_1V.q1=q1;
simp2_1V.ip=ip;
simp2_1V.k=k;
simp2_1V.n=n;
simp2_1V.qp=qp;
simp2_1V.q0=q0;
sSpecDataPointer=&simp2_1V;
sInSpeculation=1;
sSpecFuncPointer=&simp2_1;
simp2_1(&simp2_1V);
sInSpeculation=0;
i=simp2_1V.i;
m=simp2_1V.m;
a=simp2_1V.a;
kp=simp2_1V.kp;
q1=simp2_1V.q1;
ip=simp2_1V.ip;
k=simp2_1V.k;
n=simp2_1V.n;
qp=simp2_1V.qp;
q0=simp2_1V.q0;
}
else
The original loop:
{
for (i=(*ip+1); (i<=m); i++)
{
if ((a[(i+1)][(kp+1)]<(-0.000001)))
{
q=((-a[(i+1)][1])/a[(i+1)][(kp+1)]);
if ((q<q1))
{
*ip=i;
q1=q;
}
else
if (q==q1)
{
for (k=1; (k<=n); k++)
{
qp=((-a[(*ip+1)][(k+1)])/a[(*ip+1)][(kp+1)]);
q0=((-a[(i+1)][(k+1)])/a[(i+1)][(kp+1)]);
if ((q0!=qp))
break;
}
if ((q0<qp))
*ip=i;
}
}
}
}
}
The header file, defining the struct:
typedef struct simp2_1_s
{
float q0;
float qp;
int n;
int k;
int *ip;
float q1;
int kp;
float **a;
int m;
int i;
}simp2_1_t;
simp2_1_t simp2_1V;
int simp2_1(simp2_1_t *nonlocals);
#include "hydracat_speculation.h"
The speculative function:
simp2_1(simp2_1_t *nonlocals)
{
int kp;
float **a;
float q;
int i;
kp=nonlocals->kp;
i=nonlocals->i;
spec_begin_label(&&spec_start,&&spec_terminate,&&spec_terminate_last);
while (1)
{
spec_eoi_label();
spec_start:
{
i=nonlocals->i;
(nonlocals->i)++;
if ((!(i<=(nonlocals->m))))
spec_terminate_label();
{
if (((nonlocals->a)[(i+1)][((nonlocals->kp)+1)]<(-0.000001)))
{
q=((-(nonlocals->a)[(i+1)][1])/(nonlocals->a)[(i+1)][((nonlocals->kp)+1)]);
if ((q<(nonlocals->q1)))
{
*(nonlocals->ip)=i;
(nonlocals->q1)=q;
}
else
if (q==(nonlocals->q1))
{
for ((nonlocals->k)=1; ((nonlocals->k)<=(nonlocals->n)); (nonlocals->k)++)
{
(nonlocals->qp)=((-(nonlocals->a)[(*(nonlocals->ip)+1)][((nonlocals->k)+1)])/(nonlocals->a)[(*(nonlocals->ip)+1)][((nonlocals->kp)+1)]);
(nonlocals->q0)=((-(nonlocals->a)[(i+1)][((nonlocals->k)+1)])/(nonlocals->a)[(i+1)][((nonlocals->kp)+1)]);
if (((nonlocals->q0)!=(nonlocals->qp)))
break;
}
if (((nonlocals->q0)<(nonlocals->qp)))
*(nonlocals->ip)=i;
}
}
}
}
}
spec_terminate_last:
spec_terminate:
return ;
}