in vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp [817:1052]
bool Emitter::bundling(int bbindex) {
EmitterBb * bb = bbs->at(bbindex);
InstVector & insts = bb->insts;
long sizebb = insts.size();
if (sizebb==0) return true;
vectorbool * stops = bb->stops;
BundleVector * bundles = bb->bundles;
BundleDescription tmp = {0,0,0};
int iTmpl=-1;
Inst *inst0=NULL, *inst1=NULL, *inst2=NULL, *inst3=NULL;
bool stop0=false, stop1=false, stop2=false, stop3=false;
bool stop0_f=false, stop1_f=false, stop2_f=false, stop3_f=false; // inst is first in group
bool stop0_l=false, stop1_l=false, stop2_l=false; // inst is last in group
int it0=0, it1=0, it2=0, it3=0; // insts type
long i0, i1, i2, i3;
for ( i0=0 ; i0 < sizebb ; ) {
inst0=Encoder::resolvePseudo(cfg, insts[i0]);
if (Encoder::isIgnoreInst(inst0)) { i0++; continue; }
stop0=stops->at(i0);
for ( i1=i0+1 ; i1<sizebb ; ) {
inst1=Encoder::resolvePseudo(cfg, insts[i1]);
if (Encoder::isIgnoreInst(inst1)) { i1++; continue; }
stop1=stops->at(i1);
break;
}
if ( i1 >= sizebb ) { inst1=NULL; }
for ( i2=i1+1 ; i2<sizebb ; ) {
inst2=Encoder::resolvePseudo(cfg, insts[i2]);
if (Encoder::isIgnoreInst(inst2)) { i2++; continue; }
stop2=stops->at(i2);
break;
}
if ( i2 >= sizebb ) { inst2=NULL; }
for ( i3=i2+1 ; i3<sizebb ; ) {
inst3=Encoder::resolvePseudo(cfg, insts[i3]);
if (Encoder::isIgnoreInst(inst3)) { i3++; continue; }
stop3=stops->at(i3);
break;
}
if ( i3 >= sizebb ) { inst3=NULL; }
it0 = Encoder::getInstType(inst0);
it1 = Encoder::getInstType(inst1);
it2 = Encoder::getInstType(inst2);
it3 = Encoder::getInstType(inst3);
stop0_l = (it0 & IT_GL)==IT_GL;
stop1_l = (it1 & IT_GL)==IT_GL;
stop2_l = (it2 & IT_GL)==IT_GL;
stop0_f = (it0 & IT_GF)==IT_GF;
stop1_f = (it1 & IT_GF)==IT_GF;
stop2_f = (it2 & IT_GF)==IT_GF;
stop3_f = (it3 & IT_GF)==IT_GF;
/*********************************************
* Special case for br.call
* br.ret will return to next bundle, so
* all instructions after br.call must be nop
*********************************************/
if (inst0->getInstCode()==INST_BR || inst0->getInstCode()==INST_BR13) {
CompVector & cmpls0 = inst0->getComps();
if (cmpls0.size()>0 && cmpls0[0]==CMPLT_BTYPE_CALL) {
inst1=NULL;
inst2=NULL;
}
} else if (inst1!=NULL && (inst1->getInstCode()==INST_BR || inst1->getInstCode()==INST_BR13)) {
CompVector & cmpls1 = inst1->getComps();
if (cmpls1.size()>0 && cmpls1[0]==CMPLT_BTYPE_CALL) {
inst2=NULL;
}
}
/*********************************************
* Special case for inst0==LX type (brl,...)
*********************************************/
if ( Encoder::getInstType(inst0->getInstCode()) & IT_L ) {
inst1=NULL;
inst2=NULL;
getTmpl(bbindex, tmp, NULL, inst0, NULL
, false, false, stop0 || stop0_l || stop1_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, NULL, inst0, NULL);
i0 += 1;
continue;
}
IPF_ERR << "BUNDLING ERROR: CAN'T FIND TEMPLATE !\n";
IPF_ERR << "BUNDLING ERROR: " << IrPrinter::toString(inst0) << "\n";
IPF_ASSERT(0);
}
/********************************
* Special case for inst1==LX type (brl,...)
********************************/
if (inst1!=NULL && (Encoder::getInstType(inst1->getInstCode()) & IT_L)) {
inst2=NULL;
getTmpl(bbindex, tmp, inst0, inst1, NULL
, stop0 || stop0_l || stop1_f, false, stop1 || stop1_l || stop2_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, inst1, NULL);
i0 = i1 + 1;
continue;
}
inst1=NULL;
}
/********************************
* inst1!=NULL && inst2!=NULL
********************************/
if (inst1!=NULL && inst2!=NULL) {
getTmpl(bbindex, tmp, inst0, inst1, inst2
, stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f, stop2 || stop2_l || stop3_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, inst1, inst2);
i0 = i2 + 1;
continue;
}
}
/********************************
* inst2==NULL && inst1!=LX type (brl,...)
********************************/
if (inst1!=NULL) {
getTmpl(bbindex, tmp, inst0, inst1, NULL
, stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f, false);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, inst1, NULL);
i0 = i1 + 1;
continue;
}
getTmpl(bbindex, tmp, inst0, inst1, NULL
, stop0 || stop0_l || stop1_f, false, stop1 || stop1_l || stop2_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, inst1, NULL);
i0 = i1 + 1;
continue;
}
getTmpl(bbindex, tmp, inst0, NULL, inst1
, stop0 || stop0_l || stop1_f, false, stop1 || stop1_l || stop2_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, NULL, inst1);
i0 = i1 + 1;
continue;
}
getTmpl(bbindex, tmp, inst0, NULL, inst1
, false, stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, NULL, inst1);
i0 = i1 + 1;
continue;
}
getTmpl(bbindex, tmp, NULL, inst0, inst1
, false, stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, NULL,inst0, inst1);
i0 = i1 + 1;
continue;
}
}
/********************************
* inst1==NULL
********************************/
getTmpl(bbindex, tmp, inst0, NULL, NULL
, stop0 || stop0_l || stop1_f, false, false);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, NULL, NULL);
i0 += 1;
continue;
}
getTmpl(bbindex, tmp, inst0, NULL, NULL
, false, stop0 || stop0_l || stop1_f, false);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, NULL, NULL);
i0 += 1;
continue;
}
getTmpl(bbindex, tmp, inst0, NULL, NULL
, false, false, stop0 || stop0_l || stop1_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, inst0, NULL, NULL);
i0 += 1;
continue;
}
getTmpl(bbindex, tmp, NULL, inst0, NULL
, false, stop0 || stop0_l || stop1_f, false);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, NULL, inst0, NULL);
i0 += 1;
continue;
}
getTmpl(bbindex, tmp, NULL, inst0, NULL
, false, false, stop0 || stop0_l || stop1_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, NULL, inst0, NULL);
i0 += 1;
continue;
}
getTmpl(bbindex, tmp, NULL, NULL, inst0
, false, false, stop0 || stop0_l || stop1_f);
iTmpl=findTmpl(tmp);
if( iTmpl>=0 ) {
bundles->addBundle(iTmpl, NULL, NULL, inst0);
i0 += 1;
continue;
}
IPF_ERR << "ERROR: CAN'T FIND TEMPLATE !!!\n";
IPF_ASSERT(0);
i0++;
}
return true;
}