@@ -640,9 +640,10 @@ class NewGVN {
640
640
SmallPtrSetImpl<Value *> &Visited,
641
641
MemoryAccess *MemAccess, Instruction *OrigInst,
642
642
BasicBlock *PredBB);
643
-
644
- bool OpIsSafeForPHIOfOps (Value *Op, Instruction *OrigInst,
645
- const BasicBlock *PHIBlock,
643
+ bool OpIsSafeForPHIOfOpsHelper (Value *V, const BasicBlock *PHIBlock,
644
+ SmallPtrSetImpl<const Value *> &Visited,
645
+ SmallVectorImpl<Instruction *> &Worklist);
646
+ bool OpIsSafeForPHIOfOps (Value *Op, const BasicBlock *PHIBlock,
646
647
SmallPtrSetImpl<const Value *> &);
647
648
void addPhiOfOps (PHINode *Op, BasicBlock *BB, Instruction *ExistingValue);
648
649
void removePhiOfOps (Instruction *I, PHINode *PHITemp);
@@ -2505,22 +2506,19 @@ static bool okayForPHIOfOps(const Instruction *I) {
2505
2506
isa<LoadInst>(I);
2506
2507
}
2507
2508
2508
- // Return true if this operand will be safe to use for phi of ops.
2509
- //
2510
- // The reason some operands are unsafe is that we are not trying to recursively
2511
- // translate everything back through phi nodes. We actually expect some lookups
2512
- // of expressions to fail. In particular, a lookup where the expression cannot
2513
- // exist in the predecessor. This is true even if the expression, as shown, can
2514
- // be determined to be constant.
2515
- bool NewGVN::OpIsSafeForPHIOfOps (Value *V, Instruction *OrigInst,
2516
- const BasicBlock *PHIBlock,
2517
- SmallPtrSetImpl<const Value *> &Visited) {
2509
+ bool NewGVN::OpIsSafeForPHIOfOpsHelper (
2510
+ Value *V, const BasicBlock *PHIBlock,
2511
+ SmallPtrSetImpl<const Value *> &Visited,
2512
+ SmallVectorImpl<Instruction *> &Worklist) {
2513
+
2518
2514
if (!isa<Instruction>(V))
2519
2515
return true ;
2520
2516
auto OISIt = OpSafeForPHIOfOps.find (V);
2521
2517
if (OISIt != OpSafeForPHIOfOps.end ())
2522
2518
return OISIt->second ;
2523
2519
2520
+ // Keep walking until we either dominate the phi block, or hit a phi, or run
2521
+ // out of things to check.
2524
2522
if (DT->properlyDominates (getBlockForValue (V), PHIBlock)) {
2525
2523
OpSafeForPHIOfOps.insert ({V, true });
2526
2524
return true ;
@@ -2531,7 +2529,6 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *V, Instruction *OrigInst,
2531
2529
return false ;
2532
2530
}
2533
2531
2534
- SmallVector<Instruction *, 4 > Worklist;
2535
2532
auto *OrigI = cast<Instruction>(V);
2536
2533
for (auto *Op : OrigI->operand_values ()) {
2537
2534
if (!isa<Instruction>(Op))
@@ -2545,40 +2542,29 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *V, Instruction *OrigInst,
2545
2542
}
2546
2543
continue ;
2547
2544
}
2545
+ if (!Visited.insert (Op).second )
2546
+ continue ;
2548
2547
Worklist.push_back (cast<Instruction>(Op));
2549
2548
}
2549
+ return true ;
2550
+ }
2550
2551
2552
+ // Return true if this operand will be safe to use for phi of ops.
2553
+ //
2554
+ // The reason some operands are unsafe is that we are not trying to recursively
2555
+ // translate everything back through phi nodes. We actually expect some lookups
2556
+ // of expressions to fail. In particular, a lookup where the expression cannot
2557
+ // exist in the predecessor. This is true even if the expression, as shown, can
2558
+ // be determined to be constant.
2559
+ bool NewGVN::OpIsSafeForPHIOfOps (Value *V, const BasicBlock *PHIBlock,
2560
+ SmallPtrSetImpl<const Value *> &Visited) {
2561
+ SmallVector<Instruction *, 4 > Worklist;
2562
+ if (!OpIsSafeForPHIOfOpsHelper (V, PHIBlock, Visited, Worklist))
2563
+ return false ;
2551
2564
while (!Worklist.empty ()) {
2552
2565
auto *I = Worklist.pop_back_val ();
2553
- // Keep walking until we either dominate the phi block, or hit a phi, or run
2554
- // out of things to check.
2555
- //
2556
- if (DT->properlyDominates (getBlockForValue (I), PHIBlock)) {
2557
- OpSafeForPHIOfOps.insert ({I, true });
2558
- continue ;
2559
- }
2560
- // PHI in the same block.
2561
- if (isa<PHINode>(I) && getBlockForValue (I) == PHIBlock) {
2562
- OpSafeForPHIOfOps.insert ({I, false });
2563
- OpSafeForPHIOfOps.insert ({V, false });
2566
+ if (!OpIsSafeForPHIOfOpsHelper (I, PHIBlock, Visited, Worklist))
2564
2567
return false ;
2565
- }
2566
- for (auto *Op : cast<Instruction>(I)->operand_values ()) {
2567
- if (!isa<Instruction>(Op))
2568
- continue ;
2569
- // See if we already know the answer for this node.
2570
- auto OISIt = OpSafeForPHIOfOps.find (Op);
2571
- if (OISIt != OpSafeForPHIOfOps.end ()) {
2572
- if (!OISIt->second ) {
2573
- OpSafeForPHIOfOps.insert ({V, false });
2574
- return false ;
2575
- }
2576
- continue ;
2577
- }
2578
- if (!Visited.insert (Op).second )
2579
- continue ;
2580
- Worklist.push_back (cast<Instruction>(Op));
2581
- }
2582
2568
}
2583
2569
OpSafeForPHIOfOps.insert ({V, true });
2584
2570
return true ;
@@ -2697,9 +2683,9 @@ NewGVN::makePossiblePHIOfOps(Instruction *I,
2697
2683
Op = ValuePHI->getIncomingValue (PredNum);
2698
2684
}
2699
2685
// If we phi-translated the op, it must be safe.
2700
- SafeForPHIOfOps = SafeForPHIOfOps &&
2701
- (Op != OrigOp ||
2702
- OpIsSafeForPHIOfOps (Op, I , PHIBlock, VisitedOps));
2686
+ SafeForPHIOfOps =
2687
+ SafeForPHIOfOps &&
2688
+ (Op != OrigOp || OpIsSafeForPHIOfOps (Op, PHIBlock, VisitedOps));
2703
2689
}
2704
2690
// FIXME: For those things that are not safe we could generate
2705
2691
// expressions all the way down, and see if this comes out to a
0 commit comments