@@ -64,7 +64,7 @@ static cl::opt<bool> SaveTemps("save-temps", cl::desc("Save temp files"),
64
64
static cl::opt<unsigned >
65
65
NumShuffles (" num-shuffles" ,
66
66
cl::desc (" Number of times to shuffle and verify use-lists" ),
67
- cl::init(5 ));
67
+ cl::init(1 ));
68
68
69
69
namespace {
70
70
@@ -413,53 +413,93 @@ static void shuffleValueUseLists(Value *V, std::minstd_rand0 &Gen,
413
413
});
414
414
}
415
415
416
- // / Shuffle all use-lists in a module.
417
- static void shuffleUseLists (Module &M, unsigned SeedOffset) {
418
- DEBUG (dbgs () << " *** shuffle-use-lists ***\n " );
419
- std::minstd_rand0 Gen (std::minstd_rand0::default_seed + SeedOffset);
420
- DenseSet<Value *> Seen;
416
+ static void reverseValueUseLists (Value *V, DenseSet<Value *> &Seen) {
417
+ if (!Seen.insert (V).second )
418
+ return ;
419
+
420
+ if (auto *C = dyn_cast<Constant>(V))
421
+ if (!isa<GlobalValue>(C))
422
+ for (Value *Op : C->operands ())
423
+ reverseValueUseLists (Op, Seen);
424
+
425
+ if (V->use_empty () || std::next (V->use_begin ()) == V->use_end ())
426
+ // Nothing to shuffle for 0 or 1 users.
427
+ return ;
428
+
429
+ DEBUG ({
430
+ dbgs () << " V = " ;
431
+ V->dump ();
432
+ for (const Use &U : V->uses ()) {
433
+ dbgs () << " - order: op = " << U.getOperandNo () << " , U = " ;
434
+ U.getUser ()->dump ();
435
+ }
436
+ dbgs () << " => reverse\n " ;
437
+ });
421
438
422
- // Shuffle the use-list of each value that would be serialized to an IR file
423
- // (bitcode or assembly).
424
- auto shuffle = [&](Value *V) { shuffleValueUseLists (V, Gen, Seen); };
439
+ V->reverseUseList ();
425
440
441
+ DEBUG ({
442
+ for (const Use &U : V->uses ()) {
443
+ dbgs () << " - order: op = " << U.getOperandNo () << " , U = " ;
444
+ U.getUser ()->dump ();
445
+ }
446
+ });
447
+ }
448
+
449
+ template <class Changer >
450
+ static void changeUseLists (Module &M, Changer changeValueUseList) {
451
+ // Visit every value that would be serialized to an IR file.
452
+ //
426
453
// Globals.
427
454
for (GlobalVariable &G : M.globals ())
428
- shuffle (&G);
455
+ changeValueUseList (&G);
429
456
for (GlobalAlias &A : M.aliases ())
430
- shuffle (&A);
457
+ changeValueUseList (&A);
431
458
for (Function &F : M)
432
- shuffle (&F);
459
+ changeValueUseList (&F);
433
460
434
461
// Constants used by globals.
435
462
for (GlobalVariable &G : M.globals ())
436
463
if (G.hasInitializer ())
437
- shuffle (G.getInitializer ());
464
+ changeValueUseList (G.getInitializer ());
438
465
for (GlobalAlias &A : M.aliases ())
439
- shuffle (A.getAliasee ());
466
+ changeValueUseList (A.getAliasee ());
440
467
for (Function &F : M)
441
468
if (F.hasPrefixData ())
442
- shuffle (F.getPrefixData ());
469
+ changeValueUseList (F.getPrefixData ());
443
470
444
471
// Function bodies.
445
472
for (Function &F : M) {
446
473
for (Argument &A : F.args ())
447
- shuffle (&A);
474
+ changeValueUseList (&A);
448
475
for (BasicBlock &BB : F)
449
- shuffle (&BB);
476
+ changeValueUseList (&BB);
450
477
for (BasicBlock &BB : F)
451
478
for (Instruction &I : BB)
452
- shuffle (&I);
479
+ changeValueUseList (&I);
453
480
454
481
// Constants used by instructions.
455
482
for (BasicBlock &BB : F)
456
483
for (Instruction &I : BB)
457
484
for (Value *Op : I.operands ())
458
485
if ((isa<Constant>(Op) && !isa<GlobalValue>(*Op)) ||
459
486
isa<InlineAsm>(Op))
460
- shuffle (Op);
487
+ changeValueUseList (Op);
461
488
}
489
+ }
490
+
491
+ static void shuffleUseLists (Module &M, unsigned SeedOffset) {
492
+ DEBUG (dbgs () << " *** shuffle-use-lists ***\n " );
493
+ std::minstd_rand0 Gen (std::minstd_rand0::default_seed + SeedOffset);
494
+ DenseSet<Value *> Seen;
495
+ changeUseLists (M, [&](Value *V) { shuffleValueUseLists (V, Gen, Seen); });
496
+ DEBUG (dbgs () << " \n " );
497
+ }
462
498
499
+ static void reverseUseLists (Module &M) {
500
+ DEBUG (dbgs () << " *** reverse-use-lists ***\n " );
501
+ DenseSet<Value *> Seen;
502
+ changeUseLists (M, [&](Value *V) { reverseValueUseLists (V, Seen); });
463
503
DEBUG (dbgs () << " \n " );
464
504
}
465
505
@@ -495,12 +535,20 @@ int main(int argc, char **argv) {
495
535
return 0 ;
496
536
}
497
537
538
+ // Verify the use lists now and after reversing them.
539
+ verifyUseListOrder (*M);
540
+ reverseUseLists (*M);
541
+ verifyUseListOrder (*M);
542
+
498
543
for (unsigned I = 0 , E = NumShuffles; I != E; ++I) {
499
544
DEBUG (dbgs () << " *** iteration: " << I << " ***\n " );
500
545
501
- // Shuffle with a different seed each time so that use-lists that aren't
502
- // modified the first time are likely to be modified the next time.
546
+ // Shuffle with a different (deterministic) seed each time.
503
547
shuffleUseLists (*M, I);
548
+
549
+ // Verify again before and after reversing.
550
+ verifyUseListOrder (*M);
551
+ reverseUseLists (*M);
504
552
verifyUseListOrder (*M);
505
553
}
506
554
0 commit comments