@@ -5686,185 +5686,6 @@ bool CleanPHINode::runOnFunction(Function& F)
56865686 return changed;
56875687}
56885688
5689- namespace {
5690- class MergeMemFromBranchOpt : public FunctionPass , public llvm ::InstVisitor<MergeMemFromBranchOpt>
5691- {
5692- public:
5693- static char ID;
5694- MergeMemFromBranchOpt ();
5695-
5696- StringRef getPassName () const override { return " MergeMemFromBranchOpt" ; }
5697-
5698- bool runOnFunction (Function& F) override ;
5699- virtual void getAnalysisUsage (llvm::AnalysisUsage& AU) const override
5700- {
5701- AU.setPreservesCFG ();
5702- AU.addRequired <CodeGenContextWrapper>();
5703- }
5704-
5705- void visitCallInst (llvm::CallInst& C);
5706- void visitTypedWrite (llvm::CallInst* inst);
5707- private:
5708- CodeGenContext* pContext = nullptr ;
5709- };
5710- }
5711-
5712- #undef PASS_FLAG
5713- #undef PASS_DESCRIPTION
5714- #undef PASS_CFG_ONLY
5715- #undef PASS_ANALYSIS
5716- #define PASS_FLAG " igc-MergeMemFromBranchOpt"
5717- #define PASS_DESCRIPTION " Merge Mem from Branch Opt"
5718- #define PASS_CFG_ONLY false
5719- #define PASS_ANALYSIS false
5720- IGC_INITIALIZE_PASS_BEGIN (MergeMemFromBranchOpt, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
5721- IGC_INITIALIZE_PASS_END(MergeMemFromBranchOpt, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
5722-
5723- /*
5724- This optimization merge the UAV writes from if/else branch to the common successor to avoid partial writes
5725-
5726- ex: Change
5727- Label-1337.i: ; preds = %Label-1339.i, %Label-1780.i
5728- <skip instructions>
5729- %494 = inttoptr i32 %0 to %__2D_DIM_Resource addrspace(2490368)*
5730- call void @llvm.genx.GenISA.typedwrite.p2490368__2D_DIM_Resource(%__2D_DIM_Resource addrspace(2490368)* %494, i32 %17, i32 %18, i32 0, i32 0, float %491, float %492, float %493, float %Temp-2360.i163)
5731- br label %Output
5732-
5733- Label-1313.i: ; preds = %Label-1577.i
5734- %495 = inttoptr i32 %0 to %__2D_DIM_Resource addrspace(2490368)*
5735- call void @llvm.genx.GenISA.typedwrite.p2490368__2D_DIM_Resource(%__2D_DIM_Resource addrspace(2490368)* %495, i32 %17, i32 %18, i32 0, i32 0, float %scalar39, float %scalar40, float %scalar41, float %scalar42)
5736- br label %Output
5737-
5738- Output: ; preds = %Label-1313.i, %Label-1337.i
5739- ret void
5740-
5741- to
5742-
5743- Output: ; preds = %Label-1313.i, %Label-1337.i
5744- %494 = phi float [ %scalar39, %Label-1313.i ], [ %491, %Label-1337.i ]
5745- %495 = phi float [ %scalar40, %Label-1313.i ], [ %492, %Label-1337.i ]
5746- %496 = phi float [ %scalar41, %Label-1313.i ], [ %493, %Label-1337.i ]
5747- %497 = phi float [ %scalar42, %Label-1313.i ], [ %Temp-2360.i163, %Label-1337.i ]
5748- %498 = inttoptr i32 %0 to %__2D_DIM_Resource addrspace(2490368)*
5749- call void @llvm.genx.GenISA.typedwrite.p2490368__2D_DIM_Resource(%__2D_DIM_Resource addrspace(2490368)* %498, i32 %17, i32 %18, i32 0, i32 0, float %494, float %495, float %496, float %497)
5750- ret void
5751- }
5752- */
5753-
5754- char MergeMemFromBranchOpt::ID = 0;
5755- FunctionPass* IGC::createMergeMemFromBranchOptPass ()
5756- {
5757- return new MergeMemFromBranchOpt ();
5758- }
5759-
5760- MergeMemFromBranchOpt::MergeMemFromBranchOpt () : FunctionPass(ID)
5761- {
5762- initializeMergeMemFromBranchOptPass (*PassRegistry::getPassRegistry ());
5763- }
5764-
5765- void MergeMemFromBranchOpt::visitTypedWrite (llvm::CallInst* inst)
5766- {
5767- std::vector<CallInst*> callSet;
5768- // last instruction in the BB
5769- if (dyn_cast<BranchInst>(inst->getNextNode ()))
5770- {
5771- BasicBlock* BB = inst->getParent ();
5772- BasicBlock* BB2 = nullptr ;
5773- // the basicblock with inst has single successor BB
5774- if (BasicBlock* succBB = BB->getSingleSuccessor ())
5775- {
5776- callSet.push_back (inst);
5777- // find the other BB with the same successor
5778- for (pred_iterator PI = pred_begin (succBB), E = pred_end (succBB); PI != E; ++PI)
5779- {
5780- BB2 = *PI;
5781- if (BB2 != BB && BB2->getInstList ().size () > 1 )
5782- {
5783- BranchInst* br = dyn_cast<BranchInst>(&BB2->getInstList ().back ());
5784- if (br && br->getPrevNode ())
5785- {
5786- if (llvm::GenIntrinsicInst* giInst = llvm::dyn_cast<GenIntrinsicInst>(br->getPrevNode ()))
5787- {
5788- if (giInst->getIntrinsicID () == GenISAIntrinsic::GenISA_typedwrite)
5789- {
5790- if (((giInst->getOperand (0 ))->getType ()->getPointerAddressSpace () ==
5791- (inst->getOperand (0 ))->getType ()->getPointerAddressSpace ()) &&
5792- (giInst->getOperand (1 ) == inst->getOperand (1 )) &&
5793- (giInst->getOperand (2 ) == inst->getOperand (2 )) &&
5794- (giInst->getOperand (3 ) == inst->getOperand (3 )) &&
5795- (giInst->getOperand (4 ) == inst->getOperand (4 )))
5796- {
5797- callSet.push_back (giInst);
5798- }
5799- }
5800- }
5801- }
5802- }
5803- }
5804-
5805- // if there are more predecessor than the ones with urb partial write,
5806- // skip the optimization as it might increase the number of times it needs to do the urb write.
5807- if (succBB->hasNPredecessorsOrMore (callSet.size () + 1 ))
5808- return ;
5809-
5810- if (callSet.size () < 2 )
5811- return ;
5812-
5813- // start the conversion
5814- PHINode* p8 = PHINode::Create (inst->getOperand (8 )->getType (), callSet.size (), " " , &(succBB->front ()));
5815- PHINode* p7 = PHINode::Create (inst->getOperand (7 )->getType (), callSet.size (), " " , &(succBB->front ()));
5816- PHINode* p6 = PHINode::Create (inst->getOperand (6 )->getType (), callSet.size (), " " , &(succBB->front ()));
5817- PHINode* p5 = PHINode::Create (inst->getOperand (5 )->getType (), callSet.size (), " " , &(succBB->front ()));
5818- for (unsigned int i = 0 ; i < callSet.size (); i++)
5819- {
5820- p5->addIncoming (callSet[i]->getOperand (5 ), callSet[i]->getParent ());
5821- p6->addIncoming (callSet[i]->getOperand (6 ), callSet[i]->getParent ());
5822- p7->addIncoming (callSet[i]->getOperand (7 ), callSet[i]->getParent ());
5823- p8->addIncoming (callSet[i]->getOperand (8 ), callSet[i]->getParent ());
5824- }
5825-
5826- inst->removeFromParent ();
5827- inst->insertAfter (p8);
5828-
5829- if (inst->getOperand (0 ) && inst->getOperand (0 )->hasOneUse ())
5830- {
5831- if (Instruction* itp = dyn_cast<Instruction>(inst->getOperand (0 )))
5832- {
5833- itp->removeFromParent ();
5834- itp->insertAfter (p8);
5835- }
5836- }
5837-
5838- inst->setOperand (5 , p5);
5839- inst->setOperand (6 , p6);
5840- inst->setOperand (7 , p7);
5841- inst->setOperand (8 , p8);
5842-
5843- for (unsigned int i = 1 ; i < callSet.size (); i++)
5844- {
5845- callSet[i]->eraseFromParent ();
5846- }
5847- }
5848- }
5849- }
5850-
5851- void MergeMemFromBranchOpt::visitCallInst (CallInst& C)
5852- {
5853- if (llvm::GenIntrinsicInst* inst = llvm::dyn_cast<GenIntrinsicInst>(&C))
5854- {
5855- if (inst->getIntrinsicID () == GenISAIntrinsic::GenISA_typedwrite)
5856- {
5857- visitTypedWrite (inst);
5858- }
5859- }
5860- }
5861-
5862- bool MergeMemFromBranchOpt::runOnFunction (Function& F)
5863- {
5864- visit (F);
5865- return false ;
5866- }
5867-
58685689namespace {
58695690 class InsertBranchOpt : public FunctionPass
58705691 {
0 commit comments