diff --git a/build/build-clang/clang-6-linux64.json b/build/build-clang/clang-6-linux64.json index 0e7526add6601..33489edb04b8a 100644 --- a/build/build-clang/clang-6-linux64.json +++ b/build/build-clang/clang-6-linux64.json @@ -4,7 +4,7 @@ llvm_revision " : " -326563 +335538 " " stages @@ -53,7 +53,7 @@ llvm / tags / -RELEASE_600 +RELEASE_601 / final " @@ -80,7 +80,7 @@ cfe / tags / -RELEASE_600 +RELEASE_601 / final " @@ -107,7 +107,7 @@ lld / tags / -RELEASE_600 +RELEASE_601 / final " @@ -136,7 +136,7 @@ rt / tags / -RELEASE_600 +RELEASE_601 / final " @@ -163,7 +163,7 @@ libcxx / tags / -RELEASE_600 +RELEASE_601 / final " @@ -190,7 +190,7 @@ libcxxabi / tags / -RELEASE_600 +RELEASE_601 / final " @@ -304,5 +304,15 @@ find_symbolizer_linux . patch " +" +r322401 +. +patch +" +" +r325356 +. +patch +" ] } diff --git a/build/build-clang/clang-6-macosx64.json b/build/build-clang/clang-6-macosx64.json index 7bfb6bde178de..56653629e5c5e 100644 --- a/build/build-clang/clang-6-macosx64.json +++ b/build/build-clang/clang-6-macosx64.json @@ -4,7 +4,7 @@ llvm_revision " : " -326563 +335538 " " stages @@ -58,7 +58,7 @@ llvm / tags / -RELEASE_600 +RELEASE_601 / final " @@ -85,7 +85,7 @@ cfe / tags / -RELEASE_600 +RELEASE_601 / final " @@ -112,7 +112,7 @@ lld / tags / -RELEASE_600 +RELEASE_601 / final " @@ -141,7 +141,7 @@ rt / tags / -RELEASE_600 +RELEASE_601 / final " @@ -168,7 +168,7 @@ libcxx / tags / -RELEASE_600 +RELEASE_601 / final " @@ -195,7 +195,7 @@ libcxxabi / tags / -RELEASE_600 +RELEASE_601 / final " @@ -432,5 +432,15 @@ codesign . patch " +" +r322401 +. +patch +" +" +r325356 +. +patch +" ] } diff --git a/build/build-clang/r322401.patch b/build/build-clang/r322401.patch new file mode 100644 index 0000000000000..b9fa083b5311c --- /dev/null +++ b/build/build-clang/r322401.patch @@ -0,0 +1,21136 @@ +From +90f447e9556a9e094890a3da1affbb4f84fecb44 +Mon +Sep +17 +00 +: +00 +: +00 +2001 +From +: +" +Brian +M +. +Rzycki +" +< +brzycki +gmail +. +com +> +Date +: +Fri +12 +Jan +2018 +21 +: +06 +: +48 ++ +0000 +Subject +: +[ +PATCH +1 +/ +2 +] +[ +JumpThreading +] +Preservation +of +DT +and +LVI +across +the +pass +Summary +: +See +D37528 +for +a +previous +( +non +- +deferred +) +version +of +this +patch +and +its +description +. +Preserves +dominance +in +a +deferred +manner +using +a +new +class +DeferredDominance +. +This +reduces +the +performance +impact +of +updating +the +DominatorTree +at +every +edge +insertion +and +deletion +. +A +user +may +call +DDT +- +> +flush +( +) +within +JumpThreading +for +an +up +- +to +- +date +DT +. +This +patch +currently +has +one +flush +( +) +at +the +end +of +runImpl +( +) +to +ensure +DT +is +preserved +across +the +pass +. +LVI +is +also +preserved +to +help +subsequent +passes +such +as +CorrelatedValuePropagation +. +LVI +is +simpler +to +maintain +and +is +done +immediately +( +not +deferred +) +. +The +code +to +perform +the +preversation +was +minimally +altered +and +simply +marked +as +preserved +for +the +PassManager +to +be +informed +. +This +extends +the +analysis +available +to +JumpThreading +for +future +enhancements +such +as +threading +across +loop +headers +. +Reviewers +: +dberlin +kuhar +sebpop +Reviewed +By +: +kuhar +sebpop +Subscribers +: +mgorny +dmgreen +kuba +rnk +rsmith +hiraditya +llvm +- +commits +Differential +Revision +: +https +: +/ +/ +reviews +. +llvm +. +org +/ +D40146 +git +- +svn +- +id +: +https +: +/ +/ +llvm +. +org +/ +svn +/ +llvm +- +project +/ +llvm +/ +trunk +322401 +91177308 +- +0d34 +- +0410 +- +b5e6 +- +96231b3b80d8 +- +- +- +include +/ +llvm +/ +IR +/ +Dominators +. +h +| +84 ++ ++ ++ ++ ++ +. +. +. +/ +llvm +/ +Transforms +/ +Scalar +/ +JumpThreading +. +h +| +6 ++ +- +. +. +. +/ +llvm +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +h +| +3 ++ +- +include +/ +llvm +/ +Transforms +/ +Utils +/ +Local +. +h +| +20 ++ +- +lib +/ +IR +/ +Dominators +. +cpp +| +188 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +. +. +. +/ +Scalar +/ +CorrelatedValuePropagation +. +cpp +| +2 ++ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +| +174 ++ ++ ++ ++ ++ ++ ++ +- +- +lib +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +cpp +| +18 ++ +- +lib +/ +Transforms +/ +Utils +/ +Local +. +cpp +| +209 ++ ++ ++ ++ ++ ++ ++ ++ +- +- +- +. +. +. +/ +lvi +- +after +- +jumpthreading +. +ll +| +3 ++ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash +. +ll +| +265 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash2 +. +ll +| +40 ++ ++ +test +/ +Transforms +/ +JumpThreading +/ +lvi +- +tristate +. +ll +| +50 ++ ++ ++ +unittests +/ +IR +/ +CMakeLists +. +txt +| +1 ++ +unittests +/ +IR +/ +DeferredDominanceTest +. +cpp +| +344 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +15 +files +changed +1308 +insertions +( ++ +) +99 +deletions +( +- +) +create +mode +100644 +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash +. +ll +create +mode +100644 +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash2 +. +ll +create +mode +100644 +test +/ +Transforms +/ +JumpThreading +/ +lvi +- +tristate +. +ll +create +mode +100644 +unittests +/ +IR +/ +DeferredDominanceTest +. +cpp +diff +- +- +git +a +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h +b +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h +index +6ad99e516fb +. +. +c5373376ade +100644 +- +- +- +a +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h ++ ++ ++ +b +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h +- +290 +6 ++ +290 +90 +public +: +void +print +( +raw_ostream +& +OS +const +Module +* +M += +nullptr +) +const +override +; +} +; ++ +/ +/ += += += +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ +/ +/ +/ +\ +brief +Class +to +defer +updates +to +a +DominatorTree +. ++ +/ +/ +/ ++ +/ +/ +/ +Definition +: +Applying +updates +to +every +edge +insertion +and +deletion +is ++ +/ +/ +/ +expensive +and +not +necessary +. +When +one +needs +the +DominatorTree +for +analysis ++ +/ +/ +/ +they +can +request +a +flush +( +) +to +perform +a +larger +batch +update +. +This +has +the ++ +/ +/ +/ +advantage +of +the +DominatorTree +inspecting +the +set +of +updates +to +find ++ +/ +/ +/ +duplicates +or +unnecessary +subtree +updates +. ++ +/ +/ +/ ++ +/ +/ +/ +The +scope +of +DeferredDominance +operates +at +a +Function +level +. ++ +/ +/ +/ ++ +/ +/ +/ +It +is +not +necessary +for +the +user +to +scrub +the +updates +for +duplicates +or ++ +/ +/ +/ +updates +that +point +to +the +same +block +( +Delete +BB_A +BB_A +) +. +Performance ++ +/ +/ +/ +can +be +gained +if +the +caller +attempts +to +batch +updates +before +submitting ++ +/ +/ +/ +to +applyUpdates +( +ArrayRef +) +in +cases +where +duplicate +edge +requests +will ++ +/ +/ +/ +occur +. ++ +/ +/ +/ ++ +/ +/ +/ +It +is +required +for +the +state +of +the +LLVM +IR +to +be +applied +* +before +* ++ +/ +/ +/ +submitting +updates +. +The +update +routines +must +analyze +the +current +state ++ +/ +/ +/ +between +a +pair +of +( +From +To +) +basic +blocks +to +determine +if +the +update ++ +/ +/ +/ +needs +to +be +queued +. ++ +/ +/ +/ +Example +( +good +) +: ++ +/ +/ +/ +TerminatorInstructionBB +- +> +removeFromParent +( +) +; ++ +/ +/ +/ +DDT +- +> +deleteEdge +( +BB +Successor +) +; ++ +/ +/ +/ +Example +( +bad +) +: ++ +/ +/ +/ +DDT +- +> +deleteEdge +( +BB +Successor +) +; ++ +/ +/ +/ +TerminatorInstructionBB +- +> +removeFromParent +( +) +; ++ +class +DeferredDominance +{ ++ +public +: ++ +DeferredDominance +( +DominatorTree +& +DT_ +) +: +DT +( +DT_ +) +{ +} ++ ++ +/ +/ +/ +\ +brief +Queues +multiple +updates +and +discards +duplicates +. ++ +void +applyUpdates +( +ArrayRef +< +DominatorTree +: +: +UpdateType +> +Updates +) +; ++ ++ +/ +/ +/ +\ +brief +Helper +method +for +a +single +edge +insertion +. +It +' +s +almost +always ++ +/ +/ +/ +better +to +batch +updates +and +call +applyUpdates +to +quickly +remove +duplicate ++ +/ +/ +/ +edges +. +This +is +best +used +when +there +is +only +a +single +insertion +needed +to ++ +/ +/ +/ +update +Dominators +. ++ +void +insertEdge +( +BasicBlock +* +From +BasicBlock +* +To +) +; ++ ++ +/ +/ +/ +\ +brief +Helper +method +for +a +single +edge +deletion +. +It +' +s +almost +always +better ++ +/ +/ +/ +to +batch +updates +and +call +applyUpdates +to +quickly +remove +duplicate +edges +. ++ +/ +/ +/ +This +is +best +used +when +there +is +only +a +single +deletion +needed +to +update ++ +/ +/ +/ +Dominators +. ++ +void +deleteEdge +( +BasicBlock +* +From +BasicBlock +* +To +) +; ++ ++ +/ +/ +/ +\ +brief +Delays +the +deletion +of +a +basic +block +until +a +flush +( +) +event +. ++ +void +deleteBB +( +BasicBlock +* +DelBB +) +; ++ ++ +/ +/ +/ +\ +brief +Returns +true +if +DelBB +is +awaiting +deletion +at +a +flush +( +) +event +. ++ +bool +pendingDeletedBB +( +BasicBlock +* +DelBB +) +; ++ ++ +/ +/ +/ +\ +brief +Flushes +all +pending +updates +and +block +deletions +. +Returns +a ++ +/ +/ +/ +correct +DominatorTree +reference +to +be +used +by +the +caller +for +analysis +. ++ +DominatorTree +& +flush +( +) +; ++ ++ +/ +/ +/ +\ +brief +Drops +all +internal +state +and +forces +a +( +slow +) +recalculation +of +the ++ +/ +/ +/ +DominatorTree +based +on +the +current +state +of +the +LLVM +IR +in +F +. +This +should ++ +/ +/ +/ +only +be +used +in +corner +cases +such +as +the +Entry +block +of +F +being +deleted +. ++ +void +recalculate +( +Function +& +F +) +; ++ ++ +/ +/ +/ +\ +brief +Debug +method +to +help +view +the +state +of +pending +updates +. ++ +LLVM_DUMP_METHOD +void +dump +( +) +const +; ++ ++ +private +: ++ +DominatorTree +& +DT +; ++ +SmallVector +< +DominatorTree +: +: +UpdateType +16 +> +PendUpdates +; ++ +SmallPtrSet +< +BasicBlock +* +8 +> +DeletedBBs +; ++ ++ +/ +/ +/ +Apply +an +update +( +Kind +From +To +) +to +the +internal +queued +updates +. +The ++ +/ +/ +/ +update +is +only +added +when +determined +to +be +necessary +. +Checks +for ++ +/ +/ +/ +self +- +domination +unnecessary +updates +duplicate +requests +and +balanced ++ +/ +/ +/ +pairs +of +requests +are +all +performed +. +Returns +true +if +the +update +is ++ +/ +/ +/ +queued +and +false +if +it +is +discarded +. ++ +bool +applyUpdate +( +DominatorTree +: +: +UpdateKind +Kind +BasicBlock +* +From ++ +BasicBlock +* +To +) +; ++ ++ +/ +/ +/ +Performs +all +pending +basic +block +deletions +. +We +have +to +defer +the +deletion ++ +/ +/ +/ +of +these +blocks +until +after +the +DominatorTree +updates +are +applied +. +The ++ +/ +/ +/ +internal +workings +of +the +DominatorTree +code +expect +every +update +' +s +From ++ +/ +/ +/ +and +To +blocks +to +exist +and +to +be +a +member +of +the +same +Function +. ++ +bool +flushDelBB +( +) +; ++ +} +; ++ +} +/ +/ +end +namespace +llvm +# +endif +/ +/ +LLVM_IR_DOMINATORS_H +diff +- +- +git +a +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Scalar +/ +JumpThreading +. +h +b +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Scalar +/ +JumpThreading +. +h +index +a9466713b8e +. +. +b3493a29249 +100644 +- +- +- +a +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Scalar +/ +JumpThreading +. +h ++ ++ ++ +b +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Scalar +/ +JumpThreading +. +h +- +34 +6 ++ +34 +7 +class +BinaryOperator +; +class +BranchInst +; +class +CmpInst +; +class +Constant +; ++ +class +DeferredDominance +; +class +Function +; +class +Instruction +; +class +IntrinsicInst +; +- +77 +6 ++ +78 +7 +class +JumpThreadingPass +: +public +PassInfoMixin +< +JumpThreadingPass +> +{ +TargetLibraryInfo +* +TLI +; +LazyValueInfo +* +LVI +; +AliasAnalysis +* +AA +; ++ +DeferredDominance +* +DDT +; +std +: +: +unique_ptr +< +BlockFrequencyInfo +> +BFI +; +std +: +: +unique_ptr +< +BranchProbabilityInfo +> +BPI +; +bool +HasProfileData += +false +; +- +107 +8 ++ +109 +8 +public +: +/ +/ +Glue +for +old +PM +. +bool +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ +LazyValueInfo +* +LVI_ +- +AliasAnalysis +* +AA_ +bool +HasProfileData_ +- +std +: +: +unique_ptr +< +BlockFrequencyInfo +> +BFI_ ++ +AliasAnalysis +* +AA_ +DeferredDominance +* +DDT_ ++ +bool +HasProfileData_ +std +: +: +unique_ptr +< +BlockFrequencyInfo +> +BFI_ +std +: +: +unique_ptr +< +BranchProbabilityInfo +> +BPI_ +) +; +PreservedAnalyses +run +( +Function +& +F +FunctionAnalysisManager +& +AM +) +; +diff +- +- +git +a +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +h +b +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +h +index +74f75509f55 +. +. +6f0d2deac0a +100644 +- +- +- +a +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +h ++ ++ ++ +b +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +h +- +27 +6 ++ +27 +7 +namespace +llvm +{ +class +BlockFrequencyInfo +; +class +BranchProbabilityInfo +; ++ +class +DeferredDominance +; +class +DominatorTree +; +class +Function +; +class +Instruction +; +- +38 +7 ++ +39 +7 +class +TargetLibraryInfo +; +class +Value +; +/ +/ +/ +Delete +the +specified +block +which +must +have +no +predecessors +. +- +void +DeleteDeadBlock +( +BasicBlock +* +BB +) +; ++ +void +DeleteDeadBlock +( +BasicBlock +* +BB +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ +/ +We +know +that +BB +has +one +predecessor +. +If +there +are +any +single +- +entry +PHI +nodes +/ +/ +/ +in +it +fold +them +away +. +This +handles +the +case +when +all +entries +to +the +PHI +diff +- +- +git +a +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +Local +. +h +b +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +Local +. +h +index +01db88bc15c +. +. +eb1f4c41b44 +100644 +- +- +- +a +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +Local +. +h ++ ++ ++ +b +/ +llvm +/ +include +/ +llvm +/ +Transforms +/ +Utils +/ +Local +. +h +- +117 +7 ++ +117 +8 +struct +SimplifyCFGOptions +{ +/ +/ +/ +conditions +and +indirectbr +addresses +this +might +make +dead +if +/ +/ +/ +DeleteDeadConditions +is +true +. +bool +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions += +false +- +const +TargetLibraryInfo +* +TLI += +nullptr +) +; ++ +const +TargetLibraryInfo +* +TLI += +nullptr ++ +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ += += += +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- += += += +/ +/ +/ +/ +Local +dead +code +elimination +. +- +171 +18 ++ +172 +21 +bool +SimplifyInstructionsInBlock +( +BasicBlock +* +BB +/ +/ +/ +/ +/ +/ +. +. +and +delete +the +predecessor +corresponding +to +the +' +1 +' +this +will +attempt +to +/ +/ +/ +recursively +fold +the +' +and +' +to +0 +. +- +void +RemovePredecessorAndSimplify +( +BasicBlock +* +BB +BasicBlock +* +Pred +) +; ++ +void +RemovePredecessorAndSimplify +( +BasicBlock +* +BB +BasicBlock +* +Pred ++ +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ +/ +BB +is +a +block +with +one +predecessor +and +its +predecessor +is +known +to +have +one +/ +/ +/ +successor +( +BB +! +) +. +Eliminate +the +edge +between +them +moving +the +instructions +in +/ +/ +/ +the +predecessor +into +BB +. +This +deletes +the +predecessor +block +. +- +void +MergeBasicBlockIntoOnlyPred +( +BasicBlock +* +BB +DominatorTree +* +DT += +nullptr +) +; ++ +void +MergeBasicBlockIntoOnlyPred +( +BasicBlock +* +BB +DominatorTree +* +DT += +nullptr ++ +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ +/ +BB +is +known +to +contain +an +unconditional +branch +and +contains +no +instructions +/ +/ +/ +other +than +PHI +nodes +potential +debug +intrinsics +and +the +branch +. +If +/ +/ +/ +possible +eliminate +BB +by +rewriting +all +the +predecessors +to +branch +to +the +/ +/ +/ +successor +block +and +return +true +. +If +we +can +' +t +transform +return +false +. +- +bool +TryToSimplifyUncondBranchFromEmptyBlock +( +BasicBlock +* +BB +) +; ++ +bool +TryToSimplifyUncondBranchFromEmptyBlock +( +BasicBlock +* +BB ++ +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ +/ +Check +for +and +eliminate +duplicate +PHI +nodes +in +this +block +. +This +doesn +' +t +try +/ +/ +/ +to +be +clever +about +PHI +nodes +which +differ +only +in +the +order +of +the +incoming +- +382 +7 ++ +386 +8 +unsigned +removeAllNonTerminatorAndEHPadInstructions +( +BasicBlock +* +BB +) +; +/ +/ +/ +Insert +an +unreachable +instruction +before +the +specified +/ +/ +/ +instruction +making +it +and +the +rest +of +the +code +in +the +block +dead +. +unsigned +changeToUnreachable +( +Instruction +* +I +bool +UseLLVMTrap +- +bool +PreserveLCSSA += +false +) +; ++ +bool +PreserveLCSSA += +false ++ +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ +/ +Convert +the +CallInst +to +InvokeInst +with +the +specified +unwind +edge +basic +/ +/ +/ +block +. +This +also +splits +the +basic +block +where +CI +is +located +because +- +397 +12 ++ +402 +13 +BasicBlock +* +changeToInvokeAndSplitBasicBlock +( +CallInst +* +CI +/ +/ +/ +/ +/ +/ +\ +param +BB +Block +whose +terminator +will +be +replaced +. +Its +terminator +must +/ +/ +/ +have +an +unwind +successor +. +- +void +removeUnwindEdge +( +BasicBlock +* +BB +) +; ++ +void +removeUnwindEdge +( +BasicBlock +* +BB +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ +/ +Remove +all +blocks +that +can +not +be +reached +from +the +function +' +s +entry +. +/ +/ +/ +/ +/ +/ +Returns +true +if +any +basic +block +was +removed +. +- +bool +removeUnreachableBlocks +( +Function +& +F +LazyValueInfo +* +LVI += +nullptr +) +; ++ +bool +removeUnreachableBlocks +( +Function +& +F +LazyValueInfo +* +LVI += +nullptr ++ +DeferredDominance +* +DDT += +nullptr +) +; +/ +/ +/ +Combine +the +metadata +of +two +instructions +so +that +K +can +replace +J +/ +/ +/ +diff +- +- +git +a +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp +b +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp +index +ad448a3f240 +. +. +e44e845b324 +100644 +- +- +- +a +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp +- +18 +6 ++ +18 +7 +# +include +" +llvm +/ +ADT +/ +DepthFirstIterator +. +h +" +# +include +" +llvm +/ +ADT +/ +SmallPtrSet +. +h +" +# +include +" +llvm +/ +IR +/ +CFG +. +h +" ++ +# +include +" +llvm +/ +IR +/ +Constants +. +h +" +# +include +" +llvm +/ +IR +/ +Instructions +. +h +" +# +include +" +llvm +/ +IR +/ +PassManager +. +h +" +# +include +" +llvm +/ +Support +/ +CommandLine +. +h +" +- +389 +3 ++ +390 +190 +void +DominatorTreeWrapperPass +: +: +print +( +raw_ostream +& +OS +const +Module +* +) +const +{ +DT +. +print +( +OS +) +; +} ++ +/ +/ += += += +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- += += += +/ +/ ++ +/ +/ +DeferredDominance +Implementation ++ +/ +/ += += += +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- += += += +/ +/ ++ +/ +/ ++ +/ +/ +The +implementation +details +of +the +DeferredDominance +class +which +allows ++ +/ +/ +one +to +queue +updates +to +a +DominatorTree +. ++ +/ +/ ++ +/ +/ += += += +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- += += += +/ +/ ++ ++ +/ +/ +/ +\ +brief +Queues +multiple +updates +and +discards +duplicates +. ++ +void +DeferredDominance +: +: +applyUpdates +( ++ +ArrayRef +< +DominatorTree +: +: +UpdateType +> +Updates +) +{ ++ +SmallVector +< +DominatorTree +: +: +UpdateType +8 +> +Seen +; ++ +for +( +auto +U +: +Updates +) ++ +/ +/ +Avoid +duplicates +to +applyUpdate +( +) +to +save +on +analysis +. ++ +if +( +std +: +: +none_of +( +Seen +. +begin +( +) +Seen +. +end +( +) ++ +[ +U +] +( +DominatorTree +: +: +UpdateType +S +) +{ +return +S += += +U +; +} +) +) +{ ++ +Seen +. +push_back +( +U +) +; ++ +applyUpdate +( +U +. +getKind +( +) +U +. +getFrom +( +) +U +. +getTo +( +) +) +; ++ +} ++ +} ++ ++ +/ +/ +/ +\ +brief +Helper +method +for +a +single +edge +insertion +. +It +' +s +almost +always +better ++ +/ +/ +/ +to +batch +updates +and +call +applyUpdates +to +quickly +remove +duplicate +edges +. ++ +/ +/ +/ +This +is +best +used +when +there +is +only +a +single +insertion +needed +to +update ++ +/ +/ +/ +Dominators +. ++ +void +DeferredDominance +: +: +insertEdge +( +BasicBlock +* +From +BasicBlock +* +To +) +{ ++ +applyUpdate +( +DominatorTree +: +: +Insert +From +To +) +; ++ +} ++ ++ +/ +/ +/ +\ +brief +Helper +method +for +a +single +edge +deletion +. +It +' +s +almost +always +better ++ +/ +/ +/ +to +batch +updates +and +call +applyUpdates +to +quickly +remove +duplicate +edges +. ++ +/ +/ +/ +This +is +best +used +when +there +is +only +a +single +deletion +needed +to +update ++ +/ +/ +/ +Dominators +. ++ +void +DeferredDominance +: +: +deleteEdge +( +BasicBlock +* +From +BasicBlock +* +To +) +{ ++ +applyUpdate +( +DominatorTree +: +: +Delete +From +To +) +; ++ +} ++ ++ +/ +/ +/ +\ +brief +Delays +the +deletion +of +a +basic +block +until +a +flush +( +) +event +. ++ +void +DeferredDominance +: +: +deleteBB +( +BasicBlock +* +DelBB +) +{ ++ +assert +( +DelBB +& +& +" +Invalid +push_back +of +nullptr +DelBB +. +" +) +; ++ +assert +( +pred_empty +( +DelBB +) +& +& +" +DelBB +has +one +or +more +predecessors +. +" +) +; ++ +/ +/ +DelBB +is +unreachable +and +all +its +instructions +are +dead +. ++ +while +( +! +DelBB +- +> +empty +( +) +) +{ ++ +Instruction +& +I += +DelBB +- +> +back +( +) +; ++ +/ +/ +Replace +used +instructions +with +an +arbitrary +value +( +undef +) +. ++ +if +( +! +I +. +use_empty +( +) +) ++ +I +. +replaceAllUsesWith +( +llvm +: +: +UndefValue +: +: +get +( +I +. +getType +( +) +) +) +; ++ +DelBB +- +> +getInstList +( +) +. +pop_back +( +) +; ++ +} ++ +/ +/ +Make +sure +DelBB +has +a +valid +terminator +instruction +. +As +long +as +DelBB +is +a ++ +/ +/ +Child +of +Function +F +it +must +contain +valid +IR +. ++ +new +UnreachableInst +( +DelBB +- +> +getContext +( +) +DelBB +) +; ++ +DeletedBBs +. +insert +( +DelBB +) +; ++ +} ++ ++ +/ +/ +/ +\ +brief +Returns +true +if +DelBB +is +awaiting +deletion +at +a +flush +( +) +event +. ++ +bool +DeferredDominance +: +: +pendingDeletedBB +( +BasicBlock +* +DelBB +) +{ ++ +if +( +DeletedBBs +. +empty +( +) +) ++ +return +false +; ++ +return +DeletedBBs +. +count +( +DelBB +) +! += +0 +; ++ +} ++ ++ +/ +/ +/ +\ +brief +Flushes +all +pending +updates +and +block +deletions +. +Returns +a ++ +/ +/ +/ +correct +DominatorTree +reference +to +be +used +by +the +caller +for +analysis +. ++ +DominatorTree +& +DeferredDominance +: +: +flush +( +) +{ ++ +/ +/ +Updates +to +DT +must +happen +before +blocks +are +deleted +below +. +Otherwise +the ++ +/ +/ +DT +traversal +will +encounter +badref +blocks +and +assert +. ++ +if +( +! +PendUpdates +. +empty +( +) +) +{ ++ +DT +. +applyUpdates +( +PendUpdates +) +; ++ +PendUpdates +. +clear +( +) +; ++ +} ++ +flushDelBB +( +) +; ++ +return +DT +; ++ +} ++ ++ +/ +/ +/ +\ +brief +Drops +all +internal +state +and +forces +a +( +slow +) +recalculation +of +the ++ +/ +/ +/ +DominatorTree +based +on +the +current +state +of +the +LLVM +IR +in +F +. +This +should ++ +/ +/ +/ +only +be +used +in +corner +cases +such +as +the +Entry +block +of +F +being +deleted +. ++ +void +DeferredDominance +: +: +recalculate +( +Function +& +F +) +{ ++ +/ +/ +flushDelBB +must +be +flushed +before +the +recalculation +. +The +state +of +the +IR ++ +/ +/ +must +be +consistent +before +the +DT +traversal +algorithm +determines +the ++ +/ +/ +actual +DT +. ++ +if +( +flushDelBB +( +) +| +| +! +PendUpdates +. +empty +( +) +) +{ ++ +DT +. +recalculate +( +F +) +; ++ +PendUpdates +. +clear +( +) +; ++ +} ++ +} ++ ++ +/ +/ +/ +\ +brief +Debug +method +to +help +view +the +state +of +pending +updates +. ++ +# +if +! +defined +( +NDEBUG +) +| +| +defined +( +LLVM_ENABLE_DUMP +) ++ +LLVM_DUMP_METHOD +void +DeferredDominance +: +: +dump +( +) +const +{ ++ +raw_ostream +& +OS += +llvm +: +: +dbgs +( +) +; ++ +OS +< +< +" +PendUpdates +: +\ +n +" +; ++ +int +I += +0 +; ++ +for +( +auto +U +: +PendUpdates +) +{ ++ +OS +< +< +" +" +< +< +I +< +< +" +: +" +; ++ ++ ++ +I +; ++ +if +( +U +. +getKind +( +) += += +DominatorTree +: +: +Insert +) ++ +OS +< +< +" +Insert +" +; ++ +else ++ +OS +< +< +" +Delete +" +; ++ +BasicBlock +* +From += +U +. +getFrom +( +) +; ++ +if +( +From +) +{ ++ +auto +S += +From +- +> +getName +( +) +; ++ +if +( +! +From +- +> +hasName +( +) +) ++ +S += +" +( +no +name +) +" +; ++ +OS +< +< +S +< +< +" +( +" +< +< +From +< +< +" +) +" +; ++ +} +else +{ ++ +OS +< +< +" +( +badref +) +" +; ++ +} ++ +BasicBlock +* +To += +U +. +getTo +( +) +; ++ +if +( +To +) +{ ++ +auto +S += +To +- +> +getName +( +) +; ++ +if +( +! +To +- +> +hasName +( +) +) ++ +S += +" +( +no_name +) +" +; ++ +OS +< +< +S +< +< +" +( +" +< +< +To +< +< +" +) +\ +n +" +; ++ +} +else +{ ++ +OS +< +< +" +( +badref +) +\ +n +" +; ++ +} ++ +} ++ +OS +< +< +" +DeletedBBs +: +\ +n +" +; ++ +I += +0 +; ++ +for +( +auto +BB +: +DeletedBBs +) +{ ++ +OS +< +< +" +" +< +< +I +< +< +" +: +" +; ++ ++ ++ +I +; ++ +if +( +BB +- +> +hasName +( +) +) ++ +OS +< +< +BB +- +> +getName +( +) +< +< +" +( +" +; ++ +else ++ +OS +< +< +" +( +no_name +) +( +" +; ++ +OS +< +< +BB +< +< +" +) +\ +n +" +; ++ +} ++ +} ++ +# +endif ++ ++ +/ +/ +/ +Apply +an +update +( +Kind +From +To +) +to +the +internal +queued +updates +. +The ++ +/ +/ +/ +update +is +only +added +when +determined +to +be +necessary +. +Checks +for ++ +/ +/ +/ +self +- +domination +unnecessary +updates +duplicate +requests +and +balanced ++ +/ +/ +/ +pairs +of +requests +are +all +performed +. +Returns +true +if +the +update +is ++ +/ +/ +/ +queued +and +false +if +it +is +discarded +. ++ +bool +DeferredDominance +: +: +applyUpdate +( +DominatorTree +: +: +UpdateKind +Kind ++ +BasicBlock +* +From +BasicBlock +* +To +) +{ ++ +if +( +From += += +To +) ++ +return +false +; +/ +/ +Cannot +dominate +self +; +discard +update +. ++ ++ +/ +/ +Discard +updates +by +inspecting +the +current +state +of +successors +of +From +. ++ +/ +/ +Since +applyUpdate +( +) +must +be +called +* +after +* +the +Terminator +of +From +is ++ +/ +/ +altered +we +can +determine +if +the +update +is +unnecessary +. ++ +bool +HasEdge += +std +: +: +any_of +( +succ_begin +( +From +) +succ_end +( +From +) ++ +[ +To +] +( +BasicBlock +* +B +) +{ +return +B += += +To +; +} +) +; ++ +if +( +Kind += += +DominatorTree +: +: +Insert +& +& +! +HasEdge +) ++ +return +false +; +/ +/ +Unnecessary +Insert +: +edge +does +not +exist +in +IR +. ++ +if +( +Kind += += +DominatorTree +: +: +Delete +& +& +HasEdge +) ++ +return +false +; +/ +/ +Unnecessary +Delete +: +edge +still +exists +in +IR +. ++ ++ +/ +/ +Analyze +pending +updates +to +determine +if +the +update +is +unnecessary +. ++ +DominatorTree +: +: +UpdateType +Update += +{ +Kind +From +To +} +; ++ +DominatorTree +: +: +UpdateType +Invert += +{ +Kind +! += +DominatorTree +: +: +Insert ++ +? +DominatorTree +: +: +Insert ++ +: +DominatorTree +: +: +Delete ++ +From +To +} +; ++ +for +( +auto +I += +PendUpdates +. +begin +( +) +E += +PendUpdates +. +end +( +) +; +I +! += +E +; ++ ++ +I +) +{ ++ +if +( +Update += += +* +I +) ++ +return +false +; +/ +/ +Discard +duplicate +updates +. ++ +if +( +Invert += += +* +I +) +{ ++ +/ +/ +Update +and +Invert +are +both +valid +( +equivalent +to +a +no +- +op +) +. +Remove ++ +/ +/ +Invert +from +PendUpdates +and +discard +the +Update +. ++ +PendUpdates +. +erase +( +I +) +; ++ +return +false +; ++ +} ++ +} ++ +PendUpdates +. +push_back +( +Update +) +; +/ +/ +Save +the +valid +update +. ++ +return +true +; ++ +} ++ ++ +/ +/ +/ +Performs +all +pending +basic +block +deletions +. +We +have +to +defer +the +deletion ++ +/ +/ +/ +of +these +blocks +until +after +the +DominatorTree +updates +are +applied +. +The ++ +/ +/ +/ +internal +workings +of +the +DominatorTree +code +expect +every +update +' +s +From ++ +/ +/ +/ +and +To +blocks +to +exist +and +to +be +a +member +of +the +same +Function +. ++ +bool +DeferredDominance +: +: +flushDelBB +( +) +{ ++ +if +( +DeletedBBs +. +empty +( +) +) ++ +return +false +; ++ +for +( +auto +* +BB +: +DeletedBBs +) ++ +BB +- +> +eraseFromParent +( +) +; ++ +DeletedBBs +. +clear +( +) +; ++ +return +true +; ++ +} +diff +- +- +git +a +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +CorrelatedValuePropagation +. +cpp +b +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +CorrelatedValuePropagation +. +cpp +index +8f468ebf894 +. +. +535d43cdf9e +100644 +- +- +- +a +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +CorrelatedValuePropagation +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +CorrelatedValuePropagation +. +cpp +- +77 +6 ++ +77 +7 +namespace +{ +bool +runOnFunction +( +Function +& +F +) +override +; +void +getAnalysisUsage +( +AnalysisUsage +& +AU +) +const +override +{ ++ +AU +. +addRequired +< +DominatorTreeWrapperPass +> +( +) +; +AU +. +addRequired +< +LazyValueInfoWrapperPass +> +( +) +; +AU +. +addPreserved +< +GlobalsAAWrapperPass +> +( +) +; +} +- +88 +6 ++ +89 +7 +char +CorrelatedValuePropagation +: +: +ID += +0 +; +INITIALIZE_PASS_BEGIN +( +CorrelatedValuePropagation +" +correlated +- +propagation +" +" +Value +Propagation +" +false +false +) ++ +INITIALIZE_PASS_DEPENDENCY +( +DominatorTreeWrapperPass +) +INITIALIZE_PASS_DEPENDENCY +( +LazyValueInfoWrapperPass +) +INITIALIZE_PASS_END +( +CorrelatedValuePropagation +" +correlated +- +propagation +" +" +Value +Propagation +" +false +false +) +diff +- +- +git +a +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +b +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +index +141c9938bf8 +. +. +4d366e8e392 +100644 +- +- +- +a +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +- +131 +10 ++ +131 +11 +namespace +{ +bool +runOnFunction +( +Function +& +F +) +override +; +void +getAnalysisUsage +( +AnalysisUsage +& +AU +) +const +override +{ +- +if +( +PrintLVIAfterJumpThreading +) +- +AU +. +addRequired +< +DominatorTreeWrapperPass +> +( +) +; ++ +AU +. +addRequired +< +DominatorTreeWrapperPass +> +( +) +; ++ +AU +. +addPreserved +< +DominatorTreeWrapperPass +> +( +) +; +AU +. +addRequired +< +AAResultsWrapperPass +> +( +) +; +AU +. +addRequired +< +LazyValueInfoWrapperPass +> +( +) +; ++ +AU +. +addPreserved +< +LazyValueInfoWrapperPass +> +( +) +; +AU +. +addPreserved +< +GlobalsAAWrapperPass +> +( +) +; +AU +. +addRequired +< +TargetLibraryInfoWrapperPass +> +( +) +; +} +- +148 +6 ++ +149 +7 +char +JumpThreading +: +: +ID += +0 +; +INITIALIZE_PASS_BEGIN +( +JumpThreading +" +jump +- +threading +" +" +Jump +Threading +" +false +false +) ++ +INITIALIZE_PASS_DEPENDENCY +( +DominatorTreeWrapperPass +) +INITIALIZE_PASS_DEPENDENCY +( +LazyValueInfoWrapperPass +) +INITIALIZE_PASS_DEPENDENCY +( +TargetLibraryInfoWrapperPass +) +INITIALIZE_PASS_DEPENDENCY +( +AAResultsWrapperPass +) +- +278 +8 ++ +280 +12 +bool +JumpThreading +: +: +runOnFunction +( +Function +& +F +) +{ +if +( +skipFunction +( +F +) +) +return +false +; +auto +TLI += +& +getAnalysis +< +TargetLibraryInfoWrapperPass +> +( +) +. +getTLI +( +) +; ++ +/ +/ +Get +DT +analysis +before +LVI +. +When +LVI +is +initialized +it +conditionally +adds ++ +/ +/ +DT +if +it +' +s +available +. ++ +auto +DT += +& +getAnalysis +< +DominatorTreeWrapperPass +> +( +) +. +getDomTree +( +) +; +auto +LVI += +& +getAnalysis +< +LazyValueInfoWrapperPass +> +( +) +. +getLVI +( +) +; +auto +AA += +& +getAnalysis +< +AAResultsWrapperPass +> +( +) +. +getAAResults +( +) +; ++ +DeferredDominance +DDT +( +* +DT +) +; +std +: +: +unique_ptr +< +BlockFrequencyInfo +> +BFI +; +std +: +: +unique_ptr +< +BranchProbabilityInfo +> +BPI +; +bool +HasProfileData += +F +. +hasProfileData +( +) +; +- +289 +12 ++ +295 +11 +bool +JumpThreading +: +: +runOnFunction +( +Function +& +F +) +{ +BFI +. +reset +( +new +BlockFrequencyInfo +( +F +* +BPI +LI +) +) +; +} +- +bool +Changed += +Impl +. +runImpl +( +F +TLI +LVI +AA +HasProfileData +std +: +: +move +( +BFI +) +- +std +: +: +move +( +BPI +) +) +; ++ +bool +Changed += +Impl +. +runImpl +( +F +TLI +LVI +AA +& +DDT +HasProfileData ++ +std +: +: +move +( +BFI +) +std +: +: +move +( +BPI +) +) +; +if +( +PrintLVIAfterJumpThreading +) +{ +dbgs +( +) +< +< +" +LVI +for +function +' +" +< +< +F +. +getName +( +) +< +< +" +' +: +\ +n +" +; +- +LVI +- +> +printLVI +( +F +getAnalysis +< +DominatorTreeWrapperPass +> +( +) +. +getDomTree +( +) +- +dbgs +( +) +) +; ++ +LVI +- +> +printLVI +( +F +* +DT +dbgs +( +) +) +; +} +return +Changed +; +} +- +302 +8 ++ +307 +12 +bool +JumpThreading +: +: +runOnFunction +( +Function +& +F +) +{ +PreservedAnalyses +JumpThreadingPass +: +: +run +( +Function +& +F +FunctionAnalysisManager +& +AM +) +{ +auto +& +TLI += +AM +. +getResult +< +TargetLibraryAnalysis +> +( +F +) +; ++ +/ +/ +Get +DT +analysis +before +LVI +. +When +LVI +is +initialized +it +conditionally +adds ++ +/ +/ +DT +if +it +' +s +available +. ++ +auto +& +DT += +AM +. +getResult +< +DominatorTreeAnalysis +> +( +F +) +; +auto +& +LVI += +AM +. +getResult +< +LazyValueAnalysis +> +( +F +) +; +auto +& +AA += +AM +. +getResult +< +AAManager +> +( +F +) +; ++ +DeferredDominance +DDT +( +DT +) +; +std +: +: +unique_ptr +< +BlockFrequencyInfo +> +BFI +; +std +: +: +unique_ptr +< +BranchProbabilityInfo +> +BPI +; +- +313 +25 ++ +322 +28 +PreservedAnalyses +JumpThreadingPass +: +: +run +( +Function +& +F +BFI +. +reset +( +new +BlockFrequencyInfo +( +F +* +BPI +LI +) +) +; +} +- +bool +Changed += +runImpl +( +F +& +TLI +& +LVI +& +AA +HasProfileData +std +: +: +move +( +BFI +) +- +std +: +: +move +( +BPI +) +) +; ++ +bool +Changed += +runImpl +( +F +& +TLI +& +LVI +& +AA +& +DDT +HasProfileData ++ +std +: +: +move +( +BFI +) +std +: +: +move +( +BPI +) +) +; +if +( +! +Changed +) +return +PreservedAnalyses +: +: +all +( +) +; +PreservedAnalyses +PA +; +PA +. +preserve +< +GlobalsAA +> +( +) +; ++ +PA +. +preserve +< +DominatorTreeAnalysis +> +( +) +; ++ +PA +. +preserve +< +LazyValueAnalysis +> +( +) +; +return +PA +; +} +bool +JumpThreadingPass +: +: +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ +LazyValueInfo +* +LVI_ +AliasAnalysis +* +AA_ +- +bool +HasProfileData_ ++ +DeferredDominance +* +DDT_ +bool +HasProfileData_ +std +: +: +unique_ptr +< +BlockFrequencyInfo +> +BFI_ +std +: +: +unique_ptr +< +BranchProbabilityInfo +> +BPI_ +) +{ +DEBUG +( +dbgs +( +) +< +< +" +Jump +threading +on +function +' +" +< +< +F +. +getName +( +) +< +< +" +' +\ +n +" +) +; +TLI += +TLI_ +; +LVI += +LVI_ +; +AA += +AA_ +; ++ +DDT += +DDT_ +; +BFI +. +reset +( +) +; +BPI +. +reset +( +) +; +/ +/ +When +profile +data +is +available +we +need +to +update +edge +weights +after +- +353 +7 ++ +365 +7 +bool +JumpThreadingPass +: +: +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ +/ +/ +back +edges +. +This +works +for +normal +cases +but +not +for +unreachable +blocks +as +/ +/ +they +may +have +cycle +with +no +back +edge +. +bool +EverChanged += +false +; +- +EverChanged +| += +removeUnreachableBlocks +( +F +LVI +) +; ++ +EverChanged +| += +removeUnreachableBlocks +( +F +LVI +DDT +) +; +FindLoopHeaders +( +F +) +; +- +368 +6 ++ +380 +10 +bool +JumpThreadingPass +: +: +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ ++ ++ +I +; ++ +/ +/ +Don +' +t +thread +branches +over +a +block +that +' +s +slated +for +deletion +. ++ +if +( +DDT +- +> +pendingDeletedBB +( +BB +) +) ++ +continue +; ++ +/ +/ +If +the +block +is +trivially +dead +zap +it +. +This +eliminates +the +successor +/ +/ +edges +which +simplifies +the +CFG +. +if +( +pred_empty +( +BB +) +& +& +- +376 +7 ++ +392 +7 +bool +JumpThreadingPass +: +: +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ +< +< +" +' +with +terminator +: +" +< +< +* +BB +- +> +getTerminator +( +) +< +< +' +\ +n +' +) +; +LoopHeaders +. +erase +( +BB +) +; +LVI +- +> +eraseBlock +( +BB +) +; +- +DeleteDeadBlock +( +BB +) +; ++ +DeleteDeadBlock +( +BB +DDT +) +; +Changed += +true +; +continue +; +} +- +400 +7 ++ +416 +7 +bool +JumpThreadingPass +: +: +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ +/ +/ +awesome +but +it +allows +us +to +use +AssertingVH +to +prevent +nasty +/ +/ +dangling +pointer +issues +within +LazyValueInfo +. +LVI +- +> +eraseBlock +( +BB +) +; +- +if +( +TryToSimplifyUncondBranchFromEmptyBlock +( +BB +) +) ++ +if +( +TryToSimplifyUncondBranchFromEmptyBlock +( +BB +DDT +) +) +Changed += +true +; +} +} +- +408 +6 ++ +424 +7 +bool +JumpThreadingPass +: +: +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ +} +while +( +Changed +) +; +LoopHeaders +. +clear +( +) +; ++ +DDT +- +> +flush +( +) +; +return +EverChanged +; +} +- +931 +8 ++ +948 +8 +static +bool +hasAddressTakenAndUsed +( +BasicBlock +* +BB +) +{ +bool +JumpThreadingPass +: +: +ProcessBlock +( +BasicBlock +* +BB +) +{ +/ +/ +If +the +block +is +trivially +dead +just +return +and +let +the +caller +nuke +it +. +/ +/ +This +simplifies +other +transformations +. +- +if +( +pred_empty +( +BB +) +& +& +- +BB +! += +& +BB +- +> +getParent +( +) +- +> +getEntryBlock +( +) +) ++ +if +( +DDT +- +> +pendingDeletedBB +( +BB +) +| +| ++ +( +pred_empty +( +BB +) +& +& +BB +! += +& +BB +- +> +getParent +( +) +- +> +getEntryBlock +( +) +) +) +return +false +; +/ +/ +If +this +block +has +a +single +predecessor +and +if +that +pred +has +a +single +- +948 +7 ++ +965 +7 +bool +JumpThreadingPass +: +: +ProcessBlock +( +BasicBlock +* +BB +) +{ +LoopHeaders +. +insert +( +BB +) +; +LVI +- +> +eraseBlock +( +SinglePred +) +; +- +MergeBasicBlockIntoOnlyPred +( +BB +) +; ++ +MergeBasicBlockIntoOnlyPred +( +BB +nullptr +DDT +) +; +/ +/ +Now +that +BB +is +merged +into +SinglePred +( +i +. +e +. +SinglePred +Code +followed +by +/ +/ +BB +code +within +one +basic +block +BB +) +we +need +to +invalidate +the +LVI +- +1031 +18 ++ +1048 +23 +bool +JumpThreadingPass +: +: +ProcessBlock +( +BasicBlock +* +BB +) +{ +/ +/ +successors +to +branch +to +. +Let +GetBestDestForJumpOnUndef +decide +. +if +( +isa +< +UndefValue +> +( +Condition +) +) +{ +unsigned +BestSucc += +GetBestDestForJumpOnUndef +( +BB +) +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; +/ +/ +Fold +the +branch +/ +switch +. +TerminatorInst +* +BBTerm += +BB +- +> +getTerminator +( +) +; ++ +Updates +. +reserve +( +BBTerm +- +> +getNumSuccessors +( +) +) +; +for +( +unsigned +i += +0 +e += +BBTerm +- +> +getNumSuccessors +( +) +; +i +! += +e +; ++ ++ +i +) +{ +if +( +i += += +BestSucc +) +continue +; +- +BBTerm +- +> +getSuccessor +( +i +) +- +> +removePredecessor +( +BB +true +) +; ++ +BasicBlock +* +Succ += +BBTerm +- +> +getSuccessor +( +i +) +; ++ +Succ +- +> +removePredecessor +( +BB +true +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +Succ +} +) +; +} +DEBUG +( +dbgs +( +) +< +< +" +In +block +' +" +< +< +BB +- +> +getName +( +) +< +< +" +' +folding +undef +terminator +: +" +< +< +* +BBTerm +< +< +' +\ +n +' +) +; +BranchInst +: +: +Create +( +BBTerm +- +> +getSuccessor +( +BestSucc +) +BBTerm +) +; +BBTerm +- +> +eraseFromParent +( +) +; ++ +DDT +- +> +applyUpdates +( +Updates +) +; +return +true +; +} +- +1053 +7 ++ +1075 +7 +bool +JumpThreadingPass +: +: +ProcessBlock +( +BasicBlock +* +BB +) +{ +DEBUG +( +dbgs +( +) +< +< +" +In +block +' +" +< +< +BB +- +> +getName +( +) +< +< +" +' +folding +terminator +: +" +< +< +* +BB +- +> +getTerminator +( +) +< +< +' +\ +n +' +) +; ++ ++ +NumFolds +; +- +ConstantFoldTerminator +( +BB +true +) +; ++ +ConstantFoldTerminator +( +BB +true +nullptr +DDT +) +; +return +true +; +} +- +1086 +7 ++ +1108 +8 +bool +JumpThreadingPass +: +: +ProcessBlock +( +BasicBlock +* +BB +) +{ +if +( +Ret +! += +LazyValueInfo +: +: +Unknown +) +{ +unsigned +ToRemove += +Ret += += +LazyValueInfo +: +: +True +? +1 +: +0 +; +unsigned +ToKeep += +Ret += += +LazyValueInfo +: +: +True +? +0 +: +1 +; +- +CondBr +- +> +getSuccessor +( +ToRemove +) +- +> +removePredecessor +( +BB +true +) +; ++ +BasicBlock +* +ToRemoveSucc += +CondBr +- +> +getSuccessor +( +ToRemove +) +; ++ +ToRemoveSucc +- +> +removePredecessor +( +BB +true +) +; +BranchInst +: +: +Create +( +CondBr +- +> +getSuccessor +( +ToKeep +) +CondBr +) +; +CondBr +- +> +eraseFromParent +( +) +; +if +( +CondCmp +- +> +use_empty +( +) +) +- +1104 +6 ++ +1127 +7 +bool +JumpThreadingPass +: +: +ProcessBlock +( +BasicBlock +* +BB +) +{ +ConstantInt +: +: +getFalse +( +CondCmp +- +> +getType +( +) +) +; +ReplaceFoldableUses +( +CondCmp +CI +) +; +} ++ +DDT +- +> +deleteEdge +( +BB +ToRemoveSucc +) +; +return +true +; +} +- +1182 +9 ++ +1206 +12 +bool +JumpThreadingPass +: +: +ProcessImpliedCondition +( +BasicBlock +* +BB +) +{ +Optional +< +bool +> +Implication += +isImpliedCondition +( +PBI +- +> +getCondition +( +) +Cond +DL +CondIsTrue +) +; +if +( +Implication +) +{ +- +BI +- +> +getSuccessor +( +* +Implication +? +1 +: +0 +) +- +> +removePredecessor +( +BB +) +; +- +BranchInst +: +: +Create +( +BI +- +> +getSuccessor +( +* +Implication +? +0 +: +1 +) +BI +) +; ++ +BasicBlock +* +KeepSucc += +BI +- +> +getSuccessor +( +* +Implication +? +0 +: +1 +) +; ++ +BasicBlock +* +RemoveSucc += +BI +- +> +getSuccessor +( +* +Implication +? +1 +: +0 +) +; ++ +RemoveSucc +- +> +removePredecessor +( +BB +) +; ++ +BranchInst +: +: +Create +( +KeepSucc +BI +) +; +BI +- +> +eraseFromParent +( +) +; ++ +DDT +- +> +deleteEdge +( +BB +RemoveSucc +) +; +return +true +; +} +CurrentBB += +CurrentPred +; +- +1591 +17 ++ +1618 +22 +bool +JumpThreadingPass +: +: +ProcessThreadableEdges +( +Value +* +Cond +BasicBlock +* +BB +if +( +PredWithKnownDest += += +( +size_t +) +std +: +: +distance +( +pred_begin +( +BB +) +pred_end +( +BB +) +) +) +{ +bool +SeenFirstBranchToOnlyDest += +false +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +Updates +. +reserve +( +BB +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +- +1 +) +; +for +( +BasicBlock +* +SuccBB +: +successors +( +BB +) +) +{ +- +if +( +SuccBB += += +OnlyDest +& +& +! +SeenFirstBranchToOnlyDest +) ++ +if +( +SuccBB += += +OnlyDest +& +& +! +SeenFirstBranchToOnlyDest +) +{ +SeenFirstBranchToOnlyDest += +true +; +/ +/ +Don +' +t +modify +the +first +branch +. +- +else ++ +} +else +{ +SuccBB +- +> +removePredecessor +( +BB +true +) +; +/ +/ +This +is +unreachable +successor +. ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +SuccBB +} +) +; ++ +} +} +/ +/ +Finally +update +the +terminator +. +TerminatorInst +* +Term += +BB +- +> +getTerminator +( +) +; +BranchInst +: +: +Create +( +OnlyDest +Term +) +; +Term +- +> +eraseFromParent +( +) +; ++ +DDT +- +> +applyUpdates +( +Updates +) +; +/ +/ +If +the +condition +is +now +dead +due +to +the +removal +of +the +old +terminator +/ +/ +erase +it +. +- +1964 +6 ++ +1996 +10 +bool +JumpThreadingPass +: +: +ThreadEdge +( +BasicBlock +* +BB +PredTerm +- +> +setSuccessor +( +i +NewBB +) +; +} ++ +DDT +- +> +applyUpdates +( +{ +{ +DominatorTree +: +: +Insert +NewBB +SuccBB +} ++ +{ +DominatorTree +: +: +Insert +PredBB +NewBB +} ++ +{ +DominatorTree +: +: +Delete +PredBB +BB +} +} +) +; ++ +/ +/ +At +this +point +the +IR +is +fully +up +to +date +and +consistent +. +Do +a +quick +scan +/ +/ +over +the +new +instructions +and +zap +any +that +are +constants +or +dead +. +This +/ +/ +frequently +happens +because +of +phi +translation +. +- +1983 +20 ++ +2019 +42 +bool +JumpThreadingPass +: +: +ThreadEdge +( +BasicBlock +* +BB +BasicBlock +* +JumpThreadingPass +: +: +SplitBlockPreds +( +BasicBlock +* +BB +ArrayRef +< +BasicBlock +* +> +Preds +const +char +* +Suffix +) +{ ++ +SmallVector +< +BasicBlock +* +2 +> +NewBBs +; ++ +/ +/ +Collect +the +frequencies +of +all +predecessors +of +BB +which +will +be +used +to +- +/ +/ +update +the +edge +weight +on +BB +- +> +SuccBB +. +- +BlockFrequency +PredBBFreq +( +0 +) +; ++ +/ +/ +update +the +edge +weight +of +the +result +of +splitting +predecessors +. ++ +DenseMap +< +BasicBlock +* +BlockFrequency +> +FreqMap +; +if +( +HasProfileData +) +for +( +auto +Pred +: +Preds +) +- +PredBBFreq ++ += +BFI +- +> +getBlockFreq +( +Pred +) +* +BPI +- +> +getEdgeProbability +( +Pred +BB +) +; ++ +FreqMap +. +insert +( +std +: +: +make_pair +( ++ +Pred +BFI +- +> +getBlockFreq +( +Pred +) +* +BPI +- +> +getEdgeProbability +( +Pred +BB +) +) +) +; ++ ++ +/ +/ +In +the +case +when +BB +is +a +LandingPad +block +we +create +2 +new +predecessors ++ +/ +/ +instead +of +just +one +. ++ +if +( +BB +- +> +isLandingPad +( +) +) +{ ++ +std +: +: +string +NewName += +std +: +: +string +( +Suffix +) ++ +" +. +split +- +lp +" +; ++ +SplitLandingPadPredecessors +( +BB +Preds +Suffix +NewName +. +c_str +( +) +NewBBs +) +; ++ +} +else +{ ++ +NewBBs +. +push_back +( +SplitBlockPredecessors +( +BB +Preds +Suffix +) +) +; ++ +} +- +BasicBlock +* +PredBB += +SplitBlockPredecessors +( +BB +Preds +Suffix +) +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +Updates +. +reserve +( +( +2 +* +Preds +. +size +( +) +) ++ +NewBBs +. +size +( +) +) +; ++ +for +( +auto +NewBB +: +NewBBs +) +{ ++ +BlockFrequency +NewBBFreq +( +0 +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +NewBB +BB +} +) +; ++ +for +( +auto +Pred +: +predecessors +( +NewBB +) +) +{ ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +Pred +BB +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +Pred +NewBB +} +) +; ++ +if +( +HasProfileData +) +/ +/ +Update +frequencies +between +Pred +- +> +NewBB +. ++ +NewBBFreq ++ += +FreqMap +. +lookup +( +Pred +) +; ++ +} ++ +if +( +HasProfileData +) +/ +/ +Apply +the +summed +frequency +to +NewBB +. ++ +BFI +- +> +setBlockFreq +( +NewBB +NewBBFreq +. +getFrequency +( +) +) +; ++ +} +- +/ +/ +Set +the +block +frequency +of +the +newly +created +PredBB +which +is +the +sum +of +- +/ +/ +frequencies +of +Preds +. +- +if +( +HasProfileData +) +- +BFI +- +> +setBlockFreq +( +PredBB +PredBBFreq +. +getFrequency +( +) +) +; +- +return +PredBB +; ++ +DDT +- +> +applyUpdates +( +Updates +) +; ++ +return +NewBBs +[ +0 +] +; +} +bool +JumpThreadingPass +: +: +doesBlockHaveProfileData +( +BasicBlock +* +BB +) +{ +- +2140 +6 ++ +2198 +7 +bool +JumpThreadingPass +: +: +DuplicateCondBranchOnPHIIntoPred +( +} +/ +/ +And +finally +do +it +! +Start +by +factoring +the +predecessors +if +needed +. ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; +BasicBlock +* +PredBB +; +if +( +PredBBs +. +size +( +) += += +1 +) +PredBB += +PredBBs +[ +0 +] +; +- +2148 +6 ++ +2207 +7 +bool +JumpThreadingPass +: +: +DuplicateCondBranchOnPHIIntoPred +( +< +< +" +common +predecessors +. +\ +n +" +) +; +PredBB += +SplitBlockPreds +( +BB +PredBBs +" +. +thr_comm +" +) +; +} ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +PredBB +BB +} +) +; +/ +/ +Okay +we +decided +to +do +this +! +Clone +all +the +instructions +in +BB +onto +the +end +/ +/ +of +PredBB +. +- +2160 +7 ++ +2220 +11 +bool +JumpThreadingPass +: +: +DuplicateCondBranchOnPHIIntoPred +( +BranchInst +* +OldPredBranch += +dyn_cast +< +BranchInst +> +( +PredBB +- +> +getTerminator +( +) +) +; +if +( +! +OldPredBranch +| +| +! +OldPredBranch +- +> +isUnconditional +( +) +) +{ +- +PredBB += +SplitEdge +( +PredBB +BB +) +; ++ +BasicBlock +* +OldPredBB += +PredBB +; ++ +PredBB += +SplitEdge +( +OldPredBB +BB +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +OldPredBB +PredBB +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +PredBB +BB +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +OldPredBB +BB +} +) +; +OldPredBranch += +cast +< +BranchInst +> +( +PredBB +- +> +getTerminator +( +) +) +; +} +- +2202 +6 ++ +2266 +10 +bool +JumpThreadingPass +: +: +DuplicateCondBranchOnPHIIntoPred +( +/ +/ +Otherwise +insert +the +new +instruction +into +the +block +. +New +- +> +setName +( +BI +- +> +getName +( +) +) +; +PredBB +- +> +getInstList +( +) +. +insert +( +OldPredBranch +- +> +getIterator +( +) +New +) +; ++ +/ +/ +Update +Dominance +from +simplified +New +instruction +operands +. ++ +for +( +unsigned +i += +0 +e += +New +- +> +getNumOperands +( +) +; +i +! += +e +; ++ ++ +i +) ++ +if +( +BasicBlock +* +SuccBB += +dyn_cast +< +BasicBlock +> +( +New +- +> +getOperand +( +i +) +) +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +PredBB +SuccBB +} +) +; +} +} +- +2257 +6 ++ +2325 +7 +bool +JumpThreadingPass +: +: +DuplicateCondBranchOnPHIIntoPred +( +/ +/ +Remove +the +unconditional +branch +at +the +end +of +the +PredBB +block +. +OldPredBranch +- +> +eraseFromParent +( +) +; ++ +DDT +- +> +applyUpdates +( +Updates +) +; ++ ++ +NumDupes +; +return +true +; +- +2329 +6 ++ +2398 +8 +bool +JumpThreadingPass +: +: +TryToUnfoldSelect +( +CmpInst +* +CondCmp +BasicBlock +* +BB +) +{ +/ +/ +The +select +is +now +dead +. +SI +- +> +eraseFromParent +( +) +; ++ +DDT +- +> +applyUpdates +( +{ +{ +DominatorTree +: +: +Insert +NewBB +BB +} ++ +{ +DominatorTree +: +: +Insert +Pred +NewBB +} +} +) +; +/ +/ +Update +any +other +PHI +nodes +in +BB +. +for +( +BasicBlock +: +: +iterator +BI += +BB +- +> +begin +( +) +; +PHINode +* +Phi += +dyn_cast +< +PHINode +> +( +BI +) +; ++ ++ +BI +) +- +2407 +11 ++ +2478 +25 +bool +JumpThreadingPass +: +: +TryToUnfoldSelectInCurrBB +( +BasicBlock +* +BB +) +{ +/ +/ +Expand +the +select +. +TerminatorInst +* +Term += +SplitBlockAndInsertIfThen +( +SI +- +> +getCondition +( +) +SI +false +) +; ++ +BasicBlock +* +SplitBB += +SI +- +> +getParent +( +) +; ++ +BasicBlock +* +NewBB += +Term +- +> +getParent +( +) +; +PHINode +* +NewPN += +PHINode +: +: +Create +( +SI +- +> +getType +( +) +2 +" +" +SI +) +; +NewPN +- +> +addIncoming +( +SI +- +> +getTrueValue +( +) +Term +- +> +getParent +( +) +) +; +NewPN +- +> +addIncoming +( +SI +- +> +getFalseValue +( +) +BB +) +; +SI +- +> +replaceAllUsesWith +( +NewPN +) +; +SI +- +> +eraseFromParent +( +) +; ++ +/ +/ +NewBB +and +SplitBB +are +newly +created +blocks +which +require +insertion +. ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +Updates +. +reserve +( +( +2 +* +SplitBB +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +) ++ +3 +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +BB +SplitBB +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +BB +NewBB +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +NewBB +SplitBB +} +) +; ++ +/ +/ +BB +' +s +successors +were +moved +to +SplitBB +update +DDT +accordingly +. ++ +for +( +auto +* +Succ +: +successors +( +SplitBB +) +) +{ ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +Succ +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +SplitBB +Succ +} +) +; ++ +} ++ +DDT +- +> +applyUpdates +( +Updates +) +; +return +true +; +} +return +false +; +- +2498 +8 ++ +2583 +8 +bool +JumpThreadingPass +: +: +ThreadGuard +( +BasicBlock +* +BB +IntrinsicInst +* +Guard +if +( +! +TrueDestIsSafe +& +& +! +FalseDestIsSafe +) +return +false +; +- +BasicBlock +* +UnguardedBlock += +TrueDestIsSafe +? +TrueDest +: +FalseDest +; +- +BasicBlock +* +GuardedBlock += +FalseDestIsSafe +? +TrueDest +: +FalseDest +; ++ +BasicBlock +* +PredUnguardedBlock += +TrueDestIsSafe +? +TrueDest +: +FalseDest +; ++ +BasicBlock +* +PredGuardedBlock += +FalseDestIsSafe +? +TrueDest +: +FalseDest +; +ValueToValueMapTy +UnguardedMapping +GuardedMapping +; +Instruction +* +AfterGuard += +Guard +- +> +getNextNode +( +) +; +- +2508 +18 ++ +2593 +29 +bool +JumpThreadingPass +: +: +ThreadGuard +( +BasicBlock +* +BB +IntrinsicInst +* +Guard +return +false +; +/ +/ +Duplicate +all +instructions +before +the +guard +and +the +guard +itself +to +the +/ +/ +branch +where +implication +is +not +proved +. +- +GuardedBlock += +DuplicateInstructionsInSplitBetween +( +- +BB +GuardedBlock +AfterGuard +GuardedMapping +) +; ++ +BasicBlock +* +GuardedBlock += +DuplicateInstructionsInSplitBetween +( ++ +BB +PredGuardedBlock +AfterGuard +GuardedMapping +) +; +assert +( +GuardedBlock +& +& +" +Could +not +create +the +guarded +block +? +" +) +; +/ +/ +Duplicate +all +instructions +before +the +guard +in +the +unguarded +branch +. +/ +/ +Since +we +have +successfully +duplicated +the +guarded +block +and +this +block +/ +/ +has +fewer +instructions +we +expect +it +to +succeed +. +- +UnguardedBlock += +DuplicateInstructionsInSplitBetween +( +BB +UnguardedBlock +- +Guard +UnguardedMapping +) +; ++ +BasicBlock +* +UnguardedBlock += +DuplicateInstructionsInSplitBetween +( ++ +BB +PredUnguardedBlock +Guard +UnguardedMapping +) +; +assert +( +UnguardedBlock +& +& +" +Could +not +create +the +unguarded +block +? +" +) +; +DEBUG +( +dbgs +( +) +< +< +" +Moved +guard +" +< +< +* +Guard +< +< +" +to +block +" +< +< +GuardedBlock +- +> +getName +( +) +< +< +" +\ +n +" +) +; +- ++ +/ +/ +DuplicateInstructionsInSplitBetween +inserts +a +new +block +" +BB +. +split +" +between ++ +/ +/ +PredBB +and +BB +. +We +need +to +perform +two +inserts +and +one +delete +for +each +of ++ +/ +/ +the +above +calls +to +update +Dominators +. ++ +DDT +- +> +applyUpdates +( ++ +{ +/ +/ +Guarded +block +split +. ++ +{ +DominatorTree +: +: +Delete +PredGuardedBlock +BB +} ++ +{ +DominatorTree +: +: +Insert +PredGuardedBlock +GuardedBlock +} ++ +{ +DominatorTree +: +: +Insert +GuardedBlock +BB +} ++ +/ +/ +Unguarded +block +split +. ++ +{ +DominatorTree +: +: +Delete +PredUnguardedBlock +BB +} ++ +{ +DominatorTree +: +: +Insert +PredUnguardedBlock +UnguardedBlock +} ++ +{ +DominatorTree +: +: +Insert +UnguardedBlock +BB +} +} +) +; +/ +/ +Some +instructions +before +the +guard +may +still +have +uses +. +For +them +we +need +/ +/ +to +create +Phi +nodes +merging +their +copies +in +both +guarded +and +unguarded +/ +/ +branches +. +Those +instructions +that +have +no +uses +can +be +just +removed +. +diff +- +- +git +a +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +cpp +b +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +cpp +index +8f59913e14b +. +. +f3a5f148def +100644 +- +- +- +a +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +BasicBlockUtils +. +cpp +- +45 +16 ++ +45 +22 +using +namespace +llvm +; +- +void +llvm +: +: +DeleteDeadBlock +( +BasicBlock +* +BB +) +{ ++ +void +llvm +: +: +DeleteDeadBlock +( +BasicBlock +* +BB +DeferredDominance +* +DDT +) +{ +assert +( +( +pred_begin +( +BB +) += += +pred_end +( +BB +) +| +| +/ +/ +Can +delete +self +loop +. +BB +- +> +getSinglePredecessor +( +) += += +BB +) +& +& +" +Block +is +not +dead +! +" +) +; +TerminatorInst +* +BBTerm += +BB +- +> +getTerminator +( +) +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; +/ +/ +Loop +through +all +of +our +successors +and +make +sure +they +know +that +one +/ +/ +of +their +predecessors +is +going +away +. +- +for +( +BasicBlock +* +Succ +: +BBTerm +- +> +successors +( +) +) ++ +if +( +DDT +) ++ +Updates +. +reserve +( +BBTerm +- +> +getNumSuccessors +( +) +) +; ++ +for +( +BasicBlock +* +Succ +: +BBTerm +- +> +successors +( +) +) +{ +Succ +- +> +removePredecessor +( +BB +) +; ++ +if +( +DDT +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +Succ +} +) +; ++ +} +/ +/ +Zap +all +the +instructions +in +the +block +. +while +( +! +BB +- +> +empty +( +) +) +{ +- +69 +8 ++ +75 +12 +void +llvm +: +: +DeleteDeadBlock +( +BasicBlock +* +BB +) +{ +BB +- +> +getInstList +( +) +. +pop_back +( +) +; +} +- +/ +/ +Zap +the +block +! +- +BB +- +> +eraseFromParent +( +) +; ++ +if +( +DDT +) +{ ++ +DDT +- +> +applyUpdates +( +Updates +) +; ++ +DDT +- +> +deleteBB +( +BB +) +; +/ +/ +Deferred +deletion +of +BB +. ++ +} +else +{ ++ +BB +- +> +eraseFromParent +( +) +; +/ +/ +Zap +the +block +! ++ +} +} +void +llvm +: +: +FoldSingleEntryPHINodes +( +BasicBlock +* +BB +diff +- +- +git +a +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +Local +. +cpp +b +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +Local +. +cpp +index +acccf7abf80 +. +. +6564e18856c +100644 +- +- +- +a +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +Local +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +Transforms +/ +Utils +/ +Local +. +cpp +- +100 +7 ++ +100 +8 +STATISTIC +( +NumRemoved +" +Number +of +unreachable +basic +blocks +removed +" +) +; +/ +/ +/ +conditions +and +indirectbr +addresses +this +might +make +dead +if +/ +/ +/ +DeleteDeadConditions +is +true +. +bool +llvm +: +: +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions +- +const +TargetLibraryInfo +* +TLI +) +{ ++ +const +TargetLibraryInfo +* +TLI ++ +DeferredDominance +* +DDT +) +{ +TerminatorInst +* +T += +BB +- +> +getTerminator +( +) +; +IRBuilder +< +> +Builder +( +T +) +; +- +123 +6 ++ +124 +8 +bool +llvm +: +: +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions +/ +/ +Replace +the +conditional +branch +with +an +unconditional +one +. +Builder +. +CreateBr +( +Destination +) +; +BI +- +> +eraseFromParent +( +) +; ++ +if +( +DDT +) ++ +DDT +- +> +deleteEdge +( +BB +OldDest +) +; +return +true +; +} +- +193 +9 ++ +196 +12 +bool +llvm +: +: +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions +createBranchWeights +( +Weights +) +) +; +} +/ +/ +Remove +this +entry +. +- +DefaultDest +- +> +removePredecessor +( +SI +- +> +getParent +( +) +) +; ++ +BasicBlock +* +ParentBB += +SI +- +> +getParent +( +) +; ++ +DefaultDest +- +> +removePredecessor +( +ParentBB +) +; +i += +SI +- +> +removeCase +( +i +) +; +e += +SI +- +> +case_end +( +) +; ++ +if +( +DDT +) ++ +DDT +- +> +deleteEdge +( +ParentBB +DefaultDest +) +; +continue +; +} +- +221 +14 ++ +227 +20 +bool +llvm +: +: +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions +/ +/ +Insert +the +new +branch +. +Builder +. +CreateBr +( +TheOnlyDest +) +; +BasicBlock +* +BB += +SI +- +> +getParent +( +) +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +if +( +DDT +) ++ +Updates +. +reserve +( +SI +- +> +getNumSuccessors +( +) +- +1 +) +; +/ +/ +Remove +entries +from +PHI +nodes +which +we +no +longer +branch +to +. +. +. +for +( +BasicBlock +* +Succ +: +SI +- +> +successors +( +) +) +{ +/ +/ +Found +case +matching +a +constant +operand +? +- +if +( +Succ += += +TheOnlyDest +) ++ +if +( +Succ += += +TheOnlyDest +) +{ +TheOnlyDest += +nullptr +; +/ +/ +Don +' +t +modify +the +first +branch +to +TheOnlyDest +- +else ++ +} +else +{ +Succ +- +> +removePredecessor +( +BB +) +; ++ +if +( +DDT +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +Succ +} +) +; ++ +} +} +/ +/ +Delete +the +old +switch +. +- +236 +6 ++ +248 +8 +bool +llvm +: +: +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions +SI +- +> +eraseFromParent +( +) +; +if +( +DeleteDeadConditions +) +RecursivelyDeleteTriviallyDeadInstructions +( +Cond +TLI +) +; ++ +if +( +DDT +) ++ +DDT +- +> +applyUpdates +( +Updates +) +; +return +true +; +} +- +281 +14 ++ +295 +23 +bool +llvm +: +: +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions +if +( +auto +* +BA += +dyn_cast +< +BlockAddress +> +( +IBI +- +> +getAddress +( +) +- +> +stripPointerCasts +( +) +) +) +{ +BasicBlock +* +TheOnlyDest += +BA +- +> +getBasicBlock +( +) +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +if +( +DDT +) ++ +Updates +. +reserve +( +IBI +- +> +getNumDestinations +( +) +- +1 +) +; ++ +/ +/ +Insert +the +new +branch +. +Builder +. +CreateBr +( +TheOnlyDest +) +; +for +( +unsigned +i += +0 +e += +IBI +- +> +getNumDestinations +( +) +; +i +! += +e +; ++ ++ +i +) +{ +- +if +( +IBI +- +> +getDestination +( +i +) += += +TheOnlyDest +) ++ +if +( +IBI +- +> +getDestination +( +i +) += += +TheOnlyDest +) +{ +TheOnlyDest += +nullptr +; +- +else +- +IBI +- +> +getDestination +( +i +) +- +> +removePredecessor +( +IBI +- +> +getParent +( +) +) +; ++ +} +else +{ ++ +BasicBlock +* +ParentBB += +IBI +- +> +getParent +( +) +; ++ +BasicBlock +* +DestBB += +IBI +- +> +getDestination +( +i +) +; ++ +DestBB +- +> +removePredecessor +( +ParentBB +) +; ++ +if +( +DDT +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +ParentBB +DestBB +} +) +; ++ +} +} +Value +* +Address += +IBI +- +> +getAddress +( +) +; +IBI +- +> +eraseFromParent +( +) +; +- +303 +6 ++ +326 +8 +bool +llvm +: +: +ConstantFoldTerminator +( +BasicBlock +* +BB +bool +DeleteDeadConditions +new +UnreachableInst +( +BB +- +> +getContext +( +) +BB +) +; +} ++ +if +( +DDT +) ++ +DDT +- +> +applyUpdates +( +Updates +) +; +return +true +; +} +} +- +579 +7 ++ +604 +8 +bool +llvm +: +: +SimplifyInstructionsInBlock +( +BasicBlock +* +BB +/ +/ +/ +/ +/ +/ +. +. +and +delete +the +predecessor +corresponding +to +the +' +1 +' +this +will +attempt +to +/ +/ +/ +recursively +fold +the +and +to +0 +. +- +void +llvm +: +: +RemovePredecessorAndSimplify +( +BasicBlock +* +BB +BasicBlock +* +Pred +) +{ ++ +void +llvm +: +: +RemovePredecessorAndSimplify +( +BasicBlock +* +BB +BasicBlock +* +Pred ++ +DeferredDominance +* +DDT +) +{ +/ +/ +This +only +adjusts +blocks +with +PHI +nodes +. +if +( +! +isa +< +PHINode +> +( +BB +- +> +begin +( +) +) +) +return +; +- +602 +13 ++ +628 +18 +void +llvm +: +: +RemovePredecessorAndSimplify +( +BasicBlock +* +BB +BasicBlock +* +Pred +) +{ +/ +/ +of +the +block +. +if +( +PhiIt +! += +OldPhiIt +) +PhiIt += +& +BB +- +> +front +( +) +; +} ++ +if +( +DDT +) ++ +DDT +- +> +deleteEdge +( +Pred +BB +) +; +} +/ +/ +/ +MergeBasicBlockIntoOnlyPred +- +DestBB +is +a +block +with +one +predecessor +and +its +/ +/ +/ +predecessor +is +known +to +have +one +successor +( +DestBB +! +) +. +Eliminate +the +edge +/ +/ +/ +between +them +moving +the +instructions +in +the +predecessor +into +DestBB +and +/ +/ +/ +deleting +the +predecessor +block +. +- +void +llvm +: +: +MergeBasicBlockIntoOnlyPred +( +BasicBlock +* +DestBB +DominatorTree +* +DT +) +{ ++ +void +llvm +: +: +MergeBasicBlockIntoOnlyPred +( +BasicBlock +* +DestBB +DominatorTree +* +DT ++ +DeferredDominance +* +DDT +) +{ ++ +assert +( +! +( +DT +& +& +DDT +) +& +& +" +Cannot +call +with +both +DT +and +DDT +. +" +) +; ++ +/ +/ +If +BB +has +single +- +entry +PHI +nodes +fold +them +. +while +( +PHINode +* +PN += +dyn_cast +< +PHINode +> +( +DestBB +- +> +begin +( +) +) +) +{ +Value +* +NewVal += +PN +- +> +getIncomingValue +( +0 +) +; +- +621 +6 ++ +652 +25 +void +llvm +: +: +MergeBasicBlockIntoOnlyPred +( +BasicBlock +* +DestBB +DominatorTree +* +DT +) +{ +BasicBlock +* +PredBB += +DestBB +- +> +getSinglePredecessor +( +) +; +assert +( +PredBB +& +& +" +Block +doesn +' +t +have +a +single +predecessor +! +" +) +; ++ +bool +ReplaceEntryBB += +false +; ++ +if +( +PredBB += += +& +DestBB +- +> +getParent +( +) +- +> +getEntryBlock +( +) +) ++ +ReplaceEntryBB += +true +; ++ ++ +/ +/ +Deferred +DT +update +: +Collect +all +the +edges +that +enter +PredBB +. +These ++ +/ +/ +dominator +edges +will +be +redirected +to +DestBB +. ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +if +( +DDT +& +& +! +ReplaceEntryBB +) +{ ++ +Updates +. +reserve +( +1 ++ ++ +( +2 +* +std +: +: +distance +( +pred_begin +( +PredBB +) +pred_end +( +PredBB +) +) +) +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +PredBB +DestBB +} +) +; ++ +for +( +auto +I += +pred_begin +( +PredBB +) +E += +pred_end +( +PredBB +) +; +I +! += +E +; ++ ++ +I +) +{ ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +* +I +PredBB +} +) +; ++ +/ +/ +This +predecessor +of +PredBB +may +already +have +DestBB +as +a +successor +. ++ +if +( +llvm +: +: +find +( +successors +( +* +I +) +DestBB +) += += +succ_end +( +* +I +) +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +* +I +DestBB +} +) +; ++ +} ++ +} ++ +/ +/ +Zap +anything +that +took +the +address +of +DestBB +. +Not +doing +this +will +give +the +/ +/ +address +an +invalid +value +. +if +( +DestBB +- +> +hasAddressTaken +( +) +) +{ +- +641 +7 ++ +691 +7 +void +llvm +: +: +MergeBasicBlockIntoOnlyPred +( +BasicBlock +* +DestBB +DominatorTree +* +DT +) +{ +/ +/ +If +the +PredBB +is +the +entry +block +of +the +function +move +DestBB +up +to +/ +/ +become +the +entry +block +after +we +erase +PredBB +. +- +if +( +PredBB += += +& +DestBB +- +> +getParent +( +) +- +> +getEntryBlock +( +) +) ++ +if +( +ReplaceEntryBB +) +DestBB +- +> +moveAfter +( +PredBB +) +; +if +( +DT +) +{ +- +653 +8 ++ +703 +19 +void +llvm +: +: +MergeBasicBlockIntoOnlyPred +( +BasicBlock +* +DestBB +DominatorTree +* +DT +) +{ +DT +- +> +eraseNode +( +PredBB +) +; +} +} +- +/ +/ +Nuke +BB +. +- +PredBB +- +> +eraseFromParent +( +) +; ++ ++ +if +( +DDT +) +{ ++ +DDT +- +> +deleteBB +( +PredBB +) +; +/ +/ +Deferred +deletion +of +BB +. ++ +if +( +ReplaceEntryBB +) ++ +/ +/ +The +entry +block +was +removed +and +there +is +no +external +interface +for +the ++ +/ +/ +dominator +tree +to +be +notified +of +this +change +. +In +this +corner +- +case +we ++ +/ +/ +recalculate +the +entire +tree +. ++ +DDT +- +> +recalculate +( +* +( +DestBB +- +> +getParent +( +) +) +) +; ++ +else ++ +DDT +- +> +applyUpdates +( +Updates +) +; ++ +} +else +{ ++ +PredBB +- +> +eraseFromParent +( +) +; +/ +/ +Nuke +BB +. ++ +} +} +/ +/ +/ +CanMergeValues +- +Return +true +if +we +can +choose +one +of +these +values +to +use +- +861 +7 ++ +922 +8 +static +void +redirectValuesFromPredecessorsToPhi +( +BasicBlock +* +BB +/ +/ +/ +potential +side +- +effect +free +intrinsics +and +the +branch +. +If +possible +/ +/ +/ +eliminate +BB +by +rewriting +all +the +predecessors +to +branch +to +the +successor +/ +/ +/ +block +and +return +true +. +If +we +can +' +t +transform +return +false +. +- +bool +llvm +: +: +TryToSimplifyUncondBranchFromEmptyBlock +( +BasicBlock +* +BB +) +{ ++ +bool +llvm +: +: +TryToSimplifyUncondBranchFromEmptyBlock +( +BasicBlock +* +BB ++ +DeferredDominance +* +DDT +) +{ +assert +( +BB +! += +& +BB +- +> +getParent +( +) +- +> +getEntryBlock +( +) +& +& +" +TryToSimplifyUncondBranchFromEmptyBlock +called +on +entry +block +! +" +) +; +- +902 +6 ++ +964 +19 +bool +llvm +: +: +TryToSimplifyUncondBranchFromEmptyBlock +( +BasicBlock +* +BB +) +{ +DEBUG +( +dbgs +( +) +< +< +" +Killing +Trivial +BB +: +\ +n +" +< +< +* +BB +) +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +if +( +DDT +) +{ ++ +Updates +. +reserve +( +1 ++ +( +2 +* +std +: +: +distance +( +pred_begin +( +BB +) +pred_end +( +BB +) +) +) +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +Succ +} +) +; ++ +/ +/ +All +predecessors +of +BB +will +be +moved +to +Succ +. ++ +for +( +auto +I += +pred_begin +( +BB +) +E += +pred_end +( +BB +) +; +I +! += +E +; ++ ++ +I +) +{ ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +* +I +BB +} +) +; ++ +/ +/ +This +predecessor +of +BB +may +already +have +Succ +as +a +successor +. ++ +if +( +llvm +: +: +find +( +successors +( +* +I +) +Succ +) += += +succ_end +( +* +I +) +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +* +I +Succ +} +) +; ++ +} ++ +} ++ +if +( +isa +< +PHINode +> +( +Succ +- +> +begin +( +) +) +) +{ +/ +/ +If +there +is +more +than +one +pred +of +succ +and +there +are +PHI +nodes +in +/ +/ +the +successor +then +we +need +to +add +incoming +edges +for +the +PHI +nodes +- +946 +7 ++ +1021 +13 +bool +llvm +: +: +TryToSimplifyUncondBranchFromEmptyBlock +( +BasicBlock +* +BB +) +{ +/ +/ +Everything +that +jumped +to +BB +now +goes +to +Succ +. +BB +- +> +replaceAllUsesWith +( +Succ +) +; +if +( +! +Succ +- +> +hasName +( +) +) +Succ +- +> +takeName +( +BB +) +; +- +BB +- +> +eraseFromParent +( +) +; +/ +/ +Delete +the +old +basic +block +. ++ ++ +if +( +DDT +) +{ ++ +DDT +- +> +deleteBB +( +BB +) +; +/ +/ +Deferred +deletion +of +the +old +basic +block +. ++ +DDT +- +> +applyUpdates +( +Updates +) +; ++ +} +else +{ ++ +BB +- +> +eraseFromParent +( +) +; +/ +/ +Delete +the +old +basic +block +. ++ +} +return +true +; +} +- +1448 +13 ++ +1529 +19 +unsigned +llvm +: +: +removeAllNonTerminatorAndEHPadInstructions +( +BasicBlock +* +BB +) +{ +} +unsigned +llvm +: +: +changeToUnreachable +( +Instruction +* +I +bool +UseLLVMTrap +- +bool +PreserveLCSSA +) +{ ++ +bool +PreserveLCSSA +DeferredDominance +* +DDT +) +{ +BasicBlock +* +BB += +I +- +> +getParent +( +) +; ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +/ +/ +Loop +over +all +of +the +successors +removing +BB +' +s +entry +from +any +PHI +/ +/ +nodes +. +- +for +( +BasicBlock +* +Successor +: +successors +( +BB +) +) ++ +if +( +DDT +) ++ +Updates +. +reserve +( +BB +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +) +; ++ +for +( +BasicBlock +* +Successor +: +successors +( +BB +) +) +{ +Successor +- +> +removePredecessor +( +BB +PreserveLCSSA +) +; +- ++ +if +( +DDT +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +Successor +} +) +; ++ +} +/ +/ +Insert +a +call +to +llvm +. +trap +right +before +this +. +This +turns +the +undefined +/ +/ +behavior +into +a +hard +fail +instead +of +falling +through +into +random +code +. +if +( +UseLLVMTrap +) +{ +- +1474 +11 ++ +1561 +13 +unsigned +llvm +: +: +changeToUnreachable +( +Instruction +* +I +bool +UseLLVMTrap +BB +- +> +getInstList +( +) +. +erase +( +BBI ++ ++ +) +; ++ ++ +NumInstrsRemoved +; +} ++ +if +( +DDT +) ++ +DDT +- +> +applyUpdates +( +Updates +) +; +return +NumInstrsRemoved +; +} +/ +/ +/ +changeToCall +- +Convert +the +specified +invoke +into +a +normal +call +. +- +static +void +changeToCall +( +InvokeInst +* +II +) +{ ++ +static +void +changeToCall +( +InvokeInst +* +II +DeferredDominance +* +DDT += +nullptr +) +{ +SmallVector +< +Value +* +8 +> +Args +( +II +- +> +arg_begin +( +) +II +- +> +arg_end +( +) +) +; +SmallVector +< +OperandBundleDef +1 +> +OpBundles +; +II +- +> +getOperandBundlesAsDefs +( +OpBundles +) +; +- +1491 +11 ++ +1580 +16 +static +void +changeToCall +( +InvokeInst +* +II +) +{ +II +- +> +replaceAllUsesWith +( +NewCall +) +; +/ +/ +Follow +the +call +by +a +branch +to +the +normal +destination +. +- +BranchInst +: +: +Create +( +II +- +> +getNormalDest +( +) +II +) +; ++ +BasicBlock +* +NormalDestBB += +II +- +> +getNormalDest +( +) +; ++ +BranchInst +: +: +Create +( +NormalDestBB +II +) +; +/ +/ +Update +PHI +nodes +in +the +unwind +destination +- +II +- +> +getUnwindDest +( +) +- +> +removePredecessor +( +II +- +> +getParent +( +) +) +; ++ +BasicBlock +* +BB += +II +- +> +getParent +( +) +; ++ +BasicBlock +* +UnwindDestBB += +II +- +> +getUnwindDest +( +) +; ++ +UnwindDestBB +- +> +removePredecessor +( +BB +) +; +II +- +> +eraseFromParent +( +) +; ++ +if +( +DDT +) ++ +DDT +- +> +deleteEdge +( +BB +UnwindDestBB +) +; +} +BasicBlock +* +llvm +: +: +changeToInvokeAndSplitBasicBlock +( +CallInst +* +CI +- +1536 +7 ++ +1630 +8 +BasicBlock +* +llvm +: +: +changeToInvokeAndSplitBasicBlock +( +CallInst +* +CI +} +static +bool +markAliveBlocks +( +Function +& +F +- +SmallPtrSetImpl +< +BasicBlock +* +> +& +Reachable +) +{ ++ +SmallPtrSetImpl +< +BasicBlock +* +> +& +Reachable ++ +DeferredDominance +* +DDT += +nullptr +) +{ +SmallVector +< +BasicBlock +* +128 +> +Worklist +; +BasicBlock +* +BB += +& +F +. +front +( +) +; +Worklist +. +push_back +( +BB +) +; +- +1556 +7 ++ +1651 +7 +static +bool +markAliveBlocks +( +Function +& +F +if +( +II +- +> +getIntrinsicID +( +) += += +Intrinsic +: +: +assume +) +{ +if +( +match +( +II +- +> +getArgOperand +( +0 +) +m_CombineOr +( +m_Zero +( +) +m_Undef +( +) +) +) +) +{ +/ +/ +Don +' +t +insert +a +call +to +llvm +. +trap +right +before +the +unreachable +. +- +changeToUnreachable +( +II +false +) +; ++ +changeToUnreachable +( +II +false +false +DDT +) +; +Changed += +true +; +break +; +} +- +1573 +7 ++ +1668 +8 +static +bool +markAliveBlocks +( +Function +& +F +/ +/ +still +be +useful +for +widening +. +if +( +match +( +II +- +> +getArgOperand +( +0 +) +m_Zero +( +) +) +) +if +( +! +isa +< +UnreachableInst +> +( +II +- +> +getNextNode +( +) +) +) +{ +- +changeToUnreachable +( +II +- +> +getNextNode +( +) +/ +* +UseLLVMTrap += +* +/ +false +) +; ++ +changeToUnreachable +( +II +- +> +getNextNode +( +) +/ +* +UseLLVMTrap += +* +/ +false ++ +false +DDT +) +; +Changed += +true +; +break +; +} +- +1583 +7 ++ +1679 +7 +static +bool +markAliveBlocks +( +Function +& +F +if +( +auto +* +CI += +dyn_cast +< +CallInst +> +( +& +I +) +) +{ +Value +* +Callee += +CI +- +> +getCalledValue +( +) +; +if +( +isa +< +ConstantPointerNull +> +( +Callee +) +| +| +isa +< +UndefValue +> +( +Callee +) +) +{ +- +changeToUnreachable +( +CI +/ +* +UseLLVMTrap += +* +/ +false +) +; ++ +changeToUnreachable +( +CI +/ +* +UseLLVMTrap += +* +/ +false +false +DDT +) +; +Changed += +true +; +break +; +} +- +1593 +7 ++ +1689 +7 +static +bool +markAliveBlocks +( +Function +& +F +/ +/ +though +. +if +( +! +isa +< +UnreachableInst +> +( +CI +- +> +getNextNode +( +) +) +) +{ +/ +/ +Don +' +t +insert +a +call +to +llvm +. +trap +right +before +the +unreachable +. +- +changeToUnreachable +( +CI +- +> +getNextNode +( +) +false +) +; ++ +changeToUnreachable +( +CI +- +> +getNextNode +( +) +false +false +DDT +) +; +Changed += +true +; +} +break +; +- +1612 +7 ++ +1708 +7 +static +bool +markAliveBlocks +( +Function +& +F +if +( +isa +< +UndefValue +> +( +Ptr +) +| +| +( +isa +< +ConstantPointerNull +> +( +Ptr +) +& +& +SI +- +> +getPointerAddressSpace +( +) += += +0 +) +) +{ +- +changeToUnreachable +( +SI +true +) +; ++ +changeToUnreachable +( +SI +true +false +DDT +) +; +Changed += +true +; +break +; +} +- +1624 +16 ++ +1720 +20 +static +bool +markAliveBlocks +( +Function +& +F +/ +/ +Turn +invokes +that +call +' +nounwind +' +functions +into +ordinary +calls +. +Value +* +Callee += +II +- +> +getCalledValue +( +) +; +if +( +isa +< +ConstantPointerNull +> +( +Callee +) +| +| +isa +< +UndefValue +> +( +Callee +) +) +{ +- +changeToUnreachable +( +II +true +) +; ++ +changeToUnreachable +( +II +true +false +DDT +) +; +Changed += +true +; +} +else +if +( +II +- +> +doesNotThrow +( +) +& +& +canSimplifyInvokeNoUnwind +( +& +F +) +) +{ +if +( +II +- +> +use_empty +( +) +& +& +II +- +> +onlyReadsMemory +( +) +) +{ +/ +/ +jump +to +the +normal +destination +branch +. +- +BranchInst +: +: +Create +( +II +- +> +getNormalDest +( +) +II +) +; +- +II +- +> +getUnwindDest +( +) +- +> +removePredecessor +( +II +- +> +getParent +( +) +) +; ++ +BasicBlock +* +NormalDestBB += +II +- +> +getNormalDest +( +) +; ++ +BasicBlock +* +UnwindDestBB += +II +- +> +getUnwindDest +( +) +; ++ +BranchInst +: +: +Create +( +NormalDestBB +II +) +; ++ +UnwindDestBB +- +> +removePredecessor +( +II +- +> +getParent +( +) +) +; +II +- +> +eraseFromParent +( +) +; ++ +if +( +DDT +) ++ +DDT +- +> +deleteEdge +( +BB +UnwindDestBB +) +; +} +else +- +changeToCall +( +II +) +; ++ +changeToCall +( +II +DDT +) +; +Changed += +true +; +} +} +else +if +( +auto +* +CatchSwitch += +dyn_cast +< +CatchSwitchInst +> +( +Terminator +) +) +{ +- +1679 +7 ++ +1779 +7 +static +bool +markAliveBlocks +( +Function +& +F +} +} +- +Changed +| += +ConstantFoldTerminator +( +BB +true +) +; ++ +Changed +| += +ConstantFoldTerminator +( +BB +true +nullptr +DDT +) +; +for +( +BasicBlock +* +Successor +: +successors +( +BB +) +) +if +( +Reachable +. +insert +( +Successor +) +. +second +) +Worklist +. +push_back +( +Successor +) +; +- +1687 +11 ++ +1787 +11 +static +bool +markAliveBlocks +( +Function +& +F +return +Changed +; +} +- +void +llvm +: +: +removeUnwindEdge +( +BasicBlock +* +BB +) +{ ++ +void +llvm +: +: +removeUnwindEdge +( +BasicBlock +* +BB +DeferredDominance +* +DDT +) +{ +TerminatorInst +* +TI += +BB +- +> +getTerminator +( +) +; +if +( +auto +* +II += +dyn_cast +< +InvokeInst +> +( +TI +) +) +{ +- +changeToCall +( +II +) +; ++ +changeToCall +( +II +DDT +) +; +return +; +} +- +1719 +15 ++ +1819 +18 +void +llvm +: +: +removeUnwindEdge +( +BasicBlock +* +BB +) +{ +UnwindDest +- +> +removePredecessor +( +BB +) +; +TI +- +> +replaceAllUsesWith +( +NewTI +) +; +TI +- +> +eraseFromParent +( +) +; ++ +if +( +DDT +) ++ +DDT +- +> +deleteEdge +( +BB +UnwindDest +) +; +} +/ +/ +/ +removeUnreachableBlocks +- +Remove +blocks +that +are +not +reachable +even +/ +/ +/ +if +they +are +in +a +dead +cycle +. +Return +true +if +a +change +was +made +false +/ +/ +/ +otherwise +. +If +LVI +is +passed +this +function +preserves +LazyValueInfo +/ +/ +/ +after +modifying +the +CFG +. +- +bool +llvm +: +: +removeUnreachableBlocks +( +Function +& +F +LazyValueInfo +* +LVI +) +{ ++ +bool +llvm +: +: +removeUnreachableBlocks +( +Function +& +F +LazyValueInfo +* +LVI ++ +DeferredDominance +* +DDT +) +{ +SmallPtrSet +< +BasicBlock +* +16 +> +Reachable +; +- +bool +Changed += +markAliveBlocks +( +F +Reachable +) +; ++ +bool +Changed += +markAliveBlocks +( +F +Reachable +DDT +) +; +/ +/ +If +there +are +unreachable +blocks +in +the +CFG +. +. +. +if +( +Reachable +. +size +( +) += += +F +. +size +( +) +) +- +1737 +25 ++ +1840 +39 +bool +llvm +: +: +removeUnreachableBlocks +( +Function +& +F +LazyValueInfo +* +LVI +) +{ +NumRemoved ++ += +F +. +size +( +) +- +Reachable +. +size +( +) +; +/ +/ +Loop +over +all +of +the +basic +blocks +that +are +not +reachable +dropping +all +of +- +/ +/ +their +internal +references +. +. +. +- +for +( +Function +: +: +iterator +BB += ++ ++ +F +. +begin +( +) +E += +F +. +end +( +) +; +BB +! += +E +; ++ ++ +BB +) +{ +- +if +( +Reachable +. +count +( +& +* +BB +) +) ++ +/ +/ +their +internal +references +. +Update +DDT +and +LVI +if +available +. ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +for +( +Function +: +: +iterator +I += ++ ++ +F +. +begin +( +) +E += +F +. +end +( +) +; +I +! += +E +; ++ ++ +I +) +{ ++ +auto +* +BB += +& +* +I +; ++ +if +( +Reachable +. +count +( +BB +) +) +continue +; +- +- +for +( +BasicBlock +* +Successor +: +successors +( +& +* +BB +) +) ++ +for +( +BasicBlock +* +Successor +: +successors +( +BB +) +) +{ +if +( +Reachable +. +count +( +Successor +) +) +- +Successor +- +> +removePredecessor +( +& +* +BB +) +; ++ +Successor +- +> +removePredecessor +( +BB +) +; ++ +if +( +DDT +) ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB +Successor +} +) +; ++ +} +if +( +LVI +) +- +LVI +- +> +eraseBlock +( +& +* +BB +) +; ++ +LVI +- +> +eraseBlock +( +BB +) +; +BB +- +> +dropAllReferences +( +) +; +} +- +for +( +Function +: +: +iterator +I += ++ ++ +F +. +begin +( +) +; +I +! += +F +. +end +( +) +; +) +- +if +( +! +Reachable +. +count +( +& +* +I +) +) +- +I += +F +. +getBasicBlockList +( +) +. +erase +( +I +) +; +- +else ++ +for +( +Function +: +: +iterator +I += ++ ++ +F +. +begin +( +) +; +I +! += +F +. +end +( +) +; +) +{ ++ +auto +* +BB += +& +* +I +; ++ +if +( +Reachable +. +count +( +BB +) +) +{ ++ ++ ++ +I +; ++ +continue +; ++ +} ++ +if +( +DDT +) +{ ++ +DDT +- +> +deleteBB +( +BB +) +; +/ +/ +deferred +deletion +of +BB +. ++ ++ +I +; ++ +} +else +{ ++ +I += +F +. +getBasicBlockList +( +) +. +erase +( +I +) +; ++ +} ++ +} ++ +if +( +DDT +) ++ +DDT +- +> +applyUpdates +( +Updates +) +; +return +true +; +} +diff +- +- +git +a +/ +llvm +/ +test +/ +Analysis +/ +LazyValueAnalysis +/ +lvi +- +after +- +jumpthreading +. +ll +b +/ +llvm +/ +test +/ +Analysis +/ +LazyValueAnalysis +/ +lvi +- +after +- +jumpthreading +. +ll +index +41bb8c9c820 +. +. +27cd2263bea +100644 +- +- +- +a +/ +llvm +/ +test +/ +Analysis +/ +LazyValueAnalysis +/ +lvi +- +after +- +jumpthreading +. +ll ++ ++ ++ +b +/ +llvm +/ +test +/ +Analysis +/ +LazyValueAnalysis +/ +lvi +- +after +- +jumpthreading +. +ll +- +19 +10 ++ +19 +13 +entry +: +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +i32 +% +a +' +is +: +overdefined +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +i32 +% +length +' +is +: +overdefined +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +% +iv += +phi +i32 +[ +0 +% +entry +] +[ +% +iv +. +next +% +backedge +] +' +in +BB +: +' +% +backedge +' +is +: +constantrange +< +0 +400 +> ++ +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +% +iv += +phi +i32 +[ +0 +% +entry +] +[ +% +iv +. +next +% +backedge +] +' +in +BB +: +' +% +exit +' +is +: +constantrange +< +399 +400 +> +; +CHECK +- +NEXT +: +% +iv += +phi +i32 +[ +0 +% +entry +] +[ +% +iv +. +next +% +backedge +] +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +% +iv +. +next += +add +nsw +i32 +% +iv +1 +' +in +BB +: +' +% +backedge +' +is +: +constantrange +< +1 +401 +> ++ +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +% +iv +. +next += +add +nsw +i32 +% +iv +1 +' +in +BB +: +' +% +exit +' +is +: +constantrange +< +400 +401 +> +; +CHECK +- +NEXT +: +% +iv +. +next += +add +nsw +i32 +% +iv +1 +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +% +cont += +icmp +slt +i32 +% +iv +. +next +400 +' +in +BB +: +' +% +backedge +' +is +: +overdefined ++ +; +CHECK +- +NEXT +: +; +LatticeVal +for +: +' +% +cont += +icmp +slt +i32 +% +iv +. +next +400 +' +in +BB +: +' +% +exit +' +is +: +constantrange +< +0 +- +1 +> +; +CHECK +- +NEXT +: +% +cont += +icmp +slt +i32 +% +iv +. +next +400 +; +CHECK +- +NOT +: +loop +loop +: +diff +- +- +git +a +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash +. +ll +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash +. +ll +new +file +mode +100644 +index +00000000000 +. +. +a5cf24d354c +- +- +- +/ +dev +/ +null ++ ++ ++ +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash +. +ll +- +0 +0 ++ +1 +265 ++ +; +RUN +: +opt +< +% +s +- +jump +- +threading +- +disable +- +output ++ ++ +% +struct +. +ham += +type +{ +i8 +i8 +i16 +i32 +} ++ +% +struct +. +zot += +type +{ +i32 +( +. +. +. +) +* +* +} ++ +% +struct +. +quux +. +0 += +type +{ +% +struct +. +wombat +} ++ +% +struct +. +wombat += +type +{ +% +struct +. +zot +} ++ ++ +global += +external +global +% +struct +. +ham +* +align +8 ++ +global +. +1 += +external +constant +i8 +* ++ ++ +declare +i32 +wombat +. +2 +( +) ++ ++ +define +void +blam +( +) +{ ++ +bb +: ++ +% +tmp += +load +i32 +i32 +* +undef ++ +% +tmp1 += +icmp +eq +i32 +% +tmp +0 ++ +br +i1 +% +tmp1 +label +% +bb11 +label +% +bb2 ++ ++ +bb2 +: ++ +% +tmp3 += +tail +call +i32 +wombat +. +2 +( +) ++ +switch +i32 +% +tmp3 +label +% +bb4 +[ ++ +i32 +0 +label +% +bb5 ++ +i32 +1 +label +% +bb7 ++ +i32 +2 +label +% +bb7 ++ +i32 +3 +label +% +bb11 ++ +] ++ ++ +bb4 +: ++ +br +label +% +bb7 ++ ++ +bb5 +: ++ +% +tmp6 += +tail +call +i32 +wombat +. +2 +( +) ++ +br +label +% +bb7 ++ ++ +bb7 +: ++ +% +tmp8 += +phi +i32 +[ +0 +% +bb5 +] +[ +1 +% +bb4 +] +[ +2 +% +bb2 +] +[ +2 +% +bb2 +] ++ +% +tmp9 += +icmp +eq +i32 +% +tmp8 +0 ++ +br +i1 +% +tmp9 +label +% +bb11 +label +% +bb10 ++ ++ +bb10 +: ++ +ret +void ++ ++ +bb11 +: ++ +ret +void ++ +} ++ ++ +define +void +spam +( +% +struct +. +ham +* +% +arg +) +{ ++ +bb +: ++ +% +tmp += +load +i8 +i8 +* +undef +align +8 ++ +switch +i8 +% +tmp +label +% +bb11 +[ ++ +i8 +1 +label +% +bb11 ++ +i8 +2 +label +% +bb11 ++ +i8 +3 +label +% +bb1 ++ +i8 +4 +label +% +bb1 ++ +] ++ ++ +bb1 +: ++ +br +label +% +bb2 ++ ++ +bb2 +: ++ +% +tmp3 += +phi +i32 +[ +0 +% +bb1 +] +[ +% +tmp3 +% +bb8 +] ++ +br +label +% +bb4 ++ ++ +bb4 +: ++ +% +tmp5 += +load +i8 +i8 +* +undef +align +8 ++ +switch +i8 +% +tmp5 +label +% +bb11 +[ ++ +i8 +0 +label +% +bb11 ++ +i8 +1 +label +% +bb10 ++ +i8 +2 +label +% +bb10 ++ +i8 +3 +label +% +bb6 ++ +i8 +4 +label +% +bb6 ++ +] ++ ++ +bb6 +: ++ +br +label +% +bb7 ++ ++ +bb7 +: ++ +br +i1 +undef +label +% +bb8 +label +% +bb10 ++ ++ +bb8 +: ++ +% +tmp9 += +icmp +eq +% +struct +. +ham +* +undef +% +arg ++ +br +i1 +% +tmp9 +label +% +bb10 +label +% +bb2 ++ ++ +bb10 +: ++ +switch +i32 +% +tmp3 +label +% +bb4 +[ ++ +i32 +0 +label +% +bb14 ++ +i32 +1 +label +% +bb11 ++ +i32 +2 +label +% +bb12 ++ +] ++ ++ +bb11 +: ++ +unreachable ++ ++ +bb12 +: ++ +% +tmp13 += +load +% +struct +. +ham +* +% +struct +. +ham +* +* +undef ++ +br +label +% +bb14 ++ ++ +bb14 +: ++ +% +tmp15 += +phi +% +struct +. +ham +* +[ +% +tmp13 +% +bb12 +] +[ +null +% +bb10 +] ++ +br +label +% +bb16 ++ ++ +bb16 +: ++ +% +tmp17 += +load +i8 +i8 +* +undef +align +8 ++ +switch +i8 +% +tmp17 +label +% +bb11 +[ ++ +i8 +0 +label +% +bb11 ++ +i8 +11 +label +% +bb18 ++ +i8 +12 +label +% +bb18 ++ +] ++ ++ +bb18 +: ++ +br +label +% +bb19 ++ ++ +bb19 +: ++ +br +label +% +bb20 ++ ++ +bb20 +: ++ +% +tmp21 += +load +% +struct +. +ham +* +% +struct +. +ham +* +* +undef ++ +switch +i8 +undef +label +% +bb22 +[ ++ +i8 +0 +label +% +bb4 ++ +i8 +11 +label +% +bb10 ++ +i8 +12 +label +% +bb10 ++ +] ++ ++ +bb22 +: ++ +br +label +% +bb23 ++ ++ +bb23 +: ++ +% +tmp24 += +icmp +eq +% +struct +. +ham +* +% +tmp21 +null ++ +br +i1 +% +tmp24 +label +% +bb35 +label +% +bb25 ++ ++ +bb25 +: ++ +% +tmp26 += +icmp +eq +% +struct +. +ham +* +% +tmp15 +null ++ +br +i1 +% +tmp26 +label +% +bb34 +label +% +bb27 ++ ++ +bb27 +: ++ +% +tmp28 += +load +% +struct +. +ham +* +% +struct +. +ham +* +* +undef ++ +% +tmp29 += +icmp +eq +% +struct +. +ham +* +% +tmp28 +% +tmp21 ++ +br +i1 +% +tmp29 +label +% +bb35 +label +% +bb30 ++ ++ +bb30 +: ++ +br +label +% +bb31 ++ ++ +bb31 +: ++ +% +tmp32 += +load +i8 +i8 +* +undef +align +8 ++ +% +tmp33 += +icmp +eq +i8 +% +tmp32 +0 ++ +br +i1 +% +tmp33 +label +% +bb31 +label +% +bb34 ++ ++ +bb34 +: ++ +br +label +% +bb35 ++ ++ +bb35 +: ++ +% +tmp36 += +phi +i1 +[ +true +% +bb34 +] +[ +false +% +bb23 +] +[ +true +% +bb27 +] ++ +br +label +% +bb37 ++ ++ +bb37 +: ++ +% +tmp38 += +icmp +eq +% +struct +. +ham +* +% +tmp15 +null ++ +br +i1 +% +tmp38 +label +% +bb39 +label +% +bb41 ++ ++ +bb39 +: ++ +% +tmp40 += +load +% +struct +. +ham +* +% +struct +. +ham +* +* +global ++ +br +label +% +bb41 ++ ++ +bb41 +: ++ +% +tmp42 += +select +i1 +% +tmp36 +% +struct +. +ham +* +undef +% +struct +. +ham +* +undef ++ +ret +void ++ +} ++ ++ +declare +i32 +foo +( +. +. +. +) ++ ++ +define +void +zot +( +) +align +2 +personality +i8 +* +bitcast +( +i32 +( +. +. +. +) +* +foo +to +i8 +* +) +{ ++ +bb +: ++ +invoke +void +bar +( +) ++ +to +label +% +bb1 +unwind +label +% +bb3 ++ ++ +bb1 +: ++ +invoke +void +bar +( +) ++ +to +label +% +bb2 +unwind +label +% +bb4 ++ ++ +bb2 +: ++ +invoke +void +bar +( +) ++ +to +label +% +bb6 +unwind +label +% +bb17 ++ ++ +bb3 +: ++ +% +tmp += +landingpad +{ +i8 +* +i32 +} ++ +catch +i8 +* +bitcast +( +i8 +* +* +global +. +1 +to +i8 +* +) ++ +catch +i8 +* +null ++ +unreachable ++ ++ +bb4 +: ++ +% +tmp5 += +landingpad +{ +i8 +* +i32 +} ++ +catch +i8 +* +bitcast +( +i8 +* +* +global +. +1 +to +i8 +* +) ++ +catch +i8 +* +null ++ +unreachable ++ ++ +bb6 +: ++ +invoke +void +bar +( +) ++ +to +label +% +bb7 +unwind +label +% +bb19 ++ ++ +bb7 +: ++ +invoke +void +bar +( +) ++ +to +label +% +bb10 +unwind +label +% +bb8 ++ ++ +bb8 +: ++ +% +tmp9 += +landingpad +{ +i8 +* +i32 +} ++ +cleanup ++ +catch +i8 +* +bitcast +( +i8 +* +* +global +. +1 +to +i8 +* +) ++ +catch +i8 +* +null ++ +unreachable ++ ++ +bb10 +: ++ +% +tmp11 += +load +i32 +( +% +struct +. +zot +* +) +* +i32 +( +% +struct +. +zot +* +) +* +* +undef +align +8 ++ +% +tmp12 += +invoke +i32 +% +tmp11 +( +% +struct +. +zot +* +nonnull +undef +) ++ +to +label +% +bb13 +unwind +label +% +bb21 ++ ++ +bb13 +: ++ +invoke +void +bar +( +) ++ +to +label +% +bb14 +unwind +label +% +bb23 ++ ++ +bb14 +: ++ +% +tmp15 += +load +i32 +( +% +struct +. +zot +* +) +* +i32 +( +% +struct +. +zot +* +) +* +* +undef +align +8 ++ +% +tmp16 += +invoke +i32 +% +tmp15 +( +% +struct +. +zot +* +nonnull +undef +) ++ +to +label +% +bb26 +unwind +label +% +bb23 ++ ++ +bb17 +: ++ +% +tmp18 += +landingpad +{ +i8 +* +i32 +} ++ +catch +i8 +* +bitcast +( +i8 +* +* +global +. +1 +to +i8 +* +) ++ +catch +i8 +* +null ++ +unreachable ++ ++ +bb19 +: ++ +% +tmp20 += +landingpad +{ +i8 +* +i32 +} ++ +catch +i8 +* +bitcast +( +i8 +* +* +global +. +1 +to +i8 +* +) ++ +catch +i8 +* +null ++ +unreachable ++ ++ +bb21 +: ++ +% +tmp22 += +landingpad +{ +i8 +* +i32 +} ++ +catch +i8 +* +bitcast +( +i8 +* +* +global +. +1 +to +i8 +* +) ++ +catch +i8 +* +null ++ +unreachable ++ ++ +bb23 +: ++ +% +tmp24 += +phi +% +struct +. +quux +. +0 +* +[ +null +% +bb26 +] +[ +null +% +bb14 +] +[ +undef +% +bb13 +] ++ +% +tmp25 += +landingpad +{ +i8 +* +i32 +} ++ +catch +i8 +* +bitcast +( +i8 +* +* +global +. +1 +to +i8 +* +) ++ +catch +i8 +* +null ++ +br +label +% +bb30 ++ ++ +bb26 +: ++ +% +tmp27 += +load +i32 +( +% +struct +. +zot +* +) +* +i32 +( +% +struct +. +zot +* +) +* +* +undef +align +8 ++ +% +tmp28 += +invoke +i32 +% +tmp27 +( +% +struct +. +zot +* +nonnull +undef +) ++ +to +label +% +bb29 +unwind +label +% +bb23 ++ ++ +bb29 +: ++ +unreachable ++ ++ +bb30 +: ++ +% +tmp31 += +icmp +eq +% +struct +. +quux +. +0 +* +% +tmp24 +null ++ +br +i1 +% +tmp31 +label +% +bb32 +label +% +bb29 ++ ++ +bb32 +: ++ +unreachable ++ +} ++ ++ +declare +void +bar +( +) +diff +- +- +git +a +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash2 +. +ll +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash2 +. +ll +new +file +mode +100644 +index +00000000000 +. +. +92bea6a7dff +- +- +- +/ +dev +/ +null ++ ++ ++ +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +ddt +- +crash2 +. +ll +- +0 +0 ++ +1 +40 ++ +; +RUN +: +opt +< +% +s +- +jump +- +threading +- +disable +- +output ++ ++ +% +struct +. +aaa += +type +{ +i8 +} ++ ++ +define +void +chrome +( +% +struct +. +aaa +* +noalias +sret +% +arg +) +local_unnamed_addr +# +0 +align +2 +personality +i8 +* +bitcast +( +i32 +( +. +. +. +) +* +chrome2 +to +i8 +* +) +{ ++ +bb +: ++ +% +tmp += +load +i32 +i32 +* +undef +align +4 ++ +% +tmp1 += +icmp +eq +i32 +% +tmp +0 ++ +br +i1 +% +tmp1 +label +% +bb2 +label +% +bb13 ++ ++ +bb2 +: ++ +% +tmp3 += +getelementptr +inbounds +% +struct +. +aaa +% +struct +. +aaa +* +% +arg +i64 +0 +i32 +0 ++ +% +tmp4 += +load +i8 +i8 +* +% +tmp3 +align +1 ++ +% +tmp5 += +icmp +eq +i8 +% +tmp4 +0 ++ +br +i1 +% +tmp5 +label +% +bb6 +label +% +bb7 ++ ++ +bb6 +: ++ +store +i8 +0 +i8 +* +% +tmp3 +align +1 ++ +br +label +% +bb7 ++ ++ +bb7 +: ++ +% +tmp8 += +load +i8 +i8 +* +% +tmp3 +align +1 ++ +% +tmp9 += +icmp +ne +i8 +% +tmp8 +0 ++ +% +tmp10 += +select +i1 +% +tmp9 +i1 +true +i1 +false ++ +br +i1 +% +tmp10 +label +% +bb12 +label +% +bb11 ++ ++ +bb11 +: ++ +br +label +% +bb12 ++ ++ +bb12 +: ++ +br +i1 +% +tmp9 +label +% +bb14 +label +% +bb13 ++ ++ +bb13 +: ++ +unreachable ++ ++ +bb14 +: ++ +ret +void ++ +} ++ ++ +declare +i32 +chrome2 +( +. +. +. +) +diff +- +- +git +a +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +lvi +- +tristate +. +ll +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +lvi +- +tristate +. +ll +new +file +mode +100644 +index +00000000000 +. +. +0aa87383347 +- +- +- +/ +dev +/ +null ++ ++ ++ +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +lvi +- +tristate +. +ll +- +0 +0 ++ +1 +50 ++ +; +RUN +: +opt +- +jump +- +threading +- +simplifycfg +- +S +< +% +s +| +FileCheck +% +s ++ +; +CHECK +- +NOT +: +bb6 +: ++ +; +CHECK +- +NOT +: +bb7 +: ++ +; +CHECK +- +NOT +: +bb8 +: ++ +; +CHECK +- +NOT +: +bb11 +: ++ +; +CHECK +- +NOT +: +bb12 +: ++ +; +CHECK +: +bb +: ++ +; +CHECK +: +bb2 +: ++ +; +CHECK +: +bb4 +: ++ +; +CHECK +: +bb10 +: ++ +; +CHECK +: +bb13 +: ++ +declare +void +ham +( +) ++ ++ +define +void +hoge +( +) +{ ++ +bb +: ++ +% +tmp += +and +i32 +undef +1073741823 ++ +% +tmp1 += +icmp +eq +i32 +% +tmp +2 ++ +br +i1 +% +tmp1 +label +% +bb12 +label +% +bb2 ++ ++ +bb2 +: ++ +% +tmp3 += +icmp +eq +i32 +% +tmp +3 ++ +br +i1 +% +tmp3 +label +% +bb13 +label +% +bb4 ++ ++ +bb4 +: ++ +% +tmp5 += +icmp +eq +i32 +% +tmp +5 ++ +br +i1 +% +tmp5 +label +% +bb6 +label +% +bb7 ++ ++ +bb6 +: ++ +tail +call +void +ham +( +) ++ +br +label +% +bb7 ++ ++ +bb7 +: ++ +br +i1 +% +tmp3 +label +% +bb13 +label +% +bb8 ++ ++ +bb8 +: ++ +% +tmp9 += +icmp +eq +i32 +% +tmp +4 ++ +br +i1 +% +tmp9 +label +% +bb13 +label +% +bb10 ++ ++ +bb10 +: ++ +br +i1 +% +tmp9 +label +% +bb11 +label +% +bb13 ++ ++ +bb11 +: ++ +br +label +% +bb13 ++ ++ +bb12 +: ++ +br +label +% +bb2 ++ ++ +bb13 +: ++ +ret +void ++ +} +diff +- +- +git +a +/ +llvm +/ +unittests +/ +IR +/ +CMakeLists +. +txt +b +/ +llvm +/ +unittests +/ +IR +/ +CMakeLists +. +txt +index +83f9dfd3176 +. +. +15f869c6bd4 +100644 +- +- +- +a +/ +llvm +/ +unittests +/ +IR +/ +CMakeLists +. +txt ++ ++ ++ +b +/ +llvm +/ +unittests +/ +IR +/ +CMakeLists +. +txt +- +15 +6 ++ +15 +7 +set +( +IRSources +ConstantsTest +. +cpp +DebugInfoTest +. +cpp +DebugTypeODRUniquingTest +. +cpp ++ +DeferredDominanceTest +. +cpp +DominatorTreeTest +. +cpp +DominatorTreeBatchUpdatesTest +. +cpp +FunctionTest +. +cpp +diff +- +- +git +a +/ +llvm +/ +unittests +/ +IR +/ +DeferredDominanceTest +. +cpp +b +/ +llvm +/ +unittests +/ +IR +/ +DeferredDominanceTest +. +cpp +new +file +mode +100644 +index +00000000000 +. +. +96156f89a74 +- +- +- +/ +dev +/ +null ++ ++ ++ +b +/ +llvm +/ +unittests +/ +IR +/ +DeferredDominanceTest +. +cpp +- +0 +0 ++ +1 +344 ++ +/ +/ += += += +- +llvm +/ +unittests +/ +IR +/ +DeferredDominanceTest +. +cpp +- +DDT +unit +tests +- +- +- +- +- +- +- += += += +/ +/ ++ +/ +/ ++ +/ +/ +The +LLVM +Compiler +Infrastructure ++ +/ +/ ++ +/ +/ +This +file +is +distributed +under +the +University +of +Illinois +Open +Source ++ +/ +/ +License +. +See +LICENSE +. +TXT +for +details +. ++ +/ +/ ++ +/ +/ += += += +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- += += += +/ +/ ++ ++ +# +include +" +llvm +/ +AsmParser +/ +Parser +. +h +" ++ +# +include +" +llvm +/ +IR +/ +Constants +. +h +" ++ +# +include +" +llvm +/ +IR +/ +Dominators +. +h +" ++ +# +include +" +llvm +/ +IR +/ +Instructions +. +h +" ++ +# +include +" +llvm +/ +IR +/ +LLVMContext +. +h +" ++ +# +include +" +llvm +/ +IR +/ +Module +. +h +" ++ +# +include +" +llvm +/ +Support +/ +SourceMgr +. +h +" ++ +# +include +" +gtest +/ +gtest +. +h +" ++ ++ +using +namespace +llvm +; ++ ++ +static +std +: +: +unique_ptr +< +Module +> +makeLLVMModule +( +LLVMContext +& +Context ++ +StringRef +ModuleStr +) +{ ++ +SMDiagnostic +Err +; ++ +std +: +: +unique_ptr +< +Module +> +M += +parseAssemblyString +( +ModuleStr +Err +Context +) +; ++ +assert +( +M +& +& +" +Bad +LLVM +IR +? +" +) +; ++ +return +M +; ++ +} ++ ++ +TEST +( +DeferredDominance +BasicOperations +) +{ ++ +StringRef +FuncName += +" +f +" +; ++ +StringRef +ModuleString += ++ +" +define +i32 +f +( +i32 +% +i +i32 +* +% +p +) +{ +\ +n +" ++ +" +bb0 +: +\ +n +" ++ +" +store +i32 +% +i +i32 +* +% +p +\ +n +" ++ +" +switch +i32 +% +i +label +% +bb1 +[ +\ +n +" ++ +" +i32 +0 +label +% +bb2 +\ +n +" ++ +" +i32 +1 +label +% +bb2 +\ +n +" ++ +" +i32 +2 +label +% +bb3 +\ +n +" ++ +" +] +\ +n +" ++ +" +bb1 +: +\ +n +" ++ +" +ret +i32 +1 +\ +n +" ++ +" +bb2 +: +\ +n +" ++ +" +ret +i32 +2 +\ +n +" ++ +" +bb3 +: +\ +n +" ++ +" +ret +i32 +3 +\ +n +" ++ +" +} +\ +n +" +; ++ +/ +/ +Make +the +module +. ++ +LLVMContext +Context +; ++ +std +: +: +unique_ptr +< +Module +> +M += +makeLLVMModule +( +Context +ModuleString +) +; ++ +Function +* +F += +M +- +> +getFunction +( +FuncName +) +; ++ +ASSERT_NE +( +F +nullptr +) +< +< +" +Couldn +' +t +get +function +" +< +< +FuncName +< +< +" +. +" +; ++ ++ +/ +/ +Make +the +DDT +. ++ +DominatorTree +DT +( +* +F +) +; ++ +DeferredDominance +DDT +( +DT +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ ++ +Function +: +: +iterator +FI += +F +- +> +begin +( +) +; ++ +BasicBlock +* +BB0 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB1 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB2 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB3 += +& +* +FI ++ ++ +; ++ ++ +/ +/ +Test +discards +of +invalid +self +- +domination +updates +. +These +use +the +single ++ +/ +/ +short +- +hand +interface +but +are +still +queued +inside +DDT +. ++ +DDT +. +deleteEdge +( +BB0 +BB0 +) +; ++ +DDT +. +insertEdge +( +BB1 +BB1 +) +; ++ ++ +/ +/ +Delete +edge +bb0 +- +> +bb3 +and +push +the +update +twice +to +verify +duplicate ++ +/ +/ +entries +are +discarded +. ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +Updates +. +reserve +( +4 +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB0 +BB3 +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB0 +BB3 +} +) +; ++ ++ +/ +/ +Unnecessary +Insert +: +no +edge +bb1 +- +> +bb2 +after +change +to +bb0 +. ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Insert +BB1 +BB2 +} +) +; ++ +/ +/ +Unnecessary +Delete +: +edge +exists +bb0 +- +> +bb1 +after +change +to +bb0 +. ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB0 +BB1 +} +) +; ++ ++ +/ +/ +CFG +Change +: +remove +edge +bb0 +- +> +bb3 +and +one +duplicate +edge +bb0 +- +> +bb2 +. ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +4u +) +; ++ +BB0 +- +> +getTerminator +( +) +- +> +eraseFromParent +( +) +; ++ +BranchInst +: +: +Create +( +BB1 +BB2 +ConstantInt +: +: +getTrue +( +F +- +> +getContext +( +) +) +BB0 +) +; ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +2u +) +; ++ ++ +/ +/ +Deletion +of +a +BasicBlock +is +an +immediate +event +. +We +remove +all +uses +to +the ++ +/ +/ +contained +Instructions +and +change +the +Terminator +to +" +unreachable +" +when ++ +/ +/ +queued +for +deletion +. +Its +parent +is +still +F +until +DDT +. +flush +( +) +is +called +. +We ++ +/ +/ +don +' +t +defer +this +action +because +it +can +cause +problems +for +other +transforms ++ +/ +/ +or +analysis +as +it +' +s +part +of +the +actual +CFG +. +We +only +defer +updates +to +the ++ +/ +/ +DominatorTree +. +This +code +will +crash +if +it +is +placed +before +the ++ +/ +/ +BranchInst +: +: +Create +( +) +call +above +. ++ +ASSERT_FALSE +( +isa +< +UnreachableInst +> +( +BB3 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_FALSE +( +DDT +. +pendingDeletedBB +( +BB3 +) +) +; ++ +DDT +. +deleteBB +( +BB3 +) +; ++ +EXPECT_TRUE +( +DDT +. +pendingDeletedBB +( +BB3 +) +) +; ++ +ASSERT_TRUE +( +isa +< +UnreachableInst +> +( +BB3 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_EQ +( +BB3 +- +> +getParent +( +) +F +) +; ++ ++ +/ +/ +Verify +. +Updates +to +DDT +must +be +applied +* +after +* +all +changes +to +the +CFG ++ +/ +/ +( +including +block +deletion +) +. ++ +DDT +. +applyUpdates +( +Updates +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ +} ++ ++ +TEST +( +DeferredDominance +PairedUpdate +) +{ ++ +StringRef +FuncName += +" +f +" +; ++ +StringRef +ModuleString += ++ +" +define +i32 +f +( +i32 +% +i +i32 +* +% +p +) +{ +\ +n +" ++ +" +bb0 +: +\ +n +" ++ +" +store +i32 +% +i +i32 +* +% +p +\ +n +" ++ +" +switch +i32 +% +i +label +% +bb1 +[ +\ +n +" ++ +" +i32 +0 +label +% +bb2 +\ +n +" ++ +" +i32 +1 +label +% +bb2 +\ +n +" ++ +" +] +\ +n +" ++ +" +bb1 +: +\ +n +" ++ +" +ret +i32 +1 +\ +n +" ++ +" +bb2 +: +\ +n +" ++ +" +ret +i32 +2 +\ +n +" ++ +" +} +\ +n +" +; ++ +/ +/ +Make +the +module +. ++ +LLVMContext +Context +; ++ +std +: +: +unique_ptr +< +Module +> +M += +makeLLVMModule +( +Context +ModuleString +) +; ++ +Function +* +F += +M +- +> +getFunction +( +FuncName +) +; ++ +ASSERT_NE +( +F +nullptr +) +< +< +" +Couldn +' +t +get +function +" +< +< +FuncName +< +< +" +. +" +; ++ ++ +/ +/ +Make +the +DDT +. ++ +DominatorTree +DT +( +* +F +) +; ++ +DeferredDominance +DDT +( +DT +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ ++ +Function +: +: +iterator +FI += +F +- +> +begin +( +) +; ++ +BasicBlock +* +BB0 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB1 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB2 += +& +* +FI ++ ++ +; ++ ++ +/ +/ +CFG +Change +: +only +edge +from +bb0 +is +bb0 +- +> +bb1 +. ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +3u +) +; ++ +BB0 +- +> +getTerminator +( +) +- +> +eraseFromParent +( +) +; ++ +BranchInst +: +: +Create +( +BB1 +BB0 +) +; ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +1u +) +; ++ ++ +/ +/ +Must +be +done +after +the +CFG +change +. +The +applyUpdate +( +) +routine +analyzes +the ++ +/ +/ +current +state +of +the +CFG +. ++ +DDT +. +deleteEdge +( +BB0 +BB2 +) +; ++ ++ +/ +/ +CFG +Change +: +bb0 +now +has +bb0 +- +> +bb1 +and +bb0 +- +> +bb2 +. ++ +/ +/ +With +this +change +no +dominance +has +been +altered +from +the +original +IR +. +DT ++ +/ +/ +doesn +' +t +care +if +the +type +of +TerminatorInstruction +changed +only +if +the ++ +/ +/ +unique +edges +have +. ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +1u +) +; ++ +BB0 +- +> +getTerminator +( +) +- +> +eraseFromParent +( +) +; ++ +BranchInst +: +: +Create +( +BB1 +BB2 +ConstantInt +: +: +getTrue +( +F +- +> +getContext +( +) +) +BB0 +) +; ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +2u +) +; ++ ++ +/ +/ +Must +be +done +after +the +CFG +change +. +The +applyUpdate +( +) +routine +analyzes +the ++ +/ +/ +current +state +of +the +CFG +. +This +DDT +update +pairs +with +the +previous +one +and ++ +/ +/ +is +cancelled +out +before +ever +applying +updates +to +DT +. ++ +DDT +. +insertEdge +( +BB0 +BB2 +) +; ++ ++ +/ +/ +Test +the +empty +DeletedBB +list +. ++ +EXPECT_FALSE +( +DDT +. +pendingDeletedBB +( +BB0 +) +) +; ++ +EXPECT_FALSE +( +DDT +. +pendingDeletedBB +( +BB1 +) +) +; ++ +EXPECT_FALSE +( +DDT +. +pendingDeletedBB +( +BB2 +) +) +; ++ ++ +/ +/ +The +DT +has +no +changes +this +flush +( +) +simply +returns +a +reference +to +the ++ +/ +/ +internal +DT +calculated +at +the +beginning +of +this +test +. ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ +} ++ ++ +TEST +( +DeferredDominance +ReplaceEntryBB +) +{ ++ +StringRef +FuncName += +" +f +" +; ++ +StringRef +ModuleString += ++ +" +define +i32 +f +( +) +{ +\ +n +" ++ +" +bb0 +: +\ +n +" ++ +" +br +label +% +bb1 +\ +n +" ++ +" +bb1 +: +\ +n +" ++ +" +ret +i32 +1 +\ +n +" ++ +" +} +\ +n +" +; ++ +/ +/ +Make +the +module +. ++ +LLVMContext +Context +; ++ +std +: +: +unique_ptr +< +Module +> +M += +makeLLVMModule +( +Context +ModuleString +) +; ++ +Function +* +F += +M +- +> +getFunction +( +FuncName +) +; ++ +ASSERT_NE +( +F +nullptr +) +< +< +" +Couldn +' +t +get +function +" +< +< +FuncName +< +< +" +. +" +; ++ ++ +/ +/ +Make +the +DDT +. ++ +DominatorTree +DT +( +* +F +) +; ++ +DeferredDominance +DDT +( +DT +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ ++ +Function +: +: +iterator +FI += +F +- +> +begin +( +) +; ++ +BasicBlock +* +BB0 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB1 += +& +* +FI ++ ++ +; ++ ++ +/ +/ +Add +a +block +as +the +new +function +entry +BB +. +We +also +link +it +to +BB0 +. ++ +BasicBlock +* +NewEntry += ++ +BasicBlock +: +: +Create +( +F +- +> +getContext +( +) +" +new_entry +" +F +BB0 +) +; ++ +BranchInst +: +: +Create +( +BB0 +NewEntry +) +; ++ +EXPECT_EQ +( +F +- +> +begin +( +) +- +> +getName +( +) +NewEntry +- +> +getName +( +) +) +; ++ +EXPECT_TRUE +( +& +F +- +> +getEntryBlock +( +) += += +NewEntry +) +; ++ ++ +/ +/ +Insert +the +new +edge +between +new_eentry +- +> +bb0 +. +Without +this +the ++ +/ +/ +recalculate +( +) +call +below +will +not +actually +recalculate +the +DT +as +there ++ +/ +/ +are +no +changes +pending +and +no +blocks +deleted +. ++ +DDT +. +insertEdge +( +NewEntry +BB0 +) +; ++ ++ +/ +/ +Changing +the +Entry +BB +requires +a +full +recalulation +. ++ +DDT +. +recalculate +( +* +F +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ ++ +/ +/ +CFG +Change +: +remove +new_edge +- +> +bb0 +and +redirect +to +new_edge +- +> +bb1 +. ++ +EXPECT_EQ +( +NewEntry +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +1u +) +; ++ +NewEntry +- +> +getTerminator +( +) +- +> +eraseFromParent +( +) +; ++ +BranchInst +: +: +Create +( +BB1 +NewEntry +) +; ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +1u +) +; ++ ++ +/ +/ +Update +the +DDT +. +At +this +point +bb0 +now +has +no +predecessors +but +is +still +a ++ +/ +/ +Child +of +F +. ++ +DDT +. +applyUpdates +( +{ +{ +DominatorTree +: +: +Delete +NewEntry +BB0 +} ++ +{ +DominatorTree +: +: +Insert +NewEntry +BB1 +} +} +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ ++ +/ +/ +Now +remove +bb0 +from +F +. ++ +ASSERT_FALSE +( +isa +< +UnreachableInst +> +( +BB0 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_FALSE +( +DDT +. +pendingDeletedBB +( +BB0 +) +) +; ++ +DDT +. +deleteBB +( +BB0 +) +; ++ +EXPECT_TRUE +( +DDT +. +pendingDeletedBB +( +BB0 +) +) +; ++ +ASSERT_TRUE +( +isa +< +UnreachableInst +> +( +BB0 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_EQ +( +BB0 +- +> +getParent +( +) +F +) +; ++ ++ +/ +/ +Perform +a +full +recalculation +of +the +DDT +. +It +is +not +necessary +here +but +we ++ +/ +/ +do +this +to +test +the +case +when +there +are +no +pending +DT +updates +but +there +are ++ +/ +/ +pending +deleted +BBs +. ++ +DDT +. +recalculate +( +* +F +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ +} ++ ++ +TEST +( +DeferredDominance +InheritedPreds +) +{ ++ +StringRef +FuncName += +" +f +" +; ++ +StringRef +ModuleString += ++ +" +define +i32 +f +( +i32 +% +i +i32 +* +% +p +) +{ +\ +n +" ++ +" +bb0 +: +\ +n +" ++ +" +store +i32 +% +i +i32 +* +% +p +\ +n +" ++ +" +switch +i32 +% +i +label +% +bb1 +[ +\ +n +" ++ +" +i32 +2 +label +% +bb2 +\ +n +" ++ +" +i32 +3 +label +% +bb3 +\ +n +" ++ +" +] +\ +n +" ++ +" +bb1 +: +\ +n +" ++ +" +br +label +% +bb3 +\ +n +" ++ +" +bb2 +: +\ +n +" ++ +" +br +label +% +bb3 +\ +n +" ++ +" +bb3 +: +\ +n +" ++ +" +ret +i32 +3 +\ +n +" ++ +" +} +\ +n +" +; ++ +/ +/ +Make +the +module +. ++ +LLVMContext +Context +; ++ +std +: +: +unique_ptr +< +Module +> +M += +makeLLVMModule +( +Context +ModuleString +) +; ++ +Function +* +F += +M +- +> +getFunction +( +FuncName +) +; ++ +ASSERT_NE +( +F +nullptr +) +< +< +" +Couldn +' +t +get +function +" +< +< +FuncName +< +< +" +. +" +; ++ ++ +/ +/ +Make +the +DDT +. ++ +DominatorTree +DT +( +* +F +) +; ++ +DeferredDominance +DDT +( +DT +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ ++ +Function +: +: +iterator +FI += +F +- +> +begin +( +) +; ++ +BasicBlock +* +BB0 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB1 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB2 += +& +* +FI ++ ++ +; ++ +BasicBlock +* +BB3 += +& +* +FI ++ ++ +; ++ ++ +/ +/ +There +are +several +CFG +locations +where +we +have +: ++ +/ +/ ++ +/ +/ +pred1 +. +. +predN ++ +/ +/ +| +| ++ +/ +/ ++ +> +curr +< ++ +converted +into +: +pred1 +. +. +predN +curr ++ +/ +/ +| +| +| ++ +/ +/ +v ++ +> +succ +< ++ ++ +/ +/ +succ ++ +/ +/ ++ +/ +/ +There +is +a +specific +shape +of +this +we +have +to +be +careful +of +: ++ +/ +/ ++ +/ +/ +pred1 +. +. +predN ++ +/ +/ +| +| +| ++ +/ +/ +| ++ +> +curr +< ++ +converted +into +: +pred1 +. +. +predN +curr ++ +/ +/ +| +| +| +| ++ +/ +/ +| +v ++ +> +succ +< ++ ++ +/ +/ ++ +- +> +succ ++ +/ +/ ++ +/ +/ +While +the +final +CFG +form +is +functionally +identical +the +updates +to ++ +/ +/ +DDT +are +not +. +In +the +first +case +we +must +have +DDT +. +insertEdge +( +Pred1 +Succ +) ++ +/ +/ +while +in +the +latter +case +we +must +* +NOT +* +have +DDT +. +insertEdge +( +Pred1 +Succ +) +. ++ ++ +/ +/ +CFG +Change +: +bb0 +now +only +has +bb0 +- +> +bb1 +and +bb0 +- +> +bb3 +. +We +are +preparing +to ++ +/ +/ +remove +bb2 +. ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +3u +) +; ++ +BB0 +- +> +getTerminator +( +) +- +> +eraseFromParent +( +) +; ++ +BranchInst +: +: +Create +( +BB1 +BB3 +ConstantInt +: +: +getTrue +( +F +- +> +getContext +( +) +) +BB0 +) +; ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +2u +) +; ++ ++ +/ +/ +Remove +bb2 +from +F +. +This +has +to +happen +before +the +call +to +applyUpdates +( +) +for ++ +/ +/ +DDT +to +detect +there +is +no +longer +an +edge +between +bb2 +- +> +bb3 +. +The +deleteBB +( +) ++ +/ +/ +method +converts +bb2 +' +s +TI +into +" +unreachable +" +. ++ +ASSERT_FALSE +( +isa +< +UnreachableInst +> +( +BB2 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_FALSE +( +DDT +. +pendingDeletedBB +( +BB2 +) +) +; ++ +DDT +. +deleteBB +( +BB2 +) +; ++ +EXPECT_TRUE +( +DDT +. +pendingDeletedBB +( +BB2 +) +) +; ++ +ASSERT_TRUE +( +isa +< +UnreachableInst +> +( +BB2 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_EQ +( +BB2 +- +> +getParent +( +) +F +) +; ++ ++ +/ +/ +Queue +up +the +DDT +updates +. ++ +std +: +: +vector +< +DominatorTree +: +: +UpdateType +> +Updates +; ++ +Updates +. +reserve +( +4 +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB0 +BB2 +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB2 +BB3 +} +) +; ++ ++ +/ +/ +Handle +the +specific +shape +case +next +. ++ +/ +/ +CFG +Change +: +bb0 +now +only +branches +to +bb3 +. +We +are +preparing +to +remove +bb1 +. ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +2u +) +; ++ +BB0 +- +> +getTerminator +( +) +- +> +eraseFromParent +( +) +; ++ +BranchInst +: +: +Create +( +BB3 +BB0 +) +; ++ +EXPECT_EQ +( +BB0 +- +> +getTerminator +( +) +- +> +getNumSuccessors +( +) +1u +) +; ++ ++ +/ +/ +Remove +bb1 +from +F +. +This +has +to +happen +before +the +call +to +applyUpdates +( +) +for ++ +/ +/ +DDT +to +detect +there +is +no +longer +an +edge +between +bb1 +- +> +bb3 +. +The +deleteBB +( +) ++ +/ +/ +method +converts +bb1 +' +s +TI +into +" +unreachable +" +. ++ +ASSERT_FALSE +( +isa +< +UnreachableInst +> +( +BB1 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_FALSE +( +DDT +. +pendingDeletedBB +( +BB1 +) +) +; ++ +DDT +. +deleteBB +( +BB1 +) +; ++ +EXPECT_TRUE +( +DDT +. +pendingDeletedBB +( +BB1 +) +) +; ++ +ASSERT_TRUE +( +isa +< +UnreachableInst +> +( +BB1 +- +> +getTerminator +( +) +) +) +; ++ +EXPECT_EQ +( +BB1 +- +> +getParent +( +) +F +) +; ++ ++ +/ +/ +Update +the +DDT +. +In +this +case +we +don +' +t +call +DDT +. +insertEdge +( +BB0 +BB3 +) +because ++ +/ +/ +the +edge +previously +existed +at +the +start +of +this +test +when +DT +was +first ++ +/ +/ +created +. ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB0 +BB1 +} +) +; ++ +Updates +. +push_back +( +{ +DominatorTree +: +: +Delete +BB1 +BB3 +} +) +; ++ ++ +/ +/ +Verify +everything +. ++ +DDT +. +applyUpdates +( +Updates +) +; ++ +ASSERT_TRUE +( +DDT +. +flush +( +) +. +verify +( +) +) +; ++ +} +- +- +2 +. +18 +. +0 diff --git a/build/build-clang/r325356.patch b/build/build-clang/r325356.patch new file mode 100644 index 0000000000000..136ea392b59ac --- /dev/null +++ b/build/build-clang/r325356.patch @@ -0,0 +1,2898 @@ +From +3dd7de023be43bca7d6d45140e4fde42e22bc336 +Mon +Sep +17 +00 +: +00 +: +00 +2001 +From +: +" +Brian +M +. +Rzycki +" +< +brzycki +gmail +. +com +> +Date +: +Fri +16 +Feb +2018 +16 +: +35 +: +17 ++ +0000 +Subject +: +[ +PATCH +2 +/ +2 +] +[ +JumpThreading +] +PR36133 +enable +/ +disable +DominatorTree +for +LVI +analysis +Summary +: +The +LazyValueInfo +pass +caches +a +copy +of +the +DominatorTree +when +available +. +Whenever +there +are +pending +DominatorTree +updates +within +JumpThreading +' +s +DeferredDominance +object +we +cannot +use +the +cached +DT +for +LVI +analysis +. +This +commit +adds +the +new +methods +enableDT +( +) +and +disableDT +( +) +to +LVI +. +JumpThreading +also +sets +the +appropriate +usage +model +before +calling +LVI +analysis +methods +. +Fixes +https +: +/ +/ +bugs +. +llvm +. +org +/ +show_bug +. +cgi +? +id += +36133 +Reviewers +: +sebpop +dberlin +kuhar +Reviewed +by +: +sebpop +kuhar +Subscribers +: +uabelho +llvm +- +commits +aprantl +hiraditya +a +. +elovikov +Differential +Revision +: +https +: +/ +/ +reviews +. +llvm +. +org +/ +D42717 +git +- +svn +- +id +: +https +: +/ +/ +llvm +. +org +/ +svn +/ +llvm +- +project +/ +llvm +/ +trunk +325356 +91177308 +- +0d34 +- +0410 +- +b5e6 +- +96231b3b80d8 +- +- +- +include +/ +llvm +/ +Analysis +/ +LazyValueInfo +. +h +| +7 ++ ++ ++ ++ +include +/ +llvm +/ +IR +/ +Dominators +. +h +| +3 ++ ++ +lib +/ +Analysis +/ +LazyValueInfo +. +cpp +| +30 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +- +lib +/ +IR +/ +Dominators +. +cpp +| +3 ++ ++ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +| +37 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +test +/ +Transforms +/ +JumpThreading +/ +pr36133 +. +ll +| +44 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +6 +files +changed +123 +insertions +( ++ +) +1 +deletion +( +- +) +create +mode +100644 +test +/ +Transforms +/ +JumpThreading +/ +pr36133 +. +ll +diff +- +- +git +a +/ +llvm +/ +include +/ +llvm +/ +Analysis +/ +LazyValueInfo +. +h +b +/ +llvm +/ +include +/ +llvm +/ +Analysis +/ +LazyValueInfo +. +h +index +787c88cc6ec +. +. +cea5bf0df80 +100644 +- +- +- +a +/ +llvm +/ +include +/ +llvm +/ +Analysis +/ +LazyValueInfo +. +h ++ ++ ++ +b +/ +llvm +/ +include +/ +llvm +/ +Analysis +/ +LazyValueInfo +. +h +- +113 +6 ++ +113 +13 +public +: +/ +/ +/ +in +LVI +so +we +need +to +pass +it +here +as +an +argument +. +void +printLVI +( +Function +& +F +DominatorTree +& +DTree +raw_ostream +& +OS +) +; ++ +/ +/ +/ +Disables +use +of +the +DominatorTree +within +LVI +. ++ +void +disableDT +( +) +; ++ ++ +/ +/ +/ +Enables +use +of +the +DominatorTree +within +LVI +. +Does +nothing +if +the +class ++ +/ +/ +/ +instance +was +initialized +without +a +DT +pointer +. ++ +void +enableDT +( +) +; ++ +/ +/ +For +old +PM +pass +. +Delete +once +LazyValueInfoWrapperPass +is +gone +. +void +releaseMemory +( +) +; +diff +- +- +git +a +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h +b +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h +index +c5373376ade +. +. +ccb18527abc +100644 +- +- +- +a +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h ++ ++ ++ +b +/ +llvm +/ +include +/ +llvm +/ +IR +/ +Dominators +. +h +- +342 +6 ++ +342 +9 +public +: +/ +/ +/ +\ +brief +Returns +true +if +DelBB +is +awaiting +deletion +at +a +flush +( +) +event +. +bool +pendingDeletedBB +( +BasicBlock +* +DelBB +) +; ++ +/ +/ +/ +\ +brief +Returns +true +if +pending +DT +updates +are +queued +for +a +flush +( +) +event +. ++ +bool +pending +( +) +; ++ +/ +/ +/ +\ +brief +Flushes +all +pending +updates +and +block +deletions +. +Returns +a +/ +/ +/ +correct +DominatorTree +reference +to +be +used +by +the +caller +for +analysis +. +DominatorTree +& +flush +( +) +; +diff +- +- +git +a +/ +llvm +/ +lib +/ +Analysis +/ +LazyValueInfo +. +cpp +b +/ +llvm +/ +lib +/ +Analysis +/ +LazyValueInfo +. +cpp +index +d7da669f6e7 +. +. +fcbfb08cf1d +100644 +- +- +- +a +/ +llvm +/ +lib +/ +Analysis +/ +LazyValueInfo +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +Analysis +/ +LazyValueInfo +. +cpp +- +401 +6 ++ +401 +7 +namespace +{ +AssumptionCache +* +AC +; +/ +/ +/ +< +A +pointer +to +the +cache +of +llvm +. +assume +calls +. +const +DataLayout +& +DL +; +/ +/ +/ +< +A +mandatory +DataLayout +DominatorTree +* +DT +; +/ +/ +/ +< +An +optional +DT +pointer +. ++ +DominatorTree +* +DisabledDT +; +/ +/ +/ +< +Stores +DT +if +it +' +s +disabled +. +ValueLatticeElement +getBlockValue +( +Value +* +Val +BasicBlock +* +BB +) +; +bool +getEdgeValue +( +Value +* +V +BasicBlock +* +F +BasicBlock +* +T +- +463 +13 ++ +464 +30 +namespace +{ +TheCache +. +eraseBlock +( +BB +) +; +} ++ +/ +/ +/ +Disables +use +of +the +DominatorTree +within +LVI +. ++ +void +disableDT +( +) +{ ++ +if +( +DT +) +{ ++ +assert +( +! +DisabledDT +& +& +" +Both +DT +and +DisabledDT +are +not +nullptr +! +" +) +; ++ +std +: +: +swap +( +DT +DisabledDT +) +; ++ +} ++ +} ++ ++ +/ +/ +/ +Enables +use +of +the +DominatorTree +within +LVI +. +Does +nothing +if +the +class ++ +/ +/ +/ +instance +was +initialized +without +a +DT +pointer +. ++ +void +enableDT +( +) +{ ++ +if +( +DisabledDT +) +{ ++ +assert +( +! +DT +& +& +" +Both +DT +and +DisabledDT +are +not +nullptr +! +" +) +; ++ +std +: +: +swap +( +DT +DisabledDT +) +; ++ +} ++ +} ++ +/ +/ +/ +This +is +the +update +interface +to +inform +the +cache +that +an +edge +from +/ +/ +/ +PredBB +to +OldSucc +has +been +threaded +to +be +from +PredBB +to +NewSucc +. +void +threadEdge +( +BasicBlock +* +PredBB +BasicBlock +* +OldSucc +BasicBlock +* +NewSucc +) +; +LazyValueInfoImpl +( +AssumptionCache +* +AC +const +DataLayout +& +DL +DominatorTree +* +DT += +nullptr +) +- +: +AC +( +AC +) +DL +( +DL +) +DT +( +DT +) +{ +} ++ +: +AC +( +AC +) +DL +( +DL +) +DT +( +DT +) +DisabledDT +( +nullptr +) +{ +} +} +; +} +/ +/ +end +anonymous +namespace +- +1791 +6 ++ +1809 +16 +void +LazyValueInfo +: +: +printLVI +( +Function +& +F +DominatorTree +& +DTree +raw_ostream +& +OS +) +} +} ++ +void +LazyValueInfo +: +: +disableDT +( +) +{ ++ +if +( +PImpl +) ++ +getImpl +( +PImpl +AC +DL +DT +) +. +disableDT +( +) +; ++ +} ++ ++ +void +LazyValueInfo +: +: +enableDT +( +) +{ ++ +if +( +PImpl +) ++ +getImpl +( +PImpl +AC +DL +DT +) +. +enableDT +( +) +; ++ +} ++ +/ +/ +Print +the +LVI +for +the +function +arguments +at +the +start +of +each +basic +block +. +void +LazyValueInfoAnnotatedWriter +: +: +emitBasicBlockStartAnnot +( +const +BasicBlock +* +BB +formatted_raw_ostream +& +OS +) +{ +diff +- +- +git +a +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp +b +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp +index +e44e845b324 +. +. +5efd0df5db9 +100644 +- +- +- +a +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +IR +/ +Dominators +. +cpp +- +453 +6 ++ +453 +9 +bool +DeferredDominance +: +: +pendingDeletedBB +( +BasicBlock +* +DelBB +) +{ +return +DeletedBBs +. +count +( +DelBB +) +! += +0 +; +} ++ +/ +/ +/ +\ +brief +Returns +true +if +pending +DT +updates +are +queued +for +a +flush +( +) +event +. ++ +bool +DeferredDominance +: +: +pending +( +) +{ +return +! +PendUpdates +. +empty +( +) +; +} ++ +/ +/ +/ +\ +brief +Flushes +all +pending +updates +and +block +deletions +. +Returns +a +/ +/ +/ +correct +DominatorTree +reference +to +be +used +by +the +caller +for +analysis +. +DominatorTree +& +DeferredDominance +: +: +flush +( +) +{ +diff +- +- +git +a +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +b +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +index +4d366e8e392 +. +. +9ff91cf4924 +100644 +- +- +- +a +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp ++ ++ ++ +b +/ +llvm +/ +lib +/ +Transforms +/ +Scalar +/ +JumpThreading +. +cpp +- +425 +6 ++ +425 +7 +bool +JumpThreadingPass +: +: +runImpl +( +Function +& +F +TargetLibraryInfo +* +TLI_ +LoopHeaders +. +clear +( +) +; +DDT +- +> +flush +( +) +; ++ +LVI +- +> +enableDT +( +) +; +return +EverChanged +; +} +- +617 +6 ++ +618 +10 +bool +JumpThreadingPass +: +: +ComputeValueKnownInPredecessors +( +/ +/ +" +X +< +4 +" +and +" +X +< +3 +" +is +known +true +but +" +X +< +4 +" +itself +is +not +available +. +/ +/ +Perhaps +getConstantOnEdge +should +be +smart +enough +to +do +this +? ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +for +( +BasicBlock +* +P +: +predecessors +( +BB +) +) +{ +/ +/ +If +the +value +is +known +by +LazyValueInfo +to +be +a +constant +in +a +/ +/ +predecessor +use +that +information +to +try +to +thread +this +block +. +- +630 +6 ++ +635 +10 +bool +JumpThreadingPass +: +: +ComputeValueKnownInPredecessors +( +/ +/ +/ +If +I +is +a +PHI +node +then +we +know +the +incoming +values +for +any +constants +. +if +( +PHINode +* +PN += +dyn_cast +< +PHINode +> +( +I +) +) +{ ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +for +( +unsigned +i += +0 +e += +PN +- +> +getNumIncomingValues +( +) +; +i +! += +e +; ++ ++ +i +) +{ +Value +* +InVal += +PN +- +> +getIncomingValue +( +i +) +; +if +( +Constant +* +KC += +getKnownConstant +( +InVal +Preference +) +) +{ +- +759 +6 ++ +768 +10 +bool +JumpThreadingPass +: +: +ComputeValueKnownInPredecessors +( +const +DataLayout +& +DL += +PN +- +> +getModule +( +) +- +> +getDataLayout +( +) +; +/ +/ +We +can +do +this +simplification +if +any +comparisons +fold +to +true +or +false +. +/ +/ +See +if +any +do +. ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +for +( +unsigned +i += +0 +e += +PN +- +> +getNumIncomingValues +( +) +; +i +! += +e +; ++ ++ +i +) +{ +BasicBlock +* +PredBB += +PN +- +> +getIncomingBlock +( +i +) +; +Value +* +LHS += +PN +- +> +getIncomingValue +( +i +) +; +- +792 +6 ++ +805 +10 +bool +JumpThreadingPass +: +: +ComputeValueKnownInPredecessors +( +if +( +! +isa +< +Instruction +> +( +CmpLHS +) +| +| +cast +< +Instruction +> +( +CmpLHS +) +- +> +getParent +( +) +! += +BB +) +{ ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +for +( +BasicBlock +* +P +: +predecessors +( +BB +) +) +{ +/ +/ +If +the +value +is +known +by +LazyValueInfo +to +be +a +constant +in +a +/ +/ +predecessor +use +that +information +to +try +to +thread +this +block +. +- +820 +6 ++ +837 +10 +bool +JumpThreadingPass +: +: +ComputeValueKnownInPredecessors +( +match +( +CmpLHS +m_Add +( +m_Value +( +AddLHS +) +m_ConstantInt +( +AddConst +) +) +) +) +{ +if +( +! +isa +< +Instruction +> +( +AddLHS +) +| +| +cast +< +Instruction +> +( +AddLHS +) +- +> +getParent +( +) +! += +BB +) +{ ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +for +( +BasicBlock +* +P +: +predecessors +( +BB +) +) +{ +/ +/ +If +the +value +is +known +by +LazyValueInfo +to +be +a +ConstantRange +in +/ +/ +a +predecessor +use +that +information +to +try +to +thread +this +- +901 +6 ++ +922 +10 +bool +JumpThreadingPass +: +: +ComputeValueKnownInPredecessors +( +} +/ +/ +If +all +else +fails +see +if +LVI +can +figure +out +a +constant +value +for +us +. ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +Constant +* +CI += +LVI +- +> +getConstant +( +V +BB +CxtI +) +; +if +( +Constant +* +KC += +getKnownConstant +( +CI +Preference +) +) +{ +for +( +BasicBlock +* +Pred +: +predecessors +( +BB +) +) +- +1102 +6 ++ +1127 +10 +bool +JumpThreadingPass +: +: +ProcessBlock +( +BasicBlock +* +BB +) +{ +/ +/ +threading +is +concerned +. +assert +( +CondBr +- +> +isConditional +( +) +& +& +" +Threading +on +unconditional +terminator +" +) +; ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +LazyValueInfo +: +: +Tristate +Ret += +LVI +- +> +getPredicateAt +( +CondCmp +- +> +getPredicate +( +) +CondCmp +- +> +getOperand +( +0 +) +CondConst +CondBr +) +; +- +1899 +6 ++ +1928 +10 +bool +JumpThreadingPass +: +: +ThreadEdge +( +BasicBlock +* +BB +< +< +" +across +block +: +\ +n +" +< +< +* +BB +< +< +" +\ +n +" +) +; ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +LVI +- +> +threadEdge +( +PredBB +BB +SuccBB +) +; +/ +/ +We +are +going +to +have +to +map +operands +from +the +original +BB +block +to +the +new +- +2368 +6 ++ +2401 +10 +bool +JumpThreadingPass +: +: +TryToUnfoldSelect +( +CmpInst +* +CondCmp +BasicBlock +* +BB +) +{ +/ +/ +Now +check +if +one +of +the +select +values +would +allow +us +to +constant +fold +the +/ +/ +terminator +in +BB +. +We +don +' +t +do +the +transform +if +both +sides +fold +those +/ +/ +cases +will +be +threaded +in +any +case +. ++ +if +( +DDT +- +> +pending +( +) +) ++ +LVI +- +> +disableDT +( +) +; ++ +else ++ +LVI +- +> +enableDT +( +) +; +LazyValueInfo +: +: +Tristate +LHSFolds += +LVI +- +> +getPredicateOnEdge +( +CondCmp +- +> +getPredicate +( +) +SI +- +> +getOperand +( +1 +) +CondRHS +Pred +BB +CondCmp +) +; +diff +- +- +git +a +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +pr36133 +. +ll +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +pr36133 +. +ll +new +file +mode +100644 +index +00000000000 +. +. +b8d8c5fac46 +- +- +- +/ +dev +/ +null ++ ++ ++ +b +/ +llvm +/ +test +/ +Transforms +/ +JumpThreading +/ +pr36133 +. +ll +- +0 +0 ++ +1 +44 ++ +; +RUN +: +opt +- +jump +- +threading +- +S +< +% +s +| +FileCheck +% +s ++ +global += +external +global +i8 +* +align +8 ++ ++ +define +i32 +foo +( +i32 +% +arg +) +{ ++ +; +CHECK +- +LABEL +: +foo ++ +; +CHECK +- +LABEL +: +bb +: ++ +; +CHECK +: +icmp +eq ++ +; +CHECK +- +NEXT +: +br +i1 +% +tmp1 +label +% +bb7 +label +% +bb7 ++ +bb +: ++ +% +tmp += +load +i8 +* +i8 +* +* +global +align +8 ++ +% +tmp1 += +icmp +eq +i8 +* +% +tmp +null ++ +br +i1 +% +tmp1 +label +% +bb3 +label +% +bb2 ++ ++ +; +CHECK +- +NOT +: +bb2 +: ++ +bb2 +: ++ +br +label +% +bb3 ++ ++ +; +CHECK +- +NOT +: +bb3 +: ++ +bb3 +: ++ +% +tmp4 += +phi +i8 +[ +1 +% +bb2 +] +[ +0 +% +bb +] ++ +% +tmp5 += +icmp +eq +i8 +% +tmp4 +0 ++ +br +i1 +% +tmp5 +label +% +bb7 +label +% +bb6 ++ ++ +; +CHECK +- +NOT +: +bb6 +: ++ +bb6 +: ++ +br +label +% +bb7 ++ ++ +; +CHECK +- +LABEL +: +bb7 +: ++ +bb7 +: ++ +% +tmp8 += +icmp +eq +i32 +% +arg +- +1 ++ +br +i1 +% +tmp8 +label +% +bb9 +label +% +bb10 ++ ++ +; +CHECK +- +LABEL +: +bb9 +: ++ +bb9 +: ++ +ret +i32 +0 ++ ++ +; +CHECK +- +LABEL +: +bb10 +: ++ +bb10 +: ++ +% +tmp11 += +icmp +sgt +i32 +% +arg +- +1 ++ +call +void +llvm +. +assume +( +i1 +% +tmp11 +) ++ +ret +i32 +1 ++ +} ++ ++ +declare +void +llvm +. +assume +( +i1 +) +- +- +2 +. +18 +. +0