@@ -2083,13 +2083,6 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) {
20832083 return Changed;
20842084}
20852085
2086- static bool hasUsersIn (Value *V, BasicBlock *BB) {
2087- return any_of (V->users (), [BB](User *U) {
2088- auto *I = dyn_cast<Instruction>(U);
2089- return I && I->getParent () == BB;
2090- });
2091- }
2092-
20932086bool GVNPass::processAssumeIntrinsic (AssumeInst *IntrinsicI) {
20942087 Value *V = IntrinsicI->getArgOperand (0 );
20952088
@@ -2148,85 +2141,7 @@ bool GVNPass::processAssumeIntrinsic(AssumeInst *IntrinsicI) {
21482141 }
21492142
21502143 Constant *True = ConstantInt::getTrue (V->getContext ());
2151- bool Changed = false ;
2152-
2153- for (BasicBlock *Successor : successors (IntrinsicI->getParent ())) {
2154- BasicBlockEdge Edge (IntrinsicI->getParent (), Successor);
2155-
2156- // This property is only true in dominated successors, propagateEquality
2157- // will check dominance for us.
2158- Changed |= propagateEquality (V, True, Edge, false );
2159- }
2160-
2161- // We can replace assume value with true, which covers cases like this:
2162- // call void @llvm.assume(i1 %cmp)
2163- // br i1 %cmp, label %bb1, label %bb2 ; will change %cmp to true
2164- ReplaceOperandsWithMap[V] = True;
2165-
2166- // Similarly, after assume(!NotV) we know that NotV == false.
2167- Value *NotV;
2168- if (match (V, m_Not (m_Value (NotV))))
2169- ReplaceOperandsWithMap[NotV] = ConstantInt::getFalse (V->getContext ());
2170-
2171- // If we find an equality fact, canonicalize all dominated uses in this block
2172- // to one of the two values. We heuristically choice the "oldest" of the
2173- // two where age is determined by value number. (Note that propagateEquality
2174- // above handles the cross block case.)
2175- //
2176- // Key case to cover are:
2177- // 1)
2178- // %cmp = fcmp oeq float 3.000000e+00, %0 ; const on lhs could happen
2179- // call void @llvm.assume(i1 %cmp)
2180- // ret float %0 ; will change it to ret float 3.000000e+00
2181- // 2)
2182- // %load = load float, float* %addr
2183- // %cmp = fcmp oeq float %load, %0
2184- // call void @llvm.assume(i1 %cmp)
2185- // ret float %load ; will change it to ret float %0
2186- if (auto *CmpI = dyn_cast<CmpInst>(V)) {
2187- if (CmpI->isEquivalence ()) {
2188- Value *CmpLHS = CmpI->getOperand (0 );
2189- Value *CmpRHS = CmpI->getOperand (1 );
2190- // Heuristically pick the better replacement -- the choice of heuristic
2191- // isn't terribly important here, but the fact we canonicalize on some
2192- // replacement is for exposing other simplifications.
2193- // TODO: pull this out as a helper function and reuse w/ existing
2194- // (slightly different) logic.
2195- if (isa<Constant>(CmpLHS) && !isa<Constant>(CmpRHS))
2196- std::swap (CmpLHS, CmpRHS);
2197- if (!isa<Instruction>(CmpLHS) && isa<Instruction>(CmpRHS))
2198- std::swap (CmpLHS, CmpRHS);
2199- if ((isa<Argument>(CmpLHS) && isa<Argument>(CmpRHS)) ||
2200- (isa<Instruction>(CmpLHS) && isa<Instruction>(CmpRHS))) {
2201- // Move the 'oldest' value to the right-hand side, using the value
2202- // number as a proxy for age.
2203- uint32_t LVN = VN.lookupOrAdd (CmpLHS);
2204- uint32_t RVN = VN.lookupOrAdd (CmpRHS);
2205- if (LVN < RVN)
2206- std::swap (CmpLHS, CmpRHS);
2207- }
2208-
2209- // Handle degenerate case where we either haven't pruned a dead path or a
2210- // removed a trivial assume yet.
2211- if (isa<Constant>(CmpLHS) && isa<Constant>(CmpRHS))
2212- return Changed;
2213-
2214- LLVM_DEBUG (dbgs () << " Replacing dominated uses of "
2215- << *CmpLHS << " with "
2216- << *CmpRHS << " in block "
2217- << IntrinsicI->getParent ()->getName () << " \n " );
2218-
2219- // Setup the replacement map - this handles uses within the same block.
2220- if (hasUsersIn (CmpLHS, IntrinsicI->getParent ()))
2221- ReplaceOperandsWithMap[CmpLHS] = CmpRHS;
2222-
2223- // NOTE: The non-block local cases are handled by the call to
2224- // propagateEquality above; this block is just about handling the block
2225- // local cases. TODO: There's a bunch of logic in propagateEqualiy which
2226- // isn't duplicated for the block local case, can we share it somehow?
2227- }
2228- }
2229- return Changed;
2144+ return propagateEquality (V, True, IntrinsicI);
22302145}
22312146
22322147static void patchAndReplaceAllUsesWith (Instruction *I, Value *Repl) {
@@ -2496,39 +2411,28 @@ void GVNPass::assignBlockRPONumber(Function &F) {
24962411 InvalidBlockRPONumbers = false ;
24972412}
24982413
2499- bool GVNPass::replaceOperandsForInBlockEquality (Instruction *Instr) const {
2500- bool Changed = false ;
2501- for (unsigned OpNum = 0 ; OpNum < Instr->getNumOperands (); ++OpNum) {
2502- Use &Operand = Instr->getOperandUse (OpNum);
2503- auto It = ReplaceOperandsWithMap.find (Operand.get ());
2504- if (It != ReplaceOperandsWithMap.end ()) {
2505- const DataLayout &DL = Instr->getDataLayout ();
2506- if (!canReplacePointersInUseIfEqual (Operand, It->second , DL))
2507- continue ;
2508-
2509- LLVM_DEBUG (dbgs () << " GVN replacing: " << *Operand << " with "
2510- << *It->second << " in instruction " << *Instr << ' \n ' );
2511- Instr->setOperand (OpNum, It->second );
2512- Changed = true ;
2513- }
2514- }
2515- return Changed;
2516- }
2517-
2518- // / The given values are known to be equal in every block
2414+ // / The given values are known to be equal in every use
25192415// / dominated by 'Root'. Exploit this, for example by replacing 'LHS' with
25202416// / 'RHS' everywhere in the scope. Returns whether a change was made.
25212417// / If DominatesByEdge is false, then it means that we will propagate the RHS
25222418// / value starting from the end of Root.Start.
2523- bool GVNPass::propagateEquality (Value *LHS, Value *RHS,
2524- const BasicBlockEdge &Root ,
2525- bool DominatesByEdge ) {
2419+ bool GVNPass::propagateEquality (
2420+ Value *LHS, Value *RHS ,
2421+ const std::variant<BasicBlockEdge, Instruction *> &Root ) {
25262422 SmallVector<std::pair<Value*, Value*>, 4 > Worklist;
25272423 Worklist.push_back (std::make_pair (LHS, RHS));
25282424 bool Changed = false ;
2529- // For speed, compute a conservative fast approximation to
2530- // DT->dominates(Root, Root.getEnd());
2531- const bool RootDominatesEnd = isOnlyReachableViaThisEdge (Root, DT);
2425+ SmallVector<const BasicBlock *> DominatedBlocks;
2426+ if (const BasicBlockEdge *Edge = std::get_if<BasicBlockEdge>(&Root)) {
2427+ // For speed, compute a conservative fast approximation to
2428+ // DT->dominates(Root, Root.getEnd());
2429+ if (isOnlyReachableViaThisEdge (*Edge, DT))
2430+ DominatedBlocks.push_back (Edge->getEnd ());
2431+ } else {
2432+ Instruction *I = std::get<Instruction *>(Root);
2433+ for (const auto *Node : DT->getNode (I->getParent ())->children ())
2434+ DominatedBlocks.push_back (Node->getBlock ());
2435+ }
25322436
25332437 while (!Worklist.empty ()) {
25342438 std::pair<Value*, Value*> Item = Worklist.pop_back_val ();
@@ -2576,9 +2480,9 @@ bool GVNPass::propagateEquality(Value *LHS, Value *RHS,
25762480 // using the leader table is about compiling faster, not optimizing better).
25772481 // The leader table only tracks basic blocks, not edges. Only add to if we
25782482 // have the simple case where the edge dominates the end.
2579- if (RootDominatesEnd && !isa<Instruction>(RHS) &&
2580- canReplacePointersIfEqual (LHS, RHS, DL) )
2581- LeaderTable.insert (LVN, RHS, Root. getEnd () );
2483+ if (!isa<Instruction>(RHS) && canReplacePointersIfEqual (LHS, RHS, DL))
2484+ for ( const BasicBlock *BB : DominatedBlocks )
2485+ LeaderTable.insert (LVN, RHS, BB );
25822486
25832487 // Replace all occurrences of 'LHS' with 'RHS' everywhere in the scope. As
25842488 // LHS always has at least one use that is not dominated by Root, this will
@@ -2588,12 +2492,14 @@ bool GVNPass::propagateEquality(Value *LHS, Value *RHS,
25882492 auto CanReplacePointersCallBack = [&DL](const Use &U, const Value *To) {
25892493 return canReplacePointersInUseIfEqual (U, To, DL);
25902494 };
2591- unsigned NumReplacements =
2592- DominatesByEdge
2593- ? replaceDominatedUsesWithIf (LHS, RHS, *DT, Root,
2594- CanReplacePointersCallBack)
2595- : replaceDominatedUsesWithIf (LHS, RHS, *DT, Root.getStart (),
2596- CanReplacePointersCallBack);
2495+ unsigned NumReplacements;
2496+ if (const BasicBlockEdge *Edge = std::get_if<BasicBlockEdge>(&Root))
2497+ NumReplacements = replaceDominatedUsesWithIf (
2498+ LHS, RHS, *DT, *Edge, CanReplacePointersCallBack);
2499+ else
2500+ NumReplacements = replaceDominatedUsesWithIf (
2501+ LHS, RHS, *DT, std::get<Instruction *>(Root),
2502+ CanReplacePointersCallBack);
25972503
25982504 if (NumReplacements > 0 ) {
25992505 Changed = true ;
@@ -2652,26 +2558,45 @@ bool GVNPass::propagateEquality(Value *LHS, Value *RHS,
26522558 // If the number we were assigned was brand new then there is no point in
26532559 // looking for an instruction realizing it: there cannot be one!
26542560 if (Num < NextNum) {
2655- Value *NotCmp = findLeader (Root.getEnd (), Num);
2656- if (NotCmp && isa<Instruction>(NotCmp)) {
2657- unsigned NumReplacements =
2658- DominatesByEdge
2659- ? replaceDominatedUsesWith (NotCmp, NotVal, *DT, Root)
2660- : replaceDominatedUsesWith (NotCmp, NotVal, *DT,
2661- Root.getStart ());
2662- Changed |= NumReplacements > 0 ;
2663- NumGVNEqProp += NumReplacements;
2664- // Cached information for anything that uses NotCmp will be invalid.
2665- if (MD)
2666- MD->invalidateCachedPointerInfo (NotCmp);
2561+ for (const auto &Entry : LeaderTable.getLeaders (Num)) {
2562+ // Only look at leaders that either dominate the start of the edge,
2563+ // or are dominated by the end. This check is not necessary for
2564+ // correctness, it only discards cases for which the following
2565+ // use replacement will not work anyway.
2566+ if (const BasicBlockEdge *Edge = std::get_if<BasicBlockEdge>(&Root)) {
2567+ if (!DT->dominates (Entry.BB , Edge->getStart ()) &&
2568+ !DT->dominates (Edge->getEnd (), Entry.BB ))
2569+ continue ;
2570+ } else {
2571+ auto *InstBB = std::get<Instruction *>(Root)->getParent ();
2572+ if (!DT->dominates (Entry.BB , InstBB) &&
2573+ !DT->dominates (InstBB, Entry.BB ))
2574+ continue ;
2575+ }
2576+
2577+ Value *NotCmp = Entry.Val ;
2578+ if (NotCmp && isa<Instruction>(NotCmp)) {
2579+ unsigned NumReplacements;
2580+ if (const BasicBlockEdge *Edge = std::get_if<BasicBlockEdge>(&Root))
2581+ NumReplacements =
2582+ replaceDominatedUsesWith (NotCmp, NotVal, *DT, *Edge);
2583+ else
2584+ NumReplacements = replaceDominatedUsesWith (
2585+ NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
2586+ Changed |= NumReplacements > 0 ;
2587+ NumGVNEqProp += NumReplacements;
2588+ // Cached information for anything that uses NotCmp will be invalid.
2589+ if (MD)
2590+ MD->invalidateCachedPointerInfo (NotCmp);
2591+ }
26672592 }
26682593 }
26692594 // Ensure that any instruction in scope that gets the "A < B" value number
26702595 // is replaced with false.
26712596 // The leader table only tracks basic blocks, not edges. Only add to if we
26722597 // have the simple case where the edge dominates the end.
2673- if (RootDominatesEnd )
2674- LeaderTable.insert (Num, NotVal, Root. getEnd () );
2598+ for ( const BasicBlock *BB : DominatedBlocks )
2599+ LeaderTable.insert (Num, NotVal, BB );
26752600
26762601 continue ;
26772602 }
@@ -2755,11 +2680,11 @@ bool GVNPass::processInstruction(Instruction *I) {
27552680
27562681 Value *TrueVal = ConstantInt::getTrue (TrueSucc->getContext ());
27572682 BasicBlockEdge TrueE (Parent, TrueSucc);
2758- Changed |= propagateEquality (BranchCond, TrueVal, TrueE, true );
2683+ Changed |= propagateEquality (BranchCond, TrueVal, TrueE);
27592684
27602685 Value *FalseVal = ConstantInt::getFalse (FalseSucc->getContext ());
27612686 BasicBlockEdge FalseE (Parent, FalseSucc);
2762- Changed |= propagateEquality (BranchCond, FalseVal, FalseE, true );
2687+ Changed |= propagateEquality (BranchCond, FalseVal, FalseE);
27632688
27642689 return Changed;
27652690 }
@@ -2780,7 +2705,7 @@ bool GVNPass::processInstruction(Instruction *I) {
27802705 // If there is only a single edge, propagate the case value into it.
27812706 if (SwitchEdges.lookup (Dst) == 1 ) {
27822707 BasicBlockEdge E (Parent, Dst);
2783- Changed |= propagateEquality (SwitchCond, Case.getCaseValue (), E, true );
2708+ Changed |= propagateEquality (SwitchCond, Case.getCaseValue (), E);
27842709 }
27852710 }
27862711 return Changed;
@@ -2908,8 +2833,6 @@ bool GVNPass::processBlock(BasicBlock *BB) {
29082833 if (DeadBlocks.count (BB))
29092834 return false ;
29102835
2911- // Clearing map before every BB because it can be used only for single BB.
2912- ReplaceOperandsWithMap.clear ();
29132836 bool ChangedFunction = false ;
29142837
29152838 // Since we may not have visited the input blocks of the phis, we can't
@@ -2921,11 +2844,8 @@ bool GVNPass::processBlock(BasicBlock *BB) {
29212844 for (PHINode *PN : PHINodesToRemove) {
29222845 removeInstruction (PN);
29232846 }
2924- for (Instruction &Inst : make_early_inc_range (*BB)) {
2925- if (!ReplaceOperandsWithMap.empty ())
2926- ChangedFunction |= replaceOperandsForInBlockEquality (&Inst);
2847+ for (Instruction &Inst : make_early_inc_range (*BB))
29272848 ChangedFunction |= processInstruction (&Inst);
2928- }
29292849 return ChangedFunction;
29302850}
29312851
0 commit comments