@@ -192,12 +192,108 @@ int Gia_ManDupOrderDfs_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
192192 return pObj -> Value = Gia_ManAppendAnd ( pNew , Gia_ObjFanin0Copy (pObj ), Gia_ObjFanin1Copy (pObj ) );
193193}
194194
195+ /**Function*************************************************************
196+
197+ Synopsis [Propagates origin mapping from old to new manager.]
198+
199+ Description [Uses Value field of old objects to find corresponding new objects.]
200+
201+ SideEffects []
202+
203+ SeeAlso []
204+
205+ ***********************************************************************/
206+ void Gia_ManOriginsDup ( Gia_Man_t * pNew , Gia_Man_t * pOld )
207+ {
208+ Gia_Obj_t * pObj ;
209+ int i ;
210+ if ( !pOld -> vOrigins )
211+ return ;
212+ pNew -> vOrigins = Vec_IntStartFull ( Gia_ManObjNum (pNew ) );
213+ Gia_ManForEachObj ( pOld , pObj , i )
214+ {
215+ if ( (int )Gia_ObjValue (pObj ) != -1 )
216+ {
217+ int iNew = Abc_Lit2Var ( Gia_ObjValue (pObj ) );
218+ if ( iNew < Gia_ManObjNum (pNew ) )
219+ Vec_IntWriteEntry ( pNew -> vOrigins , iNew ,
220+ Vec_IntEntry (pOld -> vOrigins , i ) );
221+ }
222+ }
223+ }
224+
225+ /**Function*************************************************************
226+
227+ Synopsis [Restores origins after GIA->AIG->GIA round-trip.]
228+
229+ Description [CIs map 1:1 in order. CO drivers map 1:1 (output
230+ correspondence preserved through optimization). Remaining AND nodes
231+ get origins via top-down propagation from CO drivers through fanin
232+ cones. Note: shared nodes between multiple CO cones get the origin
233+ of whichever CO driver is visited first (non-deterministic but
234+ acceptable for best-effort source attribution).]
235+
236+ SideEffects []
237+
238+ SeeAlso []
239+
240+ ***********************************************************************/
241+ void Gia_ManOriginsAfterRoundTrip ( Gia_Man_t * pNew , Gia_Man_t * pOld )
242+ {
243+ Gia_Obj_t * pObj ;
244+ int i ;
245+ if ( !pOld -> vOrigins )
246+ return ;
247+ assert ( Gia_ManCiNum (pNew ) == Gia_ManCiNum (pOld ) );
248+ assert ( Gia_ManCoNum (pNew ) == Gia_ManCoNum (pOld ) );
249+ pNew -> vOrigins = Vec_IntStartFull ( Gia_ManObjNum (pNew ) );
250+ // const0
251+ if ( Vec_IntSize (pOld -> vOrigins ) > 0 )
252+ Vec_IntWriteEntry ( pNew -> vOrigins , 0 , Vec_IntEntry (pOld -> vOrigins , 0 ) );
253+ // CIs map 1:1 in order
254+ Gia_ManForEachCi ( pNew , pObj , i )
255+ {
256+ int iNewObj = Gia_ObjId ( pNew , pObj );
257+ int iOldCi = Gia_ObjId ( pOld , Gia_ManCi (pOld , i ) );
258+ Vec_IntWriteEntry ( pNew -> vOrigins , iNewObj ,
259+ Vec_IntEntry (pOld -> vOrigins , iOldCi ) );
260+ }
261+ // CO drivers map 1:1 (output correspondence preserved through optimization)
262+ Gia_ManForEachCo ( pNew , pObj , i )
263+ {
264+ int iNewDriver = Gia_ObjFaninId0p ( pNew , pObj );
265+ Gia_Obj_t * pOldCo = Gia_ManCo ( pOld , i );
266+ int iOldDriver = Gia_ObjFaninId0p ( pOld , pOldCo );
267+ if ( iNewDriver > 0 && Vec_IntEntry (pNew -> vOrigins , iNewDriver ) == -1 )
268+ Vec_IntWriteEntry ( pNew -> vOrigins , iNewDriver ,
269+ Vec_IntEntry (pOld -> vOrigins , iOldDriver ) );
270+ }
271+ // Top-down propagation: spread CO driver origins backward through fanin cones
272+ // Walk AND nodes in reverse topological order (high to low ID)
273+ for ( i = Gia_ManObjNum (pNew ) - 1 ; i > 0 ; i -- )
274+ {
275+ int f0 , f1 , orig ;
276+ pObj = Gia_ManObj ( pNew , i );
277+ if ( !Gia_ObjIsAnd (pObj ) )
278+ continue ;
279+ orig = Vec_IntEntry ( pNew -> vOrigins , i );
280+ if ( orig < 0 )
281+ continue ;
282+ f0 = Gia_ObjFaninId0 (pObj , i );
283+ f1 = Gia_ObjFaninId1 (pObj , i );
284+ if ( f0 > 0 && Vec_IntEntry (pNew -> vOrigins , f0 ) == -1 )
285+ Vec_IntWriteEntry ( pNew -> vOrigins , f0 , orig );
286+ if ( f1 > 0 && Vec_IntEntry (pNew -> vOrigins , f1 ) == -1 )
287+ Vec_IntWriteEntry ( pNew -> vOrigins , f1 , orig );
288+ }
289+ }
290+
195291/**Function*************************************************************
196292
197293 Synopsis [Duplicates AIG while putting objects in the DFS order.]
198294
199295 Description []
200-
296+
201297 SideEffects []
202298
203299 SeeAlso []
@@ -220,6 +316,7 @@ Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p )
220316 pObj -> Value = Gia_ManAppendCi (pNew );
221317 assert ( Gia_ManCiNum (pNew ) == Gia_ManCiNum (p ) );
222318 Gia_ManDupRemapCis ( pNew , p );
319+ Gia_ManOriginsDup ( pNew , p );
223320 Gia_ManDupRemapEquiv ( pNew , p );
224321 Gia_ManSetRegNum ( pNew , Gia_ManRegNum (p ) );
225322 return pNew ;
@@ -544,6 +641,7 @@ Gia_Man_t * Gia_ManDupOrderAiger( Gia_Man_t * p )
544641 pObj -> Value = Gia_ManAppendAnd ( pNew , Gia_ObjFanin0Copy (pObj ), Gia_ObjFanin1Copy (pObj ) );
545642 Gia_ManForEachCo ( p , pObj , i )
546643 pObj -> Value = Gia_ManAppendCo ( pNew , Gia_ObjFanin0Copy (pObj ) );
644+ Gia_ManOriginsDup ( pNew , p );
547645 Gia_ManDupRemapEquiv ( pNew , p );
548646 Gia_ManSetRegNum ( pNew , Gia_ManRegNum (p ) );
549647 assert ( Gia_ManIsNormalized (pNew ) );
@@ -777,6 +875,7 @@ Gia_Man_t * Gia_ManDup( Gia_Man_t * p )
777875 else if ( Gia_ObjIsCo (pObj ) )
778876 pObj -> Value = Gia_ManAppendCo ( pNew , Gia_ObjFanin0Copy (pObj ) );
779877 }
878+ Gia_ManOriginsDup ( pNew , p );
780879 Gia_ManSetRegNum ( pNew , Gia_ManRegNum (p ) );
781880 if ( p -> pCexSeq )
782881 pNew -> pCexSeq = Abc_CexDup ( p -> pCexSeq , Gia_ManRegNum (p ) );
@@ -1574,6 +1673,7 @@ Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p )
15741673 pNew -> pSibls [Abc_Lit2Var (pObj -> Value )] = Abc_Lit2Var (pSibl -> Value );
15751674 }
15761675 }
1676+ Gia_ManOriginsDup ( pNew , p );
15771677 return pNew ;
15781678}
15791679
@@ -1805,6 +1905,7 @@ Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p )
18051905 Gia_ManDupDfs_rec ( pNew , p , Gia_ObjFanin0 (pObj ) );
18061906 Gia_ManForEachCo ( p , pObj , i )
18071907 pObj -> Value = Gia_ManAppendCo ( pNew , Gia_ObjFanin0Copy (pObj ) );
1908+ Gia_ManOriginsDup ( pNew , p );
18081909 Gia_ManSetRegNum ( pNew , Gia_ManRegNum (p ) );
18091910 pNew -> nConstrs = p -> nConstrs ;
18101911 if ( p -> pCexSeq )
@@ -1873,6 +1974,7 @@ Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p )
18731974 Gia_ManDupDfsRehash_rec ( pNew , p , Gia_ObjFanin0 (pObj ) );
18741975 Gia_ManForEachCo ( p , pObj , i )
18751976 pObj -> Value = Gia_ManAppendCo ( pNew , Gia_ObjFanin0Copy (pObj ) );
1977+ Gia_ManOriginsDup ( pNew , p );
18761978 pNew = Gia_ManCleanup ( pTemp = pNew );
18771979 Gia_ManStop ( pTemp );
18781980 Gia_ManSetRegNum ( pNew , Gia_ManRegNum (p ) );
@@ -3889,6 +3991,8 @@ Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias )
38893991 Gia_ManChoiceMiter_rec ( pNew , pGia , Gia_ManCo ( pGia , k ) );
38903992 }
38913993 Gia_ManHashStop ( pNew );
3994+ // propagate origins from the first (primary) AIG
3995+ Gia_ManOriginsDup ( pNew , pGia0 );
38923996 // check the presence of dangling nodes
38933997 nNodes = Gia_ManHasDangling ( pNew );
38943998 //assert( nNodes == 0 );
0 commit comments