@@ -34,11 +34,147 @@ VarSplitPass::VarSplitPass(G4_Kernel& k) : kernel(k)
3434{
3535}
3636
37+ void VarSplitPass::buildPreVerify ()
38+ {
39+ for (auto bb : kernel.fg .getBBList ())
40+ {
41+ for (auto inst : bb->getInstList ())
42+ {
43+ if (inst->getDst ())
44+ {
45+ splitVerify[inst].dst = inst->getDst ();
46+ splitVerify[inst].dstLb = inst->getDst ()->getLeftBound ();
47+ splitVerify[inst].dstRb = inst->getDst ()->getRightBound ();
48+ }
49+ for (unsigned int i = 0 ; i != G4_MAX_SRCS; i++)
50+ {
51+ if (inst->getSrc (i) && inst->getSrc (i)->isSrcRegRegion ())
52+ {
53+ splitVerify[inst].src [i] = inst->getSrc (i);
54+ splitVerify[inst].srcLb [i] = inst->getSrc (i)->getLeftBound ();
55+ splitVerify[inst].srcRb [i] = inst->getSrc (i)->getRightBound ();
56+ }
57+ }
58+ }
59+ }
60+ }
61+
62+ void VarSplitPass::verify ()
63+ {
64+ // verify
65+ // parent, <child, <lb, rb>>
66+ std::unordered_map<G4_Declare*, std::unordered_map<G4_Declare*, std::pair<unsigned int , unsigned int >>> parentSplit;
67+ std::unordered_set<G4_Declare*> splitDcls;
68+
69+ auto getChildData = [&](G4_Declare* child)
70+ {
71+ std::pair<unsigned int , unsigned int > childLbRb = { 0 ,0 };
72+ bool found = false ;
73+ for (auto & item : parentSplit)
74+ {
75+ for (auto & itemCh : (item).second )
76+ {
77+ if (itemCh.first == child)
78+ {
79+ MUST_BE_TRUE (!found, " Duplicate lb/rb entry found" );
80+ childLbRb = itemCh.second ;
81+ found = true ;
82+ }
83+ }
84+ }
85+
86+ MUST_BE_TRUE (found, " Didnt find child dcl" );
87+ return childLbRb;
88+ };
89+
90+ // create parent->child mapping
91+ for (auto bb : kernel.fg .getBBList ())
92+ {
93+ for (auto inst : bb->getInstList ())
94+ {
95+ if (inst->isSplitIntrinsic ())
96+ {
97+ // ensure this is split mov instruction
98+ MUST_BE_TRUE (inst->isSplitIntrinsic (), " Didnt expect new non-split intrinsic instruction" );
99+
100+ // verify that split instruction's dst, src(0) is correct
101+ splitDcls.insert (inst->getDst ()->getTopDcl ());
102+
103+ MUST_BE_TRUE (!inst->getSrc (0 )->getTopDcl ()->getAddressed (), " Shouldnt split indirectly addressed variable" );
104+
105+ auto origSrc0 = inst->getSrc (0 )->asSrcRegRegion ();
106+ auto origLb = origSrc0->getLeftBound ();
107+ auto origRb = origSrc0->getRightBound ();
108+ auto itemToInsert = std::make_pair (inst->getDst ()->getTopDcl (), std::make_pair ((unsigned int )origLb, (unsigned int )origRb));
109+ parentSplit[origSrc0->getTopDcl ()].insert (itemToInsert);
110+ }
111+ }
112+ }
113+
114+ // now check whether usage of child is correct
115+ std::unordered_map<G4_Declare*, unsigned int > parentDefCount;
116+ for (auto bb : kernel.fg .getBBList ())
117+ {
118+ for (auto inst : bb->getInstList ())
119+ {
120+ auto dst = inst->getDst ();
121+
122+ if (dst && splitDcls.find (dst->getTopDcl ()) != splitDcls.end ())
123+ {
124+ MUST_BE_TRUE (inst->isSplitIntrinsic (), " Found split dcl as dst in non-split intrinsic instruction" );
125+ }
126+
127+ if (dst && parentSplit.find (dst->getTopDcl ()) != parentSplit.find (dst->getTopDcl ()))
128+ {
129+ auto oldDefCount = parentDefCount[dst->getTopDcl ()];
130+ parentDefCount[dst->getTopDcl ()] = oldDefCount + 1 ;
131+ MUST_BE_TRUE (oldDefCount == 0 , " Found second def of parent of split variable" );
132+ }
133+
134+ for (unsigned int i = 0 ; i != G4_MAX_SRCS; i++)
135+ {
136+ auto src = inst->getSrc (i);
137+ if (!src || !src->asSrcRegRegion ())
138+ continue ;
139+
140+ if (splitDcls.find (src->asSrcRegRegion ()->getTopDcl ()) == splitDcls.end ())
141+ continue ; // not a split dcl
142+
143+ // src is a split dcl, verify its usage is consistent with pre-transformation data structure
144+ auto lb = src->getLeftBound ();
145+ auto rb = src->getRightBound ();
146+
147+ auto childData = getChildData (src->asSrcRegRegion ()->getTopDcl ());
148+ auto childLb = childData.first ;
149+ // auto childRb = childData.second;
150+
151+ auto totalLb = childLb + lb;
152+ auto totalRb = totalLb + rb;
153+
154+ auto origInstData = splitVerify[inst];
155+ auto origLb = origInstData.srcLb [i];
156+ auto origRb = origInstData.srcRb [i];
157+
158+ MUST_BE_TRUE (origLb == totalLb, " Mismatch in lb" );
159+ MUST_BE_TRUE (origRb == totalRb, " Mismatch in rb" );
160+ }
161+ }
162+ }
163+
164+ printf (" Split verification passed successfully!\n " );
165+ }
166+
37167void VarSplitPass::run ()
38168{
169+ if (kernel.getOption (vISA_VerifyExplicitSplit))
170+ buildPreVerify ();
171+
39172 findSplitCandidates ();
40173
41174 split ();
175+
176+ if (kernel.getOption (vISA_VerifyExplicitSplit))
177+ verify ();
42178}
43179
44180void VarSplitPass::findSplitCandidates ()
0 commit comments