llvm.org GIT mirror llvm / 25bd82a
NewGVN: Evaluate phi of ops expressions before creating phi node git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314611 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Berlin 2 years ago
4 changed file(s) with 85 addition(s) and 61 deletion(s). Raw diff Collapse all Expand all
586586 const Expression *createExpression(Instruction *) const;
587587 const Expression *createBinaryExpression(unsigned, Type *, Value *, Value *,
588588 Instruction *) const;
589 PHIExpression *createPHIExpression(Instruction *, bool &HasBackEdge,
589 // Our canonical form for phi arguments is a pair of incoming value, incoming
590 // basic block.
591 typedef std::pair ValPair;
592 PHIExpression *createPHIExpression(ArrayRef, const Instruction *,
593 BasicBlock *, bool &HasBackEdge,
590594 bool &OriginalOpsConstant) const;
591595 const DeadExpression *createDeadExpression() const;
592596 const VariableExpression *createVariableExpression(Value *) const;
657661 const Expression *performSymbolicLoadEvaluation(Instruction *) const;
658662 const Expression *performSymbolicStoreEvaluation(Instruction *) const;
659663 const Expression *performSymbolicCallEvaluation(Instruction *) const;
660 const Expression *performSymbolicPHIEvaluation(Instruction *) const;
664 void sortPHIOps(MutableArrayRef Ops) const;
665 const Expression *performSymbolicPHIEvaluation(ArrayRef,
666 Instruction *I,
667 BasicBlock *PHIBlock) const;
661668 const Expression *performSymbolicAggrValueEvaluation(Instruction *) const;
662669 const Expression *performSymbolicCmpEvaluation(Instruction *) const;
663670 const Expression *performSymbolicPredicateInfoEvaluation(Instruction *) const;
856863 return CO && isa(CO);
857864 }
858865
866 // Sort PHI Operands into a canonical order. What we use here is an RPO
867 // order. The BlockInstRange numbers are generated in an RPO walk of the basic
868 // blocks.
869 void NewGVN::sortPHIOps(MutableArrayRef Ops) const {
870 std::sort(Ops.begin(), Ops.end(), [&](const ValPair &P1, const ValPair &P2) {
871 return BlockInstRange.lookup(P1.second).first <
872 BlockInstRange.lookup(P2.second).first;
873 });
874 }
875
859876 // Return true if V is a value that will always be available (IE can
860877 // be placed anywhere) in the function. We don't do globals here
861878 // because they are often worse to put in place.
863880 return isa(V) || isa(V);
864881 }
865882
866 PHIExpression *NewGVN::createPHIExpression(Instruction *I, bool &HasBackedge,
883 // Create a PHIExpression from an array of {incoming edge, value} pairs. I is
884 // the original instruction we are creating a PHIExpression for (but may not be
885 // a phi node). We require, as an invariant, that all the PHIOperands in the
886 // same block are sorted the same way. sortPHIOps will sort them into a
887 // canonical order.
888 PHIExpression *NewGVN::createPHIExpression(ArrayRef PHIOperands,
889 const Instruction *I,
890 BasicBlock *PHIBlock,
891 bool &HasBackedge,
867892 bool &OriginalOpsConstant) const {
868 BasicBlock *PHIBlock = getBlockForValue(I);
869 auto *PN = cast(I);
870 auto *E =
871 new (ExpressionAllocator) PHIExpression(PN->getNumOperands(), PHIBlock);
893 unsigned NumOps = PHIOperands.size();
894 auto *E = new (ExpressionAllocator) PHIExpression(NumOps, PHIBlock);
872895
873896 E->allocateOperands(ArgRecycler, ExpressionAllocator);
874 E->setType(I->getType());
875 E->setOpcode(I->getOpcode());
876
877 // NewGVN assumes the operands of a PHI node are in a consistent order across
878 // PHIs. LLVM doesn't seem to always guarantee this. While we need to fix
879 // this in LLVM at some point we don't want GVN to find wrong congruences.
880 // Therefore, here we sort uses in predecessor order.
881 // We're sorting the values by pointer. In theory this might be cause of
882 // non-determinism, but here we don't rely on the ordering for anything
883 // significant, e.g. we don't create new instructions based on it so we're
884 // fine.
885 SmallVector PHIOperands;
886 for (const Use &U : PN->operands())
887 PHIOperands.push_back(&U);
888 std::sort(PHIOperands.begin(), PHIOperands.end(),
889 [&](const Use *U1, const Use *U2) {
890 return PN->getIncomingBlock(*U1) < PN->getIncomingBlock(*U2);
891 });
897 E->setType(PHIOperands.begin()->first->getType());
898 E->setOpcode(Instruction::PHI);
892899
893900 // Filter out unreachable phi operands.
894 auto Filtered = make_filter_range(PHIOperands, [&](const Use *U) {
895 auto *BB = PN->getIncomingBlock(*U);
896 if (isCopyOfPHI(*U, PN))
897 return false;
901 auto Filtered = make_filter_range(PHIOperands, [&](const ValPair &P) {
902 auto *BB = P.second;
903 if (auto *PHIOp = dyn_cast(I))
904 if (isCopyOfPHI(P.first, PHIOp))
905 return false;
898906 if (!ReachableEdges.count({BB, PHIBlock}))
899907 return false;
900908 // Things in TOPClass are equivalent to everything.
901 if (ValueToClass.lookup(*U) == TOPClass)
909 if (ValueToClass.lookup(P.first) == TOPClass)
902910 return false;
903 OriginalOpsConstant = OriginalOpsConstant && isa(*U);
911 OriginalOpsConstant = OriginalOpsConstant && isa(P.first);
904912 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
905 return lookupOperandLeader(*U) != PN;
913 return lookupOperandLeader(P.first) != I;
906914 });
907 std::transform(
908 Filtered.begin(), Filtered.end(), op_inserter(E),
909 [&](const Use *U) -> Value * { return lookupOperandLeader(*U); });
915 std::transform(Filtered.begin(), Filtered.end(), op_inserter(E),
916 [&](const ValPair &P) -> Value * {
917 return lookupOperandLeader(P.first);
918 });
910919 return E;
911920 }
912921
16271636 }
16281637
16291638 // Evaluate PHI nodes symbolically and create an expression result.
1630 const Expression *NewGVN::performSymbolicPHIEvaluation(Instruction *I) const {
1639 const Expression *
1640 NewGVN::performSymbolicPHIEvaluation(ArrayRef PHIOps,
1641 Instruction *I,
1642 BasicBlock *PHIBlock) const {
16311643 // True if one of the incoming phi edges is a backedge.
16321644 bool HasBackedge = false;
16331645 // All constant tracks the state of whether all the *original* phi operands
16351647 // change in value of the phi is guaranteed not to later change the value of
16361648 // the phi. IE it can't be v = phi(undef, v+1)
16371649 bool OriginalOpsConstant = true;
1638 auto *E = cast(
1639 createPHIExpression(I, HasBackedge, OriginalOpsConstant));
1650 auto *E = cast(createPHIExpression(
1651 PHIOps, I, PHIBlock, HasBackedge, OriginalOpsConstant));
16401652 // We match the semantics of SimplifyPhiNode from InstructionSimplify here.
16411653 // See if all arguments are the same.
16421654 // We track if any were undef because they need special handling.
18851897 case Instruction::InsertValue:
18861898 E = performSymbolicAggrValueEvaluation(I);
18871899 break;
1888 case Instruction::PHI:
1889 E = performSymbolicPHIEvaluation(I);
1890 break;
1900 case Instruction::PHI: {
1901 SmallVector Ops;
1902 auto *PN = cast(I);
1903 for (unsigned i = 0; i < PN->getNumOperands(); ++i)
1904 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
1905 // Sort to ensure the invariant createPHIExpression requires is met.
1906 sortPHIOps(Ops);
1907 E = performSymbolicPHIEvaluation(Ops, I, getBlockForValue(I));
1908 } break;
18911909 case Instruction::Call:
18921910 E = performSymbolicCallEvaluation(I);
18931911 break;
26482666 continue;
26492667 if (!DebugCounter::shouldExecute(PHIOfOpsCounter))
26502668 return nullptr;
2651 SmallVector<std::pair, 4> Ops;
2669 SmallVector<ValPair, 4> Ops;
26522670 auto *PHIBlock = getBlockForValue(OpPHI);
26532671 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(I));
26542672 for (unsigned PredNum = 0; PredNum < OpPHI->getNumOperands(); ++PredNum) {
26842702 (Op != OrigOp ||
26852703 OpIsSafeForPHIOfOps(Op, I, PHIBlock, VisitedOps));
26862704 }
2687 // FIXME: For those things that are not safe We could generate
2705 // FIXME: For those things that are not safe we could generate
26882706 // expressions all the way down, and see if this comes out to a
26892707 // constant. For anything where that is true, and unsafe, we should
26902708 // have made a phi-of-ops (or value numbered it equivalent to something)
27072725 DEBUG(dbgs() << "Found phi of ops operand " << *FoundVal << " in "
27082726 << getBlockName(PredBB) << "\n");
27092727 }
2710
2711 // FIXME: We should evaluate the phi operands first and see if it ends up a
2712 // constant or variable expression.
2728 sortPHIOps(Ops);
2729 auto *E = performSymbolicPHIEvaluation(Ops, I, PHIBlock);
2730 if (isa(E) || isa(E)) {
2731 DEBUG(dbgs()
2732 << "Not creating real PHI of ops because it simplified to existing "
2733 "value or constant\n");
2734 return E;
2735 }
27132736 auto *ValuePHI = RealToTemp.lookup(I);
27142737 bool NewPHI = false;
27152738 if (!ValuePHI) {
27332756 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(I));
27342757 DEBUG(dbgs() << "Created phi of ops " << *ValuePHI << " for " << *I
27352758 << "\n");
2736 return performSymbolicEvaluation(ValuePHI, Visited);
2759
2760 return E;
27372761 }
27382762 return nullptr;
27392763 }
30943118 // so we don't process them.
30953119 if (auto *MemPHI = dyn_cast(Pair.first)) {
30963120 for (auto &U : MemPHI->incoming_values()) {
3097 if (Instruction *I = dyn_cast(U.get())) {
3121 if (auto *I = dyn_cast(&*U)) {
30983122 if (!isInstructionTriviallyDead(I))
30993123 return true;
31003124 }
77 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
88 ; CHECK: br label [[TMP6:%.*]]
99 ; CHECK: br label [[TMP6]]
10 ; CHECK: [[PHIOFOPS:%.*]] = phi i32 [ 75, [[TMP4]] ], [ 105, [[TMP5]] ]
10 ; CHECK: [[PHIOFOPS:%.*]] = phi i32 [ 105, [[TMP5]] ], [ 75, [[TMP4]] ]
1111 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 5, [[TMP4]] ], [ 7, [[TMP5]] ]
1212 ; CHECK-NEXT: ret i32 [[PHIOFOPS]]
1313 ;
3232 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
3333 ; CHECK: br label [[TMP6:%.*]]
3434 ; CHECK: br label [[TMP6]]
35 ; CHECK: [[PHIOFOPS1:%.*]] = phi i32 [ 75, [[TMP4]] ], [ 105, [[TMP5]] ]
36 ; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i32 [ 1125, [[TMP4]] ], [ 1575, [[TMP5]] ]
35 ; CHECK: [[PHIOFOPS1:%.*]] = phi i32 [ 105, [[TMP5]] ], [ 75, [[TMP4]] ]
36 ; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i32 [ 1575, [[TMP5]] ], [ 1125, [[TMP4]] ]
3737 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 5, [[TMP4]] ], [ 7, [[TMP5]] ]
3838 ; CHECK-NEXT: ret i32 [[PHIOFOPS]]
3939 ;
214214 ; CHECK: bb14:
215215 ; CHECK-NEXT: br label [[BB15:%.*]]
216216 ; CHECK: bb15:
217 ; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i64 [ [[TMP25:%.*]], [[BB15]] ], [ [[TMP12]], [[BB14]] ]
217 ; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i64 [ [[TMP12]], [[BB14]] ], [ [[TMP25:%.*]], [[BB15]] ]
218218 ; CHECK-NEXT: [[TMP16:%.*]] = phi i64 [ [[TMP24:%.*]], [[BB15]] ], [ [[TMP11]], [[BB14]] ]
219219 ; CHECK-NEXT: [[TMP17:%.*]] = phi i64 [ [[TMP22:%.*]], [[BB15]] ], [ [[TMP10]], [[BB14]] ]
220220 ; CHECK-NEXT: [[TMP18:%.*]] = phi i64 [ [[TMP20:%.*]], [[BB15]] ], [ 0, [[BB14]] ]
77 ; CHECK-NEXT: entry:
88 ; CHECK-NEXT: br i1 false, label [[FOR_COND1:%.*]], label [[FOR_INC:%.*]]
99 ; CHECK: for.cond1:
10 ; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i16 [ [[INC:%.*]], [[FOR_INC]] ], [ undef, [[ENTRY:%.*]] ]
10 ; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i16 [ undef, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC]] ]
1111 ; CHECK-NEXT: store i16 [[PHIOFOPS]], i16* @b, align 2
1212 ; CHECK-NEXT: br label [[FOR_INC]]
1313 ; CHECK: for.inc:
1212 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0
1313 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
1414 ; CHECK: br label [[TMP5]]
15 ; CHECK: [[TMP6:%.*]] = phi i32 [ 15, [[TMP4]] ], [ 10, [[TMP2:%.*]] ]
15 ; CHECK: [[PHIOFOPS:%.*]] = phi i32 [ 10, [[TMP2:%.*]] ], [ 15, [[TMP4]] ]
1616 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 10, [[TMP4]] ], [ 5, [[TMP2]] ]
17 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP7:%.*]], label [[TMP8:%.*]]
18 ; CHECK: br label [[TMP8]]
19 ; CHECK: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP7]] ], [ [[DOT0]], [[TMP5]] ]
17 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP6:%.*]], label [[TMP7:%.*]]
18 ; CHECK: br label [[TMP7]]
19 ; CHECK: [[DOT1:%.*]] = phi i32 [ [[PHIOFOPS]], [[TMP6]] ], [ [[DOT0]], [[TMP5]] ]
2020 ; CHECK-NEXT: ret i32 [[DOT1]]
2121 ;
2222 store i32 5, i32* %0, align 4
5353 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
5454 ; CHECK: br label [[TMP6:%.*]]
5555 ; CHECK: br label [[TMP6]]
56 ; CHECK: [[TMP7:%.*]] = phi i32 [ 15, [[TMP4]] ], [ 10, [[TMP5]] ]
56 ; CHECK: [[PHIOFOPS:%.*]] = phi i32 [ 10, [[TMP5]] ], [ 15, [[TMP4]] ]
5757 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 10, [[TMP4]] ], [ 5, [[TMP5]] ]
58 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP8:%.*]], label [[TMP9:%.*]]
59 ; CHECK: br label [[TMP9]]
60 ; CHECK: [[DOT1:%.*]] = phi i32 [ [[TMP7]], [[TMP8]] ], [ [[DOT0]], [[TMP6]] ]
58 ; CHECK-NEXT: br i1 [[TMP3]], label [[TMP7:%.*]], label [[TMP8:%.*]]
59 ; CHECK: br label [[TMP8]]
60 ; CHECK: [[DOT1:%.*]] = phi i32 [ [[PHIOFOPS]], [[TMP7]] ], [ [[DOT0]], [[TMP6]] ]
6161 ; CHECK-NEXT: ret i32 [[DOT1]]
6262 ;
6363 store i32 5, i32* %0, align 4