@@ -687,6 +687,8 @@ void Optimizer::initOptimizations() {
687
687
OPT_INITIALIZE_PASS (initializePayload, vISA_InitPayload, TimerID::NUM_TIMERS);
688
688
OPT_INITIALIZE_PASS (cleanupBindless, vISA_enableCleanupBindless,
689
689
TimerID::OPTIMIZER);
690
+ OPT_INITIALIZE_PASS (cleanupA0Movs, vISA_enableCleanupA0Movs,
691
+ TimerID::OPTIMIZER);
690
692
OPT_INITIALIZE_PASS (countGRFUsage, vISA_PrintRegUsage, TimerID::MISC_OPTS);
691
693
OPT_INITIALIZE_PASS (changeMoveType, vISA_ChangeMoveType, TimerID::MISC_OPTS);
692
694
OPT_INITIALIZE_PASS (accSubBeforeRA, vISA_accSubBeforeRA, TimerID::OPTIMIZER);
@@ -866,6 +868,8 @@ int Optimizer::optimization() {
866
868
867
869
runPass (PI_removePartialMovs);
868
870
871
+ runPass (PI_cleanupA0Movs);
872
+
869
873
// remove redundant movs and fold some other patterns
870
874
runPass (PI_localCopyPropagation);
871
875
@@ -2711,10 +2715,6 @@ void Optimizer::localCopyPropagation() {
2711
2715
src->asSrcRegRegion ()->getAddrImm ());
2712
2716
}
2713
2717
}
2714
- } else if (inst->hasOneUse ()) {
2715
- new_src_opnd = src;
2716
- new_src_opnd->asSrcRegRegion ()->setModifier (new_mod);
2717
- new_src_opnd->asSrcRegRegion ()->setType (builder, propType);
2718
2718
} else {
2719
2719
new_src_opnd = builder.duplicateOperand (src);
2720
2720
new_src_opnd->asSrcRegRegion ()->setModifier (new_mod);
@@ -4578,6 +4578,77 @@ G4_Operand *Optimizer::updateSendsHeaderReuse(
4578
4578
return nullptr ;
4579
4579
}
4580
4580
4581
+ void Optimizer::cleanupA0Movs () {
4582
+ for (auto bb : fg) {
4583
+ InstValues values (4 );
4584
+ for (auto iter = bb->begin (), iterEnd = bb->end (); iter != iterEnd;) {
4585
+ G4_INST *inst = *iter;
4586
+
4587
+ auto isDstExtDesc = [](G4_INST *inst) {
4588
+ G4_DstRegRegion *dst = inst->getDst ();
4589
+ if (dst && dst->getTopDcl () && dst->getTopDcl ()->isMsgDesc ()) {
4590
+ // check that its single use is at src3 of split send
4591
+ if (inst->use_size () != 1 ) {
4592
+ return false ;
4593
+ }
4594
+ auto use = inst->use_front ();
4595
+ G4_INST *useInst = use.first ;
4596
+ if (useInst->isSend ()) {
4597
+ return true ;
4598
+ }
4599
+ }
4600
+ return false ;
4601
+ };
4602
+
4603
+ if (isDstExtDesc (inst)) {
4604
+ G4_INST *valInst = values.findValue (inst);
4605
+ if (valInst != nullptr ) {
4606
+ VISA_DEBUG_VERBOSE ({
4607
+ std::cout << " can replace \n " ;
4608
+ inst->emit (std::cout);
4609
+ std::cout << " \n with \n " ;
4610
+ valInst->emit (std::cout);
4611
+ std::cout << " \n " ;
4612
+ });
4613
+ for (auto I = inst->use_begin (), E = inst->use_end (); I != E; ++I) {
4614
+ // each use is in the form of A0(0,0)<0;1,0>:ud in a send
4615
+ G4_INST *useInst = I->first ;
4616
+ Gen4_Operand_Number num = I->second ;
4617
+ vISA_ASSERT (useInst->isSend (), " use inst must be a send" );
4618
+ G4_SrcRegRegion *newExDesc =
4619
+ builder.createSrc (valInst->getDst ()->getBase (), 0 , 0 ,
4620
+ builder.getRegionScalar (), Type_UD);
4621
+ useInst->setSrc (newExDesc, useInst->getSrcNum (num));
4622
+ }
4623
+ (*iter)->removeAllDefs ();
4624
+ (*iter)->transferUse (valInst);
4625
+ iter = bb->erase (iter);
4626
+ continue ;
4627
+ } else {
4628
+ VISA_DEBUG_VERBOSE ({
4629
+ std::cout << " add new value:\n " ;
4630
+ inst->emit (std::cout);
4631
+ std::cout << " \n " ;
4632
+ });
4633
+ // this is necessary since for msg desc we always the physical a0.0,
4634
+ // so a new inst will invalidate the previous one
4635
+ values.deleteValue (inst);
4636
+ values.addValue (inst);
4637
+ }
4638
+ } else {
4639
+ G4_DstRegRegion *dst = inst->getDst ();
4640
+ if (dst && dst->isDirectAddress ()) {
4641
+ // If the address register is used for none extdesc
4642
+ values.clear ();
4643
+ } else {
4644
+ values.deleteValue (inst);
4645
+ }
4646
+ }
4647
+ ++iter;
4648
+ }
4649
+ }
4650
+ }
4651
+
4581
4652
//
4582
4653
// Perform value numbering on writes to the extended msg descriptor for bindless
4583
4654
// access of the form op (1) a0.2<1>:ud src0 src1 src2 {NoMask} and remove
@@ -4647,29 +4718,28 @@ void Optimizer::cleanupBindless() {
4647
4718
auto isDstExtDesc = [](G4_INST *inst) {
4648
4719
G4_DstRegRegion *dst = inst->getDst ();
4649
4720
if (dst && dst->getTopDcl () && dst->getTopDcl ()->isMsgDesc ()) {
4650
- // check that its single use is at src3 of split send
4651
- if (inst->use_size () != 1 ) {
4652
- return false ;
4653
- }
4654
- auto use = inst->use_front ();
4655
- G4_INST *useInst = use.first ;
4656
- if (useInst->isSend ()) {
4657
- return true ;
4721
+ // if a use is something other than a send, do not perform the
4722
+ // optimization
4723
+ for (auto use = inst->use_begin (); use != inst->use_end (); use++) {
4724
+ G4_INST* useInst = use->first ;
4725
+ if (!useInst->isSend ())
4726
+ return false ;
4658
4727
}
4728
+ return true ;
4659
4729
}
4660
4730
return false ;
4661
4731
};
4662
4732
4663
4733
if (isDstExtDesc (inst)) {
4664
4734
G4_INST *valInst = values.findValue (inst);
4665
4735
if (valInst != nullptr ) {
4666
- # if 0
4667
- std::cout << "can replace \n";
4668
- inst->emit(std::cout);
4669
- std::cout << "\n with \n";
4670
- valInst->emit(std::cout);
4671
- std::cout << "\n";
4672
- # endif
4736
+ VISA_DEBUG_VERBOSE ({
4737
+ std::cout << " can replace \n " ;
4738
+ inst->emit (std::cout);
4739
+ std::cout << " \n with \n " ;
4740
+ valInst->emit (std::cout);
4741
+ std::cout << " \n " ;
4742
+ });
4673
4743
for (auto I = inst->use_begin (), E = inst->use_end (); I != E; ++I) {
4674
4744
// each use is in the form of A0(0,0)<0;1,0>:ud in a send
4675
4745
G4_INST *useInst = I->first ;
0 commit comments