[llvm] 59a5964 - [SimplifyCFG] Don't speculatively execute BB[s] if they are predictably not taken

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 26 15:09:37 PDT 2021


On Mon, Jul 26, 2021 at 6:27 PM Philip Reames <listmail at philipreames.com> wrote:
>
> Style wise, could we extract a predictedNotTakenSuccessor interface?
> Seems like a reoccurring pattern which would be nice to extract.
It does seem reoccurring, but i'm not quite sure how it would look best,
so for now i've kept reinventing the weel.

> Philip
Roman

> On 7/25/21 5:01 PM, Roman Lebedev via llvm-commits wrote:
> > Author: Roman Lebedev
> > Date: 2021-07-26T02:55:15+03:00
> > New Revision: 59a5964e033c92f3b4866429552f20979c998e56
> >
> > URL: https://github.com/llvm/llvm-project/commit/59a5964e033c92f3b4866429552f20979c998e56
> > DIFF: https://github.com/llvm/llvm-project/commit/59a5964e033c92f3b4866429552f20979c998e56.diff
> >
> > LOG: [SimplifyCFG] Don't speculatively execute BB[s] if they are predictably not taken
> >
> > Same as D106650, but for `FoldTwoEntryPHINode()`
> >
> > Reviewed By: spatel
> >
> > Differential Revision: https://reviews.llvm.org/D106717
> >
> > Added:
> >
> >
> > Modified:
> >      llvm/lib/Transforms/Utils/SimplifyCFG.cpp
> >      llvm/test/Transforms/PGOProfile/chr.ll
> >      llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-one-block-profmd.ll
> >      llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-two-blocks-profmd.ll
> >
> > Removed:
> >
> >
> >
> > ################################################################################
> > diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
> > index f2f15199ccfd..7a88e1cab73c 100644
> > --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
> > +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
> > @@ -2736,7 +2736,33 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
> >         PN->blocks(), std::back_inserter(IfBlocks), [](BasicBlock *IfBlock) {
> >           return cast<BranchInst>(IfBlock->getTerminator())->isUnconditional();
> >         });
> > -  assert(!IfBlocks.empty() && "Will have at least one block to speculate.");
> > +  assert((IfBlocks.size() == 1 || IfBlocks.size() == 2) &&
> > +         "Will have either one or two blocks to speculate.");
> > +
> > +  // If the branch is non-unpredictable, see if we either predictably jump to
> > +  // the merge bb (if we have only a single 'then' block), or if we predictably
> > +  // jump to one specific 'then' block (if we have two of them).
> > +  // It isn't beneficial to speculatively execute the code
> > +  // from the block that we know is predictably not entered.
> > +  if (!DomBI->getMetadata(LLVMContext::MD_unpredictable)) {
> > +    uint64_t TWeight, FWeight;
> > +    if (DomBI->extractProfMetadata(TWeight, FWeight) &&
> > +        (TWeight + FWeight) != 0) {
> > +      BranchProbability BITrueProb =
> > +          BranchProbability::getBranchProbability(TWeight, TWeight + FWeight);
> > +      BranchProbability Likely = TTI.getPredictableBranchThreshold();
> > +      BranchProbability BIFalseProb = BITrueProb.getCompl();
> > +      if (IfBlocks.size() == 1) {
> > +        BranchProbability BIBBProb =
> > +            DomBI->getSuccessor(0) == BB ? BITrueProb : BIFalseProb;
> > +        if (BIBBProb >= Likely)
> > +          return false;
> > +      } else {
> > +        if (BITrueProb >= Likely || BIFalseProb >= Likely)
> > +          return false;
> > +      }
> > +    }
> > +  }
> >
> >     // Don't try to fold an unreachable block. For example, the phi node itself
> >     // can't be the candidate if-condition for a select that we want to form.
> >
> > diff  --git a/llvm/test/Transforms/PGOProfile/chr.ll b/llvm/test/Transforms/PGOProfile/chr.ll
> > index 35fad463ac4a..ec215269e1ae 100644
> > --- a/llvm/test/Transforms/PGOProfile/chr.ll
> > +++ b/llvm/test/Transforms/PGOProfile/chr.ll
> > @@ -2013,7 +2013,8 @@ define i64 @test_chr_22(i1 %i, i64* %j, i64 %v0) !prof !14 {
> >   ; CHECK-NEXT:    [[C1:%.*]] = icmp slt i64 [[V2]], 100
> >   ; CHECK-NEXT:    br i1 [[C1]], label [[BB0_SPLIT:%.*]], label [[BB0_SPLIT_NONCHR:%.*]], !prof [[PROF15]]
> >   ; CHECK:       common.ret:
> > -; CHECK-NEXT:    ret i64 99
> > +; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i64 [ 99, [[BB0_SPLIT]] ], [ 99, [[BB0_SPLIT_NONCHR]] ]
> > +; CHECK-NEXT:    ret i64 [[COMMON_RET_OP]]
> >   ; CHECK:       bb0.split:
> >   ; CHECK-NEXT:    [[V299:%.*]] = mul i64 [[V2]], 7860086430977039991
> >   ; CHECK-NEXT:    store i64 [[V299]], i64* [[J:%.*]], align 4
> >
> > diff  --git a/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-one-block-profmd.ll b/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-one-block-profmd.ll
> > index 18734f658ef0..c81eb4b08620 100644
> > --- a/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-one-block-profmd.ll
> > +++ b/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-one-block-profmd.ll
> > @@ -59,8 +59,12 @@ define i32 @predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) {
> >   ; CHECK-NEXT:  entry:
> >   ; CHECK-NEXT:    call void @sideeffect0()
> >   ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
> > +; CHECK-NEXT:    br i1 [[CMP]], label [[END:%.*]], label [[COND_TRUE:%.*]], !prof [[PROF0]]
> > +; CHECK:       cond.true:
> >   ; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
> > -; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 [[V0]], !prof [[PROF0]]
> > +; CHECK-NEXT:    br label [[END]]
> > +; CHECK:       end:
> > +; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
> >   ; CHECK-NEXT:    call void @sideeffect1()
> >   ; CHECK-NEXT:    ret i32 [[RES]]
> >   ;
> >
> > diff  --git a/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-two-blocks-profmd.ll b/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-two-blocks-profmd.ll
> > index 22344f141e15..0951162b7e83 100644
> > --- a/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-two-blocks-profmd.ll
> > +++ b/llvm/test/Transforms/SimplifyCFG/fold-two-entry-phi-node-with-two-blocks-profmd.ll
> > @@ -39,9 +39,15 @@ define i32 @predictably_taken(i32 %a, i32 %b, i32 %c, i32 %d) {
> >   ; CHECK-NEXT:  entry:
> >   ; CHECK-NEXT:    call void @sideeffect0()
> >   ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
> > +; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !prof [[PROF0:![0-9]+]]
> > +; CHECK:       cond.true:
> >   ; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
> > +; CHECK-NEXT:    br label [[END:%.*]]
> > +; CHECK:       cond.false:
> >   ; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
> > -; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V0]], i32 [[V1]], !prof [[PROF0:![0-9]+]]
> > +; CHECK-NEXT:    br label [[END]]
> > +; CHECK:       end:
> > +; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ]
> >   ; CHECK-NEXT:    call void @sideeffect1()
> >   ; CHECK-NEXT:    ret i32 [[RES]]
> >   ;
> > @@ -99,9 +105,15 @@ define i32 @predictably_nontaken(i32 %a, i32 %b, i32 %c, i32 %d) {
> >   ; CHECK-NEXT:  entry:
> >   ; CHECK-NEXT:    call void @sideeffect0()
> >   ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
> > +; CHECK-NEXT:    br i1 [[CMP]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]], !prof [[PROF0]]
> > +; CHECK:       cond.true:
> >   ; CHECK-NEXT:    [[V0:%.*]] = add i32 [[C:%.*]], [[D:%.*]]
> > +; CHECK-NEXT:    br label [[END:%.*]]
> > +; CHECK:       cond.false:
> >   ; CHECK-NEXT:    [[V1:%.*]] = sub i32 [[C]], [[D]]
> > -; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i32 [[V1]], i32 [[V0]], !prof [[PROF0]]
> > +; CHECK-NEXT:    br label [[END]]
> > +; CHECK:       end:
> > +; CHECK-NEXT:    [[RES:%.*]] = phi i32 [ [[V0]], [[COND_TRUE]] ], [ [[V1]], [[COND_FALSE]] ]
> >   ; CHECK-NEXT:    call void @sideeffect1()
> >   ; CHECK-NEXT:    ret i32 [[RES]]
> >   ;
> >
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list